libata: separate out SFF and BMDMA
Subsystems (5)
PATCH 1/1 libata: separate out SFF and BMDMA
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
PATCH 1/22 pata_sch: use ata_pci_sff_init_one()
pata_sch is standard SFF. No reason to open code init. Use ata_pci_sff_init_one() instead.
--- drivers/ata/pata_sch.c | 12 +----------- 1 files changed, 1 insertions(+), 11 deletions(-)
drivers/ata/pata_sch.c +1 -11
@@ -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 )
Signature · 1 line
1.5.4.5
PATCH 2/22 sata_inic162x: inic162x is not dependent on CONFIG_ATA_SFF
In reply to Tejun Heosata_inic162x no longer uses SFF interface. Move it out of CONFIG_ATA_SFF.
--- drivers/ata/Kconfig | 12 ++++++------ 1 files changed, 6 insertions(+), 6 deletions(-)
drivers/ata/Kconfig +6 -6
@@ -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
Signature · 1 line
1.5.4.5
PATCH 3/22 sata_mv: remove unnecessary initialization
In reply to Tejun Heosata_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.
--- drivers/ata/sata_mv.c | 3 --- 1 files changed, 0 insertions(+), 3 deletions(-)
drivers/ata/sata_mv.c +0 -3
@@ -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);
Signature · 1 line
1.5.4.5
PATCH 4/22 libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
In reply to Tejun HeoClearing 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.
--- drivers/ata/libata-sff.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
drivers/ata/libata-sff.c +6 -4
@@ -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);
Signature · 1 line
1.5.4.5
Re: [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
Hello.
Quoted 8 lines · 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 unnecessaryata_sff_sync()while at it.Signed-off-by Tejun Heo <[email protected]>
Sorry for the grammar nipicking but...
Quoted 5 lines
drivers/ata/libata-sff.c +0
-0
drivers/ata/libata-sff.c void ata_sff_error_handler(struct ata_port *ap) · line 2124
Quoted 10 lines
drivers/ata/libata-sff.c +1
-4@@ -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
PATCH 4/22 libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
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.
---
s/clear/cleared/. git tree is updated too. Thanks.
drivers/ata/libata-sff.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/ata/libata-sff.c +6 -4
@@ -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);
Re: [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
In reply to Tejun HeoQuoted 20 lines · 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 unnecessaryata_sff_sync()while at it.Signed-off-by Tejun Heo <[email protected]>--- drivers/ata/libata-sff.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)drivers/ata/libata-sff.c +0
-1@@ -2119,11 +2119,13 @@ void ata_sff_error_handler(struct ata_port *ap) } ap->ops->bmdma_stop (qc); - }
drivers/ata/libata-sff.c void ata_sff_error_handler(struct ata_port *ap) · line 2128
Quoted 10 lines
drivers/ata/libata-sff.c +6
-3-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
Re: [PATCH 04/22] libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
Quoted 7 lines · Jeff Garzik
Quoted 6 lines · 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 unnecessaryata_sff_sync()while at it.
Quoted 6 lines
Quoted 1 line
Signed-off-by Tejun Heo <[email protected]>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.
Signature · 1 line
tejun
PATCH 4/22 libata-sff: clear IRQ from ata_sff_error_handler() only when necessary
In reply to Tejun HeoClearing 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.
--- drivers/ata/libata-sff.c | 10 ++++++---- 1 files changed, 6 insertions(+), 4 deletions(-)
drivers/ata/libata-sff.c +6 -4
@@ -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);
Signature · 1 line
1.5.4.5
PATCH 5/22 libata-sff: kill unused prototype and make ata_dev_select() static
In reply to Tejun Heoata_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.
--- drivers/ata/libata-sff.c | 2 +- drivers/ata/libata.h | 3 --- 2 files changed, 1 insertions(+), 4 deletions(-)
drivers/ata/libata-sff.c +1 -1
@@ -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))
drivers/ata/libata.h +0 -3
@@ -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 */
Signature · 1 line
1.5.4.5
Re: [PATCH 05/22] libata-sff: kill unused prototype and make ata_dev_select() static
Hello.
Quoted 29 lines · Tejun Heo
ata_irq_on()was renamed toata_sff_irq_on()and exported a while ago but prototype for the original function lingered indrivers/ata/libata.h. Kill it. Also,ata_dev_select()is only used insidedrivers/ata/libata-sff.c. Make it static.Signed-off-by Tejun Heo <[email protected]>--- drivers/ata/libata-sff.c | 2 +- drivers/ata/libata.h | 3 --- 2 files changed, 1 insertions(+), 4 deletions(-)drivers/ata/libata-sff.c +1
-1@@ -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))drivers/ata/libata.h +0
-0
drivers/ata/libata.h static inline int sata_pmp_attach(struct ata_device *dev) · line 206
Quoted 9 lines
drivers/ata/libata.h +0
-3@@ -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
PATCH 6/22 libata: kill ATA_FLAG_DISABLED
In reply to Tejun HeoATA_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()).
--- 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(-)
drivers/ata/libata-core.c +1 -65
@@ -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);
drivers/ata/libata-scsi.c +0 -3
@@ -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) {
drivers/ata/libata-sff.c +8 -16
@@ -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" ); }
drivers/ata/pata_bf54x.c +5 -11
@@ -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);
drivers/ata/pdc_adma.c +30 -36
80 lines not on this page · raw message
drivers/ata/sata_inic162x.c +3 -14
@@ -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);
drivers/ata/sata_mv.c +1 -7
@@ -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,
drivers/ata/sata_nv.c +111 -123
267 lines not on this page · raw message
drivers/ata/sata_promise.c +2 -4
@@ -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);
drivers/ata/sata_qstor.c +37 -42
96 lines not on this page · raw message
drivers/ata/sata_sil.c +0 -3
@@ -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 ;
drivers/ata/sata_sil24.c +2 -7
@@ -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);
drivers/ata/sata_sx4.c +1 -3
@@ -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);
drivers/ata/sata_vsc.c +2 -8
@@ -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++; } }
drivers/scsi/ipr.c +3 -4
@@ -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 ; };
drivers/scsi/libsas/sas_scsi_host.c +1 -1
@@ -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)
include/linux/libata.h +0 -8
@@ -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,
Signature · 1 line
1.5.4.5
PATCH 7/22 sata_inic162x: kill PORT_PRD_ADDR initialization
In reply to Tejun Heosata_inic162x doesn't use PRD anymore. No need to initialize it.
--- drivers/ata/sata_inic162x.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/ata/sata_inic162x.c +1 -2
@@ -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 ); }
Signature · 1 line
1.5.4.5
PATCH 8/22 libata-sff: reorder SFF/BMDMA functions
In reply to Tejun HeoReorder functions such that SFF and BMDMA functions are grouped. While at it, s/BMDMA/SFF in a few comments where it actually meant SFF.
--- drivers/ata/libata-sff.c | 610 +++++++++++++++++++++++----------------------- include/linux/libata.h | 24 +- 2 files changed, 322 insertions(+), 312 deletions(-)
drivers/ata/libata-sff.c +308 -302
@@ -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 */
include/linux/libata.h +14 -10
@@ -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.
Signature · 1 line
1.5.4.5
PATCH 9/22 pata_cmd640/bf54x/icside: fix inheritance
In reply to Tejun Heocmd640 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.
--- 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(-)
drivers/ata/pata_bf54x.c +3 -1
@@ -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[] = {
drivers/ata/pata_cmd640.c +2 -2
@@ -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,
drivers/ata/pata_icside.c +3 -1
@@ -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
Signature · 1 line
1.5.4.5
PATCH 10/22 libata-sff: clean up BMDMA initialization
In reply to Tejun HeoWhen 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.
--- 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(-)
drivers/ata/libata-core.c +0 -25
@@ -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);
drivers/ata/libata-sff.c +60 -62
210 lines not on this page · raw message
drivers/ata/pata_acpi.c +2 -2
@@ -106,7 +106,7 @@ static unsigned long pacpi_discover_modes(struct ata_port *ap, struct ata_devicestatic 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;
drivers/ata/pata_ali.c +1 -1
@@ -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; }/**
drivers/ata/pata_bf54x.c +0 -2
@@ -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[] = {
drivers/ata/pata_cmd640.c +1 -5
@@ -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 = {
drivers/ata/pata_hpt366.c +1 -1
@@ -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; }/**
drivers/ata/pata_hpt37x.c +2 -2
@@ -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; }/**
drivers/ata/pata_icside.c +1 -1
@@ -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
drivers/ata/pata_it821x.c +1 -1
@@ -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;
drivers/ata/pata_pdc2027x.c +2 -2
@@ -265,7 +265,7 @@ static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned longstruct 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 longif (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; }/**
drivers/ata/pata_pdc202xx_old.c +1 -1
@@ -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); }/**
drivers/ata/pata_platform.c +0 -1
@@ -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,
drivers/ata/pata_scc.c +3 -3
@@ -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;
drivers/ata/pata_serverworks.c +3 -3
@@ -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 loif (!strcmp (p, model_num)) mask &= ~(0xE0 <<ATA_SHIFT_UDMA ); } -return ata_bmdma_mode_filter (adev, mask); +return mask; }/**
drivers/ata/pdc_adma.c +0 -4
@@ -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)
drivers/ata/sata_inic162x.c +0 -5
@@ -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)
drivers/ata/sata_nv.c +4 -2
@@ -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;
drivers/ata/sata_promise.c +2 -1
@@ -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;
drivers/ata/sata_qstor.c +0 -4
@@ -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 ;
drivers/ata/sata_sx4.c +0 -5
@@ -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)
drivers/ata/sata_uli.c +1 -3
@@ -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;
include/linux/libata.h +2 -5
@@ -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 */ /**
Signature · 1 line
1.5.4.5
Re: [PATCH 10/22] libata-sff: clean up BMDMA initialization
Quoted 14 lines · Tejun Heo
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 clearsap->mwdma_maskandudma_maskinstead of depending onata_bmdma_mode_filter(). This makesata_bmdma_mode_filter()unnecessary and p1 is removed.*
ata_port_start()which actually is BMDMA specific is moved toata_bmdma_port_start().ata_port_start()andata_sff_port_start()are killed.
Quoted 8 lines
Drivers which no longer calls into PRD table allocation are...
pdc_adma,sata_inic162x,sata_qstor,sata_sx4,pata_cmd640and all drivers which inherit fromata_sff_port_ops.
pata_icsidesets ->port_start toATA_OP_NULLas it doesn't need PRD but is a BMDMA controller and doesn't have customport_startlike other such controllers.
Nice!
PATCH 11/22 libata-sff: introduce ata_sff_init/exit() and ata_sff_port_init()
In reply to Tejun HeoIn preparation of proper SFF/BMDMA separation, introduce ata_sff_init/exit() and ata_sff_port_init(). These functions currently don't do anything.
--- drivers/ata/libata-core.c | 23 +++++++++++++++++------ drivers/ata/libata-sff.c | 23 +++++++++++++++++++++++ drivers/ata/libata.h | 10 ++++++++++ 3 files changed, 50 insertions(+), 6 deletions(-)
drivers/ata/libata-core.c +17 -6
@@ -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);
drivers/ata/libata-sff.c +23 -0
@@ -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);
drivers/ata/libata.h +10 -0
@@ -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__ */
Signature · 1 line
1.5.4.5
PATCH 12/22 libata-sff: ap->[last_]ctl are SFF specific
In reply to Tejun Heoap->[last_]ctl are specific to SFF controllers. Put them inside CONFIG_ATA_SFF and move initialization into ata_sff_port_init().
--- drivers/ata/libata-core.c | 2 -- drivers/ata/libata-sff.c | 2 ++ include/linux/libata.h | 8 ++++++-- 3 files changed, 8 insertions(+), 4 deletions(-)
drivers/ata/libata-core.c +0 -2
@@ -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 */
drivers/ata/libata-sff.c +2 -0
@@ -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 )
include/linux/libata.h +6 -2
@@ -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
Signature · 1 line
1.5.4.5
PATCH 13/22 libata-sff: port_task is SFF specific
In reply to Tejun Heoport_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.
--- 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(-)
drivers/ata/libata-core.c +1 -61
@@ -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); }
drivers/ata/libata-eh.c +2 -2
@@ -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 */
drivers/ata/libata-sff.c +46 -18
154 lines not on this page · raw message
drivers/ata/libata.h +3 -4
@@ -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 )
include/linux/libata.h +1 -2
@@ -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;
Signature · 1 line
1.5.4.5
PATCH 14/22 libata-sff: separate out BMDMA EHs
In reply to Tejun HeoAll 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.
--- 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(-)
drivers/ata/libata-eh.c +5 -2
@@ -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
drivers/ata/libata-sff.c +106 -96
244 lines not on this page · raw message
drivers/ata/libata.h +6 -11
@@ -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 )
drivers/ata/pata_icside.c +0 -1
@@ -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 */ };
drivers/ata/pata_mpc52xx.c +0 -1
@@ -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
drivers/ata/pata_scc.c +0 -1
@@ -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,
drivers/ata/sata_mv.c +0 -2
@@ -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,
drivers/ata/sata_nv.c +3 -3
@@ -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
drivers/ata/sata_qstor.c +0 -1
@@ -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,
include/linux/libata.h +2 -2
@@ -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);
Signature · 1 line
1.5.4.5
PATCH 15/22 libata-sff: ata_sff_[dumb_]qc_prep are BMDMA specific
In reply to Tejun HeoBoth 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.
--- 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(-)
drivers/ata/libata-sff.c +145 -143
@@ -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);
drivers/ata/pata_atiixp.c +1 -1
@@ -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,
drivers/ata/pata_cs5520.c +1 -1
@@ -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,
drivers/ata/pata_cs5530.c +1 -1
@@ -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,
drivers/ata/pata_sc1200.c +1 -1
@@ -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,
drivers/ata/pdc_adma.c +1 -3
@@ -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 */
drivers/ata/sata_nv.c +2 -2
@@ -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 ; }
drivers/ata/sata_qstor.c +1 -3
@@ -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);
include/linux/libata.h +2 -2
@@ -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);
Signature · 1 line
1.5.4.5
PATCH 16/22 libata-sff: prd is BMDMA specific
In reply to Tejun Heostruct ata_prd and ap->prd are BMDMA specific. Add bmdma_ prefix to them and move them inside CONFIG_ATA_SFF.
--- 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(-)
drivers/ata/libata-sff.c +15 -12
@@ -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 ; }
drivers/ata/pata_ns87415.c +1 -1
@@ -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 );
drivers/ata/pata_scc.c +2 -2
@@ -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 ; }
drivers/ata/sata_nv.c +2 -2
@@ -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;
drivers/ata/sata_promise.c +11 -10
@@ -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);
drivers/ata/sata_svw.c +1 -1
@@ -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 );
include/linux/ata.h +1 -1
@@ -418,7 +418,7 @@ enum ata_ioctls {/* core structures */ -struct ata_prd { +struct ata_bmdma_prd {__le32 addr;__le32 flags_len; };
include/linux/libata.h +2 -0
@@ -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;
Signature · 1 line
1.5.4.5
PATCH 17/22 libata-sff: separate out BMDMA qc_issue
In reply to Tejun HeoSeparate 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.
--- 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(-)
drivers/ata/libata-sff.c +67 -45
@@ -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);
drivers/ata/pata_acpi.c +2 -2
@@ -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); }/**
drivers/ata/pata_cs5530.c +1 -1
@@ -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 = {
drivers/ata/pata_hpt3x2n.c +1 -1
@@ -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 = {
drivers/ata/pata_it821x.c +2 -2
@@ -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); }/**
drivers/ata/pata_oldpiix.c +1 -1
@@ -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); }
drivers/ata/pata_radisys.c +1 -1
@@ -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); }
drivers/ata/pata_sc1200.c +1 -1
@@ -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 = {
drivers/ata/sata_nv.c +2 -2
@@ -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" );
include/linux/libata.h +1 -0
@@ -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);
Signature · 1 line
1.5.4.5
PATCH 18/22 libata-sff: ata_sff_irq_clear() is BMDMA specific
In reply to Tejun Heoata_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.
--- 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(-)
drivers/ata/libata-sff.c +38 -29
@@ -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);
drivers/ata/pata_bf54x.c +1 -1
@@ -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)
drivers/ata/pata_scc.c +1 -1
@@ -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)
drivers/ata/sata_nv.c +1 -1
@@ -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 ; }
drivers/ata/sata_sil.c +2 -2
@@ -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 ))
drivers/ata/sata_via.c +1 -1
@@ -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); }/**
include/linux/libata.h +1 -1
@@ -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);
Signature · 1 line
1.5.4.5
PATCH 19/22 libata-sff: separate out BMDMA irq handler
In reply to Tejun HeoSeparate 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.
--- 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(-)
drivers/ata/ata_piix.c +1 -1
@@ -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 )
drivers/ata/libata-sff.c +117 -55
250 lines not on this page · raw message
drivers/ata/pata_cs5520.c +1 -1
@@ -258,7 +258,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devicontinue ; 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;
drivers/ata/pata_hpt3x3.c +1 -1
@@ -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); }
drivers/ata/pata_icside.c +1 -1
@@ -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); }
drivers/ata/pata_ninja32.c +1 -1
@@ -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); }
drivers/ata/pata_pdc2027x.c +1 -1
@@ -759,7 +759,7 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_dereturn -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); }
drivers/ata/pata_scc.c +1 -1
@@ -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); }
drivers/ata/pata_sil680.c +1 -1
@@ -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:
drivers/ata/sata_mv.c +1 -1
@@ -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); }
drivers/ata/sata_nv.c +2 -2
@@ -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.
drivers/ata/sata_qstor.c +1 -1
@@ -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; }
drivers/ata/sata_sis.c +1 -1
@@ -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); }
drivers/ata/sata_svw.c +1 -1
@@ -502,7 +502,7 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *enwritel (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); }
drivers/ata/sata_uli.c +1 -1
@@ -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); }
drivers/ata/sata_via.c +1 -1
@@ -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); }
drivers/ata/sata_vsc.c +1 -1
@@ -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
include/linux/libata.h +4 -1
@@ -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);
Signature · 1 line
1.5.4.5
PATCH 20/22 libata-sff: separate out BMDMA init
In reply to Tejun HeoSeparate 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.
--- 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(-)
drivers/ata/ata_piix.c +1 -1
@@ -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;
drivers/ata/libata-sff.c +111 -24
190 lines not on this page · raw message
drivers/ata/pata_acpi.c +1 -1
@@ -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[] = {
drivers/ata/pata_ali.c +4 -1
@@ -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
drivers/ata/pata_amd.c +1 -1
@@ -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
drivers/ata/pata_artop.c +1 -1
@@ -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[] = {
drivers/ata/pata_atiixp.c +1 -1
@@ -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[] = {
drivers/ata/pata_cmd64x.c +1 -1
@@ -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
drivers/ata/pata_cs5530.c +1 -1
@@ -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
drivers/ata/pata_cs5535.c +1 -1
@@ -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[] = {
drivers/ata/pata_cs5536.c +1 -1
@@ -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[] = {
drivers/ata/pata_cypress.c +1 -1
@@ -136,7 +136,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *iif (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[] = {
drivers/ata/pata_efar.c +1 -1
@@ -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[] = {
drivers/ata/pata_hpt366.c +1 -1
@@ -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
drivers/ata/pata_hpt37x.c +1 -1
@@ -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[] = {
drivers/ata/pata_hpt3x2n.c +1 -1
@@ -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[] = {
drivers/ata/pata_it8213.c +1 -1
@@ -274,7 +274,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *endev_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[] = {
drivers/ata/pata_it821x.c +1 -1
@@ -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
drivers/ata/pata_jmicron.c +1 -1
@@ -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[] = {
drivers/ata/pata_marvell.c +1 -1
@@ -153,7 +153,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *ireturn -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[] = {
drivers/ata/pata_netcell.c +1 -1
@@ -71,7 +71,7 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *eata_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[] = {
drivers/ata/pata_ns87415.c +1 -1
@@ -375,7 +375,7 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *epci_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[] = {
drivers/ata/pata_oldpiix.c +1 -1
@@ -249,7 +249,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *edev_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[] = {
drivers/ata/pata_optidma.c +1 -1
@@ -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[] = {
drivers/ata/pata_pdc202xx_old.c +1 -1
@@ -324,7 +324,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *idreturn -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[] = {
drivers/ata/pata_radisys.c +1 -1
@@ -228,7 +228,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *edev_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[] = {
drivers/ata/pata_sc1200.c +1 -1
@@ -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[] = {
drivers/ata/pata_sch.c +1 -1
@@ -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 )
drivers/ata/pata_serverworks.c +1 -1
@@ -461,7 +461,7 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_idif (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
drivers/ata/pata_sil680.c +1 -1
@@ -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
drivers/ata/pata_sis.c +1 -1
@@ -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[] = {
drivers/ata/pata_sl82c105.c +1 -1
@@ -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[] = {
drivers/ata/pata_triflex.c +1 -1
@@ -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[] = {
drivers/ata/pata_via.c +1 -1
@@ -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
drivers/ata/sata_nv.c +1 -1
@@ -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;
drivers/ata/sata_sis.c +1 -1
@@ -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;
drivers/ata/sata_via.c +1 -1
@@ -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;
include/linux/libata.h +7 -0
@@ -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 */ /**
Signature · 1 line
1.5.4.5
PATCH 20/22 libata-sff: separate out BMDMA init
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.
---
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(-)
drivers/ata/libata-sff.c +111 -24
@@ -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 atareturn 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 */
drivers/ata/ata_piix.c +1 -1
@@ -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;
drivers/ata/pata_sch.c +1 -1
@@ -179,7 +179,7 @@ static int __devinit sch_init_one(structdev_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 )
drivers/ata/sata_nv.c +1 -1
@@ -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;
drivers/ata/sata_sis.c +1 -1
@@ -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;
drivers/ata/sata_via.c +2 -2
@@ -445,7 +445,7 @@ static int vt6420_prepare_host(struct pcstruct 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 pcstruct 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;
drivers/ata/pata_acpi.c +1 -1
@@ -265,7 +265,7 @@ static int pacpi_init_one (struct pci_dereturn 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[] = {
drivers/ata/pata_ali.c +4 -1
@@ -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
drivers/ata/pata_amd.c +1 -1
@@ -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
drivers/ata/pata_artop.c +1 -1
@@ -400,7 +400,7 @@ static int artop_init_one (struct pci_deBUG_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[] = {
drivers/ata/pata_atiixp.c +1 -1
@@ -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[] = {
drivers/ata/pata_cmd64x.c +1 -1
@@ -373,7 +373,7 @@ static int cmd64x_init_one(struct pci_depci_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
drivers/ata/pata_cs5530.c +1 -1
@@ -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
drivers/ata/pata_cs5535.c +1 -1
@@ -199,7 +199,7 @@ static int cs5535_init_one(struct pci_derdmsr (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[] = {
drivers/ata/pata_cs5536.c +1 -1
@@ -261,7 +261,7 @@ static int cs5536_init_one(struct pci_dereturn -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[] = {
drivers/ata/pata_cypress.c +1 -1
@@ -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[] = {
drivers/ata/pata_efar.c +1 -1
@@ -262,7 +262,7 @@ static int efar_init_one (struct pci_devdev_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[] = {
drivers/ata/pata_hpt366.c +1 -1
@@ -393,7 +393,7 @@ static int hpt36x_init_one(struct pci_debreak ; }/* 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
drivers/ata/pata_hpt37x.c +1 -1
@@ -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[] = {
drivers/ata/pata_hpt3x2n.c +1 -1
@@ -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[] = {
drivers/ata/pata_it8213.c +1 -1
@@ -274,7 +274,7 @@ static int it8213_init_one (struct pci_ddev_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[] = {
drivers/ata/pata_it821x.c +1 -1
@@ -923,7 +923,7 @@ static int it821x_init_one(struct pci_deelse 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
drivers/ata/pata_jmicron.c +1 -1
@@ -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[] = {
drivers/ata/pata_marvell.c +1 -1
@@ -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[] = {
drivers/ata/pata_netcell.c +1 -1
@@ -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[] = {
drivers/ata/pata_ns87415.c +1 -1
@@ -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[] = {
drivers/ata/pata_oldpiix.c +1 -1
@@ -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[] = {
drivers/ata/pata_optidma.c +1 -1
@@ -430,7 +430,7 @@ static int optidma_init_one(struct pci_dif (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[] = {
drivers/ata/pata_pdc202xx_old.c +1 -1
@@ -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[] = {
drivers/ata/pata_radisys.c +1 -1
@@ -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[] = {
drivers/ata/pata_sc1200.c +1 -1
@@ -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[] = {
drivers/ata/pata_serverworks.c +1 -1
@@ -461,7 +461,7 @@ static int serverworks_init_one(struct pif (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
drivers/ata/pata_sil680.c +1 -1
@@ -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
drivers/ata/pata_sis.c +1 -1
@@ -822,7 +822,7 @@ static int sis_init_one (struct pci_devsis_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[] = {
drivers/ata/pata_sl82c105.c +1 -1
@@ -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[] = {
drivers/ata/pata_triflex.c +1 -1
@@ -201,7 +201,7 @@ static int triflex_init_one(struct pci_dif (!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[] = {
drivers/ata/pata_via.c +1 -1
@@ -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
include/linux/libata.h +7 -0
@@ -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 */ /**
PATCH 21/22 sata_qstor: kill dummy BMDMA ops
In reply to Tejun HeoNow 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.
--- drivers/ata/sata_qstor.c | 14 -------------- 1 files changed, 0 insertions(+), 14 deletions(-)
drivers/ata/sata_qstor.c +0 -14
@@ -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 );
Signature · 1 line
1.5.4.5
Re: [PATCH 21/22] sata_qstor: kill dummy BMDMA ops
Hello.
Quoted 2 lines · Tejun Heo
Now that SFF and BMDMA are completely separate,
sata_qstorwhich
SFF and BMDMA being separate sounds funny. :-)
MBR, Sergei
Re: [PATCH 21/22] sata_qstor: kill dummy BMDMA ops
Quoted 8 lines · Sergei Shtylyov
Hello.
Quoted 2 lines · Tejun Heo
Now that SFF and BMDMA are completely separate,
sata_qstorwhichSFF 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
Signature · 1 line
tejun
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.
Signature · 1 line
tejun
Hello.
Quoted 2 lines · Tejun Heo
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. :-)
Quoted 2 lines
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.
Quoted 4 lines
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. :-)
Quoted 13 lines
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 fromata_sff_port_opsor clear ->mode_filter explicitly.
Quoted 8 lines
2. non-BMDMA drivers call into BMDMA PRD table allocation. It doesn't actually allocate PRD table if
bmdma_addris 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_stopfromata_sff_post_internal_cmd()).
What do you mean by BMDMA here? I'm now at a loss...
Quoted 3 lines
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
Hello, Sergei.
Quoted 5 lines · Sergei Shtylyov
Quoted 1 line · Tejun Heo
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.
Quoted 7 lines
Quoted 2 lines
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. :-)
Quoted 5 lines
Quoted 3 lines
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.
Quoted 17 lines
Quoted 17 lines
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 fromata_sff_port_opsor clear ->mode_filter explicitly.2. non-BMDMA drivers call into BMDMA PRD table allocation. It doesn't actually allocate PRD table if
bmdma_addris not initialized but is still confusing.
Quoted 6 lines
Quoted 4 lines
3. For BMDMA drivers which don't use traditional BMDMA register, some methods might not be invoked as expected (e.g.
bmdma_stopfromata_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.
Quoted 5 lines
Quoted 2 lines
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.
Signature · 1 line
tejun
Tejun Heo wrote:
..
Quoted 3 lines
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
Quoted 10 lines · Mark Lord
Tejun Heo wrote:
..Quoted 3 lines
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 tosata_mv..
Quoted 6 lines
Currently
sata_mvis 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.
Signature · 1 line
tejun
Quoted 157 lines · Tejun Heo
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 fromata_sff_port_opsor clear ->mode_filter explicitly.2. non-BMDMA drivers call into BMDMA PRD table allocation. It doesn't actually allocate PRD table if
bmdma_addris 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_stopfromata_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_addrcondition 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
Kconfigoptions 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_iand 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
Quoted 8 lines
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
Quoted 1 line · Jeff Garzik
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.
Signature · 1 line
tejun
Quoted 6 lines · Tejun Heo
Quoted 1 line · Jeff Garzik
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
Quoted 8 lines · Jeff Garzik
Quoted 6 lines · Tejun Heo
Quoted 1 line · Jeff Garzik
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.
Quoted 5 lines
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.
Signature · 1 line
tejun
PATCH 22/22 libata-sff: make BMDMA optional
In reply to Tejun HeoMake 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).
--- 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(-)
drivers/ata/Kconfig +185 -163
@@ -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
drivers/ata/Makefile +28 -19
100 lines not on this page · raw message
drivers/ata/libata-sff.c +13 -0
@@ -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 */
include/linux/libata.h +16 -6
@@ -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
Signature · 1 line
1.5.4.5
Hello.
Quoted 86 lines · Tejun Heo
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 fromata_sff_port_opsor clear ->mode_filter explicitly.2. non-BMDMA drivers call into BMDMA PRD table allocation. It doesn't actually allocate PRD table if
bmdma_addris 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_stopfromata_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_addrcondition 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
Kconfigoptions according to the groups of drivers they belong to.This patchset is on top of
Quoted 7 lines
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_iand makes the followings changes.
Tejun, what was the fate of this patchset? Looks like it ended up
ignored...
MBR, Sergei
Quoted 2 lines · Sergei Shtylyov
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.
Signature · 1 line
tejun