* [PATCHSET #upstream] libata: separate out SFF and BMDMA
@ 2008-10-21 9:17 Tejun Heo
2008-10-21 9:17 ` [PATCH 01/22] pata_sch: use ata_pci_sff_init_one() Tejun Heo
` (27 more replies)
0 siblings, 28 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi
Hello,
This is the first take of separate-out-SFF-and-BMDMA patchset.
Historically, ATA meant SFF (or TASKFILE interface) plus BMDMA and
that holds true for many modern SATA controllers. This was reflected
in libata implementation and libata core layer and SFF/BMDMA support
used to be all tangled in one piece.
For SFF/BMDMA drivers, this assumption is fine but for drivers which
have native interfaces (e.g. ahci, sata_sil24), this meant that those
drivers had to emulate SFF/BMDMA to ceratin not-so-well defined level
libata core layer expects. A lot of this vague dependency on
SFF/BMDMA was removed during recent SFF/BMDMA separation but there
still are SFF/BMDMA specific assumptions in libata core layer.
Another issue which surpassed with the addition of all the legacy,
platform and somewhat peculiar PATA drivers is that now there are
enough drivers which use SFF interface but use its own DMA interface
or don't support DMA at all. This, in similar fashion, led those
drivers to fake certain level of BMDMA functionality to please the
libata SFF/BMDMA layer. This led to the following interesting
solutions in low level drivers.
1. For BMDMA drivers which don't use traditional BMDMA register,
ata_bmdma_mode_filter() incorrectly inhibits DMA modes. Those
drivers either have to inherit from ata_sff_port_ops or clear
->mode_filter explicitly.
2. non-BMDMA drivers call into BMDMA PRD table allocation. It doesn't
actually allocate PRD table if bmdma_addr is not initialized but is
still confusing.
3. For BMDMA drivers which don't use traditional BMDMA register, some
methods might not be invoked as expected (e.g. bmdma_stop from
ata_sff_post_internal_cmd()).
4. SFF drivers w/ custom DMA interface implement noop BMDMA ops
worrying libata core might call into one of them.
This patchset further separates SFF/BMDMA support from the rest of the
libata and separate out BMDMA from SFF. This patchset contains the
following 22 patches.
0001-pata_sch-use-ata_pci_sff_init_one.patch
0002-sata_inic162x-inic162x-is-not-dependent-on-CONFIG_A.patch
0003-sata_mv-remove-unnecessary-initialization.patch
0004-libata-sff-clear-IRQ-from-ata_sff_error_handler-o.patch
0005-libata-sff-kill-unused-prototype-and-make-ata_dev_s.patch
0006-libata-kill-ATA_FLAG_DISABLED.patch
0007-sata_inic162x-kill-PORT_PRD_ADDR-initialization.patch
0008-libata-sff-reorder-SFF-BMDMA-functions.patch
0009-pata_cmd640-bf54x-icside-fix-inheritance.patch
0010-libata-sff-clean-up-BMDMA-initialization.patch
0011-libata-sff-introduce-ata_sff_init-exit-and-ata_sf.patch
0012-libata-sff-ap-last_-ctl-are-SFF-specific.patch
0013-libata-sff-port_task-is-SFF-specific.patch
0014-libata-sff-separate-out-BMDMA-EHs.patch
0015-libata-sff-ata_sff_-dumb_-qc_prep-are-BMDMA-specifi.patch
0016-libata-sff-prd-is-BMDMA-specific.patch
0017-libata-sff-separate-out-BMDMA-qc_issue.patch
0018-libata-sff-ata_sff_irq_clear-is-BMDMA-specific.patch
0019-libata-sff-separate-out-BMDMA-irq-handler.patch
0020-libata-sff-separate-out-BMDMA-init.patch
0021-sata_qstor-kill-dummy-BMDMA-ops.patch
0022-libata-sff-make-BMDMA-optional.patch
0001-0010 make things aligned for the future changes.
0004 changes the default SFF error handler behavior such that
unnecessary register accesses are removed. I'm fairly sure this
change is safe (tested on various SFF/BMDMA controllers) but we'll
need to look out for problem reports.
0006 kills ATA_FLAG_DISABLED (finally). This patch touches SCSI SAS
drivers.
0010 cleans up BMDMA initialization and bmdma_addr condition checks.
0011-0013 further separate out SFF assumptions from libata core layer.
0014-0021 separate out BMDMA from SFF.
0022 makes BMDMA optional and reorganizes Kconfig options according to
the groups of drivers they belong to.
This patchset is on top of
linus#master (2515ddc6db8eb49a79f0fe5e67ff09ac7c81eab4)
+ [1] libata-sff-fix-ata_sff_post_internal_cmd
+ [2] libata-initialize-port_task-when-!CONFIG_ATA_SFF
+ [3] libata-eh-fix-slave-link-EH-action-mask-handling
+ [4] libata-transfer-EHI-control-flags-to-slave-ehc_i
and makes the followings changes.
drivers/ata/Kconfig | 360 +++----
drivers/ata/Makefile | 47
drivers/ata/ata_piix.c | 4
drivers/ata/libata-core.c | 172 ---
drivers/ata/libata-eh.c | 11
drivers/ata/libata-scsi.c | 3
drivers/ata/libata-sff.c | 1757 ++++++++++++++++++++----------------
drivers/ata/libata.h | 37
drivers/ata/pata_acpi.c | 10
drivers/ata/pata_ali.c | 7
drivers/ata/pata_amd.c | 2
drivers/ata/pata_artop.c | 2
drivers/ata/pata_atiixp.c | 4
drivers/ata/pata_bf54x.c | 20
drivers/ata/pata_cmd640.c | 10
drivers/ata/pata_cmd64x.c | 2
drivers/ata/pata_cs5520.c | 4
drivers/ata/pata_cs5530.c | 6
drivers/ata/pata_cs5535.c | 2
drivers/ata/pata_cs5536.c | 2
drivers/ata/pata_cypress.c | 2
drivers/ata/pata_efar.c | 2
drivers/ata/pata_hpt366.c | 4
drivers/ata/pata_hpt37x.c | 6
drivers/ata/pata_hpt3x2n.c | 4
drivers/ata/pata_hpt3x3.c | 2
drivers/ata/pata_icside.c | 7
drivers/ata/pata_it8213.c | 2
drivers/ata/pata_it821x.c | 8
drivers/ata/pata_jmicron.c | 2
drivers/ata/pata_marvell.c | 2
drivers/ata/pata_mpc52xx.c | 1
drivers/ata/pata_netcell.c | 2
drivers/ata/pata_ninja32.c | 2
drivers/ata/pata_ns87415.c | 4
drivers/ata/pata_oldpiix.c | 4
drivers/ata/pata_optidma.c | 2
drivers/ata/pata_pdc2027x.c | 6
drivers/ata/pata_pdc202xx_old.c | 4
drivers/ata/pata_platform.c | 1
drivers/ata/pata_radisys.c | 4
drivers/ata/pata_sc1200.c | 6
drivers/ata/pata_scc.c | 15
drivers/ata/pata_sch.c | 12
drivers/ata/pata_serverworks.c | 8
drivers/ata/pata_sil680.c | 4
drivers/ata/pata_sis.c | 2
drivers/ata/pata_sl82c105.c | 2
drivers/ata/pata_triflex.c | 2
drivers/ata/pata_via.c | 2
drivers/ata/pdc_adma.c | 74 -
drivers/ata/sata_inic162x.c | 25
drivers/ata/sata_mv.c | 15
drivers/ata/sata_nv.c | 264 ++---
drivers/ata/sata_promise.c | 30
drivers/ata/sata_qstor.c | 102 --
drivers/ata/sata_sil.c | 7
drivers/ata/sata_sil24.c | 9
drivers/ata/sata_sis.c | 4
drivers/ata/sata_svw.c | 4
drivers/ata/sata_sx4.c | 9
drivers/ata/sata_uli.c | 6
drivers/ata/sata_via.c | 6
drivers/ata/sata_vsc.c | 12
drivers/scsi/ipr.c | 7
drivers/scsi/libsas/sas_scsi_host.c | 2
include/linux/ata.h | 2
include/linux/libata.h | 91 +
68 files changed, 1653 insertions(+), 1602 deletions(-)
Thanks.
--
tejun
[1] http://article.gmane.org/gmane.linux.ide/35364
[2] http://article.gmane.org/gmane.linux.ide/35363
[3] http://article.gmane.org/gmane.linux.ide/35390
[4] http://article.gmane.org/gmane.linux.ide/35393
^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 01/22] pata_sch: use ata_pci_sff_init_one()
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 02/22] sata_inic162x: inic162x is not dependent on CONFIG_ATA_SFF Tejun Heo
` (26 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
pata_sch is standard SFF. No reason to open code init. Use
ata_pci_sff_init_one() instead.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/pata_sch.c | 12 +-----------
1 files changed, 1 insertions(+), 11 deletions(-)
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c
index c8cc027..4c77d63 100644
--- a/drivers/ata/pata_sch.c
+++ b/drivers/ata/pata_sch.c
@@ -174,22 +174,12 @@ static int __devinit sch_init_one(struct pci_dev *pdev,
{
static int printed_version;
const struct ata_port_info *ppi[] = { &sch_port_info, NULL };
- struct ata_host *host;
- int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- /* enable device and prepare host */
- rc = pcim_enable_device(pdev);
- if (rc)
- return rc;
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
- if (rc)
- return rc;
- pci_set_master(pdev);
- return ata_pci_sff_activate_host(host, ata_sff_interrupt, &sch_sht);
+ return ata_pci_sff_init_one(pdev, ppi, &sch_sht, NULL);
}
static int __init sch_init(void)
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 02/22] sata_inic162x: inic162x is not dependent on CONFIG_ATA_SFF
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
2008-10-21 9:17 ` [PATCH 01/22] pata_sch: use ata_pci_sff_init_one() Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 03/22] sata_mv: remove unnecessary initialization Tejun Heo
` (25 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
sata_inic162x no longer uses SFF interface. Move it out of
CONFIG_ATA_SFF.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/Kconfig | 12 ++++++------
1 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 78fbec8..7cf243e 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -63,6 +63,12 @@ config SATA_SIL24
If unsure, say N.
+config SATA_INIC162X
+ tristate "Initio 162x SATA support"
+ depends on PCI
+ help
+ This option enables support for Initio 162x Serial ATA.
+
config SATA_FSL
tristate "Freescale 3.0Gbps SATA support"
depends on FSL_SOC
@@ -203,12 +209,6 @@ config SATA_VITESSE
If unsure, say N.
-config SATA_INIC162X
- tristate "Initio 162x SATA support"
- depends on PCI
- help
- This option enables support for Initio 162x Serial ATA.
-
config PATA_ACPI
tristate "ACPI firmware driver for PATA"
depends on ATA_ACPI
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 03/22] sata_mv: remove unnecessary initialization
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
2008-10-21 9:17 ` [PATCH 01/22] pata_sch: use ata_pci_sff_init_one() Tejun Heo
2008-10-21 9:17 ` [PATCH 02/22] sata_inic162x: inic162x is not dependent on CONFIG_ATA_SFF Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary Tejun Heo
` (24 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
sata_mv initializes unused ioports fields including bmdma_addr to
NULL. As later changes will conditionalize BMDMA, this makes sata_mv
unnecessarily dependent on BMDMA. Remove the unnecessary
initialization.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/sata_mv.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 2b24ae5..92f3ad8 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -2861,9 +2861,6 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
/* special case: control/altstatus doesn't have ATA_REG_ address */
port->altstatus_addr = port->ctl_addr = shd_base + SHD_CTL_AST_OFS;
- /* unused: */
- port->cmd_addr = port->bmdma_addr = port->scr_addr = NULL;
-
/* Clear any currently outstanding port interrupt conditions */
serr_ofs = mv_scr_offset(SCR_ERROR);
writelfl(readl(port_mmio + serr_ofs), port_mmio + serr_ofs);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (2 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 03/22] sata_mv: remove unnecessary initialization Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:53 ` Sergei Shtylyov
2008-10-28 4:10 ` [PATCH 04/22] " Jeff Garzik
2008-10-21 9:17 ` [PATCH 05/22] libata-sff: kill unused prototype and make ata_dev_select() static Tejun Heo
` (23 subsequent siblings)
27 siblings, 2 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
Clearing IRQ from ata_sff_error_handler() is necessary only when the
port is gonna be thawed before performing EH actions and some
controllers don't like being accessed after certain fail modes until
they're reset. Clear IRQ iff the port is being thawed. Also, remove
unnecessary ata_sff_sync() while at it.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-sff.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 4b47394..b9fb068 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2119,11 +2119,13 @@ void ata_sff_error_handler(struct ata_port *ap)
}
ap->ops->bmdma_stop(qc);
- }
- ata_sff_sync(ap); /* FIXME: We don't need this */
- ap->ops->sff_check_status(ap);
- ap->ops->sff_irq_clear(ap);
+ /* if we're gonna thaw, make sure IRQ is clear */
+ if (thaw) {
+ ap->ops->sff_check_status(ap);
+ ap->ops->sff_irq_clear(ap);
+ }
+ }
spin_unlock_irqrestore(ap->lock, flags);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 05/22] libata-sff: kill unused prototype and make ata_dev_select() static
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (3 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2010-05-07 13:47 ` Sergei Shtylyov
2008-10-21 9:17 ` [PATCH 06/22] libata: kill ATA_FLAG_DISABLED Tejun Heo
` (22 subsequent siblings)
27 siblings, 1 reply; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
ata_irq_on() was renamed to ata_sff_irq_on() and exported a while ago
but prototype for the original function lingered in
drivers/ata/libata.h. Kill it. Also, ata_dev_select() is only used
inside drivers/ata/libata-sff.c. Make it static.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-sff.c | 2 +-
drivers/ata/libata.h | 3 ---
2 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index b9fb068..edcd72c 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -468,7 +468,7 @@ void ata_sff_dev_select(struct ata_port *ap, unsigned int device)
* LOCKING:
* caller.
*/
-void ata_dev_select(struct ata_port *ap, unsigned int device,
+static void ata_dev_select(struct ata_port *ap, unsigned int device,
unsigned int wait, unsigned int can_sleep)
{
if (ata_msg_probe(ap))
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index fe2839e..1f626b5 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -201,9 +201,6 @@ static inline int sata_pmp_attach(struct ata_device *dev)
/* libata-sff.c */
#ifdef CONFIG_ATA_SFF
-extern void ata_dev_select(struct ata_port *ap, unsigned int device,
- unsigned int wait, unsigned int can_sleep);
-extern u8 ata_irq_on(struct ata_port *ap);
extern void ata_pio_task(struct work_struct *work);
#endif /* CONFIG_ATA_SFF */
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 06/22] libata: kill ATA_FLAG_DISABLED
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (4 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 05/22] libata-sff: kill unused prototype and make ata_dev_select() static Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 07/22] sata_inic162x: kill PORT_PRD_ADDR initialization Tejun Heo
` (21 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
ATA_FLAG_DISABLED is only used by drivers which don't use
->error_handler framework and is largely broken. Its only meaningful
function is to make irq handlers skip processing if the flag is set,
which is largely useless and even harmful as it makes those ports more
likely to cause IRQ storms.
Kill ATA_FLAG_DISABLED and makes the callers disable attached devices
instead. ata_port_probe() and ata_port_disable() which manipulate the
flag are also killed.
This simplifies condition check in IRQ handlers. While updating IRQ
handlers, remove ap NULL check as libata guarantees consecutive port
allocation (unoccupied ports are initialized with dummies) and
long-obsolete ATA_QCFLAG_ACTIVE check (checked by ata_qc_from_tag()).
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-core.c | 66 +----------
drivers/ata/libata-scsi.c | 3 -
drivers/ata/libata-sff.c | 24 ++---
drivers/ata/pata_bf54x.c | 16 +--
drivers/ata/pdc_adma.c | 66 +++++------
drivers/ata/sata_inic162x.c | 17 +--
drivers/ata/sata_mv.c | 8 +-
drivers/ata/sata_nv.c | 234 +++++++++++++++++------------------
drivers/ata/sata_promise.c | 6 +-
drivers/ata/sata_qstor.c | 79 ++++++------
drivers/ata/sata_sil.c | 3 -
drivers/ata/sata_sil24.c | 9 +-
drivers/ata/sata_sx4.c | 4 +-
drivers/ata/sata_vsc.c | 10 +--
drivers/scsi/ipr.c | 7 +-
drivers/scsi/libsas/sas_scsi_host.c | 2 +-
include/linux/libata.h | 8 --
17 files changed, 207 insertions(+), 355 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index bbb3cae..231e967 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1821,22 +1821,6 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
ap->qc_active = preempted_qc_active;
ap->nr_active_links = preempted_nr_active_links;
- /* XXX - Some LLDDs (sata_mv) disable port on command failure.
- * Until those drivers are fixed, we detect the condition
- * here, fail the command with AC_ERR_SYSTEM and reenable the
- * port.
- *
- * Note that this doesn't change any behavior as internal
- * command failure results in disabling the device in the
- * higher layer for LLDDs without new reset/EH callbacks.
- *
- * Kill the following code as soon as those drivers are fixed.
- */
- if (ap->flags & ATA_FLAG_DISABLED) {
- err_mask |= AC_ERR_SYSTEM;
- ata_port_probe(ap);
- }
-
spin_unlock_irqrestore(ap->lock, flags);
if ((err_mask & AC_ERR_TIMEOUT) && auto_timeout)
@@ -2582,8 +2566,6 @@ int ata_bus_probe(struct ata_port *ap)
int rc;
struct ata_device *dev;
- ata_port_probe(ap);
-
ata_link_for_each_dev(dev, &ap->link)
tries[dev->devno] = ATA_PROBE_MAX_TRIES;
@@ -2611,8 +2593,7 @@ int ata_bus_probe(struct ata_port *ap)
ap->ops->phy_reset(ap);
ata_link_for_each_dev(dev, &ap->link) {
- if (!(ap->flags & ATA_FLAG_DISABLED) &&
- dev->class != ATA_DEV_UNKNOWN)
+ if (dev->class != ATA_DEV_UNKNOWN)
classes[dev->devno] = dev->class;
else
classes[dev->devno] = ATA_DEV_NONE;
@@ -2620,8 +2601,6 @@ int ata_bus_probe(struct ata_port *ap)
dev->class = ATA_DEV_UNKNOWN;
}
- ata_port_probe(ap);
-
/* read IDENTIFY page and configure devices. We have to do the identify
specific sequence bass-ackwards so that PDIAG- is released by
the slave device */
@@ -2677,8 +2656,6 @@ int ata_bus_probe(struct ata_port *ap)
if (ata_dev_enabled(dev))
return 0;
- /* no device present, disable port */
- ata_port_disable(ap);
return -ENODEV;
fail:
@@ -2710,22 +2687,6 @@ int ata_bus_probe(struct ata_port *ap)
}
/**
- * ata_port_probe - Mark port as enabled
- * @ap: Port for which we indicate enablement
- *
- * Modify @ap data structure such that the system
- * thinks that the entire port is enabled.
- *
- * LOCKING: host lock, or some other form of
- * serialization.
- */
-
-void ata_port_probe(struct ata_port *ap)
-{
- ap->flags &= ~ATA_FLAG_DISABLED;
-}
-
-/**
* sata_print_link_status - Print SATA link status
* @link: SATA link to printk link status about
*
@@ -2772,26 +2733,6 @@ struct ata_device *ata_dev_pair(struct ata_device *adev)
}
/**
- * ata_port_disable - Disable port.
- * @ap: Port to be disabled.
- *
- * Modify @ap data structure such that the system
- * thinks that the entire port is disabled, and should
- * never attempt to probe or communicate with devices
- * on this port.
- *
- * LOCKING: host lock, or some other form of
- * serialization.
- */
-
-void ata_port_disable(struct ata_port *ap)
-{
- ap->link.device[0].class = ATA_DEV_NONE;
- ap->link.device[1].class = ATA_DEV_NONE;
- ap->flags |= ATA_FLAG_DISABLED;
-}
-
-/**
* sata_down_spd_limit - adjust SATA spd limit downward
* @link: Link to adjust SATA spd limit for
*
@@ -5355,7 +5296,6 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
ap->pflags |= ATA_PFLAG_INITIALIZING;
ap->lock = &host->lock;
- ap->flags = ATA_FLAG_DISABLED;
ap->print_id = -1;
ap->ctl = ATA_DEVCTL_OBS;
ap->host = host;
@@ -5848,8 +5788,6 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
struct ata_eh_info *ehi = &ap->link.eh_info;
unsigned long flags;
- ata_port_probe(ap);
-
/* kick EH for boot probing */
spin_lock_irqsave(ap->lock, flags);
@@ -6469,7 +6407,6 @@ EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_do_set_mode);
EXPORT_SYMBOL_GPL(ata_std_qc_defer);
EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
-EXPORT_SYMBOL_GPL(ata_port_probe);
EXPORT_SYMBOL_GPL(ata_dev_disable);
EXPORT_SYMBOL_GPL(sata_set_spd);
EXPORT_SYMBOL_GPL(ata_wait_after_reset);
@@ -6481,7 +6418,6 @@ EXPORT_SYMBOL_GPL(sata_std_hardreset);
EXPORT_SYMBOL_GPL(ata_std_postreset);
EXPORT_SYMBOL_GPL(ata_dev_classify);
EXPORT_SYMBOL_GPL(ata_dev_pair);
-EXPORT_SYMBOL_GPL(ata_port_disable);
EXPORT_SYMBOL_GPL(ata_ratelimit);
EXPORT_SYMBOL_GPL(ata_wait_register);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 5d312dc..fd77fcd 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -3224,9 +3224,6 @@ void ata_scsi_scan_host(struct ata_port *ap, int sync)
struct ata_link *link;
struct ata_device *dev;
- if (ap->flags & ATA_FLAG_DISABLED)
- return;
-
repeat:
ata_port_for_each_link(link, ap) {
ata_link_for_each_dev(dev, link) {
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index edcd72c..dbb8695 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1640,18 +1640,12 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
spin_lock_irqsave(&host->lock, flags);
for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap;
-
- ap = host->ports[i];
- if (ap &&
- !(ap->flags & ATA_FLAG_DISABLED)) {
- struct ata_queued_cmd *qc;
+ struct ata_port *ap = host->ports[i];
+ struct ata_queued_cmd *qc;
- qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
- (qc->flags & ATA_QCFLAG_ACTIVE))
- handled |= ata_sff_host_intr(ap, qc);
- }
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ if (qc && !(qc->tf.flags & ATA_TFLAG_POLLING))
+ handled |= ata_sff_host_intr(ap, qc);
}
spin_unlock_irqrestore(&host->lock, flags);
@@ -2340,9 +2334,6 @@ u8 ata_bmdma_status(struct ata_port *ap)
* PCI/etc. bus probe sem.
* Obtains host lock.
*
- * SIDE EFFECTS:
- * Sets ATA_FLAG_DISABLED if bus reset fails.
- *
* DEPRECATED:
* This function is only for drivers which still use old EH and
* will be removed soon.
@@ -2410,8 +2401,9 @@ void ata_bus_reset(struct ata_port *ap)
return;
err_out:
- ata_port_printk(ap, KERN_ERR, "disabling port\n");
- ata_port_disable(ap);
+ device[0].class = ATA_DEV_NONE;
+ device[1].class = ATA_DEV_NONE;
+ ata_port_printk(ap, KERN_ERR, "giving up port\n");
DPRINTK("EXIT\n");
}
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index 1266924..b833328 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1439,18 +1439,12 @@ static irqreturn_t bfin_ata_interrupt(int irq, void *dev_instance)
spin_lock_irqsave(&host->lock, flags);
for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap;
+ struct ata_port *ap = host->ports[i];
+ struct ata_queued_cmd *qc;
- ap = host->ports[i];
- if (ap &&
- !(ap->flags & ATA_FLAG_DISABLED)) {
- struct ata_queued_cmd *qc;
-
- qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)) &&
- (qc->flags & ATA_QCFLAG_ACTIVE))
- handled |= bfin_ata_host_intr(ap, qc);
- }
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
+ handled |= bfin_ata_host_intr(ap, qc);
}
spin_unlock_irqrestore(&host->lock, flags);
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index be53545..b8cc349 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -439,8 +439,6 @@ static inline unsigned int adma_intr_pkt(struct ata_host *host)
continue;
handled = 1;
adma_enter_reg_mode(ap);
- if (ap->flags & ATA_FLAG_DISABLED)
- continue;
pp = ap->private_data;
if (!pp || pp->state != adma_state_pkt)
continue;
@@ -481,42 +479,38 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host)
unsigned int handled = 0, port_no;
for (port_no = 0; port_no < host->n_ports; ++port_no) {
- struct ata_port *ap;
- ap = host->ports[port_no];
- if (ap && (!(ap->flags & ATA_FLAG_DISABLED))) {
- struct ata_queued_cmd *qc;
- struct adma_port_priv *pp = ap->private_data;
- if (!pp || pp->state != adma_state_mmio)
+ struct ata_port *ap = host->ports[port_no];
+ struct adma_port_priv *pp = ap->private_data;
+ struct ata_queued_cmd *qc;
+
+ if (!pp || pp->state != adma_state_mmio)
+ continue;
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
+
+ /* check main status, clearing INTRQ */
+ u8 status = ata_sff_check_status(ap);
+ if ((status & ATA_BUSY))
continue;
- qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
-
- /* check main status, clearing INTRQ */
- u8 status = ata_sff_check_status(ap);
- if ((status & ATA_BUSY))
- continue;
- DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
- ap->print_id, qc->tf.protocol, status);
-
- /* complete taskfile transaction */
- pp->state = adma_state_idle;
- qc->err_mask |= ac_err_mask(status);
- if (!qc->err_mask)
- ata_qc_complete(qc);
- else {
- struct ata_eh_info *ehi =
- &ap->link.eh_info;
- ata_ehi_clear_desc(ehi);
- ata_ehi_push_desc(ehi,
- "status 0x%02X", status);
-
- if (qc->err_mask == AC_ERR_DEV)
- ata_port_abort(ap);
- else
- ata_port_freeze(ap);
- }
- handled = 1;
+ DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
+ ap->print_id, qc->tf.protocol, status);
+
+ /* complete taskfile transaction */
+ pp->state = adma_state_idle;
+ qc->err_mask |= ac_err_mask(status);
+ if (!qc->err_mask)
+ ata_qc_complete(qc);
+ else {
+ struct ata_eh_info *ehi = &ap->link.eh_info;
+ ata_ehi_clear_desc(ehi);
+ ata_ehi_push_desc(ehi, "status 0x%02X", status);
+
+ if (qc->err_mask == AC_ERR_DEV)
+ ata_port_abort(ap);
+ else
+ ata_port_freeze(ap);
}
+ handled = 1;
}
}
return handled;
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index fbbd87c..9dd7559 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -414,22 +414,11 @@ static irqreturn_t inic_interrupt(int irq, void *dev_instance)
spin_lock(&host->lock);
- for (i = 0; i < NR_PORTS; i++) {
- struct ata_port *ap = host->ports[i];
-
- if (!(host_irq_stat & (HIRQ_PORT0 << i)))
- continue;
-
- if (likely(ap && !(ap->flags & ATA_FLAG_DISABLED))) {
- inic_host_intr(ap);
+ for (i = 0; i < NR_PORTS; i++)
+ if (host_irq_stat & (HIRQ_PORT0 << i)) {
+ inic_host_intr(host->ports[i]);
handled++;
- } else {
- if (ata_ratelimit())
- dev_printk(KERN_ERR, host->dev, "interrupt "
- "from disabled port %d (0x%x)\n",
- i, host_irq_stat);
}
- }
spin_unlock(&host->lock);
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 92f3ad8..13368cb 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1818,9 +1818,7 @@ static void mv_unexpected_intr(struct ata_port *ap, int edma_was_enabled)
char *when = "idle";
ata_ehi_clear_desc(ehi);
- if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
- when = "disabled";
- } else if (edma_was_enabled) {
+ if (edma_was_enabled) {
when = "EDMA enabled";
} else {
struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->link.active_tag);
@@ -2055,10 +2053,6 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause)
struct mv_port_priv *pp;
int edma_was_enabled;
- if (!ap || (ap->flags & ATA_FLAG_DISABLED)) {
- mv_unexpected_intr(ap, 0);
- return;
- }
/*
* Grab a snapshot of the EDMA_EN flag setting,
* so that we have a consistent view for this port,
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index fae3841..521dcd3 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -879,107 +879,107 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
+ struct nv_adma_port_priv *pp = ap->private_data;
+ void __iomem *mmio = pp->ctl_block;
+ u16 status;
+ u32 gen_ctl;
+ u32 notifier, notifier_error;
+
notifier_clears[i] = 0;
- if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
- struct nv_adma_port_priv *pp = ap->private_data;
- void __iomem *mmio = pp->ctl_block;
- u16 status;
- u32 gen_ctl;
- u32 notifier, notifier_error;
-
- /* if ADMA is disabled, use standard ata interrupt handler */
- if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) {
- u8 irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804)
- >> (NV_INT_PORT_SHIFT * i);
- handled += nv_host_intr(ap, irq_stat);
- continue;
- }
+ /* if ADMA is disabled, use standard ata interrupt handler */
+ if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) {
+ u8 irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804)
+ >> (NV_INT_PORT_SHIFT * i);
+ handled += nv_host_intr(ap, irq_stat);
+ continue;
+ }
- /* if in ATA register mode, check for standard interrupts */
- if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) {
- u8 irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804)
- >> (NV_INT_PORT_SHIFT * i);
- if (ata_tag_valid(ap->link.active_tag))
- /** NV_INT_DEV indication seems unreliable at times
- at least in ADMA mode. Force it on always when a
- command is active, to prevent losing interrupts. */
- irq_stat |= NV_INT_DEV;
- handled += nv_host_intr(ap, irq_stat);
- }
+ /* if in ATA register mode, check for standard interrupts */
+ if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) {
+ u8 irq_stat = readb(host->iomap[NV_MMIO_BAR] + NV_INT_STATUS_CK804)
+ >> (NV_INT_PORT_SHIFT * i);
+ if (ata_tag_valid(ap->link.active_tag))
+ /** NV_INT_DEV indication seems unreliable
+ at times at least in ADMA mode. Force it
+ on always when a command is active, to
+ prevent losing interrupts. */
+ irq_stat |= NV_INT_DEV;
+ handled += nv_host_intr(ap, irq_stat);
+ }
+
+ notifier = readl(mmio + NV_ADMA_NOTIFIER);
+ notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
+ notifier_clears[i] = notifier | notifier_error;
+
+ gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL);
+
+ if (!NV_ADMA_CHECK_INTR(gen_ctl, ap->port_no) && !notifier &&
+ !notifier_error)
+ /* Nothing to do */
+ continue;
+
+ status = readw(mmio + NV_ADMA_STAT);
+
+ /* Clear status. Ensure the controller sees the clearing
+ before we start looking at any of the CPB statuses, so
+ that any CPB completions after this point in the handler
+ will raise another interrupt. */
+ writew(status, mmio + NV_ADMA_STAT);
+ readw(mmio + NV_ADMA_STAT); /* flush posted write */
+ rmb();
+
+ handled++; /* irq handled if we got here */
+
+ /* freeze if hotplugged or controller error */
+ if (unlikely(status & (NV_ADMA_STAT_HOTPLUG |
+ NV_ADMA_STAT_HOTUNPLUG |
+ NV_ADMA_STAT_TIMEOUT |
+ NV_ADMA_STAT_SERROR))) {
+ struct ata_eh_info *ehi = &ap->link.eh_info;
- notifier = readl(mmio + NV_ADMA_NOTIFIER);
- notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
- notifier_clears[i] = notifier | notifier_error;
-
- gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL);
-
- if (!NV_ADMA_CHECK_INTR(gen_ctl, ap->port_no) && !notifier &&
- !notifier_error)
- /* Nothing to do */
- continue;
-
- status = readw(mmio + NV_ADMA_STAT);
-
- /* Clear status. Ensure the controller sees the clearing before we start
- looking at any of the CPB statuses, so that any CPB completions after
- this point in the handler will raise another interrupt. */
- writew(status, mmio + NV_ADMA_STAT);
- readw(mmio + NV_ADMA_STAT); /* flush posted write */
- rmb();
-
- handled++; /* irq handled if we got here */
-
- /* freeze if hotplugged or controller error */
- if (unlikely(status & (NV_ADMA_STAT_HOTPLUG |
- NV_ADMA_STAT_HOTUNPLUG |
- NV_ADMA_STAT_TIMEOUT |
- NV_ADMA_STAT_SERROR))) {
- struct ata_eh_info *ehi = &ap->link.eh_info;
-
- ata_ehi_clear_desc(ehi);
- __ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status);
- if (status & NV_ADMA_STAT_TIMEOUT) {
- ehi->err_mask |= AC_ERR_SYSTEM;
- ata_ehi_push_desc(ehi, "timeout");
- } else if (status & NV_ADMA_STAT_HOTPLUG) {
- ata_ehi_hotplugged(ehi);
- ata_ehi_push_desc(ehi, "hotplug");
- } else if (status & NV_ADMA_STAT_HOTUNPLUG) {
- ata_ehi_hotplugged(ehi);
- ata_ehi_push_desc(ehi, "hot unplug");
- } else if (status & NV_ADMA_STAT_SERROR) {
- /* let libata analyze SError and figure out the cause */
- ata_ehi_push_desc(ehi, "SError");
- } else
- ata_ehi_push_desc(ehi, "unknown");
- ata_port_freeze(ap);
- continue;
+ ata_ehi_clear_desc(ehi);
+ __ata_ehi_push_desc(ehi, "ADMA status 0x%08x: ", status);
+ if (status & NV_ADMA_STAT_TIMEOUT) {
+ ehi->err_mask |= AC_ERR_SYSTEM;
+ ata_ehi_push_desc(ehi, "timeout");
+ } else if (status & NV_ADMA_STAT_HOTPLUG) {
+ ata_ehi_hotplugged(ehi);
+ ata_ehi_push_desc(ehi, "hotplug");
+ } else if (status & NV_ADMA_STAT_HOTUNPLUG) {
+ ata_ehi_hotplugged(ehi);
+ ata_ehi_push_desc(ehi, "hot unplug");
+ } else if (status & NV_ADMA_STAT_SERROR) {
+ /* let libata analyze SError and figure out
+ the cause */
+ ata_ehi_push_desc(ehi, "SError");
+ } else
+ ata_ehi_push_desc(ehi, "unknown");
+ ata_port_freeze(ap);
+ continue;
+ }
+
+ if (status & (NV_ADMA_STAT_DONE |
+ NV_ADMA_STAT_CPBERR |
+ NV_ADMA_STAT_CMD_COMPLETE)) {
+ u32 check_commands = notifier_clears[i];
+ int pos, error = 0;
+
+ if (status & NV_ADMA_STAT_CPBERR) {
+ /* Check all active commands */
+ if (ata_tag_valid(ap->link.active_tag))
+ check_commands = 1 <<
+ ap->link.active_tag;
+ else
+ check_commands = ap->link.sactive;
}
- if (status & (NV_ADMA_STAT_DONE |
- NV_ADMA_STAT_CPBERR |
- NV_ADMA_STAT_CMD_COMPLETE)) {
- u32 check_commands = notifier_clears[i];
- int pos, error = 0;
-
- if (status & NV_ADMA_STAT_CPBERR) {
- /* Check all active commands */
- if (ata_tag_valid(ap->link.active_tag))
- check_commands = 1 <<
- ap->link.active_tag;
- else
- check_commands = ap->
- link.sactive;
- }
-
- /** Check CPBs for completed commands */
- while ((pos = ffs(check_commands)) && !error) {
- pos--;
- error = nv_adma_check_cpb(ap, pos,
+ /** Check CPBs for completed commands */
+ while ((pos = ffs(check_commands)) && !error) {
+ pos--;
+ error = nv_adma_check_cpb(ap, pos,
notifier_error & (1 << pos));
- check_commands &= ~(1 << pos);
- }
+ check_commands &= ~(1 << pos);
}
}
}
@@ -1444,22 +1444,16 @@ static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance)
spin_lock_irqsave(&host->lock, flags);
for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap;
-
- ap = host->ports[i];
- if (ap &&
- !(ap->flags & ATA_FLAG_DISABLED)) {
- struct ata_queued_cmd *qc;
-
- qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
- handled += ata_sff_host_intr(ap, qc);
- else
- // No request pending? Clear interrupt status
- // anyway, in case there's one pending.
- ap->ops->sff_check_status(ap);
- }
+ struct ata_port *ap = host->ports[i];
+ struct ata_queued_cmd *qc;
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
+ handled += ata_sff_host_intr(ap, qc);
+ else
+ // No request pending? Clear interrupt status
+ // anyway, in case there's one pending.
+ ap->ops->sff_check_status(ap);
}
spin_unlock_irqrestore(&host->lock, flags);
@@ -1472,11 +1466,7 @@ static irqreturn_t nv_do_interrupt(struct ata_host *host, u8 irq_stat)
int i, handled = 0;
for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
-
- if (ap && !(ap->flags & ATA_FLAG_DISABLED))
- handled += nv_host_intr(ap, irq_stat);
-
+ handled += nv_host_intr(host->ports[i], irq_stat);
irq_stat >>= NV_INT_PORT_SHIFT;
}
@@ -2309,16 +2299,14 @@ static irqreturn_t nv_swncq_interrupt(int irq, void *dev_instance)
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
- if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
- if (ap->link.sactive) {
- nv_swncq_host_interrupt(ap, (u16)irq_stat);
- handled = 1;
- } else {
- if (irq_stat) /* reserve Hotplug */
- nv_swncq_irq_clear(ap, 0xfff0);
+ if (ap->link.sactive) {
+ nv_swncq_host_interrupt(ap, (u16)irq_stat);
+ handled = 1;
+ } else {
+ if (irq_stat) /* reserve Hotplug */
+ nv_swncq_irq_clear(ap, 0xfff0);
- handled += nv_host_intr(ap, (u8)irq_stat);
- }
+ handled += nv_host_intr(ap, (u8)irq_stat);
}
irq_stat >>= NV_INT_PORT_SHIFT_MCP55;
}
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 750d8cd..3c440e5 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -844,8 +844,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
/* check for a plug or unplug event */
ata_no = pdc_port_no_to_ata_no(i, is_sataii_tx4);
tmp = hotplug_status & (0x11 << ata_no);
- if (tmp && ap &&
- !(ap->flags & ATA_FLAG_DISABLED)) {
+ if (tmp) {
struct ata_eh_info *ehi = &ap->link.eh_info;
ata_ehi_clear_desc(ehi);
ata_ehi_hotplugged(ehi);
@@ -857,8 +856,7 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
/* check for a packet interrupt */
tmp = mask & (1 << (i + 1));
- if (tmp && ap &&
- !(ap->flags & ATA_FLAG_DISABLED)) {
+ if (tmp) {
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->link.active_tag);
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index a000c86..48a3756 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -402,26 +402,24 @@ static inline unsigned int qs_intr_pkt(struct ata_host *host)
u8 sHST = sff1 & 0x3f; /* host status */
unsigned int port_no = (sff1 >> 8) & 0x03;
struct ata_port *ap = host->ports[port_no];
+ struct qs_port_priv *pp = ap->private_data;
+ struct ata_queued_cmd *qc;
DPRINTK("SFF=%08x%08x: sCHAN=%u sHST=%d sDST=%02x\n",
sff1, sff0, port_no, sHST, sDST);
handled = 1;
- if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
- struct ata_queued_cmd *qc;
- struct qs_port_priv *pp = ap->private_data;
- if (!pp || pp->state != qs_state_pkt)
- continue;
- qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
- switch (sHST) {
- case 0: /* successful CPB */
- case 3: /* device error */
- qs_enter_reg_mode(qc->ap);
- qs_do_or_die(qc, sDST);
- break;
- default:
- break;
- }
+ if (!pp || pp->state != qs_state_pkt)
+ continue;
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
+ switch (sHST) {
+ case 0: /* successful CPB */
+ case 3: /* device error */
+ qs_enter_reg_mode(qc->ap);
+ qs_do_or_die(qc, sDST);
+ break;
+ default:
+ break;
}
}
}
@@ -434,33 +432,30 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)
unsigned int handled = 0, port_no;
for (port_no = 0; port_no < host->n_ports; ++port_no) {
- struct ata_port *ap;
- ap = host->ports[port_no];
- if (ap &&
- !(ap->flags & ATA_FLAG_DISABLED)) {
- struct ata_queued_cmd *qc;
- struct qs_port_priv *pp;
- qc = ata_qc_from_tag(ap, ap->link.active_tag);
- if (!qc || !(qc->flags & ATA_QCFLAG_ACTIVE)) {
- /*
- * The qstor hardware generates spurious
- * interrupts from time to time when switching
- * in and out of packet mode.
- * There's no obvious way to know if we're
- * here now due to that, so just ack the irq
- * and pretend we knew it was ours.. (ugh).
- * This does not affect packet mode.
- */
- ata_sff_check_status(ap);
- handled = 1;
- continue;
- }
- pp = ap->private_data;
- if (!pp || pp->state != qs_state_mmio)
- continue;
- if (!(qc->tf.flags & ATA_TFLAG_POLLING))
- handled |= ata_sff_host_intr(ap, qc);
+ struct ata_port *ap = host->ports[port_no];
+ struct qs_port_priv *pp = ap->private_data;
+ struct ata_queued_cmd *qc;
+
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ if (!qc) {
+ /*
+ * The qstor hardware generates spurious
+ * interrupts from time to time when switching
+ * in and out of packet mode. There's no
+ * obvious way to know if we're here now due
+ * to that, so just ack the irq and pretend we
+ * knew it was ours.. (ugh). This does not
+ * affect packet mode.
+ */
+ ata_sff_check_status(ap);
+ handled = 1;
+ continue;
}
+
+ if (!pp || pp->state != qs_state_mmio)
+ continue;
+ if (!(qc->tf.flags & ATA_TFLAG_POLLING))
+ handled |= ata_sff_host_intr(ap, qc);
}
return handled;
}
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 031d7b7..dce3b91 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -439,9 +439,6 @@ static irqreturn_t sil_interrupt(int irq, void *dev_instance)
struct ata_port *ap = host->ports[i];
u32 bmdma2 = readl(mmio_base + sil_port[ap->port_no].bmdma2);
- if (unlikely(!ap || ap->flags & ATA_FLAG_DISABLED))
- continue;
-
/* turn off SATA_IRQ if not supported */
if (ap->flags & SIL_FLAG_NO_SATA_IRQ)
bmdma2 &= ~SIL_DMA_SATA_IRQ;
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 4621807..e9e66e2 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -1151,13 +1151,8 @@ static irqreturn_t sil24_interrupt(int irq, void *dev_instance)
for (i = 0; i < host->n_ports; i++)
if (status & (1 << i)) {
- struct ata_port *ap = host->ports[i];
- if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
- sil24_host_intr(ap);
- handled++;
- } else
- printk(KERN_ERR DRV_NAME
- ": interrupt from disabled port %d\n", i);
+ sil24_host_intr(host->ports[i]);
+ handled++;
}
spin_unlock(&host->lock);
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index ec04b8d..8027f64 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -314,7 +314,6 @@ static void pdc_20621_phy_reset(struct ata_port *ap)
{
VPRINTK("ENTER\n");
ap->cbl = ATA_CBL_SATA;
- ata_port_probe(ap);
ata_bus_reset(ap);
}
@@ -839,8 +838,7 @@ static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance)
ap = host->ports[port_no];
tmp = mask & (1 << i);
VPRINTK("seq %u, port_no %u, ap %p, tmp %x\n", i, port_no, ap, tmp);
- if (tmp && ap &&
- !(ap->flags & ATA_FLAG_DISABLED)) {
+ if (tmp && ap) {
struct ata_queued_cmd *qc;
qc = ata_qc_from_tag(ap, ap->link.active_tag);
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index c57cdff..45bd21c 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -284,14 +284,8 @@ static irqreturn_t vsc_sata_interrupt(int irq, void *dev_instance)
for (i = 0; i < host->n_ports; i++) {
u8 port_status = (status >> (8 * i)) & 0xff;
if (port_status) {
- struct ata_port *ap = host->ports[i];
-
- if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
- vsc_port_intr(port_status, ap);
- handled++;
- } else
- dev_printk(KERN_ERR, host->dev,
- "interrupt from disabled port %d\n", i);
+ vsc_port_intr(port_status, host->ports[i]);
+ handled++;
}
}
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index 098739d..8ca7bd4 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3637,7 +3637,7 @@ static void ipr_slave_destroy(struct scsi_device *sdev)
res = (struct ipr_resource_entry *) sdev->hostdata;
if (res) {
if (res->sata_port)
- ata_port_disable(res->sata_port->ap);
+ res->sata_port->ap->link.device[0].class = ATA_DEV_NONE;
sdev->hostdata = NULL;
res->sdev = NULL;
res->sata_port = NULL;
@@ -5001,7 +5001,7 @@ static void ipr_ata_phy_reset(struct ata_port *ap)
rc = ipr_device_reset(ioa_cfg, res);
if (rc) {
- ata_port_disable(ap);
+ ap->link.device[0].class = ATA_DEV_NONE;
goto out_unlock;
}
@@ -5015,8 +5015,7 @@ static void ipr_ata_phy_reset(struct ata_port *ap)
ap->link.device[0].class = ATA_DEV_ATAPI;
break;
default:
- ap->link.device[0].class = ATA_DEV_UNKNOWN;
- ata_port_disable(ap);
+ ap->link.device[0].class = ATA_DEV_NONE;
break;
};
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c
index 7448387..cca1f1e 100644
--- a/drivers/scsi/libsas/sas_scsi_host.c
+++ b/drivers/scsi/libsas/sas_scsi_host.c
@@ -817,7 +817,7 @@ void sas_slave_destroy(struct scsi_device *scsi_dev)
struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
if (dev_is_sata(dev))
- ata_port_disable(dev->sata_dev.ap);
+ dev->sata_dev.ap->link.device[0].class = ATA_DEV_NONE;
}
int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index c261aa0..e0b8c24 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -199,12 +199,6 @@ enum {
ATA_FLAG_SW_ACTIVITY = (1 << 22), /* driver supports sw activity
* led */
- /* The following flag belongs to ap->pflags but is kept in
- * ap->flags because it's referenced in many LLDs and will be
- * removed in not-too-distant future.
- */
- ATA_FLAG_DISABLED = (1 << 23), /* port is disabled, ignore it */
-
/* bits 24:31 of ap->flags are reserved for LLD specific flags */
/* struct ata_port pflags */
@@ -888,7 +882,6 @@ static inline int ata_port_is_dummy(struct ata_port *ap)
return ap->ops == &ata_dummy_port_ops;
}
-extern void ata_port_probe(struct ata_port *);
extern int sata_set_spd(struct ata_link *link);
extern int ata_std_prereset(struct ata_link *link, unsigned long deadline);
extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
@@ -903,7 +896,6 @@ extern int sata_link_hardreset(struct ata_link *link,
extern int sata_std_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline);
extern void ata_std_postreset(struct ata_link *link, unsigned int *classes);
-extern void ata_port_disable(struct ata_port *);
extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports);
extern struct ata_host *ata_host_alloc_pinfo(struct device *dev,
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 07/22] sata_inic162x: kill PORT_PRD_ADDR initialization
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (5 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 06/22] libata: kill ATA_FLAG_DISABLED Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 08/22] libata-sff: reorder SFF/BMDMA functions Tejun Heo
` (20 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
sata_inic162x doesn't use PRD anymore. No need to initialize it.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/sata_inic162x.c | 3 +--
1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 9dd7559..e87349d 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -667,8 +667,7 @@ static void init_port(struct ata_port *ap)
memset(pp->pkt, 0, sizeof(struct inic_pkt));
memset(pp->cpb_tbl, 0, IDMA_CPB_TBL_SIZE);
- /* setup PRD and CPB lookup table addresses */
- writel(ap->prd_dma, port_base + PORT_PRD_ADDR);
+ /* setup CPB lookup table addresses */
writel(pp->cpb_tbl_dma, port_base + PORT_CPB_CPBLAR);
}
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 08/22] libata-sff: reorder SFF/BMDMA functions
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (6 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 07/22] sata_inic162x: kill PORT_PRD_ADDR initialization Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 09/22] pata_cmd640/bf54x/icside: fix inheritance Tejun Heo
` (19 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
Reorder functions such that SFF and BMDMA functions are grouped.
While at it, s/BMDMA/SFF in a few comments where it actually meant
SFF.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-sff.c | 610 +++++++++++++++++++++++-----------------------
include/linux/libata.h | 24 +-
2 files changed, 322 insertions(+), 312 deletions(-)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index dbb8695..2c5ebd1 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -67,17 +67,6 @@ const struct ata_port_operations ata_sff_port_ops = {
.port_start = ata_sff_port_start,
};
-const struct ata_port_operations ata_bmdma_port_ops = {
- .inherits = &ata_sff_port_ops,
-
- .mode_filter = ata_bmdma_mode_filter,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-};
-
/**
* ata_fill_sg - Fill PCI IDE PRD table
* @qc: Metadata associated with taskfile to be transferred
@@ -1590,7 +1579,7 @@ inline unsigned int ata_sff_host_intr(struct ata_port *ap,
if (status & ATA_BUSY)
goto idle_irq;
- /* ack bmdma irq events */
+ /* clear irq events */
ap->ops->sff_irq_clear(ap);
ata_sff_hsm_move(ap, qc, status, 0);
@@ -1657,7 +1646,7 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
* ata_sff_freeze - Freeze SFF controller port
* @ap: port to freeze
*
- * Freeze BMDMA controller port.
+ * Freeze SFF controller port.
*
* LOCKING:
* Inherited from caller.
@@ -2207,291 +2196,8 @@ void ata_sff_std_ports(struct ata_ioports *ioaddr)
ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD;
}
-unsigned long ata_bmdma_mode_filter(struct ata_device *adev,
- unsigned long xfer_mask)
-{
- /* Filter out DMA modes if the device has been configured by
- the BIOS as PIO only */
-
- if (adev->link->ap->ioaddr.bmdma_addr == NULL)
- xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
- return xfer_mask;
-}
-
-/**
- * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_bmdma_setup(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
- u8 dmactl;
-
- /* load PRD table addr. */
- mb(); /* make sure PRD table writes are visible to controller */
- iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
-
- /* specify data direction, triple-check start bit is clear */
- dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
- if (!rw)
- dmactl |= ATA_DMA_WR;
- iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
- /* issue r/w command */
- ap->ops->sff_exec_command(ap, &qc->tf);
-}
-
-/**
- * ata_bmdma_start - Start a PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_bmdma_start(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- u8 dmactl;
-
- /* start host DMA transaction */
- dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
- iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
-
- /* Strictly, one may wish to issue an ioread8() here, to
- * flush the mmio write. However, control also passes
- * to the hardware at this point, and it will interrupt
- * us when we are to resume control. So, in effect,
- * we don't care when the mmio write flushes.
- * Further, a read of the DMA status register _immediately_
- * following the write may not be what certain flaky hardware
- * is expected, so I think it is best to not add a readb()
- * without first all the MMIO ATA cards/mobos.
- * Or maybe I'm just being paranoid.
- *
- * FIXME: The posting of this write means I/O starts are
- * unneccessarily delayed for MMIO
- */
-}
-
-/**
- * ata_bmdma_stop - Stop PCI IDE BMDMA transfer
- * @qc: Command we are ending DMA for
- *
- * Clears the ATA_DMA_START flag in the dma control register
- *
- * May be used as the bmdma_stop() entry in ata_port_operations.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_bmdma_stop(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
- /* clear start/stop bit */
- iowrite8(ioread8(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
- mmio + ATA_DMA_CMD);
-
- /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
- ata_sff_dma_pause(ap);
-}
-
-/**
- * ata_bmdma_status - Read PCI IDE BMDMA status
- * @ap: Port associated with this ATA transaction.
- *
- * Read and return BMDMA status register.
- *
- * May be used as the bmdma_status() entry in ata_port_operations.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-u8 ata_bmdma_status(struct ata_port *ap)
-{
- return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
-}
-
-/**
- * ata_bus_reset - reset host port and associated ATA channel
- * @ap: port to reset
- *
- * This is typically the first time we actually start issuing
- * commands to the ATA channel. We wait for BSY to clear, then
- * issue EXECUTE DEVICE DIAGNOSTIC command, polling for its
- * result. Determine what devices, if any, are on the channel
- * by looking at the device 0/1 error register. Look at the signature
- * stored in each device's taskfile registers, to determine if
- * the device is ATA or ATAPI.
- *
- * LOCKING:
- * PCI/etc. bus probe sem.
- * Obtains host lock.
- *
- * DEPRECATED:
- * This function is only for drivers which still use old EH and
- * will be removed soon.
- */
-void ata_bus_reset(struct ata_port *ap)
-{
- struct ata_device *device = ap->link.device;
- struct ata_ioports *ioaddr = &ap->ioaddr;
- unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
- u8 err;
- unsigned int dev0, dev1 = 0, devmask = 0;
- int rc;
-
- DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no);
-
- /* determine if device 0/1 are present */
- if (ap->flags & ATA_FLAG_SATA_RESET)
- dev0 = 1;
- else {
- dev0 = ata_devchk(ap, 0);
- if (slave_possible)
- dev1 = ata_devchk(ap, 1);
- }
-
- if (dev0)
- devmask |= (1 << 0);
- if (dev1)
- devmask |= (1 << 1);
-
- /* select device 0 again */
- ap->ops->sff_dev_select(ap, 0);
-
- /* issue bus reset */
- if (ap->flags & ATA_FLAG_SRST) {
- rc = ata_bus_softreset(ap, devmask,
- ata_deadline(jiffies, 40000));
- if (rc && rc != -ENODEV)
- goto err_out;
- }
-
- /*
- * determine by signature whether we have ATA or ATAPI devices
- */
- device[0].class = ata_sff_dev_classify(&device[0], dev0, &err);
- if ((slave_possible) && (err != 0x81))
- device[1].class = ata_sff_dev_classify(&device[1], dev1, &err);
-
- /* is double-select really necessary? */
- if (device[1].class != ATA_DEV_NONE)
- ap->ops->sff_dev_select(ap, 1);
- if (device[0].class != ATA_DEV_NONE)
- ap->ops->sff_dev_select(ap, 0);
-
- /* if no devices were detected, disable this port */
- if ((device[0].class == ATA_DEV_NONE) &&
- (device[1].class == ATA_DEV_NONE))
- goto err_out;
-
- if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
- /* set up device control for ATA_FLAG_SATA_RESET */
- iowrite8(ap->ctl, ioaddr->ctl_addr);
- }
-
- DPRINTK("EXIT\n");
- return;
-
-err_out:
- device[0].class = ATA_DEV_NONE;
- device[1].class = ATA_DEV_NONE;
- ata_port_printk(ap, KERN_ERR, "giving up port\n");
-
- DPRINTK("EXIT\n");
-}
-
#ifdef CONFIG_PCI
-/**
- * ata_pci_bmdma_clear_simplex - attempt to kick device out of simplex
- * @pdev: PCI device
- *
- * Some PCI ATA devices report simplex mode but in fact can be told to
- * enter non simplex mode. This implements the necessary logic to
- * perform the task on such devices. Calling it on other devices will
- * have -undefined- behaviour.
- */
-int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev)
-{
- unsigned long bmdma = pci_resource_start(pdev, 4);
- u8 simplex;
-
- if (bmdma == 0)
- return -ENOENT;
-
- simplex = inb(bmdma + 0x02);
- outb(simplex & 0x60, bmdma + 0x02);
- simplex = inb(bmdma + 0x02);
- if (simplex & 0x80)
- return -EOPNOTSUPP;
- return 0;
-}
-
-/**
- * ata_pci_bmdma_init - acquire PCI BMDMA resources and init ATA host
- * @host: target ATA host
- *
- * Acquire PCI BMDMA resources and initialize @host accordingly.
- *
- * LOCKING:
- * Inherited from calling layer (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-int ata_pci_bmdma_init(struct ata_host *host)
-{
- struct device *gdev = host->dev;
- struct pci_dev *pdev = to_pci_dev(gdev);
- int i, rc;
-
- /* No BAR4 allocation: No DMA */
- if (pci_resource_start(pdev, 4) == 0)
- return 0;
-
- /* TODO: If we get no DMA mask we should fall back to PIO */
- rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
- rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
-
- /* request and iomap DMA region */
- rc = pcim_iomap_regions(pdev, 1 << 4, dev_driver_string(gdev));
- if (rc) {
- dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n");
- return -ENOMEM;
- }
- host->iomap = pcim_iomap_table(pdev);
-
- for (i = 0; i < 2; i++) {
- struct ata_port *ap = host->ports[i];
- void __iomem *bmdma = host->iomap[4] + 8 * i;
-
- if (ata_port_is_dummy(ap))
- continue;
-
- ap->ioaddr.bmdma_addr = bmdma;
- if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
- (ioread8(bmdma + 2) & 0x80))
- host->flags |= ATA_HOST_SIMPLEX;
-
- ata_port_desc(ap, "bmdma 0x%llx",
- (unsigned long long)pci_resource_start(pdev, 4) + 8 * i);
- }
-
- return 0;
-}
-
static int ata_resources_present(struct pci_dev *pdev, int port)
{
int i;
@@ -2811,8 +2517,305 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
#endif /* CONFIG_PCI */
+/**
+ * ata_bus_reset - reset host port and associated ATA channel
+ * @ap: port to reset
+ *
+ * This is typically the first time we actually start issuing
+ * commands to the ATA channel. We wait for BSY to clear, then
+ * issue EXECUTE DEVICE DIAGNOSTIC command, polling for its
+ * result. Determine what devices, if any, are on the channel
+ * by looking at the device 0/1 error register. Look at the signature
+ * stored in each device's taskfile registers, to determine if
+ * the device is ATA or ATAPI.
+ *
+ * LOCKING:
+ * PCI/etc. bus probe sem.
+ * Obtains host lock.
+ *
+ * DEPRECATED:
+ * This function is only for drivers which still use old EH and
+ * will be removed soon.
+ */
+void ata_bus_reset(struct ata_port *ap)
+{
+ struct ata_device *device = ap->link.device;
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+ unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
+ u8 err;
+ unsigned int dev0, dev1 = 0, devmask = 0;
+ int rc;
+
+ DPRINTK("ENTER, host %u, port %u\n", ap->print_id, ap->port_no);
+
+ /* determine if device 0/1 are present */
+ if (ap->flags & ATA_FLAG_SATA_RESET)
+ dev0 = 1;
+ else {
+ dev0 = ata_devchk(ap, 0);
+ if (slave_possible)
+ dev1 = ata_devchk(ap, 1);
+ }
+
+ if (dev0)
+ devmask |= (1 << 0);
+ if (dev1)
+ devmask |= (1 << 1);
+
+ /* select device 0 again */
+ ap->ops->sff_dev_select(ap, 0);
+
+ /* issue bus reset */
+ if (ap->flags & ATA_FLAG_SRST) {
+ rc = ata_bus_softreset(ap, devmask,
+ ata_deadline(jiffies, 40000));
+ if (rc && rc != -ENODEV)
+ goto err_out;
+ }
+
+ /*
+ * determine by signature whether we have ATA or ATAPI devices
+ */
+ device[0].class = ata_sff_dev_classify(&device[0], dev0, &err);
+ if ((slave_possible) && (err != 0x81))
+ device[1].class = ata_sff_dev_classify(&device[1], dev1, &err);
+
+ /* is double-select really necessary? */
+ if (device[1].class != ATA_DEV_NONE)
+ ap->ops->sff_dev_select(ap, 1);
+ if (device[0].class != ATA_DEV_NONE)
+ ap->ops->sff_dev_select(ap, 0);
+
+ /* if no devices were detected, disable this port */
+ if ((device[0].class == ATA_DEV_NONE) &&
+ (device[1].class == ATA_DEV_NONE))
+ goto err_out;
+
+ if (ap->flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST)) {
+ /* set up device control for ATA_FLAG_SATA_RESET */
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
+ }
+
+ DPRINTK("EXIT\n");
+ return;
+
+err_out:
+ device[0].class = ATA_DEV_NONE;
+ device[1].class = ATA_DEV_NONE;
+ ata_port_printk(ap, KERN_ERR, "giving up port\n");
+
+ DPRINTK("EXIT\n");
+}
+
+const struct ata_port_operations ata_bmdma_port_ops = {
+ .inherits = &ata_sff_port_ops,
+
+ .mode_filter = ata_bmdma_mode_filter,
+
+ .bmdma_setup = ata_bmdma_setup,
+ .bmdma_start = ata_bmdma_start,
+ .bmdma_stop = ata_bmdma_stop,
+ .bmdma_status = ata_bmdma_status,
+};
+
+unsigned long ata_bmdma_mode_filter(struct ata_device *adev,
+ unsigned long xfer_mask)
+{
+ /* Filter out DMA modes if the device has been configured by
+ the BIOS as PIO only */
+
+ if (adev->link->ap->ioaddr.bmdma_addr == NULL)
+ xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
+ return xfer_mask;
+}
+
+/**
+ * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
+ * @qc: Info associated with this ATA transaction.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+void ata_bmdma_setup(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
+ u8 dmactl;
+
+ /* load PRD table addr. */
+ mb(); /* make sure PRD table writes are visible to controller */
+ iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
+
+ /* specify data direction, triple-check start bit is clear */
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
+ if (!rw)
+ dmactl |= ATA_DMA_WR;
+ iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+
+ /* issue r/w command */
+ ap->ops->sff_exec_command(ap, &qc->tf);
+}
+
+/**
+ * ata_bmdma_start - Start a PCI IDE BMDMA transaction
+ * @qc: Info associated with this ATA transaction.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+void ata_bmdma_start(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ u8 dmactl;
+
+ /* start host DMA transaction */
+ dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+ iowrite8(dmactl | ATA_DMA_START, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
+
+ /* Strictly, one may wish to issue an ioread8() here, to
+ * flush the mmio write. However, control also passes
+ * to the hardware at this point, and it will interrupt
+ * us when we are to resume control. So, in effect,
+ * we don't care when the mmio write flushes.
+ * Further, a read of the DMA status register _immediately_
+ * following the write may not be what certain flaky hardware
+ * is expected, so I think it is best to not add a readb()
+ * without first all the MMIO ATA cards/mobos.
+ * Or maybe I'm just being paranoid.
+ *
+ * FIXME: The posting of this write means I/O starts are
+ * unneccessarily delayed for MMIO
+ */
+}
+
+/**
+ * ata_bmdma_stop - Stop PCI IDE BMDMA transfer
+ * @qc: Command we are ending DMA for
+ *
+ * Clears the ATA_DMA_START flag in the dma control register
+ *
+ * May be used as the bmdma_stop() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+void ata_bmdma_stop(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+ /* clear start/stop bit */
+ iowrite8(ioread8(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
+ mmio + ATA_DMA_CMD);
+
+ /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
+ ata_sff_dma_pause(ap);
+}
+
+/**
+ * ata_bmdma_status - Read PCI IDE BMDMA status
+ * @ap: Port associated with this ATA transaction.
+ *
+ * Read and return BMDMA status register.
+ *
+ * May be used as the bmdma_status() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+u8 ata_bmdma_status(struct ata_port *ap)
+{
+ return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+}
+
+#ifdef CONFIG_PCI
+
+/**
+ * ata_pci_bmdma_clear_simplex - attempt to kick device out of simplex
+ * @pdev: PCI device
+ *
+ * Some PCI ATA devices report simplex mode but in fact can be told to
+ * enter non simplex mode. This implements the necessary logic to
+ * perform the task on such devices. Calling it on other devices will
+ * have -undefined- behaviour.
+ */
+int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev)
+{
+ unsigned long bmdma = pci_resource_start(pdev, 4);
+ u8 simplex;
+
+ if (bmdma == 0)
+ return -ENOENT;
+
+ simplex = inb(bmdma + 0x02);
+ outb(simplex & 0x60, bmdma + 0x02);
+ simplex = inb(bmdma + 0x02);
+ if (simplex & 0x80)
+ return -EOPNOTSUPP;
+ return 0;
+}
+
+/**
+ * ata_pci_bmdma_init - acquire PCI BMDMA resources and init ATA host
+ * @host: target ATA host
+ *
+ * Acquire PCI BMDMA resources and initialize @host accordingly.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_pci_bmdma_init(struct ata_host *host)
+{
+ struct device *gdev = host->dev;
+ struct pci_dev *pdev = to_pci_dev(gdev);
+ int i, rc;
+
+ /* No BAR4 allocation: No DMA */
+ if (pci_resource_start(pdev, 4) == 0)
+ return 0;
+
+ /* TODO: If we get no DMA mask we should fall back to PIO */
+ rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ return rc;
+
+ /* request and iomap DMA region */
+ rc = pcim_iomap_regions(pdev, 1 << 4, dev_driver_string(gdev));
+ if (rc) {
+ dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n");
+ return -ENOMEM;
+ }
+ host->iomap = pcim_iomap_table(pdev);
+
+ for (i = 0; i < 2; i++) {
+ struct ata_port *ap = host->ports[i];
+ void __iomem *bmdma = host->iomap[4] + 8 * i;
+
+ if (ata_port_is_dummy(ap))
+ continue;
+
+ ap->ioaddr.bmdma_addr = bmdma;
+ if ((!(ap->flags & ATA_FLAG_IGN_SIMPLEX)) &&
+ (ioread8(bmdma + 2) & 0x80))
+ host->flags |= ATA_HOST_SIMPLEX;
+
+ ata_port_desc(ap, "bmdma 0x%llx",
+ (unsigned long long)pci_resource_start(pdev, 4) + 8 * i);
+ }
+
+ return 0;
+}
+
+#endif /* CONFIG_PCI */
+
EXPORT_SYMBOL_GPL(ata_sff_port_ops);
-EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
EXPORT_SYMBOL_GPL(ata_sff_qc_prep);
EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep);
EXPORT_SYMBOL_GPL(ata_sff_dev_select);
@@ -2845,17 +2848,20 @@ EXPORT_SYMBOL_GPL(ata_sff_error_handler);
EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd);
EXPORT_SYMBOL_GPL(ata_sff_port_start);
EXPORT_SYMBOL_GPL(ata_sff_std_ports);
+#ifdef CONFIG_PCI
+EXPORT_SYMBOL_GPL(ata_pci_sff_init_host);
+EXPORT_SYMBOL_GPL(ata_pci_sff_prepare_host);
+EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
+EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
+#endif /* CONFIG_PCI */
+EXPORT_SYMBOL_GPL(ata_bus_reset);
+EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
EXPORT_SYMBOL_GPL(ata_bmdma_mode_filter);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
EXPORT_SYMBOL_GPL(ata_bmdma_start);
EXPORT_SYMBOL_GPL(ata_bmdma_stop);
EXPORT_SYMBOL_GPL(ata_bmdma_status);
-EXPORT_SYMBOL_GPL(ata_bus_reset);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
-EXPORT_SYMBOL_GPL(ata_pci_sff_init_host);
-EXPORT_SYMBOL_GPL(ata_pci_sff_prepare_host);
-EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
-EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
#endif /* CONFIG_PCI */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index e0b8c24..c7fb1a2 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1523,17 +1523,7 @@ extern void ata_sff_error_handler(struct ata_port *ap);
extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc);
extern int ata_sff_port_start(struct ata_port *ap);
extern void ata_sff_std_ports(struct ata_ioports *ioaddr);
-extern unsigned long ata_bmdma_mode_filter(struct ata_device *dev,
- unsigned long xfer_mask);
-extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
-extern void ata_bmdma_start(struct ata_queued_cmd *qc);
-extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
-extern u8 ata_bmdma_status(struct ata_port *ap);
-extern void ata_bus_reset(struct ata_port *ap);
-
#ifdef CONFIG_PCI
-extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev);
-extern int ata_pci_bmdma_init(struct ata_host *host);
extern int ata_pci_sff_init_host(struct ata_host *host);
extern int ata_pci_sff_prepare_host(struct pci_dev *pdev,
const struct ata_port_info * const * ppi,
@@ -1546,6 +1536,20 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev,
struct scsi_host_template *sht, void *host_priv);
#endif /* CONFIG_PCI */
+extern void ata_bus_reset(struct ata_port *ap); /* deprecated */
+
+extern unsigned long ata_bmdma_mode_filter(struct ata_device *dev,
+ unsigned long xfer_mask);
+extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
+extern void ata_bmdma_start(struct ata_queued_cmd *qc);
+extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
+extern u8 ata_bmdma_status(struct ata_port *ap);
+
+#ifdef CONFIG_PCI
+extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev);
+extern int ata_pci_bmdma_init(struct ata_host *host);
+#endif /* CONFIG_PCI */
+
/**
* ata_sff_busy_wait - Wait for a port status register
* @ap: Port to wait for.
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 09/22] pata_cmd640/bf54x/icside: fix inheritance
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (7 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 08/22] libata-sff: reorder SFF/BMDMA functions Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 10/22] libata-sff: clean up BMDMA initialization Tejun Heo
` (18 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
cmd640 is PIO only while bf54x and icside are BMDMAs. Fix
inheritance. bf54x and icside are quasi-BMDMA controllers which don't
use the standard BMDMA registers so they don't initialize bmdma_addr
and inherited from sff to avoid the default mode_filter which disables
DMA modes if bmdma_addr is not initialized.
This patch makes both drivers explicitly specify ->mode_filter to
ATA_OP_NULL while inheriting from ata_bmdma_port_ops. These will be
removed by the next patch.
This patch makes all and only BMDMA drivers inherit from
ata_bmdma_port_ops to ease further SFF/BMDMA separation.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/pata_bf54x.c | 4 +++-
drivers/ata/pata_cmd640.c | 4 ++--
drivers/ata/pata_icside.c | 4 +++-
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index b833328..27cd40a 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1460,7 +1460,7 @@ static struct scsi_host_template bfin_sht = {
};
static struct ata_port_operations bfin_pata_ops = {
- .inherits = &ata_sff_port_ops,
+ .inherits = &ata_bmdma_port_ops,
.set_piomode = bfin_set_piomode,
.set_dmamode = bfin_set_dmamode,
@@ -1490,6 +1490,8 @@ static struct ata_port_operations bfin_pata_ops = {
.port_start = bfin_port_start,
.port_stop = bfin_port_stop,
+
+ .mode_filter = ATA_OP_NULL, /* will be removed soon */
};
static struct ata_port_info bfin_port_info[] = {
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
index 2de30b9..4b2612b 100644
--- a/drivers/ata/pata_cmd640.c
+++ b/drivers/ata/pata_cmd640.c
@@ -166,11 +166,11 @@ static int cmd640_port_start(struct ata_port *ap)
}
static struct scsi_host_template cmd640_sht = {
- ATA_BMDMA_SHT(DRV_NAME),
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations cmd640_port_ops = {
- .inherits = &ata_bmdma_port_ops,
+ .inherits = &ata_sff_port_ops,
/* In theory xfer_noirq is not needed once we kill the prefetcher */
.sff_data_xfer = ata_sff_data_xfer_noirq,
.qc_issue = cmd640_qc_issue,
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index cf9e984..f2623c6 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -333,7 +333,7 @@ static void pata_icside_postreset(struct ata_link *link, unsigned int *classes)
}
static struct ata_port_operations pata_icside_port_ops = {
- .inherits = &ata_sff_port_ops,
+ .inherits = &ata_bmdma_port_ops,
/* no need to build any PRD tables for DMA */
.qc_prep = ata_noop_qc_prep,
.sff_data_xfer = ata_sff_data_xfer_noirq,
@@ -346,6 +346,8 @@ static struct ata_port_operations pata_icside_port_ops = {
.set_dmamode = pata_icside_set_dmamode,
.postreset = pata_icside_postreset,
.post_internal_cmd = pata_icside_bmdma_stop,
+
+ .mode_filter = ATA_OP_NULL, /* will be removed soon */
};
static void __devinit
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 10/22] libata-sff: clean up BMDMA initialization
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (8 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 09/22] pata_cmd640/bf54x/icside: fix inheritance Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-28 4:16 ` Jeff Garzik
2008-10-21 9:17 ` [PATCH 11/22] libata-sff: introduce ata_sff_init/exit() and ata_sff_port_init() Tejun Heo
` (17 subsequent siblings)
27 siblings, 1 reply; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
When BMDMA initialization failed or BMDMA was not available for
whatever reason, bmdma_addr was left at zero and used as indication
that BMDMA shouldn't be used. This leads to the following problems.
p1. For BMDMA drivers which don't use traditional BMDMA register,
ata_bmdma_mode_filter() incorrectly inhibits DMA modes. Those
drivers either have to inherit from ata_sff_port_ops or clear
->mode_filter explicitly.
p2. non-BMDMA drivers call into BMDMA PRD table allocation. It
doesn't actually allocate PRD table if bmdma_addr is not
initialized but is still confusing.
p3. For BMDMA drivers which don't use traditional BMDMA register, some
methods might not be invoked as expected (e.g. bmdma_stop from
ata_sff_post_internal_cmd()).
p4. SFF drivers w/ custom DMA interface implement noop BMDMA ops
worrying libata core might call into one of them.
These problems are caused by the muddy line between SFF and BMDMA and
the assumption that all BMDMA controllers initialize bmdma_addr.
This patch fixes #1 and #2 by removing the bmdma_addr assumption and
moving prd allocation to BMDMA port start. Following patches will fix
the remaining issues.
This patch improves BMDMA initialization such that
* When BMDMA register initialization fails, falls back to PIO instead
of failing. ata_pci_bmdma_init() never fails now.
* When ata_pci_bmdma_init() falls back to PIO, it clears
ap->mwdma_mask and udma_mask instead of depending on
ata_bmdma_mode_filter(). This makes ata_bmdma_mode_filter()
unnecessary and p1 is removed.
* ata_port_start() which actually is BMDMA specific is moved to
ata_bmdma_port_start(). ata_port_start() and ata_sff_port_start()
are killed.
Drivers which no longer calls into PRD table allocation are...
pdc_adma, sata_inic162x, sata_qstor, sata_sx4, pata_cmd640 and all
drivers which inherit from ata_sff_port_ops.
pata_icside sets ->port_start to ATA_OP_NULL as it doesn't need PRD
but is a BMDMA controller and doesn't have custom port_start like
other such controllers.
Note that with the previous patch which makes all and only BMDMA
drivers inherit from ata_bmdma_port_ops, this change doesn't break
drivers which need PRD table.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-core.c | 25 --------
drivers/ata/libata-sff.c | 122 +++++++++++++++++++--------------------
drivers/ata/pata_acpi.c | 4 +-
drivers/ata/pata_ali.c | 2 +-
drivers/ata/pata_bf54x.c | 2 -
drivers/ata/pata_cmd640.c | 6 +--
drivers/ata/pata_hpt366.c | 2 +-
drivers/ata/pata_hpt37x.c | 4 +-
drivers/ata/pata_icside.c | 2 +-
drivers/ata/pata_it821x.c | 2 +-
drivers/ata/pata_pdc2027x.c | 4 +-
drivers/ata/pata_pdc202xx_old.c | 2 +-
drivers/ata/pata_platform.c | 1 -
drivers/ata/pata_scc.c | 6 +-
drivers/ata/pata_serverworks.c | 6 +-
drivers/ata/pdc_adma.c | 4 -
drivers/ata/sata_inic162x.c | 5 --
drivers/ata/sata_nv.c | 6 +-
drivers/ata/sata_promise.c | 3 +-
drivers/ata/sata_qstor.c | 4 -
drivers/ata/sata_sx4.c | 5 --
drivers/ata/sata_uli.c | 4 +-
include/linux/libata.h | 7 +--
23 files changed, 87 insertions(+), 141 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 231e967..05e31c2 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5148,30 +5148,6 @@ void ata_host_resume(struct ata_host *host)
#endif
/**
- * ata_port_start - Set port up for dma.
- * @ap: Port to initialize
- *
- * Called just after data structures for each port are
- * initialized. Allocates space for PRD table.
- *
- * May be used as the port_start() entry in ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-int ata_port_start(struct ata_port *ap)
-{
- struct device *dev = ap->dev;
-
- ap->prd = dmam_alloc_coherent(dev, ATA_PRD_TBL_SZ, &ap->prd_dma,
- GFP_KERNEL);
- if (!ap->prd)
- return -ENOMEM;
-
- return 0;
-}
-
-/**
* ata_dev_init - Initialize an ata_device structure
* @dev: Device structure to initialize
*
@@ -6403,7 +6379,6 @@ EXPORT_SYMBOL_GPL(ata_xfer_mode2mask);
EXPORT_SYMBOL_GPL(ata_xfer_mode2shift);
EXPORT_SYMBOL_GPL(ata_mode_string);
EXPORT_SYMBOL_GPL(ata_id_xfermask);
-EXPORT_SYMBOL_GPL(ata_port_start);
EXPORT_SYMBOL_GPL(ata_do_set_mode);
EXPORT_SYMBOL_GPL(ata_std_qc_defer);
EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 2c5ebd1..0e4814b 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -63,8 +63,6 @@ const struct ata_port_operations ata_sff_port_ops = {
.sff_data_xfer = ata_sff_data_xfer,
.sff_irq_on = ata_sff_irq_on,
.sff_irq_clear = ata_sff_irq_clear,
-
- .port_start = ata_sff_port_start,
};
/**
@@ -2152,26 +2150,6 @@ void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc)
}
/**
- * ata_sff_port_start - Set port up for dma.
- * @ap: Port to initialize
- *
- * Called just after data structures for each port are
- * initialized. Allocates space for PRD table if the device
- * is DMA capable SFF.
- *
- * May be used as the port_start() entry in ata_port_operations.
- *
- * LOCKING:
- * Inherited from caller.
- */
-int ata_sff_port_start(struct ata_port *ap)
-{
- if (ap->ioaddr.bmdma_addr)
- return ata_port_start(ap);
- return 0;
-}
-
-/**
* ata_sff_std_ports - initialize ioaddr with standard port offsets.
* @ioaddr: IO address structure to be initialized
*
@@ -2328,21 +2306,12 @@ int ata_pci_sff_prepare_host(struct pci_dev *pdev,
goto err_out;
/* init DMA related stuff */
- rc = ata_pci_bmdma_init(host);
- if (rc)
- goto err_bmdma;
+ ata_pci_bmdma_init(host);
devres_remove_group(&pdev->dev, NULL);
*r_host = host;
return 0;
- err_bmdma:
- /* This is necessary because PCI and iomap resources are
- * merged and releasing the top group won't release the
- * acquired resources if some of those have been acquired
- * before entering this function.
- */
- pcim_iounmap_regions(pdev, 0xf);
err_out:
devres_release_group(&pdev->dev, NULL);
return rc;
@@ -2610,24 +2579,13 @@ err_out:
const struct ata_port_operations ata_bmdma_port_ops = {
.inherits = &ata_sff_port_ops,
- .mode_filter = ata_bmdma_mode_filter,
-
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
.bmdma_status = ata_bmdma_status,
-};
-unsigned long ata_bmdma_mode_filter(struct ata_device *adev,
- unsigned long xfer_mask)
-{
- /* Filter out DMA modes if the device has been configured by
- the BIOS as PIO only */
-
- if (adev->link->ap->ioaddr.bmdma_addr == NULL)
- xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
- return xfer_mask;
-}
+ .port_start = ata_bmdma_port_start,
+};
/**
* ata_bmdma_setup - Set up PCI IDE BMDMA transaction
@@ -2729,6 +2687,30 @@ u8 ata_bmdma_status(struct ata_port *ap)
return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
}
+/**
+ * ata_bmdma_port_start - Set port up for bmdma.
+ * @ap: Port to initialize
+ *
+ * Called just after data structures for each port are
+ * initialized. Allocates space for PRD table.
+ *
+ * May be used as the port_start() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+int ata_bmdma_port_start(struct ata_port *ap)
+{
+ if (ap->mwdma_mask || ap->udma_mask) {
+ ap->prd = dmam_alloc_coherent(ap->host->dev, ATA_PRD_TBL_SZ,
+ &ap->prd_dma, GFP_KERNEL);
+ if (!ap->prd)
+ return -ENOMEM;
+ }
+
+ return 0;
+}
+
#ifdef CONFIG_PCI
/**
@@ -2756,6 +2738,19 @@ int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev)
return 0;
}
+static void ata_bmdma_nodma(struct ata_host *host, const char *reason)
+{
+ int i;
+
+ dev_printk(KERN_ERR, host->dev, "BMDMA: %s, falling back to PIO\n",
+ reason);
+
+ for (i = 0; i < 2; i++) {
+ host->ports[i]->mwdma_mask = 0;
+ host->ports[i]->udma_mask = 0;
+ }
+}
+
/**
* ata_pci_bmdma_init - acquire PCI BMDMA resources and init ATA host
* @host: target ATA host
@@ -2764,33 +2759,39 @@ int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev)
*
* LOCKING:
* Inherited from calling layer (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
*/
-int ata_pci_bmdma_init(struct ata_host *host)
+void ata_pci_bmdma_init(struct ata_host *host)
{
struct device *gdev = host->dev;
struct pci_dev *pdev = to_pci_dev(gdev);
int i, rc;
/* No BAR4 allocation: No DMA */
- if (pci_resource_start(pdev, 4) == 0)
- return 0;
+ if (pci_resource_start(pdev, 4) == 0) {
+ ata_bmdma_nodma(host, "BAR4 is zero");
+ return;
+ }
- /* TODO: If we get no DMA mask we should fall back to PIO */
+ /* Some controllers require BMDMA region to be initialized
+ * even if DMA is not in use to clear IRQ status via
+ * ->sff_irq_clear method. Try to initialize bmdma_addr
+ * regardless of dma masks.
+ */
rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
if (rc)
- return rc;
- rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
- if (rc)
- return rc;
+ ata_bmdma_nodma(host, "failed to set dma mask");
+ if (!rc) {
+ rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
+ if (rc)
+ ata_bmdma_nodma(host,
+ "failed to set consistent dma mask");
+ }
/* request and iomap DMA region */
rc = pcim_iomap_regions(pdev, 1 << 4, dev_driver_string(gdev));
if (rc) {
- dev_printk(KERN_ERR, gdev, "failed to request/iomap BAR4\n");
- return -ENOMEM;
+ ata_bmdma_nodma(host, "failed to request/iomap BAR4");
+ return;
}
host->iomap = pcim_iomap_table(pdev);
@@ -2809,8 +2810,6 @@ int ata_pci_bmdma_init(struct ata_host *host)
ata_port_desc(ap, "bmdma 0x%llx",
(unsigned long long)pci_resource_start(pdev, 4) + 8 * i);
}
-
- return 0;
}
#endif /* CONFIG_PCI */
@@ -2846,7 +2845,6 @@ EXPORT_SYMBOL_GPL(sata_sff_hardreset);
EXPORT_SYMBOL_GPL(ata_sff_postreset);
EXPORT_SYMBOL_GPL(ata_sff_error_handler);
EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd);
-EXPORT_SYMBOL_GPL(ata_sff_port_start);
EXPORT_SYMBOL_GPL(ata_sff_std_ports);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(ata_pci_sff_init_host);
@@ -2856,11 +2854,11 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
#endif /* CONFIG_PCI */
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
-EXPORT_SYMBOL_GPL(ata_bmdma_mode_filter);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
EXPORT_SYMBOL_GPL(ata_bmdma_start);
EXPORT_SYMBOL_GPL(ata_bmdma_stop);
EXPORT_SYMBOL_GPL(ata_bmdma_status);
+EXPORT_SYMBOL_GPL(ata_bmdma_port_start);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index eb919c1..d701e28 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -106,7 +106,7 @@ static unsigned long pacpi_discover_modes(struct ata_port *ap, struct ata_device
static unsigned long pacpi_mode_filter(struct ata_device *adev, unsigned long mask)
{
struct pata_acpi *acpi = adev->link->ap->private_data;
- return ata_bmdma_mode_filter(adev, mask & acpi->mask[adev->devno]);
+ return mask & acpi->mask[adev->devno];
}
/**
@@ -210,7 +210,7 @@ static int pacpi_port_start(struct ata_port *ap)
return -ENOMEM;
acpi->mask[0] = pacpi_discover_modes(ap, &ap->link.device[0]);
acpi->mask[1] = pacpi_discover_modes(ap, &ap->link.device[1]);
- ret = ata_sff_port_start(ap);
+ ret = ata_bmdma_port_start(ap);
if (ret < 0)
return ret;
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 5ca70fa..171a49e 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -121,7 +121,7 @@ static unsigned long ali_20_filter(struct ata_device *adev, unsigned long mask)
ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
if (strstr(model_num, "WDC"))
return mask &= ~ATA_MASK_UDMA;
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
}
/**
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index 27cd40a..de3e45f 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1490,8 +1490,6 @@ static struct ata_port_operations bfin_pata_ops = {
.port_start = bfin_port_start,
.port_stop = bfin_port_stop,
-
- .mode_filter = ATA_OP_NULL, /* will be removed soon */
};
static struct ata_port_info bfin_port_info[] = {
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
index 4b2612b..32f0602 100644
--- a/drivers/ata/pata_cmd640.c
+++ b/drivers/ata/pata_cmd640.c
@@ -153,16 +153,12 @@ static int cmd640_port_start(struct ata_port *ap)
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
struct cmd640_reg *timing;
- int ret = ata_sff_port_start(ap);
- if (ret < 0)
- return ret;
-
timing = devm_kzalloc(&pdev->dev, sizeof(struct cmd640_reg), GFP_KERNEL);
if (timing == NULL)
return -ENOMEM;
timing->last = -1; /* Force a load */
ap->private_data = timing;
- return ret;
+ return 0;
}
static struct scsi_host_template cmd640_sht = {
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index f2b83ea..d7b0bc5 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -184,7 +184,7 @@ static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask)
if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
mask &= ~(0xF0 << ATA_SHIFT_UDMA);
}
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
}
/**
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 4216399..b380d57 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -283,7 +283,7 @@ static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
}
/**
@@ -299,7 +299,7 @@ static unsigned long hpt370a_filter(struct ata_device *adev, unsigned long mask)
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
}
/**
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index f2623c6..4485e86 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -347,7 +347,7 @@ static struct ata_port_operations pata_icside_port_ops = {
.postreset = pata_icside_postreset,
.post_internal_cmd = pata_icside_bmdma_stop,
- .mode_filter = ATA_OP_NULL, /* will be removed soon */
+ .port_start = ATA_OP_NULL, /* don't need PRD table */
};
static void __devinit
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 0221c9a..27c5968 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -740,7 +740,7 @@ static int it821x_port_start(struct ata_port *ap)
struct it821x_dev *itdev;
u8 conf;
- int ret = ata_sff_port_start(ap);
+ int ret = ata_bmdma_port_start(ap);
if (ret < 0)
return ret;
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index 0e1c2c1..dfecd1a 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -265,7 +265,7 @@ static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long
struct ata_device *pair = ata_dev_pair(adev);
if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL)
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
/* Check for slave of a Maxtor at UDMA6 */
ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
@@ -274,7 +274,7 @@ static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long
if (strstr(model_num, "Maxtor") == NULL && pair->dma_mode == XFER_UDMA_6)
mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
}
/**
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index d267306..b452e4a 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -240,7 +240,7 @@ static int pdc2026x_port_start(struct ata_port *ap)
u8 burst = ioread8(bmdma + 0x1f);
iowrite8(burst | 0x01, bmdma + 0x1f);
}
- return ata_sff_port_start(ap);
+ return ata_bmdma_port_start(ap);
}
/**
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index 8f65ad6..ddf315a 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -55,7 +55,6 @@ static struct ata_port_operations pata_platform_port_ops = {
.sff_data_xfer = ata_sff_data_xfer_noirq,
.cable_detect = ata_cable_unknown,
.set_mode = pata_platform_set_mode,
- .port_start = ATA_OP_NULL,
};
static void pata_platform_setup_port(struct ata_ioports *ioaddr,
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 16673d1..12b9f43 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -266,7 +266,7 @@ unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask)
printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
}
/**
@@ -931,7 +931,7 @@ static void scc_irq_clear (struct ata_port *ap)
* scc_port_start - Set port up for dma.
* @ap: Port to initialize
*
- * Allocate space for PRD table using ata_port_start().
+ * Allocate space for PRD table using ata_bmdma_port_start().
* Set PRD table address for PTERADD. (PRD Transfer End Read)
*/
@@ -940,7 +940,7 @@ static int scc_port_start (struct ata_port *ap)
void __iomem *mmio = ap->ioaddr.bmdma_addr;
int rc;
- rc = ata_port_start(ap);
+ rc = ata_bmdma_port_start(ap);
if (rc)
return rc;
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index ffd26d0..d1be370 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -199,7 +199,7 @@ static unsigned long serverworks_osb4_filter(struct ata_device *adev, unsigned l
{
if (adev->class == ATA_DEV_ATA)
mask &= ~ATA_MASK_UDMA;
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
}
@@ -219,7 +219,7 @@ static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned lo
/* Disk, UDMA */
if (adev->class != ATA_DEV_ATA)
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
/* Actually do need to check */
ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
@@ -228,7 +228,7 @@ static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned lo
if (!strcmp(p, model_num))
mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
- return ata_bmdma_mode_filter(adev, mask);
+ return mask;
}
/**
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index b8cc349..943f204 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -553,11 +553,7 @@ static int adma_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
struct adma_port_priv *pp;
- int rc;
- rc = ata_port_start(ap);
- if (rc)
- return rc;
adma_enter_reg_mode(ap);
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index e87349d..eabf7dd 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -681,7 +681,6 @@ static int inic_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
struct inic_port_priv *pp;
- int rc;
/* alloc and initialize private data */
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
@@ -690,10 +689,6 @@ static int inic_port_start(struct ata_port *ap)
ap->private_data = pp;
/* Alloc resources */
- rc = ata_port_start(ap);
- if (rc)
- return rc;
-
pp->pkt = dmam_alloc_coherent(dev, sizeof(struct inic_pkt),
&pp->pkt_dma, GFP_KERNEL);
if (!pp->pkt)
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 521dcd3..1a9b8e6 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1101,7 +1101,8 @@ static int nv_adma_port_start(struct ata_port *ap)
if (rc)
return rc;
- rc = ata_port_start(ap);
+ /* we might fallback to bmdma, allocate bmdma resources */
+ rc = ata_bmdma_port_start(ap);
if (rc)
return rc;
@@ -1910,7 +1911,8 @@ static int nv_swncq_port_start(struct ata_port *ap)
struct nv_swncq_port_priv *pp;
int rc;
- rc = ata_port_start(ap);
+ /* we might fallback to bmdma, allocate bmdma resources */
+ rc = ata_bmdma_port_start(ap);
if (rc)
return rc;
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 3c440e5..d65b5a6 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -310,7 +310,8 @@ static int pdc_common_port_start(struct ata_port *ap)
struct pdc_port_priv *pp;
int rc;
- rc = ata_port_start(ap);
+ /* we use the same prd table as bmdma, allocate it */
+ rc = ata_bmdma_port_start(ap);
if (rc)
return rc;
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 48a3756..62403a8 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -502,11 +502,7 @@ static int qs_port_start(struct ata_port *ap)
void __iomem *mmio_base = qs_mmio_base(ap->host);
void __iomem *chan = mmio_base + (ap->port_no * 0x4000);
u64 addr;
- int rc;
- rc = ata_port_start(ap);
- if (rc)
- return rc;
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
return -ENOMEM;
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index 8027f64..1a6ab4c 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -291,11 +291,6 @@ static int pdc_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
struct pdc_port_priv *pp;
- int rc;
-
- rc = ata_port_start(ap);
- if (rc)
- return rc;
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
if (!pp)
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 019575b..4801689 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -180,9 +180,7 @@ static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- rc = ata_pci_bmdma_init(host);
- if (rc)
- return rc;
+ ata_pci_bmdma_init(host);
iomap = host->iomap;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index c7fb1a2..ea415aa 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -949,7 +949,6 @@ extern unsigned long ata_xfer_mode2mask(u8 xfer_mode);
extern int ata_xfer_mode2shift(unsigned long xfer_mode);
extern const char *ata_mode_string(unsigned long xfer_mask);
extern unsigned long ata_id_xfermask(const u16 *id);
-extern int ata_port_start(struct ata_port *ap);
extern int ata_std_qc_defer(struct ata_queued_cmd *qc);
extern void ata_noop_qc_prep(struct ata_queued_cmd *qc);
extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
@@ -1521,7 +1520,6 @@ extern int sata_sff_hardreset(struct ata_link *link, unsigned int *class,
extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes);
extern void ata_sff_error_handler(struct ata_port *ap);
extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc);
-extern int ata_sff_port_start(struct ata_port *ap);
extern void ata_sff_std_ports(struct ata_ioports *ioaddr);
#ifdef CONFIG_PCI
extern int ata_pci_sff_init_host(struct ata_host *host);
@@ -1538,16 +1536,15 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev,
extern void ata_bus_reset(struct ata_port *ap); /* deprecated */
-extern unsigned long ata_bmdma_mode_filter(struct ata_device *dev,
- unsigned long xfer_mask);
extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
extern void ata_bmdma_start(struct ata_queued_cmd *qc);
extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
extern u8 ata_bmdma_status(struct ata_port *ap);
+extern int ata_bmdma_port_start(struct ata_port *ap);
#ifdef CONFIG_PCI
extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev);
-extern int ata_pci_bmdma_init(struct ata_host *host);
+extern void ata_pci_bmdma_init(struct ata_host *host);
#endif /* CONFIG_PCI */
/**
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 11/22] libata-sff: introduce ata_sff_init/exit() and ata_sff_port_init()
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (9 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 10/22] libata-sff: clean up BMDMA initialization Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 12/22] libata-sff: ap->[last_]ctl are SFF specific Tejun Heo
` (16 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
In preparation of proper SFF/BMDMA separation, introduce
ata_sff_init/exit() and ata_sff_port_init(). These functions
currently don't do anything.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-core.c | 23 +++++++++++++++++------
drivers/ata/libata-sff.c | 23 +++++++++++++++++++++++
drivers/ata/libata.h | 10 ++++++++++
3 files changed, 50 insertions(+), 6 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 05e31c2..582aeb6 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5309,6 +5309,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
ap->stats.unhandled_irq = 1;
ap->stats.idle_irq = 1;
#endif
+ ata_sff_port_init(ap);
+
return ap;
}
@@ -6224,28 +6226,37 @@ static void __init ata_parse_force_param(void)
static int __init ata_init(void)
{
+ int rc = -ENOMEM;
+
ata_parse_force_param();
ata_wq = create_workqueue("ata");
if (!ata_wq)
- goto free_force_tbl;
+ goto fail;
ata_aux_wq = create_singlethread_workqueue("ata_aux");
if (!ata_aux_wq)
- goto free_wq;
+ goto fail;
+
+ rc = ata_sff_init();
+ if (rc)
+ goto fail;
printk(KERN_DEBUG "libata version " DRV_VERSION " loaded.\n");
return 0;
-free_wq:
- destroy_workqueue(ata_wq);
-free_force_tbl:
+ fail:
kfree(ata_force_tbl);
- return -ENOMEM;
+ if (ata_wq)
+ destroy_workqueue(ata_wq);
+ if (ata_aux_wq)
+ destroy_workqueue(ata_aux_wq);
+ return rc;
}
static void __exit ata_exit(void)
{
+ ata_sff_exit();
kfree(ata_force_tbl);
destroy_workqueue(ata_wq);
destroy_workqueue(ata_aux_wq);
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 0e4814b..41affa4 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2814,6 +2814,29 @@ void ata_pci_bmdma_init(struct ata_host *host)
#endif /* CONFIG_PCI */
+/**
+ * ata_sff_port_init - Initialize SFF/BMDMA ATA port
+ * @ap: Port to initialize
+ *
+ * Called on port allocation to initialize SFF/BMDMA specific
+ * fields.
+ *
+ * LOCKING:
+ * None.
+ */
+void ata_sff_port_init(struct ata_port *ap)
+{
+}
+
+int __init ata_sff_init(void)
+{
+ return 0;
+}
+
+void __exit ata_sff_exit(void)
+{
+}
+
EXPORT_SYMBOL_GPL(ata_sff_port_ops);
EXPORT_SYMBOL_GPL(ata_sff_qc_prep);
EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep);
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 1f626b5..31d89d9 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -202,6 +202,16 @@ static inline int sata_pmp_attach(struct ata_device *dev)
/* libata-sff.c */
#ifdef CONFIG_ATA_SFF
extern void ata_pio_task(struct work_struct *work);
+extern void ata_sff_port_init(struct ata_port *ap);
+extern int ata_sff_init(void);
+extern void ata_sff_exit(void);
+#else /* CONFIG_ATA_SFF */
+static inline void ata_sff_port_init(struct ata_port *ap)
+{ }
+static inline int ata_sff_init(void)
+{ return 0; }
+static inline void ata_sff_exit(void)
+{ }
#endif /* CONFIG_ATA_SFF */
#endif /* __LIBATA_H__ */
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 12/22] libata-sff: ap->[last_]ctl are SFF specific
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (10 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 11/22] libata-sff: introduce ata_sff_init/exit() and ata_sff_port_init() Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 13/22] libata-sff: port_task is " Tejun Heo
` (15 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
ap->[last_]ctl are specific to SFF controllers. Put them inside
CONFIG_ATA_SFF and move initialization into ata_sff_port_init().
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-core.c | 2 --
drivers/ata/libata-sff.c | 2 ++
include/linux/libata.h | 8 ++++++--
3 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 582aeb6..3dd8512 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -5273,10 +5273,8 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
ap->pflags |= ATA_PFLAG_INITIALIZING;
ap->lock = &host->lock;
ap->print_id = -1;
- ap->ctl = ATA_DEVCTL_OBS;
ap->host = host;
ap->dev = host->dev;
- ap->last_ctl = 0xFF;
#if defined(ATA_VERBOSE_DEBUG)
/* turn on all debugging levels */
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 41affa4..9124f8d 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2826,6 +2826,8 @@ void ata_pci_bmdma_init(struct ata_host *host)
*/
void ata_sff_port_init(struct ata_port *ap)
{
+ ap->ctl = ATA_DEVCTL_OBS;
+ ap->last_ctl = 0xFF;
}
int __init ata_sff_init(void)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index ea415aa..3125039 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -679,10 +679,10 @@ struct ata_port {
#ifdef CONFIG_ATA_SFF
struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */
-#endif /* CONFIG_ATA_SFF */
-
u8 ctl; /* cache of ATA control register */
u8 last_ctl; /* Cache last written value */
+#endif /* CONFIG_ATA_SFF */
+
unsigned int pio_mask;
unsigned int mwdma_mask;
unsigned int udma_mask;
@@ -1346,7 +1346,11 @@ static inline void ata_tf_init(struct ata_device *dev, struct ata_taskfile *tf)
{
memset(tf, 0, sizeof(*tf));
+#ifdef CONFIG_ATA_SFF
tf->ctl = dev->link->ap->ctl;
+#else
+ tf->ctl = ATA_DEVCTL_OBS;
+#endif
if (dev->devno == 0)
tf->device = ATA_DEVICE_OBS;
else
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 13/22] libata-sff: port_task is SFF specific
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (11 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 12/22] libata-sff: ap->[last_]ctl are SFF specific Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 14/22] libata-sff: separate out BMDMA EHs Tejun Heo
` (14 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
port_task is tightly bound to the standard SFF PIO HSM implementation.
Using it for any other purpose would be error-prone and there's no
such user and if some drivers need such feature, it would be much
better off using its own. Move it inside CONFIG_ATA_SFF and rename it
to sff_pio_task.
The only function which is exposed to the core layer is
ata_sff_flush_pio_task() which is renamed from ata_port_flush_task()
and now also takes care of resetting hsm_task_state to HSM_ST_IDLE,
which is possible as it's now specific to PIO HSM.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-core.c | 62 +------------------------------------------
drivers/ata/libata-eh.c | 4 +-
drivers/ata/libata-sff.c | 64 ++++++++++++++++++++++++++++++++------------
drivers/ata/libata.h | 7 ++---
include/linux/libata.h | 3 +-
5 files changed, 53 insertions(+), 87 deletions(-)
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 3dd8512..13ee83d 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -93,7 +93,6 @@ static void ata_dev_xfermask(struct ata_device *dev);
static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
unsigned int ata_print_id = 1;
-static struct workqueue_struct *ata_wq;
struct workqueue_struct *ata_aux_wq;
@@ -1599,53 +1598,6 @@ unsigned long ata_id_xfermask(const u16 *id)
return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask);
}
-/**
- * ata_pio_queue_task - Queue port_task
- * @ap: The ata_port to queue port_task for
- * @fn: workqueue function to be scheduled
- * @data: data for @fn to use
- * @delay: delay time in msecs for workqueue function
- *
- * Schedule @fn(@data) for execution after @delay jiffies using
- * port_task. There is one port_task per port and it's the
- * user(low level driver)'s responsibility to make sure that only
- * one task is active at any given time.
- *
- * libata core layer takes care of synchronization between
- * port_task and EH. ata_pio_queue_task() may be ignored for EH
- * synchronization.
- *
- * LOCKING:
- * Inherited from caller.
- */
-void ata_pio_queue_task(struct ata_port *ap, void *data, unsigned long delay)
-{
- ap->port_task_data = data;
-
- /* may fail if ata_port_flush_task() in progress */
- queue_delayed_work(ata_wq, &ap->port_task, msecs_to_jiffies(delay));
-}
-
-/**
- * ata_port_flush_task - Flush port_task
- * @ap: The ata_port to flush port_task for
- *
- * After this function completes, port_task is guranteed not to
- * be running or scheduled.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- */
-void ata_port_flush_task(struct ata_port *ap)
-{
- DPRINTK("ENTER\n");
-
- cancel_rearming_delayed_work(&ap->port_task);
-
- if (ata_msg_ctl(ap))
- ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __func__);
-}
-
static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
{
struct completion *waiting = qc->private_data;
@@ -1767,7 +1719,7 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
rc = wait_for_completion_timeout(&wait, msecs_to_jiffies(timeout));
- ata_port_flush_task(ap);
+ ata_sff_flush_pio_task(ap);
if (!rc) {
spin_lock_irqsave(ap->lock, flags);
@@ -5285,11 +5237,6 @@ struct ata_port *ata_port_alloc(struct ata_host *host)
ap->msg_enable = ATA_MSG_DRV | ATA_MSG_ERR | ATA_MSG_WARN;
#endif
-#ifdef CONFIG_ATA_SFF
- INIT_DELAYED_WORK(&ap->port_task, ata_pio_task);
-#else
- INIT_DELAYED_WORK(&ap->port_task, NULL);
-#endif
INIT_DELAYED_WORK(&ap->hotplug_task, ata_scsi_hotplug);
INIT_WORK(&ap->scsi_rescan_task, ata_scsi_dev_rescan);
INIT_LIST_HEAD(&ap->eh_done_q);
@@ -6228,10 +6175,6 @@ static int __init ata_init(void)
ata_parse_force_param();
- ata_wq = create_workqueue("ata");
- if (!ata_wq)
- goto fail;
-
ata_aux_wq = create_singlethread_workqueue("ata_aux");
if (!ata_aux_wq)
goto fail;
@@ -6245,8 +6188,6 @@ static int __init ata_init(void)
fail:
kfree(ata_force_tbl);
- if (ata_wq)
- destroy_workqueue(ata_wq);
if (ata_aux_wq)
destroy_workqueue(ata_aux_wq);
return rc;
@@ -6256,7 +6197,6 @@ static void __exit ata_exit(void)
{
ata_sff_exit();
kfree(ata_force_tbl);
- destroy_workqueue(ata_wq);
destroy_workqueue(ata_aux_wq);
}
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 7ccd0ce..0ee48f7 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -511,8 +511,8 @@ void ata_scsi_error(struct Scsi_Host *host)
DPRINTK("ENTER\n");
- /* synchronize with port task */
- ata_port_flush_task(ap);
+ /* make sure sff pio task is not running */
+ ata_sff_flush_pio_task(ap);
/* synchronize with host lock and sort out timeouts */
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 9124f8d..4c9adc6 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -39,6 +39,8 @@
#include "libata.h"
+static struct workqueue_struct *ata_sff_wq;
+
const struct ata_port_operations ata_sff_port_ops = {
.inherits = &ata_base_port_ops,
@@ -1172,7 +1174,7 @@ fsm_start:
if (in_wq)
spin_unlock_irqrestore(ap->lock, flags);
- /* if polling, ata_pio_task() handles the rest.
+ /* if polling, ata_sff_pio_task() handles the rest.
* otherwise, interrupt handler takes over from here.
*/
break;
@@ -1317,14 +1319,37 @@ fsm_start:
return poll_next;
}
-void ata_pio_task(struct work_struct *work)
+static void ata_sff_queue_pio_task(struct ata_port *ap, unsigned long delay)
+{
+ /* may fail if ata_sff_flush_pio_task() in progress */
+ queue_delayed_work(ata_sff_wq, &ap->sff_pio_task,
+ msecs_to_jiffies(delay));
+}
+
+void ata_sff_flush_pio_task(struct ata_port *ap)
+{
+ DPRINTK("ENTER\n");
+
+ cancel_rearming_delayed_work(&ap->sff_pio_task);
+ ap->hsm_task_state = HSM_ST_IDLE;
+
+ if (ata_msg_ctl(ap))
+ ata_port_printk(ap, KERN_DEBUG, "%s: EXIT\n", __func__);
+}
+
+static void ata_sff_pio_task(struct work_struct *work)
{
struct ata_port *ap =
- container_of(work, struct ata_port, port_task.work);
- struct ata_queued_cmd *qc = ap->port_task_data;
+ container_of(work, struct ata_port, sff_pio_task.work);
+ struct ata_queued_cmd *qc;
u8 status;
int poll_next;
+ /* qc can be NULL if timeout occurred */
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ if (!qc)
+ return;
+
fsm_start:
WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
@@ -1340,7 +1365,7 @@ fsm_start:
msleep(2);
status = ata_sff_busy_wait(ap, ATA_BUSY, 10);
if (status & ATA_BUSY) {
- ata_pio_queue_task(ap, qc, ATA_SHORT_PAUSE);
+ ata_sff_queue_pio_task(ap, ATA_SHORT_PAUSE);
return;
}
}
@@ -1410,7 +1435,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
ap->hsm_task_state = HSM_ST_LAST;
if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_pio_queue_task(ap, qc, 0);
+ ata_sff_queue_pio_task(ap, 0);
break;
@@ -1432,20 +1457,21 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
if (qc->tf.flags & ATA_TFLAG_WRITE) {
/* PIO data out protocol */
ap->hsm_task_state = HSM_ST_FIRST;
- ata_pio_queue_task(ap, qc, 0);
+ ata_sff_queue_pio_task(ap, 0);
- /* always send first data block using
- * the ata_pio_task() codepath.
+ /* always send first data block using the
+ * ata_sff_pio_task() codepath.
*/
} else {
/* PIO data in protocol */
ap->hsm_task_state = HSM_ST;
if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_pio_queue_task(ap, qc, 0);
+ ata_sff_queue_pio_task(ap, 0);
- /* if polling, ata_pio_task() handles the rest.
- * otherwise, interrupt handler takes over from here.
+ /* if polling, ata_sff_pio_task() handles the
+ * rest. otherwise, interrupt handler takes
+ * over from here.
*/
}
@@ -1463,7 +1489,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
/* send cdb by polling if no cdb interrupt */
if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
(qc->tf.flags & ATA_TFLAG_POLLING))
- ata_pio_queue_task(ap, qc, 0);
+ ata_sff_queue_pio_task(ap, 0);
break;
case ATAPI_PROT_DMA:
@@ -1475,7 +1501,7 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
/* send cdb by polling if no cdb interrupt */
if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
- ata_pio_queue_task(ap, qc, 0);
+ ata_sff_queue_pio_task(ap, 0);
break;
default:
@@ -2080,8 +2106,6 @@ void ata_sff_error_handler(struct ata_port *ap)
/* reset PIO HSM and stop DMA engine */
spin_lock_irqsave(ap->lock, flags);
- ap->hsm_task_state = HSM_ST_IDLE;
-
if (ap->ioaddr.bmdma_addr &&
qc && (qc->tf.protocol == ATA_PROT_DMA ||
qc->tf.protocol == ATAPI_PROT_DMA)) {
@@ -2141,8 +2165,6 @@ void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc)
spin_lock_irqsave(ap->lock, flags);
- ap->hsm_task_state = HSM_ST_IDLE;
-
if (ap->ioaddr.bmdma_addr)
ata_bmdma_stop(qc);
@@ -2826,17 +2848,23 @@ void ata_pci_bmdma_init(struct ata_host *host)
*/
void ata_sff_port_init(struct ata_port *ap)
{
+ INIT_DELAYED_WORK(&ap->sff_pio_task, ata_sff_pio_task);
ap->ctl = ATA_DEVCTL_OBS;
ap->last_ctl = 0xFF;
}
int __init ata_sff_init(void)
{
+ ata_sff_wq = create_workqueue("ata_sff");
+ if (!ata_sff_wq)
+ return -ENOMEM;
+
return 0;
}
void __exit ata_sff_exit(void)
{
+ destroy_workqueue(ata_sff_wq);
}
EXPORT_SYMBOL_GPL(ata_sff_port_ops);
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 31d89d9..81b6852 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -80,9 +80,6 @@ extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
unsigned int tag);
extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
extern void ata_dev_disable(struct ata_device *dev);
-extern void ata_pio_queue_task(struct ata_port *ap, void *data,
- unsigned long delay);
-extern void ata_port_flush_task(struct ata_port *ap);
extern unsigned ata_exec_internal(struct ata_device *dev,
struct ata_taskfile *tf, const u8 *cdb,
int dma_dir, void *buf, unsigned int buflen,
@@ -201,11 +198,13 @@ static inline int sata_pmp_attach(struct ata_device *dev)
/* libata-sff.c */
#ifdef CONFIG_ATA_SFF
-extern void ata_pio_task(struct work_struct *work);
+extern void ata_sff_flush_pio_task(struct ata_port *ap);
extern void ata_sff_port_init(struct ata_port *ap);
extern int ata_sff_init(void);
extern void ata_sff_exit(void);
#else /* CONFIG_ATA_SFF */
+static inline void ata_sff_flush_pio_task(struct ata_port *ap)
+{ }
static inline void ata_sff_port_init(struct ata_port *ap)
{ }
static inline int ata_sff_init(void)
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 3125039..43b13cd 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -681,6 +681,7 @@ struct ata_port {
struct ata_ioports ioaddr; /* ATA cmd/ctl/dma register blocks */
u8 ctl; /* cache of ATA control register */
u8 last_ctl; /* Cache last written value */
+ struct delayed_work sff_pio_task;
#endif /* CONFIG_ATA_SFF */
unsigned int pio_mask;
@@ -704,8 +705,6 @@ struct ata_port {
struct ata_host *host;
struct device *dev;
- void *port_task_data;
- struct delayed_work port_task;
struct delayed_work hotplug_task;
struct work_struct scsi_rescan_task;
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 14/22] libata-sff: separate out BMDMA EHs
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (12 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 13/22] libata-sff: port_task is " Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 15/22] libata-sff: ata_sff_[dumb_]qc_prep are BMDMA specific Tejun Heo
` (13 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
All of error handling logic in ata_sff_error_handler() and
ata_sff_post_internal_cmd() are for BMDMA. Create
ata_bmdma_error_handler() and ata_bmdma_post_internal_cmd() and move
BMDMA error handling logic into those.
While at it, change DMA protocol check to ata_is_dma() and fix
post_internal_cmd to call ap->ops->bmdma_stop instead of directly
calling ata_bmdma_stop().
As these functions are BMDMA specific, there's no reason to check for
bmdma_addr before calling bmdma methods if the protocol of the failed
command is DMA. sata_mv and pata_mpc52xx now don't need to set
.post_internal_cmd to ATA_OP_NULL and pata_icside and sata_qstor don't
need to set it to their bmdma_stop routines.
softreset/hardreset selection is now done by ata_std_error_handler()
with the help of ata_sff_check_reset() and both
ata_sff_error_handler() and ata_sff_post_internal_cmd() are noop and
removed.
This fixes p3 described in clean-up-BMDMA-initialization patch.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-eh.c | 7 +-
drivers/ata/libata-sff.c | 202 +++++++++++++++++++++++---------------------
drivers/ata/libata.h | 17 ++---
drivers/ata/pata_icside.c | 1 -
drivers/ata/pata_mpc52xx.c | 1 -
drivers/ata/pata_scc.c | 1 -
drivers/ata/sata_mv.c | 2 -
drivers/ata/sata_nv.c | 6 +-
drivers/ata/sata_qstor.c | 1 -
include/linux/libata.h | 4 +-
10 files changed, 122 insertions(+), 120 deletions(-)
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 0ee48f7..7f87156 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -3294,13 +3294,16 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
void ata_std_error_handler(struct ata_port *ap)
{
struct ata_port_operations *ops = ap->ops;
+ ata_reset_fn_t softreset = ops->softreset;
ata_reset_fn_t hardreset = ops->hardreset;
/* ignore built-in hardreset if SCR access is not available */
- if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
+ if (hardreset == sata_std_hardreset && !sata_scr_valid(&ap->link))
hardreset = NULL;
- ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
+ ata_sff_check_reset(ap, &softreset, &hardreset);
+
+ ata_do_eh(ap, ops->prereset, softreset, hardreset, ops->postreset);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 4c9adc6..a7d35b6 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -54,8 +54,6 @@ const struct ata_port_operations ata_sff_port_ops = {
.softreset = ata_sff_softreset,
.hardreset = sata_sff_hardreset,
.postreset = ata_sff_postreset,
- .error_handler = ata_sff_error_handler,
- .post_internal_cmd = ata_sff_post_internal_cmd,
.sff_dev_select = ata_sff_dev_select,
.sff_check_status = ata_sff_check_status,
@@ -2080,98 +2078,6 @@ void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
}
/**
- * ata_sff_error_handler - Stock error handler for BMDMA controller
- * @ap: port to handle error for
- *
- * Stock error handler for SFF controller. It can handle both
- * PATA and SATA controllers. Many controllers should be able to
- * use this EH as-is or with some added handling before and
- * after.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- */
-void ata_sff_error_handler(struct ata_port *ap)
-{
- ata_reset_fn_t softreset = ap->ops->softreset;
- ata_reset_fn_t hardreset = ap->ops->hardreset;
- struct ata_queued_cmd *qc;
- unsigned long flags;
- int thaw = 0;
-
- qc = __ata_qc_from_tag(ap, ap->link.active_tag);
- if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
- qc = NULL;
-
- /* reset PIO HSM and stop DMA engine */
- spin_lock_irqsave(ap->lock, flags);
-
- if (ap->ioaddr.bmdma_addr &&
- qc && (qc->tf.protocol == ATA_PROT_DMA ||
- qc->tf.protocol == ATAPI_PROT_DMA)) {
- u8 host_stat;
-
- host_stat = ap->ops->bmdma_status(ap);
-
- /* BMDMA controllers indicate host bus error by
- * setting DMA_ERR bit and timing out. As it wasn't
- * really a timeout event, adjust error mask and
- * cancel frozen state.
- */
- if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
- qc->err_mask = AC_ERR_HOST_BUS;
- thaw = 1;
- }
-
- ap->ops->bmdma_stop(qc);
-
- /* if we're gonna thaw, make sure IRQ is clear */
- if (thaw) {
- ap->ops->sff_check_status(ap);
- ap->ops->sff_irq_clear(ap);
- }
- }
-
- spin_unlock_irqrestore(ap->lock, flags);
-
- if (thaw)
- ata_eh_thaw_port(ap);
-
- /* PIO and DMA engines have been stopped, perform recovery */
-
- /* Ignore ata_sff_softreset if ctl isn't accessible and
- * built-in hardresets if SCR access isn't available.
- */
- if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
- softreset = NULL;
- if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
- hardreset = NULL;
-
- ata_do_eh(ap, ap->ops->prereset, softreset, hardreset,
- ap->ops->postreset);
-}
-
-/**
- * ata_sff_post_internal_cmd - Stock post_internal_cmd for SFF controller
- * @qc: internal command to clean up
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- */
-void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- unsigned long flags;
-
- spin_lock_irqsave(ap->lock, flags);
-
- if (ap->ioaddr.bmdma_addr)
- ata_bmdma_stop(qc);
-
- spin_unlock_irqrestore(ap->lock, flags);
-}
-
-/**
* ata_sff_std_ports - initialize ioaddr with standard port offsets.
* @ioaddr: IO address structure to be initialized
*
@@ -2601,6 +2507,9 @@ err_out:
const struct ata_port_operations ata_bmdma_port_ops = {
.inherits = &ata_sff_port_ops,
+ .error_handler = ata_bmdma_error_handler,
+ .post_internal_cmd = ata_bmdma_post_internal_cmd,
+
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
@@ -2610,6 +2519,82 @@ const struct ata_port_operations ata_bmdma_port_ops = {
};
/**
+ * ata_bmdma_error_handler - Stock error handler for BMDMA controller
+ * @ap: port to handle error for
+ *
+ * Stock error handler for BMDMA controller. It can handle both
+ * PATA and SATA controllers. Most BMDMA controllers should be
+ * able to use this EH as-is or with some added handling before
+ * and after.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ */
+void ata_bmdma_error_handler(struct ata_port *ap)
+{
+ struct ata_queued_cmd *qc;
+ unsigned long flags;
+ int thaw = 0;
+
+ qc = __ata_qc_from_tag(ap, ap->link.active_tag);
+ if (qc && !(qc->flags & ATA_QCFLAG_FAILED))
+ qc = NULL;
+
+ /* reset PIO HSM and stop DMA engine */
+ spin_lock_irqsave(ap->lock, flags);
+
+ if (qc && ata_is_dma(qc->tf.protocol)) {
+ u8 host_stat;
+
+ host_stat = ap->ops->bmdma_status(ap);
+
+ /* BMDMA controllers indicate host bus error by
+ * setting DMA_ERR bit and timing out. As it wasn't
+ * really a timeout event, adjust error mask and
+ * cancel frozen state.
+ */
+ if (qc->err_mask == AC_ERR_TIMEOUT && (host_stat & ATA_DMA_ERR)) {
+ qc->err_mask = AC_ERR_HOST_BUS;
+ thaw = 1;
+ }
+
+ ap->ops->bmdma_stop(qc);
+
+ /* if we're gonna thaw, make sure IRQ is clear */
+ if (thaw) {
+ ap->ops->sff_check_status(ap);
+ ap->ops->sff_irq_clear(ap);
+ }
+ }
+
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ if (thaw)
+ ata_eh_thaw_port(ap);
+
+ ata_std_error_handler(ap);
+}
+
+/**
+ * ata_bmdma_post_internal_cmd - Stock post_internal_cmd for BMDMA
+ * @qc: internal command to clean up
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ */
+void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ unsigned long flags;
+
+ if (ata_is_dma(qc->tf.protocol)) {
+ spin_lock_irqsave(ap->lock, flags);
+ ap->ops->bmdma_stop(qc);
+ spin_unlock_irqrestore(ap->lock, flags);
+ }
+}
+
+/**
* ata_bmdma_setup - Set up PCI IDE BMDMA transaction
* @qc: Info associated with this ATA transaction.
*
@@ -2837,6 +2822,31 @@ void ata_pci_bmdma_init(struct ata_host *host)
#endif /* CONFIG_PCI */
/**
+ * ata_sff_check_reset - Check whether standard reset methods are valid
+ * @ap: Port of interest
+ * @softresetp: I/O parameter for softreset
+ * @hardresetp: I/O parameter for hardreset
+ *
+ * Verify whether soft and hard resets are valid and if not
+ * nullify them. Called from ata_std_error_handler() to verify
+ * stock reset methods.
+ *
+ * LOCKING:
+ * None.
+ */
+void ata_sff_check_reset(struct ata_port *ap, ata_reset_fn_t *softresetp,
+ ata_reset_fn_t *hardresetp)
+{
+ /* ignore ata_sff_softreset if ctl isn't accessible */
+ if (*softresetp == ata_sff_softreset && !ap->ioaddr.ctl_addr)
+ *softresetp = NULL;
+
+ /* ignore built-in hardreset if SCR access is not available */
+ if (*hardresetp == sata_sff_hardreset && !sata_scr_valid(&ap->link))
+ *hardresetp = NULL;
+}
+
+/**
* ata_sff_port_init - Initialize SFF/BMDMA ATA port
* @ap: Port to initialize
*
@@ -2896,8 +2906,6 @@ EXPORT_SYMBOL_GPL(ata_sff_wait_after_reset);
EXPORT_SYMBOL_GPL(ata_sff_softreset);
EXPORT_SYMBOL_GPL(sata_sff_hardreset);
EXPORT_SYMBOL_GPL(ata_sff_postreset);
-EXPORT_SYMBOL_GPL(ata_sff_error_handler);
-EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd);
EXPORT_SYMBOL_GPL(ata_sff_std_ports);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(ata_pci_sff_init_host);
@@ -2907,6 +2915,8 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
#endif /* CONFIG_PCI */
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
+EXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
+EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
EXPORT_SYMBOL_GPL(ata_bmdma_start);
EXPORT_SYMBOL_GPL(ata_bmdma_stop);
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 81b6852..b9e0463 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -38,17 +38,6 @@ struct ata_scsi_args {
void (*done)(struct scsi_cmnd *);
};
-static inline int ata_is_builtin_hardreset(ata_reset_fn_t reset)
-{
- if (reset == sata_std_hardreset)
- return 1;
-#ifdef CONFIG_ATA_SFF
- if (reset == sata_sff_hardreset)
- return 1;
-#endif
- return 0;
-}
-
/* libata-core.c */
enum {
/* flags for ata_dev_read_id() */
@@ -200,6 +189,8 @@ static inline int sata_pmp_attach(struct ata_device *dev)
#ifdef CONFIG_ATA_SFF
extern void ata_sff_flush_pio_task(struct ata_port *ap);
extern void ata_sff_port_init(struct ata_port *ap);
+extern void ata_sff_check_reset(struct ata_port *ap, ata_reset_fn_t *softresetp,
+ ata_reset_fn_t *hardresetp);
extern int ata_sff_init(void);
extern void ata_sff_exit(void);
#else /* CONFIG_ATA_SFF */
@@ -207,6 +198,10 @@ static inline void ata_sff_flush_pio_task(struct ata_port *ap)
{ }
static inline void ata_sff_port_init(struct ata_port *ap)
{ }
+static inline void ata_sff_check_reset(struct ata_port *ap,
+ ata_reset_fn_t *softresetp,
+ ata_reset_fn_t *hardresetp)
+{ }
static inline int ata_sff_init(void)
{ return 0; }
static inline void ata_sff_exit(void)
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index 4485e86..6ab3ada 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -345,7 +345,6 @@ static struct ata_port_operations pata_icside_port_ops = {
.cable_detect = ata_cable_40wire,
.set_dmamode = pata_icside_set_dmamode,
.postreset = pata_icside_postreset,
- .post_internal_cmd = pata_icside_bmdma_stop,
.port_start = ATA_OP_NULL, /* don't need PRD table */
};
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index a9e8273..e176bb4 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -264,7 +264,6 @@ static struct ata_port_operations mpc52xx_ata_port_ops = {
.sff_dev_select = mpc52xx_ata_dev_select,
.cable_detect = ata_cable_40wire,
.set_piomode = mpc52xx_ata_set_piomode,
- .post_internal_cmd = ATA_OP_NULL,
};
static int __devinit
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 12b9f43..46a62f2 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -990,7 +990,6 @@ static struct ata_port_operations scc_pata_ops = {
.prereset = scc_pata_prereset,
.softreset = scc_softreset,
.postreset = scc_postreset,
- .post_internal_cmd = scc_bmdma_stop,
.sff_irq_clear = scc_irq_clear,
.sff_irq_on = scc_irq_on,
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 13368cb..20e926c 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -579,8 +579,6 @@ static struct ata_port_operations mv5_ops = {
.freeze = mv_eh_freeze,
.thaw = mv_eh_thaw,
.hardreset = mv_hardreset,
- .error_handler = ata_std_error_handler, /* avoid SFF EH */
- .post_internal_cmd = ATA_OP_NULL,
.scr_read = mv5_scr_read,
.scr_write = mv5_scr_write,
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 1a9b8e6..1e67c17 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1076,7 +1076,7 @@ static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc)
struct nv_adma_port_priv *pp = qc->ap->private_data;
if (pp->flags & NV_ADMA_PORT_REGISTER_MODE)
- ata_sff_post_internal_cmd(qc);
+ ata_bmdma_post_internal_cmd(qc);
}
static int nv_adma_port_start(struct ata_port *ap)
@@ -1664,7 +1664,7 @@ static void nv_adma_error_handler(struct ata_port *ap)
readw(mmio + NV_ADMA_CTL); /* flush posted write */
}
- ata_sff_error_handler(ap);
+ ata_bmdma_error_handler(ap);
}
static void nv_swncq_qc_to_dq(struct ata_port *ap, struct ata_queued_cmd *qc)
@@ -1790,7 +1790,7 @@ static void nv_swncq_error_handler(struct ata_port *ap)
ehc->i.action |= ATA_EH_RESET;
}
- ata_sff_error_handler(ap);
+ ata_bmdma_error_handler(ap);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 62403a8..a130c83 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -146,7 +146,6 @@ static struct ata_port_operations qs_ata_ops = {
.prereset = qs_prereset,
.softreset = ATA_OP_NULL,
.error_handler = qs_error_handler,
- .post_internal_cmd = ATA_OP_NULL,
.scr_read = qs_scr_read,
.scr_write = qs_scr_write,
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 43b13cd..f53f828 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1521,8 +1521,6 @@ extern int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
extern int sata_sff_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline);
extern void ata_sff_postreset(struct ata_link *link, unsigned int *classes);
-extern void ata_sff_error_handler(struct ata_port *ap);
-extern void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc);
extern void ata_sff_std_ports(struct ata_ioports *ioaddr);
#ifdef CONFIG_PCI
extern int ata_pci_sff_init_host(struct ata_host *host);
@@ -1539,6 +1537,8 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev,
extern void ata_bus_reset(struct ata_port *ap); /* deprecated */
+extern void ata_bmdma_error_handler(struct ata_port *ap);
+extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);
extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
extern void ata_bmdma_start(struct ata_queued_cmd *qc);
extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 15/22] libata-sff: ata_sff_[dumb_]qc_prep are BMDMA specific
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (13 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 14/22] libata-sff: separate out BMDMA EHs Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 16/22] libata-sff: prd is " Tejun Heo
` (12 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
Both qc_prep functions deal only with BMDMA PRD setup and PIO only SFF
drivers don't need them. Move and rename to
ata_bmdma_[dumb_]qc_prep().
All usages are renamed except for pdc_adma and sata_qstor. Those two
drivers are not BMDMA drivers and don't need to call BMDMA qc_prep
functions. Calls to ata_sff_qc_prep() in the two drivers are removed.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-sff.c | 288 +++++++++++++++++++++++----------------------
drivers/ata/pata_atiixp.c | 2 +-
drivers/ata/pata_cs5520.c | 2 +-
drivers/ata/pata_cs5530.c | 2 +-
drivers/ata/pata_sc1200.c | 2 +-
drivers/ata/pdc_adma.c | 4 +-
drivers/ata/sata_nv.c | 4 +-
drivers/ata/sata_qstor.c | 4 +-
include/linux/libata.h | 4 +-
9 files changed, 155 insertions(+), 157 deletions(-)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index a7d35b6..ac041e2 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -44,7 +44,7 @@ static struct workqueue_struct *ata_sff_wq;
const struct ata_port_operations ata_sff_port_ops = {
.inherits = &ata_base_port_ops,
- .qc_prep = ata_sff_qc_prep,
+ .qc_prep = ata_noop_qc_prep,
.qc_issue = ata_sff_qc_issue,
.qc_fill_rtf = ata_sff_qc_fill_rtf,
@@ -66,146 +66,6 @@ const struct ata_port_operations ata_sff_port_ops = {
};
/**
- * ata_fill_sg - Fill PCI IDE PRD table
- * @qc: Metadata associated with taskfile to be transferred
- *
- * Fill PCI IDE PRD (scatter-gather) table with segments
- * associated with the current disk command.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- *
- */
-static void ata_fill_sg(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- struct scatterlist *sg;
- unsigned int si, pi;
-
- pi = 0;
- for_each_sg(qc->sg, sg, qc->n_elem, si) {
- u32 addr, offset;
- u32 sg_len, len;
-
- /* determine if physical DMA addr spans 64K boundary.
- * Note h/w doesn't support 64-bit, so we unconditionally
- * truncate dma_addr_t to u32.
- */
- addr = (u32) sg_dma_address(sg);
- sg_len = sg_dma_len(sg);
-
- while (sg_len) {
- offset = addr & 0xffff;
- len = sg_len;
- if ((offset + sg_len) > 0x10000)
- len = 0x10000 - offset;
-
- ap->prd[pi].addr = cpu_to_le32(addr);
- ap->prd[pi].flags_len = cpu_to_le32(len & 0xffff);
- VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
-
- pi++;
- sg_len -= len;
- addr += len;
- }
- }
-
- ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
-}
-
-/**
- * ata_fill_sg_dumb - Fill PCI IDE PRD table
- * @qc: Metadata associated with taskfile to be transferred
- *
- * Fill PCI IDE PRD (scatter-gather) table with segments
- * associated with the current disk command. Perform the fill
- * so that we avoid writing any length 64K records for
- * controllers that don't follow the spec.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- *
- */
-static void ata_fill_sg_dumb(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- struct scatterlist *sg;
- unsigned int si, pi;
-
- pi = 0;
- for_each_sg(qc->sg, sg, qc->n_elem, si) {
- u32 addr, offset;
- u32 sg_len, len, blen;
-
- /* determine if physical DMA addr spans 64K boundary.
- * Note h/w doesn't support 64-bit, so we unconditionally
- * truncate dma_addr_t to u32.
- */
- addr = (u32) sg_dma_address(sg);
- sg_len = sg_dma_len(sg);
-
- while (sg_len) {
- offset = addr & 0xffff;
- len = sg_len;
- if ((offset + sg_len) > 0x10000)
- len = 0x10000 - offset;
-
- blen = len & 0xffff;
- ap->prd[pi].addr = cpu_to_le32(addr);
- if (blen == 0) {
- /* Some PATA chipsets like the CS5530 can't
- cope with 0x0000 meaning 64K as the spec says */
- ap->prd[pi].flags_len = cpu_to_le32(0x8000);
- blen = 0x8000;
- ap->prd[++pi].addr = cpu_to_le32(addr + 0x8000);
- }
- ap->prd[pi].flags_len = cpu_to_le32(blen);
- VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
-
- pi++;
- sg_len -= len;
- addr += len;
- }
- }
-
- ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
-}
-
-/**
- * ata_sff_qc_prep - Prepare taskfile for submission
- * @qc: Metadata associated with taskfile to be prepared
- *
- * Prepare ATA taskfile for submission.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_sff_qc_prep(struct ata_queued_cmd *qc)
-{
- if (!(qc->flags & ATA_QCFLAG_DMAMAP))
- return;
-
- ata_fill_sg(qc);
-}
-
-/**
- * ata_sff_dumb_qc_prep - Prepare taskfile for submission
- * @qc: Metadata associated with taskfile to be prepared
- *
- * Prepare ATA taskfile for submission.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_sff_dumb_qc_prep(struct ata_queued_cmd *qc)
-{
- if (!(qc->flags & ATA_QCFLAG_DMAMAP))
- return;
-
- ata_fill_sg_dumb(qc);
-}
-
-/**
* ata_sff_check_status - Read device status reg & clear interrupt
* @ap: port where the device is
*
@@ -2510,6 +2370,8 @@ const struct ata_port_operations ata_bmdma_port_ops = {
.error_handler = ata_bmdma_error_handler,
.post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .qc_prep = ata_bmdma_qc_prep,
+
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
@@ -2519,6 +2381,146 @@ const struct ata_port_operations ata_bmdma_port_ops = {
};
/**
+ * ata_bmdma_fill_sg - Fill PCI IDE PRD table
+ * @qc: Metadata associated with taskfile to be transferred
+ *
+ * Fill PCI IDE PRD (scatter-gather) table with segments
+ * associated with the current disk command.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ *
+ */
+static void ata_bmdma_fill_sg(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct scatterlist *sg;
+ unsigned int si, pi;
+
+ pi = 0;
+ for_each_sg(qc->sg, sg, qc->n_elem, si) {
+ u32 addr, offset;
+ u32 sg_len, len;
+
+ /* determine if physical DMA addr spans 64K boundary.
+ * Note h/w doesn't support 64-bit, so we unconditionally
+ * truncate dma_addr_t to u32.
+ */
+ addr = (u32) sg_dma_address(sg);
+ sg_len = sg_dma_len(sg);
+
+ while (sg_len) {
+ offset = addr & 0xffff;
+ len = sg_len;
+ if ((offset + sg_len) > 0x10000)
+ len = 0x10000 - offset;
+
+ ap->prd[pi].addr = cpu_to_le32(addr);
+ ap->prd[pi].flags_len = cpu_to_le32(len & 0xffff);
+ VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
+
+ pi++;
+ sg_len -= len;
+ addr += len;
+ }
+ }
+
+ ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+}
+
+/**
+ * ata_bmdma_fill_sg_dumb - Fill PCI IDE PRD table
+ * @qc: Metadata associated with taskfile to be transferred
+ *
+ * Fill PCI IDE PRD (scatter-gather) table with segments
+ * associated with the current disk command. Perform the fill
+ * so that we avoid writing any length 64K records for
+ * controllers that don't follow the spec.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ *
+ */
+static void ata_bmdma_fill_sg_dumb(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct scatterlist *sg;
+ unsigned int si, pi;
+
+ pi = 0;
+ for_each_sg(qc->sg, sg, qc->n_elem, si) {
+ u32 addr, offset;
+ u32 sg_len, len, blen;
+
+ /* determine if physical DMA addr spans 64K boundary.
+ * Note h/w doesn't support 64-bit, so we unconditionally
+ * truncate dma_addr_t to u32.
+ */
+ addr = (u32) sg_dma_address(sg);
+ sg_len = sg_dma_len(sg);
+
+ while (sg_len) {
+ offset = addr & 0xffff;
+ len = sg_len;
+ if ((offset + sg_len) > 0x10000)
+ len = 0x10000 - offset;
+
+ blen = len & 0xffff;
+ ap->prd[pi].addr = cpu_to_le32(addr);
+ if (blen == 0) {
+ /* Some PATA chipsets like the CS5530 can't
+ cope with 0x0000 meaning 64K as the spec says */
+ ap->prd[pi].flags_len = cpu_to_le32(0x8000);
+ blen = 0x8000;
+ ap->prd[++pi].addr = cpu_to_le32(addr + 0x8000);
+ }
+ ap->prd[pi].flags_len = cpu_to_le32(blen);
+ VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
+
+ pi++;
+ sg_len -= len;
+ addr += len;
+ }
+ }
+
+ ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+}
+
+/**
+ * ata_bmdma_qc_prep - Prepare taskfile for submission
+ * @qc: Metadata associated with taskfile to be prepared
+ *
+ * Prepare ATA taskfile for submission.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+void ata_bmdma_qc_prep(struct ata_queued_cmd *qc)
+{
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+ return;
+
+ ata_bmdma_fill_sg(qc);
+}
+
+/**
+ * ata_bmdma_dumb_qc_prep - Prepare taskfile for submission
+ * @qc: Metadata associated with taskfile to be prepared
+ *
+ * Prepare ATA taskfile for submission.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc)
+{
+ if (!(qc->flags & ATA_QCFLAG_DMAMAP))
+ return;
+
+ ata_bmdma_fill_sg_dumb(qc);
+}
+
+/**
* ata_bmdma_error_handler - Stock error handler for BMDMA controller
* @ap: port to handle error for
*
@@ -2878,8 +2880,6 @@ void __exit ata_sff_exit(void)
}
EXPORT_SYMBOL_GPL(ata_sff_port_ops);
-EXPORT_SYMBOL_GPL(ata_sff_qc_prep);
-EXPORT_SYMBOL_GPL(ata_sff_dumb_qc_prep);
EXPORT_SYMBOL_GPL(ata_sff_dev_select);
EXPORT_SYMBOL_GPL(ata_sff_check_status);
EXPORT_SYMBOL_GPL(ata_sff_dma_pause);
@@ -2915,6 +2915,8 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
#endif /* CONFIG_PCI */
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
+EXPORT_SYMBOL_GPL(ata_bmdma_qc_prep);
+EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index e8a0d99..3fae282 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -223,7 +223,7 @@ static struct scsi_host_template atiixp_sht = {
static struct ata_port_operations atiixp_port_ops = {
.inherits = &ata_bmdma_port_ops,
- .qc_prep = ata_sff_dumb_qc_prep,
+ .qc_prep = ata_bmdma_dumb_qc_prep,
.bmdma_start = atiixp_bmdma_start,
.bmdma_stop = atiixp_bmdma_stop,
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 1186bcd..d5fe2b1 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -146,7 +146,7 @@ static struct scsi_host_template cs5520_sht = {
static struct ata_port_operations cs5520_port_ops = {
.inherits = &ata_bmdma_port_ops,
- .qc_prep = ata_sff_dumb_qc_prep,
+ .qc_prep = ata_bmdma_dumb_qc_prep,
.cable_detect = ata_cable_40wire,
.set_piomode = cs5520_set_piomode,
.set_dmamode = cs5520_set_dmamode,
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 0c4b271..6dae09a 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -168,7 +168,7 @@ static struct scsi_host_template cs5530_sht = {
static struct ata_port_operations cs5530_port_ops = {
.inherits = &ata_bmdma_port_ops,
- .qc_prep = ata_sff_dumb_qc_prep,
+ .qc_prep = ata_bmdma_dumb_qc_prep,
.qc_issue = cs5530_qc_issue,
.cable_detect = ata_cable_40wire,
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 0278fd2..cee8eb9 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -185,7 +185,7 @@ static struct scsi_host_template sc1200_sht = {
static struct ata_port_operations sc1200_port_ops = {
.inherits = &ata_bmdma_port_ops,
- .qc_prep = ata_sff_dumb_qc_prep,
+ .qc_prep = ata_bmdma_dumb_qc_prep,
.qc_issue = sc1200_qc_issue,
.cable_detect = ata_cable_40wire,
.set_piomode = sc1200_set_piomode,
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 943f204..17fd1d5 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -321,10 +321,8 @@ static void adma_qc_prep(struct ata_queued_cmd *qc)
VPRINTK("ENTER\n");
adma_enter_reg_mode(qc->ap);
- if (qc->tf.protocol != ATA_PROT_DMA) {
- ata_sff_qc_prep(qc);
+ if (qc->tf.protocol != ATA_PROT_DMA)
return;
- }
buf[i++] = 0; /* Response flags */
buf[i++] = 0; /* reserved */
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 1e67c17..72a8630 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1354,7 +1354,7 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
BUG_ON(!(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) &&
(qc->flags & ATA_QCFLAG_DMAMAP));
nv_adma_register_mode(qc->ap);
- ata_sff_qc_prep(qc);
+ ata_bmdma_qc_prep(qc);
return;
}
@@ -1937,7 +1937,7 @@ static int nv_swncq_port_start(struct ata_port *ap)
static void nv_swncq_qc_prep(struct ata_queued_cmd *qc)
{
if (qc->tf.protocol != ATA_PROT_NCQ) {
- ata_sff_qc_prep(qc);
+ ata_bmdma_qc_prep(qc);
return;
}
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index a130c83..b8783bc 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -301,10 +301,8 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
VPRINTK("ENTER\n");
qs_enter_reg_mode(qc->ap);
- if (qc->tf.protocol != ATA_PROT_DMA) {
- ata_sff_qc_prep(qc);
+ if (qc->tf.protocol != ATA_PROT_DMA)
return;
- }
nelem = qs_fill_sg(qc);
diff --git a/include/linux/libata.h b/include/linux/libata.h
index f53f828..197ce14 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1483,8 +1483,6 @@ extern const struct ata_port_operations ata_bmdma_port_ops;
.sg_tablesize = LIBATA_MAX_PRD, \
.dma_boundary = ATA_DMA_BOUNDARY
-extern void ata_sff_qc_prep(struct ata_queued_cmd *qc);
-extern void ata_sff_dumb_qc_prep(struct ata_queued_cmd *qc);
extern void ata_sff_dev_select(struct ata_port *ap, unsigned int device);
extern u8 ata_sff_check_status(struct ata_port *ap);
extern void ata_sff_pause(struct ata_port *ap);
@@ -1537,6 +1535,8 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev,
extern void ata_bus_reset(struct ata_port *ap); /* deprecated */
+extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc);
+extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc);
extern void ata_bmdma_error_handler(struct ata_port *ap);
extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);
extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 16/22] libata-sff: prd is BMDMA specific
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (14 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 15/22] libata-sff: ata_sff_[dumb_]qc_prep are BMDMA specific Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 17/22] libata-sff: separate out BMDMA qc_issue Tejun Heo
` (11 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
struct ata_prd and ap->prd are BMDMA specific. Add bmdma_ prefix to
them and move them inside CONFIG_ATA_SFF.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-sff.c | 27 +++++++++++++++------------
drivers/ata/pata_ns87415.c | 2 +-
drivers/ata/pata_scc.c | 4 ++--
drivers/ata/sata_nv.c | 4 ++--
drivers/ata/sata_promise.c | 21 +++++++++++----------
drivers/ata/sata_svw.c | 2 +-
include/linux/ata.h | 2 +-
include/linux/libata.h | 2 ++
8 files changed, 35 insertions(+), 29 deletions(-)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index ac041e2..de03c0b 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2394,6 +2394,7 @@ const struct ata_port_operations ata_bmdma_port_ops = {
static void ata_bmdma_fill_sg(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
+ struct ata_bmdma_prd *prd = ap->bmdma_prd;
struct scatterlist *sg;
unsigned int si, pi;
@@ -2415,8 +2416,8 @@ static void ata_bmdma_fill_sg(struct ata_queued_cmd *qc)
if ((offset + sg_len) > 0x10000)
len = 0x10000 - offset;
- ap->prd[pi].addr = cpu_to_le32(addr);
- ap->prd[pi].flags_len = cpu_to_le32(len & 0xffff);
+ prd[pi].addr = cpu_to_le32(addr);
+ prd[pi].flags_len = cpu_to_le32(len & 0xffff);
VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
pi++;
@@ -2425,7 +2426,7 @@ static void ata_bmdma_fill_sg(struct ata_queued_cmd *qc)
}
}
- ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+ prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
}
/**
@@ -2444,6 +2445,7 @@ static void ata_bmdma_fill_sg(struct ata_queued_cmd *qc)
static void ata_bmdma_fill_sg_dumb(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
+ struct ata_bmdma_prd *prd = ap->bmdma_prd;
struct scatterlist *sg;
unsigned int si, pi;
@@ -2466,15 +2468,15 @@ static void ata_bmdma_fill_sg_dumb(struct ata_queued_cmd *qc)
len = 0x10000 - offset;
blen = len & 0xffff;
- ap->prd[pi].addr = cpu_to_le32(addr);
+ prd[pi].addr = cpu_to_le32(addr);
if (blen == 0) {
/* Some PATA chipsets like the CS5530 can't
cope with 0x0000 meaning 64K as the spec says */
- ap->prd[pi].flags_len = cpu_to_le32(0x8000);
+ prd[pi].flags_len = cpu_to_le32(0x8000);
blen = 0x8000;
- ap->prd[++pi].addr = cpu_to_le32(addr + 0x8000);
+ prd[++pi].addr = cpu_to_le32(addr + 0x8000);
}
- ap->prd[pi].flags_len = cpu_to_le32(blen);
+ prd[pi].flags_len = cpu_to_le32(blen);
VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", pi, addr, len);
pi++;
@@ -2483,7 +2485,7 @@ static void ata_bmdma_fill_sg_dumb(struct ata_queued_cmd *qc)
}
}
- ap->prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+ prd[pi - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
}
/**
@@ -2611,7 +2613,7 @@ void ata_bmdma_setup(struct ata_queued_cmd *qc)
/* load PRD table addr. */
mb(); /* make sure PRD table writes are visible to controller */
- iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
+ iowrite32(ap->bmdma_prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
/* specify data direction, triple-check start bit is clear */
dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
@@ -2711,9 +2713,10 @@ u8 ata_bmdma_status(struct ata_port *ap)
int ata_bmdma_port_start(struct ata_port *ap)
{
if (ap->mwdma_mask || ap->udma_mask) {
- ap->prd = dmam_alloc_coherent(ap->host->dev, ATA_PRD_TBL_SZ,
- &ap->prd_dma, GFP_KERNEL);
- if (!ap->prd)
+ ap->bmdma_prd =
+ dmam_alloc_coherent(ap->host->dev, ATA_PRD_TBL_SZ,
+ &ap->bmdma_prd_dma, GFP_KERNEL);
+ if (!ap->bmdma_prd)
return -ENOMEM;
}
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c
index e0aa7ea..260e0b0 100644
--- a/drivers/ata/pata_ns87415.c
+++ b/drivers/ata/pata_ns87415.c
@@ -126,7 +126,7 @@ static void ns87415_bmdma_setup(struct ata_queued_cmd *qc)
/* load PRD table addr. */
mb(); /* make sure PRD table writes are visible to controller */
- iowrite32(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
+ iowrite32(ap->bmdma_prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
/* specify data direction, triple-check start bit is clear */
dmactl = ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 46a62f2..c96b090 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -431,7 +431,7 @@ static void scc_bmdma_setup (struct ata_queued_cmd *qc)
void __iomem *mmio = ap->ioaddr.bmdma_addr;
/* load PRD table addr */
- out_be32(mmio + SCC_DMA_TABLE_OFS, ap->prd_dma);
+ out_be32(mmio + SCC_DMA_TABLE_OFS, ap->bmdma_prd_dma);
/* specify data direction, triple-check start bit is clear */
dmactl = in_be32(mmio + SCC_DMA_CMD);
@@ -944,7 +944,7 @@ static int scc_port_start (struct ata_port *ap)
if (rc)
return rc;
- out_be32(mmio + SCC_DMA_PTERADD, ap->prd_dma);
+ out_be32(mmio + SCC_DMA_PTERADD, ap->bmdma_prd_dma);
return 0;
}
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 72a8630..e30ce2e 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -271,7 +271,7 @@ enum ncq_saw_flag_list {
};
struct nv_swncq_port_priv {
- struct ata_prd *prd; /* our SG list */
+ struct ata_bmdma_prd *prd; /* our SG list */
dma_addr_t prd_dma; /* and its DMA mapping */
void __iomem *sactive_block;
void __iomem *irq_block;
@@ -1952,7 +1952,7 @@ static void nv_swncq_fill_sg(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
struct scatterlist *sg;
struct nv_swncq_port_priv *pp = ap->private_data;
- struct ata_prd *prd;
+ struct ata_bmdma_prd *prd;
unsigned int si, idx;
prd = pp->prd + ATA_MAX_PRD * qc->tag;
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index d65b5a6..4d7a400 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -408,7 +408,7 @@ static int pdc_sata_scr_write(struct ata_link *link,
static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
- dma_addr_t sg_table = ap->prd_dma;
+ dma_addr_t sg_table = ap->bmdma_prd_dma;
unsigned int cdb_len = qc->dev->cdb_len;
u8 *cdb = qc->cdb;
struct pdc_port_priv *pp = ap->private_data;
@@ -496,6 +496,7 @@ static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
static void pdc_fill_sg(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
+ struct ata_bmdma_prd *prd = ap->bmdma_prd;
struct scatterlist *sg;
const u32 SG_COUNT_ASIC_BUG = 41*4;
unsigned int si, idx;
@@ -522,8 +523,8 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
if ((offset + sg_len) > 0x10000)
len = 0x10000 - offset;
- ap->prd[idx].addr = cpu_to_le32(addr);
- ap->prd[idx].flags_len = cpu_to_le32(len & 0xffff);
+ prd[idx].addr = cpu_to_le32(addr);
+ prd[idx].flags_len = cpu_to_le32(len & 0xffff);
VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
idx++;
@@ -532,27 +533,27 @@ static void pdc_fill_sg(struct ata_queued_cmd *qc)
}
}
- len = le32_to_cpu(ap->prd[idx - 1].flags_len);
+ len = le32_to_cpu(prd[idx - 1].flags_len);
if (len > SG_COUNT_ASIC_BUG) {
u32 addr;
VPRINTK("Splitting last PRD.\n");
- addr = le32_to_cpu(ap->prd[idx - 1].addr);
- ap->prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG);
+ addr = le32_to_cpu(prd[idx - 1].addr);
+ prd[idx - 1].flags_len = cpu_to_le32(len - SG_COUNT_ASIC_BUG);
VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx - 1, addr, SG_COUNT_ASIC_BUG);
addr = addr + len - SG_COUNT_ASIC_BUG;
len = SG_COUNT_ASIC_BUG;
- ap->prd[idx].addr = cpu_to_le32(addr);
- ap->prd[idx].flags_len = cpu_to_le32(len);
+ prd[idx].addr = cpu_to_le32(addr);
+ prd[idx].flags_len = cpu_to_le32(len);
VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
idx++;
}
- ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
+ prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
}
static void pdc_qc_prep(struct ata_queued_cmd *qc)
@@ -567,7 +568,7 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
pdc_fill_sg(qc);
/*FALLTHROUGH*/
case ATA_PROT_NODATA:
- i = pdc_pkt_header(&qc->tf, qc->ap->prd_dma,
+ i = pdc_pkt_header(&qc->tf, qc->ap->bmdma_prd_dma,
qc->dev->devno, pp->pkt);
if (qc->tf.flags & ATA_TFLAG_LBA48)
i = pdc_prep_lba48(&qc->tf, pp->pkt, i);
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 609d147..43e0024 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -224,7 +224,7 @@ static void k2_bmdma_setup_mmio(struct ata_queued_cmd *qc)
/* load PRD table addr. */
mb(); /* make sure PRD table writes are visible to controller */
- writel(ap->prd_dma, mmio + ATA_DMA_TABLE_OFS);
+ writel(ap->bmdma_prd_dma, mmio + ATA_DMA_TABLE_OFS);
/* specify data direction, triple-check start bit is clear */
dmactl = readb(mmio + ATA_DMA_CMD);
diff --git a/include/linux/ata.h b/include/linux/ata.h
index a53318b..a4e55f0 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -418,7 +418,7 @@ enum ata_ioctls {
/* core structures */
-struct ata_prd {
+struct ata_bmdma_prd {
__le32 addr;
__le32 flags_len;
};
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 197ce14..5256be0 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -682,6 +682,8 @@ struct ata_port {
u8 ctl; /* cache of ATA control register */
u8 last_ctl; /* Cache last written value */
struct delayed_work sff_pio_task;
+ struct ata_bmdma_prd *bmdma_prd; /* BMDMA SG list */
+ dma_addr_t bmdma_prd_dma; /* and its DMA mapping */
#endif /* CONFIG_ATA_SFF */
unsigned int pio_mask;
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 17/22] libata-sff: separate out BMDMA qc_issue
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (15 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 16/22] libata-sff: prd is " Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 18/22] libata-sff: ata_sff_irq_clear() is BMDMA specific Tejun Heo
` (10 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
Separate out ata_bmdma_qc_issue() from ata_sff_qc_issue() such that
ata_sff_qc_issue() only deals with non-BMDMA SFF protocols (PIO and
nodata) while ata_bmdma_qc_issue() deals with the BMDMA protocols and
uses ata_sff_qc_issue() for non-DMA commands. All the users are
updated accordingly.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-sff.c | 112 ++++++++++++++++++++++++++------------------
drivers/ata/pata_acpi.c | 4 +-
drivers/ata/pata_cs5530.c | 2 +-
drivers/ata/pata_hpt3x2n.c | 2 +-
drivers/ata/pata_it821x.c | 4 +-
drivers/ata/pata_oldpiix.c | 2 +-
drivers/ata/pata_radisys.c | 2 +-
drivers/ata/pata_sc1200.c | 2 +-
drivers/ata/sata_nv.c | 4 +-
include/linux/libata.h | 1 +
10 files changed, 79 insertions(+), 56 deletions(-)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index de03c0b..197b8c3 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1239,15 +1239,11 @@ fsm_start:
}
/**
- * ata_sff_qc_issue - issue taskfile to device in proto-dependent manner
+ * ata_sff_qc_issue - issue taskfile to a SFF controller
* @qc: command to issue to device
*
- * Using various libata functions and hooks, this function
- * starts an ATA command. ATA commands are grouped into
- * classes called "protocols", and issuing each type of protocol
- * is slightly different.
- *
- * May be used as the qc_issue() entry in ata_port_operations.
+ * This function issues a PIO or NODATA command to a SFF
+ * controller.
*
* LOCKING:
* spin_lock_irqsave(host lock)
@@ -1262,23 +1258,8 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
/* Use polling pio if the LLD doesn't handle
* interrupt driven pio and atapi CDB interrupt.
*/
- if (ap->flags & ATA_FLAG_PIO_POLLING) {
- switch (qc->tf.protocol) {
- case ATA_PROT_PIO:
- case ATA_PROT_NODATA:
- case ATAPI_PROT_PIO:
- case ATAPI_PROT_NODATA:
- qc->tf.flags |= ATA_TFLAG_POLLING;
- break;
- case ATAPI_PROT_DMA:
- if (qc->dev->flags & ATA_DFLAG_CDB_INTR)
- /* see ata_dma_blacklisted() */
- BUG();
- break;
- default:
- break;
- }
- }
+ if (ap->flags & ATA_FLAG_PIO_POLLING)
+ qc->tf.flags |= ATA_TFLAG_POLLING;
/* select the device */
ata_dev_select(ap, qc->dev->devno, 1, 0);
@@ -1297,15 +1278,6 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
break;
- case ATA_PROT_DMA:
- WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
-
- ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */
- ap->ops->bmdma_setup(qc); /* set up bmdma */
- ap->ops->bmdma_start(qc); /* initiate bmdma */
- ap->hsm_task_state = HSM_ST_LAST;
- break;
-
case ATA_PROT_PIO:
if (qc->tf.flags & ATA_TFLAG_POLLING)
ata_qc_set_polling(qc);
@@ -1350,18 +1322,6 @@ unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
ata_sff_queue_pio_task(ap, 0);
break;
- case ATAPI_PROT_DMA:
- WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
-
- ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */
- ap->ops->bmdma_setup(qc); /* set up bmdma */
- ap->hsm_task_state = HSM_ST_FIRST;
-
- /* send cdb by polling if no cdb interrupt */
- if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
- ata_sff_queue_pio_task(ap, 0);
- break;
-
default:
WARN_ON(1);
return AC_ERR_SYSTEM;
@@ -2371,6 +2331,7 @@ const struct ata_port_operations ata_bmdma_port_ops = {
.post_internal_cmd = ata_bmdma_post_internal_cmd,
.qc_prep = ata_bmdma_qc_prep,
+ .qc_issue = ata_bmdma_qc_issue,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
@@ -2523,6 +2484,66 @@ void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc)
}
/**
+ * ata_bmdma_qc_issue - issue taskfile to a BMDMA controller
+ * @qc: command to issue to device
+ *
+ * This function issues a PIO, NODATA or DMA command to a
+ * SFF/BMDMA controller. PIO and NODATA are handled by
+ * ata_sff_qc_issue().
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ *
+ * RETURNS:
+ * Zero on success, AC_ERR_* mask on failure
+ */
+unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+
+ /* see ata_dma_blacklisted() */
+ BUG_ON((ap->flags & ATA_FLAG_PIO_POLLING) &&
+ qc->tf.protocol == ATAPI_PROT_DMA);
+
+ /* defer PIO handling to sff_qc_issue */
+ if (!ata_is_dma(qc->tf.protocol))
+ return ata_sff_qc_issue(qc);
+
+ /* select the device */
+ ata_dev_select(ap, qc->dev->devno, 1, 0);
+
+ /* start the command */
+ switch (qc->tf.protocol) {
+ case ATA_PROT_DMA:
+ WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+
+ ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */
+ ap->ops->bmdma_setup(qc); /* set up bmdma */
+ ap->ops->bmdma_start(qc); /* initiate bmdma */
+ ap->hsm_task_state = HSM_ST_LAST;
+ break;
+
+ case ATAPI_PROT_DMA:
+ WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
+
+ ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */
+ ap->ops->bmdma_setup(qc); /* set up bmdma */
+ ap->hsm_task_state = HSM_ST_FIRST;
+
+ /* send cdb by polling if no cdb interrupt */
+ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
+ ata_sff_queue_pio_task(ap, 0);
+ break;
+
+ default:
+ WARN_ON(1);
+ return AC_ERR_SYSTEM;
+ }
+
+ return 0;
+}
+
+/**
* ata_bmdma_error_handler - Stock error handler for BMDMA controller
* @ap: port to handle error for
*
@@ -2919,6 +2940,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
EXPORT_SYMBOL_GPL(ata_bmdma_qc_prep);
+EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue);
EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index d701e28..49ccc2d 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -177,7 +177,7 @@ static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
struct pata_acpi *acpi = ap->private_data;
if (acpi->gtm.flags & 0x10)
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
if (adev != acpi->last) {
pacpi_set_piomode(ap, adev);
@@ -185,7 +185,7 @@ static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
pacpi_set_dmamode(ap, adev);
acpi->last = adev;
}
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
}
/**
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 6dae09a..f267953 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -157,7 +157,7 @@ static unsigned int cs5530_qc_issue(struct ata_queued_cmd *qc)
cs5530_set_dmamode(ap, adev);
}
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
}
static struct scsi_host_template cs5530_sht = {
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index d5c9fd7..4fb82d1 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -323,7 +323,7 @@ static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc)
hpt3x2n_set_clock(ap, 0x23);
}
}
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
}
static struct scsi_host_template hpt3x2n_sht = {
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 27c5968..8a65309 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -429,7 +429,7 @@ static unsigned int it821x_smart_qc_issue(struct ata_queued_cmd *qc)
case 0xFC: /* Internal 'report rebuild state' */
/* Arguably should just no-op this one */
case ATA_CMD_SET_FEATURES:
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
}
printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command);
return AC_ERR_DEV;
@@ -447,7 +447,7 @@ static unsigned int it821x_smart_qc_issue(struct ata_queued_cmd *qc)
static unsigned int it821x_passthru_qc_issue(struct ata_queued_cmd *qc)
{
it821x_passthru_dev_select(qc->ap, qc->dev->devno);
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
}
/**
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index df64f24..5c073ca 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -201,7 +201,7 @@ static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc)
if (ata_dma_enabled(adev))
oldpiix_set_dmamode(ap, adev);
}
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
}
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 1c0d9fa..aa38e6d 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -180,7 +180,7 @@ static unsigned int radisys_qc_issue(struct ata_queued_cmd *qc)
radisys_set_piomode(ap, adev);
}
}
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
}
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index cee8eb9..a1db07a 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -175,7 +175,7 @@ static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc)
sc1200_set_dmamode(ap, adev);
}
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
}
static struct scsi_host_template sc1200_sht = {
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index e30ce2e..3d77bc4 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1413,7 +1413,7 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
BUG_ON(!(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) &&
(qc->flags & ATA_QCFLAG_DMAMAP));
nv_adma_register_mode(qc->ap);
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
} else
nv_adma_mode(qc->ap);
@@ -2013,7 +2013,7 @@ static unsigned int nv_swncq_qc_issue(struct ata_queued_cmd *qc)
struct nv_swncq_port_priv *pp = ap->private_data;
if (qc->tf.protocol != ATA_PROT_NCQ)
- return ata_sff_qc_issue(qc);
+ return ata_bmdma_qc_issue(qc);
DPRINTK("Enter\n");
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 5256be0..34adaca 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1538,6 +1538,7 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev,
extern void ata_bus_reset(struct ata_port *ap); /* deprecated */
extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc);
+extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc);
extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc);
extern void ata_bmdma_error_handler(struct ata_port *ap);
extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 18/22] libata-sff: ata_sff_irq_clear() is BMDMA specific
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (16 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 17/22] libata-sff: separate out BMDMA qc_issue Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 19/22] libata-sff: separate out BMDMA irq handler Tejun Heo
` (9 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
ata_sff_irq_clear() is BMDMA specific. Rename it to
ata_bmdma_irq_clear(), move it to ata_bmdma_port_ops and make
->sff_irq_clear() optional.
Note: ata_bmdma_irq_clear() is actually only needed by ata_piix and
possibly by sata_sil. This should be moved to respective low
level drivers later.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-sff.c | 67 ++++++++++++++++++++++++++--------------------
drivers/ata/pata_bf54x.c | 2 +-
drivers/ata/pata_scc.c | 2 +-
drivers/ata/sata_nv.c | 2 +-
drivers/ata/sata_sil.c | 4 +-
drivers/ata/sata_via.c | 2 +-
include/linux/libata.h | 2 +-
7 files changed, 45 insertions(+), 36 deletions(-)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 197b8c3..96d93ce 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -62,7 +62,6 @@ const struct ata_port_operations ata_sff_port_ops = {
.sff_exec_command = ata_sff_exec_command,
.sff_data_xfer = ata_sff_data_xfer,
.sff_irq_on = ata_sff_irq_on,
- .sff_irq_clear = ata_sff_irq_clear,
};
/**
@@ -356,33 +355,13 @@ u8 ata_sff_irq_on(struct ata_port *ap)
iowrite8(ap->ctl, ioaddr->ctl_addr);
tmp = ata_wait_idle(ap);
- ap->ops->sff_irq_clear(ap);
+ if (ap->ops->sff_irq_clear)
+ ap->ops->sff_irq_clear(ap);
return tmp;
}
/**
- * ata_sff_irq_clear - Clear PCI IDE BMDMA interrupt.
- * @ap: Port associated with this ATA transaction.
- *
- * Clear interrupt and error flags in DMA status register.
- *
- * May be used as the irq_clear() entry in ata_port_operations.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_sff_irq_clear(struct ata_port *ap)
-{
- void __iomem *mmio = ap->ioaddr.bmdma_addr;
-
- if (!mmio)
- return;
-
- iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS);
-}
-
-/**
* ata_sff_tf_load - send taskfile registers to host controller
* @ap: Port to which output is sent
* @tf: ATA taskfile register set
@@ -1422,7 +1401,8 @@ inline unsigned int ata_sff_host_intr(struct ata_port *ap,
goto idle_irq;
/* clear irq events */
- ap->ops->sff_irq_clear(ap);
+ if (ap->ops->sff_irq_clear)
+ ap->ops->sff_irq_clear(ap);
ata_sff_hsm_move(ap, qc, status, 0);
@@ -1438,7 +1418,8 @@ idle_irq:
#ifdef ATA_IRQ_TRAP
if ((ap->stats.idle_irq % 1000) == 0) {
ap->ops->sff_check_status(ap);
- ap->ops->sff_irq_clear(ap);
+ if (ap->ops->sff_irq_clear)
+ ap->ops->sff_irq_clear(ap);
ata_port_printk(ap, KERN_WARNING, "irq trap\n");
return 1;
}
@@ -1509,7 +1490,8 @@ void ata_sff_freeze(struct ata_port *ap)
*/
ap->ops->sff_check_status(ap);
- ap->ops->sff_irq_clear(ap);
+ if (ap->ops->sff_irq_clear)
+ ap->ops->sff_irq_clear(ap);
}
/**
@@ -1525,7 +1507,8 @@ void ata_sff_thaw(struct ata_port *ap)
{
/* clear & re-enable interrupts */
ap->ops->sff_check_status(ap);
- ap->ops->sff_irq_clear(ap);
+ if (ap->ops->sff_irq_clear)
+ ap->ops->sff_irq_clear(ap);
ap->ops->sff_irq_on(ap);
}
@@ -2333,6 +2316,7 @@ const struct ata_port_operations ata_bmdma_port_ops = {
.qc_prep = ata_bmdma_qc_prep,
.qc_issue = ata_bmdma_qc_issue,
+ .sff_irq_clear = ata_bmdma_irq_clear,
.bmdma_setup = ata_bmdma_setup,
.bmdma_start = ata_bmdma_start,
.bmdma_stop = ata_bmdma_stop,
@@ -2588,7 +2572,8 @@ void ata_bmdma_error_handler(struct ata_port *ap)
/* if we're gonna thaw, make sure IRQ is clear */
if (thaw) {
ap->ops->sff_check_status(ap);
- ap->ops->sff_irq_clear(ap);
+ if (ap->ops->sff_irq_clear)
+ ap->ops->sff_irq_clear(ap);
}
}
@@ -2620,6 +2605,30 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
}
/**
+ * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
+ * @ap: Port associated with this ATA transaction.
+ *
+ * Clear interrupt and error flags in DMA status register.
+ *
+ * May be used as the irq_clear() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+void ata_bmdma_irq_clear(struct ata_port *ap)
+{
+ void __iomem *mmio = ap->ioaddr.bmdma_addr;
+
+ /* This function is called for non-DMA commands too. Check
+ * whether bmdma_addr is valid.
+ */
+ if (!mmio)
+ return;
+
+ iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS);
+}
+
+/**
* ata_bmdma_setup - Set up PCI IDE BMDMA transaction
* @qc: Info associated with this ATA transaction.
*
@@ -2916,7 +2925,6 @@ EXPORT_SYMBOL_GPL(ata_sff_exec_command);
EXPORT_SYMBOL_GPL(ata_sff_data_xfer);
EXPORT_SYMBOL_GPL(ata_sff_data_xfer_noirq);
EXPORT_SYMBOL_GPL(ata_sff_irq_on);
-EXPORT_SYMBOL_GPL(ata_sff_irq_clear);
EXPORT_SYMBOL_GPL(ata_sff_hsm_move);
EXPORT_SYMBOL_GPL(ata_sff_qc_issue);
EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
@@ -2944,6 +2952,7 @@ EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue);
EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
+EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
EXPORT_SYMBOL_GPL(ata_bmdma_setup);
EXPORT_SYMBOL_GPL(ata_bmdma_start);
EXPORT_SYMBOL_GPL(ata_bmdma_stop);
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index de3e45f..170a71e 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -1203,7 +1203,7 @@ static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf,
* bfin_irq_clear - Clear ATAPI interrupt.
* @ap: Port associated with this ATA transaction.
*
- * Note: Original code is ata_sff_irq_clear().
+ * Note: Original code is ata_bmdma_irq_clear().
*/
static void bfin_irq_clear(struct ata_port *ap)
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index c96b090..0ffe330 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -914,7 +914,7 @@ static void scc_postreset(struct ata_link *link, unsigned int *classes)
* scc_irq_clear - Clear PCI IDE BMDMA interrupt.
* @ap: Port associated with this ATA transaction.
*
- * Note: Original code is ata_sff_irq_clear().
+ * Note: Original code is ata_bmdma_irq_clear().
*/
static void scc_irq_clear (struct ata_port *ap)
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 3d77bc4..6f02be2 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -1045,7 +1045,7 @@ static void nv_adma_irq_clear(struct ata_port *ap)
u32 notifier_clears[2];
if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) {
- ata_sff_irq_clear(ap);
+ ata_bmdma_irq_clear(ap);
return;
}
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index dce3b91..70b62af 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -410,7 +410,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
goto err_hsm;
/* ack bmdma irq events */
- ata_sff_irq_clear(ap);
+ ata_bmdma_irq_clear(ap);
/* kick HSM in the ass */
ata_sff_hsm_move(ap, qc, status, 0);
@@ -478,7 +478,7 @@ static void sil_thaw(struct ata_port *ap)
/* clear IRQ */
ap->ops->sff_check_status(ap);
- ata_sff_irq_clear(ap);
+ ata_bmdma_irq_clear(ap);
/* turn on SATA IRQ if supported */
if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ))
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 1cfa745..282de39 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -174,7 +174,7 @@ static void svia_noop_freeze(struct ata_port *ap)
* certain way. Leave it alone and just clear pending IRQ.
*/
ap->ops->sff_check_status(ap);
- ata_sff_irq_clear(ap);
+ ata_bmdma_irq_clear(ap);
}
/**
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 34adaca..5c06e5f 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1501,7 +1501,6 @@ extern unsigned int ata_sff_data_xfer(struct ata_device *dev,
extern unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev,
unsigned char *buf, unsigned int buflen, int rw);
extern u8 ata_sff_irq_on(struct ata_port *ap);
-extern void ata_sff_irq_clear(struct ata_port *ap);
extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
u8 status, int in_wq);
extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc);
@@ -1542,6 +1541,7 @@ extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc);
extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc);
extern void ata_bmdma_error_handler(struct ata_port *ap);
extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);
+extern void ata_bmdma_irq_clear(struct ata_port *ap);
extern void ata_bmdma_setup(struct ata_queued_cmd *qc);
extern void ata_bmdma_start(struct ata_queued_cmd *qc);
extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 19/22] libata-sff: separate out BMDMA irq handler
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (17 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 18/22] libata-sff: ata_sff_irq_clear() is BMDMA specific Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 20/22] libata-sff: separate out BMDMA init Tejun Heo
` (8 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
Separate out BMDMA irq handler from SFF irq handler. The misnamed
host_intr() functions are renamed to ata_sff_port_intr() and
ata_bmdma_port_intr().
All BMDMA drivers now use ata_bmdma_interrupt() or
ata_bmdma_port_intr() while all non-BMDMA SFF ones use
ata_sff_interrupt() or ata_sff_port_intr().
For now, ata_pci_sff_init_one() uses ata_bmdma_interrupt() as it's
used by both SFF and BMDMA drivers.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/ata_piix.c | 2 +-
drivers/ata/libata-sff.c | 172 +++++++++++++++++++++++++++++--------------
drivers/ata/pata_cs5520.c | 2 +-
drivers/ata/pata_hpt3x3.c | 2 +-
drivers/ata/pata_icside.c | 2 +-
drivers/ata/pata_ninja32.c | 2 +-
drivers/ata/pata_pdc2027x.c | 2 +-
drivers/ata/pata_scc.c | 2 +-
drivers/ata/pata_sil680.c | 2 +-
drivers/ata/sata_mv.c | 2 +-
drivers/ata/sata_nv.c | 4 +-
drivers/ata/sata_qstor.c | 2 +-
drivers/ata/sata_sis.c | 2 +-
drivers/ata/sata_svw.c | 2 +-
drivers/ata/sata_uli.c | 2 +-
drivers/ata/sata_via.c | 2 +-
drivers/ata/sata_vsc.c | 2 +-
include/linux/libata.h | 5 +-
18 files changed, 138 insertions(+), 73 deletions(-)
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index e9e32ed..c1da5e6 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -1471,7 +1471,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
}
pci_set_master(pdev);
- return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht);
+ return ata_pci_sff_activate_host(host, ata_bmdma_interrupt, &piix_sht);
}
static int __init piix_init(void)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 96d93ce..4655181 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1328,14 +1328,28 @@ bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc)
return true;
}
+static unsigned int ata_sff_idle_irq(struct ata_port *ap)
+{
+ ap->stats.idle_irq++;
+
+#ifdef ATA_IRQ_TRAP
+ if ((ap->stats.idle_irq % 1000) == 0) {
+ ap->ops->sff_check_status(ap);
+ if (ap->ops->sff_irq_clear)
+ ap->ops->sff_irq_clear(ap);
+ ata_port_printk(ap, KERN_WARNING, "irq trap\n");
+ return 1;
+ }
+#endif
+ return 0; /* irq not handled */
+}
+
/**
- * ata_sff_host_intr - Handle host interrupt for given (port, task)
+ * ata_sff_port_intr - Handle SFF port interrupt
* @ap: Port on which interrupt arrived (possibly...)
* @qc: Taskfile currently active in engine
*
- * Handle host interrupt for given queued command. Currently,
- * only DMA interrupts are handled. All other commands are
- * handled via polling with interrupts disabled (nIEN bit).
+ * Handle port interrupt for given queued command.
*
* LOCKING:
* spin_lock_irqsave(host lock)
@@ -1343,11 +1357,10 @@ bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc)
* RETURNS:
* One if interrupt was handled, zero if not (shared irq).
*/
-inline unsigned int ata_sff_host_intr(struct ata_port *ap,
+inline unsigned int ata_sff_port_intr(struct ata_port *ap,
struct ata_queued_cmd *qc)
{
- struct ata_eh_info *ehi = &ap->link.eh_info;
- u8 status, host_stat = 0;
+ u8 status;
VPRINTK("ata%u: protocol %d task_state %d\n",
ap->print_id, qc->tf.protocol, ap->hsm_task_state);
@@ -1364,41 +1377,20 @@ inline unsigned int ata_sff_host_intr(struct ata_port *ap,
* need to check ata_is_atapi(qc->tf.protocol) again.
*/
if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
- goto idle_irq;
- break;
- case HSM_ST_LAST:
- if (qc->tf.protocol == ATA_PROT_DMA ||
- qc->tf.protocol == ATAPI_PROT_DMA) {
- /* check status of DMA engine */
- host_stat = ap->ops->bmdma_status(ap);
- VPRINTK("ata%u: host_stat 0x%X\n",
- ap->print_id, host_stat);
-
- /* if it's not our irq... */
- if (!(host_stat & ATA_DMA_INTR))
- goto idle_irq;
-
- /* before we do anything else, clear DMA-Start bit */
- ap->ops->bmdma_stop(qc);
-
- if (unlikely(host_stat & ATA_DMA_ERR)) {
- /* error when transfering data to/from memory */
- qc->err_mask |= AC_ERR_HOST_BUS;
- ap->hsm_task_state = HSM_ST_ERR;
- }
- }
+ return ata_sff_idle_irq(ap);
break;
case HSM_ST:
+ case HSM_ST_LAST:
break;
default:
- goto idle_irq;
+ return ata_sff_idle_irq(ap);
}
/* check main status, clearing INTRQ if needed */
status = ata_sff_irq_status(ap);
if (status & ATA_BUSY)
- goto idle_irq;
+ return ata_sff_idle_irq(ap);
/* clear irq events */
if (ap->ops->sff_irq_clear)
@@ -1406,34 +1398,16 @@ inline unsigned int ata_sff_host_intr(struct ata_port *ap,
ata_sff_hsm_move(ap, qc, status, 0);
- if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
- qc->tf.protocol == ATAPI_PROT_DMA))
- ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
-
return 1; /* irq handled */
-
-idle_irq:
- ap->stats.idle_irq++;
-
-#ifdef ATA_IRQ_TRAP
- if ((ap->stats.idle_irq % 1000) == 0) {
- ap->ops->sff_check_status(ap);
- if (ap->ops->sff_irq_clear)
- ap->ops->sff_irq_clear(ap);
- ata_port_printk(ap, KERN_WARNING, "irq trap\n");
- return 1;
- }
-#endif
- return 0; /* irq not handled */
}
/**
- * ata_sff_interrupt - Default ATA host interrupt handler
+ * ata_sff_interrupt - Default SFF ATA host interrupt handler
* @irq: irq line (unused)
* @dev_instance: pointer to our ata_host information structure
*
* Default interrupt handler for PCI IDE devices. Calls
- * ata_sff_host_intr() for each port that is not disabled.
+ * ata_sff_port_intr() for each port that is not disabled.
*
* LOCKING:
* Obtains host lock during operation.
@@ -1457,7 +1431,7 @@ irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
qc = ata_qc_from_tag(ap, ap->link.active_tag);
if (qc && !(qc->tf.flags & ATA_TFLAG_POLLING))
- handled |= ata_sff_host_intr(ap, qc);
+ handled |= ata_sff_port_intr(ap, qc);
}
spin_unlock_irqrestore(&host->lock, flags);
@@ -2205,7 +2179,7 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
host->private_data = host_priv;
pci_set_master(pdev);
- rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
+ rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
out:
if (rc == 0)
devres_remove_group(&pdev->dev, NULL);
@@ -2528,6 +2502,92 @@ unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc)
}
/**
+ * ata_bmdma_port_intr - Handle BMDMA port interrupt
+ * @ap: Port on which interrupt arrived (possibly...)
+ * @qc: Taskfile currently active in engine
+ *
+ * Handle port interrupt for given queued command.
+ *
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ *
+ * RETURNS:
+ * One if interrupt was handled, zero if not (shared irq).
+ */
+inline unsigned int ata_bmdma_port_intr(struct ata_port *ap,
+ struct ata_queued_cmd *qc)
+{
+ struct ata_eh_info *ehi = &ap->link.eh_info;
+ u8 host_stat = 0;
+ unsigned int handled;
+
+ if (ap->hsm_task_state == HSM_ST_LAST && ata_is_dma(qc->tf.protocol)) {
+ /* check status of DMA engine */
+ host_stat = ap->ops->bmdma_status(ap);
+ VPRINTK("ata%u: host_stat 0x%X\n",
+ ap->print_id, host_stat);
+
+ /* if it's not our irq... */
+ if (!(host_stat & ATA_DMA_INTR))
+ return ata_sff_idle_irq(ap);
+
+ /* before we do anything else, clear DMA-Start bit */
+ ap->ops->bmdma_stop(qc);
+
+ if (unlikely(host_stat & ATA_DMA_ERR)) {
+ /* error when transfering data to/from memory */
+ qc->err_mask |= AC_ERR_HOST_BUS;
+ ap->hsm_task_state = HSM_ST_ERR;
+ }
+ }
+
+ handled = ata_sff_port_intr(ap, qc);
+
+ if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol))
+ ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
+
+ return handled;
+}
+
+/**
+ * ata_bmdma_interrupt - Default BMDMA ATA host interrupt handler
+ * @irq: irq line (unused)
+ * @dev_instance: pointer to our ata_host information structure
+ *
+ * Default interrupt handler for PCI IDE devices. Calls
+ * ata_bmdma_port_intr() for each port that is not disabled.
+ *
+ * LOCKING:
+ * Obtains host lock during operation.
+ *
+ * RETURNS:
+ * IRQ_NONE or IRQ_HANDLED.
+ */
+irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance)
+{
+ struct ata_host *host = dev_instance;
+ unsigned int i;
+ unsigned int handled = 0;
+ unsigned long flags;
+
+ /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
+ spin_lock_irqsave(&host->lock, flags);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap = host->ports[i];
+ struct ata_queued_cmd *qc;
+
+ qc = ata_qc_from_tag(ap, ap->link.active_tag);
+ if (qc && !(qc->tf.flags & ATA_TFLAG_POLLING))
+ handled |= ata_bmdma_port_intr(ap, qc);
+ }
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return IRQ_RETVAL(handled);
+}
+
+/**
* ata_bmdma_error_handler - Stock error handler for BMDMA controller
* @ap: port to handle error for
*
@@ -2928,7 +2988,7 @@ EXPORT_SYMBOL_GPL(ata_sff_irq_on);
EXPORT_SYMBOL_GPL(ata_sff_hsm_move);
EXPORT_SYMBOL_GPL(ata_sff_qc_issue);
EXPORT_SYMBOL_GPL(ata_sff_qc_fill_rtf);
-EXPORT_SYMBOL_GPL(ata_sff_host_intr);
+EXPORT_SYMBOL_GPL(ata_sff_port_intr);
EXPORT_SYMBOL_GPL(ata_sff_interrupt);
EXPORT_SYMBOL_GPL(ata_sff_freeze);
EXPORT_SYMBOL_GPL(ata_sff_thaw);
@@ -2950,6 +3010,8 @@ EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
EXPORT_SYMBOL_GPL(ata_bmdma_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue);
EXPORT_SYMBOL_GPL(ata_bmdma_dumb_qc_prep);
+EXPORT_SYMBOL_GPL(ata_bmdma_port_intr);
+EXPORT_SYMBOL_GPL(ata_bmdma_interrupt);
EXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index d5fe2b1..8cd06e4 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -258,7 +258,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
continue;
rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
- ata_sff_interrupt, 0, DRV_NAME, host);
+ ata_bmdma_interrupt, 0, DRV_NAME, host);
if (rc)
return rc;
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index f11a320..8ac65cb 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -209,7 +209,7 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd");
}
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &hpt3x3_sht);
}
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index 6ab3ada..4cbef74 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -482,7 +482,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
pata_icside_setup_ioaddr(ap, info->base, info, info->port[i]);
}
- return ata_host_activate(host, ec->irq, ata_sff_interrupt, 0,
+ return ata_host_activate(host, ec->irq, ata_bmdma_interrupt, 0,
&pata_icside_sht);
}
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c
index 565e67c..8f6b64d 100644
--- a/drivers/ata/pata_ninja32.c
+++ b/drivers/ata/pata_ninja32.c
@@ -142,7 +142,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id)
iowrite8(0xa4, base + 0x1c); /* Unknown */
iowrite8(0x83, base + 0x1d); /* BMDMA control: WAIT0 */
/* FIXME: Should we disable them at remove ? */
- return ata_host_activate(host, dev->irq, ata_sff_interrupt,
+ return ata_host_activate(host, dev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &ninja32_sht);
}
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index dfecd1a..76727aa 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -759,7 +759,7 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
return -EIO;
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &pdc2027x_sht);
}
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 0ffe330..7a5b49c 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -1145,7 +1145,7 @@ static int scc_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (rc)
return rc;
- return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &scc_sht);
}
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index a598bb3..9fffab2 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -355,7 +355,7 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
ata_sff_std_ports(&host->ports[1]->ioaddr);
/* Register & activate */
- return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &sil680_sht);
use_ioports:
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 20e926c..d9cfbf4 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -2074,7 +2074,7 @@ static void mv_port_intr(struct ata_port *ap, u32 port_cause)
} else if (!edma_was_enabled) {
struct ata_queued_cmd *qc = mv_get_active_qc(ap);
if (qc)
- ata_sff_host_intr(ap, qc);
+ ata_sff_port_intr(ap, qc);
else
mv_unexpected_intr(ap, edma_was_enabled);
}
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 6f02be2..0806f65 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -866,7 +866,7 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
}
/* handle interrupt */
- return ata_sff_host_intr(ap, qc);
+ return ata_bmdma_port_intr(ap, qc);
}
static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
@@ -1450,7 +1450,7 @@ static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance)
qc = ata_qc_from_tag(ap, ap->link.active_tag);
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
- handled += ata_sff_host_intr(ap, qc);
+ handled += ata_bmdma_port_intr(ap, qc);
else
// No request pending? Clear interrupt status
// anyway, in case there's one pending.
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index b8783bc..44ff556 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -452,7 +452,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)
if (!pp || pp->state != qs_state_mmio)
continue;
if (!(qc->tf.flags & ATA_TFLAG_POLLING))
- handled |= ata_sff_host_intr(ap, qc);
+ handled |= ata_sff_port_intr(ap, qc);
}
return handled;
}
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 9c43b4e..6104df7 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -333,7 +333,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
pci_intx(pdev, 1);
- return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &sis_sht);
}
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 43e0024..b1049bd 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -502,7 +502,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &k2_sata_sht);
}
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index 4801689..5753e89 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -241,7 +241,7 @@ static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_master(pdev);
pci_intx(pdev, 1);
- return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &uli_sht);
}
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 282de39..7ebc406 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -448,7 +448,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
svia_configure(pdev);
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ return ata_host_activate(host, pdev->irq, ata_bmdma_interrupt,
IRQF_SHARED, &svia_sht);
}
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index 45bd21c..a0cba98 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -245,7 +245,7 @@ static void vsc_port_intr(u8 port_status, struct ata_port *ap)
qc = ata_qc_from_tag(ap, ap->link.active_tag);
if (qc && likely(!(qc->tf.flags & ATA_TFLAG_POLLING)))
- handled = ata_sff_host_intr(ap, qc);
+ handled = ata_bmdma_port_intr(ap, qc);
/* We received an interrupt during a polled command,
* or some other spurious condition. Interrupt reporting
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 5c06e5f..8cc0a9b 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1505,7 +1505,7 @@ extern int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
u8 status, int in_wq);
extern unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc);
extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc);
-extern unsigned int ata_sff_host_intr(struct ata_port *ap,
+extern unsigned int ata_sff_port_intr(struct ata_port *ap,
struct ata_queued_cmd *qc);
extern irqreturn_t ata_sff_interrupt(int irq, void *dev_instance);
extern void ata_sff_freeze(struct ata_port *ap);
@@ -1539,6 +1539,9 @@ extern void ata_bus_reset(struct ata_port *ap); /* deprecated */
extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc);
extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc);
extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc);
+extern unsigned int ata_bmdma_port_intr(struct ata_port *ap,
+ struct ata_queued_cmd *qc);
+extern irqreturn_t ata_bmdma_interrupt(int irq, void *dev_instance);
extern void ata_bmdma_error_handler(struct ata_port *ap);
extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);
extern void ata_bmdma_irq_clear(struct ata_port *ap);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 20/22] libata-sff: separate out BMDMA init
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (18 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 19/22] libata-sff: separate out BMDMA irq handler Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 15:49 ` [PATCH 20/22 UPDATED] " Tejun Heo
2008-10-21 9:17 ` [PATCH 21/22] sata_qstor: kill dummy BMDMA ops Tejun Heo
` (7 subsequent siblings)
27 siblings, 1 reply; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
Separate out ata_pci_bmdma_prepare_host() and ata_pci_bmdma_init_one()
from their SFF counterparts. SFF ones no longer try to initialize
BMDMA or set PCI master.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/ata_piix.c | 2 +-
drivers/ata/libata-sff.c | 135 ++++++++++++++++++++++++++++++++-------
drivers/ata/pata_acpi.c | 2 +-
drivers/ata/pata_ali.c | 5 +-
drivers/ata/pata_amd.c | 2 +-
drivers/ata/pata_artop.c | 2 +-
drivers/ata/pata_atiixp.c | 2 +-
drivers/ata/pata_cmd64x.c | 2 +-
drivers/ata/pata_cs5530.c | 2 +-
drivers/ata/pata_cs5535.c | 2 +-
drivers/ata/pata_cs5536.c | 2 +-
drivers/ata/pata_cypress.c | 2 +-
drivers/ata/pata_efar.c | 2 +-
drivers/ata/pata_hpt366.c | 2 +-
drivers/ata/pata_hpt37x.c | 2 +-
drivers/ata/pata_hpt3x2n.c | 2 +-
drivers/ata/pata_it8213.c | 2 +-
drivers/ata/pata_it821x.c | 2 +-
drivers/ata/pata_jmicron.c | 2 +-
drivers/ata/pata_marvell.c | 2 +-
drivers/ata/pata_netcell.c | 2 +-
drivers/ata/pata_ns87415.c | 2 +-
drivers/ata/pata_oldpiix.c | 2 +-
drivers/ata/pata_optidma.c | 2 +-
drivers/ata/pata_pdc202xx_old.c | 2 +-
drivers/ata/pata_radisys.c | 2 +-
drivers/ata/pata_sc1200.c | 2 +-
drivers/ata/pata_sch.c | 2 +-
drivers/ata/pata_serverworks.c | 2 +-
drivers/ata/pata_sil680.c | 2 +-
drivers/ata/pata_sis.c | 2 +-
drivers/ata/pata_sl82c105.c | 2 +-
drivers/ata/pata_triflex.c | 2 +-
drivers/ata/pata_via.c | 2 +-
drivers/ata/sata_nv.c | 2 +-
drivers/ata/sata_sis.c | 2 +-
drivers/ata/sata_via.c | 2 +-
include/linux/libata.h | 7 ++
38 files changed, 157 insertions(+), 60 deletions(-)
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index c1da5e6..1959254 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -1435,7 +1435,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
hpriv->map = piix_init_sata_map(pdev, port_info,
piix_map_db_table[ent->driver_data]);
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
host->private_data = hpriv;
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 4655181..2a4e62d 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1974,13 +1974,13 @@ int ata_pci_sff_init_host(struct ata_host *host)
}
/**
- * ata_pci_sff_prepare_host - helper to prepare native PCI ATA host
+ * ata_pci_sff_prepare_host - helper to prepare PCI PIO-only SFF ATA host
* @pdev: target PCI device
* @ppi: array of port_info, must be enough for two ports
* @r_host: out argument for the initialized ATA host
*
- * Helper to allocate ATA host for @pdev, acquire all native PCI
- * resources and initialize it accordingly in one go.
+ * Helper to allocate PIO-only SFF ATA host for @pdev, acquire
+ * all PCI resources and initialize it accordingly in one go.
*
* LOCKING:
* Inherited from calling layer (may sleep).
@@ -2010,9 +2010,6 @@ int ata_pci_sff_prepare_host(struct pci_dev *pdev,
if (rc)
goto err_out;
- /* init DMA related stuff */
- ata_pci_bmdma_init(host);
-
devres_remove_group(&pdev->dev, NULL);
*r_host = host;
return 0;
@@ -2115,8 +2112,21 @@ int ata_pci_sff_activate_host(struct ata_host *host,
return rc;
}
+static const struct ata_port_info *ata_sff_find_valid_pi(
+ const struct ata_port_info * const *ppi)
+{
+ int i;
+
+ /* look up the first valid port_info */
+ for (i = 0; i < 2 && ppi[i]; i++)
+ if (ppi[i]->port_ops != &ata_dummy_port_ops)
+ return ppi[i];
+
+ return NULL;
+}
+
/**
- * ata_pci_sff_init_one - Initialize/register PCI IDE host controller
+ * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller
* @pdev: Controller to be initialized
* @ppi: array of port_info, must be enough for two ports
* @sht: scsi_host_template to use when registering the host
@@ -2124,11 +2134,7 @@ int ata_pci_sff_activate_host(struct ata_host *host,
*
* This is a helper function which can be called from a driver's
* xxx_init_one() probe function if the hardware uses traditional
- * IDE taskfile registers.
- *
- * This function calls pci_enable_device(), reserves its register
- * regions, sets the dma mask, enables bus master mode, and calls
- * ata_device_add()
+ * IDE taskfile registers and is PIO only.
*
* ASSUMPTION:
* Nobody makes a single channel controller that appears solely as
@@ -2145,20 +2151,13 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
struct scsi_host_template *sht, void *host_priv)
{
struct device *dev = &pdev->dev;
- const struct ata_port_info *pi = NULL;
+ const struct ata_port_info *pi;
struct ata_host *host = NULL;
- int i, rc;
+ int rc;
DPRINTK("ENTER\n");
- /* look up the first valid port_info */
- for (i = 0; i < 2 && ppi[i]; i++) {
- if (ppi[i]->port_ops != &ata_dummy_port_ops) {
- pi = ppi[i];
- break;
- }
- }
-
+ pi = ata_sff_find_valid_pi(ppi);
if (!pi) {
dev_printk(KERN_ERR, &pdev->dev,
"no valid port_info specified\n");
@@ -2178,8 +2177,7 @@ int ata_pci_sff_init_one(struct pci_dev *pdev,
goto out;
host->private_data = host_priv;
- pci_set_master(pdev);
- rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
+ rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
out:
if (rc == 0)
devres_remove_group(&pdev->dev, NULL);
@@ -2914,6 +2912,93 @@ void ata_pci_bmdma_init(struct ata_host *host)
}
}
+/**
+ * ata_pci_bmdma_prepare_host - helper to prepare PCI BMDMA ATA host
+ * @pdev: target PCI device
+ * @ppi: array of port_info, must be enough for two ports
+ * @r_host: out argument for the initialized ATA host
+ *
+ * Helper to allocate BMDMA ATA host for @pdev, acquire all PCI
+ * resources and initialize it accordingly in one go.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_pci_bmdma_prepare_host(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ struct ata_host **r_host)
+{
+ int rc;
+
+ rc = ata_pci_sff_prepare_host(pdev, ppi, r_host);
+ if (rc)
+ return rc;
+
+ ata_pci_bmdma_init(*r_host);
+ return 0;
+}
+
+/**
+ * ata_pci_bmdma_init_one - Initialize/register BMDMA PCI IDE controller
+ * @pdev: Controller to be initialized
+ * @ppi: array of port_info, must be enough for two ports
+ * @sht: scsi_host_template to use when registering the host
+ * @host_priv: host private_data
+ *
+ * This function is similar to ata_pci_sff_init_one() but also
+ * takes care of BMDMA initialization.
+ *
+ * LOCKING:
+ * Inherited from PCI layer (may sleep).
+ *
+ * RETURNS:
+ * Zero on success, negative on errno-based value on error.
+ */
+int ata_pci_bmdma_init_one(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ struct scsi_host_template *sht, void *host_priv)
+{
+ struct device *dev = &pdev->dev;
+ const struct ata_port_info *pi;
+ struct ata_host *host = NULL;
+ int rc;
+
+ DPRINTK("ENTER\n");
+
+ pi = ata_sff_find_valid_pi(ppi);
+ if (!pi) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "no valid port_info specified\n");
+ return -EINVAL;
+ }
+
+ if (!devres_open_group(dev, NULL, GFP_KERNEL))
+ return -ENOMEM;
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ goto out;
+
+ /* prepare and activate BMDMA host */
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
+ if (rc)
+ goto out;
+ host->private_data = host_priv;
+
+ pci_set_master(pdev);
+ rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
+ out:
+ if (rc == 0)
+ devres_remove_group(&pdev->dev, NULL);
+ else
+ devres_release_group(&pdev->dev, NULL);
+
+ return rc;
+}
+
#endif /* CONFIG_PCI */
/**
@@ -3023,4 +3108,6 @@ EXPORT_SYMBOL_GPL(ata_bmdma_port_start);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
+EXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host);
+EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one);
#endif /* CONFIG_PCI */
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index 49ccc2d..6e1bfda 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -265,7 +265,7 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
return rc;
pcim_pin_device(pdev);
}
- return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &pacpi_sht, NULL);
}
static const struct pci_device_id pacpi_pci_tbl[] = {
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 171a49e..8ccf889 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -553,7 +553,10 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
}
pci_dev_put(isa_bridge);
- return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL);
+ if (!ppi[0]->mwdma_mask && !ppi[0]->udma_mask)
+ return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL);
+ else
+ return ata_pci_bmdma_init_one(pdev, ppi, &ali_sht, NULL);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 57dd00f..19de535 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -523,7 +523,7 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* And fire it up */
- return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv);
+ return ata_pci_bmdma_init_one(pdev, ppi, &amd_sht, hpriv);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 0f513bc..80cff6f 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -400,7 +400,7 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
BUG_ON(ppi[0] == NULL);
- return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &artop_sht, NULL);
}
static const struct pci_device_id artop_pci_tbl[] = {
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 3fae282..60ffd04 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -243,7 +243,7 @@ static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
.port_ops = &atiixp_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
- return ata_pci_sff_init_one(dev, ppi, &atiixp_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &atiixp_sht, NULL);
}
static const struct pci_device_id atiixp[] = {
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index ddd09b7..a770b37 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -373,7 +373,7 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
#endif
- return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &cmd64x_sht, NULL);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index f267953..6c8ee7d 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -325,7 +325,7 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
ppi[1] = &info_palmax_secondary;
/* Now kick off ATA set up */
- return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &cs5530_sht, NULL);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index f1b6556..6d9cc80 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -199,7 +199,7 @@ static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
rdmsr(ATAC_CH0D1_PIO, timings, dummy);
if (CS5535_BAD_PIO(timings))
wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0);
- return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &cs5535_sht, NULL);
}
static const struct pci_device_id cs5535[] = {
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
index 73f8332..2310acb 100644
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -261,7 +261,7 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV;
}
- return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &cs5536_sht, NULL);
}
static const struct pci_device_id cs5536[] = {
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index 2ff6260..43c4571 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -136,7 +136,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
if (PCI_FUNC(pdev->devfn) != 1)
return -ENODEV;
- return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &cy82c693_sht, NULL);
}
static const struct pci_device_id cy82c693[] = {
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index 9fba829..67a0ff0 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -262,7 +262,7 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &efar_sht, NULL);
}
static const struct pci_device_id efar_pci_tbl[] = {
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index d7b0bc5..f0e6c4c 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -393,7 +393,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
break;
}
/* Now kick off ATA set up */
- return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv);
+ return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, hpriv);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index b380d57..fe654ae 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -1019,7 +1019,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
}
/* Now kick off ATA set up */
- return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data);
+ return ata_pci_bmdma_init_one(dev, ppi, &hpt37x_sht, private_data);
}
static const struct pci_device_id hpt37x[] = {
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 4fb82d1..5d1ef7e 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -554,7 +554,7 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
}
/* Now kick off ATA set up */
- return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv);
+ return ata_pci_bmdma_init_one(dev, ppi, &hpt3x2n_sht, hpriv);
}
static const struct pci_device_id hpt3x2n[] = {
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index c113d7c..f6dff1e 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -274,7 +274,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &it8213_sht, NULL);
}
static const struct pci_device_id it8213_pci_tbl[] = {
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 8a65309..fd5af2b 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -923,7 +923,7 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
else
ppi[0] = &info_smart;
}
- return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &it821x_sht, NULL);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 73b7596..5d220fc 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -144,7 +144,7 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
};
const struct ata_port_info *ppi[] = { &info, NULL };
- return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL);
}
static const struct pci_device_id jmicron_pci_tbl[] = {
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index 0d87eec..f5c8db5 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -153,7 +153,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
return -ENODEV;
}
#endif
- return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &marvell_sht, NULL);
}
static const struct pci_device_id marvell_pci_tbl[] = {
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index d9719c8..c540c90 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -71,7 +71,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
ata_pci_bmdma_clear_simplex(pdev);
/* And let the library code do the work */
- return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, port_info, &netcell_sht, NULL);
}
static const struct pci_device_id netcell_pci_tbl[] = {
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c
index 260e0b0..31e7f83 100644
--- a/drivers/ata/pata_ns87415.c
+++ b/drivers/ata/pata_ns87415.c
@@ -375,7 +375,7 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e
pci_write_config_byte(pdev, 0x55, 0xEE);
/* Select PIO0 8bit clocking */
pci_write_config_byte(pdev, 0x54, 0xB7);
- return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &ns87415_sht, NULL);
}
static const struct pci_device_id ns87415_pci_tbl[] = {
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 5c073ca..ef637c0 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -249,7 +249,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &oldpiix_sht, NULL);
}
static const struct pci_device_id oldpiix_pci_tbl[] = {
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 4cd7444..522b0ca 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -430,7 +430,7 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (optiplus_with_udma(dev))
ppi[0] = &info_82c700_udma;
- return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &optidma_sht, NULL);
}
static const struct pci_device_id optidma[] = {
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index b452e4a..43ec5e6 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -324,7 +324,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
return -ENODEV;
}
}
- return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &pdc202xx_sht, NULL);
}
static const struct pci_device_id pdc202xx[] = {
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index aa38e6d..8e4c519 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -228,7 +228,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &radisys_sht, NULL);
}
static const struct pci_device_id radisys_pci_tbl[] = {
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index a1db07a..c836e1b 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -213,7 +213,7 @@ static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* Can't enable port 2 yet, see top comments */
const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
- return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &sc1200_sht, NULL);
}
static const struct pci_device_id sc1200[] = {
diff --git a/drivers/ata/pata_sch.c b/drivers/ata/pata_sch.c
index 4c77d63..0b381f1 100644
--- a/drivers/ata/pata_sch.c
+++ b/drivers/ata/pata_sch.c
@@ -179,7 +179,7 @@ static int __devinit sch_init_one(struct pci_dev *pdev,
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &sch_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &sch_sht, NULL);
}
static int __init sch_init(void)
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index d1be370..3a15ac5 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -461,7 +461,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
ata_pci_bmdma_clear_simplex(pdev);
- return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &serverworks_sht, NULL);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 9fffab2..7c85227 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -359,7 +359,7 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
IRQF_SHARED, &sil680_sht);
use_ioports:
- return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &sil680_sht, NULL);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 26345d7..cda3338 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -822,7 +822,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
sis_fixup(pdev, chipset);
- return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset);
+ return ata_pci_bmdma_init_one(pdev, ppi, &sis_sht, chipset);
}
static const struct pci_device_id sis_pci_tbl[] = {
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index 69877bd..51d1481 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -317,7 +317,7 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val);
- return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL);
}
static const struct pci_device_id sl82c105[] = {
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index b181261..fa1b074 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -201,7 +201,7 @@ static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
if (!printed_version++)
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &triflex_sht, NULL);
}
static const struct pci_device_id triflex[] = {
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index 8fdb2ce..fdd132e 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -537,7 +537,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
}
/* We have established the device type, now fire it up */
- return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config);
+ return ata_pci_bmdma_init_one(pdev, ppi, &via_sht, (void *)config);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index 0806f65..ca132c5 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -2360,7 +2360,7 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
ppi[0] = &nv_port_info[type];
ipriv = ppi[0]->private_data;
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 6104df7..b65eb71 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -315,7 +315,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 7ebc406..1d40df1 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -316,7 +316,7 @@ static int vt6420_prepare_host(struct pci_dev *pdev, struct ata_host **r_host)
struct ata_host *host;
int rc;
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
*r_host = host;
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 8cc0a9b..d500200 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -1554,6 +1554,13 @@ extern int ata_bmdma_port_start(struct ata_port *ap);
#ifdef CONFIG_PCI
extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev);
extern void ata_pci_bmdma_init(struct ata_host *host);
+extern int ata_pci_bmdma_prepare_host(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ struct ata_host **r_host);
+extern int ata_pci_bmdma_init_one(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ struct scsi_host_template *sht,
+ void *host_priv);
#endif /* CONFIG_PCI */
/**
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 21/22] sata_qstor: kill dummy BMDMA ops
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (19 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 20/22] libata-sff: separate out BMDMA init Tejun Heo
@ 2008-10-21 9:17 ` Tejun Heo
2008-10-21 10:10 ` Sergei Shtylyov
2008-10-21 9:18 ` [PATCH 22/22] libata-sff: make BMDMA optional Tejun Heo
` (6 subsequent siblings)
27 siblings, 1 reply; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:17 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
Now that SFF and BMDMA are completely separate, sata_qstor which
inherits from ata_sff_port_ops doesn't have anything to worry about
its BMDMA ops being called. Kill the dummy BMDMA ops.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/sata_qstor.c | 14 --------------
1 files changed, 0 insertions(+), 14 deletions(-)
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 44ff556..5912f80 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -119,8 +119,6 @@ static void qs_host_stop(struct ata_host *host);
static void qs_qc_prep(struct ata_queued_cmd *qc);
static unsigned int qs_qc_issue(struct ata_queued_cmd *qc);
static int qs_check_atapi_dma(struct ata_queued_cmd *qc);
-static void qs_bmdma_stop(struct ata_queued_cmd *qc);
-static u8 qs_bmdma_status(struct ata_port *ap);
static void qs_freeze(struct ata_port *ap);
static void qs_thaw(struct ata_port *ap);
static int qs_prereset(struct ata_link *link, unsigned long deadline);
@@ -136,8 +134,6 @@ static struct ata_port_operations qs_ata_ops = {
.inherits = &ata_sff_port_ops,
.check_atapi_dma = qs_check_atapi_dma,
- .bmdma_stop = qs_bmdma_stop,
- .bmdma_status = qs_bmdma_status,
.qc_prep = qs_qc_prep,
.qc_issue = qs_qc_issue,
@@ -188,16 +184,6 @@ static int qs_check_atapi_dma(struct ata_queued_cmd *qc)
return 1; /* ATAPI DMA not supported */
}
-static void qs_bmdma_stop(struct ata_queued_cmd *qc)
-{
- /* nothing */
-}
-
-static u8 qs_bmdma_status(struct ata_port *ap)
-{
- return 0;
-}
-
static inline void qs_enter_reg_mode(struct ata_port *ap)
{
u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* [PATCH 22/22] libata-sff: make BMDMA optional
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (20 preceding siblings ...)
2008-10-21 9:17 ` [PATCH 21/22] sata_qstor: kill dummy BMDMA ops Tejun Heo
@ 2008-10-21 9:18 ` Tejun Heo
2008-10-21 9:26 ` [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (5 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:18 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
Make BMDMA optional depending on new config variable CONFIG_ATA_BMDMA.
In Kconfig, drivers are grouped into four groups - non-SFF native, SFF
w/ custom DMA interface, SFF w/ BMDMA, and PIO-only SFF ones.
ata_ioports.bmdma_add and ata_port.bmdma_prd[_dma] are put into
CONFIG_ATA_BMDMA, as are all bmdma related ops, variables and
functions.
This increase the binary size slightly when BMDMA is enabled but on
both native-only and PIO-only configurations the size is slightly
reduced. Either way, the size difference is insignificant. This
chnage is more meaningful to signify the separation between SFF and
BMDMA and as a tool to verify the separation (at least to certain
extent).
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/Kconfig | 348 ++++++++++++++++++++++++----------------------
drivers/ata/Makefile | 47 ++++---
drivers/ata/libata-sff.c | 13 ++
include/linux/libata.h | 22 ++-
4 files changed, 242 insertions(+), 188 deletions(-)
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 7cf243e..e4695eb 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -47,6 +47,8 @@ config SATA_PMP
This option adds support for SATA Port Multipliers
(the SATA version of an ethernet hub, or SAS expander).
+comment "Controllers with non-SFF native interface"
+
config SATA_AHCI
tristate "AHCI SATA support"
depends on PCI
@@ -98,24 +100,7 @@ config ATA_SFF
if ATA_SFF
-config SATA_SVW
- tristate "ServerWorks Frodo / Apple K2 SATA support"
- depends on PCI
- help
- This option enables support for Broadcom/Serverworks/Apple K2
- SATA support.
-
- If unsure, say N.
-
-config ATA_PIIX
- tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support"
- depends on PCI
- help
- This option enables support for ICH5/6/7/8 Serial ATA
- and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series
- host controllers.
-
- If unsure, say N.
+comment "SFF controllers with custom DMA interface"
config SATA_MV
tristate "Marvell SATA support (HIGHLY EXPERIMENTAL)"
@@ -126,11 +111,11 @@ config SATA_MV
If unsure, say N.
-config SATA_NV
- tristate "NVIDIA SATA support"
+config SATA_QSTOR
+ tristate "Pacific Digital SATA QStor support"
depends on PCI
help
- This option enables support for NVIDIA Serial ATA.
+ This option enables support for Pacific Digital Serial ATA QStor.
If unsure, say N.
@@ -142,11 +127,44 @@ config PDC_ADMA
If unsure, say N.
-config SATA_QSTOR
- tristate "Pacific Digital SATA QStor support"
+comment "SFF controllers with BMDMA"
+
+config ATA_BMDMA
+ bool "ATA BMDMA support"
+ default y
+ help
+ This option adds support for SFF ATA controllers with BMDMA
+ capability. BMDMA stands for bus-master DMA and the
+ de-facto DMA interface for SFF controllers.
+
+ If unuser, say Y.
+
+if ATA_BMDMA
+
+config SATA_SVW
+ tristate "ServerWorks Frodo / Apple K2 SATA support"
depends on PCI
help
- This option enables support for Pacific Digital Serial ATA QStor.
+ This option enables support for Broadcom/Serverworks/Apple K2
+ SATA support.
+
+ If unsure, say N.
+
+config ATA_PIIX
+ tristate "Intel ESB, ICH, PIIX3, PIIX4 PATA/SATA support"
+ depends on PCI
+ help
+ This option enables support for ICH5/6/7/8 Serial ATA
+ and support for PATA on the Intel ESB/ICH/PIIX3/PIIX4 series
+ host controllers.
+
+ If unsure, say N.
+
+config SATA_NV
+ tristate "NVIDIA SATA support"
+ depends on PCI
+ help
+ This option enables support for NVIDIA Serial ATA.
If unsure, say N.
@@ -244,15 +262,6 @@ config PATA_ARTOP
If unsure, say N.
-config PATA_AT32
- tristate "Atmel AVR32 PATA support (Experimental)"
- depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL
- help
- This option enables support for the IDE devices on the
- Atmel AT32AP platform.
-
- If unsure, say N.
-
config PATA_ATIIXP
tristate "ATI PATA support"
depends on PCI
@@ -262,16 +271,6 @@ config PATA_ATIIXP
If unsure, say N.
-config PATA_CMD640_PCI
- tristate "CMD640 PCI PATA support (Very Experimental)"
- depends on PCI && EXPERIMENTAL
- help
- This option enables support for the CMD640 PCI IDE
- interface chip. Only the primary channel is currently
- supported.
-
- If unsure, say N.
-
config PATA_CMD64X
tristate "CMD64x PATA support"
depends on PCI
@@ -388,15 +387,6 @@ config PATA_HPT3X3_DMA
controllers. Enable with care as there are still some
problems with DMA on this chipset.
-config PATA_ISAPNP
- tristate "ISA Plug and Play PATA support (Experimental)"
- depends on EXPERIMENTAL && ISAPNP
- help
- This option enables support for ISA plug & play ATA
- controllers such as those found on old soundcards.
-
- If unsure, say N.
-
config PATA_IT821X
tristate "IT8211/2 PATA support"
depends on PCI
@@ -425,15 +415,6 @@ config PATA_JMICRON
If unsure, say N.
-config PATA_LEGACY
- tristate "Legacy ISA PATA support (Experimental)"
- depends on ISA && EXPERIMENTAL
- help
- This option enables support for ISA/VLB bus legacy PATA
- ports and allows them to be accessed via the new ATA layer.
-
- If unsure, say N.
-
config PATA_TRIFLEX
tristate "Compaq Triflex PATA support"
depends on PCI
@@ -454,23 +435,6 @@ config PATA_MARVELL
If unsure, say N.
-config PATA_MPC52xx
- tristate "Freescale MPC52xx SoC internal IDE"
- depends on PPC_MPC52xx
- help
- This option enables support for integrated IDE controller
- of the Freescale MPC52xx SoC.
-
- If unsure, say N.
-
-config PATA_MPIIX
- tristate "Intel PATA MPIIX support"
- depends on PCI
- help
- This option enables support for MPIIX PATA support.
-
- If unsure, say N.
-
config PATA_OLDPIIX
tristate "Intel PATA old PIIX support"
depends on PCI
@@ -497,15 +461,6 @@ config PATA_NINJA32
If unsure, say N.
-config PATA_NS87410
- tristate "Nat Semi NS87410 PATA support (Experimental)"
- depends on PCI && EXPERIMENTAL
- help
- This option enables support for the National Semiconductor
- NS87410 PCI-IDE controller.
-
- If unsure, say N.
-
config PATA_NS87415
tristate "Nat Semi NS87415 PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
@@ -515,15 +470,6 @@ config PATA_NS87415
If unsure, say N.
-config PATA_OPTI
- tristate "OPTI621/6215 PATA support (Very Experimental)"
- depends on PCI && EXPERIMENTAL
- help
- This option enables full PIO support for the early Opti ATA
- controllers found on some old motherboards.
-
- If unsure, say N.
-
config PATA_OPTIDMA
tristate "OPTI FireStar PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
@@ -534,15 +480,6 @@ config PATA_OPTIDMA
If unsure, say N.
-config PATA_PCMCIA
- tristate "PCMCIA PATA support"
- depends on PCMCIA
- help
- This option enables support for PCMCIA ATA interfaces, including
- compact flash card adapters via the new ATA layer.
-
- If unsure, say N.
-
config PATA_PDC_OLD
tristate "Older Promise PATA controller support (Experimental)"
depends on PCI && EXPERIMENTAL
@@ -552,12 +489,6 @@ config PATA_PDC_OLD
If unsure, say N.
-config PATA_QDI
- tristate "QDI VLB PATA support"
- depends on ISA
- help
- Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
-
config PATA_RADISYS
tristate "RADISYS 82600 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
@@ -567,24 +498,6 @@ config PATA_RADISYS
If unsure, say N.
-config PATA_RB532
- tristate "RouterBoard 532 PATA CompactFlash support"
- depends on MIKROTIK_RB532
- help
- This option enables support for the RouterBoard 532
- PATA CompactFlash controller.
-
- If unsure, say N.
-
-config PATA_RZ1000
- tristate "PC Tech RZ1000 PATA support"
- depends on PCI
- help
- This option enables basic support for the PC Tech RZ1000/1
- PATA controllers via the new ATA layer
-
- If unsure, say N.
-
config PATA_SC1200
tristate "SC1200 PATA support (Very Experimental)"
depends on PCI && EXPERIMENTAL
@@ -645,40 +558,6 @@ config PATA_WINBOND
If unsure, say N.
-config PATA_WINBOND_VLB
- tristate "Winbond W83759A VLB PATA support (Experimental)"
- depends on ISA && EXPERIMENTAL
- help
- Support for the Winbond W83759A controller on Vesa Local Bus
- systems.
-
-config HAVE_PATA_PLATFORM
- bool
- help
- This is an internal configuration node for any machine that
- uses pata-platform driver to enable the relevant driver in the
- configuration structure without having to submit endless patches
- to update the PATA_PLATFORM entry.
-
-config PATA_PLATFORM
- tristate "Generic platform device PATA support"
- depends on EMBEDDED || PPC || HAVE_PATA_PLATFORM
- help
- This option enables support for generic directly connected ATA
- devices commonly found on embedded systems.
-
- If unsure, say N.
-
-config PATA_OF_PLATFORM
- tristate "OpenFirmware platform device PATA support"
- depends on PATA_PLATFORM && PPC_OF
- help
- This option enables support for generic directly connected ATA
- devices commonly found on embedded systems with OpenFirmware
- bindings.
-
- If unsure, say N.
-
config PATA_ICSIDE
tristate "Acorn ICS PATA support"
depends on ARM && ARCH_ACORN
@@ -724,5 +603,148 @@ config PATA_BF54X
If unsure, say N.
+endif # ATA_BMDMA
+
+comment "PIO-only SFF controllers"
+
+config PATA_AT32
+ tristate "Atmel AVR32 PATA support (Experimental)"
+ depends on AVR32 && PLATFORM_AT32AP && EXPERIMENTAL
+ help
+ This option enables support for the IDE devices on the
+ Atmel AT32AP platform.
+
+ If unsure, say N.
+
+config PATA_CMD640_PCI
+ tristate "CMD640 PCI PATA support (Very Experimental)"
+ depends on PCI && EXPERIMENTAL
+ help
+ This option enables support for the CMD640 PCI IDE
+ interface chip. Only the primary channel is currently
+ supported.
+
+ If unsure, say N.
+
+config PATA_ISAPNP
+ tristate "ISA Plug and Play PATA support (Experimental)"
+ depends on EXPERIMENTAL && ISAPNP
+ help
+ This option enables support for ISA plug & play ATA
+ controllers such as those found on old soundcards.
+
+ If unsure, say N.
+
+config PATA_LEGACY
+ tristate "Legacy ISA PATA support (Experimental)"
+ depends on ISA && EXPERIMENTAL
+ help
+ This option enables support for ISA/VLB bus legacy PATA
+ ports and allows them to be accessed via the new ATA layer.
+
+ If unsure, say N.
+
+config PATA_MPC52xx
+ tristate "Freescale MPC52xx SoC internal IDE"
+ depends on PPC_MPC52xx
+ help
+ This option enables support for integrated IDE controller
+ of the Freescale MPC52xx SoC.
+
+ If unsure, say N.
+
+config PATA_MPIIX
+ tristate "Intel PATA MPIIX support"
+ depends on PCI
+ help
+ This option enables support for MPIIX PATA support.
+
+ If unsure, say N.
+
+config PATA_NS87410
+ tristate "Nat Semi NS87410 PATA support (Experimental)"
+ depends on PCI && EXPERIMENTAL
+ help
+ This option enables support for the National Semiconductor
+ NS87410 PCI-IDE controller.
+
+ If unsure, say N.
+
+config PATA_OPTI
+ tristate "OPTI621/6215 PATA support (Very Experimental)"
+ depends on PCI && EXPERIMENTAL
+ help
+ This option enables full PIO support for the early Opti ATA
+ controllers found on some old motherboards.
+
+ If unsure, say N.
+
+config PATA_PCMCIA
+ tristate "PCMCIA PATA support"
+ depends on PCMCIA
+ help
+ This option enables support for PCMCIA ATA interfaces, including
+ compact flash card adapters via the new ATA layer.
+
+ If unsure, say N.
+
+config HAVE_PATA_PLATFORM
+ bool
+ help
+ This is an internal configuration node for any machine that
+ uses pata-platform driver to enable the relevant driver in the
+ configuration structure without having to submit endless patches
+ to update the PATA_PLATFORM entry.
+
+config PATA_PLATFORM
+ tristate "Generic platform device PATA support"
+ depends on EMBEDDED || PPC || HAVE_PATA_PLATFORM
+ help
+ This option enables support for generic directly connected ATA
+ devices commonly found on embedded systems.
+
+ If unsure, say N.
+
+config PATA_OF_PLATFORM
+ tristate "OpenFirmware platform device PATA support"
+ depends on PATA_PLATFORM && PPC_OF
+ help
+ This option enables support for generic directly connected ATA
+ devices commonly found on embedded systems with OpenFirmware
+ bindings.
+
+ If unsure, say N.
+
+config PATA_QDI
+ tristate "QDI VLB PATA support"
+ depends on ISA
+ help
+ Support for QDI 6500 and 6580 PATA controllers on VESA local bus.
+
+config PATA_RB532
+ tristate "RouterBoard 532 PATA CompactFlash support"
+ depends on MIKROTIK_RB532
+ help
+ This option enables support for the RouterBoard 532
+ PATA CompactFlash controller.
+
+ If unsure, say N.
+
+config PATA_RZ1000
+ tristate "PC Tech RZ1000 PATA support"
+ depends on PCI
+ help
+ This option enables basic support for the PC Tech RZ1000/1
+ PATA controllers via the new ATA layer
+
+ If unsure, say N.
+
+config PATA_WINBOND_VLB
+ tristate "Winbond W83759A VLB PATA support (Experimental)"
+ depends on ISA && EXPERIMENTAL
+ help
+ Support for the Winbond W83759A controller on Vesa Local Bus
+ systems.
+
endif # ATA_SFF
endif # ATA
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 674965f..4fad2cf 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -1,30 +1,34 @@
obj-$(CONFIG_ATA) += libata.o
+# non-SFF interface
obj-$(CONFIG_SATA_AHCI) += ahci.o
+obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
+obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
+obj-$(CONFIG_SATA_FSL) += sata_fsl.o
+
+# SFF w/ custom DMA
+obj-$(CONFIG_SATA_MV) += sata_mv.o
+obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o
+obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
+
+# SFF SATA w/ BMDMA
obj-$(CONFIG_SATA_SVW) += sata_svw.o
obj-$(CONFIG_ATA_PIIX) += ata_piix.o
obj-$(CONFIG_SATA_PROMISE) += sata_promise.o
-obj-$(CONFIG_SATA_QSTOR) += sata_qstor.o
obj-$(CONFIG_SATA_SIL) += sata_sil.o
-obj-$(CONFIG_SATA_SIL24) += sata_sil24.o
obj-$(CONFIG_SATA_VIA) += sata_via.o
obj-$(CONFIG_SATA_VITESSE) += sata_vsc.o
obj-$(CONFIG_SATA_SIS) += sata_sis.o
obj-$(CONFIG_SATA_SX4) += sata_sx4.o
obj-$(CONFIG_SATA_NV) += sata_nv.o
obj-$(CONFIG_SATA_ULI) += sata_uli.o
-obj-$(CONFIG_SATA_MV) += sata_mv.o
-obj-$(CONFIG_SATA_INIC162X) += sata_inic162x.o
-obj-$(CONFIG_PDC_ADMA) += pdc_adma.o
-obj-$(CONFIG_SATA_FSL) += sata_fsl.o
+# SFF PATA w/ BMDMA
obj-$(CONFIG_PATA_ALI) += pata_ali.o
obj-$(CONFIG_PATA_AMD) += pata_amd.o
obj-$(CONFIG_PATA_ARTOP) += pata_artop.o
-obj-$(CONFIG_PATA_AT32) += pata_at32.o
obj-$(CONFIG_PATA_ATIIXP) += pata_atiixp.o
-obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o
obj-$(CONFIG_PATA_CMD64X) += pata_cmd64x.o
obj-$(CONFIG_PATA_CS5520) += pata_cs5520.o
obj-$(CONFIG_PATA_CS5530) += pata_cs5530.o
@@ -36,42 +40,47 @@ obj-$(CONFIG_PATA_HPT366) += pata_hpt366.o
obj-$(CONFIG_PATA_HPT37X) += pata_hpt37x.o
obj-$(CONFIG_PATA_HPT3X2N) += pata_hpt3x2n.o
obj-$(CONFIG_PATA_HPT3X3) += pata_hpt3x3.o
-obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o
obj-$(CONFIG_PATA_IT821X) += pata_it821x.o
obj-$(CONFIG_PATA_IT8213) += pata_it8213.o
obj-$(CONFIG_PATA_JMICRON) += pata_jmicron.o
obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
obj-$(CONFIG_PATA_NINJA32) += pata_ninja32.o
-obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
obj-$(CONFIG_PATA_NS87415) += pata_ns87415.o
-obj-$(CONFIG_PATA_OPTI) += pata_opti.o
obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
-obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
-obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o
-obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
obj-$(CONFIG_PATA_PDC2027X) += pata_pdc2027x.o
obj-$(CONFIG_PATA_PDC_OLD) += pata_pdc202xx_old.o
-obj-$(CONFIG_PATA_QDI) += pata_qdi.o
obj-$(CONFIG_PATA_RADISYS) += pata_radisys.o
-obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o
-obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o
obj-$(CONFIG_PATA_SC1200) += pata_sc1200.o
obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o
obj-$(CONFIG_PATA_SIL680) += pata_sil680.o
obj-$(CONFIG_PATA_VIA) += pata_via.o
obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o
-obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o
obj-$(CONFIG_PATA_SIS) += pata_sis.o
obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
obj-$(CONFIG_PATA_SCC) += pata_scc.o
obj-$(CONFIG_PATA_SCH) += pata_sch.o
obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o
+obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
+
+# SFF PIO only
+obj-$(CONFIG_PATA_AT32) += pata_at32.o
+obj-$(CONFIG_PATA_CMD640_PCI) += pata_cmd640.o
+obj-$(CONFIG_PATA_ISAPNP) += pata_isapnp.o
+obj-$(CONFIG_PATA_MPC52xx) += pata_mpc52xx.o
+obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
+obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
+obj-$(CONFIG_PATA_OPTI) += pata_opti.o
+obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o
-obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
+obj-$(CONFIG_PATA_QDI) += pata_qdi.o
+obj-$(CONFIG_PATA_RB532) += pata_rb532_cf.o
+obj-$(CONFIG_PATA_RZ1000) += pata_rz1000.o
+obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o
+
# Should be last but two libata driver
obj-$(CONFIG_PATA_ACPI) += pata_acpi.o
# Should be last but one libata driver
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 2a4e62d..f8d2527 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -686,11 +686,15 @@ static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
case ATAPI_PROT_NODATA:
ap->hsm_task_state = HSM_ST_LAST;
break;
+#ifdef CONFIG_ATA_BMDMA
case ATAPI_PROT_DMA:
ap->hsm_task_state = HSM_ST_LAST;
/* initiate bmdma */
ap->ops->bmdma_start(qc);
break;
+#endif /* CONFIG_ATA_BMDMA */
+ default:
+ BUG();
}
}
@@ -2279,6 +2283,12 @@ err_out:
DPRINTK("EXIT\n");
}
+/*
+ * BMDMA support
+ */
+
+#ifdef CONFIG_ATA_BMDMA
+
const struct ata_port_operations ata_bmdma_port_ops = {
.inherits = &ata_sff_port_ops,
@@ -3000,6 +3010,7 @@ int ata_pci_bmdma_init_one(struct pci_dev *pdev,
}
#endif /* CONFIG_PCI */
+#endif /* CONFIG_ATA_BMDMA */
/**
* ata_sff_check_reset - Check whether standard reset methods are valid
@@ -3091,6 +3102,7 @@ EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
#endif /* CONFIG_PCI */
EXPORT_SYMBOL_GPL(ata_bus_reset);
+#ifdef CONFIG_ATA_BMDMA
EXPORT_SYMBOL_GPL(ata_bmdma_port_ops);
EXPORT_SYMBOL_GPL(ata_bmdma_qc_prep);
EXPORT_SYMBOL_GPL(ata_bmdma_qc_issue);
@@ -3111,3 +3123,4 @@ EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
EXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host);
EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one);
#endif /* CONFIG_PCI */
+#endif /* CONFIG_ATA_BMDMA */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index d500200..d2b0807 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -480,7 +480,9 @@ struct ata_ioports {
void __iomem *command_addr;
void __iomem *altstatus_addr;
void __iomem *ctl_addr;
+#ifdef CONFIG_ATA_BMDMA
void __iomem *bmdma_addr;
+#endif /* CONFIG_ATA_BMDMA */
void __iomem *scr_addr;
};
#endif /* CONFIG_ATA_SFF */
@@ -682,8 +684,10 @@ struct ata_port {
u8 ctl; /* cache of ATA control register */
u8 last_ctl; /* Cache last written value */
struct delayed_work sff_pio_task;
+#ifdef CONFIG_ATA_BMDMA
struct ata_bmdma_prd *bmdma_prd; /* BMDMA SG list */
dma_addr_t bmdma_prd_dma; /* and its DMA mapping */
+#endif /* CONFIG_ATA_BMDMA */
#endif /* CONFIG_ATA_SFF */
unsigned int pio_mask;
@@ -812,10 +816,12 @@ struct ata_port_operations {
u8 (*sff_irq_on)(struct ata_port *);
void (*sff_irq_clear)(struct ata_port *);
+#ifdef CONFIG_ATA_BMDMA
void (*bmdma_setup)(struct ata_queued_cmd *qc);
void (*bmdma_start)(struct ata_queued_cmd *qc);
void (*bmdma_stop)(struct ata_queued_cmd *qc);
u8 (*bmdma_status)(struct ata_port *ap);
+#endif /*CONFIG_ATA_BMDMA*/
#endif /* CONFIG_ATA_SFF */
ssize_t (*em_show)(struct ata_port *ap, char *buf);
@@ -1472,7 +1478,6 @@ extern void sata_pmp_error_handler(struct ata_port *ap);
#ifdef CONFIG_ATA_SFF
extern const struct ata_port_operations ata_sff_port_ops;
-extern const struct ata_port_operations ata_bmdma_port_ops;
/* PIO only, sg_tablesize and dma_boundary limits can be removed */
#define ATA_PIO_SHT(drv_name) \
@@ -1480,11 +1485,6 @@ extern const struct ata_port_operations ata_bmdma_port_ops;
.sg_tablesize = LIBATA_MAX_PRD, \
.dma_boundary = ATA_DMA_BOUNDARY
-#define ATA_BMDMA_SHT(drv_name) \
- ATA_BASE_SHT(drv_name), \
- .sg_tablesize = LIBATA_MAX_PRD, \
- .dma_boundary = ATA_DMA_BOUNDARY
-
extern void ata_sff_dev_select(struct ata_port *ap, unsigned int device);
extern u8 ata_sff_check_status(struct ata_port *ap);
extern void ata_sff_pause(struct ata_port *ap);
@@ -1536,6 +1536,15 @@ extern int ata_pci_sff_init_one(struct pci_dev *pdev,
extern void ata_bus_reset(struct ata_port *ap); /* deprecated */
+#ifdef CONFIG_ATA_BMDMA
+
+extern const struct ata_port_operations ata_bmdma_port_ops;
+
+#define ATA_BMDMA_SHT(drv_name) \
+ ATA_BASE_SHT(drv_name), \
+ .sg_tablesize = LIBATA_MAX_PRD, \
+ .dma_boundary = ATA_DMA_BOUNDARY
+
extern void ata_bmdma_qc_prep(struct ata_queued_cmd *qc);
extern unsigned int ata_bmdma_qc_issue(struct ata_queued_cmd *qc);
extern void ata_bmdma_dumb_qc_prep(struct ata_queued_cmd *qc);
@@ -1562,6 +1571,7 @@ extern int ata_pci_bmdma_init_one(struct pci_dev *pdev,
struct scsi_host_template *sht,
void *host_priv);
#endif /* CONFIG_PCI */
+#endif /* CONFIG_ATA_BMDMA */
/**
* ata_sff_busy_wait - Wait for a port status register
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (21 preceding siblings ...)
2008-10-21 9:18 ` [PATCH 22/22] libata-sff: make BMDMA optional Tejun Heo
@ 2008-10-21 9:26 ` Tejun Heo
2008-10-21 11:36 ` Sergei Shtylyov
` (4 subsequent siblings)
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 9:26 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi
Hello, a few more things.
The tree is available in the following git tree.
git://git.kernel.org/pub/scm/linux/kernel/git/tj/libata-dev.git separate-sff-bmdma
http://www.kernel.org/pub/scm/linux/kernel/git/tj/libata-dev.git;h=separate-sff-bmdma
I've tested the changes on the following drivers.
ahci, ata_generic, ata_piix, pata_hpt3x2n, pata_jmicron, pdc_adma,
sata_inic162x, sata_promise, sata_sil, sata_via.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
2008-10-21 9:17 ` [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary Tejun Heo
@ 2008-10-21 9:53 ` Sergei Shtylyov
2008-10-21 11:45 ` [PATCH 04/22, UPDATED] " Tejun Heo
2008-10-28 4:10 ` [PATCH 04/22] " Jeff Garzik
1 sibling, 1 reply; 44+ messages in thread
From: Sergei Shtylyov @ 2008-10-21 9:53 UTC (permalink / raw)
To: Tejun Heo; +Cc: jeff, linux-ide, linux-scsi
Hello.
Tejun Heo wrote:
> Clearing IRQ from ata_sff_error_handler() is necessary only when the
> port is gonna be thawed before performing EH actions and some
> controllers don't like being accessed after certain fail modes until
> they're reset. Clear IRQ iff the port is being thawed. Also, remove
> unnecessary ata_sff_sync() while at it.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
>
Sorry for the grammar nipicking but...
> diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
> index 4b47394..b9fb068 100644
> --- a/drivers/ata/libata-sff.c
> +++ b/drivers/ata/libata-sff.c
> @@ -2119,11 +2119,13 @@ void ata_sff_error_handler(struct ata_port *ap)
> }
>
> ap->ops->bmdma_stop(qc);
> - }
>
> - ata_sff_sync(ap); /* FIXME: We don't need this */
> - ap->ops->sff_check_status(ap);
> - ap->ops->sff_irq_clear(ap);
> + /* if we're gonna thaw, make sure IRQ is clear */
>
IRQ cannot be clear, only cleared. :-)
MBR, Sergei
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 21/22] sata_qstor: kill dummy BMDMA ops
2008-10-21 9:17 ` [PATCH 21/22] sata_qstor: kill dummy BMDMA ops Tejun Heo
@ 2008-10-21 10:10 ` Sergei Shtylyov
2008-10-21 11:27 ` Tejun Heo
0 siblings, 1 reply; 44+ messages in thread
From: Sergei Shtylyov @ 2008-10-21 10:10 UTC (permalink / raw)
To: Tejun Heo; +Cc: jeff, linux-ide, linux-scsi
Hello.
Tejun Heo wrote:
> Now that SFF and BMDMA are completely separate, sata_qstor which
>
SFF and BMDMA being separate sounds funny. :-)
MBR, Sergei
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 21/22] sata_qstor: kill dummy BMDMA ops
2008-10-21 10:10 ` Sergei Shtylyov
@ 2008-10-21 11:27 ` Tejun Heo
0 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 11:27 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: jeff, linux-ide, linux-scsi
Sergei Shtylyov wrote:
> Hello.
>
> Tejun Heo wrote:
>
>> Now that SFF and BMDMA are completely separate, sata_qstor which
>>
>
> SFF and BMDMA being separate sounds funny. :-)
Yeah, I wish I could say "PIO TF and BMDMA" but, well, it's too late.
SFF is the new TF in libata. I mean, who cares. :-P
--
tejun
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (22 preceding siblings ...)
2008-10-21 9:26 ` [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
@ 2008-10-21 11:36 ` Sergei Shtylyov
2008-10-21 11:43 ` Tejun Heo
2008-10-27 19:43 ` Mark Lord
` (3 subsequent siblings)
27 siblings, 1 reply; 44+ messages in thread
From: Sergei Shtylyov @ 2008-10-21 11:36 UTC (permalink / raw)
To: Tejun Heo; +Cc: jeff, linux-ide, linux-scsi
Hello.
Tejun Heo wrote:
> This is the first take of separate-out-SFF-and-BMDMA patchset.
>
If BMDMA means the well known Intel BMIDE spec (also known as
SFF-8038i) this separation starts to sound funny. :-)
> Historically, ATA meant SFF (or TASKFILE interface) plus BMDMA and
>
ATA means the taskfile interface plus the command set -- and nothing
else.
SFF couldn't mean taskfile interface because SFF ATAPI specs refers
to ATA in this part -- it could only mean either ATAPI command set or
BMDMA (BMIDE) interface which is spec'ed by SFF-8038i.
> that holds true for many modern SATA controllers. This was reflected
> in libata implementation and libata core layer and SFF/BMDMA support
> used to be all tangled in one piece.
>
The "all tangled" expression describes this mess quite well. :-)
> Another issue which surpassed with the addition of all the legacy,
> platform and somewhat peculiar PATA drivers is that now there are
> enough drivers which use SFF interface but use its own DMA interface
> or don't support DMA at all. This, in similar fashion, led those
> drivers to fake certain level of BMDMA functionality to please the
> libata SFF/BMDMA layer. This led to the following interesting
> solutions in low level drivers.
>
> 1. For BMDMA drivers which don't use traditional BMDMA register,
> ata_bmdma_mode_filter() incorrectly inhibits DMA modes. Those
> drivers either have to inherit from ata_sff_port_ops or clear
> ->mode_filter explicitly.
>
> 2. non-BMDMA drivers call into BMDMA PRD table allocation. It doesn't
> actually allocate PRD table if bmdma_addr is not initialized but is
> still confusing.
>
> 3. For BMDMA drivers which don't use traditional BMDMA register, some
> methods might not be invoked as expected (e.g. bmdma_stop from
> ata_sff_post_internal_cmd()).
>
What do you mean by BMDMA here? I'm now at a loss...
> 4. SFF drivers w/ custom DMA interface implement noop BMDMA ops
> worrying libata core might call into one of them.
>
Are those drivers not the same as "BMDMA drivers which don't use
traditional BMDMA register"?
MBR, Sergei
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-10-21 11:36 ` Sergei Shtylyov
@ 2008-10-21 11:43 ` Tejun Heo
0 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 11:43 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: jeff, linux-ide, linux-scsi
Hello, Sergei.
Sergei Shtylyov wrote:
> Tejun Heo wrote:
>> This is the first take of separate-out-SFF-and-BMDMA patchset.
>
> If BMDMA means the well known Intel BMIDE spec (also known as
> SFF-8038i) this separation starts to sound funny. :-)
Heh.. we had this discussion before. SFF is TF ATA in libata.
>> Historically, ATA meant SFF (or TASKFILE interface) plus BMDMA and
>>
> ATA means the taskfile interface plus the command set -- and nothing
> else. SFF couldn't mean taskfile interface because SFF ATAPI specs
> refers to ATA in this part -- it could only mean either ATAPI
> command set or BMDMA (BMIDE) interface which is spec'ed by
> SFF-8038i.
Yeah, I know now. We can either do s/sff/tf/ or just accept that SFF
is TF in libata for whatever reason. Maybe it's not Small Form Factor
but something like Strange Form of tF. :-)
>> that holds true for many modern SATA controllers. This was reflected
>> in libata implementation and libata core layer and SFF/BMDMA support
>> used to be all tangled in one piece.
>
> The "all tangled" expression describes this mess quite well. :-)
So, the above is actually about the tangledness between ATA SFF and
BMDMA.
>> Another issue which surpassed with the addition of all the legacy,
>> platform and somewhat peculiar PATA drivers is that now there are
>> enough drivers which use SFF interface but use its own DMA interface
>> or don't support DMA at all. This, in similar fashion, led those
>> drivers to fake certain level of BMDMA functionality to please the
>> libata SFF/BMDMA layer. This led to the following interesting
>> solutions in low level drivers.
>>
>> 1. For BMDMA drivers which don't use traditional BMDMA register,
>> ata_bmdma_mode_filter() incorrectly inhibits DMA modes. Those
>> drivers either have to inherit from ata_sff_port_ops or clear
>> ->mode_filter explicitly.
>>
>> 2. non-BMDMA drivers call into BMDMA PRD table allocation. It doesn't
>> actually allocate PRD table if bmdma_addr is not initialized but is
>> still confusing.
>>
>> 3. For BMDMA drivers which don't use traditional BMDMA register, some
>> methods might not be invoked as expected (e.g. bmdma_stop from
>> ata_sff_post_internal_cmd()).
>>
>
> What do you mean by BMDMA here? I'm now at a loss...
Rephrased: Drivers which inherit from bmdma_port_ops as they share
many similar characteristics with the standard BMDMA interface but
uses different register format.
>> 4. SFF drivers w/ custom DMA interface implement noop BMDMA ops
>> worrying libata core might call into one of them.
>
> Are those drivers not the same as "BMDMA drivers which don't use
> traditional BMDMA register"?
Rephrased: Drivers which uses ATA TF interface but uses completely
custom DMA interface instead of BMDMA or something similar to it.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 04/22, UPDATED] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
2008-10-21 9:53 ` Sergei Shtylyov
@ 2008-10-21 11:45 ` Tejun Heo
0 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 11:45 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: jeff, linux-ide, linux-scsi
Clearing IRQ from ata_sff_error_handler() is necessary only when the
port is gonna be thawed before performing EH actions and some
controllers don't like being accessed after certain fail modes until
they're reset. Clear IRQ iff the port is being thawed. Also, remove
unnecessary ata_sff_sync() while at it.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
s/clear/cleared/. git tree is updated too. Thanks.
drivers/ata/libata-sff.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
Index: work/drivers/ata/libata-sff.c
===================================================================
--- work.orig/drivers/ata/libata-sff.c
+++ work/drivers/ata/libata-sff.c
@@ -2119,11 +2119,13 @@ void ata_sff_error_handler(struct ata_po
}
ap->ops->bmdma_stop(qc);
- }
- ata_sff_sync(ap); /* FIXME: We don't need this */
- ap->ops->sff_check_status(ap);
- ap->ops->sff_irq_clear(ap);
+ /* if we're gonna thaw, make sure IRQ is cleared */
+ if (thaw) {
+ ap->ops->sff_check_status(ap);
+ ap->ops->sff_irq_clear(ap);
+ }
+ }
spin_unlock_irqrestore(ap->lock, flags);
^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 20/22 UPDATED] libata-sff: separate out BMDMA init
2008-10-21 9:17 ` [PATCH 20/22] libata-sff: separate out BMDMA init Tejun Heo
@ 2008-10-21 15:49 ` Tejun Heo
0 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-21 15:49 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi
Separate out ata_pci_bmdma_prepare_host() and ata_pci_bmdma_init_one()
from their SFF counterparts. SFF ones no longer try to initialize
BMDMA or set PCI master.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
Updated to reflect sata_via change[1]. git tree is updated accordingly.
[1] http://thread.gmane.org/gmane.linux.ide/35437
drivers/ata/ata_piix.c | 2
drivers/ata/libata-sff.c | 135 ++++++++++++++++++++++++++++++++--------
drivers/ata/pata_acpi.c | 2
drivers/ata/pata_ali.c | 5 +
drivers/ata/pata_amd.c | 2
drivers/ata/pata_artop.c | 2
drivers/ata/pata_atiixp.c | 2
drivers/ata/pata_cmd64x.c | 2
drivers/ata/pata_cs5530.c | 2
drivers/ata/pata_cs5535.c | 2
drivers/ata/pata_cs5536.c | 2
drivers/ata/pata_cypress.c | 2
drivers/ata/pata_efar.c | 2
drivers/ata/pata_hpt366.c | 2
drivers/ata/pata_hpt37x.c | 2
drivers/ata/pata_hpt3x2n.c | 2
drivers/ata/pata_it8213.c | 2
drivers/ata/pata_it821x.c | 2
drivers/ata/pata_jmicron.c | 2
drivers/ata/pata_marvell.c | 2
drivers/ata/pata_netcell.c | 2
drivers/ata/pata_ns87415.c | 2
drivers/ata/pata_oldpiix.c | 2
drivers/ata/pata_optidma.c | 2
drivers/ata/pata_pdc202xx_old.c | 2
drivers/ata/pata_radisys.c | 2
drivers/ata/pata_sc1200.c | 2
drivers/ata/pata_sch.c | 2
drivers/ata/pata_serverworks.c | 2
drivers/ata/pata_sil680.c | 2
drivers/ata/pata_sis.c | 2
drivers/ata/pata_sl82c105.c | 2
drivers/ata/pata_triflex.c | 2
drivers/ata/pata_via.c | 2
drivers/ata/sata_nv.c | 2
drivers/ata/sata_sis.c | 2
drivers/ata/sata_via.c | 4 -
include/linux/libata.h | 7 ++
38 files changed, 158 insertions(+), 61 deletions(-)
Index: work/drivers/ata/libata-sff.c
===================================================================
--- work.orig/drivers/ata/libata-sff.c
+++ work/drivers/ata/libata-sff.c
@@ -1974,13 +1974,13 @@ int ata_pci_sff_init_host(struct ata_hos
}
/**
- * ata_pci_sff_prepare_host - helper to prepare native PCI ATA host
+ * ata_pci_sff_prepare_host - helper to prepare PCI PIO-only SFF ATA host
* @pdev: target PCI device
* @ppi: array of port_info, must be enough for two ports
* @r_host: out argument for the initialized ATA host
*
- * Helper to allocate ATA host for @pdev, acquire all native PCI
- * resources and initialize it accordingly in one go.
+ * Helper to allocate PIO-only SFF ATA host for @pdev, acquire
+ * all PCI resources and initialize it accordingly in one go.
*
* LOCKING:
* Inherited from calling layer (may sleep).
@@ -2010,9 +2010,6 @@ int ata_pci_sff_prepare_host(struct pci_
if (rc)
goto err_out;
- /* init DMA related stuff */
- ata_pci_bmdma_init(host);
-
devres_remove_group(&pdev->dev, NULL);
*r_host = host;
return 0;
@@ -2115,8 +2112,21 @@ int ata_pci_sff_activate_host(struct ata
return rc;
}
+static const struct ata_port_info *ata_sff_find_valid_pi(
+ const struct ata_port_info * const *ppi)
+{
+ int i;
+
+ /* look up the first valid port_info */
+ for (i = 0; i < 2 && ppi[i]; i++)
+ if (ppi[i]->port_ops != &ata_dummy_port_ops)
+ return ppi[i];
+
+ return NULL;
+}
+
/**
- * ata_pci_sff_init_one - Initialize/register PCI IDE host controller
+ * ata_pci_sff_init_one - Initialize/register PIO-only PCI IDE controller
* @pdev: Controller to be initialized
* @ppi: array of port_info, must be enough for two ports
* @sht: scsi_host_template to use when registering the host
@@ -2124,11 +2134,7 @@ int ata_pci_sff_activate_host(struct ata
*
* This is a helper function which can be called from a driver's
* xxx_init_one() probe function if the hardware uses traditional
- * IDE taskfile registers.
- *
- * This function calls pci_enable_device(), reserves its register
- * regions, sets the dma mask, enables bus master mode, and calls
- * ata_device_add()
+ * IDE taskfile registers and is PIO only.
*
* ASSUMPTION:
* Nobody makes a single channel controller that appears solely as
@@ -2145,20 +2151,13 @@ int ata_pci_sff_init_one(struct pci_dev
struct scsi_host_template *sht, void *host_priv)
{
struct device *dev = &pdev->dev;
- const struct ata_port_info *pi = NULL;
+ const struct ata_port_info *pi;
struct ata_host *host = NULL;
- int i, rc;
+ int rc;
DPRINTK("ENTER\n");
- /* look up the first valid port_info */
- for (i = 0; i < 2 && ppi[i]; i++) {
- if (ppi[i]->port_ops != &ata_dummy_port_ops) {
- pi = ppi[i];
- break;
- }
- }
-
+ pi = ata_sff_find_valid_pi(ppi);
if (!pi) {
dev_printk(KERN_ERR, &pdev->dev,
"no valid port_info specified\n");
@@ -2178,8 +2177,7 @@ int ata_pci_sff_init_one(struct pci_dev
goto out;
host->private_data = host_priv;
- pci_set_master(pdev);
- rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
+ rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
out:
if (rc == 0)
devres_remove_group(&pdev->dev, NULL);
@@ -2914,6 +2912,93 @@ void ata_pci_bmdma_init(struct ata_host
}
}
+/**
+ * ata_pci_bmdma_prepare_host - helper to prepare PCI BMDMA ATA host
+ * @pdev: target PCI device
+ * @ppi: array of port_info, must be enough for two ports
+ * @r_host: out argument for the initialized ATA host
+ *
+ * Helper to allocate BMDMA ATA host for @pdev, acquire all PCI
+ * resources and initialize it accordingly in one go.
+ *
+ * LOCKING:
+ * Inherited from calling layer (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_pci_bmdma_prepare_host(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ struct ata_host **r_host)
+{
+ int rc;
+
+ rc = ata_pci_sff_prepare_host(pdev, ppi, r_host);
+ if (rc)
+ return rc;
+
+ ata_pci_bmdma_init(*r_host);
+ return 0;
+}
+
+/**
+ * ata_pci_bmdma_init_one - Initialize/register BMDMA PCI IDE controller
+ * @pdev: Controller to be initialized
+ * @ppi: array of port_info, must be enough for two ports
+ * @sht: scsi_host_template to use when registering the host
+ * @host_priv: host private_data
+ *
+ * This function is similar to ata_pci_sff_init_one() but also
+ * takes care of BMDMA initialization.
+ *
+ * LOCKING:
+ * Inherited from PCI layer (may sleep).
+ *
+ * RETURNS:
+ * Zero on success, negative on errno-based value on error.
+ */
+int ata_pci_bmdma_init_one(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ struct scsi_host_template *sht, void *host_priv)
+{
+ struct device *dev = &pdev->dev;
+ const struct ata_port_info *pi;
+ struct ata_host *host = NULL;
+ int rc;
+
+ DPRINTK("ENTER\n");
+
+ pi = ata_sff_find_valid_pi(ppi);
+ if (!pi) {
+ dev_printk(KERN_ERR, &pdev->dev,
+ "no valid port_info specified\n");
+ return -EINVAL;
+ }
+
+ if (!devres_open_group(dev, NULL, GFP_KERNEL))
+ return -ENOMEM;
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ goto out;
+
+ /* prepare and activate BMDMA host */
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
+ if (rc)
+ goto out;
+ host->private_data = host_priv;
+
+ pci_set_master(pdev);
+ rc = ata_pci_sff_activate_host(host, ata_bmdma_interrupt, sht);
+ out:
+ if (rc == 0)
+ devres_remove_group(&pdev->dev, NULL);
+ else
+ devres_release_group(&pdev->dev, NULL);
+
+ return rc;
+}
+
#endif /* CONFIG_PCI */
/**
@@ -3023,4 +3108,6 @@ EXPORT_SYMBOL_GPL(ata_bmdma_port_start);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
+EXPORT_SYMBOL_GPL(ata_pci_bmdma_prepare_host);
+EXPORT_SYMBOL_GPL(ata_pci_bmdma_init_one);
#endif /* CONFIG_PCI */
Index: work/drivers/ata/ata_piix.c
===================================================================
--- work.orig/drivers/ata/ata_piix.c
+++ work/drivers/ata/ata_piix.c
@@ -1435,7 +1435,7 @@ static int __devinit piix_init_one(struc
hpriv->map = piix_init_sata_map(pdev, port_info,
piix_map_db_table[ent->driver_data]);
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
host->private_data = hpriv;
Index: work/drivers/ata/pata_sch.c
===================================================================
--- work.orig/drivers/ata/pata_sch.c
+++ work/drivers/ata/pata_sch.c
@@ -179,7 +179,7 @@ static int __devinit sch_init_one(struct
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &sch_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &sch_sht, NULL);
}
static int __init sch_init(void)
Index: work/drivers/ata/sata_nv.c
===================================================================
--- work.orig/drivers/ata/sata_nv.c
+++ work/drivers/ata/sata_nv.c
@@ -2360,7 +2360,7 @@ static int nv_init_one(struct pci_dev *p
ppi[0] = &nv_port_info[type];
ipriv = ppi[0]->private_data;
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
Index: work/drivers/ata/sata_sis.c
===================================================================
--- work.orig/drivers/ata/sata_sis.c
+++ work/drivers/ata/sata_sis.c
@@ -315,7 +315,7 @@ static int sis_init_one(struct pci_dev *
break;
}
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
Index: work/drivers/ata/sata_via.c
===================================================================
--- work.orig/drivers/ata/sata_via.c
+++ work/drivers/ata/sata_via.c
@@ -445,7 +445,7 @@ static int vt6420_prepare_host(struct pc
struct ata_host *host;
int rc;
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
*r_host = host;
@@ -502,7 +502,7 @@ static int vt8251_prepare_host(struct pc
struct ata_host *host;
int i, rc;
- rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
+ rc = ata_pci_bmdma_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
*r_host = host;
Index: work/drivers/ata/pata_acpi.c
===================================================================
--- work.orig/drivers/ata/pata_acpi.c
+++ work/drivers/ata/pata_acpi.c
@@ -265,7 +265,7 @@ static int pacpi_init_one (struct pci_de
return rc;
pcim_pin_device(pdev);
}
- return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &pacpi_sht, NULL);
}
static const struct pci_device_id pacpi_pci_tbl[] = {
Index: work/drivers/ata/pata_ali.c
===================================================================
--- work.orig/drivers/ata/pata_ali.c
+++ work/drivers/ata/pata_ali.c
@@ -553,7 +553,10 @@ static int ali_init_one(struct pci_dev *
}
pci_dev_put(isa_bridge);
- return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL);
+ if (!ppi[0]->mwdma_mask && !ppi[0]->udma_mask)
+ return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL);
+ else
+ return ata_pci_bmdma_init_one(pdev, ppi, &ali_sht, NULL);
}
#ifdef CONFIG_PM
Index: work/drivers/ata/pata_amd.c
===================================================================
--- work.orig/drivers/ata/pata_amd.c
+++ work/drivers/ata/pata_amd.c
@@ -523,7 +523,7 @@ static int amd_init_one(struct pci_dev *
}
/* And fire it up */
- return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv);
+ return ata_pci_bmdma_init_one(pdev, ppi, &amd_sht, hpriv);
}
#ifdef CONFIG_PM
Index: work/drivers/ata/pata_artop.c
===================================================================
--- work.orig/drivers/ata/pata_artop.c
+++ work/drivers/ata/pata_artop.c
@@ -400,7 +400,7 @@ static int artop_init_one (struct pci_de
BUG_ON(ppi[0] == NULL);
- return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &artop_sht, NULL);
}
static const struct pci_device_id artop_pci_tbl[] = {
Index: work/drivers/ata/pata_atiixp.c
===================================================================
--- work.orig/drivers/ata/pata_atiixp.c
+++ work/drivers/ata/pata_atiixp.c
@@ -243,7 +243,7 @@ static int atiixp_init_one(struct pci_de
.port_ops = &atiixp_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
- return ata_pci_sff_init_one(dev, ppi, &atiixp_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &atiixp_sht, NULL);
}
static const struct pci_device_id atiixp[] = {
Index: work/drivers/ata/pata_cmd64x.c
===================================================================
--- work.orig/drivers/ata/pata_cmd64x.c
+++ work/drivers/ata/pata_cmd64x.c
@@ -373,7 +373,7 @@ static int cmd64x_init_one(struct pci_de
pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
#endif
- return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &cmd64x_sht, NULL);
}
#ifdef CONFIG_PM
Index: work/drivers/ata/pata_cs5530.c
===================================================================
--- work.orig/drivers/ata/pata_cs5530.c
+++ work/drivers/ata/pata_cs5530.c
@@ -325,7 +325,7 @@ static int cs5530_init_one(struct pci_de
ppi[1] = &info_palmax_secondary;
/* Now kick off ATA set up */
- return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &cs5530_sht, NULL);
}
#ifdef CONFIG_PM
Index: work/drivers/ata/pata_cs5535.c
===================================================================
--- work.orig/drivers/ata/pata_cs5535.c
+++ work/drivers/ata/pata_cs5535.c
@@ -199,7 +199,7 @@ static int cs5535_init_one(struct pci_de
rdmsr(ATAC_CH0D1_PIO, timings, dummy);
if (CS5535_BAD_PIO(timings))
wrmsr(ATAC_CH0D1_PIO, 0xF7F4F7F4UL, 0);
- return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &cs5535_sht, NULL);
}
static const struct pci_device_id cs5535[] = {
Index: work/drivers/ata/pata_cs5536.c
===================================================================
--- work.orig/drivers/ata/pata_cs5536.c
+++ work/drivers/ata/pata_cs5536.c
@@ -261,7 +261,7 @@ static int cs5536_init_one(struct pci_de
return -ENODEV;
}
- return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &cs5536_sht, NULL);
}
static const struct pci_device_id cs5536[] = {
Index: work/drivers/ata/pata_cypress.c
===================================================================
--- work.orig/drivers/ata/pata_cypress.c
+++ work/drivers/ata/pata_cypress.c
@@ -136,7 +136,7 @@ static int cy82c693_init_one(struct pci_
if (PCI_FUNC(pdev->devfn) != 1)
return -ENODEV;
- return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &cy82c693_sht, NULL);
}
static const struct pci_device_id cy82c693[] = {
Index: work/drivers/ata/pata_efar.c
===================================================================
--- work.orig/drivers/ata/pata_efar.c
+++ work/drivers/ata/pata_efar.c
@@ -262,7 +262,7 @@ static int efar_init_one (struct pci_dev
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &efar_sht, NULL);
}
static const struct pci_device_id efar_pci_tbl[] = {
Index: work/drivers/ata/pata_hpt366.c
===================================================================
--- work.orig/drivers/ata/pata_hpt366.c
+++ work/drivers/ata/pata_hpt366.c
@@ -393,7 +393,7 @@ static int hpt36x_init_one(struct pci_de
break;
}
/* Now kick off ATA set up */
- return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv);
+ return ata_pci_bmdma_init_one(dev, ppi, &hpt36x_sht, hpriv);
}
#ifdef CONFIG_PM
Index: work/drivers/ata/pata_hpt37x.c
===================================================================
--- work.orig/drivers/ata/pata_hpt37x.c
+++ work/drivers/ata/pata_hpt37x.c
@@ -1019,7 +1019,7 @@ static int hpt37x_init_one(struct pci_de
}
/* Now kick off ATA set up */
- return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data);
+ return ata_pci_bmdma_init_one(dev, ppi, &hpt37x_sht, private_data);
}
static const struct pci_device_id hpt37x[] = {
Index: work/drivers/ata/pata_hpt3x2n.c
===================================================================
--- work.orig/drivers/ata/pata_hpt3x2n.c
+++ work/drivers/ata/pata_hpt3x2n.c
@@ -554,7 +554,7 @@ static int hpt3x2n_init_one(struct pci_d
}
/* Now kick off ATA set up */
- return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv);
+ return ata_pci_bmdma_init_one(dev, ppi, &hpt3x2n_sht, hpriv);
}
static const struct pci_device_id hpt3x2n[] = {
Index: work/drivers/ata/pata_it8213.c
===================================================================
--- work.orig/drivers/ata/pata_it8213.c
+++ work/drivers/ata/pata_it8213.c
@@ -274,7 +274,7 @@ static int it8213_init_one (struct pci_d
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &it8213_sht, NULL);
}
static const struct pci_device_id it8213_pci_tbl[] = {
Index: work/drivers/ata/pata_it821x.c
===================================================================
--- work.orig/drivers/ata/pata_it821x.c
+++ work/drivers/ata/pata_it821x.c
@@ -923,7 +923,7 @@ static int it821x_init_one(struct pci_de
else
ppi[0] = &info_smart;
}
- return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &it821x_sht, NULL);
}
#ifdef CONFIG_PM
Index: work/drivers/ata/pata_jmicron.c
===================================================================
--- work.orig/drivers/ata/pata_jmicron.c
+++ work/drivers/ata/pata_jmicron.c
@@ -144,7 +144,7 @@ static int jmicron_init_one (struct pci_
};
const struct ata_port_info *ppi[] = { &info, NULL };
- return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &jmicron_sht, NULL);
}
static const struct pci_device_id jmicron_pci_tbl[] = {
Index: work/drivers/ata/pata_marvell.c
===================================================================
--- work.orig/drivers/ata/pata_marvell.c
+++ work/drivers/ata/pata_marvell.c
@@ -153,7 +153,7 @@ static int marvell_init_one (struct pci_
return -ENODEV;
}
#endif
- return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &marvell_sht, NULL);
}
static const struct pci_device_id marvell_pci_tbl[] = {
Index: work/drivers/ata/pata_netcell.c
===================================================================
--- work.orig/drivers/ata/pata_netcell.c
+++ work/drivers/ata/pata_netcell.c
@@ -71,7 +71,7 @@ static int netcell_init_one (struct pci_
ata_pci_bmdma_clear_simplex(pdev);
/* And let the library code do the work */
- return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, port_info, &netcell_sht, NULL);
}
static const struct pci_device_id netcell_pci_tbl[] = {
Index: work/drivers/ata/pata_ns87415.c
===================================================================
--- work.orig/drivers/ata/pata_ns87415.c
+++ work/drivers/ata/pata_ns87415.c
@@ -375,7 +375,7 @@ static int ns87415_init_one (struct pci_
pci_write_config_byte(pdev, 0x55, 0xEE);
/* Select PIO0 8bit clocking */
pci_write_config_byte(pdev, 0x54, 0xB7);
- return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &ns87415_sht, NULL);
}
static const struct pci_device_id ns87415_pci_tbl[] = {
Index: work/drivers/ata/pata_oldpiix.c
===================================================================
--- work.orig/drivers/ata/pata_oldpiix.c
+++ work/drivers/ata/pata_oldpiix.c
@@ -249,7 +249,7 @@ static int oldpiix_init_one (struct pci_
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &oldpiix_sht, NULL);
}
static const struct pci_device_id oldpiix_pci_tbl[] = {
Index: work/drivers/ata/pata_optidma.c
===================================================================
--- work.orig/drivers/ata/pata_optidma.c
+++ work/drivers/ata/pata_optidma.c
@@ -430,7 +430,7 @@ static int optidma_init_one(struct pci_d
if (optiplus_with_udma(dev))
ppi[0] = &info_82c700_udma;
- return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &optidma_sht, NULL);
}
static const struct pci_device_id optidma[] = {
Index: work/drivers/ata/pata_pdc202xx_old.c
===================================================================
--- work.orig/drivers/ata/pata_pdc202xx_old.c
+++ work/drivers/ata/pata_pdc202xx_old.c
@@ -324,7 +324,7 @@ static int pdc202xx_init_one(struct pci_
return -ENODEV;
}
}
- return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &pdc202xx_sht, NULL);
}
static const struct pci_device_id pdc202xx[] = {
Index: work/drivers/ata/pata_radisys.c
===================================================================
--- work.orig/drivers/ata/pata_radisys.c
+++ work/drivers/ata/pata_radisys.c
@@ -228,7 +228,7 @@ static int radisys_init_one (struct pci_
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &radisys_sht, NULL);
}
static const struct pci_device_id radisys_pci_tbl[] = {
Index: work/drivers/ata/pata_sc1200.c
===================================================================
--- work.orig/drivers/ata/pata_sc1200.c
+++ work/drivers/ata/pata_sc1200.c
@@ -213,7 +213,7 @@ static int sc1200_init_one(struct pci_de
/* Can't enable port 2 yet, see top comments */
const struct ata_port_info *ppi[] = { &info, &ata_dummy_port_info };
- return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &sc1200_sht, NULL);
}
static const struct pci_device_id sc1200[] = {
Index: work/drivers/ata/pata_serverworks.c
===================================================================
--- work.orig/drivers/ata/pata_serverworks.c
+++ work/drivers/ata/pata_serverworks.c
@@ -461,7 +461,7 @@ static int serverworks_init_one(struct p
if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
ata_pci_bmdma_clear_simplex(pdev);
- return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &serverworks_sht, NULL);
}
#ifdef CONFIG_PM
Index: work/drivers/ata/pata_sil680.c
===================================================================
--- work.orig/drivers/ata/pata_sil680.c
+++ work/drivers/ata/pata_sil680.c
@@ -359,7 +359,7 @@ static int __devinit sil680_init_one(str
IRQF_SHARED, &sil680_sht);
use_ioports:
- return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL);
+ return ata_pci_bmdma_init_one(pdev, ppi, &sil680_sht, NULL);
}
#ifdef CONFIG_PM
Index: work/drivers/ata/pata_sis.c
===================================================================
--- work.orig/drivers/ata/pata_sis.c
+++ work/drivers/ata/pata_sis.c
@@ -822,7 +822,7 @@ static int sis_init_one (struct pci_dev
sis_fixup(pdev, chipset);
- return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset);
+ return ata_pci_bmdma_init_one(pdev, ppi, &sis_sht, chipset);
}
static const struct pci_device_id sis_pci_tbl[] = {
Index: work/drivers/ata/pata_sl82c105.c
===================================================================
--- work.orig/drivers/ata/pata_sl82c105.c
+++ work/drivers/ata/pata_sl82c105.c
@@ -317,7 +317,7 @@ static int sl82c105_init_one(struct pci_
val |= CTRL_P0EN | CTRL_P0F16 | CTRL_P1F16;
pci_write_config_dword(dev, 0x40, val);
- return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &sl82c105_sht, NULL);
}
static const struct pci_device_id sl82c105[] = {
Index: work/drivers/ata/pata_triflex.c
===================================================================
--- work.orig/drivers/ata/pata_triflex.c
+++ work/drivers/ata/pata_triflex.c
@@ -201,7 +201,7 @@ static int triflex_init_one(struct pci_d
if (!printed_version++)
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
- return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL);
+ return ata_pci_bmdma_init_one(dev, ppi, &triflex_sht, NULL);
}
static const struct pci_device_id triflex[] = {
Index: work/drivers/ata/pata_via.c
===================================================================
--- work.orig/drivers/ata/pata_via.c
+++ work/drivers/ata/pata_via.c
@@ -537,7 +537,7 @@ static int via_init_one(struct pci_dev *
}
/* We have established the device type, now fire it up */
- return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config);
+ return ata_pci_bmdma_init_one(pdev, ppi, &via_sht, (void *)config);
}
#ifdef CONFIG_PM
Index: work/include/linux/libata.h
===================================================================
--- work.orig/include/linux/libata.h
+++ work/include/linux/libata.h
@@ -1554,6 +1554,13 @@ extern int ata_bmdma_port_start(struct a
#ifdef CONFIG_PCI
extern int ata_pci_bmdma_clear_simplex(struct pci_dev *pdev);
extern void ata_pci_bmdma_init(struct ata_host *host);
+extern int ata_pci_bmdma_prepare_host(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ struct ata_host **r_host);
+extern int ata_pci_bmdma_init_one(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ struct scsi_host_template *sht,
+ void *host_priv);
#endif /* CONFIG_PCI */
/**
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (23 preceding siblings ...)
2008-10-21 11:36 ` Sergei Shtylyov
@ 2008-10-27 19:43 ` Mark Lord
2008-10-28 1:06 ` Tejun Heo
2008-10-28 4:20 ` Jeff Garzik
` (2 subsequent siblings)
27 siblings, 1 reply; 44+ messages in thread
From: Mark Lord @ 2008-10-27 19:43 UTC (permalink / raw)
To: Tejun Heo; +Cc: jeff, linux-ide, linux-scsi
Tejun Heo wrote:
..
> This patchset further separates SFF/BMDMA support from the rest of the
> libata and separate out BMDMA from SFF. This patchset contains the
> following 22 patches.
..
Heh.. I wonder how this will fit with an upcoming task on my list:
adding ATAPI support to sata_mv..
Currently sata_mv is a more-or-less purely FIS-based driver,
with little need for SFF and no need for BMDMA.
But ATAPI on those chips uses BMDMA, as does target-mode (also on the list).
It'll be interesting.
Cheers
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-10-27 19:43 ` Mark Lord
@ 2008-10-28 1:06 ` Tejun Heo
0 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-28 1:06 UTC (permalink / raw)
To: Mark Lord; +Cc: jeff, linux-ide, linux-scsi
Mark Lord wrote:
> Tejun Heo wrote:
> ..
>> This patchset further separates SFF/BMDMA support from the rest of the
>> libata and separate out BMDMA from SFF. This patchset contains the
>> following 22 patches.
> ..
>
> Heh.. I wonder how this will fit with an upcoming task on my list:
> adding ATAPI support to sata_mv..
>
> Currently sata_mv is a more-or-less purely FIS-based driver,
> with little need for SFF and no need for BMDMA.
>
> But ATAPI on those chips uses BMDMA, as does target-mode (also on the
> list).
> It'll be interesting.
Nah... just move it to 'dependent on BMDMA' and inherit from
ata_bmdma_port_ops. There are other drivers which do the same thing.
--
tejun
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
2008-10-21 9:17 ` [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary Tejun Heo
2008-10-21 9:53 ` Sergei Shtylyov
@ 2008-10-28 4:10 ` Jeff Garzik
2008-10-28 4:28 ` Tejun Heo
1 sibling, 1 reply; 44+ messages in thread
From: Jeff Garzik @ 2008-10-28 4:10 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, linux-scsi
Tejun Heo wrote:
> Clearing IRQ from ata_sff_error_handler() is necessary only when the
> port is gonna be thawed before performing EH actions and some
> controllers don't like being accessed after certain fail modes until
> they're reset. Clear IRQ iff the port is being thawed. Also, remove
> unnecessary ata_sff_sync() while at it.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> ---
> drivers/ata/libata-sff.c | 10 ++++++----
> 1 files changed, 6 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
> index 4b47394..b9fb068 100644
> --- a/drivers/ata/libata-sff.c
> +++ b/drivers/ata/libata-sff.c
> @@ -2119,11 +2119,13 @@ void ata_sff_error_handler(struct ata_port *ap)
> }
>
> ap->ops->bmdma_stop(qc);
> - }
>
> - ata_sff_sync(ap); /* FIXME: We don't need this */
> - ap->ops->sff_check_status(ap);
> - ap->ops->sff_irq_clear(ap);
> + /* if we're gonna thaw, make sure IRQ is clear */
> + if (thaw) {
> + ap->ops->sff_check_status(ap);
> + ap->ops->sff_irq_clear(ap);
> + }
> + }
I'll allow it, but, this description is not strictly true. This
clearing was done in the error handler unconditionally in an attempt to
catch outstanding conditions. The logic being that it is safer (FSVO
safe) to clear on error just in case interrupts were screaming.
Jeff
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 10/22] libata-sff: clean up BMDMA initialization
2008-10-21 9:17 ` [PATCH 10/22] libata-sff: clean up BMDMA initialization Tejun Heo
@ 2008-10-28 4:16 ` Jeff Garzik
0 siblings, 0 replies; 44+ messages in thread
From: Jeff Garzik @ 2008-10-28 4:16 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, linux-scsi
Tejun Heo wrote:
> This patch improves BMDMA initialization such that
>
> * When BMDMA register initialization fails, falls back to PIO instead
> of failing. ata_pci_bmdma_init() never fails now.
>
> * When ata_pci_bmdma_init() falls back to PIO, it clears
> ap->mwdma_mask and udma_mask instead of depending on
> ata_bmdma_mode_filter(). This makes ata_bmdma_mode_filter()
> unnecessary and p1 is removed.
>
> * ata_port_start() which actually is BMDMA specific is moved to
> ata_bmdma_port_start(). ata_port_start() and ata_sff_port_start()
> are killed.
>
> Drivers which no longer calls into PRD table allocation are...
>
> pdc_adma, sata_inic162x, sata_qstor, sata_sx4, pata_cmd640 and all
> drivers which inherit from ata_sff_port_ops.
>
> pata_icside sets ->port_start to ATA_OP_NULL as it doesn't need PRD
> but is a BMDMA controller and doesn't have custom port_start like
> other such controllers.
Nice!
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (24 preceding siblings ...)
2008-10-27 19:43 ` Mark Lord
@ 2008-10-28 4:20 ` Jeff Garzik
2008-11-03 14:26 ` Tejun Heo
2008-10-28 4:31 ` [PATCH 04/22 DESC UPDATED] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary Tejun Heo
2010-05-07 13:59 ` [PATCHSET #upstream] libata: separate out SFF and BMDMA Sergei Shtylyov
27 siblings, 1 reply; 44+ messages in thread
From: Jeff Garzik @ 2008-10-28 4:20 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, linux-scsi
Tejun Heo wrote:
> Hello,
>
> This is the first take of separate-out-SFF-and-BMDMA patchset.
>
> Historically, ATA meant SFF (or TASKFILE interface) plus BMDMA and
> that holds true for many modern SATA controllers. This was reflected
> in libata implementation and libata core layer and SFF/BMDMA support
> used to be all tangled in one piece.
>
> For SFF/BMDMA drivers, this assumption is fine but for drivers which
> have native interfaces (e.g. ahci, sata_sil24), this meant that those
> drivers had to emulate SFF/BMDMA to ceratin not-so-well defined level
> libata core layer expects. A lot of this vague dependency on
> SFF/BMDMA was removed during recent SFF/BMDMA separation but there
> still are SFF/BMDMA specific assumptions in libata core layer.
>
> Another issue which surpassed with the addition of all the legacy,
> platform and somewhat peculiar PATA drivers is that now there are
> enough drivers which use SFF interface but use its own DMA interface
> or don't support DMA at all. This, in similar fashion, led those
> drivers to fake certain level of BMDMA functionality to please the
> libata SFF/BMDMA layer. This led to the following interesting
> solutions in low level drivers.
>
> 1. For BMDMA drivers which don't use traditional BMDMA register,
> ata_bmdma_mode_filter() incorrectly inhibits DMA modes. Those
> drivers either have to inherit from ata_sff_port_ops or clear
> ->mode_filter explicitly.
>
> 2. non-BMDMA drivers call into BMDMA PRD table allocation. It doesn't
> actually allocate PRD table if bmdma_addr is not initialized but is
> still confusing.
>
> 3. For BMDMA drivers which don't use traditional BMDMA register, some
> methods might not be invoked as expected (e.g. bmdma_stop from
> ata_sff_post_internal_cmd()).
>
> 4. SFF drivers w/ custom DMA interface implement noop BMDMA ops
> worrying libata core might call into one of them.
>
> This patchset further separates SFF/BMDMA support from the rest of the
> libata and separate out BMDMA from SFF. This patchset contains the
> following 22 patches.
>
> 0001-pata_sch-use-ata_pci_sff_init_one.patch
> 0002-sata_inic162x-inic162x-is-not-dependent-on-CONFIG_A.patch
> 0003-sata_mv-remove-unnecessary-initialization.patch
> 0004-libata-sff-clear-IRQ-from-ata_sff_error_handler-o.patch
> 0005-libata-sff-kill-unused-prototype-and-make-ata_dev_s.patch
> 0006-libata-kill-ATA_FLAG_DISABLED.patch
> 0007-sata_inic162x-kill-PORT_PRD_ADDR-initialization.patch
> 0008-libata-sff-reorder-SFF-BMDMA-functions.patch
> 0009-pata_cmd640-bf54x-icside-fix-inheritance.patch
> 0010-libata-sff-clean-up-BMDMA-initialization.patch
> 0011-libata-sff-introduce-ata_sff_init-exit-and-ata_sf.patch
> 0012-libata-sff-ap-last_-ctl-are-SFF-specific.patch
> 0013-libata-sff-port_task-is-SFF-specific.patch
> 0014-libata-sff-separate-out-BMDMA-EHs.patch
> 0015-libata-sff-ata_sff_-dumb_-qc_prep-are-BMDMA-specifi.patch
> 0016-libata-sff-prd-is-BMDMA-specific.patch
> 0017-libata-sff-separate-out-BMDMA-qc_issue.patch
> 0018-libata-sff-ata_sff_irq_clear-is-BMDMA-specific.patch
> 0019-libata-sff-separate-out-BMDMA-irq-handler.patch
> 0020-libata-sff-separate-out-BMDMA-init.patch
> 0021-sata_qstor-kill-dummy-BMDMA-ops.patch
> 0022-libata-sff-make-BMDMA-optional.patch
>
> 0001-0010 make things aligned for the future changes.
>
> 0004 changes the default SFF error handler behavior such that
> unnecessary register accesses are removed. I'm fairly sure this
> change is safe (tested on various SFF/BMDMA controllers) but we'll
> need to look out for problem reports.
>
> 0006 kills ATA_FLAG_DISABLED (finally). This patch touches SCSI SAS
> drivers.
>
> 0010 cleans up BMDMA initialization and bmdma_addr condition checks.
>
> 0011-0013 further separate out SFF assumptions from libata core layer.
>
> 0014-0021 separate out BMDMA from SFF.
>
> 0022 makes BMDMA optional and reorganizes Kconfig options according to
> the groups of drivers they belong to.
>
> This patchset is on top of
>
> linus#master (2515ddc6db8eb49a79f0fe5e67ff09ac7c81eab4)
> + [1] libata-sff-fix-ata_sff_post_internal_cmd
> + [2] libata-initialize-port_task-when-!CONFIG_ATA_SFF
> + [3] libata-eh-fix-slave-link-EH-action-mask-handling
> + [4] libata-transfer-EHI-control-flags-to-slave-ehc_i
>
> and makes the followings changes.
>
> drivers/ata/Kconfig | 360 +++----
> drivers/ata/Makefile | 47
> drivers/ata/ata_piix.c | 4
> drivers/ata/libata-core.c | 172 ---
> drivers/ata/libata-eh.c | 11
> drivers/ata/libata-scsi.c | 3
> drivers/ata/libata-sff.c | 1757 ++++++++++++++++++++----------------
> drivers/ata/libata.h | 37
> drivers/ata/pata_acpi.c | 10
> drivers/ata/pata_ali.c | 7
> drivers/ata/pata_amd.c | 2
> drivers/ata/pata_artop.c | 2
> drivers/ata/pata_atiixp.c | 4
> drivers/ata/pata_bf54x.c | 20
> drivers/ata/pata_cmd640.c | 10
> drivers/ata/pata_cmd64x.c | 2
> drivers/ata/pata_cs5520.c | 4
> drivers/ata/pata_cs5530.c | 6
> drivers/ata/pata_cs5535.c | 2
> drivers/ata/pata_cs5536.c | 2
> drivers/ata/pata_cypress.c | 2
> drivers/ata/pata_efar.c | 2
> drivers/ata/pata_hpt366.c | 4
> drivers/ata/pata_hpt37x.c | 6
> drivers/ata/pata_hpt3x2n.c | 4
> drivers/ata/pata_hpt3x3.c | 2
> drivers/ata/pata_icside.c | 7
> drivers/ata/pata_it8213.c | 2
> drivers/ata/pata_it821x.c | 8
> drivers/ata/pata_jmicron.c | 2
> drivers/ata/pata_marvell.c | 2
> drivers/ata/pata_mpc52xx.c | 1
> drivers/ata/pata_netcell.c | 2
> drivers/ata/pata_ninja32.c | 2
> drivers/ata/pata_ns87415.c | 4
> drivers/ata/pata_oldpiix.c | 4
> drivers/ata/pata_optidma.c | 2
> drivers/ata/pata_pdc2027x.c | 6
> drivers/ata/pata_pdc202xx_old.c | 4
> drivers/ata/pata_platform.c | 1
> drivers/ata/pata_radisys.c | 4
> drivers/ata/pata_sc1200.c | 6
> drivers/ata/pata_scc.c | 15
> drivers/ata/pata_sch.c | 12
> drivers/ata/pata_serverworks.c | 8
> drivers/ata/pata_sil680.c | 4
> drivers/ata/pata_sis.c | 2
> drivers/ata/pata_sl82c105.c | 2
> drivers/ata/pata_triflex.c | 2
> drivers/ata/pata_via.c | 2
> drivers/ata/pdc_adma.c | 74 -
> drivers/ata/sata_inic162x.c | 25
> drivers/ata/sata_mv.c | 15
> drivers/ata/sata_nv.c | 264 ++---
> drivers/ata/sata_promise.c | 30
> drivers/ata/sata_qstor.c | 102 --
> drivers/ata/sata_sil.c | 7
> drivers/ata/sata_sil24.c | 9
> drivers/ata/sata_sis.c | 4
> drivers/ata/sata_svw.c | 4
> drivers/ata/sata_sx4.c | 9
> drivers/ata/sata_uli.c | 6
> drivers/ata/sata_via.c | 6
> drivers/ata/sata_vsc.c | 12
> drivers/scsi/ipr.c | 7
> drivers/scsi/libsas/sas_scsi_host.c | 2
> include/linux/ata.h | 2
> include/linux/libata.h | 91 +
> 68 files changed, 1653 insertions(+), 1602 deletions(-)
ACK patchset
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
2008-10-28 4:10 ` [PATCH 04/22] " Jeff Garzik
@ 2008-10-28 4:28 ` Tejun Heo
0 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-28 4:28 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-ide, linux-scsi
Jeff Garzik wrote:
> Tejun Heo wrote:
>> Clearing IRQ from ata_sff_error_handler() is necessary only when the
>> port is gonna be thawed before performing EH actions and some
>> controllers don't like being accessed after certain fail modes until
>> they're reset. Clear IRQ iff the port is being thawed. Also, remove
>> unnecessary ata_sff_sync() while at it.
>>
>> Signed-off-by: Tejun Heo <tj@kernel.org>
>
> I'll allow it, but, this description is not strictly true. This
> clearing was done in the error handler unconditionally in an attempt to
> catch outstanding conditions. The logic being that it is safer (FSVO
> safe) to clear on error just in case interrupts were screaming.
The avoid-IRQ-stream-by-clearing-IRQ doesn't work at all.
1. If the port is already frozen && IRQ is screaming && EH is not gonna
thaw until reset is complete, it doesn't matter.
2. If IRQ is screaming && the port is not frozen or freezing doesn't
work, the IRQ will get killed way before it reaches EH.
So, clearing IRQ there doesn't make any difference w.r.t. screaming IRQ,
about which we really need to do something. It's one of the most common
bug reports I get these days.
But, yeah, it's probably better to include the above in the commit
message. I'll update the patch.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 44+ messages in thread
* [PATCH 04/22 DESC UPDATED] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (25 preceding siblings ...)
2008-10-28 4:20 ` Jeff Garzik
@ 2008-10-28 4:31 ` Tejun Heo
2010-05-07 13:59 ` [PATCHSET #upstream] libata: separate out SFF and BMDMA Sergei Shtylyov
27 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-10-28 4:31 UTC (permalink / raw)
To: jeff, linux-ide, linux-scsi; +Cc: Tejun Heo
Clearing IRQ from ata_sff_error_handler() is necessary only when the
port is gonna be thawed before performing EH actions and some
controllers don't like being accessed after certain fail modes until
they're reset. Clear IRQ iff the port is being thawed. Also, remove
unnecessary ata_sff_sync() while at it.
Note that the original reason why IRQ was cleared unconditonally was
to help screaming IRQ cases; however, it didn't make any difference as
to screaming IRQs because...
1. If the port is already frozen && IRQ is screaming && EH is not
gonna thaw until reset is complete, it doesn't matter.
2. If IRQ is screaming && the port is not frozen or freezing doesn't
work, the IRQ will get killed way before it reaches EH.
Signed-off-by: Tejun Heo <tj@kernel.org>
---
drivers/ata/libata-sff.c | 10 ++++++----
1 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 4b47394..b9fb068 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -2119,11 +2119,13 @@ void ata_sff_error_handler(struct ata_port *ap)
}
ap->ops->bmdma_stop(qc);
- }
- ata_sff_sync(ap); /* FIXME: We don't need this */
- ap->ops->sff_check_status(ap);
- ap->ops->sff_irq_clear(ap);
+ /* if we're gonna thaw, make sure IRQ is clear */
+ if (thaw) {
+ ap->ops->sff_check_status(ap);
+ ap->ops->sff_irq_clear(ap);
+ }
+ }
spin_unlock_irqrestore(ap->lock, flags);
--
1.5.4.5
^ permalink raw reply related [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-10-28 4:20 ` Jeff Garzik
@ 2008-11-03 14:26 ` Tejun Heo
2008-11-04 5:35 ` Jeff Garzik
0 siblings, 1 reply; 44+ messages in thread
From: Tejun Heo @ 2008-11-03 14:26 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-ide, linux-scsi
Jeff Garzik wrote:
> ACK patchset
Jeff, are you gonna create #upstream soon? I have other patches
targeted for #upstream and having a branch open and having patch orders
fixed there would help a lot.
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-11-03 14:26 ` Tejun Heo
@ 2008-11-04 5:35 ` Jeff Garzik
2008-11-04 5:38 ` Tejun Heo
0 siblings, 1 reply; 44+ messages in thread
From: Jeff Garzik @ 2008-11-04 5:35 UTC (permalink / raw)
To: Tejun Heo; +Cc: linux-ide, linux-scsi
Tejun Heo wrote:
> Jeff Garzik wrote:
>> ACK patchset
>
> Jeff, are you gonna create #upstream soon? I have other patches
> targeted for #upstream and having a branch open and having patch orders
> fixed there would help a lot.
Yep, I was waiting on the patchset in $subject to be resent, because
otherwise there was no content for #upstream.
#tj-upstream sounded like it contained some work for 2.6.28 and some for
later kernels, so I didn't want to pull it verbatim.
Jeff
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-11-04 5:35 ` Jeff Garzik
@ 2008-11-04 5:38 ` Tejun Heo
0 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2008-11-04 5:38 UTC (permalink / raw)
To: Jeff Garzik; +Cc: linux-ide, linux-scsi
Jeff Garzik wrote:
> Tejun Heo wrote:
>> Jeff Garzik wrote:
>>> ACK patchset
>>
>> Jeff, are you gonna create #upstream soon? I have other patches
>> targeted for #upstream and having a branch open and having patch orders
>> fixed there would help a lot.
>
> Yep, I was waiting on the patchset in $subject to be resent, because
> otherwise there was no content for #upstream.
>
> #tj-upstream sounded like it contained some work for 2.6.28 and some for
> later kernels, so I didn't want to pull it verbatim.
Ah... it was #tj-upstream before -rc1 opened and just contained fixes
and stuff you already acked. I probably should have renamed it to
#tj-upstream-fixes. Are you gonna push in the lost patches into 2.6.28?
Thanks.
--
tejun
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCH 05/22] libata-sff: kill unused prototype and make ata_dev_select() static
2008-10-21 9:17 ` [PATCH 05/22] libata-sff: kill unused prototype and make ata_dev_select() static Tejun Heo
@ 2010-05-07 13:47 ` Sergei Shtylyov
0 siblings, 0 replies; 44+ messages in thread
From: Sergei Shtylyov @ 2010-05-07 13:47 UTC (permalink / raw)
To: jeff; +Cc: Tejun Heo, linux-ide, linux-scsi
Hello.
Tejun Heo wrote:
> ata_irq_on() was renamed to ata_sff_irq_on() and exported a while ago
> but prototype for the original function lingered in
> drivers/ata/libata.h. Kill it. Also, ata_dev_select() is only used
> inside drivers/ata/libata-sff.c. Make it static.
>
> Signed-off-by: Tejun Heo <tj@kernel.org>
> ---
> drivers/ata/libata-sff.c | 2 +-
> drivers/ata/libata.h | 3 ---
> 2 files changed, 1 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
> index b9fb068..edcd72c 100644
> --- a/drivers/ata/libata-sff.c
> +++ b/drivers/ata/libata-sff.c
> @@ -468,7 +468,7 @@ void ata_sff_dev_select(struct ata_port *ap, unsigned int device)
> * LOCKING:
> * caller.
> */
> -void ata_dev_select(struct ata_port *ap, unsigned int device,
> +static void ata_dev_select(struct ata_port *ap, unsigned int device,
> unsigned int wait, unsigned int can_sleep)
> {
> if (ata_msg_probe(ap))
> diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
> index fe2839e..1f626b5 100644
> --- a/drivers/ata/libata.h
> +++ b/drivers/ata/libata.h
> @@ -201,9 +201,6 @@ static inline int sata_pmp_attach(struct ata_device *dev)
>
> /* libata-sff.c */
> #ifdef CONFIG_ATA_SFF
> -extern void ata_dev_select(struct ata_port *ap, unsigned int device,
> - unsigned int wait, unsigned int can_sleep);
> -extern u8 ata_irq_on(struct ata_port *ap);
> extern void ata_pio_task(struct work_struct *work);
> #endif /* CONFIG_ATA_SFF */
>
Hey, why this Tejun's patch ended up ignored? I've just submitted the
patch killing that orphan proto and am pondering what to do with
ata_dev_select() and now it turns out that Tejun has taken care of both
back in 2008... :-/
WBR, Sergei
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
` (26 preceding siblings ...)
2008-10-28 4:31 ` [PATCH 04/22 DESC UPDATED] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary Tejun Heo
@ 2010-05-07 13:59 ` Sergei Shtylyov
2010-05-08 15:33 ` Tejun Heo
27 siblings, 1 reply; 44+ messages in thread
From: Sergei Shtylyov @ 2010-05-07 13:59 UTC (permalink / raw)
To: Tejun Heo; +Cc: jeff, linux-ide, linux-scsi
Hello.
Tejun Heo wrote:
> This is the first take of separate-out-SFF-and-BMDMA patchset.
>
> Historically, ATA meant SFF (or TASKFILE interface) plus BMDMA and
> that holds true for many modern SATA controllers. This was reflected
> in libata implementation and libata core layer and SFF/BMDMA support
> used to be all tangled in one piece.
>
> For SFF/BMDMA drivers, this assumption is fine but for drivers which
> have native interfaces (e.g. ahci, sata_sil24), this meant that those
> drivers had to emulate SFF/BMDMA to ceratin not-so-well defined level
> libata core layer expects. A lot of this vague dependency on
> SFF/BMDMA was removed during recent SFF/BMDMA separation but there
> still are SFF/BMDMA specific assumptions in libata core layer.
>
> Another issue which surpassed with the addition of all the legacy,
> platform and somewhat peculiar PATA drivers is that now there are
> enough drivers which use SFF interface but use its own DMA interface
> or don't support DMA at all. This, in similar fashion, led those
> drivers to fake certain level of BMDMA functionality to please the
> libata SFF/BMDMA layer. This led to the following interesting
> solutions in low level drivers.
>
> 1. For BMDMA drivers which don't use traditional BMDMA register,
> ata_bmdma_mode_filter() incorrectly inhibits DMA modes. Those
> drivers either have to inherit from ata_sff_port_ops or clear
> ->mode_filter explicitly.
>
> 2. non-BMDMA drivers call into BMDMA PRD table allocation. It doesn't
> actually allocate PRD table if bmdma_addr is not initialized but is
> still confusing.
>
> 3. For BMDMA drivers which don't use traditional BMDMA register, some
> methods might not be invoked as expected (e.g. bmdma_stop from
> ata_sff_post_internal_cmd()).
>
> 4. SFF drivers w/ custom DMA interface implement noop BMDMA ops
> worrying libata core might call into one of them.
>
> This patchset further separates SFF/BMDMA support from the rest of the
> libata and separate out BMDMA from SFF. This patchset contains the
> following 22 patches.
>
> 0001-pata_sch-use-ata_pci_sff_init_one.patch
> 0002-sata_inic162x-inic162x-is-not-dependent-on-CONFIG_A.patch
> 0003-sata_mv-remove-unnecessary-initialization.patch
> 0004-libata-sff-clear-IRQ-from-ata_sff_error_handler-o.patch
> 0005-libata-sff-kill-unused-prototype-and-make-ata_dev_s.patch
> 0006-libata-kill-ATA_FLAG_DISABLED.patch
> 0007-sata_inic162x-kill-PORT_PRD_ADDR-initialization.patch
> 0008-libata-sff-reorder-SFF-BMDMA-functions.patch
> 0009-pata_cmd640-bf54x-icside-fix-inheritance.patch
> 0010-libata-sff-clean-up-BMDMA-initialization.patch
> 0011-libata-sff-introduce-ata_sff_init-exit-and-ata_sf.patch
> 0012-libata-sff-ap-last_-ctl-are-SFF-specific.patch
> 0013-libata-sff-port_task-is-SFF-specific.patch
> 0014-libata-sff-separate-out-BMDMA-EHs.patch
> 0015-libata-sff-ata_sff_-dumb_-qc_prep-are-BMDMA-specifi.patch
> 0016-libata-sff-prd-is-BMDMA-specific.patch
> 0017-libata-sff-separate-out-BMDMA-qc_issue.patch
> 0018-libata-sff-ata_sff_irq_clear-is-BMDMA-specific.patch
> 0019-libata-sff-separate-out-BMDMA-irq-handler.patch
> 0020-libata-sff-separate-out-BMDMA-init.patch
> 0021-sata_qstor-kill-dummy-BMDMA-ops.patch
> 0022-libata-sff-make-BMDMA-optional.patch
>
> 0001-0010 make things aligned for the future changes.
>
> 0004 changes the default SFF error handler behavior such that
> unnecessary register accesses are removed. I'm fairly sure this
> change is safe (tested on various SFF/BMDMA controllers) but we'll
> need to look out for problem reports.
>
> 0006 kills ATA_FLAG_DISABLED (finally). This patch touches SCSI SAS
> drivers.
>
> 0010 cleans up BMDMA initialization and bmdma_addr condition checks.
>
> 0011-0013 further separate out SFF assumptions from libata core layer.
>
> 0014-0021 separate out BMDMA from SFF.
>
> 0022 makes BMDMA optional and reorganizes Kconfig options according to
> the groups of drivers they belong to.
>
> This patchset is on top of
>
> linus#master (2515ddc6db8eb49a79f0fe5e67ff09ac7c81eab4)
> + [1] libata-sff-fix-ata_sff_post_internal_cmd
> + [2] libata-initialize-port_task-when-!CONFIG_ATA_SFF
> + [3] libata-eh-fix-slave-link-EH-action-mask-handling
> + [4] libata-transfer-EHI-control-flags-to-slave-ehc_i
>
> and makes the followings changes.
Tejun, what was the fate of this patchset? Looks like it ended up
ignored...
MBR, Sergei
^ permalink raw reply [flat|nested] 44+ messages in thread
* Re: [PATCHSET #upstream] libata: separate out SFF and BMDMA
2010-05-07 13:59 ` [PATCHSET #upstream] libata: separate out SFF and BMDMA Sergei Shtylyov
@ 2010-05-08 15:33 ` Tejun Heo
0 siblings, 0 replies; 44+ messages in thread
From: Tejun Heo @ 2010-05-08 15:33 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: jeff, linux-ide, linux-scsi
On 05/07/2010 03:59 PM, Sergei Shtylyov wrote:
> Tejun, what was the fate of this patchset? Looks like it ended up
> ignored...
Hmm... I frankly don't remember anything about it. 2008 is way beyond
the scope of my feeble memory. :-)
It looks like both Jeff and I dropped the ball there. I'll find out
whether any patch can be salvaged and resubmit.
Thanks for digging it up.
--
tejun
^ permalink raw reply [flat|nested] 44+ messages in thread
end of thread, other threads:[~2010-05-08 15:33 UTC | newest]
Thread overview: 44+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-10-21 9:17 [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
2008-10-21 9:17 ` [PATCH 01/22] pata_sch: use ata_pci_sff_init_one() Tejun Heo
2008-10-21 9:17 ` [PATCH 02/22] sata_inic162x: inic162x is not dependent on CONFIG_ATA_SFF Tejun Heo
2008-10-21 9:17 ` [PATCH 03/22] sata_mv: remove unnecessary initialization Tejun Heo
2008-10-21 9:17 ` [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary Tejun Heo
2008-10-21 9:53 ` Sergei Shtylyov
2008-10-21 11:45 ` [PATCH 04/22, UPDATED] " Tejun Heo
2008-10-28 4:10 ` [PATCH 04/22] " Jeff Garzik
2008-10-28 4:28 ` Tejun Heo
2008-10-21 9:17 ` [PATCH 05/22] libata-sff: kill unused prototype and make ata_dev_select() static Tejun Heo
2010-05-07 13:47 ` Sergei Shtylyov
2008-10-21 9:17 ` [PATCH 06/22] libata: kill ATA_FLAG_DISABLED Tejun Heo
2008-10-21 9:17 ` [PATCH 07/22] sata_inic162x: kill PORT_PRD_ADDR initialization Tejun Heo
2008-10-21 9:17 ` [PATCH 08/22] libata-sff: reorder SFF/BMDMA functions Tejun Heo
2008-10-21 9:17 ` [PATCH 09/22] pata_cmd640/bf54x/icside: fix inheritance Tejun Heo
2008-10-21 9:17 ` [PATCH 10/22] libata-sff: clean up BMDMA initialization Tejun Heo
2008-10-28 4:16 ` Jeff Garzik
2008-10-21 9:17 ` [PATCH 11/22] libata-sff: introduce ata_sff_init/exit() and ata_sff_port_init() Tejun Heo
2008-10-21 9:17 ` [PATCH 12/22] libata-sff: ap->[last_]ctl are SFF specific Tejun Heo
2008-10-21 9:17 ` [PATCH 13/22] libata-sff: port_task is " Tejun Heo
2008-10-21 9:17 ` [PATCH 14/22] libata-sff: separate out BMDMA EHs Tejun Heo
2008-10-21 9:17 ` [PATCH 15/22] libata-sff: ata_sff_[dumb_]qc_prep are BMDMA specific Tejun Heo
2008-10-21 9:17 ` [PATCH 16/22] libata-sff: prd is " Tejun Heo
2008-10-21 9:17 ` [PATCH 17/22] libata-sff: separate out BMDMA qc_issue Tejun Heo
2008-10-21 9:17 ` [PATCH 18/22] libata-sff: ata_sff_irq_clear() is BMDMA specific Tejun Heo
2008-10-21 9:17 ` [PATCH 19/22] libata-sff: separate out BMDMA irq handler Tejun Heo
2008-10-21 9:17 ` [PATCH 20/22] libata-sff: separate out BMDMA init Tejun Heo
2008-10-21 15:49 ` [PATCH 20/22 UPDATED] " Tejun Heo
2008-10-21 9:17 ` [PATCH 21/22] sata_qstor: kill dummy BMDMA ops Tejun Heo
2008-10-21 10:10 ` Sergei Shtylyov
2008-10-21 11:27 ` Tejun Heo
2008-10-21 9:18 ` [PATCH 22/22] libata-sff: make BMDMA optional Tejun Heo
2008-10-21 9:26 ` [PATCHSET #upstream] libata: separate out SFF and BMDMA Tejun Heo
2008-10-21 11:36 ` Sergei Shtylyov
2008-10-21 11:43 ` Tejun Heo
2008-10-27 19:43 ` Mark Lord
2008-10-28 1:06 ` Tejun Heo
2008-10-28 4:20 ` Jeff Garzik
2008-11-03 14:26 ` Tejun Heo
2008-11-04 5:35 ` Jeff Garzik
2008-11-04 5:38 ` Tejun Heo
2008-10-28 4:31 ` [PATCH 04/22 DESC UPDATED] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary Tejun Heo
2010-05-07 13:59 ` [PATCHSET #upstream] libata: separate out SFF and BMDMA Sergei Shtylyov
2010-05-08 15:33 ` Tejun Heo
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).