162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  libata-sff.c - helper library for PCI IDE BMDMA
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright 2003-2006 Red Hat, Inc.  All rights reserved.
662306a36Sopenharmony_ci *  Copyright 2003-2006 Jeff Garzik
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *  libata documentation is available via 'make {ps|pdf}docs',
962306a36Sopenharmony_ci *  as Documentation/driver-api/libata.rst
1062306a36Sopenharmony_ci *
1162306a36Sopenharmony_ci *  Hardware documentation available from http://www.t13.org/ and
1262306a36Sopenharmony_ci *  http://www.sata-io.org/
1362306a36Sopenharmony_ci */
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include <linux/kernel.h>
1662306a36Sopenharmony_ci#include <linux/gfp.h>
1762306a36Sopenharmony_ci#include <linux/pci.h>
1862306a36Sopenharmony_ci#include <linux/module.h>
1962306a36Sopenharmony_ci#include <linux/libata.h>
2062306a36Sopenharmony_ci#include <linux/highmem.h>
2162306a36Sopenharmony_ci#include <trace/events/libata.h>
2262306a36Sopenharmony_ci#include "libata.h"
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic struct workqueue_struct *ata_sff_wq;
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ciconst struct ata_port_operations ata_sff_port_ops = {
2762306a36Sopenharmony_ci	.inherits		= &ata_base_port_ops,
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	.qc_prep		= ata_noop_qc_prep,
3062306a36Sopenharmony_ci	.qc_issue		= ata_sff_qc_issue,
3162306a36Sopenharmony_ci	.qc_fill_rtf		= ata_sff_qc_fill_rtf,
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	.freeze			= ata_sff_freeze,
3462306a36Sopenharmony_ci	.thaw			= ata_sff_thaw,
3562306a36Sopenharmony_ci	.prereset		= ata_sff_prereset,
3662306a36Sopenharmony_ci	.softreset		= ata_sff_softreset,
3762306a36Sopenharmony_ci	.hardreset		= sata_sff_hardreset,
3862306a36Sopenharmony_ci	.postreset		= ata_sff_postreset,
3962306a36Sopenharmony_ci	.error_handler		= ata_sff_error_handler,
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci	.sff_dev_select		= ata_sff_dev_select,
4262306a36Sopenharmony_ci	.sff_check_status	= ata_sff_check_status,
4362306a36Sopenharmony_ci	.sff_tf_load		= ata_sff_tf_load,
4462306a36Sopenharmony_ci	.sff_tf_read		= ata_sff_tf_read,
4562306a36Sopenharmony_ci	.sff_exec_command	= ata_sff_exec_command,
4662306a36Sopenharmony_ci	.sff_data_xfer		= ata_sff_data_xfer,
4762306a36Sopenharmony_ci	.sff_drain_fifo		= ata_sff_drain_fifo,
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	.lost_interrupt		= ata_sff_lost_interrupt,
5062306a36Sopenharmony_ci};
5162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_port_ops);
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/**
5462306a36Sopenharmony_ci *	ata_sff_check_status - Read device status reg & clear interrupt
5562306a36Sopenharmony_ci *	@ap: port where the device is
5662306a36Sopenharmony_ci *
5762306a36Sopenharmony_ci *	Reads ATA taskfile status register for currently-selected device
5862306a36Sopenharmony_ci *	and return its value. This also clears pending interrupts
5962306a36Sopenharmony_ci *      from this device
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci *	LOCKING:
6262306a36Sopenharmony_ci *	Inherited from caller.
6362306a36Sopenharmony_ci */
6462306a36Sopenharmony_ciu8 ata_sff_check_status(struct ata_port *ap)
6562306a36Sopenharmony_ci{
6662306a36Sopenharmony_ci	return ioread8(ap->ioaddr.status_addr);
6762306a36Sopenharmony_ci}
6862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_check_status);
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci/**
7162306a36Sopenharmony_ci *	ata_sff_altstatus - Read device alternate status reg
7262306a36Sopenharmony_ci *	@ap: port where the device is
7362306a36Sopenharmony_ci *	@status: pointer to a status value
7462306a36Sopenharmony_ci *
7562306a36Sopenharmony_ci *	Reads ATA alternate status register for currently-selected device
7662306a36Sopenharmony_ci *	and return its value.
7762306a36Sopenharmony_ci *
7862306a36Sopenharmony_ci *	RETURN:
7962306a36Sopenharmony_ci *	true if the register exists, false if not.
8062306a36Sopenharmony_ci *
8162306a36Sopenharmony_ci *	LOCKING:
8262306a36Sopenharmony_ci *	Inherited from caller.
8362306a36Sopenharmony_ci */
8462306a36Sopenharmony_cistatic bool ata_sff_altstatus(struct ata_port *ap, u8 *status)
8562306a36Sopenharmony_ci{
8662306a36Sopenharmony_ci	u8 tmp;
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	if (ap->ops->sff_check_altstatus) {
8962306a36Sopenharmony_ci		tmp = ap->ops->sff_check_altstatus(ap);
9062306a36Sopenharmony_ci		goto read;
9162306a36Sopenharmony_ci	}
9262306a36Sopenharmony_ci	if (ap->ioaddr.altstatus_addr) {
9362306a36Sopenharmony_ci		tmp = ioread8(ap->ioaddr.altstatus_addr);
9462306a36Sopenharmony_ci		goto read;
9562306a36Sopenharmony_ci	}
9662306a36Sopenharmony_ci	return false;
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ciread:
9962306a36Sopenharmony_ci	if (status)
10062306a36Sopenharmony_ci		*status = tmp;
10162306a36Sopenharmony_ci	return true;
10262306a36Sopenharmony_ci}
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci/**
10562306a36Sopenharmony_ci *	ata_sff_irq_status - Check if the device is busy
10662306a36Sopenharmony_ci *	@ap: port where the device is
10762306a36Sopenharmony_ci *
10862306a36Sopenharmony_ci *	Determine if the port is currently busy. Uses altstatus
10962306a36Sopenharmony_ci *	if available in order to avoid clearing shared IRQ status
11062306a36Sopenharmony_ci *	when finding an IRQ source. Non ctl capable devices don't
11162306a36Sopenharmony_ci *	share interrupt lines fortunately for us.
11262306a36Sopenharmony_ci *
11362306a36Sopenharmony_ci *	LOCKING:
11462306a36Sopenharmony_ci *	Inherited from caller.
11562306a36Sopenharmony_ci */
11662306a36Sopenharmony_cistatic u8 ata_sff_irq_status(struct ata_port *ap)
11762306a36Sopenharmony_ci{
11862306a36Sopenharmony_ci	u8 status;
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci	/* Not us: We are busy */
12162306a36Sopenharmony_ci	if (ata_sff_altstatus(ap, &status) && (status & ATA_BUSY))
12262306a36Sopenharmony_ci		return status;
12362306a36Sopenharmony_ci	/* Clear INTRQ latch */
12462306a36Sopenharmony_ci	status = ap->ops->sff_check_status(ap);
12562306a36Sopenharmony_ci	return status;
12662306a36Sopenharmony_ci}
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci/**
12962306a36Sopenharmony_ci *	ata_sff_sync - Flush writes
13062306a36Sopenharmony_ci *	@ap: Port to wait for.
13162306a36Sopenharmony_ci *
13262306a36Sopenharmony_ci *	CAUTION:
13362306a36Sopenharmony_ci *	If we have an mmio device with no ctl and no altstatus
13462306a36Sopenharmony_ci *	method this will fail. No such devices are known to exist.
13562306a36Sopenharmony_ci *
13662306a36Sopenharmony_ci *	LOCKING:
13762306a36Sopenharmony_ci *	Inherited from caller.
13862306a36Sopenharmony_ci */
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cistatic void ata_sff_sync(struct ata_port *ap)
14162306a36Sopenharmony_ci{
14262306a36Sopenharmony_ci	ata_sff_altstatus(ap, NULL);
14362306a36Sopenharmony_ci}
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/**
14662306a36Sopenharmony_ci *	ata_sff_pause		-	Flush writes and wait 400nS
14762306a36Sopenharmony_ci *	@ap: Port to pause for.
14862306a36Sopenharmony_ci *
14962306a36Sopenharmony_ci *	CAUTION:
15062306a36Sopenharmony_ci *	If we have an mmio device with no ctl and no altstatus
15162306a36Sopenharmony_ci *	method this will fail. No such devices are known to exist.
15262306a36Sopenharmony_ci *
15362306a36Sopenharmony_ci *	LOCKING:
15462306a36Sopenharmony_ci *	Inherited from caller.
15562306a36Sopenharmony_ci */
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_civoid ata_sff_pause(struct ata_port *ap)
15862306a36Sopenharmony_ci{
15962306a36Sopenharmony_ci	ata_sff_sync(ap);
16062306a36Sopenharmony_ci	ndelay(400);
16162306a36Sopenharmony_ci}
16262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_pause);
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci/**
16562306a36Sopenharmony_ci *	ata_sff_dma_pause	-	Pause before commencing DMA
16662306a36Sopenharmony_ci *	@ap: Port to pause for.
16762306a36Sopenharmony_ci *
16862306a36Sopenharmony_ci *	Perform I/O fencing and ensure sufficient cycle delays occur
16962306a36Sopenharmony_ci *	for the HDMA1:0 transition
17062306a36Sopenharmony_ci */
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_civoid ata_sff_dma_pause(struct ata_port *ap)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	/*
17562306a36Sopenharmony_ci	 * An altstatus read will cause the needed delay without
17662306a36Sopenharmony_ci	 * messing up the IRQ status
17762306a36Sopenharmony_ci	 */
17862306a36Sopenharmony_ci	if (ata_sff_altstatus(ap, NULL))
17962306a36Sopenharmony_ci		return;
18062306a36Sopenharmony_ci	/* There are no DMA controllers without ctl. BUG here to ensure
18162306a36Sopenharmony_ci	   we never violate the HDMA1:0 transition timing and risk
18262306a36Sopenharmony_ci	   corruption. */
18362306a36Sopenharmony_ci	BUG();
18462306a36Sopenharmony_ci}
18562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_dma_pause);
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cistatic int ata_sff_check_ready(struct ata_link *link)
18862306a36Sopenharmony_ci{
18962306a36Sopenharmony_ci	u8 status = link->ap->ops->sff_check_status(link->ap);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	return ata_check_ready(status);
19262306a36Sopenharmony_ci}
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci/**
19562306a36Sopenharmony_ci *	ata_sff_wait_ready - sleep until BSY clears, or timeout
19662306a36Sopenharmony_ci *	@link: SFF link to wait ready status for
19762306a36Sopenharmony_ci *	@deadline: deadline jiffies for the operation
19862306a36Sopenharmony_ci *
19962306a36Sopenharmony_ci *	Sleep until ATA Status register bit BSY clears, or timeout
20062306a36Sopenharmony_ci *	occurs.
20162306a36Sopenharmony_ci *
20262306a36Sopenharmony_ci *	LOCKING:
20362306a36Sopenharmony_ci *	Kernel thread context (may sleep).
20462306a36Sopenharmony_ci *
20562306a36Sopenharmony_ci *	RETURNS:
20662306a36Sopenharmony_ci *	0 on success, -errno otherwise.
20762306a36Sopenharmony_ci */
20862306a36Sopenharmony_ciint ata_sff_wait_ready(struct ata_link *link, unsigned long deadline)
20962306a36Sopenharmony_ci{
21062306a36Sopenharmony_ci	return ata_wait_ready(link, deadline, ata_sff_check_ready);
21162306a36Sopenharmony_ci}
21262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_wait_ready);
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci/**
21562306a36Sopenharmony_ci *	ata_sff_set_devctl - Write device control reg
21662306a36Sopenharmony_ci *	@ap: port where the device is
21762306a36Sopenharmony_ci *	@ctl: value to write
21862306a36Sopenharmony_ci *
21962306a36Sopenharmony_ci *	Writes ATA device control register.
22062306a36Sopenharmony_ci *
22162306a36Sopenharmony_ci *	RETURN:
22262306a36Sopenharmony_ci *	true if the register exists, false if not.
22362306a36Sopenharmony_ci *
22462306a36Sopenharmony_ci *	LOCKING:
22562306a36Sopenharmony_ci *	Inherited from caller.
22662306a36Sopenharmony_ci */
22762306a36Sopenharmony_cistatic bool ata_sff_set_devctl(struct ata_port *ap, u8 ctl)
22862306a36Sopenharmony_ci{
22962306a36Sopenharmony_ci	if (ap->ops->sff_set_devctl) {
23062306a36Sopenharmony_ci		ap->ops->sff_set_devctl(ap, ctl);
23162306a36Sopenharmony_ci		return true;
23262306a36Sopenharmony_ci	}
23362306a36Sopenharmony_ci	if (ap->ioaddr.ctl_addr) {
23462306a36Sopenharmony_ci		iowrite8(ctl, ap->ioaddr.ctl_addr);
23562306a36Sopenharmony_ci		return true;
23662306a36Sopenharmony_ci	}
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	return false;
23962306a36Sopenharmony_ci}
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci/**
24262306a36Sopenharmony_ci *	ata_sff_dev_select - Select device 0/1 on ATA bus
24362306a36Sopenharmony_ci *	@ap: ATA channel to manipulate
24462306a36Sopenharmony_ci *	@device: ATA device (numbered from zero) to select
24562306a36Sopenharmony_ci *
24662306a36Sopenharmony_ci *	Use the method defined in the ATA specification to
24762306a36Sopenharmony_ci *	make either device 0, or device 1, active on the
24862306a36Sopenharmony_ci *	ATA channel.  Works with both PIO and MMIO.
24962306a36Sopenharmony_ci *
25062306a36Sopenharmony_ci *	May be used as the dev_select() entry in ata_port_operations.
25162306a36Sopenharmony_ci *
25262306a36Sopenharmony_ci *	LOCKING:
25362306a36Sopenharmony_ci *	caller.
25462306a36Sopenharmony_ci */
25562306a36Sopenharmony_civoid ata_sff_dev_select(struct ata_port *ap, unsigned int device)
25662306a36Sopenharmony_ci{
25762306a36Sopenharmony_ci	u8 tmp;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	if (device == 0)
26062306a36Sopenharmony_ci		tmp = ATA_DEVICE_OBS;
26162306a36Sopenharmony_ci	else
26262306a36Sopenharmony_ci		tmp = ATA_DEVICE_OBS | ATA_DEV1;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	iowrite8(tmp, ap->ioaddr.device_addr);
26562306a36Sopenharmony_ci	ata_sff_pause(ap);	/* needed; also flushes, for mmio */
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_dev_select);
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci/**
27062306a36Sopenharmony_ci *	ata_dev_select - Select device 0/1 on ATA bus
27162306a36Sopenharmony_ci *	@ap: ATA channel to manipulate
27262306a36Sopenharmony_ci *	@device: ATA device (numbered from zero) to select
27362306a36Sopenharmony_ci *	@wait: non-zero to wait for Status register BSY bit to clear
27462306a36Sopenharmony_ci *	@can_sleep: non-zero if context allows sleeping
27562306a36Sopenharmony_ci *
27662306a36Sopenharmony_ci *	Use the method defined in the ATA specification to
27762306a36Sopenharmony_ci *	make either device 0, or device 1, active on the
27862306a36Sopenharmony_ci *	ATA channel.
27962306a36Sopenharmony_ci *
28062306a36Sopenharmony_ci *	This is a high-level version of ata_sff_dev_select(), which
28162306a36Sopenharmony_ci *	additionally provides the services of inserting the proper
28262306a36Sopenharmony_ci *	pauses and status polling, where needed.
28362306a36Sopenharmony_ci *
28462306a36Sopenharmony_ci *	LOCKING:
28562306a36Sopenharmony_ci *	caller.
28662306a36Sopenharmony_ci */
28762306a36Sopenharmony_cistatic void ata_dev_select(struct ata_port *ap, unsigned int device,
28862306a36Sopenharmony_ci			   unsigned int wait, unsigned int can_sleep)
28962306a36Sopenharmony_ci{
29062306a36Sopenharmony_ci	if (wait)
29162306a36Sopenharmony_ci		ata_wait_idle(ap);
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	ap->ops->sff_dev_select(ap, device);
29462306a36Sopenharmony_ci
29562306a36Sopenharmony_ci	if (wait) {
29662306a36Sopenharmony_ci		if (can_sleep && ap->link.device[device].class == ATA_DEV_ATAPI)
29762306a36Sopenharmony_ci			ata_msleep(ap, 150);
29862306a36Sopenharmony_ci		ata_wait_idle(ap);
29962306a36Sopenharmony_ci	}
30062306a36Sopenharmony_ci}
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci/**
30362306a36Sopenharmony_ci *	ata_sff_irq_on - Enable interrupts on a port.
30462306a36Sopenharmony_ci *	@ap: Port on which interrupts are enabled.
30562306a36Sopenharmony_ci *
30662306a36Sopenharmony_ci *	Enable interrupts on a legacy IDE device using MMIO or PIO,
30762306a36Sopenharmony_ci *	wait for idle, clear any pending interrupts.
30862306a36Sopenharmony_ci *
30962306a36Sopenharmony_ci *	Note: may NOT be used as the sff_irq_on() entry in
31062306a36Sopenharmony_ci *	ata_port_operations.
31162306a36Sopenharmony_ci *
31262306a36Sopenharmony_ci *	LOCKING:
31362306a36Sopenharmony_ci *	Inherited from caller.
31462306a36Sopenharmony_ci */
31562306a36Sopenharmony_civoid ata_sff_irq_on(struct ata_port *ap)
31662306a36Sopenharmony_ci{
31762306a36Sopenharmony_ci	if (ap->ops->sff_irq_on) {
31862306a36Sopenharmony_ci		ap->ops->sff_irq_on(ap);
31962306a36Sopenharmony_ci		return;
32062306a36Sopenharmony_ci	}
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci	ap->ctl &= ~ATA_NIEN;
32362306a36Sopenharmony_ci	ap->last_ctl = ap->ctl;
32462306a36Sopenharmony_ci
32562306a36Sopenharmony_ci	ata_sff_set_devctl(ap, ap->ctl);
32662306a36Sopenharmony_ci	ata_wait_idle(ap);
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci	if (ap->ops->sff_irq_clear)
32962306a36Sopenharmony_ci		ap->ops->sff_irq_clear(ap);
33062306a36Sopenharmony_ci}
33162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_irq_on);
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci/**
33462306a36Sopenharmony_ci *	ata_sff_tf_load - send taskfile registers to host controller
33562306a36Sopenharmony_ci *	@ap: Port to which output is sent
33662306a36Sopenharmony_ci *	@tf: ATA taskfile register set
33762306a36Sopenharmony_ci *
33862306a36Sopenharmony_ci *	Outputs ATA taskfile to standard ATA host controller.
33962306a36Sopenharmony_ci *
34062306a36Sopenharmony_ci *	LOCKING:
34162306a36Sopenharmony_ci *	Inherited from caller.
34262306a36Sopenharmony_ci */
34362306a36Sopenharmony_civoid ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
34462306a36Sopenharmony_ci{
34562306a36Sopenharmony_ci	struct ata_ioports *ioaddr = &ap->ioaddr;
34662306a36Sopenharmony_ci	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci	if (tf->ctl != ap->last_ctl) {
34962306a36Sopenharmony_ci		if (ioaddr->ctl_addr)
35062306a36Sopenharmony_ci			iowrite8(tf->ctl, ioaddr->ctl_addr);
35162306a36Sopenharmony_ci		ap->last_ctl = tf->ctl;
35262306a36Sopenharmony_ci		ata_wait_idle(ap);
35362306a36Sopenharmony_ci	}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ci	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
35662306a36Sopenharmony_ci		WARN_ON_ONCE(!ioaddr->ctl_addr);
35762306a36Sopenharmony_ci		iowrite8(tf->hob_feature, ioaddr->feature_addr);
35862306a36Sopenharmony_ci		iowrite8(tf->hob_nsect, ioaddr->nsect_addr);
35962306a36Sopenharmony_ci		iowrite8(tf->hob_lbal, ioaddr->lbal_addr);
36062306a36Sopenharmony_ci		iowrite8(tf->hob_lbam, ioaddr->lbam_addr);
36162306a36Sopenharmony_ci		iowrite8(tf->hob_lbah, ioaddr->lbah_addr);
36262306a36Sopenharmony_ci	}
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	if (is_addr) {
36562306a36Sopenharmony_ci		iowrite8(tf->feature, ioaddr->feature_addr);
36662306a36Sopenharmony_ci		iowrite8(tf->nsect, ioaddr->nsect_addr);
36762306a36Sopenharmony_ci		iowrite8(tf->lbal, ioaddr->lbal_addr);
36862306a36Sopenharmony_ci		iowrite8(tf->lbam, ioaddr->lbam_addr);
36962306a36Sopenharmony_ci		iowrite8(tf->lbah, ioaddr->lbah_addr);
37062306a36Sopenharmony_ci	}
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci	if (tf->flags & ATA_TFLAG_DEVICE)
37362306a36Sopenharmony_ci		iowrite8(tf->device, ioaddr->device_addr);
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_ci	ata_wait_idle(ap);
37662306a36Sopenharmony_ci}
37762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_tf_load);
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci/**
38062306a36Sopenharmony_ci *	ata_sff_tf_read - input device's ATA taskfile shadow registers
38162306a36Sopenharmony_ci *	@ap: Port from which input is read
38262306a36Sopenharmony_ci *	@tf: ATA taskfile register set for storing input
38362306a36Sopenharmony_ci *
38462306a36Sopenharmony_ci *	Reads ATA taskfile registers for currently-selected device
38562306a36Sopenharmony_ci *	into @tf. Assumes the device has a fully SFF compliant task file
38662306a36Sopenharmony_ci *	layout and behaviour. If you device does not (eg has a different
38762306a36Sopenharmony_ci *	status method) then you will need to provide a replacement tf_read
38862306a36Sopenharmony_ci *
38962306a36Sopenharmony_ci *	LOCKING:
39062306a36Sopenharmony_ci *	Inherited from caller.
39162306a36Sopenharmony_ci */
39262306a36Sopenharmony_civoid ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
39362306a36Sopenharmony_ci{
39462306a36Sopenharmony_ci	struct ata_ioports *ioaddr = &ap->ioaddr;
39562306a36Sopenharmony_ci
39662306a36Sopenharmony_ci	tf->status = ata_sff_check_status(ap);
39762306a36Sopenharmony_ci	tf->error = ioread8(ioaddr->error_addr);
39862306a36Sopenharmony_ci	tf->nsect = ioread8(ioaddr->nsect_addr);
39962306a36Sopenharmony_ci	tf->lbal = ioread8(ioaddr->lbal_addr);
40062306a36Sopenharmony_ci	tf->lbam = ioread8(ioaddr->lbam_addr);
40162306a36Sopenharmony_ci	tf->lbah = ioread8(ioaddr->lbah_addr);
40262306a36Sopenharmony_ci	tf->device = ioread8(ioaddr->device_addr);
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	if (tf->flags & ATA_TFLAG_LBA48) {
40562306a36Sopenharmony_ci		if (likely(ioaddr->ctl_addr)) {
40662306a36Sopenharmony_ci			iowrite8(tf->ctl | ATA_HOB, ioaddr->ctl_addr);
40762306a36Sopenharmony_ci			tf->hob_feature = ioread8(ioaddr->error_addr);
40862306a36Sopenharmony_ci			tf->hob_nsect = ioread8(ioaddr->nsect_addr);
40962306a36Sopenharmony_ci			tf->hob_lbal = ioread8(ioaddr->lbal_addr);
41062306a36Sopenharmony_ci			tf->hob_lbam = ioread8(ioaddr->lbam_addr);
41162306a36Sopenharmony_ci			tf->hob_lbah = ioread8(ioaddr->lbah_addr);
41262306a36Sopenharmony_ci			iowrite8(tf->ctl, ioaddr->ctl_addr);
41362306a36Sopenharmony_ci			ap->last_ctl = tf->ctl;
41462306a36Sopenharmony_ci		} else
41562306a36Sopenharmony_ci			WARN_ON_ONCE(1);
41662306a36Sopenharmony_ci	}
41762306a36Sopenharmony_ci}
41862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_tf_read);
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci/**
42162306a36Sopenharmony_ci *	ata_sff_exec_command - issue ATA command to host controller
42262306a36Sopenharmony_ci *	@ap: port to which command is being issued
42362306a36Sopenharmony_ci *	@tf: ATA taskfile register set
42462306a36Sopenharmony_ci *
42562306a36Sopenharmony_ci *	Issues ATA command, with proper synchronization with interrupt
42662306a36Sopenharmony_ci *	handler / other threads.
42762306a36Sopenharmony_ci *
42862306a36Sopenharmony_ci *	LOCKING:
42962306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
43062306a36Sopenharmony_ci */
43162306a36Sopenharmony_civoid ata_sff_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
43262306a36Sopenharmony_ci{
43362306a36Sopenharmony_ci	iowrite8(tf->command, ap->ioaddr.command_addr);
43462306a36Sopenharmony_ci	ata_sff_pause(ap);
43562306a36Sopenharmony_ci}
43662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_exec_command);
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci/**
43962306a36Sopenharmony_ci *	ata_tf_to_host - issue ATA taskfile to host controller
44062306a36Sopenharmony_ci *	@ap: port to which command is being issued
44162306a36Sopenharmony_ci *	@tf: ATA taskfile register set
44262306a36Sopenharmony_ci *	@tag: tag of the associated command
44362306a36Sopenharmony_ci *
44462306a36Sopenharmony_ci *	Issues ATA taskfile register set to ATA host controller,
44562306a36Sopenharmony_ci *	with proper synchronization with interrupt handler and
44662306a36Sopenharmony_ci *	other threads.
44762306a36Sopenharmony_ci *
44862306a36Sopenharmony_ci *	LOCKING:
44962306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
45062306a36Sopenharmony_ci */
45162306a36Sopenharmony_cistatic inline void ata_tf_to_host(struct ata_port *ap,
45262306a36Sopenharmony_ci				  const struct ata_taskfile *tf,
45362306a36Sopenharmony_ci				  unsigned int tag)
45462306a36Sopenharmony_ci{
45562306a36Sopenharmony_ci	trace_ata_tf_load(ap, tf);
45662306a36Sopenharmony_ci	ap->ops->sff_tf_load(ap, tf);
45762306a36Sopenharmony_ci	trace_ata_exec_command(ap, tf, tag);
45862306a36Sopenharmony_ci	ap->ops->sff_exec_command(ap, tf);
45962306a36Sopenharmony_ci}
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci/**
46262306a36Sopenharmony_ci *	ata_sff_data_xfer - Transfer data by PIO
46362306a36Sopenharmony_ci *	@qc: queued command
46462306a36Sopenharmony_ci *	@buf: data buffer
46562306a36Sopenharmony_ci *	@buflen: buffer length
46662306a36Sopenharmony_ci *	@rw: read/write
46762306a36Sopenharmony_ci *
46862306a36Sopenharmony_ci *	Transfer data from/to the device data register by PIO.
46962306a36Sopenharmony_ci *
47062306a36Sopenharmony_ci *	LOCKING:
47162306a36Sopenharmony_ci *	Inherited from caller.
47262306a36Sopenharmony_ci *
47362306a36Sopenharmony_ci *	RETURNS:
47462306a36Sopenharmony_ci *	Bytes consumed.
47562306a36Sopenharmony_ci */
47662306a36Sopenharmony_ciunsigned int ata_sff_data_xfer(struct ata_queued_cmd *qc, unsigned char *buf,
47762306a36Sopenharmony_ci			       unsigned int buflen, int rw)
47862306a36Sopenharmony_ci{
47962306a36Sopenharmony_ci	struct ata_port *ap = qc->dev->link->ap;
48062306a36Sopenharmony_ci	void __iomem *data_addr = ap->ioaddr.data_addr;
48162306a36Sopenharmony_ci	unsigned int words = buflen >> 1;
48262306a36Sopenharmony_ci
48362306a36Sopenharmony_ci	/* Transfer multiple of 2 bytes */
48462306a36Sopenharmony_ci	if (rw == READ)
48562306a36Sopenharmony_ci		ioread16_rep(data_addr, buf, words);
48662306a36Sopenharmony_ci	else
48762306a36Sopenharmony_ci		iowrite16_rep(data_addr, buf, words);
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci	/* Transfer trailing byte, if any. */
49062306a36Sopenharmony_ci	if (unlikely(buflen & 0x01)) {
49162306a36Sopenharmony_ci		unsigned char pad[2] = { };
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci		/* Point buf to the tail of buffer */
49462306a36Sopenharmony_ci		buf += buflen - 1;
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci		/*
49762306a36Sopenharmony_ci		 * Use io*16_rep() accessors here as well to avoid pointlessly
49862306a36Sopenharmony_ci		 * swapping bytes to and from on the big endian machines...
49962306a36Sopenharmony_ci		 */
50062306a36Sopenharmony_ci		if (rw == READ) {
50162306a36Sopenharmony_ci			ioread16_rep(data_addr, pad, 1);
50262306a36Sopenharmony_ci			*buf = pad[0];
50362306a36Sopenharmony_ci		} else {
50462306a36Sopenharmony_ci			pad[0] = *buf;
50562306a36Sopenharmony_ci			iowrite16_rep(data_addr, pad, 1);
50662306a36Sopenharmony_ci		}
50762306a36Sopenharmony_ci		words++;
50862306a36Sopenharmony_ci	}
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_ci	return words << 1;
51162306a36Sopenharmony_ci}
51262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_data_xfer);
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_ci/**
51562306a36Sopenharmony_ci *	ata_sff_data_xfer32 - Transfer data by PIO
51662306a36Sopenharmony_ci *	@qc: queued command
51762306a36Sopenharmony_ci *	@buf: data buffer
51862306a36Sopenharmony_ci *	@buflen: buffer length
51962306a36Sopenharmony_ci *	@rw: read/write
52062306a36Sopenharmony_ci *
52162306a36Sopenharmony_ci *	Transfer data from/to the device data register by PIO using 32bit
52262306a36Sopenharmony_ci *	I/O operations.
52362306a36Sopenharmony_ci *
52462306a36Sopenharmony_ci *	LOCKING:
52562306a36Sopenharmony_ci *	Inherited from caller.
52662306a36Sopenharmony_ci *
52762306a36Sopenharmony_ci *	RETURNS:
52862306a36Sopenharmony_ci *	Bytes consumed.
52962306a36Sopenharmony_ci */
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ciunsigned int ata_sff_data_xfer32(struct ata_queued_cmd *qc, unsigned char *buf,
53262306a36Sopenharmony_ci			       unsigned int buflen, int rw)
53362306a36Sopenharmony_ci{
53462306a36Sopenharmony_ci	struct ata_device *dev = qc->dev;
53562306a36Sopenharmony_ci	struct ata_port *ap = dev->link->ap;
53662306a36Sopenharmony_ci	void __iomem *data_addr = ap->ioaddr.data_addr;
53762306a36Sopenharmony_ci	unsigned int words = buflen >> 2;
53862306a36Sopenharmony_ci	int slop = buflen & 3;
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_ci	if (!(ap->pflags & ATA_PFLAG_PIO32))
54162306a36Sopenharmony_ci		return ata_sff_data_xfer(qc, buf, buflen, rw);
54262306a36Sopenharmony_ci
54362306a36Sopenharmony_ci	/* Transfer multiple of 4 bytes */
54462306a36Sopenharmony_ci	if (rw == READ)
54562306a36Sopenharmony_ci		ioread32_rep(data_addr, buf, words);
54662306a36Sopenharmony_ci	else
54762306a36Sopenharmony_ci		iowrite32_rep(data_addr, buf, words);
54862306a36Sopenharmony_ci
54962306a36Sopenharmony_ci	/* Transfer trailing bytes, if any */
55062306a36Sopenharmony_ci	if (unlikely(slop)) {
55162306a36Sopenharmony_ci		unsigned char pad[4] = { };
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci		/* Point buf to the tail of buffer */
55462306a36Sopenharmony_ci		buf += buflen - slop;
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci		/*
55762306a36Sopenharmony_ci		 * Use io*_rep() accessors here as well to avoid pointlessly
55862306a36Sopenharmony_ci		 * swapping bytes to and from on the big endian machines...
55962306a36Sopenharmony_ci		 */
56062306a36Sopenharmony_ci		if (rw == READ) {
56162306a36Sopenharmony_ci			if (slop < 3)
56262306a36Sopenharmony_ci				ioread16_rep(data_addr, pad, 1);
56362306a36Sopenharmony_ci			else
56462306a36Sopenharmony_ci				ioread32_rep(data_addr, pad, 1);
56562306a36Sopenharmony_ci			memcpy(buf, pad, slop);
56662306a36Sopenharmony_ci		} else {
56762306a36Sopenharmony_ci			memcpy(pad, buf, slop);
56862306a36Sopenharmony_ci			if (slop < 3)
56962306a36Sopenharmony_ci				iowrite16_rep(data_addr, pad, 1);
57062306a36Sopenharmony_ci			else
57162306a36Sopenharmony_ci				iowrite32_rep(data_addr, pad, 1);
57262306a36Sopenharmony_ci		}
57362306a36Sopenharmony_ci	}
57462306a36Sopenharmony_ci	return (buflen + 1) & ~1;
57562306a36Sopenharmony_ci}
57662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_data_xfer32);
57762306a36Sopenharmony_ci
57862306a36Sopenharmony_cistatic void ata_pio_xfer(struct ata_queued_cmd *qc, struct page *page,
57962306a36Sopenharmony_ci		unsigned int offset, size_t xfer_size)
58062306a36Sopenharmony_ci{
58162306a36Sopenharmony_ci	bool do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
58262306a36Sopenharmony_ci	unsigned char *buf;
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	buf = kmap_atomic(page);
58562306a36Sopenharmony_ci	qc->ap->ops->sff_data_xfer(qc, buf + offset, xfer_size, do_write);
58662306a36Sopenharmony_ci	kunmap_atomic(buf);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	if (!do_write && !PageSlab(page))
58962306a36Sopenharmony_ci		flush_dcache_page(page);
59062306a36Sopenharmony_ci}
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci/**
59362306a36Sopenharmony_ci *	ata_pio_sector - Transfer a sector of data.
59462306a36Sopenharmony_ci *	@qc: Command on going
59562306a36Sopenharmony_ci *
59662306a36Sopenharmony_ci *	Transfer qc->sect_size bytes of data from/to the ATA device.
59762306a36Sopenharmony_ci *
59862306a36Sopenharmony_ci *	LOCKING:
59962306a36Sopenharmony_ci *	Inherited from caller.
60062306a36Sopenharmony_ci */
60162306a36Sopenharmony_cistatic void ata_pio_sector(struct ata_queued_cmd *qc)
60262306a36Sopenharmony_ci{
60362306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
60462306a36Sopenharmony_ci	struct page *page;
60562306a36Sopenharmony_ci	unsigned int offset;
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_ci	if (!qc->cursg) {
60862306a36Sopenharmony_ci		qc->curbytes = qc->nbytes;
60962306a36Sopenharmony_ci		return;
61062306a36Sopenharmony_ci	}
61162306a36Sopenharmony_ci	if (qc->curbytes == qc->nbytes - qc->sect_size)
61262306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST_LAST;
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	page = sg_page(qc->cursg);
61562306a36Sopenharmony_ci	offset = qc->cursg->offset + qc->cursg_ofs;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci	/* get the current page and offset */
61862306a36Sopenharmony_ci	page = nth_page(page, (offset >> PAGE_SHIFT));
61962306a36Sopenharmony_ci	offset %= PAGE_SIZE;
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci	trace_ata_sff_pio_transfer_data(qc, offset, qc->sect_size);
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ci	/*
62462306a36Sopenharmony_ci	 * Split the transfer when it splits a page boundary.  Note that the
62562306a36Sopenharmony_ci	 * split still has to be dword aligned like all ATA data transfers.
62662306a36Sopenharmony_ci	 */
62762306a36Sopenharmony_ci	WARN_ON_ONCE(offset % 4);
62862306a36Sopenharmony_ci	if (offset + qc->sect_size > PAGE_SIZE) {
62962306a36Sopenharmony_ci		unsigned int split_len = PAGE_SIZE - offset;
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci		ata_pio_xfer(qc, page, offset, split_len);
63262306a36Sopenharmony_ci		ata_pio_xfer(qc, nth_page(page, 1), 0,
63362306a36Sopenharmony_ci			     qc->sect_size - split_len);
63462306a36Sopenharmony_ci	} else {
63562306a36Sopenharmony_ci		ata_pio_xfer(qc, page, offset, qc->sect_size);
63662306a36Sopenharmony_ci	}
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	qc->curbytes += qc->sect_size;
63962306a36Sopenharmony_ci	qc->cursg_ofs += qc->sect_size;
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	if (qc->cursg_ofs == qc->cursg->length) {
64262306a36Sopenharmony_ci		qc->cursg = sg_next(qc->cursg);
64362306a36Sopenharmony_ci		if (!qc->cursg)
64462306a36Sopenharmony_ci			ap->hsm_task_state = HSM_ST_LAST;
64562306a36Sopenharmony_ci		qc->cursg_ofs = 0;
64662306a36Sopenharmony_ci	}
64762306a36Sopenharmony_ci}
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci/**
65062306a36Sopenharmony_ci *	ata_pio_sectors - Transfer one or many sectors.
65162306a36Sopenharmony_ci *	@qc: Command on going
65262306a36Sopenharmony_ci *
65362306a36Sopenharmony_ci *	Transfer one or many sectors of data from/to the
65462306a36Sopenharmony_ci *	ATA device for the DRQ request.
65562306a36Sopenharmony_ci *
65662306a36Sopenharmony_ci *	LOCKING:
65762306a36Sopenharmony_ci *	Inherited from caller.
65862306a36Sopenharmony_ci */
65962306a36Sopenharmony_cistatic void ata_pio_sectors(struct ata_queued_cmd *qc)
66062306a36Sopenharmony_ci{
66162306a36Sopenharmony_ci	if (is_multi_taskfile(&qc->tf)) {
66262306a36Sopenharmony_ci		/* READ/WRITE MULTIPLE */
66362306a36Sopenharmony_ci		unsigned int nsect;
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci		WARN_ON_ONCE(qc->dev->multi_count == 0);
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci		nsect = min((qc->nbytes - qc->curbytes) / qc->sect_size,
66862306a36Sopenharmony_ci			    qc->dev->multi_count);
66962306a36Sopenharmony_ci		while (nsect--)
67062306a36Sopenharmony_ci			ata_pio_sector(qc);
67162306a36Sopenharmony_ci	} else
67262306a36Sopenharmony_ci		ata_pio_sector(qc);
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci	ata_sff_sync(qc->ap); /* flush */
67562306a36Sopenharmony_ci}
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci/**
67862306a36Sopenharmony_ci *	atapi_send_cdb - Write CDB bytes to hardware
67962306a36Sopenharmony_ci *	@ap: Port to which ATAPI device is attached.
68062306a36Sopenharmony_ci *	@qc: Taskfile currently active
68162306a36Sopenharmony_ci *
68262306a36Sopenharmony_ci *	When device has indicated its readiness to accept
68362306a36Sopenharmony_ci *	a CDB, this function is called.  Send the CDB.
68462306a36Sopenharmony_ci *
68562306a36Sopenharmony_ci *	LOCKING:
68662306a36Sopenharmony_ci *	caller.
68762306a36Sopenharmony_ci */
68862306a36Sopenharmony_cistatic void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
68962306a36Sopenharmony_ci{
69062306a36Sopenharmony_ci	/* send SCSI cdb */
69162306a36Sopenharmony_ci	trace_atapi_send_cdb(qc, 0, qc->dev->cdb_len);
69262306a36Sopenharmony_ci	WARN_ON_ONCE(qc->dev->cdb_len < 12);
69362306a36Sopenharmony_ci
69462306a36Sopenharmony_ci	ap->ops->sff_data_xfer(qc, qc->cdb, qc->dev->cdb_len, 1);
69562306a36Sopenharmony_ci	ata_sff_sync(ap);
69662306a36Sopenharmony_ci	/* FIXME: If the CDB is for DMA do we need to do the transition delay
69762306a36Sopenharmony_ci	   or is bmdma_start guaranteed to do it ? */
69862306a36Sopenharmony_ci	switch (qc->tf.protocol) {
69962306a36Sopenharmony_ci	case ATAPI_PROT_PIO:
70062306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST;
70162306a36Sopenharmony_ci		break;
70262306a36Sopenharmony_ci	case ATAPI_PROT_NODATA:
70362306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST_LAST;
70462306a36Sopenharmony_ci		break;
70562306a36Sopenharmony_ci#ifdef CONFIG_ATA_BMDMA
70662306a36Sopenharmony_ci	case ATAPI_PROT_DMA:
70762306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST_LAST;
70862306a36Sopenharmony_ci		/* initiate bmdma */
70962306a36Sopenharmony_ci		trace_ata_bmdma_start(ap, &qc->tf, qc->tag);
71062306a36Sopenharmony_ci		ap->ops->bmdma_start(qc);
71162306a36Sopenharmony_ci		break;
71262306a36Sopenharmony_ci#endif /* CONFIG_ATA_BMDMA */
71362306a36Sopenharmony_ci	default:
71462306a36Sopenharmony_ci		BUG();
71562306a36Sopenharmony_ci	}
71662306a36Sopenharmony_ci}
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci/**
71962306a36Sopenharmony_ci *	__atapi_pio_bytes - Transfer data from/to the ATAPI device.
72062306a36Sopenharmony_ci *	@qc: Command on going
72162306a36Sopenharmony_ci *	@bytes: number of bytes
72262306a36Sopenharmony_ci *
72362306a36Sopenharmony_ci *	Transfer data from/to the ATAPI device.
72462306a36Sopenharmony_ci *
72562306a36Sopenharmony_ci *	LOCKING:
72662306a36Sopenharmony_ci *	Inherited from caller.
72762306a36Sopenharmony_ci *
72862306a36Sopenharmony_ci */
72962306a36Sopenharmony_cistatic int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
73062306a36Sopenharmony_ci{
73162306a36Sopenharmony_ci	int rw = (qc->tf.flags & ATA_TFLAG_WRITE) ? WRITE : READ;
73262306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
73362306a36Sopenharmony_ci	struct ata_device *dev = qc->dev;
73462306a36Sopenharmony_ci	struct ata_eh_info *ehi = &dev->link->eh_info;
73562306a36Sopenharmony_ci	struct scatterlist *sg;
73662306a36Sopenharmony_ci	struct page *page;
73762306a36Sopenharmony_ci	unsigned char *buf;
73862306a36Sopenharmony_ci	unsigned int offset, count, consumed;
73962306a36Sopenharmony_ci
74062306a36Sopenharmony_cinext_sg:
74162306a36Sopenharmony_ci	sg = qc->cursg;
74262306a36Sopenharmony_ci	if (unlikely(!sg)) {
74362306a36Sopenharmony_ci		ata_ehi_push_desc(ehi, "unexpected or too much trailing data "
74462306a36Sopenharmony_ci				  "buf=%u cur=%u bytes=%u",
74562306a36Sopenharmony_ci				  qc->nbytes, qc->curbytes, bytes);
74662306a36Sopenharmony_ci		return -1;
74762306a36Sopenharmony_ci	}
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci	page = sg_page(sg);
75062306a36Sopenharmony_ci	offset = sg->offset + qc->cursg_ofs;
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci	/* get the current page and offset */
75362306a36Sopenharmony_ci	page = nth_page(page, (offset >> PAGE_SHIFT));
75462306a36Sopenharmony_ci	offset %= PAGE_SIZE;
75562306a36Sopenharmony_ci
75662306a36Sopenharmony_ci	/* don't overrun current sg */
75762306a36Sopenharmony_ci	count = min(sg->length - qc->cursg_ofs, bytes);
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci	/* don't cross page boundaries */
76062306a36Sopenharmony_ci	count = min(count, (unsigned int)PAGE_SIZE - offset);
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	trace_atapi_pio_transfer_data(qc, offset, count);
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	/* do the actual data transfer */
76562306a36Sopenharmony_ci	buf = kmap_atomic(page);
76662306a36Sopenharmony_ci	consumed = ap->ops->sff_data_xfer(qc, buf + offset, count, rw);
76762306a36Sopenharmony_ci	kunmap_atomic(buf);
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	bytes -= min(bytes, consumed);
77062306a36Sopenharmony_ci	qc->curbytes += count;
77162306a36Sopenharmony_ci	qc->cursg_ofs += count;
77262306a36Sopenharmony_ci
77362306a36Sopenharmony_ci	if (qc->cursg_ofs == sg->length) {
77462306a36Sopenharmony_ci		qc->cursg = sg_next(qc->cursg);
77562306a36Sopenharmony_ci		qc->cursg_ofs = 0;
77662306a36Sopenharmony_ci	}
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ci	/*
77962306a36Sopenharmony_ci	 * There used to be a  WARN_ON_ONCE(qc->cursg && count != consumed);
78062306a36Sopenharmony_ci	 * Unfortunately __atapi_pio_bytes doesn't know enough to do the WARN
78162306a36Sopenharmony_ci	 * check correctly as it doesn't know if it is the last request being
78262306a36Sopenharmony_ci	 * made. Somebody should implement a proper sanity check.
78362306a36Sopenharmony_ci	 */
78462306a36Sopenharmony_ci	if (bytes)
78562306a36Sopenharmony_ci		goto next_sg;
78662306a36Sopenharmony_ci	return 0;
78762306a36Sopenharmony_ci}
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_ci/**
79062306a36Sopenharmony_ci *	atapi_pio_bytes - Transfer data from/to the ATAPI device.
79162306a36Sopenharmony_ci *	@qc: Command on going
79262306a36Sopenharmony_ci *
79362306a36Sopenharmony_ci *	Transfer Transfer data from/to the ATAPI device.
79462306a36Sopenharmony_ci *
79562306a36Sopenharmony_ci *	LOCKING:
79662306a36Sopenharmony_ci *	Inherited from caller.
79762306a36Sopenharmony_ci */
79862306a36Sopenharmony_cistatic void atapi_pio_bytes(struct ata_queued_cmd *qc)
79962306a36Sopenharmony_ci{
80062306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
80162306a36Sopenharmony_ci	struct ata_device *dev = qc->dev;
80262306a36Sopenharmony_ci	struct ata_eh_info *ehi = &dev->link->eh_info;
80362306a36Sopenharmony_ci	unsigned int ireason, bc_lo, bc_hi, bytes;
80462306a36Sopenharmony_ci	int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci	/* Abuse qc->result_tf for temp storage of intermediate TF
80762306a36Sopenharmony_ci	 * here to save some kernel stack usage.
80862306a36Sopenharmony_ci	 * For normal completion, qc->result_tf is not relevant. For
80962306a36Sopenharmony_ci	 * error, qc->result_tf is later overwritten by ata_qc_complete().
81062306a36Sopenharmony_ci	 * So, the correctness of qc->result_tf is not affected.
81162306a36Sopenharmony_ci	 */
81262306a36Sopenharmony_ci	ap->ops->sff_tf_read(ap, &qc->result_tf);
81362306a36Sopenharmony_ci	ireason = qc->result_tf.nsect;
81462306a36Sopenharmony_ci	bc_lo = qc->result_tf.lbam;
81562306a36Sopenharmony_ci	bc_hi = qc->result_tf.lbah;
81662306a36Sopenharmony_ci	bytes = (bc_hi << 8) | bc_lo;
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	/* shall be cleared to zero, indicating xfer of data */
81962306a36Sopenharmony_ci	if (unlikely(ireason & ATAPI_COD))
82062306a36Sopenharmony_ci		goto atapi_check;
82162306a36Sopenharmony_ci
82262306a36Sopenharmony_ci	/* make sure transfer direction matches expected */
82362306a36Sopenharmony_ci	i_write = ((ireason & ATAPI_IO) == 0) ? 1 : 0;
82462306a36Sopenharmony_ci	if (unlikely(do_write != i_write))
82562306a36Sopenharmony_ci		goto atapi_check;
82662306a36Sopenharmony_ci
82762306a36Sopenharmony_ci	if (unlikely(!bytes))
82862306a36Sopenharmony_ci		goto atapi_check;
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	if (unlikely(__atapi_pio_bytes(qc, bytes)))
83162306a36Sopenharmony_ci		goto err_out;
83262306a36Sopenharmony_ci	ata_sff_sync(ap); /* flush */
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	return;
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci atapi_check:
83762306a36Sopenharmony_ci	ata_ehi_push_desc(ehi, "ATAPI check failed (ireason=0x%x bytes=%u)",
83862306a36Sopenharmony_ci			  ireason, bytes);
83962306a36Sopenharmony_ci err_out:
84062306a36Sopenharmony_ci	qc->err_mask |= AC_ERR_HSM;
84162306a36Sopenharmony_ci	ap->hsm_task_state = HSM_ST_ERR;
84262306a36Sopenharmony_ci}
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci/**
84562306a36Sopenharmony_ci *	ata_hsm_ok_in_wq - Check if the qc can be handled in the workqueue.
84662306a36Sopenharmony_ci *	@ap: the target ata_port
84762306a36Sopenharmony_ci *	@qc: qc on going
84862306a36Sopenharmony_ci *
84962306a36Sopenharmony_ci *	RETURNS:
85062306a36Sopenharmony_ci *	1 if ok in workqueue, 0 otherwise.
85162306a36Sopenharmony_ci */
85262306a36Sopenharmony_cistatic inline int ata_hsm_ok_in_wq(struct ata_port *ap,
85362306a36Sopenharmony_ci						struct ata_queued_cmd *qc)
85462306a36Sopenharmony_ci{
85562306a36Sopenharmony_ci	if (qc->tf.flags & ATA_TFLAG_POLLING)
85662306a36Sopenharmony_ci		return 1;
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci	if (ap->hsm_task_state == HSM_ST_FIRST) {
85962306a36Sopenharmony_ci		if (qc->tf.protocol == ATA_PROT_PIO &&
86062306a36Sopenharmony_ci		   (qc->tf.flags & ATA_TFLAG_WRITE))
86162306a36Sopenharmony_ci		    return 1;
86262306a36Sopenharmony_ci
86362306a36Sopenharmony_ci		if (ata_is_atapi(qc->tf.protocol) &&
86462306a36Sopenharmony_ci		   !(qc->dev->flags & ATA_DFLAG_CDB_INTR))
86562306a36Sopenharmony_ci			return 1;
86662306a36Sopenharmony_ci	}
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci	return 0;
86962306a36Sopenharmony_ci}
87062306a36Sopenharmony_ci
87162306a36Sopenharmony_ci/**
87262306a36Sopenharmony_ci *	ata_hsm_qc_complete - finish a qc running on standard HSM
87362306a36Sopenharmony_ci *	@qc: Command to complete
87462306a36Sopenharmony_ci *	@in_wq: 1 if called from workqueue, 0 otherwise
87562306a36Sopenharmony_ci *
87662306a36Sopenharmony_ci *	Finish @qc which is running on standard HSM.
87762306a36Sopenharmony_ci *
87862306a36Sopenharmony_ci *	LOCKING:
87962306a36Sopenharmony_ci *	If @in_wq is zero, spin_lock_irqsave(host lock).
88062306a36Sopenharmony_ci *	Otherwise, none on entry and grabs host lock.
88162306a36Sopenharmony_ci */
88262306a36Sopenharmony_cistatic void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
88362306a36Sopenharmony_ci{
88462306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
88562306a36Sopenharmony_ci
88662306a36Sopenharmony_ci	if (in_wq) {
88762306a36Sopenharmony_ci		/* EH might have kicked in while host lock is released. */
88862306a36Sopenharmony_ci		qc = ata_qc_from_tag(ap, qc->tag);
88962306a36Sopenharmony_ci		if (qc) {
89062306a36Sopenharmony_ci			if (likely(!(qc->err_mask & AC_ERR_HSM))) {
89162306a36Sopenharmony_ci				ata_sff_irq_on(ap);
89262306a36Sopenharmony_ci				ata_qc_complete(qc);
89362306a36Sopenharmony_ci			} else
89462306a36Sopenharmony_ci				ata_port_freeze(ap);
89562306a36Sopenharmony_ci		}
89662306a36Sopenharmony_ci	} else {
89762306a36Sopenharmony_ci		if (likely(!(qc->err_mask & AC_ERR_HSM)))
89862306a36Sopenharmony_ci			ata_qc_complete(qc);
89962306a36Sopenharmony_ci		else
90062306a36Sopenharmony_ci			ata_port_freeze(ap);
90162306a36Sopenharmony_ci	}
90262306a36Sopenharmony_ci}
90362306a36Sopenharmony_ci
90462306a36Sopenharmony_ci/**
90562306a36Sopenharmony_ci *	ata_sff_hsm_move - move the HSM to the next state.
90662306a36Sopenharmony_ci *	@ap: the target ata_port
90762306a36Sopenharmony_ci *	@qc: qc on going
90862306a36Sopenharmony_ci *	@status: current device status
90962306a36Sopenharmony_ci *	@in_wq: 1 if called from workqueue, 0 otherwise
91062306a36Sopenharmony_ci *
91162306a36Sopenharmony_ci *	RETURNS:
91262306a36Sopenharmony_ci *	1 when poll next status needed, 0 otherwise.
91362306a36Sopenharmony_ci */
91462306a36Sopenharmony_ciint ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
91562306a36Sopenharmony_ci		     u8 status, int in_wq)
91662306a36Sopenharmony_ci{
91762306a36Sopenharmony_ci	struct ata_link *link = qc->dev->link;
91862306a36Sopenharmony_ci	struct ata_eh_info *ehi = &link->eh_info;
91962306a36Sopenharmony_ci	int poll_next;
92062306a36Sopenharmony_ci
92162306a36Sopenharmony_ci	lockdep_assert_held(ap->lock);
92262306a36Sopenharmony_ci
92362306a36Sopenharmony_ci	WARN_ON_ONCE((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	/* Make sure ata_sff_qc_issue() does not throw things
92662306a36Sopenharmony_ci	 * like DMA polling into the workqueue. Notice that
92762306a36Sopenharmony_ci	 * in_wq is not equivalent to (qc->tf.flags & ATA_TFLAG_POLLING).
92862306a36Sopenharmony_ci	 */
92962306a36Sopenharmony_ci	WARN_ON_ONCE(in_wq != ata_hsm_ok_in_wq(ap, qc));
93062306a36Sopenharmony_ci
93162306a36Sopenharmony_cifsm_start:
93262306a36Sopenharmony_ci	trace_ata_sff_hsm_state(qc, status);
93362306a36Sopenharmony_ci
93462306a36Sopenharmony_ci	switch (ap->hsm_task_state) {
93562306a36Sopenharmony_ci	case HSM_ST_FIRST:
93662306a36Sopenharmony_ci		/* Send first data block or PACKET CDB */
93762306a36Sopenharmony_ci
93862306a36Sopenharmony_ci		/* If polling, we will stay in the work queue after
93962306a36Sopenharmony_ci		 * sending the data. Otherwise, interrupt handler
94062306a36Sopenharmony_ci		 * takes over after sending the data.
94162306a36Sopenharmony_ci		 */
94262306a36Sopenharmony_ci		poll_next = (qc->tf.flags & ATA_TFLAG_POLLING);
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci		/* check device status */
94562306a36Sopenharmony_ci		if (unlikely((status & ATA_DRQ) == 0)) {
94662306a36Sopenharmony_ci			/* handle BSY=0, DRQ=0 as error */
94762306a36Sopenharmony_ci			if (likely(status & (ATA_ERR | ATA_DF)))
94862306a36Sopenharmony_ci				/* device stops HSM for abort/error */
94962306a36Sopenharmony_ci				qc->err_mask |= AC_ERR_DEV;
95062306a36Sopenharmony_ci			else {
95162306a36Sopenharmony_ci				/* HSM violation. Let EH handle this */
95262306a36Sopenharmony_ci				ata_ehi_push_desc(ehi,
95362306a36Sopenharmony_ci					"ST_FIRST: !(DRQ|ERR|DF)");
95462306a36Sopenharmony_ci				qc->err_mask |= AC_ERR_HSM;
95562306a36Sopenharmony_ci			}
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_ci			ap->hsm_task_state = HSM_ST_ERR;
95862306a36Sopenharmony_ci			goto fsm_start;
95962306a36Sopenharmony_ci		}
96062306a36Sopenharmony_ci
96162306a36Sopenharmony_ci		/* Device should not ask for data transfer (DRQ=1)
96262306a36Sopenharmony_ci		 * when it finds something wrong.
96362306a36Sopenharmony_ci		 * We ignore DRQ here and stop the HSM by
96462306a36Sopenharmony_ci		 * changing hsm_task_state to HSM_ST_ERR and
96562306a36Sopenharmony_ci		 * let the EH abort the command or reset the device.
96662306a36Sopenharmony_ci		 */
96762306a36Sopenharmony_ci		if (unlikely(status & (ATA_ERR | ATA_DF))) {
96862306a36Sopenharmony_ci			/* Some ATAPI tape drives forget to clear the ERR bit
96962306a36Sopenharmony_ci			 * when doing the next command (mostly request sense).
97062306a36Sopenharmony_ci			 * We ignore ERR here to workaround and proceed sending
97162306a36Sopenharmony_ci			 * the CDB.
97262306a36Sopenharmony_ci			 */
97362306a36Sopenharmony_ci			if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) {
97462306a36Sopenharmony_ci				ata_ehi_push_desc(ehi, "ST_FIRST: "
97562306a36Sopenharmony_ci					"DRQ=1 with device error, "
97662306a36Sopenharmony_ci					"dev_stat 0x%X", status);
97762306a36Sopenharmony_ci				qc->err_mask |= AC_ERR_HSM;
97862306a36Sopenharmony_ci				ap->hsm_task_state = HSM_ST_ERR;
97962306a36Sopenharmony_ci				goto fsm_start;
98062306a36Sopenharmony_ci			}
98162306a36Sopenharmony_ci		}
98262306a36Sopenharmony_ci
98362306a36Sopenharmony_ci		if (qc->tf.protocol == ATA_PROT_PIO) {
98462306a36Sopenharmony_ci			/* PIO data out protocol.
98562306a36Sopenharmony_ci			 * send first data block.
98662306a36Sopenharmony_ci			 */
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci			/* ata_pio_sectors() might change the state
98962306a36Sopenharmony_ci			 * to HSM_ST_LAST. so, the state is changed here
99062306a36Sopenharmony_ci			 * before ata_pio_sectors().
99162306a36Sopenharmony_ci			 */
99262306a36Sopenharmony_ci			ap->hsm_task_state = HSM_ST;
99362306a36Sopenharmony_ci			ata_pio_sectors(qc);
99462306a36Sopenharmony_ci		} else
99562306a36Sopenharmony_ci			/* send CDB */
99662306a36Sopenharmony_ci			atapi_send_cdb(ap, qc);
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci		/* if polling, ata_sff_pio_task() handles the rest.
99962306a36Sopenharmony_ci		 * otherwise, interrupt handler takes over from here.
100062306a36Sopenharmony_ci		 */
100162306a36Sopenharmony_ci		break;
100262306a36Sopenharmony_ci
100362306a36Sopenharmony_ci	case HSM_ST:
100462306a36Sopenharmony_ci		/* complete command or read/write the data register */
100562306a36Sopenharmony_ci		if (qc->tf.protocol == ATAPI_PROT_PIO) {
100662306a36Sopenharmony_ci			/* ATAPI PIO protocol */
100762306a36Sopenharmony_ci			if ((status & ATA_DRQ) == 0) {
100862306a36Sopenharmony_ci				/* No more data to transfer or device error.
100962306a36Sopenharmony_ci				 * Device error will be tagged in HSM_ST_LAST.
101062306a36Sopenharmony_ci				 */
101162306a36Sopenharmony_ci				ap->hsm_task_state = HSM_ST_LAST;
101262306a36Sopenharmony_ci				goto fsm_start;
101362306a36Sopenharmony_ci			}
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci			/* Device should not ask for data transfer (DRQ=1)
101662306a36Sopenharmony_ci			 * when it finds something wrong.
101762306a36Sopenharmony_ci			 * We ignore DRQ here and stop the HSM by
101862306a36Sopenharmony_ci			 * changing hsm_task_state to HSM_ST_ERR and
101962306a36Sopenharmony_ci			 * let the EH abort the command or reset the device.
102062306a36Sopenharmony_ci			 */
102162306a36Sopenharmony_ci			if (unlikely(status & (ATA_ERR | ATA_DF))) {
102262306a36Sopenharmony_ci				ata_ehi_push_desc(ehi, "ST-ATAPI: "
102362306a36Sopenharmony_ci					"DRQ=1 with device error, "
102462306a36Sopenharmony_ci					"dev_stat 0x%X", status);
102562306a36Sopenharmony_ci				qc->err_mask |= AC_ERR_HSM;
102662306a36Sopenharmony_ci				ap->hsm_task_state = HSM_ST_ERR;
102762306a36Sopenharmony_ci				goto fsm_start;
102862306a36Sopenharmony_ci			}
102962306a36Sopenharmony_ci
103062306a36Sopenharmony_ci			atapi_pio_bytes(qc);
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci			if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
103362306a36Sopenharmony_ci				/* bad ireason reported by device */
103462306a36Sopenharmony_ci				goto fsm_start;
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci		} else {
103762306a36Sopenharmony_ci			/* ATA PIO protocol */
103862306a36Sopenharmony_ci			if (unlikely((status & ATA_DRQ) == 0)) {
103962306a36Sopenharmony_ci				/* handle BSY=0, DRQ=0 as error */
104062306a36Sopenharmony_ci				if (likely(status & (ATA_ERR | ATA_DF))) {
104162306a36Sopenharmony_ci					/* device stops HSM for abort/error */
104262306a36Sopenharmony_ci					qc->err_mask |= AC_ERR_DEV;
104362306a36Sopenharmony_ci
104462306a36Sopenharmony_ci					/* If diagnostic failed and this is
104562306a36Sopenharmony_ci					 * IDENTIFY, it's likely a phantom
104662306a36Sopenharmony_ci					 * device.  Mark hint.
104762306a36Sopenharmony_ci					 */
104862306a36Sopenharmony_ci					if (qc->dev->horkage &
104962306a36Sopenharmony_ci					    ATA_HORKAGE_DIAGNOSTIC)
105062306a36Sopenharmony_ci						qc->err_mask |=
105162306a36Sopenharmony_ci							AC_ERR_NODEV_HINT;
105262306a36Sopenharmony_ci				} else {
105362306a36Sopenharmony_ci					/* HSM violation. Let EH handle this.
105462306a36Sopenharmony_ci					 * Phantom devices also trigger this
105562306a36Sopenharmony_ci					 * condition.  Mark hint.
105662306a36Sopenharmony_ci					 */
105762306a36Sopenharmony_ci					ata_ehi_push_desc(ehi, "ST-ATA: "
105862306a36Sopenharmony_ci						"DRQ=0 without device error, "
105962306a36Sopenharmony_ci						"dev_stat 0x%X", status);
106062306a36Sopenharmony_ci					qc->err_mask |= AC_ERR_HSM |
106162306a36Sopenharmony_ci							AC_ERR_NODEV_HINT;
106262306a36Sopenharmony_ci				}
106362306a36Sopenharmony_ci
106462306a36Sopenharmony_ci				ap->hsm_task_state = HSM_ST_ERR;
106562306a36Sopenharmony_ci				goto fsm_start;
106662306a36Sopenharmony_ci			}
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_ci			/* For PIO reads, some devices may ask for
106962306a36Sopenharmony_ci			 * data transfer (DRQ=1) alone with ERR=1.
107062306a36Sopenharmony_ci			 * We respect DRQ here and transfer one
107162306a36Sopenharmony_ci			 * block of junk data before changing the
107262306a36Sopenharmony_ci			 * hsm_task_state to HSM_ST_ERR.
107362306a36Sopenharmony_ci			 *
107462306a36Sopenharmony_ci			 * For PIO writes, ERR=1 DRQ=1 doesn't make
107562306a36Sopenharmony_ci			 * sense since the data block has been
107662306a36Sopenharmony_ci			 * transferred to the device.
107762306a36Sopenharmony_ci			 */
107862306a36Sopenharmony_ci			if (unlikely(status & (ATA_ERR | ATA_DF))) {
107962306a36Sopenharmony_ci				/* data might be corrputed */
108062306a36Sopenharmony_ci				qc->err_mask |= AC_ERR_DEV;
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci				if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
108362306a36Sopenharmony_ci					ata_pio_sectors(qc);
108462306a36Sopenharmony_ci					status = ata_wait_idle(ap);
108562306a36Sopenharmony_ci				}
108662306a36Sopenharmony_ci
108762306a36Sopenharmony_ci				if (status & (ATA_BUSY | ATA_DRQ)) {
108862306a36Sopenharmony_ci					ata_ehi_push_desc(ehi, "ST-ATA: "
108962306a36Sopenharmony_ci						"BUSY|DRQ persists on ERR|DF, "
109062306a36Sopenharmony_ci						"dev_stat 0x%X", status);
109162306a36Sopenharmony_ci					qc->err_mask |= AC_ERR_HSM;
109262306a36Sopenharmony_ci				}
109362306a36Sopenharmony_ci
109462306a36Sopenharmony_ci				/* There are oddball controllers with
109562306a36Sopenharmony_ci				 * status register stuck at 0x7f and
109662306a36Sopenharmony_ci				 * lbal/m/h at zero which makes it
109762306a36Sopenharmony_ci				 * pass all other presence detection
109862306a36Sopenharmony_ci				 * mechanisms we have.  Set NODEV_HINT
109962306a36Sopenharmony_ci				 * for it.  Kernel bz#7241.
110062306a36Sopenharmony_ci				 */
110162306a36Sopenharmony_ci				if (status == 0x7f)
110262306a36Sopenharmony_ci					qc->err_mask |= AC_ERR_NODEV_HINT;
110362306a36Sopenharmony_ci
110462306a36Sopenharmony_ci				/* ata_pio_sectors() might change the
110562306a36Sopenharmony_ci				 * state to HSM_ST_LAST. so, the state
110662306a36Sopenharmony_ci				 * is changed after ata_pio_sectors().
110762306a36Sopenharmony_ci				 */
110862306a36Sopenharmony_ci				ap->hsm_task_state = HSM_ST_ERR;
110962306a36Sopenharmony_ci				goto fsm_start;
111062306a36Sopenharmony_ci			}
111162306a36Sopenharmony_ci
111262306a36Sopenharmony_ci			ata_pio_sectors(qc);
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci			if (ap->hsm_task_state == HSM_ST_LAST &&
111562306a36Sopenharmony_ci			    (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
111662306a36Sopenharmony_ci				/* all data read */
111762306a36Sopenharmony_ci				status = ata_wait_idle(ap);
111862306a36Sopenharmony_ci				goto fsm_start;
111962306a36Sopenharmony_ci			}
112062306a36Sopenharmony_ci		}
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci		poll_next = 1;
112362306a36Sopenharmony_ci		break;
112462306a36Sopenharmony_ci
112562306a36Sopenharmony_ci	case HSM_ST_LAST:
112662306a36Sopenharmony_ci		if (unlikely(!ata_ok(status))) {
112762306a36Sopenharmony_ci			qc->err_mask |= __ac_err_mask(status);
112862306a36Sopenharmony_ci			ap->hsm_task_state = HSM_ST_ERR;
112962306a36Sopenharmony_ci			goto fsm_start;
113062306a36Sopenharmony_ci		}
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_ci		/* no more data to transfer */
113362306a36Sopenharmony_ci		trace_ata_sff_hsm_command_complete(qc, status);
113462306a36Sopenharmony_ci
113562306a36Sopenharmony_ci		WARN_ON_ONCE(qc->err_mask & (AC_ERR_DEV | AC_ERR_HSM));
113662306a36Sopenharmony_ci
113762306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST_IDLE;
113862306a36Sopenharmony_ci
113962306a36Sopenharmony_ci		/* complete taskfile transaction */
114062306a36Sopenharmony_ci		ata_hsm_qc_complete(qc, in_wq);
114162306a36Sopenharmony_ci
114262306a36Sopenharmony_ci		poll_next = 0;
114362306a36Sopenharmony_ci		break;
114462306a36Sopenharmony_ci
114562306a36Sopenharmony_ci	case HSM_ST_ERR:
114662306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST_IDLE;
114762306a36Sopenharmony_ci
114862306a36Sopenharmony_ci		/* complete taskfile transaction */
114962306a36Sopenharmony_ci		ata_hsm_qc_complete(qc, in_wq);
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci		poll_next = 0;
115262306a36Sopenharmony_ci		break;
115362306a36Sopenharmony_ci	default:
115462306a36Sopenharmony_ci		poll_next = 0;
115562306a36Sopenharmony_ci		WARN(true, "ata%d: SFF host state machine in invalid state %d",
115662306a36Sopenharmony_ci		     ap->print_id, ap->hsm_task_state);
115762306a36Sopenharmony_ci	}
115862306a36Sopenharmony_ci
115962306a36Sopenharmony_ci	return poll_next;
116062306a36Sopenharmony_ci}
116162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_hsm_move);
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_civoid ata_sff_queue_work(struct work_struct *work)
116462306a36Sopenharmony_ci{
116562306a36Sopenharmony_ci	queue_work(ata_sff_wq, work);
116662306a36Sopenharmony_ci}
116762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_queue_work);
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_civoid ata_sff_queue_delayed_work(struct delayed_work *dwork, unsigned long delay)
117062306a36Sopenharmony_ci{
117162306a36Sopenharmony_ci	queue_delayed_work(ata_sff_wq, dwork, delay);
117262306a36Sopenharmony_ci}
117362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_queue_delayed_work);
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_civoid ata_sff_queue_pio_task(struct ata_link *link, unsigned long delay)
117662306a36Sopenharmony_ci{
117762306a36Sopenharmony_ci	struct ata_port *ap = link->ap;
117862306a36Sopenharmony_ci
117962306a36Sopenharmony_ci	WARN_ON((ap->sff_pio_task_link != NULL) &&
118062306a36Sopenharmony_ci		(ap->sff_pio_task_link != link));
118162306a36Sopenharmony_ci	ap->sff_pio_task_link = link;
118262306a36Sopenharmony_ci
118362306a36Sopenharmony_ci	/* may fail if ata_sff_flush_pio_task() in progress */
118462306a36Sopenharmony_ci	ata_sff_queue_delayed_work(&ap->sff_pio_task, msecs_to_jiffies(delay));
118562306a36Sopenharmony_ci}
118662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_queue_pio_task);
118762306a36Sopenharmony_ci
118862306a36Sopenharmony_civoid ata_sff_flush_pio_task(struct ata_port *ap)
118962306a36Sopenharmony_ci{
119062306a36Sopenharmony_ci	trace_ata_sff_flush_pio_task(ap);
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_ci	cancel_delayed_work_sync(&ap->sff_pio_task);
119362306a36Sopenharmony_ci
119462306a36Sopenharmony_ci	/*
119562306a36Sopenharmony_ci	 * We wanna reset the HSM state to IDLE.  If we do so without
119662306a36Sopenharmony_ci	 * grabbing the port lock, critical sections protected by it which
119762306a36Sopenharmony_ci	 * expect the HSM state to stay stable may get surprised.  For
119862306a36Sopenharmony_ci	 * example, we may set IDLE in between the time
119962306a36Sopenharmony_ci	 * __ata_sff_port_intr() checks for HSM_ST_IDLE and before it calls
120062306a36Sopenharmony_ci	 * ata_sff_hsm_move() causing ata_sff_hsm_move() to BUG().
120162306a36Sopenharmony_ci	 */
120262306a36Sopenharmony_ci	spin_lock_irq(ap->lock);
120362306a36Sopenharmony_ci	ap->hsm_task_state = HSM_ST_IDLE;
120462306a36Sopenharmony_ci	spin_unlock_irq(ap->lock);
120562306a36Sopenharmony_ci
120662306a36Sopenharmony_ci	ap->sff_pio_task_link = NULL;
120762306a36Sopenharmony_ci}
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_cistatic void ata_sff_pio_task(struct work_struct *work)
121062306a36Sopenharmony_ci{
121162306a36Sopenharmony_ci	struct ata_port *ap =
121262306a36Sopenharmony_ci		container_of(work, struct ata_port, sff_pio_task.work);
121362306a36Sopenharmony_ci	struct ata_link *link = ap->sff_pio_task_link;
121462306a36Sopenharmony_ci	struct ata_queued_cmd *qc;
121562306a36Sopenharmony_ci	u8 status;
121662306a36Sopenharmony_ci	int poll_next;
121762306a36Sopenharmony_ci
121862306a36Sopenharmony_ci	spin_lock_irq(ap->lock);
121962306a36Sopenharmony_ci
122062306a36Sopenharmony_ci	BUG_ON(ap->sff_pio_task_link == NULL);
122162306a36Sopenharmony_ci	/* qc can be NULL if timeout occurred */
122262306a36Sopenharmony_ci	qc = ata_qc_from_tag(ap, link->active_tag);
122362306a36Sopenharmony_ci	if (!qc) {
122462306a36Sopenharmony_ci		ap->sff_pio_task_link = NULL;
122562306a36Sopenharmony_ci		goto out_unlock;
122662306a36Sopenharmony_ci	}
122762306a36Sopenharmony_ci
122862306a36Sopenharmony_cifsm_start:
122962306a36Sopenharmony_ci	WARN_ON_ONCE(ap->hsm_task_state == HSM_ST_IDLE);
123062306a36Sopenharmony_ci
123162306a36Sopenharmony_ci	/*
123262306a36Sopenharmony_ci	 * This is purely heuristic.  This is a fast path.
123362306a36Sopenharmony_ci	 * Sometimes when we enter, BSY will be cleared in
123462306a36Sopenharmony_ci	 * a chk-status or two.  If not, the drive is probably seeking
123562306a36Sopenharmony_ci	 * or something.  Snooze for a couple msecs, then
123662306a36Sopenharmony_ci	 * chk-status again.  If still busy, queue delayed work.
123762306a36Sopenharmony_ci	 */
123862306a36Sopenharmony_ci	status = ata_sff_busy_wait(ap, ATA_BUSY, 5);
123962306a36Sopenharmony_ci	if (status & ATA_BUSY) {
124062306a36Sopenharmony_ci		spin_unlock_irq(ap->lock);
124162306a36Sopenharmony_ci		ata_msleep(ap, 2);
124262306a36Sopenharmony_ci		spin_lock_irq(ap->lock);
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci		status = ata_sff_busy_wait(ap, ATA_BUSY, 10);
124562306a36Sopenharmony_ci		if (status & ATA_BUSY) {
124662306a36Sopenharmony_ci			ata_sff_queue_pio_task(link, ATA_SHORT_PAUSE);
124762306a36Sopenharmony_ci			goto out_unlock;
124862306a36Sopenharmony_ci		}
124962306a36Sopenharmony_ci	}
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_ci	/*
125262306a36Sopenharmony_ci	 * hsm_move() may trigger another command to be processed.
125362306a36Sopenharmony_ci	 * clean the link beforehand.
125462306a36Sopenharmony_ci	 */
125562306a36Sopenharmony_ci	ap->sff_pio_task_link = NULL;
125662306a36Sopenharmony_ci	/* move the HSM */
125762306a36Sopenharmony_ci	poll_next = ata_sff_hsm_move(ap, qc, status, 1);
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci	/* another command or interrupt handler
126062306a36Sopenharmony_ci	 * may be running at this point.
126162306a36Sopenharmony_ci	 */
126262306a36Sopenharmony_ci	if (poll_next)
126362306a36Sopenharmony_ci		goto fsm_start;
126462306a36Sopenharmony_ciout_unlock:
126562306a36Sopenharmony_ci	spin_unlock_irq(ap->lock);
126662306a36Sopenharmony_ci}
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci/**
126962306a36Sopenharmony_ci *	ata_sff_qc_issue - issue taskfile to a SFF controller
127062306a36Sopenharmony_ci *	@qc: command to issue to device
127162306a36Sopenharmony_ci *
127262306a36Sopenharmony_ci *	This function issues a PIO or NODATA command to a SFF
127362306a36Sopenharmony_ci *	controller.
127462306a36Sopenharmony_ci *
127562306a36Sopenharmony_ci *	LOCKING:
127662306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
127762306a36Sopenharmony_ci *
127862306a36Sopenharmony_ci *	RETURNS:
127962306a36Sopenharmony_ci *	Zero on success, AC_ERR_* mask on failure
128062306a36Sopenharmony_ci */
128162306a36Sopenharmony_ciunsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
128262306a36Sopenharmony_ci{
128362306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
128462306a36Sopenharmony_ci	struct ata_link *link = qc->dev->link;
128562306a36Sopenharmony_ci
128662306a36Sopenharmony_ci	/* Use polling pio if the LLD doesn't handle
128762306a36Sopenharmony_ci	 * interrupt driven pio and atapi CDB interrupt.
128862306a36Sopenharmony_ci	 */
128962306a36Sopenharmony_ci	if (ap->flags & ATA_FLAG_PIO_POLLING)
129062306a36Sopenharmony_ci		qc->tf.flags |= ATA_TFLAG_POLLING;
129162306a36Sopenharmony_ci
129262306a36Sopenharmony_ci	/* select the device */
129362306a36Sopenharmony_ci	ata_dev_select(ap, qc->dev->devno, 1, 0);
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	/* start the command */
129662306a36Sopenharmony_ci	switch (qc->tf.protocol) {
129762306a36Sopenharmony_ci	case ATA_PROT_NODATA:
129862306a36Sopenharmony_ci		if (qc->tf.flags & ATA_TFLAG_POLLING)
129962306a36Sopenharmony_ci			ata_qc_set_polling(qc);
130062306a36Sopenharmony_ci
130162306a36Sopenharmony_ci		ata_tf_to_host(ap, &qc->tf, qc->tag);
130262306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST_LAST;
130362306a36Sopenharmony_ci
130462306a36Sopenharmony_ci		if (qc->tf.flags & ATA_TFLAG_POLLING)
130562306a36Sopenharmony_ci			ata_sff_queue_pio_task(link, 0);
130662306a36Sopenharmony_ci
130762306a36Sopenharmony_ci		break;
130862306a36Sopenharmony_ci
130962306a36Sopenharmony_ci	case ATA_PROT_PIO:
131062306a36Sopenharmony_ci		if (qc->tf.flags & ATA_TFLAG_POLLING)
131162306a36Sopenharmony_ci			ata_qc_set_polling(qc);
131262306a36Sopenharmony_ci
131362306a36Sopenharmony_ci		ata_tf_to_host(ap, &qc->tf, qc->tag);
131462306a36Sopenharmony_ci
131562306a36Sopenharmony_ci		if (qc->tf.flags & ATA_TFLAG_WRITE) {
131662306a36Sopenharmony_ci			/* PIO data out protocol */
131762306a36Sopenharmony_ci			ap->hsm_task_state = HSM_ST_FIRST;
131862306a36Sopenharmony_ci			ata_sff_queue_pio_task(link, 0);
131962306a36Sopenharmony_ci
132062306a36Sopenharmony_ci			/* always send first data block using the
132162306a36Sopenharmony_ci			 * ata_sff_pio_task() codepath.
132262306a36Sopenharmony_ci			 */
132362306a36Sopenharmony_ci		} else {
132462306a36Sopenharmony_ci			/* PIO data in protocol */
132562306a36Sopenharmony_ci			ap->hsm_task_state = HSM_ST;
132662306a36Sopenharmony_ci
132762306a36Sopenharmony_ci			if (qc->tf.flags & ATA_TFLAG_POLLING)
132862306a36Sopenharmony_ci				ata_sff_queue_pio_task(link, 0);
132962306a36Sopenharmony_ci
133062306a36Sopenharmony_ci			/* if polling, ata_sff_pio_task() handles the
133162306a36Sopenharmony_ci			 * rest.  otherwise, interrupt handler takes
133262306a36Sopenharmony_ci			 * over from here.
133362306a36Sopenharmony_ci			 */
133462306a36Sopenharmony_ci		}
133562306a36Sopenharmony_ci
133662306a36Sopenharmony_ci		break;
133762306a36Sopenharmony_ci
133862306a36Sopenharmony_ci	case ATAPI_PROT_PIO:
133962306a36Sopenharmony_ci	case ATAPI_PROT_NODATA:
134062306a36Sopenharmony_ci		if (qc->tf.flags & ATA_TFLAG_POLLING)
134162306a36Sopenharmony_ci			ata_qc_set_polling(qc);
134262306a36Sopenharmony_ci
134362306a36Sopenharmony_ci		ata_tf_to_host(ap, &qc->tf, qc->tag);
134462306a36Sopenharmony_ci
134562306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST_FIRST;
134662306a36Sopenharmony_ci
134762306a36Sopenharmony_ci		/* send cdb by polling if no cdb interrupt */
134862306a36Sopenharmony_ci		if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
134962306a36Sopenharmony_ci		    (qc->tf.flags & ATA_TFLAG_POLLING))
135062306a36Sopenharmony_ci			ata_sff_queue_pio_task(link, 0);
135162306a36Sopenharmony_ci		break;
135262306a36Sopenharmony_ci
135362306a36Sopenharmony_ci	default:
135462306a36Sopenharmony_ci		return AC_ERR_SYSTEM;
135562306a36Sopenharmony_ci	}
135662306a36Sopenharmony_ci
135762306a36Sopenharmony_ci	return 0;
135862306a36Sopenharmony_ci}
135962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_qc_issue);
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_ci/**
136262306a36Sopenharmony_ci *	ata_sff_qc_fill_rtf - fill result TF using ->sff_tf_read
136362306a36Sopenharmony_ci *	@qc: qc to fill result TF for
136462306a36Sopenharmony_ci *
136562306a36Sopenharmony_ci *	@qc is finished and result TF needs to be filled.  Fill it
136662306a36Sopenharmony_ci *	using ->sff_tf_read.
136762306a36Sopenharmony_ci *
136862306a36Sopenharmony_ci *	LOCKING:
136962306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
137062306a36Sopenharmony_ci */
137162306a36Sopenharmony_civoid ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc)
137262306a36Sopenharmony_ci{
137362306a36Sopenharmony_ci	qc->ap->ops->sff_tf_read(qc->ap, &qc->result_tf);
137462306a36Sopenharmony_ci}
137562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_cistatic unsigned int ata_sff_idle_irq(struct ata_port *ap)
137862306a36Sopenharmony_ci{
137962306a36Sopenharmony_ci	ap->stats.idle_irq++;
138062306a36Sopenharmony_ci
138162306a36Sopenharmony_ci#ifdef ATA_IRQ_TRAP
138262306a36Sopenharmony_ci	if ((ap->stats.idle_irq % 1000) == 0) {
138362306a36Sopenharmony_ci		ap->ops->sff_check_status(ap);
138462306a36Sopenharmony_ci		if (ap->ops->sff_irq_clear)
138562306a36Sopenharmony_ci			ap->ops->sff_irq_clear(ap);
138662306a36Sopenharmony_ci		ata_port_warn(ap, "irq trap\n");
138762306a36Sopenharmony_ci		return 1;
138862306a36Sopenharmony_ci	}
138962306a36Sopenharmony_ci#endif
139062306a36Sopenharmony_ci	return 0;	/* irq not handled */
139162306a36Sopenharmony_ci}
139262306a36Sopenharmony_ci
139362306a36Sopenharmony_cistatic unsigned int __ata_sff_port_intr(struct ata_port *ap,
139462306a36Sopenharmony_ci					struct ata_queued_cmd *qc,
139562306a36Sopenharmony_ci					bool hsmv_on_idle)
139662306a36Sopenharmony_ci{
139762306a36Sopenharmony_ci	u8 status;
139862306a36Sopenharmony_ci
139962306a36Sopenharmony_ci	trace_ata_sff_port_intr(qc, hsmv_on_idle);
140062306a36Sopenharmony_ci
140162306a36Sopenharmony_ci	/* Check whether we are expecting interrupt in this state */
140262306a36Sopenharmony_ci	switch (ap->hsm_task_state) {
140362306a36Sopenharmony_ci	case HSM_ST_FIRST:
140462306a36Sopenharmony_ci		/* Some pre-ATAPI-4 devices assert INTRQ
140562306a36Sopenharmony_ci		 * at this state when ready to receive CDB.
140662306a36Sopenharmony_ci		 */
140762306a36Sopenharmony_ci
140862306a36Sopenharmony_ci		/* Check the ATA_DFLAG_CDB_INTR flag is enough here.
140962306a36Sopenharmony_ci		 * The flag was turned on only for atapi devices.  No
141062306a36Sopenharmony_ci		 * need to check ata_is_atapi(qc->tf.protocol) again.
141162306a36Sopenharmony_ci		 */
141262306a36Sopenharmony_ci		if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
141362306a36Sopenharmony_ci			return ata_sff_idle_irq(ap);
141462306a36Sopenharmony_ci		break;
141562306a36Sopenharmony_ci	case HSM_ST_IDLE:
141662306a36Sopenharmony_ci		return ata_sff_idle_irq(ap);
141762306a36Sopenharmony_ci	default:
141862306a36Sopenharmony_ci		break;
141962306a36Sopenharmony_ci	}
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci	/* check main status, clearing INTRQ if needed */
142262306a36Sopenharmony_ci	status = ata_sff_irq_status(ap);
142362306a36Sopenharmony_ci	if (status & ATA_BUSY) {
142462306a36Sopenharmony_ci		if (hsmv_on_idle) {
142562306a36Sopenharmony_ci			/* BMDMA engine is already stopped, we're screwed */
142662306a36Sopenharmony_ci			qc->err_mask |= AC_ERR_HSM;
142762306a36Sopenharmony_ci			ap->hsm_task_state = HSM_ST_ERR;
142862306a36Sopenharmony_ci		} else
142962306a36Sopenharmony_ci			return ata_sff_idle_irq(ap);
143062306a36Sopenharmony_ci	}
143162306a36Sopenharmony_ci
143262306a36Sopenharmony_ci	/* clear irq events */
143362306a36Sopenharmony_ci	if (ap->ops->sff_irq_clear)
143462306a36Sopenharmony_ci		ap->ops->sff_irq_clear(ap);
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci	ata_sff_hsm_move(ap, qc, status, 0);
143762306a36Sopenharmony_ci
143862306a36Sopenharmony_ci	return 1;	/* irq handled */
143962306a36Sopenharmony_ci}
144062306a36Sopenharmony_ci
144162306a36Sopenharmony_ci/**
144262306a36Sopenharmony_ci *	ata_sff_port_intr - Handle SFF port interrupt
144362306a36Sopenharmony_ci *	@ap: Port on which interrupt arrived (possibly...)
144462306a36Sopenharmony_ci *	@qc: Taskfile currently active in engine
144562306a36Sopenharmony_ci *
144662306a36Sopenharmony_ci *	Handle port interrupt for given queued command.
144762306a36Sopenharmony_ci *
144862306a36Sopenharmony_ci *	LOCKING:
144962306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
145062306a36Sopenharmony_ci *
145162306a36Sopenharmony_ci *	RETURNS:
145262306a36Sopenharmony_ci *	One if interrupt was handled, zero if not (shared irq).
145362306a36Sopenharmony_ci */
145462306a36Sopenharmony_ciunsigned int ata_sff_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
145562306a36Sopenharmony_ci{
145662306a36Sopenharmony_ci	return __ata_sff_port_intr(ap, qc, false);
145762306a36Sopenharmony_ci}
145862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_port_intr);
145962306a36Sopenharmony_ci
146062306a36Sopenharmony_cistatic inline irqreturn_t __ata_sff_interrupt(int irq, void *dev_instance,
146162306a36Sopenharmony_ci	unsigned int (*port_intr)(struct ata_port *, struct ata_queued_cmd *))
146262306a36Sopenharmony_ci{
146362306a36Sopenharmony_ci	struct ata_host *host = dev_instance;
146462306a36Sopenharmony_ci	bool retried = false;
146562306a36Sopenharmony_ci	unsigned int i;
146662306a36Sopenharmony_ci	unsigned int handled, idle, polling;
146762306a36Sopenharmony_ci	unsigned long flags;
146862306a36Sopenharmony_ci
146962306a36Sopenharmony_ci	/* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
147062306a36Sopenharmony_ci	spin_lock_irqsave(&host->lock, flags);
147162306a36Sopenharmony_ci
147262306a36Sopenharmony_ciretry:
147362306a36Sopenharmony_ci	handled = idle = polling = 0;
147462306a36Sopenharmony_ci	for (i = 0; i < host->n_ports; i++) {
147562306a36Sopenharmony_ci		struct ata_port *ap = host->ports[i];
147662306a36Sopenharmony_ci		struct ata_queued_cmd *qc;
147762306a36Sopenharmony_ci
147862306a36Sopenharmony_ci		qc = ata_qc_from_tag(ap, ap->link.active_tag);
147962306a36Sopenharmony_ci		if (qc) {
148062306a36Sopenharmony_ci			if (!(qc->tf.flags & ATA_TFLAG_POLLING))
148162306a36Sopenharmony_ci				handled |= port_intr(ap, qc);
148262306a36Sopenharmony_ci			else
148362306a36Sopenharmony_ci				polling |= 1 << i;
148462306a36Sopenharmony_ci		} else
148562306a36Sopenharmony_ci			idle |= 1 << i;
148662306a36Sopenharmony_ci	}
148762306a36Sopenharmony_ci
148862306a36Sopenharmony_ci	/*
148962306a36Sopenharmony_ci	 * If no port was expecting IRQ but the controller is actually
149062306a36Sopenharmony_ci	 * asserting IRQ line, nobody cared will ensue.  Check IRQ
149162306a36Sopenharmony_ci	 * pending status if available and clear spurious IRQ.
149262306a36Sopenharmony_ci	 */
149362306a36Sopenharmony_ci	if (!handled && !retried) {
149462306a36Sopenharmony_ci		bool retry = false;
149562306a36Sopenharmony_ci
149662306a36Sopenharmony_ci		for (i = 0; i < host->n_ports; i++) {
149762306a36Sopenharmony_ci			struct ata_port *ap = host->ports[i];
149862306a36Sopenharmony_ci
149962306a36Sopenharmony_ci			if (polling & (1 << i))
150062306a36Sopenharmony_ci				continue;
150162306a36Sopenharmony_ci
150262306a36Sopenharmony_ci			if (!ap->ops->sff_irq_check ||
150362306a36Sopenharmony_ci			    !ap->ops->sff_irq_check(ap))
150462306a36Sopenharmony_ci				continue;
150562306a36Sopenharmony_ci
150662306a36Sopenharmony_ci			if (idle & (1 << i)) {
150762306a36Sopenharmony_ci				ap->ops->sff_check_status(ap);
150862306a36Sopenharmony_ci				if (ap->ops->sff_irq_clear)
150962306a36Sopenharmony_ci					ap->ops->sff_irq_clear(ap);
151062306a36Sopenharmony_ci			} else {
151162306a36Sopenharmony_ci				/* clear INTRQ and check if BUSY cleared */
151262306a36Sopenharmony_ci				if (!(ap->ops->sff_check_status(ap) & ATA_BUSY))
151362306a36Sopenharmony_ci					retry |= true;
151462306a36Sopenharmony_ci				/*
151562306a36Sopenharmony_ci				 * With command in flight, we can't do
151662306a36Sopenharmony_ci				 * sff_irq_clear() w/o racing with completion.
151762306a36Sopenharmony_ci				 */
151862306a36Sopenharmony_ci			}
151962306a36Sopenharmony_ci		}
152062306a36Sopenharmony_ci
152162306a36Sopenharmony_ci		if (retry) {
152262306a36Sopenharmony_ci			retried = true;
152362306a36Sopenharmony_ci			goto retry;
152462306a36Sopenharmony_ci		}
152562306a36Sopenharmony_ci	}
152662306a36Sopenharmony_ci
152762306a36Sopenharmony_ci	spin_unlock_irqrestore(&host->lock, flags);
152862306a36Sopenharmony_ci
152962306a36Sopenharmony_ci	return IRQ_RETVAL(handled);
153062306a36Sopenharmony_ci}
153162306a36Sopenharmony_ci
153262306a36Sopenharmony_ci/**
153362306a36Sopenharmony_ci *	ata_sff_interrupt - Default SFF ATA host interrupt handler
153462306a36Sopenharmony_ci *	@irq: irq line (unused)
153562306a36Sopenharmony_ci *	@dev_instance: pointer to our ata_host information structure
153662306a36Sopenharmony_ci *
153762306a36Sopenharmony_ci *	Default interrupt handler for PCI IDE devices.  Calls
153862306a36Sopenharmony_ci *	ata_sff_port_intr() for each port that is not disabled.
153962306a36Sopenharmony_ci *
154062306a36Sopenharmony_ci *	LOCKING:
154162306a36Sopenharmony_ci *	Obtains host lock during operation.
154262306a36Sopenharmony_ci *
154362306a36Sopenharmony_ci *	RETURNS:
154462306a36Sopenharmony_ci *	IRQ_NONE or IRQ_HANDLED.
154562306a36Sopenharmony_ci */
154662306a36Sopenharmony_ciirqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
154762306a36Sopenharmony_ci{
154862306a36Sopenharmony_ci	return __ata_sff_interrupt(irq, dev_instance, ata_sff_port_intr);
154962306a36Sopenharmony_ci}
155062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_interrupt);
155162306a36Sopenharmony_ci
155262306a36Sopenharmony_ci/**
155362306a36Sopenharmony_ci *	ata_sff_lost_interrupt	-	Check for an apparent lost interrupt
155462306a36Sopenharmony_ci *	@ap: port that appears to have timed out
155562306a36Sopenharmony_ci *
155662306a36Sopenharmony_ci *	Called from the libata error handlers when the core code suspects
155762306a36Sopenharmony_ci *	an interrupt has been lost. If it has complete anything we can and
155862306a36Sopenharmony_ci *	then return. Interface must support altstatus for this faster
155962306a36Sopenharmony_ci *	recovery to occur.
156062306a36Sopenharmony_ci *
156162306a36Sopenharmony_ci *	Locking:
156262306a36Sopenharmony_ci *	Caller holds host lock
156362306a36Sopenharmony_ci */
156462306a36Sopenharmony_ci
156562306a36Sopenharmony_civoid ata_sff_lost_interrupt(struct ata_port *ap)
156662306a36Sopenharmony_ci{
156762306a36Sopenharmony_ci	u8 status = 0;
156862306a36Sopenharmony_ci	struct ata_queued_cmd *qc;
156962306a36Sopenharmony_ci
157062306a36Sopenharmony_ci	/* Only one outstanding command per SFF channel */
157162306a36Sopenharmony_ci	qc = ata_qc_from_tag(ap, ap->link.active_tag);
157262306a36Sopenharmony_ci	/* We cannot lose an interrupt on a non-existent or polled command */
157362306a36Sopenharmony_ci	if (!qc || qc->tf.flags & ATA_TFLAG_POLLING)
157462306a36Sopenharmony_ci		return;
157562306a36Sopenharmony_ci	/* See if the controller thinks it is still busy - if so the command
157662306a36Sopenharmony_ci	   isn't a lost IRQ but is still in progress */
157762306a36Sopenharmony_ci	if (WARN_ON_ONCE(!ata_sff_altstatus(ap, &status)))
157862306a36Sopenharmony_ci		return;
157962306a36Sopenharmony_ci	if (status & ATA_BUSY)
158062306a36Sopenharmony_ci		return;
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_ci	/* There was a command running, we are no longer busy and we have
158362306a36Sopenharmony_ci	   no interrupt. */
158462306a36Sopenharmony_ci	ata_port_warn(ap, "lost interrupt (Status 0x%x)\n", status);
158562306a36Sopenharmony_ci	/* Run the host interrupt logic as if the interrupt had not been
158662306a36Sopenharmony_ci	   lost */
158762306a36Sopenharmony_ci	ata_sff_port_intr(ap, qc);
158862306a36Sopenharmony_ci}
158962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_lost_interrupt);
159062306a36Sopenharmony_ci
159162306a36Sopenharmony_ci/**
159262306a36Sopenharmony_ci *	ata_sff_freeze - Freeze SFF controller port
159362306a36Sopenharmony_ci *	@ap: port to freeze
159462306a36Sopenharmony_ci *
159562306a36Sopenharmony_ci *	Freeze SFF controller port.
159662306a36Sopenharmony_ci *
159762306a36Sopenharmony_ci *	LOCKING:
159862306a36Sopenharmony_ci *	Inherited from caller.
159962306a36Sopenharmony_ci */
160062306a36Sopenharmony_civoid ata_sff_freeze(struct ata_port *ap)
160162306a36Sopenharmony_ci{
160262306a36Sopenharmony_ci	ap->ctl |= ATA_NIEN;
160362306a36Sopenharmony_ci	ap->last_ctl = ap->ctl;
160462306a36Sopenharmony_ci
160562306a36Sopenharmony_ci	ata_sff_set_devctl(ap, ap->ctl);
160662306a36Sopenharmony_ci
160762306a36Sopenharmony_ci	/* Under certain circumstances, some controllers raise IRQ on
160862306a36Sopenharmony_ci	 * ATA_NIEN manipulation.  Also, many controllers fail to mask
160962306a36Sopenharmony_ci	 * previously pending IRQ on ATA_NIEN assertion.  Clear it.
161062306a36Sopenharmony_ci	 */
161162306a36Sopenharmony_ci	ap->ops->sff_check_status(ap);
161262306a36Sopenharmony_ci
161362306a36Sopenharmony_ci	if (ap->ops->sff_irq_clear)
161462306a36Sopenharmony_ci		ap->ops->sff_irq_clear(ap);
161562306a36Sopenharmony_ci}
161662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_freeze);
161762306a36Sopenharmony_ci
161862306a36Sopenharmony_ci/**
161962306a36Sopenharmony_ci *	ata_sff_thaw - Thaw SFF controller port
162062306a36Sopenharmony_ci *	@ap: port to thaw
162162306a36Sopenharmony_ci *
162262306a36Sopenharmony_ci *	Thaw SFF controller port.
162362306a36Sopenharmony_ci *
162462306a36Sopenharmony_ci *	LOCKING:
162562306a36Sopenharmony_ci *	Inherited from caller.
162662306a36Sopenharmony_ci */
162762306a36Sopenharmony_civoid ata_sff_thaw(struct ata_port *ap)
162862306a36Sopenharmony_ci{
162962306a36Sopenharmony_ci	/* clear & re-enable interrupts */
163062306a36Sopenharmony_ci	ap->ops->sff_check_status(ap);
163162306a36Sopenharmony_ci	if (ap->ops->sff_irq_clear)
163262306a36Sopenharmony_ci		ap->ops->sff_irq_clear(ap);
163362306a36Sopenharmony_ci	ata_sff_irq_on(ap);
163462306a36Sopenharmony_ci}
163562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_thaw);
163662306a36Sopenharmony_ci
163762306a36Sopenharmony_ci/**
163862306a36Sopenharmony_ci *	ata_sff_prereset - prepare SFF link for reset
163962306a36Sopenharmony_ci *	@link: SFF link to be reset
164062306a36Sopenharmony_ci *	@deadline: deadline jiffies for the operation
164162306a36Sopenharmony_ci *
164262306a36Sopenharmony_ci *	SFF link @link is about to be reset.  Initialize it.  It first
164362306a36Sopenharmony_ci *	calls ata_std_prereset() and wait for !BSY if the port is
164462306a36Sopenharmony_ci *	being softreset.
164562306a36Sopenharmony_ci *
164662306a36Sopenharmony_ci *	LOCKING:
164762306a36Sopenharmony_ci *	Kernel thread context (may sleep)
164862306a36Sopenharmony_ci *
164962306a36Sopenharmony_ci *	RETURNS:
165062306a36Sopenharmony_ci *	Always 0.
165162306a36Sopenharmony_ci */
165262306a36Sopenharmony_ciint ata_sff_prereset(struct ata_link *link, unsigned long deadline)
165362306a36Sopenharmony_ci{
165462306a36Sopenharmony_ci	struct ata_eh_context *ehc = &link->eh_context;
165562306a36Sopenharmony_ci	int rc;
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ci	/* The standard prereset is best-effort and always returns 0 */
165862306a36Sopenharmony_ci	ata_std_prereset(link, deadline);
165962306a36Sopenharmony_ci
166062306a36Sopenharmony_ci	/* if we're about to do hardreset, nothing more to do */
166162306a36Sopenharmony_ci	if (ehc->i.action & ATA_EH_HARDRESET)
166262306a36Sopenharmony_ci		return 0;
166362306a36Sopenharmony_ci
166462306a36Sopenharmony_ci	/* wait for !BSY if we don't know that no device is attached */
166562306a36Sopenharmony_ci	if (!ata_link_offline(link)) {
166662306a36Sopenharmony_ci		rc = ata_sff_wait_ready(link, deadline);
166762306a36Sopenharmony_ci		if (rc && rc != -ENODEV) {
166862306a36Sopenharmony_ci			ata_link_warn(link,
166962306a36Sopenharmony_ci				      "device not ready (errno=%d), forcing hardreset\n",
167062306a36Sopenharmony_ci				      rc);
167162306a36Sopenharmony_ci			ehc->i.action |= ATA_EH_HARDRESET;
167262306a36Sopenharmony_ci		}
167362306a36Sopenharmony_ci	}
167462306a36Sopenharmony_ci
167562306a36Sopenharmony_ci	return 0;
167662306a36Sopenharmony_ci}
167762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_prereset);
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_ci/**
168062306a36Sopenharmony_ci *	ata_devchk - PATA device presence detection
168162306a36Sopenharmony_ci *	@ap: ATA channel to examine
168262306a36Sopenharmony_ci *	@device: Device to examine (starting at zero)
168362306a36Sopenharmony_ci *
168462306a36Sopenharmony_ci *	This technique was originally described in
168562306a36Sopenharmony_ci *	Hale Landis's ATADRVR (www.ata-atapi.com), and
168662306a36Sopenharmony_ci *	later found its way into the ATA/ATAPI spec.
168762306a36Sopenharmony_ci *
168862306a36Sopenharmony_ci *	Write a pattern to the ATA shadow registers,
168962306a36Sopenharmony_ci *	and if a device is present, it will respond by
169062306a36Sopenharmony_ci *	correctly storing and echoing back the
169162306a36Sopenharmony_ci *	ATA shadow register contents.
169262306a36Sopenharmony_ci *
169362306a36Sopenharmony_ci *	RETURN:
169462306a36Sopenharmony_ci *	true if device is present, false if not.
169562306a36Sopenharmony_ci *
169662306a36Sopenharmony_ci *	LOCKING:
169762306a36Sopenharmony_ci *	caller.
169862306a36Sopenharmony_ci */
169962306a36Sopenharmony_cistatic bool ata_devchk(struct ata_port *ap, unsigned int device)
170062306a36Sopenharmony_ci{
170162306a36Sopenharmony_ci	struct ata_ioports *ioaddr = &ap->ioaddr;
170262306a36Sopenharmony_ci	u8 nsect, lbal;
170362306a36Sopenharmony_ci
170462306a36Sopenharmony_ci	ap->ops->sff_dev_select(ap, device);
170562306a36Sopenharmony_ci
170662306a36Sopenharmony_ci	iowrite8(0x55, ioaddr->nsect_addr);
170762306a36Sopenharmony_ci	iowrite8(0xaa, ioaddr->lbal_addr);
170862306a36Sopenharmony_ci
170962306a36Sopenharmony_ci	iowrite8(0xaa, ioaddr->nsect_addr);
171062306a36Sopenharmony_ci	iowrite8(0x55, ioaddr->lbal_addr);
171162306a36Sopenharmony_ci
171262306a36Sopenharmony_ci	iowrite8(0x55, ioaddr->nsect_addr);
171362306a36Sopenharmony_ci	iowrite8(0xaa, ioaddr->lbal_addr);
171462306a36Sopenharmony_ci
171562306a36Sopenharmony_ci	nsect = ioread8(ioaddr->nsect_addr);
171662306a36Sopenharmony_ci	lbal = ioread8(ioaddr->lbal_addr);
171762306a36Sopenharmony_ci
171862306a36Sopenharmony_ci	if ((nsect == 0x55) && (lbal == 0xaa))
171962306a36Sopenharmony_ci		return true;	/* we found a device */
172062306a36Sopenharmony_ci
172162306a36Sopenharmony_ci	return false;		/* nothing found */
172262306a36Sopenharmony_ci}
172362306a36Sopenharmony_ci
172462306a36Sopenharmony_ci/**
172562306a36Sopenharmony_ci *	ata_sff_dev_classify - Parse returned ATA device signature
172662306a36Sopenharmony_ci *	@dev: ATA device to classify (starting at zero)
172762306a36Sopenharmony_ci *	@present: device seems present
172862306a36Sopenharmony_ci *	@r_err: Value of error register on completion
172962306a36Sopenharmony_ci *
173062306a36Sopenharmony_ci *	After an event -- SRST, E.D.D., or SATA COMRESET -- occurs,
173162306a36Sopenharmony_ci *	an ATA/ATAPI-defined set of values is placed in the ATA
173262306a36Sopenharmony_ci *	shadow registers, indicating the results of device detection
173362306a36Sopenharmony_ci *	and diagnostics.
173462306a36Sopenharmony_ci *
173562306a36Sopenharmony_ci *	Select the ATA device, and read the values from the ATA shadow
173662306a36Sopenharmony_ci *	registers.  Then parse according to the Error register value,
173762306a36Sopenharmony_ci *	and the spec-defined values examined by ata_dev_classify().
173862306a36Sopenharmony_ci *
173962306a36Sopenharmony_ci *	LOCKING:
174062306a36Sopenharmony_ci *	caller.
174162306a36Sopenharmony_ci *
174262306a36Sopenharmony_ci *	RETURNS:
174362306a36Sopenharmony_ci *	Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE.
174462306a36Sopenharmony_ci */
174562306a36Sopenharmony_ciunsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
174662306a36Sopenharmony_ci				  u8 *r_err)
174762306a36Sopenharmony_ci{
174862306a36Sopenharmony_ci	struct ata_port *ap = dev->link->ap;
174962306a36Sopenharmony_ci	struct ata_taskfile tf;
175062306a36Sopenharmony_ci	unsigned int class;
175162306a36Sopenharmony_ci	u8 err;
175262306a36Sopenharmony_ci
175362306a36Sopenharmony_ci	ap->ops->sff_dev_select(ap, dev->devno);
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_ci	memset(&tf, 0, sizeof(tf));
175662306a36Sopenharmony_ci
175762306a36Sopenharmony_ci	ap->ops->sff_tf_read(ap, &tf);
175862306a36Sopenharmony_ci	err = tf.error;
175962306a36Sopenharmony_ci	if (r_err)
176062306a36Sopenharmony_ci		*r_err = err;
176162306a36Sopenharmony_ci
176262306a36Sopenharmony_ci	/* see if device passed diags: continue and warn later */
176362306a36Sopenharmony_ci	if (err == 0)
176462306a36Sopenharmony_ci		/* diagnostic fail : do nothing _YET_ */
176562306a36Sopenharmony_ci		dev->horkage |= ATA_HORKAGE_DIAGNOSTIC;
176662306a36Sopenharmony_ci	else if (err == 1)
176762306a36Sopenharmony_ci		/* do nothing */ ;
176862306a36Sopenharmony_ci	else if ((dev->devno == 0) && (err == 0x81))
176962306a36Sopenharmony_ci		/* do nothing */ ;
177062306a36Sopenharmony_ci	else
177162306a36Sopenharmony_ci		return ATA_DEV_NONE;
177262306a36Sopenharmony_ci
177362306a36Sopenharmony_ci	/* determine if device is ATA or ATAPI */
177462306a36Sopenharmony_ci	class = ata_port_classify(ap, &tf);
177562306a36Sopenharmony_ci	switch (class) {
177662306a36Sopenharmony_ci	case ATA_DEV_UNKNOWN:
177762306a36Sopenharmony_ci		/*
177862306a36Sopenharmony_ci		 * If the device failed diagnostic, it's likely to
177962306a36Sopenharmony_ci		 * have reported incorrect device signature too.
178062306a36Sopenharmony_ci		 * Assume ATA device if the device seems present but
178162306a36Sopenharmony_ci		 * device signature is invalid with diagnostic
178262306a36Sopenharmony_ci		 * failure.
178362306a36Sopenharmony_ci		 */
178462306a36Sopenharmony_ci		if (present && (dev->horkage & ATA_HORKAGE_DIAGNOSTIC))
178562306a36Sopenharmony_ci			class = ATA_DEV_ATA;
178662306a36Sopenharmony_ci		else
178762306a36Sopenharmony_ci			class = ATA_DEV_NONE;
178862306a36Sopenharmony_ci		break;
178962306a36Sopenharmony_ci	case ATA_DEV_ATA:
179062306a36Sopenharmony_ci		if (ap->ops->sff_check_status(ap) == 0)
179162306a36Sopenharmony_ci			class = ATA_DEV_NONE;
179262306a36Sopenharmony_ci		break;
179362306a36Sopenharmony_ci	}
179462306a36Sopenharmony_ci	return class;
179562306a36Sopenharmony_ci}
179662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_dev_classify);
179762306a36Sopenharmony_ci
179862306a36Sopenharmony_ci/**
179962306a36Sopenharmony_ci *	ata_sff_wait_after_reset - wait for devices to become ready after reset
180062306a36Sopenharmony_ci *	@link: SFF link which is just reset
180162306a36Sopenharmony_ci *	@devmask: mask of present devices
180262306a36Sopenharmony_ci *	@deadline: deadline jiffies for the operation
180362306a36Sopenharmony_ci *
180462306a36Sopenharmony_ci *	Wait devices attached to SFF @link to become ready after
180562306a36Sopenharmony_ci *	reset.  It contains preceding 150ms wait to avoid accessing TF
180662306a36Sopenharmony_ci *	status register too early.
180762306a36Sopenharmony_ci *
180862306a36Sopenharmony_ci *	LOCKING:
180962306a36Sopenharmony_ci *	Kernel thread context (may sleep).
181062306a36Sopenharmony_ci *
181162306a36Sopenharmony_ci *	RETURNS:
181262306a36Sopenharmony_ci *	0 on success, -ENODEV if some or all of devices in @devmask
181362306a36Sopenharmony_ci *	don't seem to exist.  -errno on other errors.
181462306a36Sopenharmony_ci */
181562306a36Sopenharmony_ciint ata_sff_wait_after_reset(struct ata_link *link, unsigned int devmask,
181662306a36Sopenharmony_ci			     unsigned long deadline)
181762306a36Sopenharmony_ci{
181862306a36Sopenharmony_ci	struct ata_port *ap = link->ap;
181962306a36Sopenharmony_ci	struct ata_ioports *ioaddr = &ap->ioaddr;
182062306a36Sopenharmony_ci	unsigned int dev0 = devmask & (1 << 0);
182162306a36Sopenharmony_ci	unsigned int dev1 = devmask & (1 << 1);
182262306a36Sopenharmony_ci	int rc, ret = 0;
182362306a36Sopenharmony_ci
182462306a36Sopenharmony_ci	ata_msleep(ap, ATA_WAIT_AFTER_RESET);
182562306a36Sopenharmony_ci
182662306a36Sopenharmony_ci	/* always check readiness of the master device */
182762306a36Sopenharmony_ci	rc = ata_sff_wait_ready(link, deadline);
182862306a36Sopenharmony_ci	/* -ENODEV means the odd clown forgot the D7 pulldown resistor
182962306a36Sopenharmony_ci	 * and TF status is 0xff, bail out on it too.
183062306a36Sopenharmony_ci	 */
183162306a36Sopenharmony_ci	if (rc)
183262306a36Sopenharmony_ci		return rc;
183362306a36Sopenharmony_ci
183462306a36Sopenharmony_ci	/* if device 1 was found in ata_devchk, wait for register
183562306a36Sopenharmony_ci	 * access briefly, then wait for BSY to clear.
183662306a36Sopenharmony_ci	 */
183762306a36Sopenharmony_ci	if (dev1) {
183862306a36Sopenharmony_ci		int i;
183962306a36Sopenharmony_ci
184062306a36Sopenharmony_ci		ap->ops->sff_dev_select(ap, 1);
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci		/* Wait for register access.  Some ATAPI devices fail
184362306a36Sopenharmony_ci		 * to set nsect/lbal after reset, so don't waste too
184462306a36Sopenharmony_ci		 * much time on it.  We're gonna wait for !BSY anyway.
184562306a36Sopenharmony_ci		 */
184662306a36Sopenharmony_ci		for (i = 0; i < 2; i++) {
184762306a36Sopenharmony_ci			u8 nsect, lbal;
184862306a36Sopenharmony_ci
184962306a36Sopenharmony_ci			nsect = ioread8(ioaddr->nsect_addr);
185062306a36Sopenharmony_ci			lbal = ioread8(ioaddr->lbal_addr);
185162306a36Sopenharmony_ci			if ((nsect == 1) && (lbal == 1))
185262306a36Sopenharmony_ci				break;
185362306a36Sopenharmony_ci			ata_msleep(ap, 50);	/* give drive a breather */
185462306a36Sopenharmony_ci		}
185562306a36Sopenharmony_ci
185662306a36Sopenharmony_ci		rc = ata_sff_wait_ready(link, deadline);
185762306a36Sopenharmony_ci		if (rc) {
185862306a36Sopenharmony_ci			if (rc != -ENODEV)
185962306a36Sopenharmony_ci				return rc;
186062306a36Sopenharmony_ci			ret = rc;
186162306a36Sopenharmony_ci		}
186262306a36Sopenharmony_ci	}
186362306a36Sopenharmony_ci
186462306a36Sopenharmony_ci	/* is all this really necessary? */
186562306a36Sopenharmony_ci	ap->ops->sff_dev_select(ap, 0);
186662306a36Sopenharmony_ci	if (dev1)
186762306a36Sopenharmony_ci		ap->ops->sff_dev_select(ap, 1);
186862306a36Sopenharmony_ci	if (dev0)
186962306a36Sopenharmony_ci		ap->ops->sff_dev_select(ap, 0);
187062306a36Sopenharmony_ci
187162306a36Sopenharmony_ci	return ret;
187262306a36Sopenharmony_ci}
187362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_wait_after_reset);
187462306a36Sopenharmony_ci
187562306a36Sopenharmony_cistatic int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
187662306a36Sopenharmony_ci			     unsigned long deadline)
187762306a36Sopenharmony_ci{
187862306a36Sopenharmony_ci	struct ata_ioports *ioaddr = &ap->ioaddr;
187962306a36Sopenharmony_ci
188062306a36Sopenharmony_ci	if (ap->ioaddr.ctl_addr) {
188162306a36Sopenharmony_ci		/* software reset.  causes dev0 to be selected */
188262306a36Sopenharmony_ci		iowrite8(ap->ctl, ioaddr->ctl_addr);
188362306a36Sopenharmony_ci		udelay(20);	/* FIXME: flush */
188462306a36Sopenharmony_ci		iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
188562306a36Sopenharmony_ci		udelay(20);	/* FIXME: flush */
188662306a36Sopenharmony_ci		iowrite8(ap->ctl, ioaddr->ctl_addr);
188762306a36Sopenharmony_ci		ap->last_ctl = ap->ctl;
188862306a36Sopenharmony_ci	}
188962306a36Sopenharmony_ci
189062306a36Sopenharmony_ci	/* wait the port to become ready */
189162306a36Sopenharmony_ci	return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
189262306a36Sopenharmony_ci}
189362306a36Sopenharmony_ci
189462306a36Sopenharmony_ci/**
189562306a36Sopenharmony_ci *	ata_sff_softreset - reset host port via ATA SRST
189662306a36Sopenharmony_ci *	@link: ATA link to reset
189762306a36Sopenharmony_ci *	@classes: resulting classes of attached devices
189862306a36Sopenharmony_ci *	@deadline: deadline jiffies for the operation
189962306a36Sopenharmony_ci *
190062306a36Sopenharmony_ci *	Reset host port using ATA SRST.
190162306a36Sopenharmony_ci *
190262306a36Sopenharmony_ci *	LOCKING:
190362306a36Sopenharmony_ci *	Kernel thread context (may sleep)
190462306a36Sopenharmony_ci *
190562306a36Sopenharmony_ci *	RETURNS:
190662306a36Sopenharmony_ci *	0 on success, -errno otherwise.
190762306a36Sopenharmony_ci */
190862306a36Sopenharmony_ciint ata_sff_softreset(struct ata_link *link, unsigned int *classes,
190962306a36Sopenharmony_ci		      unsigned long deadline)
191062306a36Sopenharmony_ci{
191162306a36Sopenharmony_ci	struct ata_port *ap = link->ap;
191262306a36Sopenharmony_ci	unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
191362306a36Sopenharmony_ci	unsigned int devmask = 0;
191462306a36Sopenharmony_ci	int rc;
191562306a36Sopenharmony_ci	u8 err;
191662306a36Sopenharmony_ci
191762306a36Sopenharmony_ci	/* determine if device 0/1 are present */
191862306a36Sopenharmony_ci	if (ata_devchk(ap, 0))
191962306a36Sopenharmony_ci		devmask |= (1 << 0);
192062306a36Sopenharmony_ci	if (slave_possible && ata_devchk(ap, 1))
192162306a36Sopenharmony_ci		devmask |= (1 << 1);
192262306a36Sopenharmony_ci
192362306a36Sopenharmony_ci	/* select device 0 again */
192462306a36Sopenharmony_ci	ap->ops->sff_dev_select(ap, 0);
192562306a36Sopenharmony_ci
192662306a36Sopenharmony_ci	/* issue bus reset */
192762306a36Sopenharmony_ci	rc = ata_bus_softreset(ap, devmask, deadline);
192862306a36Sopenharmony_ci	/* if link is occupied, -ENODEV too is an error */
192962306a36Sopenharmony_ci	if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
193062306a36Sopenharmony_ci		ata_link_err(link, "SRST failed (errno=%d)\n", rc);
193162306a36Sopenharmony_ci		return rc;
193262306a36Sopenharmony_ci	}
193362306a36Sopenharmony_ci
193462306a36Sopenharmony_ci	/* determine by signature whether we have ATA or ATAPI devices */
193562306a36Sopenharmony_ci	classes[0] = ata_sff_dev_classify(&link->device[0],
193662306a36Sopenharmony_ci					  devmask & (1 << 0), &err);
193762306a36Sopenharmony_ci	if (slave_possible && err != 0x81)
193862306a36Sopenharmony_ci		classes[1] = ata_sff_dev_classify(&link->device[1],
193962306a36Sopenharmony_ci						  devmask & (1 << 1), &err);
194062306a36Sopenharmony_ci
194162306a36Sopenharmony_ci	return 0;
194262306a36Sopenharmony_ci}
194362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_softreset);
194462306a36Sopenharmony_ci
194562306a36Sopenharmony_ci/**
194662306a36Sopenharmony_ci *	sata_sff_hardreset - reset host port via SATA phy reset
194762306a36Sopenharmony_ci *	@link: link to reset
194862306a36Sopenharmony_ci *	@class: resulting class of attached device
194962306a36Sopenharmony_ci *	@deadline: deadline jiffies for the operation
195062306a36Sopenharmony_ci *
195162306a36Sopenharmony_ci *	SATA phy-reset host port using DET bits of SControl register,
195262306a36Sopenharmony_ci *	wait for !BSY and classify the attached device.
195362306a36Sopenharmony_ci *
195462306a36Sopenharmony_ci *	LOCKING:
195562306a36Sopenharmony_ci *	Kernel thread context (may sleep)
195662306a36Sopenharmony_ci *
195762306a36Sopenharmony_ci *	RETURNS:
195862306a36Sopenharmony_ci *	0 on success, -errno otherwise.
195962306a36Sopenharmony_ci */
196062306a36Sopenharmony_ciint sata_sff_hardreset(struct ata_link *link, unsigned int *class,
196162306a36Sopenharmony_ci		       unsigned long deadline)
196262306a36Sopenharmony_ci{
196362306a36Sopenharmony_ci	struct ata_eh_context *ehc = &link->eh_context;
196462306a36Sopenharmony_ci	const unsigned int *timing = sata_ehc_deb_timing(ehc);
196562306a36Sopenharmony_ci	bool online;
196662306a36Sopenharmony_ci	int rc;
196762306a36Sopenharmony_ci
196862306a36Sopenharmony_ci	rc = sata_link_hardreset(link, timing, deadline, &online,
196962306a36Sopenharmony_ci				 ata_sff_check_ready);
197062306a36Sopenharmony_ci	if (online)
197162306a36Sopenharmony_ci		*class = ata_sff_dev_classify(link->device, 1, NULL);
197262306a36Sopenharmony_ci
197362306a36Sopenharmony_ci	return rc;
197462306a36Sopenharmony_ci}
197562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(sata_sff_hardreset);
197662306a36Sopenharmony_ci
197762306a36Sopenharmony_ci/**
197862306a36Sopenharmony_ci *	ata_sff_postreset - SFF postreset callback
197962306a36Sopenharmony_ci *	@link: the target SFF ata_link
198062306a36Sopenharmony_ci *	@classes: classes of attached devices
198162306a36Sopenharmony_ci *
198262306a36Sopenharmony_ci *	This function is invoked after a successful reset.  It first
198362306a36Sopenharmony_ci *	calls ata_std_postreset() and performs SFF specific postreset
198462306a36Sopenharmony_ci *	processing.
198562306a36Sopenharmony_ci *
198662306a36Sopenharmony_ci *	LOCKING:
198762306a36Sopenharmony_ci *	Kernel thread context (may sleep)
198862306a36Sopenharmony_ci */
198962306a36Sopenharmony_civoid ata_sff_postreset(struct ata_link *link, unsigned int *classes)
199062306a36Sopenharmony_ci{
199162306a36Sopenharmony_ci	struct ata_port *ap = link->ap;
199262306a36Sopenharmony_ci
199362306a36Sopenharmony_ci	ata_std_postreset(link, classes);
199462306a36Sopenharmony_ci
199562306a36Sopenharmony_ci	/* is double-select really necessary? */
199662306a36Sopenharmony_ci	if (classes[0] != ATA_DEV_NONE)
199762306a36Sopenharmony_ci		ap->ops->sff_dev_select(ap, 1);
199862306a36Sopenharmony_ci	if (classes[1] != ATA_DEV_NONE)
199962306a36Sopenharmony_ci		ap->ops->sff_dev_select(ap, 0);
200062306a36Sopenharmony_ci
200162306a36Sopenharmony_ci	/* bail out if no device is present */
200262306a36Sopenharmony_ci	if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE)
200362306a36Sopenharmony_ci		return;
200462306a36Sopenharmony_ci
200562306a36Sopenharmony_ci	/* set up device control */
200662306a36Sopenharmony_ci	if (ata_sff_set_devctl(ap, ap->ctl))
200762306a36Sopenharmony_ci		ap->last_ctl = ap->ctl;
200862306a36Sopenharmony_ci}
200962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_postreset);
201062306a36Sopenharmony_ci
201162306a36Sopenharmony_ci/**
201262306a36Sopenharmony_ci *	ata_sff_drain_fifo - Stock FIFO drain logic for SFF controllers
201362306a36Sopenharmony_ci *	@qc: command
201462306a36Sopenharmony_ci *
201562306a36Sopenharmony_ci *	Drain the FIFO and device of any stuck data following a command
201662306a36Sopenharmony_ci *	failing to complete. In some cases this is necessary before a
201762306a36Sopenharmony_ci *	reset will recover the device.
201862306a36Sopenharmony_ci *
201962306a36Sopenharmony_ci */
202062306a36Sopenharmony_ci
202162306a36Sopenharmony_civoid ata_sff_drain_fifo(struct ata_queued_cmd *qc)
202262306a36Sopenharmony_ci{
202362306a36Sopenharmony_ci	int count;
202462306a36Sopenharmony_ci	struct ata_port *ap;
202562306a36Sopenharmony_ci
202662306a36Sopenharmony_ci	/* We only need to flush incoming data when a command was running */
202762306a36Sopenharmony_ci	if (qc == NULL || qc->dma_dir == DMA_TO_DEVICE)
202862306a36Sopenharmony_ci		return;
202962306a36Sopenharmony_ci
203062306a36Sopenharmony_ci	ap = qc->ap;
203162306a36Sopenharmony_ci	/* Drain up to 64K of data before we give up this recovery method */
203262306a36Sopenharmony_ci	for (count = 0; (ap->ops->sff_check_status(ap) & ATA_DRQ)
203362306a36Sopenharmony_ci						&& count < 65536; count += 2)
203462306a36Sopenharmony_ci		ioread16(ap->ioaddr.data_addr);
203562306a36Sopenharmony_ci
203662306a36Sopenharmony_ci	if (count)
203762306a36Sopenharmony_ci		ata_port_dbg(ap, "drained %d bytes to clear DRQ\n", count);
203862306a36Sopenharmony_ci
203962306a36Sopenharmony_ci}
204062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_drain_fifo);
204162306a36Sopenharmony_ci
204262306a36Sopenharmony_ci/**
204362306a36Sopenharmony_ci *	ata_sff_error_handler - Stock error handler for SFF controller
204462306a36Sopenharmony_ci *	@ap: port to handle error for
204562306a36Sopenharmony_ci *
204662306a36Sopenharmony_ci *	Stock error handler for SFF controller.  It can handle both
204762306a36Sopenharmony_ci *	PATA and SATA controllers.  Many controllers should be able to
204862306a36Sopenharmony_ci *	use this EH as-is or with some added handling before and
204962306a36Sopenharmony_ci *	after.
205062306a36Sopenharmony_ci *
205162306a36Sopenharmony_ci *	LOCKING:
205262306a36Sopenharmony_ci *	Kernel thread context (may sleep)
205362306a36Sopenharmony_ci */
205462306a36Sopenharmony_civoid ata_sff_error_handler(struct ata_port *ap)
205562306a36Sopenharmony_ci{
205662306a36Sopenharmony_ci	ata_reset_fn_t softreset = ap->ops->softreset;
205762306a36Sopenharmony_ci	ata_reset_fn_t hardreset = ap->ops->hardreset;
205862306a36Sopenharmony_ci	struct ata_queued_cmd *qc;
205962306a36Sopenharmony_ci	unsigned long flags;
206062306a36Sopenharmony_ci
206162306a36Sopenharmony_ci	qc = __ata_qc_from_tag(ap, ap->link.active_tag);
206262306a36Sopenharmony_ci	if (qc && !(qc->flags & ATA_QCFLAG_EH))
206362306a36Sopenharmony_ci		qc = NULL;
206462306a36Sopenharmony_ci
206562306a36Sopenharmony_ci	spin_lock_irqsave(ap->lock, flags);
206662306a36Sopenharmony_ci
206762306a36Sopenharmony_ci	/*
206862306a36Sopenharmony_ci	 * We *MUST* do FIFO draining before we issue a reset as
206962306a36Sopenharmony_ci	 * several devices helpfully clear their internal state and
207062306a36Sopenharmony_ci	 * will lock solid if we touch the data port post reset. Pass
207162306a36Sopenharmony_ci	 * qc in case anyone wants to do different PIO/DMA recovery or
207262306a36Sopenharmony_ci	 * has per command fixups
207362306a36Sopenharmony_ci	 */
207462306a36Sopenharmony_ci	if (ap->ops->sff_drain_fifo)
207562306a36Sopenharmony_ci		ap->ops->sff_drain_fifo(qc);
207662306a36Sopenharmony_ci
207762306a36Sopenharmony_ci	spin_unlock_irqrestore(ap->lock, flags);
207862306a36Sopenharmony_ci
207962306a36Sopenharmony_ci	/* ignore built-in hardresets if SCR access is not available */
208062306a36Sopenharmony_ci	if ((hardreset == sata_std_hardreset ||
208162306a36Sopenharmony_ci	     hardreset == sata_sff_hardreset) && !sata_scr_valid(&ap->link))
208262306a36Sopenharmony_ci		hardreset = NULL;
208362306a36Sopenharmony_ci
208462306a36Sopenharmony_ci	ata_do_eh(ap, ap->ops->prereset, softreset, hardreset,
208562306a36Sopenharmony_ci		  ap->ops->postreset);
208662306a36Sopenharmony_ci}
208762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_error_handler);
208862306a36Sopenharmony_ci
208962306a36Sopenharmony_ci/**
209062306a36Sopenharmony_ci *	ata_sff_std_ports - initialize ioaddr with standard port offsets.
209162306a36Sopenharmony_ci *	@ioaddr: IO address structure to be initialized
209262306a36Sopenharmony_ci *
209362306a36Sopenharmony_ci *	Utility function which initializes data_addr, error_addr,
209462306a36Sopenharmony_ci *	feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
209562306a36Sopenharmony_ci *	device_addr, status_addr, and command_addr to standard offsets
209662306a36Sopenharmony_ci *	relative to cmd_addr.
209762306a36Sopenharmony_ci *
209862306a36Sopenharmony_ci *	Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
209962306a36Sopenharmony_ci */
210062306a36Sopenharmony_civoid ata_sff_std_ports(struct ata_ioports *ioaddr)
210162306a36Sopenharmony_ci{
210262306a36Sopenharmony_ci	ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
210362306a36Sopenharmony_ci	ioaddr->error_addr = ioaddr->cmd_addr + ATA_REG_ERR;
210462306a36Sopenharmony_ci	ioaddr->feature_addr = ioaddr->cmd_addr + ATA_REG_FEATURE;
210562306a36Sopenharmony_ci	ioaddr->nsect_addr = ioaddr->cmd_addr + ATA_REG_NSECT;
210662306a36Sopenharmony_ci	ioaddr->lbal_addr = ioaddr->cmd_addr + ATA_REG_LBAL;
210762306a36Sopenharmony_ci	ioaddr->lbam_addr = ioaddr->cmd_addr + ATA_REG_LBAM;
210862306a36Sopenharmony_ci	ioaddr->lbah_addr = ioaddr->cmd_addr + ATA_REG_LBAH;
210962306a36Sopenharmony_ci	ioaddr->device_addr = ioaddr->cmd_addr + ATA_REG_DEVICE;
211062306a36Sopenharmony_ci	ioaddr->status_addr = ioaddr->cmd_addr + ATA_REG_STATUS;
211162306a36Sopenharmony_ci	ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD;
211262306a36Sopenharmony_ci}
211362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sff_std_ports);
211462306a36Sopenharmony_ci
211562306a36Sopenharmony_ci#ifdef CONFIG_PCI
211662306a36Sopenharmony_ci
211762306a36Sopenharmony_cistatic bool ata_resources_present(struct pci_dev *pdev, int port)
211862306a36Sopenharmony_ci{
211962306a36Sopenharmony_ci	int i;
212062306a36Sopenharmony_ci
212162306a36Sopenharmony_ci	/* Check the PCI resources for this channel are enabled */
212262306a36Sopenharmony_ci	port *= 2;
212362306a36Sopenharmony_ci	for (i = 0; i < 2; i++) {
212462306a36Sopenharmony_ci		if (pci_resource_start(pdev, port + i) == 0 ||
212562306a36Sopenharmony_ci		    pci_resource_len(pdev, port + i) == 0)
212662306a36Sopenharmony_ci			return false;
212762306a36Sopenharmony_ci	}
212862306a36Sopenharmony_ci	return true;
212962306a36Sopenharmony_ci}
213062306a36Sopenharmony_ci
213162306a36Sopenharmony_ci/**
213262306a36Sopenharmony_ci *	ata_pci_sff_init_host - acquire native PCI ATA resources and init host
213362306a36Sopenharmony_ci *	@host: target ATA host
213462306a36Sopenharmony_ci *
213562306a36Sopenharmony_ci *	Acquire native PCI ATA resources for @host and initialize the
213662306a36Sopenharmony_ci *	first two ports of @host accordingly.  Ports marked dummy are
213762306a36Sopenharmony_ci *	skipped and allocation failure makes the port dummy.
213862306a36Sopenharmony_ci *
213962306a36Sopenharmony_ci *	Note that native PCI resources are valid even for legacy hosts
214062306a36Sopenharmony_ci *	as we fix up pdev resources array early in boot, so this
214162306a36Sopenharmony_ci *	function can be used for both native and legacy SFF hosts.
214262306a36Sopenharmony_ci *
214362306a36Sopenharmony_ci *	LOCKING:
214462306a36Sopenharmony_ci *	Inherited from calling layer (may sleep).
214562306a36Sopenharmony_ci *
214662306a36Sopenharmony_ci *	RETURNS:
214762306a36Sopenharmony_ci *	0 if at least one port is initialized, -ENODEV if no port is
214862306a36Sopenharmony_ci *	available.
214962306a36Sopenharmony_ci */
215062306a36Sopenharmony_ciint ata_pci_sff_init_host(struct ata_host *host)
215162306a36Sopenharmony_ci{
215262306a36Sopenharmony_ci	struct device *gdev = host->dev;
215362306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(gdev);
215462306a36Sopenharmony_ci	unsigned int mask = 0;
215562306a36Sopenharmony_ci	int i, rc;
215662306a36Sopenharmony_ci
215762306a36Sopenharmony_ci	/* request, iomap BARs and init port addresses accordingly */
215862306a36Sopenharmony_ci	for (i = 0; i < 2; i++) {
215962306a36Sopenharmony_ci		struct ata_port *ap = host->ports[i];
216062306a36Sopenharmony_ci		int base = i * 2;
216162306a36Sopenharmony_ci		void __iomem * const *iomap;
216262306a36Sopenharmony_ci
216362306a36Sopenharmony_ci		if (ata_port_is_dummy(ap))
216462306a36Sopenharmony_ci			continue;
216562306a36Sopenharmony_ci
216662306a36Sopenharmony_ci		/* Discard disabled ports.  Some controllers show
216762306a36Sopenharmony_ci		 * their unused channels this way.  Disabled ports are
216862306a36Sopenharmony_ci		 * made dummy.
216962306a36Sopenharmony_ci		 */
217062306a36Sopenharmony_ci		if (!ata_resources_present(pdev, i)) {
217162306a36Sopenharmony_ci			ap->ops = &ata_dummy_port_ops;
217262306a36Sopenharmony_ci			continue;
217362306a36Sopenharmony_ci		}
217462306a36Sopenharmony_ci
217562306a36Sopenharmony_ci		rc = pcim_iomap_regions(pdev, 0x3 << base,
217662306a36Sopenharmony_ci					dev_driver_string(gdev));
217762306a36Sopenharmony_ci		if (rc) {
217862306a36Sopenharmony_ci			dev_warn(gdev,
217962306a36Sopenharmony_ci				 "failed to request/iomap BARs for port %d (errno=%d)\n",
218062306a36Sopenharmony_ci				 i, rc);
218162306a36Sopenharmony_ci			if (rc == -EBUSY)
218262306a36Sopenharmony_ci				pcim_pin_device(pdev);
218362306a36Sopenharmony_ci			ap->ops = &ata_dummy_port_ops;
218462306a36Sopenharmony_ci			continue;
218562306a36Sopenharmony_ci		}
218662306a36Sopenharmony_ci		host->iomap = iomap = pcim_iomap_table(pdev);
218762306a36Sopenharmony_ci
218862306a36Sopenharmony_ci		ap->ioaddr.cmd_addr = iomap[base];
218962306a36Sopenharmony_ci		ap->ioaddr.altstatus_addr =
219062306a36Sopenharmony_ci		ap->ioaddr.ctl_addr = (void __iomem *)
219162306a36Sopenharmony_ci			((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
219262306a36Sopenharmony_ci		ata_sff_std_ports(&ap->ioaddr);
219362306a36Sopenharmony_ci
219462306a36Sopenharmony_ci		ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
219562306a36Sopenharmony_ci			(unsigned long long)pci_resource_start(pdev, base),
219662306a36Sopenharmony_ci			(unsigned long long)pci_resource_start(pdev, base + 1));
219762306a36Sopenharmony_ci
219862306a36Sopenharmony_ci		mask |= 1 << i;
219962306a36Sopenharmony_ci	}
220062306a36Sopenharmony_ci
220162306a36Sopenharmony_ci	if (!mask) {
220262306a36Sopenharmony_ci		dev_err(gdev, "no available native port\n");
220362306a36Sopenharmony_ci		return -ENODEV;
220462306a36Sopenharmony_ci	}
220562306a36Sopenharmony_ci
220662306a36Sopenharmony_ci	return 0;
220762306a36Sopenharmony_ci}
220862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_pci_sff_init_host);
220962306a36Sopenharmony_ci
221062306a36Sopenharmony_ci/**
221162306a36Sopenharmony_ci *	ata_pci_sff_prepare_host - helper to prepare PCI PIO-only SFF ATA host
221262306a36Sopenharmony_ci *	@pdev: target PCI device
221362306a36Sopenharmony_ci *	@ppi: array of port_info, must be enough for two ports
221462306a36Sopenharmony_ci *	@r_host: out argument for the initialized ATA host
221562306a36Sopenharmony_ci *
221662306a36Sopenharmony_ci *	Helper to allocate PIO-only SFF ATA host for @pdev, acquire
221762306a36Sopenharmony_ci *	all PCI resources and initialize it accordingly in one go.
221862306a36Sopenharmony_ci *
221962306a36Sopenharmony_ci *	LOCKING:
222062306a36Sopenharmony_ci *	Inherited from calling layer (may sleep).
222162306a36Sopenharmony_ci *
222262306a36Sopenharmony_ci *	RETURNS:
222362306a36Sopenharmony_ci *	0 on success, -errno otherwise.
222462306a36Sopenharmony_ci */
222562306a36Sopenharmony_ciint ata_pci_sff_prepare_host(struct pci_dev *pdev,
222662306a36Sopenharmony_ci			     const struct ata_port_info * const *ppi,
222762306a36Sopenharmony_ci			     struct ata_host **r_host)
222862306a36Sopenharmony_ci{
222962306a36Sopenharmony_ci	struct ata_host *host;
223062306a36Sopenharmony_ci	int rc;
223162306a36Sopenharmony_ci
223262306a36Sopenharmony_ci	if (!devres_open_group(&pdev->dev, NULL, GFP_KERNEL))
223362306a36Sopenharmony_ci		return -ENOMEM;
223462306a36Sopenharmony_ci
223562306a36Sopenharmony_ci	host = ata_host_alloc_pinfo(&pdev->dev, ppi, 2);
223662306a36Sopenharmony_ci	if (!host) {
223762306a36Sopenharmony_ci		dev_err(&pdev->dev, "failed to allocate ATA host\n");
223862306a36Sopenharmony_ci		rc = -ENOMEM;
223962306a36Sopenharmony_ci		goto err_out;
224062306a36Sopenharmony_ci	}
224162306a36Sopenharmony_ci
224262306a36Sopenharmony_ci	rc = ata_pci_sff_init_host(host);
224362306a36Sopenharmony_ci	if (rc)
224462306a36Sopenharmony_ci		goto err_out;
224562306a36Sopenharmony_ci
224662306a36Sopenharmony_ci	devres_remove_group(&pdev->dev, NULL);
224762306a36Sopenharmony_ci	*r_host = host;
224862306a36Sopenharmony_ci	return 0;
224962306a36Sopenharmony_ci
225062306a36Sopenharmony_cierr_out:
225162306a36Sopenharmony_ci	devres_release_group(&pdev->dev, NULL);
225262306a36Sopenharmony_ci	return rc;
225362306a36Sopenharmony_ci}
225462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_pci_sff_prepare_host);
225562306a36Sopenharmony_ci
225662306a36Sopenharmony_ci/**
225762306a36Sopenharmony_ci *	ata_pci_sff_activate_host - start SFF host, request IRQ and register it
225862306a36Sopenharmony_ci *	@host: target SFF ATA host
225962306a36Sopenharmony_ci *	@irq_handler: irq_handler used when requesting IRQ(s)
226062306a36Sopenharmony_ci *	@sht: scsi_host_template to use when registering the host
226162306a36Sopenharmony_ci *
226262306a36Sopenharmony_ci *	This is the counterpart of ata_host_activate() for SFF ATA
226362306a36Sopenharmony_ci *	hosts.  This separate helper is necessary because SFF hosts
226462306a36Sopenharmony_ci *	use two separate interrupts in legacy mode.
226562306a36Sopenharmony_ci *
226662306a36Sopenharmony_ci *	LOCKING:
226762306a36Sopenharmony_ci *	Inherited from calling layer (may sleep).
226862306a36Sopenharmony_ci *
226962306a36Sopenharmony_ci *	RETURNS:
227062306a36Sopenharmony_ci *	0 on success, -errno otherwise.
227162306a36Sopenharmony_ci */
227262306a36Sopenharmony_ciint ata_pci_sff_activate_host(struct ata_host *host,
227362306a36Sopenharmony_ci			      irq_handler_t irq_handler,
227462306a36Sopenharmony_ci			      const struct scsi_host_template *sht)
227562306a36Sopenharmony_ci{
227662306a36Sopenharmony_ci	struct device *dev = host->dev;
227762306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(dev);
227862306a36Sopenharmony_ci	const char *drv_name = dev_driver_string(host->dev);
227962306a36Sopenharmony_ci	int legacy_mode = 0, rc;
228062306a36Sopenharmony_ci
228162306a36Sopenharmony_ci	rc = ata_host_start(host);
228262306a36Sopenharmony_ci	if (rc)
228362306a36Sopenharmony_ci		return rc;
228462306a36Sopenharmony_ci
228562306a36Sopenharmony_ci	if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
228662306a36Sopenharmony_ci		u8 tmp8, mask = 0;
228762306a36Sopenharmony_ci
228862306a36Sopenharmony_ci		/*
228962306a36Sopenharmony_ci		 * ATA spec says we should use legacy mode when one
229062306a36Sopenharmony_ci		 * port is in legacy mode, but disabled ports on some
229162306a36Sopenharmony_ci		 * PCI hosts appear as fixed legacy ports, e.g SB600/700
229262306a36Sopenharmony_ci		 * on which the secondary port is not wired, so
229362306a36Sopenharmony_ci		 * ignore ports that are marked as 'dummy' during
229462306a36Sopenharmony_ci		 * this check
229562306a36Sopenharmony_ci		 */
229662306a36Sopenharmony_ci		pci_read_config_byte(pdev, PCI_CLASS_PROG, &tmp8);
229762306a36Sopenharmony_ci		if (!ata_port_is_dummy(host->ports[0]))
229862306a36Sopenharmony_ci			mask |= (1 << 0);
229962306a36Sopenharmony_ci		if (!ata_port_is_dummy(host->ports[1]))
230062306a36Sopenharmony_ci			mask |= (1 << 2);
230162306a36Sopenharmony_ci		if ((tmp8 & mask) != mask)
230262306a36Sopenharmony_ci			legacy_mode = 1;
230362306a36Sopenharmony_ci	}
230462306a36Sopenharmony_ci
230562306a36Sopenharmony_ci	if (!devres_open_group(dev, NULL, GFP_KERNEL))
230662306a36Sopenharmony_ci		return -ENOMEM;
230762306a36Sopenharmony_ci
230862306a36Sopenharmony_ci	if (!legacy_mode && pdev->irq) {
230962306a36Sopenharmony_ci		int i;
231062306a36Sopenharmony_ci
231162306a36Sopenharmony_ci		rc = devm_request_irq(dev, pdev->irq, irq_handler,
231262306a36Sopenharmony_ci				      IRQF_SHARED, drv_name, host);
231362306a36Sopenharmony_ci		if (rc)
231462306a36Sopenharmony_ci			goto out;
231562306a36Sopenharmony_ci
231662306a36Sopenharmony_ci		for (i = 0; i < 2; i++) {
231762306a36Sopenharmony_ci			if (ata_port_is_dummy(host->ports[i]))
231862306a36Sopenharmony_ci				continue;
231962306a36Sopenharmony_ci			ata_port_desc(host->ports[i], "irq %d", pdev->irq);
232062306a36Sopenharmony_ci		}
232162306a36Sopenharmony_ci	} else if (legacy_mode) {
232262306a36Sopenharmony_ci		if (!ata_port_is_dummy(host->ports[0])) {
232362306a36Sopenharmony_ci			rc = devm_request_irq(dev, ATA_PRIMARY_IRQ(pdev),
232462306a36Sopenharmony_ci					      irq_handler, IRQF_SHARED,
232562306a36Sopenharmony_ci					      drv_name, host);
232662306a36Sopenharmony_ci			if (rc)
232762306a36Sopenharmony_ci				goto out;
232862306a36Sopenharmony_ci
232962306a36Sopenharmony_ci			ata_port_desc(host->ports[0], "irq %d",
233062306a36Sopenharmony_ci				      ATA_PRIMARY_IRQ(pdev));
233162306a36Sopenharmony_ci		}
233262306a36Sopenharmony_ci
233362306a36Sopenharmony_ci		if (!ata_port_is_dummy(host->ports[1])) {
233462306a36Sopenharmony_ci			rc = devm_request_irq(dev, ATA_SECONDARY_IRQ(pdev),
233562306a36Sopenharmony_ci					      irq_handler, IRQF_SHARED,
233662306a36Sopenharmony_ci					      drv_name, host);
233762306a36Sopenharmony_ci			if (rc)
233862306a36Sopenharmony_ci				goto out;
233962306a36Sopenharmony_ci
234062306a36Sopenharmony_ci			ata_port_desc(host->ports[1], "irq %d",
234162306a36Sopenharmony_ci				      ATA_SECONDARY_IRQ(pdev));
234262306a36Sopenharmony_ci		}
234362306a36Sopenharmony_ci	}
234462306a36Sopenharmony_ci
234562306a36Sopenharmony_ci	rc = ata_host_register(host, sht);
234662306a36Sopenharmony_ciout:
234762306a36Sopenharmony_ci	if (rc == 0)
234862306a36Sopenharmony_ci		devres_remove_group(dev, NULL);
234962306a36Sopenharmony_ci	else
235062306a36Sopenharmony_ci		devres_release_group(dev, NULL);
235162306a36Sopenharmony_ci
235262306a36Sopenharmony_ci	return rc;
235362306a36Sopenharmony_ci}
235462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
235562306a36Sopenharmony_ci
235662306a36Sopenharmony_cistatic const struct ata_port_info *ata_sff_find_valid_pi(
235762306a36Sopenharmony_ci					const struct ata_port_info * const *ppi)
235862306a36Sopenharmony_ci{
235962306a36Sopenharmony_ci	int i;
236062306a36Sopenharmony_ci
236162306a36Sopenharmony_ci	/* look up the first valid port_info */
236262306a36Sopenharmony_ci	for (i = 0; i < 2 && ppi[i]; i++)
236362306a36Sopenharmony_ci		if (ppi[i]->port_ops != &ata_dummy_port_ops)
236462306a36Sopenharmony_ci			return ppi[i];
236562306a36Sopenharmony_ci
236662306a36Sopenharmony_ci	return NULL;
236762306a36Sopenharmony_ci}
236862306a36Sopenharmony_ci
236962306a36Sopenharmony_cistatic int ata_pci_init_one(struct pci_dev *pdev,
237062306a36Sopenharmony_ci		const struct ata_port_info * const *ppi,
237162306a36Sopenharmony_ci		const struct scsi_host_template *sht, void *host_priv,
237262306a36Sopenharmony_ci		int hflags, bool bmdma)
237362306a36Sopenharmony_ci{
237462306a36Sopenharmony_ci	struct device *dev = &pdev->dev;
237562306a36Sopenharmony_ci	const struct ata_port_info *pi;
237662306a36Sopenharmony_ci	struct ata_host *host = NULL;
237762306a36Sopenharmony_ci	int rc;
237862306a36Sopenharmony_ci
237962306a36Sopenharmony_ci	pi = ata_sff_find_valid_pi(ppi);
238062306a36Sopenharmony_ci	if (!pi) {
238162306a36Sopenharmony_ci		dev_err(&pdev->dev, "no valid port_info specified\n");
238262306a36Sopenharmony_ci		return -EINVAL;
238362306a36Sopenharmony_ci	}
238462306a36Sopenharmony_ci
238562306a36Sopenharmony_ci	if (!devres_open_group(dev, NULL, GFP_KERNEL))
238662306a36Sopenharmony_ci		return -ENOMEM;
238762306a36Sopenharmony_ci
238862306a36Sopenharmony_ci	rc = pcim_enable_device(pdev);
238962306a36Sopenharmony_ci	if (rc)
239062306a36Sopenharmony_ci		goto out;
239162306a36Sopenharmony_ci
239262306a36Sopenharmony_ci#ifdef CONFIG_ATA_BMDMA
239362306a36Sopenharmony_ci	if (bmdma)
239462306a36Sopenharmony_ci		/* prepare and activate BMDMA host */
239562306a36Sopenharmony_ci		rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
239662306a36Sopenharmony_ci	else
239762306a36Sopenharmony_ci#endif
239862306a36Sopenharmony_ci		/* prepare and activate SFF host */
239962306a36Sopenharmony_ci		rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
240062306a36Sopenharmony_ci	if (rc)
240162306a36Sopenharmony_ci		goto out;
240262306a36Sopenharmony_ci	host->private_data = host_priv;
240362306a36Sopenharmony_ci	host->flags |= hflags;
240462306a36Sopenharmony_ci
240562306a36Sopenharmony_ci#ifdef CONFIG_ATA_BMDMA
240662306a36Sopenharmony_ci	if (bmdma) {
240762306a36Sopenharmony_ci		pci_set_master(pdev);
240862306a36Sopenharmony_ci		rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
240962306a36Sopenharmony_ci	} else
241062306a36Sopenharmony_ci#endif
241162306a36Sopenharmony_ci		rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
241262306a36Sopenharmony_ciout:
241362306a36Sopenharmony_ci	if (rc == 0)
241462306a36Sopenharmony_ci		devres_remove_group(&pdev->dev, NULL);
241562306a36Sopenharmony_ci	else
241662306a36Sopenharmony_ci		devres_release_group(&pdev->dev, NULL);
241762306a36Sopenharmony_ci
241862306a36Sopenharmony_ci	return rc;
241962306a36Sopenharmony_ci}
242062306a36Sopenharmony_ci
242162306a36Sopenharmony_ci/**
242262306a36Sopenharmony_ci *	ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller
242362306a36Sopenharmony_ci *	@pdev: Controller to be initialized
242462306a36Sopenharmony_ci *	@ppi: array of port_info, must be enough for two ports
242562306a36Sopenharmony_ci *	@sht: scsi_host_template to use when registering the host
242662306a36Sopenharmony_ci *	@host_priv: host private_data
242762306a36Sopenharmony_ci *	@hflag: host flags
242862306a36Sopenharmony_ci *
242962306a36Sopenharmony_ci *	This is a helper function which can be called from a driver's
243062306a36Sopenharmony_ci *	xxx_init_one() probe function if the hardware uses traditional
243162306a36Sopenharmony_ci *	IDE taskfile registers and is PIO only.
243262306a36Sopenharmony_ci *
243362306a36Sopenharmony_ci *	ASSUMPTION:
243462306a36Sopenharmony_ci *	Nobody makes a single channel controller that appears solely as
243562306a36Sopenharmony_ci *	the secondary legacy port on PCI.
243662306a36Sopenharmony_ci *
243762306a36Sopenharmony_ci *	LOCKING:
243862306a36Sopenharmony_ci *	Inherited from PCI layer (may sleep).
243962306a36Sopenharmony_ci *
244062306a36Sopenharmony_ci *	RETURNS:
244162306a36Sopenharmony_ci *	Zero on success, negative on errno-based value on error.
244262306a36Sopenharmony_ci */
244362306a36Sopenharmony_ciint ata_pci_sff_init_one(struct pci_dev *pdev,
244462306a36Sopenharmony_ci		 const struct ata_port_info * const *ppi,
244562306a36Sopenharmony_ci		 const struct scsi_host_template *sht, void *host_priv, int hflag)
244662306a36Sopenharmony_ci{
244762306a36Sopenharmony_ci	return ata_pci_init_one(pdev, ppi, sht, host_priv, hflag, 0);
244862306a36Sopenharmony_ci}
244962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
245062306a36Sopenharmony_ci
245162306a36Sopenharmony_ci#endif /* CONFIG_PCI */
245262306a36Sopenharmony_ci
245362306a36Sopenharmony_ci/*
245462306a36Sopenharmony_ci *	BMDMA support
245562306a36Sopenharmony_ci */
245662306a36Sopenharmony_ci
245762306a36Sopenharmony_ci#ifdef CONFIG_ATA_BMDMA
245862306a36Sopenharmony_ci
245962306a36Sopenharmony_ciconst struct ata_port_operations ata_bmdma_port_ops = {
246062306a36Sopenharmony_ci	.inherits		= &ata_sff_port_ops,
246162306a36Sopenharmony_ci
246262306a36Sopenharmony_ci	.error_handler		= ata_bmdma_error_handler,
246362306a36Sopenharmony_ci	.post_internal_cmd	= ata_bmdma_post_internal_cmd,
246462306a36Sopenharmony_ci
246562306a36Sopenharmony_ci	.qc_prep		= ata_bmdma_qc_prep,
246662306a36Sopenharmony_ci	.qc_issue		= ata_bmdma_qc_issue,
246762306a36Sopenharmony_ci
246862306a36Sopenharmony_ci	.sff_irq_clear		= ata_bmdma_irq_clear,
246962306a36Sopenharmony_ci	.bmdma_setup		= ata_bmdma_setup,
247062306a36Sopenharmony_ci	.bmdma_start		= ata_bmdma_start,
247162306a36Sopenharmony_ci	.bmdma_stop		= ata_bmdma_stop,
247262306a36Sopenharmony_ci	.bmdma_status		= ata_bmdma_status,
247362306a36Sopenharmony_ci
247462306a36Sopenharmony_ci	.port_start		= ata_bmdma_port_start,
247562306a36Sopenharmony_ci};
247662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
247762306a36Sopenharmony_ci
247862306a36Sopenharmony_ciconst struct ata_port_operations ata_bmdma32_port_ops = {
247962306a36Sopenharmony_ci	.inherits		= &ata_bmdma_port_ops,
248062306a36Sopenharmony_ci
248162306a36Sopenharmony_ci	.sff_data_xfer		= ata_sff_data_xfer32,
248262306a36Sopenharmony_ci	.port_start		= ata_bmdma_port_start32,
248362306a36Sopenharmony_ci};
248462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma32_port_ops);
248562306a36Sopenharmony_ci
248662306a36Sopenharmony_ci/**
248762306a36Sopenharmony_ci *	ata_bmdma_fill_sg - Fill PCI IDE PRD table
248862306a36Sopenharmony_ci *	@qc: Metadata associated with taskfile to be transferred
248962306a36Sopenharmony_ci *
249062306a36Sopenharmony_ci *	Fill PCI IDE PRD (scatter-gather) table with segments
249162306a36Sopenharmony_ci *	associated with the current disk command.
249262306a36Sopenharmony_ci *
249362306a36Sopenharmony_ci *	LOCKING:
249462306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
249562306a36Sopenharmony_ci *
249662306a36Sopenharmony_ci */
249762306a36Sopenharmony_cistatic void ata_bmdma_fill_sg(struct ata_queued_cmd *qc)
249862306a36Sopenharmony_ci{
249962306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
250062306a36Sopenharmony_ci	struct ata_bmdma_prd *prd = ap->bmdma_prd;
250162306a36Sopenharmony_ci	struct scatterlist *sg;
250262306a36Sopenharmony_ci	unsigned int si, pi;
250362306a36Sopenharmony_ci
250462306a36Sopenharmony_ci	pi = 0;
250562306a36Sopenharmony_ci	for_each_sg(qc->sg, sg, qc->n_elem, si) {
250662306a36Sopenharmony_ci		u32 addr, offset;
250762306a36Sopenharmony_ci		u32 sg_len, len;
250862306a36Sopenharmony_ci
250962306a36Sopenharmony_ci		/* determine if physical DMA addr spans 64K boundary.
251062306a36Sopenharmony_ci		 * Note h/w doesn't support 64-bit, so we unconditionally
251162306a36Sopenharmony_ci		 * truncate dma_addr_t to u32.
251262306a36Sopenharmony_ci		 */
251362306a36Sopenharmony_ci		addr = (u32) sg_dma_address(sg);
251462306a36Sopenharmony_ci		sg_len = sg_dma_len(sg);
251562306a36Sopenharmony_ci
251662306a36Sopenharmony_ci		while (sg_len) {
251762306a36Sopenharmony_ci			offset = addr & 0xffff;
251862306a36Sopenharmony_ci			len = sg_len;
251962306a36Sopenharmony_ci			if ((offset + sg_len) > 0x10000)
252062306a36Sopenharmony_ci				len = 0x10000 - offset;
252162306a36Sopenharmony_ci
252262306a36Sopenharmony_ci			prd[pi].addr = cpu_to_le32(addr);
252362306a36Sopenharmony_ci			prd[pi].flags_len = cpu_to_le32(len & 0xffff);
252462306a36Sopenharmony_ci
252562306a36Sopenharmony_ci			pi++;
252662306a36Sopenharmony_ci			sg_len -= len;
252762306a36Sopenharmony_ci			addr += len;
252862306a36Sopenharmony_ci		}
252962306a36Sopenharmony_ci	}
253062306a36Sopenharmony_ci
253162306a36Sopenharmony_ci	prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
253262306a36Sopenharmony_ci}
253362306a36Sopenharmony_ci
253462306a36Sopenharmony_ci/**
253562306a36Sopenharmony_ci *	ata_bmdma_fill_sg_dumb - Fill PCI IDE PRD table
253662306a36Sopenharmony_ci *	@qc: Metadata associated with taskfile to be transferred
253762306a36Sopenharmony_ci *
253862306a36Sopenharmony_ci *	Fill PCI IDE PRD (scatter-gather) table with segments
253962306a36Sopenharmony_ci *	associated with the current disk command. Perform the fill
254062306a36Sopenharmony_ci *	so that we avoid writing any length 64K records for
254162306a36Sopenharmony_ci *	controllers that don't follow the spec.
254262306a36Sopenharmony_ci *
254362306a36Sopenharmony_ci *	LOCKING:
254462306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
254562306a36Sopenharmony_ci *
254662306a36Sopenharmony_ci */
254762306a36Sopenharmony_cistatic void ata_bmdma_fill_sg_dumb(struct ata_queued_cmd *qc)
254862306a36Sopenharmony_ci{
254962306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
255062306a36Sopenharmony_ci	struct ata_bmdma_prd *prd = ap->bmdma_prd;
255162306a36Sopenharmony_ci	struct scatterlist *sg;
255262306a36Sopenharmony_ci	unsigned int si, pi;
255362306a36Sopenharmony_ci
255462306a36Sopenharmony_ci	pi = 0;
255562306a36Sopenharmony_ci	for_each_sg(qc->sg, sg, qc->n_elem, si) {
255662306a36Sopenharmony_ci		u32 addr, offset;
255762306a36Sopenharmony_ci		u32 sg_len, len, blen;
255862306a36Sopenharmony_ci
255962306a36Sopenharmony_ci		/* determine if physical DMA addr spans 64K boundary.
256062306a36Sopenharmony_ci		 * Note h/w doesn't support 64-bit, so we unconditionally
256162306a36Sopenharmony_ci		 * truncate dma_addr_t to u32.
256262306a36Sopenharmony_ci		 */
256362306a36Sopenharmony_ci		addr = (u32) sg_dma_address(sg);
256462306a36Sopenharmony_ci		sg_len = sg_dma_len(sg);
256562306a36Sopenharmony_ci
256662306a36Sopenharmony_ci		while (sg_len) {
256762306a36Sopenharmony_ci			offset = addr & 0xffff;
256862306a36Sopenharmony_ci			len = sg_len;
256962306a36Sopenharmony_ci			if ((offset + sg_len) > 0x10000)
257062306a36Sopenharmony_ci				len = 0x10000 - offset;
257162306a36Sopenharmony_ci
257262306a36Sopenharmony_ci			blen = len & 0xffff;
257362306a36Sopenharmony_ci			prd[pi].addr = cpu_to_le32(addr);
257462306a36Sopenharmony_ci			if (blen == 0) {
257562306a36Sopenharmony_ci				/* Some PATA chipsets like the CS5530 can't
257662306a36Sopenharmony_ci				   cope with 0x0000 meaning 64K as the spec
257762306a36Sopenharmony_ci				   says */
257862306a36Sopenharmony_ci				prd[pi].flags_len = cpu_to_le32(0x8000);
257962306a36Sopenharmony_ci				blen = 0x8000;
258062306a36Sopenharmony_ci				prd[++pi].addr = cpu_to_le32(addr + 0x8000);
258162306a36Sopenharmony_ci			}
258262306a36Sopenharmony_ci			prd[pi].flags_len = cpu_to_le32(blen);
258362306a36Sopenharmony_ci
258462306a36Sopenharmony_ci			pi++;
258562306a36Sopenharmony_ci			sg_len -= len;
258662306a36Sopenharmony_ci			addr += len;
258762306a36Sopenharmony_ci		}
258862306a36Sopenharmony_ci	}
258962306a36Sopenharmony_ci
259062306a36Sopenharmony_ci	prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
259162306a36Sopenharmony_ci}
259262306a36Sopenharmony_ci
259362306a36Sopenharmony_ci/**
259462306a36Sopenharmony_ci *	ata_bmdma_qc_prep - Prepare taskfile for submission
259562306a36Sopenharmony_ci *	@qc: Metadata associated with taskfile to be prepared
259662306a36Sopenharmony_ci *
259762306a36Sopenharmony_ci *	Prepare ATA taskfile for submission.
259862306a36Sopenharmony_ci *
259962306a36Sopenharmony_ci *	LOCKING:
260062306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
260162306a36Sopenharmony_ci */
260262306a36Sopenharmony_cienum ata_completion_errors ata_bmdma_qc_prep(struct ata_queued_cmd *qc)
260362306a36Sopenharmony_ci{
260462306a36Sopenharmony_ci	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
260562306a36Sopenharmony_ci		return AC_ERR_OK;
260662306a36Sopenharmony_ci
260762306a36Sopenharmony_ci	ata_bmdma_fill_sg(qc);
260862306a36Sopenharmony_ci
260962306a36Sopenharmony_ci	return AC_ERR_OK;
261062306a36Sopenharmony_ci}
261162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_qc_prep);
261262306a36Sopenharmony_ci
261362306a36Sopenharmony_ci/**
261462306a36Sopenharmony_ci *	ata_bmdma_dumb_qc_prep - Prepare taskfile for submission
261562306a36Sopenharmony_ci *	@qc: Metadata associated with taskfile to be prepared
261662306a36Sopenharmony_ci *
261762306a36Sopenharmony_ci *	Prepare ATA taskfile for submission.
261862306a36Sopenharmony_ci *
261962306a36Sopenharmony_ci *	LOCKING:
262062306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
262162306a36Sopenharmony_ci */
262262306a36Sopenharmony_cienum ata_completion_errors ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc)
262362306a36Sopenharmony_ci{
262462306a36Sopenharmony_ci	if (!(qc->flags & ATA_QCFLAG_DMAMAP))
262562306a36Sopenharmony_ci		return AC_ERR_OK;
262662306a36Sopenharmony_ci
262762306a36Sopenharmony_ci	ata_bmdma_fill_sg_dumb(qc);
262862306a36Sopenharmony_ci
262962306a36Sopenharmony_ci	return AC_ERR_OK;
263062306a36Sopenharmony_ci}
263162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep);
263262306a36Sopenharmony_ci
263362306a36Sopenharmony_ci/**
263462306a36Sopenharmony_ci *	ata_bmdma_qc_issue - issue taskfile to a BMDMA controller
263562306a36Sopenharmony_ci *	@qc: command to issue to device
263662306a36Sopenharmony_ci *
263762306a36Sopenharmony_ci *	This function issues a PIO, NODATA or DMA command to a
263862306a36Sopenharmony_ci *	SFF/BMDMA controller.  PIO and NODATA are handled by
263962306a36Sopenharmony_ci *	ata_sff_qc_issue().
264062306a36Sopenharmony_ci *
264162306a36Sopenharmony_ci *	LOCKING:
264262306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
264362306a36Sopenharmony_ci *
264462306a36Sopenharmony_ci *	RETURNS:
264562306a36Sopenharmony_ci *	Zero on success, AC_ERR_* mask on failure
264662306a36Sopenharmony_ci */
264762306a36Sopenharmony_ciunsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc)
264862306a36Sopenharmony_ci{
264962306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
265062306a36Sopenharmony_ci	struct ata_link *link = qc->dev->link;
265162306a36Sopenharmony_ci
265262306a36Sopenharmony_ci	/* defer PIO handling to sff_qc_issue */
265362306a36Sopenharmony_ci	if (!ata_is_dma(qc->tf.protocol))
265462306a36Sopenharmony_ci		return ata_sff_qc_issue(qc);
265562306a36Sopenharmony_ci
265662306a36Sopenharmony_ci	/* select the device */
265762306a36Sopenharmony_ci	ata_dev_select(ap, qc->dev->devno, 1, 0);
265862306a36Sopenharmony_ci
265962306a36Sopenharmony_ci	/* start the command */
266062306a36Sopenharmony_ci	switch (qc->tf.protocol) {
266162306a36Sopenharmony_ci	case ATA_PROT_DMA:
266262306a36Sopenharmony_ci		WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
266362306a36Sopenharmony_ci
266462306a36Sopenharmony_ci		trace_ata_tf_load(ap, &qc->tf);
266562306a36Sopenharmony_ci		ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
266662306a36Sopenharmony_ci		trace_ata_bmdma_setup(ap, &qc->tf, qc->tag);
266762306a36Sopenharmony_ci		ap->ops->bmdma_setup(qc);	    /* set up bmdma */
266862306a36Sopenharmony_ci		trace_ata_bmdma_start(ap, &qc->tf, qc->tag);
266962306a36Sopenharmony_ci		ap->ops->bmdma_start(qc);	    /* initiate bmdma */
267062306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST_LAST;
267162306a36Sopenharmony_ci		break;
267262306a36Sopenharmony_ci
267362306a36Sopenharmony_ci	case ATAPI_PROT_DMA:
267462306a36Sopenharmony_ci		WARN_ON_ONCE(qc->tf.flags & ATA_TFLAG_POLLING);
267562306a36Sopenharmony_ci
267662306a36Sopenharmony_ci		trace_ata_tf_load(ap, &qc->tf);
267762306a36Sopenharmony_ci		ap->ops->sff_tf_load(ap, &qc->tf);  /* load tf registers */
267862306a36Sopenharmony_ci		trace_ata_bmdma_setup(ap, &qc->tf, qc->tag);
267962306a36Sopenharmony_ci		ap->ops->bmdma_setup(qc);	    /* set up bmdma */
268062306a36Sopenharmony_ci		ap->hsm_task_state = HSM_ST_FIRST;
268162306a36Sopenharmony_ci
268262306a36Sopenharmony_ci		/* send cdb by polling if no cdb interrupt */
268362306a36Sopenharmony_ci		if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
268462306a36Sopenharmony_ci			ata_sff_queue_pio_task(link, 0);
268562306a36Sopenharmony_ci		break;
268662306a36Sopenharmony_ci
268762306a36Sopenharmony_ci	default:
268862306a36Sopenharmony_ci		WARN_ON(1);
268962306a36Sopenharmony_ci		return AC_ERR_SYSTEM;
269062306a36Sopenharmony_ci	}
269162306a36Sopenharmony_ci
269262306a36Sopenharmony_ci	return 0;
269362306a36Sopenharmony_ci}
269462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_qc_issue);
269562306a36Sopenharmony_ci
269662306a36Sopenharmony_ci/**
269762306a36Sopenharmony_ci *	ata_bmdma_port_intr - Handle BMDMA port interrupt
269862306a36Sopenharmony_ci *	@ap: Port on which interrupt arrived (possibly...)
269962306a36Sopenharmony_ci *	@qc: Taskfile currently active in engine
270062306a36Sopenharmony_ci *
270162306a36Sopenharmony_ci *	Handle port interrupt for given queued command.
270262306a36Sopenharmony_ci *
270362306a36Sopenharmony_ci *	LOCKING:
270462306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
270562306a36Sopenharmony_ci *
270662306a36Sopenharmony_ci *	RETURNS:
270762306a36Sopenharmony_ci *	One if interrupt was handled, zero if not (shared irq).
270862306a36Sopenharmony_ci */
270962306a36Sopenharmony_ciunsigned int ata_bmdma_port_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
271062306a36Sopenharmony_ci{
271162306a36Sopenharmony_ci	struct ata_eh_info *ehi = &ap->link.eh_info;
271262306a36Sopenharmony_ci	u8 host_stat = 0;
271362306a36Sopenharmony_ci	bool bmdma_stopped = false;
271462306a36Sopenharmony_ci	unsigned int handled;
271562306a36Sopenharmony_ci
271662306a36Sopenharmony_ci	if (ap->hsm_task_state == HSM_ST_LAST && ata_is_dma(qc->tf.protocol)) {
271762306a36Sopenharmony_ci		/* check status of DMA engine */
271862306a36Sopenharmony_ci		host_stat = ap->ops->bmdma_status(ap);
271962306a36Sopenharmony_ci		trace_ata_bmdma_status(ap, host_stat);
272062306a36Sopenharmony_ci
272162306a36Sopenharmony_ci		/* if it's not our irq... */
272262306a36Sopenharmony_ci		if (!(host_stat & ATA_DMA_INTR))
272362306a36Sopenharmony_ci			return ata_sff_idle_irq(ap);
272462306a36Sopenharmony_ci
272562306a36Sopenharmony_ci		/* before we do anything else, clear DMA-Start bit */
272662306a36Sopenharmony_ci		trace_ata_bmdma_stop(ap, &qc->tf, qc->tag);
272762306a36Sopenharmony_ci		ap->ops->bmdma_stop(qc);
272862306a36Sopenharmony_ci		bmdma_stopped = true;
272962306a36Sopenharmony_ci
273062306a36Sopenharmony_ci		if (unlikely(host_stat & ATA_DMA_ERR)) {
273162306a36Sopenharmony_ci			/* error when transferring data to/from memory */
273262306a36Sopenharmony_ci			qc->err_mask |= AC_ERR_HOST_BUS;
273362306a36Sopenharmony_ci			ap->hsm_task_state = HSM_ST_ERR;
273462306a36Sopenharmony_ci		}
273562306a36Sopenharmony_ci	}
273662306a36Sopenharmony_ci
273762306a36Sopenharmony_ci	handled = __ata_sff_port_intr(ap, qc, bmdma_stopped);
273862306a36Sopenharmony_ci
273962306a36Sopenharmony_ci	if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol))
274062306a36Sopenharmony_ci		ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
274162306a36Sopenharmony_ci
274262306a36Sopenharmony_ci	return handled;
274362306a36Sopenharmony_ci}
274462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_port_intr);
274562306a36Sopenharmony_ci
274662306a36Sopenharmony_ci/**
274762306a36Sopenharmony_ci *	ata_bmdma_interrupt - Default BMDMA ATA host interrupt handler
274862306a36Sopenharmony_ci *	@irq: irq line (unused)
274962306a36Sopenharmony_ci *	@dev_instance: pointer to our ata_host information structure
275062306a36Sopenharmony_ci *
275162306a36Sopenharmony_ci *	Default interrupt handler for PCI IDE devices.  Calls
275262306a36Sopenharmony_ci *	ata_bmdma_port_intr() for each port that is not disabled.
275362306a36Sopenharmony_ci *
275462306a36Sopenharmony_ci *	LOCKING:
275562306a36Sopenharmony_ci *	Obtains host lock during operation.
275662306a36Sopenharmony_ci *
275762306a36Sopenharmony_ci *	RETURNS:
275862306a36Sopenharmony_ci *	IRQ_NONE or IRQ_HANDLED.
275962306a36Sopenharmony_ci */
276062306a36Sopenharmony_ciirqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance)
276162306a36Sopenharmony_ci{
276262306a36Sopenharmony_ci	return __ata_sff_interrupt(irq, dev_instance, ata_bmdma_port_intr);
276362306a36Sopenharmony_ci}
276462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_interrupt);
276562306a36Sopenharmony_ci
276662306a36Sopenharmony_ci/**
276762306a36Sopenharmony_ci *	ata_bmdma_error_handler - Stock error handler for BMDMA controller
276862306a36Sopenharmony_ci *	@ap: port to handle error for
276962306a36Sopenharmony_ci *
277062306a36Sopenharmony_ci *	Stock error handler for BMDMA controller.  It can handle both
277162306a36Sopenharmony_ci *	PATA and SATA controllers.  Most BMDMA controllers should be
277262306a36Sopenharmony_ci *	able to use this EH as-is or with some added handling before
277362306a36Sopenharmony_ci *	and after.
277462306a36Sopenharmony_ci *
277562306a36Sopenharmony_ci *	LOCKING:
277662306a36Sopenharmony_ci *	Kernel thread context (may sleep)
277762306a36Sopenharmony_ci */
277862306a36Sopenharmony_civoid ata_bmdma_error_handler(struct ata_port *ap)
277962306a36Sopenharmony_ci{
278062306a36Sopenharmony_ci	struct ata_queued_cmd *qc;
278162306a36Sopenharmony_ci	unsigned long flags;
278262306a36Sopenharmony_ci	bool thaw = false;
278362306a36Sopenharmony_ci
278462306a36Sopenharmony_ci	qc = __ata_qc_from_tag(ap, ap->link.active_tag);
278562306a36Sopenharmony_ci	if (qc && !(qc->flags & ATA_QCFLAG_EH))
278662306a36Sopenharmony_ci		qc = NULL;
278762306a36Sopenharmony_ci
278862306a36Sopenharmony_ci	/* reset PIO HSM and stop DMA engine */
278962306a36Sopenharmony_ci	spin_lock_irqsave(ap->lock, flags);
279062306a36Sopenharmony_ci
279162306a36Sopenharmony_ci	if (qc && ata_is_dma(qc->tf.protocol)) {
279262306a36Sopenharmony_ci		u8 host_stat;
279362306a36Sopenharmony_ci
279462306a36Sopenharmony_ci		host_stat = ap->ops->bmdma_status(ap);
279562306a36Sopenharmony_ci		trace_ata_bmdma_status(ap, host_stat);
279662306a36Sopenharmony_ci
279762306a36Sopenharmony_ci		/* BMDMA controllers indicate host bus error by
279862306a36Sopenharmony_ci		 * setting DMA_ERR bit and timing out.  As it wasn't
279962306a36Sopenharmony_ci		 * really a timeout event, adjust error mask and
280062306a36Sopenharmony_ci		 * cancel frozen state.
280162306a36Sopenharmony_ci		 */
280262306a36Sopenharmony_ci		if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
280362306a36Sopenharmony_ci			qc->err_mask = AC_ERR_HOST_BUS;
280462306a36Sopenharmony_ci			thaw = true;
280562306a36Sopenharmony_ci		}
280662306a36Sopenharmony_ci
280762306a36Sopenharmony_ci		trace_ata_bmdma_stop(ap, &qc->tf, qc->tag);
280862306a36Sopenharmony_ci		ap->ops->bmdma_stop(qc);
280962306a36Sopenharmony_ci
281062306a36Sopenharmony_ci		/* if we're gonna thaw, make sure IRQ is clear */
281162306a36Sopenharmony_ci		if (thaw) {
281262306a36Sopenharmony_ci			ap->ops->sff_check_status(ap);
281362306a36Sopenharmony_ci			if (ap->ops->sff_irq_clear)
281462306a36Sopenharmony_ci				ap->ops->sff_irq_clear(ap);
281562306a36Sopenharmony_ci		}
281662306a36Sopenharmony_ci	}
281762306a36Sopenharmony_ci
281862306a36Sopenharmony_ci	spin_unlock_irqrestore(ap->lock, flags);
281962306a36Sopenharmony_ci
282062306a36Sopenharmony_ci	if (thaw)
282162306a36Sopenharmony_ci		ata_eh_thaw_port(ap);
282262306a36Sopenharmony_ci
282362306a36Sopenharmony_ci	ata_sff_error_handler(ap);
282462306a36Sopenharmony_ci}
282562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
282662306a36Sopenharmony_ci
282762306a36Sopenharmony_ci/**
282862306a36Sopenharmony_ci *	ata_bmdma_post_internal_cmd - Stock post_internal_cmd for BMDMA
282962306a36Sopenharmony_ci *	@qc: internal command to clean up
283062306a36Sopenharmony_ci *
283162306a36Sopenharmony_ci *	LOCKING:
283262306a36Sopenharmony_ci *	Kernel thread context (may sleep)
283362306a36Sopenharmony_ci */
283462306a36Sopenharmony_civoid ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
283562306a36Sopenharmony_ci{
283662306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
283762306a36Sopenharmony_ci	unsigned long flags;
283862306a36Sopenharmony_ci
283962306a36Sopenharmony_ci	if (ata_is_dma(qc->tf.protocol)) {
284062306a36Sopenharmony_ci		spin_lock_irqsave(ap->lock, flags);
284162306a36Sopenharmony_ci		trace_ata_bmdma_stop(ap, &qc->tf, qc->tag);
284262306a36Sopenharmony_ci		ap->ops->bmdma_stop(qc);
284362306a36Sopenharmony_ci		spin_unlock_irqrestore(ap->lock, flags);
284462306a36Sopenharmony_ci	}
284562306a36Sopenharmony_ci}
284662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
284762306a36Sopenharmony_ci
284862306a36Sopenharmony_ci/**
284962306a36Sopenharmony_ci *	ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
285062306a36Sopenharmony_ci *	@ap: Port associated with this ATA transaction.
285162306a36Sopenharmony_ci *
285262306a36Sopenharmony_ci *	Clear interrupt and error flags in DMA status register.
285362306a36Sopenharmony_ci *
285462306a36Sopenharmony_ci *	May be used as the irq_clear() entry in ata_port_operations.
285562306a36Sopenharmony_ci *
285662306a36Sopenharmony_ci *	LOCKING:
285762306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
285862306a36Sopenharmony_ci */
285962306a36Sopenharmony_civoid ata_bmdma_irq_clear(struct ata_port *ap)
286062306a36Sopenharmony_ci{
286162306a36Sopenharmony_ci	void __iomem *mmio = ap->ioaddr.bmdma_addr;
286262306a36Sopenharmony_ci
286362306a36Sopenharmony_ci	if (!mmio)
286462306a36Sopenharmony_ci		return;
286562306a36Sopenharmony_ci
286662306a36Sopenharmony_ci	iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS);
286762306a36Sopenharmony_ci}
286862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
286962306a36Sopenharmony_ci
287062306a36Sopenharmony_ci/**
287162306a36Sopenharmony_ci *	ata_bmdma_setup - Set up PCI IDE BMDMA transaction
287262306a36Sopenharmony_ci *	@qc: Info associated with this ATA transaction.
287362306a36Sopenharmony_ci *
287462306a36Sopenharmony_ci *	LOCKING:
287562306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
287662306a36Sopenharmony_ci */
287762306a36Sopenharmony_civoid ata_bmdma_setup(struct ata_queued_cmd *qc)
287862306a36Sopenharmony_ci{
287962306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
288062306a36Sopenharmony_ci	unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
288162306a36Sopenharmony_ci	u8 dmactl;
288262306a36Sopenharmony_ci
288362306a36Sopenharmony_ci	/* load PRD table addr. */
288462306a36Sopenharmony_ci	mb();	/* make sure PRD table writes are visible to controller */
288562306a36Sopenharmony_ci	iowrite32(ap->bmdma_prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
288662306a36Sopenharmony_ci
288762306a36Sopenharmony_ci	/* specify data direction, triple-check start bit is clear */
288862306a36Sopenharmony_ci	dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
288962306a36Sopenharmony_ci	dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
289062306a36Sopenharmony_ci	if (!rw)
289162306a36Sopenharmony_ci		dmactl |= ATA_DMA_WR;
289262306a36Sopenharmony_ci	iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
289362306a36Sopenharmony_ci
289462306a36Sopenharmony_ci	/* issue r/w command */
289562306a36Sopenharmony_ci	ap->ops->sff_exec_command(ap, &qc->tf);
289662306a36Sopenharmony_ci}
289762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_setup);
289862306a36Sopenharmony_ci
289962306a36Sopenharmony_ci/**
290062306a36Sopenharmony_ci *	ata_bmdma_start - Start a PCI IDE BMDMA transaction
290162306a36Sopenharmony_ci *	@qc: Info associated with this ATA transaction.
290262306a36Sopenharmony_ci *
290362306a36Sopenharmony_ci *	LOCKING:
290462306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
290562306a36Sopenharmony_ci */
290662306a36Sopenharmony_civoid ata_bmdma_start(struct ata_queued_cmd *qc)
290762306a36Sopenharmony_ci{
290862306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
290962306a36Sopenharmony_ci	u8 dmactl;
291062306a36Sopenharmony_ci
291162306a36Sopenharmony_ci	/* start host DMA transaction */
291262306a36Sopenharmony_ci	dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
291362306a36Sopenharmony_ci	iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
291462306a36Sopenharmony_ci
291562306a36Sopenharmony_ci	/* Strictly, one may wish to issue an ioread8() here, to
291662306a36Sopenharmony_ci	 * flush the mmio write.  However, control also passes
291762306a36Sopenharmony_ci	 * to the hardware at this point, and it will interrupt
291862306a36Sopenharmony_ci	 * us when we are to resume control.  So, in effect,
291962306a36Sopenharmony_ci	 * we don't care when the mmio write flushes.
292062306a36Sopenharmony_ci	 * Further, a read of the DMA status register _immediately_
292162306a36Sopenharmony_ci	 * following the write may not be what certain flaky hardware
292262306a36Sopenharmony_ci	 * is expected, so I think it is best to not add a readb()
292362306a36Sopenharmony_ci	 * without first all the MMIO ATA cards/mobos.
292462306a36Sopenharmony_ci	 * Or maybe I'm just being paranoid.
292562306a36Sopenharmony_ci	 *
292662306a36Sopenharmony_ci	 * FIXME: The posting of this write means I/O starts are
292762306a36Sopenharmony_ci	 * unnecessarily delayed for MMIO
292862306a36Sopenharmony_ci	 */
292962306a36Sopenharmony_ci}
293062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_start);
293162306a36Sopenharmony_ci
293262306a36Sopenharmony_ci/**
293362306a36Sopenharmony_ci *	ata_bmdma_stop - Stop PCI IDE BMDMA transfer
293462306a36Sopenharmony_ci *	@qc: Command we are ending DMA for
293562306a36Sopenharmony_ci *
293662306a36Sopenharmony_ci *	Clears the ATA_DMA_START flag in the dma control register
293762306a36Sopenharmony_ci *
293862306a36Sopenharmony_ci *	May be used as the bmdma_stop() entry in ata_port_operations.
293962306a36Sopenharmony_ci *
294062306a36Sopenharmony_ci *	LOCKING:
294162306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
294262306a36Sopenharmony_ci */
294362306a36Sopenharmony_civoid ata_bmdma_stop(struct ata_queued_cmd *qc)
294462306a36Sopenharmony_ci{
294562306a36Sopenharmony_ci	struct ata_port *ap = qc->ap;
294662306a36Sopenharmony_ci	void __iomem *mmio = ap->ioaddr.bmdma_addr;
294762306a36Sopenharmony_ci
294862306a36Sopenharmony_ci	/* clear start/stop bit */
294962306a36Sopenharmony_ci	iowrite8(ioread8(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
295062306a36Sopenharmony_ci		 mmio + ATA_DMA_CMD);
295162306a36Sopenharmony_ci
295262306a36Sopenharmony_ci	/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
295362306a36Sopenharmony_ci	ata_sff_dma_pause(ap);
295462306a36Sopenharmony_ci}
295562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_stop);
295662306a36Sopenharmony_ci
295762306a36Sopenharmony_ci/**
295862306a36Sopenharmony_ci *	ata_bmdma_status - Read PCI IDE BMDMA status
295962306a36Sopenharmony_ci *	@ap: Port associated with this ATA transaction.
296062306a36Sopenharmony_ci *
296162306a36Sopenharmony_ci *	Read and return BMDMA status register.
296262306a36Sopenharmony_ci *
296362306a36Sopenharmony_ci *	May be used as the bmdma_status() entry in ata_port_operations.
296462306a36Sopenharmony_ci *
296562306a36Sopenharmony_ci *	LOCKING:
296662306a36Sopenharmony_ci *	spin_lock_irqsave(host lock)
296762306a36Sopenharmony_ci */
296862306a36Sopenharmony_ciu8 ata_bmdma_status(struct ata_port *ap)
296962306a36Sopenharmony_ci{
297062306a36Sopenharmony_ci	return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
297162306a36Sopenharmony_ci}
297262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_status);
297362306a36Sopenharmony_ci
297462306a36Sopenharmony_ci
297562306a36Sopenharmony_ci/**
297662306a36Sopenharmony_ci *	ata_bmdma_port_start - Set port up for bmdma.
297762306a36Sopenharmony_ci *	@ap: Port to initialize
297862306a36Sopenharmony_ci *
297962306a36Sopenharmony_ci *	Called just after data structures for each port are
298062306a36Sopenharmony_ci *	initialized.  Allocates space for PRD table.
298162306a36Sopenharmony_ci *
298262306a36Sopenharmony_ci *	May be used as the port_start() entry in ata_port_operations.
298362306a36Sopenharmony_ci *
298462306a36Sopenharmony_ci *	LOCKING:
298562306a36Sopenharmony_ci *	Inherited from caller.
298662306a36Sopenharmony_ci */
298762306a36Sopenharmony_ciint ata_bmdma_port_start(struct ata_port *ap)
298862306a36Sopenharmony_ci{
298962306a36Sopenharmony_ci	if (ap->mwdma_mask || ap->udma_mask) {
299062306a36Sopenharmony_ci		ap->bmdma_prd =
299162306a36Sopenharmony_ci			dmam_alloc_coherent(ap->host->dev, ATA_PRD_TBL_SZ,
299262306a36Sopenharmony_ci					    &ap->bmdma_prd_dma, GFP_KERNEL);
299362306a36Sopenharmony_ci		if (!ap->bmdma_prd)
299462306a36Sopenharmony_ci			return -ENOMEM;
299562306a36Sopenharmony_ci	}
299662306a36Sopenharmony_ci
299762306a36Sopenharmony_ci	return 0;
299862306a36Sopenharmony_ci}
299962306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_port_start);
300062306a36Sopenharmony_ci
300162306a36Sopenharmony_ci/**
300262306a36Sopenharmony_ci *	ata_bmdma_port_start32 - Set port up for dma.
300362306a36Sopenharmony_ci *	@ap: Port to initialize
300462306a36Sopenharmony_ci *
300562306a36Sopenharmony_ci *	Called just after data structures for each port are
300662306a36Sopenharmony_ci *	initialized.  Enables 32bit PIO and allocates space for PRD
300762306a36Sopenharmony_ci *	table.
300862306a36Sopenharmony_ci *
300962306a36Sopenharmony_ci *	May be used as the port_start() entry in ata_port_operations for
301062306a36Sopenharmony_ci *	devices that are capable of 32bit PIO.
301162306a36Sopenharmony_ci *
301262306a36Sopenharmony_ci *	LOCKING:
301362306a36Sopenharmony_ci *	Inherited from caller.
301462306a36Sopenharmony_ci */
301562306a36Sopenharmony_ciint ata_bmdma_port_start32(struct ata_port *ap)
301662306a36Sopenharmony_ci{
301762306a36Sopenharmony_ci	ap->pflags |= ATA_PFLAG_PIO32 | ATA_PFLAG_PIO32CHANGE;
301862306a36Sopenharmony_ci	return ata_bmdma_port_start(ap);
301962306a36Sopenharmony_ci}
302062306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_bmdma_port_start32);
302162306a36Sopenharmony_ci
302262306a36Sopenharmony_ci#ifdef CONFIG_PCI
302362306a36Sopenharmony_ci
302462306a36Sopenharmony_ci/**
302562306a36Sopenharmony_ci *	ata_pci_bmdma_clear_simplex -	attempt to kick device out of simplex
302662306a36Sopenharmony_ci *	@pdev: PCI device
302762306a36Sopenharmony_ci *
302862306a36Sopenharmony_ci *	Some PCI ATA devices report simplex mode but in fact can be told to
302962306a36Sopenharmony_ci *	enter non simplex mode. This implements the necessary logic to
303062306a36Sopenharmony_ci *	perform the task on such devices. Calling it on other devices will
303162306a36Sopenharmony_ci *	have -undefined- behaviour.
303262306a36Sopenharmony_ci */
303362306a36Sopenharmony_ciint ata_pci_bmdma_clear_simplex(struct pci_dev *pdev)
303462306a36Sopenharmony_ci{
303562306a36Sopenharmony_ci	unsigned long bmdma = pci_resource_start(pdev, 4);
303662306a36Sopenharmony_ci	u8 simplex;
303762306a36Sopenharmony_ci
303862306a36Sopenharmony_ci	if (bmdma == 0)
303962306a36Sopenharmony_ci		return -ENOENT;
304062306a36Sopenharmony_ci
304162306a36Sopenharmony_ci	simplex = inb(bmdma + 0x02);
304262306a36Sopenharmony_ci	outb(simplex & 0x60, bmdma + 0x02);
304362306a36Sopenharmony_ci	simplex = inb(bmdma + 0x02);
304462306a36Sopenharmony_ci	if (simplex & 0x80)
304562306a36Sopenharmony_ci		return -EOPNOTSUPP;
304662306a36Sopenharmony_ci	return 0;
304762306a36Sopenharmony_ci}
304862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
304962306a36Sopenharmony_ci
305062306a36Sopenharmony_cistatic void ata_bmdma_nodma(struct ata_host *host, const char *reason)
305162306a36Sopenharmony_ci{
305262306a36Sopenharmony_ci	int i;
305362306a36Sopenharmony_ci
305462306a36Sopenharmony_ci	dev_err(host->dev, "BMDMA: %s, falling back to PIO\n", reason);
305562306a36Sopenharmony_ci
305662306a36Sopenharmony_ci	for (i = 0; i < 2; i++) {
305762306a36Sopenharmony_ci		host->ports[i]->mwdma_mask = 0;
305862306a36Sopenharmony_ci		host->ports[i]->udma_mask = 0;
305962306a36Sopenharmony_ci	}
306062306a36Sopenharmony_ci}
306162306a36Sopenharmony_ci
306262306a36Sopenharmony_ci/**
306362306a36Sopenharmony_ci *	ata_pci_bmdma_init - acquire PCI BMDMA resources and init ATA host
306462306a36Sopenharmony_ci *	@host: target ATA host
306562306a36Sopenharmony_ci *
306662306a36Sopenharmony_ci *	Acquire PCI BMDMA resources and initialize @host accordingly.
306762306a36Sopenharmony_ci *
306862306a36Sopenharmony_ci *	LOCKING:
306962306a36Sopenharmony_ci *	Inherited from calling layer (may sleep).
307062306a36Sopenharmony_ci */
307162306a36Sopenharmony_civoid ata_pci_bmdma_init(struct ata_host *host)
307262306a36Sopenharmony_ci{
307362306a36Sopenharmony_ci	struct device *gdev = host->dev;
307462306a36Sopenharmony_ci	struct pci_dev *pdev = to_pci_dev(gdev);
307562306a36Sopenharmony_ci	int i, rc;
307662306a36Sopenharmony_ci
307762306a36Sopenharmony_ci	/* No BAR4 allocation: No DMA */
307862306a36Sopenharmony_ci	if (pci_resource_start(pdev, 4) == 0) {
307962306a36Sopenharmony_ci		ata_bmdma_nodma(host, "BAR4 is zero");
308062306a36Sopenharmony_ci		return;
308162306a36Sopenharmony_ci	}
308262306a36Sopenharmony_ci
308362306a36Sopenharmony_ci	/*
308462306a36Sopenharmony_ci	 * Some controllers require BMDMA region to be initialized
308562306a36Sopenharmony_ci	 * even if DMA is not in use to clear IRQ status via
308662306a36Sopenharmony_ci	 * ->sff_irq_clear method.  Try to initialize bmdma_addr
308762306a36Sopenharmony_ci	 * regardless of dma masks.
308862306a36Sopenharmony_ci	 */
308962306a36Sopenharmony_ci	rc = dma_set_mask_and_coherent(&pdev->dev, ATA_DMA_MASK);
309062306a36Sopenharmony_ci	if (rc)
309162306a36Sopenharmony_ci		ata_bmdma_nodma(host, "failed to set dma mask");
309262306a36Sopenharmony_ci
309362306a36Sopenharmony_ci	/* request and iomap DMA region */
309462306a36Sopenharmony_ci	rc = pcim_iomap_regions(pdev, 1 << 4, dev_driver_string(gdev));
309562306a36Sopenharmony_ci	if (rc) {
309662306a36Sopenharmony_ci		ata_bmdma_nodma(host, "failed to request/iomap BAR4");
309762306a36Sopenharmony_ci		return;
309862306a36Sopenharmony_ci	}
309962306a36Sopenharmony_ci	host->iomap = pcim_iomap_table(pdev);
310062306a36Sopenharmony_ci
310162306a36Sopenharmony_ci	for (i = 0; i < 2; i++) {
310262306a36Sopenharmony_ci		struct ata_port *ap = host->ports[i];
310362306a36Sopenharmony_ci		void __iomem *bmdma = host->iomap[4] + 8 * i;
310462306a36Sopenharmony_ci
310562306a36Sopenharmony_ci		if (ata_port_is_dummy(ap))
310662306a36Sopenharmony_ci			continue;
310762306a36Sopenharmony_ci
310862306a36Sopenharmony_ci		ap->ioaddr.bmdma_addr = bmdma;
310962306a36Sopenharmony_ci		if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
311062306a36Sopenharmony_ci		    (ioread8(bmdma + 2) & 0x80))
311162306a36Sopenharmony_ci			host->flags |= ATA_HOST_SIMPLEX;
311262306a36Sopenharmony_ci
311362306a36Sopenharmony_ci		ata_port_desc(ap, "bmdma 0x%llx",
311462306a36Sopenharmony_ci		    (unsigned long long)pci_resource_start(pdev, 4) + 8 * i);
311562306a36Sopenharmony_ci	}
311662306a36Sopenharmony_ci}
311762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
311862306a36Sopenharmony_ci
311962306a36Sopenharmony_ci/**
312062306a36Sopenharmony_ci *	ata_pci_bmdma_prepare_host - helper to prepare PCI BMDMA ATA host
312162306a36Sopenharmony_ci *	@pdev: target PCI device
312262306a36Sopenharmony_ci *	@ppi: array of port_info, must be enough for two ports
312362306a36Sopenharmony_ci *	@r_host: out argument for the initialized ATA host
312462306a36Sopenharmony_ci *
312562306a36Sopenharmony_ci *	Helper to allocate BMDMA ATA host for @pdev, acquire all PCI
312662306a36Sopenharmony_ci *	resources and initialize it accordingly in one go.
312762306a36Sopenharmony_ci *
312862306a36Sopenharmony_ci *	LOCKING:
312962306a36Sopenharmony_ci *	Inherited from calling layer (may sleep).
313062306a36Sopenharmony_ci *
313162306a36Sopenharmony_ci *	RETURNS:
313262306a36Sopenharmony_ci *	0 on success, -errno otherwise.
313362306a36Sopenharmony_ci */
313462306a36Sopenharmony_ciint ata_pci_bmdma_prepare_host(struct pci_dev *pdev,
313562306a36Sopenharmony_ci			       const struct ata_port_info * const * ppi,
313662306a36Sopenharmony_ci			       struct ata_host **r_host)
313762306a36Sopenharmony_ci{
313862306a36Sopenharmony_ci	int rc;
313962306a36Sopenharmony_ci
314062306a36Sopenharmony_ci	rc = ata_pci_sff_prepare_host(pdev, ppi, r_host);
314162306a36Sopenharmony_ci	if (rc)
314262306a36Sopenharmony_ci		return rc;
314362306a36Sopenharmony_ci
314462306a36Sopenharmony_ci	ata_pci_bmdma_init(*r_host);
314562306a36Sopenharmony_ci	return 0;
314662306a36Sopenharmony_ci}
314762306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host);
314862306a36Sopenharmony_ci
314962306a36Sopenharmony_ci/**
315062306a36Sopenharmony_ci *	ata_pci_bmdma_init_one - Initialize/register BMDMA PCI IDE controller
315162306a36Sopenharmony_ci *	@pdev: Controller to be initialized
315262306a36Sopenharmony_ci *	@ppi: array of port_info, must be enough for two ports
315362306a36Sopenharmony_ci *	@sht: scsi_host_template to use when registering the host
315462306a36Sopenharmony_ci *	@host_priv: host private_data
315562306a36Sopenharmony_ci *	@hflags: host flags
315662306a36Sopenharmony_ci *
315762306a36Sopenharmony_ci *	This function is similar to ata_pci_sff_init_one() but also
315862306a36Sopenharmony_ci *	takes care of BMDMA initialization.
315962306a36Sopenharmony_ci *
316062306a36Sopenharmony_ci *	LOCKING:
316162306a36Sopenharmony_ci *	Inherited from PCI layer (may sleep).
316262306a36Sopenharmony_ci *
316362306a36Sopenharmony_ci *	RETURNS:
316462306a36Sopenharmony_ci *	Zero on success, negative on errno-based value on error.
316562306a36Sopenharmony_ci */
316662306a36Sopenharmony_ciint ata_pci_bmdma_init_one(struct pci_dev *pdev,
316762306a36Sopenharmony_ci			   const struct ata_port_info * const * ppi,
316862306a36Sopenharmony_ci			   const struct scsi_host_template *sht, void *host_priv,
316962306a36Sopenharmony_ci			   int hflags)
317062306a36Sopenharmony_ci{
317162306a36Sopenharmony_ci	return ata_pci_init_one(pdev, ppi, sht, host_priv, hflags, 1);
317262306a36Sopenharmony_ci}
317362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one);
317462306a36Sopenharmony_ci
317562306a36Sopenharmony_ci#endif /* CONFIG_PCI */
317662306a36Sopenharmony_ci#endif /* CONFIG_ATA_BMDMA */
317762306a36Sopenharmony_ci
317862306a36Sopenharmony_ci/**
317962306a36Sopenharmony_ci *	ata_sff_port_init - Initialize SFF/BMDMA ATA port
318062306a36Sopenharmony_ci *	@ap: Port to initialize
318162306a36Sopenharmony_ci *
318262306a36Sopenharmony_ci *	Called on port allocation to initialize SFF/BMDMA specific
318362306a36Sopenharmony_ci *	fields.
318462306a36Sopenharmony_ci *
318562306a36Sopenharmony_ci *	LOCKING:
318662306a36Sopenharmony_ci *	None.
318762306a36Sopenharmony_ci */
318862306a36Sopenharmony_civoid ata_sff_port_init(struct ata_port *ap)
318962306a36Sopenharmony_ci{
319062306a36Sopenharmony_ci	INIT_DELAYED_WORK(&ap->sff_pio_task, ata_sff_pio_task);
319162306a36Sopenharmony_ci	ap->ctl = ATA_DEVCTL_OBS;
319262306a36Sopenharmony_ci	ap->last_ctl = 0xFF;
319362306a36Sopenharmony_ci}
319462306a36Sopenharmony_ci
319562306a36Sopenharmony_ciint __init ata_sff_init(void)
319662306a36Sopenharmony_ci{
319762306a36Sopenharmony_ci	ata_sff_wq = alloc_workqueue("ata_sff", WQ_MEM_RECLAIM, WQ_MAX_ACTIVE);
319862306a36Sopenharmony_ci	if (!ata_sff_wq)
319962306a36Sopenharmony_ci		return -ENOMEM;
320062306a36Sopenharmony_ci
320162306a36Sopenharmony_ci	return 0;
320262306a36Sopenharmony_ci}
320362306a36Sopenharmony_ci
320462306a36Sopenharmony_civoid ata_sff_exit(void)
320562306a36Sopenharmony_ci{
320662306a36Sopenharmony_ci	destroy_workqueue(ata_sff_wq);
320762306a36Sopenharmony_ci}
3208