summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 08:38:06 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2008-04-18 08:38:06 -0700
commit8019aa946af5218bc4446c21e43cc19c9401ac68 (patch)
tree6681b73a560f5a4e4a4e8f97b3833a087a488439
parent73e3e6481f56b3b5b618671a8d32b19a35f84316 (diff)
parent48feb3c419508487becfb9ea3afcc54c3eac6d80 (diff)
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev: (79 commits) ata-acpi: don't call _GTF for disabled drive sata_mv add temporary 3 second init delay for SiliconImage PMs sata_mv remove redundant edma init code sata_mv add basic port multiplier support sata_mv fix SOC flags, enable NCQ on SOC sata_mv disable hotplug for now sata_mv cosmetics sata_mv hardreset rework [libata] improve Kconfig help text for new PMP, SFF options libata: make EH fail gracefully if no reset method is available libata: Be a bit more slack about early devices libata: cable logic libata: move link onlineness check out of softreset methods libata: kill dead code paths in reset path pata_scc: fix build breakage libata: make PMP support optional libata: implement PMP helpers libata: separate PMP support code from core code libata: make SFF support optional libata: don't use ap->ioaddr in non-SFF drivers ...
-rw-r--r--drivers/ata/Kconfig64
-rw-r--r--drivers/ata/Makefile5
-rw-r--r--drivers/ata/ahci.c309
-rw-r--r--drivers/ata/ata_generic.c51
-rw-r--r--drivers/ata/ata_piix.c312
-rw-r--r--drivers/ata/libata-acpi.c8
-rw-r--r--drivers/ata/libata-core.c2228
-rw-r--r--drivers/ata/libata-eh.c225
-rw-r--r--drivers/ata/libata-pmp.c247
-rw-r--r--drivers/ata/libata-scsi.c17
-rw-r--r--drivers/ata/libata-sff.c2296
-rw-r--r--drivers/ata/libata.h53
-rw-r--r--drivers/ata/pata_acpi.c83
-rw-r--r--drivers/ata/pata_ali.c165
-rw-r--r--drivers/ata/pata_amd.c268
-rw-r--r--drivers/ata/pata_artop.c125
-rw-r--r--drivers/ata/pata_at32.c46
-rw-r--r--drivers/ata/pata_atiixp.c57
-rw-r--r--drivers/ata/pata_bf54x.c137
-rw-r--r--drivers/ata/pata_cmd640.c83
-rw-r--r--drivers/ata/pata_cmd64x.c137
-rw-r--r--drivers/ata/pata_cs5520.c64
-rw-r--r--drivers/ata/pata_cs5530.c80
-rw-r--r--drivers/ata/pata_cs5535.c50
-rw-r--r--drivers/ata/pata_cs5536.c50
-rw-r--r--drivers/ata/pata_cypress.c50
-rw-r--r--drivers/ata/pata_efar.c66
-rw-r--r--drivers/ata/pata_hpt366.c77
-rw-r--r--drivers/ata/pata_hpt37x.c245
-rw-r--r--drivers/ata/pata_hpt3x2n.c85
-rw-r--r--drivers/ata/pata_hpt3x3.c56
-rw-r--r--drivers/ata/pata_icside.c67
-rw-r--r--drivers/ata/pata_isapnp.c41
-rw-r--r--drivers/ata/pata_it8213.c67
-rw-r--r--drivers/ata/pata_it821x.c109
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c46
-rw-r--r--drivers/ata/pata_jmicron.c68
-rw-r--r--drivers/ata/pata_legacy.c316
-rw-r--r--drivers/ata/pata_marvell.c69
-rw-r--r--drivers/ata/pata_mpc52xx.c48
-rw-r--r--drivers/ata/pata_mpiix.c71
-rw-r--r--drivers/ata/pata_netcell.c58
-rw-r--r--drivers/ata/pata_ninja32.c54
-rw-r--r--drivers/ata/pata_ns87410.c68
-rw-r--r--drivers/ata/pata_ns87415.c102
-rw-r--r--drivers/ata/pata_oldpiix.c74
-rw-r--r--drivers/ata/pata_opti.c66
-rw-r--r--drivers/ata/pata_optidma.c103
-rw-r--r--drivers/ata/pata_pcmcia.c68
-rw-r--r--drivers/ata/pata_pdc2027x.c99
-rw-r--r--drivers/ata/pata_pdc202xx_old.c96
-rw-r--r--drivers/ata/pata_platform.c46
-rw-r--r--drivers/ata/pata_qdi.c77
-rw-r--r--drivers/ata/pata_radisys.c57
-rw-r--r--drivers/ata/pata_rb500_cf.c54
-rw-r--r--drivers/ata/pata_rz1000.c49
-rw-r--r--drivers/ata/pata_sc1200.c59
-rw-r--r--drivers/ata/pata_scc.c257
-rw-r--r--drivers/ata/pata_serverworks.c114
-rw-r--r--drivers/ata/pata_sil680.c71
-rw-r--r--drivers/ata/pata_sis.c230
-rw-r--r--drivers/ata/pata_sl82c105.c67
-rw-r--r--drivers/ata/pata_triflex.c58
-rw-r--r--drivers/ata/pata_via.c134
-rw-r--r--drivers/ata/pata_winbond.c47
-rw-r--r--drivers/ata/pdc_adma.c80
-rw-r--r--drivers/ata/sata_fsl.c136
-rw-r--r--drivers/ata/sata_inic162x.c73
-rw-r--r--drivers/ata/sata_mv.c632
-rw-r--r--drivers/ata/sata_nv.c263
-rw-r--r--drivers/ata/sata_promise.c118
-rw-r--r--drivers/ata/sata_qstor.c56
-rw-r--r--drivers/ata/sata_sil.c55
-rw-r--r--drivers/ata/sata_sil24.c247
-rw-r--r--drivers/ata/sata_sis.c44
-rw-r--r--drivers/ata/sata_svw.c47
-rw-r--r--drivers/ata/sata_sx4.c52
-rw-r--r--drivers/ata/sata_uli.c55
-rw-r--r--drivers/ata/sata_via.c126
-rw-r--r--drivers/ata/sata_vsc.c44
-rw-r--r--drivers/scsi/ipr.c74
-rw-r--r--drivers/scsi/libsas/sas_ata.c19
-rw-r--r--include/linux/libata.h718
83 files changed, 4787 insertions, 8801 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 25aba69b59b4..292aa9a0f02f 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -28,7 +28,7 @@ config ATA_NONSTANDARD
default n
config ATA_ACPI
- bool
+ bool "ATA ACPI Support"
depends on ACPI && PCI
select ACPI_DOCK
default y
@@ -41,6 +41,13 @@ config ATA_ACPI
You can disable this at kernel boot time by using the
option libata.noacpi=1
+config SATA_PMP
+ bool "SATA Port Multiplier support"
+ default y
+ help
+ This option adds support for SATA Port Multipliers
+ (the SATA version of an ethernet hub, or SAS expander).
+
config SATA_AHCI
tristate "AHCI SATA support"
depends on PCI
@@ -49,6 +56,43 @@ config SATA_AHCI
If unsure, say N.
+config SATA_SIL24
+ tristate "Silicon Image 3124/3132 SATA support"
+ depends on PCI
+ help
+ This option enables support for Silicon Image 3124/3132 Serial ATA.
+
+ If unsure, say N.
+
+config SATA_FSL
+ tristate "Freescale 3.0Gbps SATA support"
+ depends on FSL_SOC
+ help
+ This option enables support for Freescale 3.0Gbps SATA controller.
+ It can be found on MPC837x and MPC8315.
+
+ If unsure, say N.
+
+config ATA_SFF
+ bool "ATA SFF support"
+ default y
+ help
+ This option adds support for ATA controllers with SFF
+ compliant or similar programming interface.
+
+ SFF is the legacy IDE interface that has been around since
+ the dawn of time. Almost all PATA controllers have an
+ SFF interface. Many SATA controllers have an SFF interface
+ when configured into a legacy compatibility mode.
+
+ For users with exclusively modern controllers like AHCI,
+ Silicon Image 3124, or Marvell 6440, you may choose to
+ disable this uneeded SFF support.
+
+ If unsure, say Y.
+
+if ATA_SFF
+
config SATA_SVW
tristate "ServerWorks Frodo / Apple K2 SATA support"
depends on PCI
@@ -125,14 +169,6 @@ config SATA_SIL
If unsure, say N.
-config SATA_SIL24
- tristate "Silicon Image 3124/3132 SATA support"
- depends on PCI
- help
- This option enables support for Silicon Image 3124/3132 Serial ATA.
-
- If unsure, say N.
-
config SATA_SIS
tristate "SiS 964/965/966/180 SATA support"
depends on PCI
@@ -183,15 +219,6 @@ config PATA_ACPI
firmware in the BIOS. This driver can sometimes handle
otherwise unsupported hardware.
-config SATA_FSL
- tristate "Freescale 3.0Gbps SATA support"
- depends on FSL_SOC
- help
- This option enables support for Freescale 3.0Gbps SATA controller.
- It can be found on MPC837x and MPC8315.
-
- If unsure, say N.
-
config PATA_ALI
tristate "ALi PATA support (Experimental)"
depends on PCI && EXPERIMENTAL
@@ -679,4 +706,5 @@ config PATA_BF54X
If unsure, say N.
+endif # ATA_SFF
endif # ATA
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 0511e6f0bb58..1fbc2aa648b7 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -78,6 +78,7 @@ obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
# Should be last libata driver
obj-$(CONFIG_PATA_LEGACY) += pata_legacy.o
-libata-objs := libata-core.o libata-scsi.o libata-sff.o libata-eh.o \
- libata-pmp.o
+libata-objs := libata-core.o libata-scsi.o libata-eh.o
+libata-$(CONFIG_ATA_SFF) += libata-sff.o
+libata-$(CONFIG_SATA_PMP) += libata-pmp.o
libata-$(CONFIG_ATA_ACPI) += libata-acpi.o
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index b1eb4e24c86a..739ba3f222e8 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -62,7 +62,6 @@ enum {
AHCI_MAX_PORTS = 32,
AHCI_MAX_SG = 168, /* hardware max is 64K */
AHCI_DMA_BOUNDARY = 0xffffffff,
- AHCI_USE_CLUSTERING = 1,
AHCI_MAX_CMDS = 32,
AHCI_CMD_SZ = 32,
AHCI_CMD_SLOT_SZ = AHCI_MAX_CMDS * AHCI_CMD_SZ,
@@ -198,7 +197,6 @@ enum {
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
ATA_FLAG_ACPI_SATA | ATA_FLAG_AN |
ATA_FLAG_IPM,
- AHCI_LFLAG_COMMON = ATA_LFLAG_SKIP_D2H_BSY,
ICH_MAP = 0x90, /* ICH MAP register */
};
@@ -245,19 +243,24 @@ static int ahci_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
static int ahci_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc);
-static void ahci_irq_clear(struct ata_port *ap);
+static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc);
static int ahci_port_start(struct ata_port *ap);
static void ahci_port_stop(struct ata_port *ap);
-static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
static void ahci_qc_prep(struct ata_queued_cmd *qc);
-static u8 ahci_check_status(struct ata_port *ap);
static void ahci_freeze(struct ata_port *ap);
static void ahci_thaw(struct ata_port *ap);
static void ahci_pmp_attach(struct ata_port *ap);
static void ahci_pmp_detach(struct ata_port *ap);
+static int ahci_softreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+static int ahci_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+static void ahci_postreset(struct ata_link *link, unsigned int *class);
static void ahci_error_handler(struct ata_port *ap);
-static void ahci_vt8251_error_handler(struct ata_port *ap);
-static void ahci_p5wdh_error_handler(struct ata_port *ap);
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
static int ahci_port_resume(struct ata_port *ap);
static void ahci_dev_config(struct ata_device *dev);
@@ -276,129 +279,54 @@ static struct class_device_attribute *ahci_shost_attrs[] = {
};
static struct scsi_host_template ahci_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .change_queue_depth = ata_scsi_change_queue_depth,
+ ATA_NCQ_SHT(DRV_NAME),
.can_queue = AHCI_MAX_CMDS - 1,
- .this_id = ATA_SHT_THIS_ID,
.sg_tablesize = AHCI_MAX_SG,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = AHCI_USE_CLUSTERING,
- .proc_name = DRV_NAME,
.dma_boundary = AHCI_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
.shost_attrs = ahci_shost_attrs,
};
-static const struct ata_port_operations ahci_ops = {
- .check_status = ahci_check_status,
- .check_altstatus = ahci_check_status,
- .dev_select = ata_noop_dev_select,
-
- .dev_config = ahci_dev_config,
-
- .tf_read = ahci_tf_read,
+static struct ata_port_operations ahci_ops = {
+ .inherits = &sata_pmp_port_ops,
.qc_defer = sata_pmp_qc_defer_cmd_switch,
.qc_prep = ahci_qc_prep,
.qc_issue = ahci_qc_issue,
-
- .irq_clear = ahci_irq_clear,
-
- .scr_read = ahci_scr_read,
- .scr_write = ahci_scr_write,
+ .qc_fill_rtf = ahci_qc_fill_rtf,
.freeze = ahci_freeze,
.thaw = ahci_thaw,
-
+ .softreset = ahci_softreset,
+ .hardreset = ahci_hardreset,
+ .postreset = ahci_postreset,
+ .pmp_softreset = ahci_softreset,
.error_handler = ahci_error_handler,
.post_internal_cmd = ahci_post_internal_cmd,
-
- .pmp_attach = ahci_pmp_attach,
- .pmp_detach = ahci_pmp_detach,
-
-#ifdef CONFIG_PM
- .port_suspend = ahci_port_suspend,
- .port_resume = ahci_port_resume,
-#endif
- .enable_pm = ahci_enable_alpm,
- .disable_pm = ahci_disable_alpm,
-
- .port_start = ahci_port_start,
- .port_stop = ahci_port_stop,
-};
-
-static const struct ata_port_operations ahci_vt8251_ops = {
- .check_status = ahci_check_status,
- .check_altstatus = ahci_check_status,
- .dev_select = ata_noop_dev_select,
-
- .tf_read = ahci_tf_read,
-
- .qc_defer = sata_pmp_qc_defer_cmd_switch,
- .qc_prep = ahci_qc_prep,
- .qc_issue = ahci_qc_issue,
-
- .irq_clear = ahci_irq_clear,
+ .dev_config = ahci_dev_config,
.scr_read = ahci_scr_read,
.scr_write = ahci_scr_write,
-
- .freeze = ahci_freeze,
- .thaw = ahci_thaw,
-
- .error_handler = ahci_vt8251_error_handler,
- .post_internal_cmd = ahci_post_internal_cmd,
-
.pmp_attach = ahci_pmp_attach,
.pmp_detach = ahci_pmp_detach,
+ .enable_pm = ahci_enable_alpm,
+ .disable_pm = ahci_disable_alpm,
#ifdef CONFIG_PM
.port_suspend = ahci_port_suspend,
.port_resume = ahci_port_resume,
#endif
-
.port_start = ahci_port_start,
.port_stop = ahci_port_stop,
};
-static const struct ata_port_operations ahci_p5wdh_ops = {
- .check_status = ahci_check_status,
- .check_altstatus = ahci_check_status,
- .dev_select = ata_noop_dev_select,
-
- .tf_read = ahci_tf_read,
-
- .qc_defer = sata_pmp_qc_defer_cmd_switch,
- .qc_prep = ahci_qc_prep,
- .qc_issue = ahci_qc_issue,
-
- .irq_clear = ahci_irq_clear,
-
- .scr_read = ahci_scr_read,
- .scr_write = ahci_scr_write,
-
- .freeze = ahci_freeze,
- .thaw = ahci_thaw,
-
- .error_handler = ahci_p5wdh_error_handler,
- .post_internal_cmd = ahci_post_internal_cmd,
-
- .pmp_attach = ahci_pmp_attach,
- .pmp_detach = ahci_pmp_detach,
-
-#ifdef CONFIG_PM
- .port_suspend = ahci_port_suspend,
- .port_resume = ahci_port_resume,
-#endif
+static struct ata_port_operations ahci_vt8251_ops = {
+ .inherits = &ahci_ops,
+ .hardreset = ahci_vt8251_hardreset,
+};
- .port_start = ahci_port_start,
- .port_stop = ahci_port_stop,
+static struct ata_port_operations ahci_p5wdh_ops = {
+ .inherits = &ahci_ops,
+ .hardreset = ahci_p5wdh_hardreset,
};
#define AHCI_HFLAGS(flags) .private_data = (void *)(flags)
@@ -407,7 +335,6 @@ static const struct ata_port_info ahci_port_info[] = {
/* board_ahci */
{
.flags = AHCI_FLAG_COMMON,
- .link_flags = AHCI_LFLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
@@ -416,7 +343,6 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
- .link_flags = AHCI_LFLAG_COMMON | ATA_LFLAG_HRST_TO_RESUME,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_vt8251_ops,
@@ -425,7 +351,6 @@ static const struct ata_port_info ahci_port_info[] = {
{
AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR),
.flags = AHCI_FLAG_COMMON,
- .link_flags = AHCI_LFLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
@@ -436,7 +361,6 @@ static const struct ata_port_info ahci_port_info[] = {
AHCI_HFLAG_32BIT_ONLY |
AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
- .link_flags = AHCI_LFLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
@@ -447,7 +371,6 @@ static const struct ata_port_info ahci_port_info[] = {
AHCI_HFLAG_MV_PATA),
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA,
- .link_flags = AHCI_LFLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
@@ -457,7 +380,6 @@ static const struct ata_port_info ahci_port_info[] = {
AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL |
AHCI_HFLAG_NO_PMP),
.flags = AHCI_FLAG_COMMON,
- .link_flags = AHCI_LFLAG_COMMON,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &ahci_ops,
@@ -1255,13 +1177,14 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag,
static int ahci_kick_engine(struct ata_port *ap, int force_restart)
{
- void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ahci_port_base(ap);
struct ahci_host_priv *hpriv = ap->host->private_data;
+ u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF;
u32 tmp;
int busy, rc;
/* do we need to kick the port? */
- busy = ahci_check_status(ap) & (ATA_BUSY | ATA_DRQ);
+ busy = status & (ATA_BUSY | ATA_DRQ);
if (!busy && !force_restart)
return 0;
@@ -1328,10 +1251,21 @@ static int ahci_exec_polled_cmd(struct ata_port *ap, int pmp,
return 0;
}
-static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
- int pmp, unsigned long deadline)
+static int ahci_check_ready(struct ata_link *link)
+{
+ void __iomem *port_mmio = ahci_port_base(link->ap);
+ u8 status = readl(port_mmio + PORT_TFDATA) & 0xFF;
+
+ if (!(status & ATA_BUSY))
+ return 1;
+ return 0;
+}
+
+static int ahci_softreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
{
struct ata_port *ap = link->ap;
+ int pmp = sata_srst_pmp(link);
const char *reason = NULL;
unsigned long now, msecs;
struct ata_taskfile tf;
@@ -1339,12 +1273,6 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
DPRINTK("ENTER\n");
- if (ata_link_offline(link)) {
- DPRINTK("PHY reports no device\n");
- *class = ATA_DEV_NONE;
- return 0;
- }
-
/* prepare for SRST (AHCI-1.1 10.4.1) */
rc = ahci_kick_engine(ap, 1);
if (rc && rc != -EOPNOTSUPP)
@@ -1374,10 +1302,8 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
tf.ctl &= ~ATA_SRST;
ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0);
- /* wait a while before checking status */
- ata_wait_after_reset(ap, deadline);
-
- rc = ata_wait_ready(ap, deadline);
+ /* wait for link to become ready */
+ rc = ata_wait_after_reset(link, deadline, ahci_check_ready);
/* link occupied, -ENODEV too is an error */
if (rc) {
reason = "device not ready";
@@ -1393,24 +1319,15 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
return rc;
}
-static int ahci_softreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
-{
- int pmp = 0;
-
- if (link->ap->flags & ATA_FLAG_PMP)
- pmp = SATA_PMP_CTRL_PORT;
-
- return ahci_do_softreset(link, class, pmp, deadline);
-}
-
static int ahci_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
+ const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
struct ata_port *ap = link->ap;
struct ahci_port_priv *pp = ap->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
struct ata_taskfile tf;
+ bool online;
int rc;
DPRINTK("ENTER\n");
@@ -1422,14 +1339,13 @@ static int ahci_hardreset(struct ata_link *link, unsigned int *class,
tf.command = 0x80;
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
- rc = sata_std_hardreset(link, class, deadline);
+ rc = sata_link_hardreset(link, timing, deadline, &online,
+ ahci_check_ready);
ahci_start_engine(ap);
- if (rc == 0 && ata_link_online(link))
+ if (online)
*class = ahci_dev_classify(ap);
- if (rc != -EAGAIN && *class == ATA_DEV_UNKNOWN)
- *class = ATA_DEV_NONE;
DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
return rc;
@@ -1439,7 +1355,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
struct ata_port *ap = link->ap;
- u32 serror;
+ bool online;
int rc;
DPRINTK("ENTER\n");
@@ -1447,11 +1363,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
ahci_stop_engine(ap);
rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
- deadline);
-
- /* vt8251 needs SError cleared for the port to operate */
- ahci_scr_read(ap, SCR_ERROR, &serror);
- ahci_scr_write(ap, SCR_ERROR, serror);
+ deadline, &online, NULL);
ahci_start_engine(ap);
@@ -1460,7 +1372,7 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
/* vt8251 doesn't clear BSY on signature FIS reception,
* request follow-up softreset.
*/
- return rc ?: -EAGAIN;
+ return online ? -EAGAIN : rc;
}
static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
@@ -1470,6 +1382,7 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
struct ahci_port_priv *pp = ap->private_data;
u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
struct ata_taskfile tf;
+ bool online;
int rc;
ahci_stop_engine(ap);
@@ -1480,16 +1393,10 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
ata_tf_to_fis(&tf, 0, 0, d2h_fis);
rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
- deadline);
+ deadline, &online, NULL);
ahci_start_engine(ap);
- if (rc || ata_link_offline(link))
- return rc;
-
- /* spec mandates ">= 2ms" before checking status */
- msleep(150);
-
/* The pseudo configuration device on SIMG4726 attached to
* ASUS P5W-DH Deluxe doesn't send signature FIS after
* hardreset if no device is attached to the first downstream
@@ -1503,11 +1410,13 @@ static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
* have to be reset again. For most cases, this should
* suffice while making probing snappish enough.
*/
- rc = ata_wait_ready(ap, jiffies + 2 * HZ);
- if (rc)
- ahci_kick_engine(ap, 0);
-
- return 0;
+ if (online) {
+ rc = ata_wait_after_reset(link, jiffies + 2 * HZ,
+ ahci_check_ready);
+ if (rc)
+ ahci_kick_engine(ap, 0);
+ }
+ return rc;
}
static void ahci_postreset(struct ata_link *link, unsigned int *class)
@@ -1530,27 +1439,6 @@ static void ahci_postreset(struct ata_link *link, unsigned int *class)
}
}
-static int ahci_pmp_softreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
-{
- return ahci_do_softreset(link, class, link->pmp, deadline);
-}
-
-static u8 ahci_check_status(struct ata_port *ap)
-{
- void __iomem *mmio = ap->ioaddr.cmd_addr;
-
- return readl(mmio + PORT_TFDATA) & 0xFF;
-}
-
-static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
- struct ahci_port_priv *pp = ap->private_data;
- u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
-
- ata_tf_from_fis(d2h_fis, tf);
-}
-
static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl)
{
struct scatterlist *sg;
@@ -1663,27 +1551,27 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
u32 *unk = (u32 *)(pp->rx_fis + RX_FIS_UNK);
active_ehi->err_mask |= AC_ERR_HSM;
- active_ehi->action |= ATA_EH_SOFTRESET;
+ active_ehi->action |= ATA_EH_RESET;
ata_ehi_push_desc(active_ehi,
"unknown FIS %08x %08x %08x %08x" ,
unk[0], unk[1], unk[2], unk[3]);
}
- if (ap->nr_pmp_links && (irq_stat & PORT_IRQ_BAD_PMP)) {
+ if (sata_pmp_attached(ap) && (irq_stat & PORT_IRQ_BAD_PMP)) {
active_ehi->err_mask |= AC_ERR_HSM;
- active_ehi->action |= ATA_EH_SOFTRESET;
+ active_ehi->action |= ATA_EH_RESET;
ata_ehi_push_desc(active_ehi, "incorrect PMP");
}
if (irq_stat & (PORT_IRQ_HBUS_ERR | PORT_IRQ_HBUS_DATA_ERR)) {
host_ehi->err_mask |= AC_ERR_HOST_BUS;
- host_ehi->action |= ATA_EH_SOFTRESET;
+ host_ehi->action |= ATA_EH_RESET;
ata_ehi_push_desc(host_ehi, "host bus error");
}
if (irq_stat & PORT_IRQ_IF_ERR) {
host_ehi->err_mask |= AC_ERR_ATA_BUS;
- host_ehi->action |= ATA_EH_SOFTRESET;
+ host_ehi->action |= ATA_EH_RESET;
ata_ehi_push_desc(host_ehi, "interface fatal error");
}
@@ -1704,7 +1592,7 @@ static void ahci_error_intr(struct ata_port *ap, u32 irq_stat)
static void ahci_port_intr(struct ata_port *ap)
{
- void __iomem *port_mmio = ap->ioaddr.cmd_addr;
+ void __iomem *port_mmio = ahci_port_base(ap);
struct ata_eh_info *ehi = &ap->link.eh_info;
struct ahci_port_priv *pp = ap->private_data;
struct ahci_host_priv *hpriv = ap->host->private_data;
@@ -1766,21 +1654,16 @@ static void ahci_port_intr(struct ata_port *ap)
else
qc_active = readl(port_mmio + PORT_CMD_ISSUE);
- rc = ata_qc_complete_multiple(ap, qc_active, NULL);
+ rc = ata_qc_complete_multiple(ap, qc_active);
/* while resetting, invalid completions are expected */
if (unlikely(rc < 0 && !resetting)) {
ehi->err_mask |= AC_ERR_HSM;
- ehi->action |= ATA_EH_SOFTRESET;
+ ehi->action |= ATA_EH_RESET;
ata_port_freeze(ap);
}
}
-static void ahci_irq_clear(struct ata_port *ap)
-{
- /* TODO */
-}
-
static irqreturn_t ahci_interrupt(int irq, void *dev_instance)
{
struct ata_host *host = dev_instance;
@@ -1854,6 +1737,15 @@ static unsigned int ahci_qc_issue(struct ata_queued_cmd *qc)
return 0;
}
+static bool ahci_qc_fill_rtf(struct ata_queued_cmd *qc)
+{
+ struct ahci_port_priv *pp = qc->ap->private_data;
+ u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+
+ ata_tf_from_fis(d2h_fis, &qc->result_tf);
+ return true;
+}
+
static void ahci_freeze(struct ata_port *ap)
{
void __iomem *port_mmio = ahci_port_base(ap);
@@ -1886,37 +1778,7 @@ static void ahci_error_handler(struct ata_port *ap)
ahci_start_engine(ap);
}
- /* perform recovery */
- sata_pmp_do_eh(ap, ata_std_prereset, ahci_softreset,
- ahci_hardreset, ahci_postreset,
- sata_pmp_std_prereset, ahci_pmp_softreset,
- sata_pmp_std_hardreset, sata_pmp_std_postreset);
-}
-
-static void ahci_vt8251_error_handler(struct ata_port *ap)
-{
- if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
- /* restart engine */
- ahci_stop_engine(ap);
- ahci_start_engine(ap);
- }
-
- /* perform recovery */
- ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_vt8251_hardreset,
- ahci_postreset);
-}
-
-static void ahci_p5wdh_error_handler(struct ata_port *ap)
-{
- if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
- /* restart engine */
- ahci_stop_engine(ap);
- ahci_start_engine(ap);
- }
-
- /* perform recovery */
- ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_p5wdh_hardreset,
- ahci_postreset);
+ sata_pmp_error_handler(ap);
}
static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
@@ -1961,7 +1823,7 @@ static int ahci_port_resume(struct ata_port *ap)
ahci_power_up(ap);
ahci_start_port(ap);
- if (ap->nr_pmp_links)
+ if (sata_pmp_attached(ap))
ahci_pmp_attach(ap);
else
ahci_pmp_detach(ap);
@@ -2324,7 +2186,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
- void __iomem *port_mmio = ahci_port_base(ap);
ata_port_pbar_desc(ap, AHCI_PCI_BAR, -1, "abar");
ata_port_pbar_desc(ap, AHCI_PCI_BAR,
@@ -2333,12 +2194,8 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* set initial link pm policy */
ap->pm_policy = NOT_AVAILABLE;
- /* standard SATA port setup */
- if (hpriv->port_map & (1 << i))
- ap->ioaddr.cmd_addr = port_mmio;
-
/* disabled/not-implemented port */
- else
+ if (!(hpriv->port_map & (1 << i)))
ap->ops = &ata_dummy_port_ops;
}
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 20534202fc79..47aeccd52fa9 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -95,53 +95,13 @@ static int generic_set_mode(struct ata_link *link, struct ata_device **unused)
}
static struct scsi_host_template generic_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations generic_port_ops = {
- .set_mode = generic_set_mode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_bmdma_port_ops,
.cable_detect = ata_cable_unknown,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_mode = generic_set_mode,
};
static int all_generic_ide; /* Set to claim all devices */
@@ -160,7 +120,6 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
{
u16 command;
static const struct ata_port_info info = {
- .sht = &generic_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -191,9 +150,9 @@ static int ata_generic_init_one(struct pci_dev *dev, const struct pci_device_id
return -ENODEV;
if (dev->vendor == PCI_VENDOR_ID_AL)
- ata_pci_clear_simplex(dev);
+ ata_pci_bmdma_clear_simplex(dev);
- return ata_pci_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &generic_sht, NULL);
}
static struct pci_device_id ata_generic[] = {
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index fae8404254c0..b7c38eeb498f 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -100,13 +100,11 @@ enum {
PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
ICH5_PMR = 0x90, /* port mapping register */
ICH5_PCS = 0x92, /* port control and status */
- PIIX_SCC = 0x0A, /* sub-class code register */
PIIX_SIDPR_BAR = 5,
PIIX_SIDPR_LEN = 16,
PIIX_SIDPR_IDX = 0,
PIIX_SIDPR_DATA = 4,
- PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */
PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */
PIIX_FLAG_SIDPR = (1 << 29), /* SATA idx/data pair regs */
@@ -140,12 +138,11 @@ enum piix_controller_ids {
ich_pata_100, /* ICH up to UDMA 100 */
ich5_sata,
ich6_sata,
- ich6_sata_ahci,
- ich6m_sata_ahci,
- ich8_sata_ahci,
+ ich6m_sata,
+ ich8_sata,
ich8_2port_sata,
- ich8m_apple_sata_ahci, /* locks up on second port enable */
- tolapai_sata_ahci,
+ ich8m_apple_sata, /* locks up on second port enable */
+ tolapai_sata,
piix_pata_vmw, /* PIIX4 for VMware, spurious DMA_ERR */
};
@@ -162,7 +159,7 @@ struct piix_host_priv {
static int piix_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent);
-static void piix_pata_error_handler(struct ata_port *ap);
+static int piix_pata_prereset(struct ata_link *link, unsigned long deadline);
static void piix_set_piomode(struct ata_port *ap, struct ata_device *adev);
static void piix_set_dmamode(struct ata_port *ap, struct ata_device *adev);
static void ich_set_dmamode(struct ata_port *ap, struct ata_device *adev);
@@ -170,7 +167,6 @@ static int ich_pata_cable_detect(struct ata_port *ap);
static u8 piix_vmw_bmdma_status(struct ata_port *ap);
static int piix_sidpr_scr_read(struct ata_port *ap, unsigned int reg, u32 *val);
static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val);
-static void piix_sidpr_error_handler(struct ata_port *ap);
#ifdef CONFIG_PM
static int piix_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
static int piix_pci_device_resume(struct pci_dev *pdev);
@@ -236,25 +232,27 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* 82801FB/FW (ICH6/ICH6W) */
{ 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
/* 82801FR/FRW (ICH6R/ICH6RW) */
- { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
- /* 82801FBM ICH6M (ICH6R with only port 0 and 2 implemented) */
- { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
+ { 0x8086, 0x2652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
+ /* 82801FBM ICH6M (ICH6R with only port 0 and 2 implemented).
+ * Attach iff the controller is in IDE mode. */
+ { 0x8086, 0x2653, PCI_ANY_ID, PCI_ANY_ID,
+ PCI_CLASS_STORAGE_IDE << 8, 0xffff00, ich6m_sata },
/* 82801GB/GR/GH (ICH7, identical to ICH6) */
- { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+ { 0x8086, 0x27c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
/* 2801GBM/GHM (ICH7M, identical to ICH6M) */
- { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata_ahci },
+ { 0x8086, 0x27c4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6m_sata },
/* Enterprise Southbridge 2 (631xESB/632xESB) */
- { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata_ahci },
+ { 0x8086, 0x2680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
/* SATA Controller 1 IDE (ICH8) */
- { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x2820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
/* SATA Controller 2 IDE (ICH8) */
{ 0x8086, 0x2825, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* Mobile SATA Controller IDE (ICH8M) */
- { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x2828, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
/* Mobile SATA Controller IDE (ICH8M), Apple */
- { 0x8086, 0x2828, 0x106b, 0x00a0, 0, 0, ich8m_apple_sata_ahci },
+ { 0x8086, 0x2828, 0x106b, 0x00a0, 0, 0, ich8m_apple_sata },
/* SATA Controller IDE (ICH9) */
- { 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x2920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
/* SATA Controller IDE (ICH9) */
{ 0x8086, 0x2921, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (ICH9) */
@@ -264,15 +262,15 @@ static const struct pci_device_id piix_pci_tbl[] = {
/* SATA Controller IDE (ICH9M) */
{ 0x8086, 0x292d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (ICH9M) */
- { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x292e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
/* SATA Controller IDE (Tolapai) */
- { 0x8086, 0x5028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, tolapai_sata_ahci },
+ { 0x8086, 0x5028, PCI_ANY_ID, PCI_ANY_ID, 0, 0, tolapai_sata },
/* SATA Controller IDE (ICH10) */
- { 0x8086, 0x3a00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x3a00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
/* SATA Controller IDE (ICH10) */
{ 0x8086, 0x3a06, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
/* SATA Controller IDE (ICH10) */
- { 0x8086, 0x3a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata_ahci },
+ { 0x8086, 0x3a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_sata },
/* SATA Controller IDE (ICH10) */
{ 0x8086, 0x3a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich8_2port_sata },
@@ -291,170 +289,37 @@ static struct pci_driver piix_pci_driver = {
};
static struct scsi_host_template piix_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations piix_pata_ops = {
+static struct ata_port_operations piix_pata_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = ata_cable_40wire,
.set_piomode = piix_set_piomode,
.set_dmamode = piix_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = piix_pata_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
+ .prereset = piix_pata_prereset,
+};
- .port_start = ata_port_start,
+static struct ata_port_operations piix_vmw_ops = {
+ .inherits = &piix_pata_ops,
+ .bmdma_status = piix_vmw_bmdma_status,
};
-static const struct ata_port_operations ich_pata_ops = {
- .set_piomode = piix_set_piomode,
- .set_dmamode = ich_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = piix_pata_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+static struct ata_port_operations ich_pata_ops = {
+ .inherits = &piix_pata_ops,
.cable_detect = ich_pata_cable_detect,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
+ .set_dmamode = ich_set_dmamode,
};
-static const struct ata_port_operations piix_sata_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
+static struct ata_port_operations piix_sata_ops = {
+ .inherits = &ata_bmdma_port_ops,
};
-static const struct ata_port_operations piix_vmw_ops = {
- .set_piomode = piix_set_piomode,
- .set_dmamode = piix_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = piix_vmw_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = piix_pata_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
-};
-
-static const struct ata_port_operations piix_sidpr_sata_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
+static struct ata_port_operations piix_sidpr_sata_ops = {
+ .inherits = &piix_sata_ops,
+ .hardreset = sata_std_hardreset,
.scr_read = piix_sidpr_scr_read,
.scr_write = piix_sidpr_scr_write,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = piix_sidpr_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
};
static const struct piix_map_db ich5_map_db = {
@@ -553,12 +418,11 @@ static const struct piix_map_db tolapai_map_db = {
static const struct piix_map_db *piix_map_db_table[] = {
[ich5_sata] = &ich5_map_db,
[ich6_sata] = &ich6_map_db,
- [ich6_sata_ahci] = &ich6_map_db,
- [ich6m_sata_ahci] = &ich6m_map_db,
- [ich8_sata_ahci] = &ich8_map_db,
+ [ich6m_sata] = &ich6m_map_db,
+ [ich8_sata] = &ich8_map_db,
[ich8_2port_sata] = &ich8_2port_map_db,
- [ich8m_apple_sata_ahci] = &ich8m_apple_map_db,
- [tolapai_sata_ahci] = &tolapai_map_db,
+ [ich8m_apple_sata] = &ich8m_apple_map_db,
+ [tolapai_sata] = &tolapai_map_db,
};
static struct ata_port_info piix_port_info[] = {
@@ -624,28 +488,18 @@ static struct ata_port_info piix_port_info[] = {
.port_ops = &piix_sata_ops,
},
- [ich6_sata_ahci] =
- {
- .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI,
- .pio_mask = 0x1f, /* pio0-4 */
- .mwdma_mask = 0x07, /* mwdma0-2 */
- .udma_mask = ATA_UDMA6,
- .port_ops = &piix_sata_ops,
- },
-
- [ich6m_sata_ahci] =
+ [ich6m_sata] =
{
- .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI,
+ .flags = PIIX_SATA_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
- [ich8_sata_ahci] =
+ [ich8_sata] =
{
- .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI |
- PIIX_FLAG_SIDPR,
+ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA6,
@@ -654,27 +508,25 @@ static struct ata_port_info piix_port_info[] = {
[ich8_2port_sata] =
{
- .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI |
- PIIX_FLAG_SIDPR,
+ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
- [tolapai_sata_ahci] =
+ [tolapai_sata] =
{
- .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI,
+ .flags = PIIX_SATA_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA6,
.port_ops = &piix_sata_ops,
},
- [ich8m_apple_sata_ahci] =
+ [ich8m_apple_sata] =
{
- .flags = PIIX_SATA_FLAGS | PIIX_FLAG_AHCI |
- PIIX_FLAG_SIDPR,
+ .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SIDPR,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA6,
@@ -683,7 +535,6 @@ static struct ata_port_info piix_port_info[] = {
[piix_pata_vmw] =
{
- .sht = &piix_sht,
.flags = PIIX_PATA_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
@@ -776,13 +627,7 @@ static int piix_pata_prereset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &piix_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-static void piix_pata_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, piix_pata_prereset, ata_std_softreset, NULL,
- ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -1168,35 +1013,6 @@ static int piix_sidpr_scr_write(struct ata_port *ap, unsigned int reg, u32 val)
return 0;
}
-static int piix_sidpr_hardreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
-{
- const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
- int rc;
-
- /* do hardreset */
- rc = sata_link_hardreset(link, timing, deadline);
- if (rc) {
- ata_link_printk(link, KERN_ERR,
- "COMRESET failed (errno=%d)\n", rc);
- return rc;
- }
-
- /* TODO: phy layer with polling, timeouts, etc. */
- if (ata_link_offline(link)) {
- *class = ATA_DEV_NONE;
- return 0;
- }
-
- return -EAGAIN;
-}
-
-static void piix_sidpr_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
- piix_sidpr_hardreset, ata_std_postreset);
-}
-
#ifdef CONFIG_PM
static int piix_broken_suspend(void)
{
@@ -1633,6 +1449,16 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
if (rc)
return rc;
+ /* ICH6R may be driven by either ata_piix or ahci driver
+ * regardless of BIOS configuration. Make sure AHCI mode is
+ * off.
+ */
+ if (pdev->vendor == PCI_VENDOR_ID_INTEL && pdev->device == 0x2652) {
+ int rc = piix_disable_ahci(pdev);
+ if (rc)
+ return rc;
+ }
+
/* SATA map init can change port_info, do it before prepping host */
hpriv = devm_kzalloc(dev, sizeof(*hpriv), GFP_KERNEL);
if (!hpriv)
@@ -1642,22 +1468,12 @@ 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_prepare_sff_host(pdev, ppi, &host);
+ rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
host->private_data = hpriv;
/* initialize controller */
- if (port_flags & PIIX_FLAG_AHCI) {
- u8 tmp;
- pci_read_config_byte(pdev, PIIX_SCC, &tmp);
- if (tmp == PIIX_AHCI_DEVICE) {
- rc = piix_disable_ahci(pdev);
- if (rc)
- return rc;
- }
- }
-
if (port_flags & ATA_FLAG_SATA) {
piix_init_pcs(host, piix_map_db_table[ent->driver_data]);
piix_init_sidpr(host);
@@ -1686,7 +1502,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev,
}
pci_set_master(pdev);
- return ata_pci_activate_sff_host(host, ata_interrupt, &piix_sht);
+ return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht);
}
static int __init piix_init(void)
diff --git a/drivers/ata/libata-acpi.c b/drivers/ata/libata-acpi.c
index bf98a566adac..8c1cfc645c85 100644
--- a/drivers/ata/libata-acpi.c
+++ b/drivers/ata/libata-acpi.c
@@ -77,7 +77,7 @@ void ata_acpi_associate_sata_port(struct ata_port *ap)
{
WARN_ON(!(ap->flags & ATA_FLAG_ACPI_SATA));
- if (!ap->nr_pmp_links) {
+ if (!sata_pmp_attached(ap)) {
acpi_integer adr = SATA_ADR(ap->port_no, NO_PORT_MULT);
ap->link.device->acpi_handle =
@@ -839,7 +839,8 @@ void ata_acpi_on_resume(struct ata_port *ap)
*/
ata_link_for_each_dev(dev, &ap->link) {
ata_acpi_clear_gtf(dev);
- if (ata_dev_get_GTF(dev, NULL) >= 0)
+ if (ata_dev_enabled(dev) &&
+ ata_dev_get_GTF(dev, NULL) >= 0)
dev->flags |= ATA_DFLAG_ACPI_PENDING;
}
} else {
@@ -849,7 +850,8 @@ void ata_acpi_on_resume(struct ata_port *ap)
*/
ata_link_for_each_dev(dev, &ap->link) {
ata_acpi_clear_gtf(dev);
- dev->flags |= ATA_DFLAG_ACPI_PENDING;
+ if (ata_dev_enabled(dev))
+ dev->flags |= ATA_DFLAG_ACPI_PENDING;
}
}
}
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index be95fdb69726..733eb94d055e 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -46,7 +46,6 @@
#include <linux/init.h>
#include <linux/list.h>
#include <linux/mm.h>
-#include <linux/highmem.h>
#include <linux/spinlock.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
@@ -74,6 +73,19 @@ const unsigned long sata_deb_timing_normal[] = { 5, 100, 2000 };
const unsigned long sata_deb_timing_hotplug[] = { 25, 500, 2000 };
const unsigned long sata_deb_timing_long[] = { 100, 2000, 5000 };
+const struct ata_port_operations ata_base_port_ops = {
+ .prereset = ata_std_prereset,
+ .postreset = ata_std_postreset,
+ .error_handler = ata_std_error_handler,
+};
+
+const struct ata_port_operations sata_port_ops = {
+ .inherits = &ata_base_port_ops,
+
+ .qc_defer = ata_std_qc_defer,
+ .hardreset = sata_std_hardreset,
+};
+
static unsigned int ata_dev_init_params(struct ata_device *dev,
u16 heads, u16 sectors);
static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
@@ -1043,50 +1055,6 @@ static void ata_lpm_disable(struct ata_host *host)
}
#endif /* CONFIG_PM */
-
-/**
- * ata_devchk - PATA device presence detection
- * @ap: ATA channel to examine
- * @device: Device to examine (starting at zero)
- *
- * This technique was originally described in
- * Hale Landis's ATADRVR (www.ata-atapi.com), and
- * later found its way into the ATA/ATAPI spec.
- *
- * Write a pattern to the ATA shadow registers,
- * and if a device is present, it will respond by
- * correctly storing and echoing back the
- * ATA shadow register contents.
- *
- * LOCKING:
- * caller.
- */
-
-static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
-{
- struct ata_ioports *ioaddr = &ap->ioaddr;
- u8 nsect, lbal;
-
- ap->ops->dev_select(ap, device);
-
- iowrite8(0x55, ioaddr->nsect_addr);
- iowrite8(0xaa, ioaddr->lbal_addr);
-
- iowrite8(0xaa, ioaddr->nsect_addr);
- iowrite8(0x55, ioaddr->lbal_addr);
-
- iowrite8(0x55, ioaddr->nsect_addr);
- iowrite8(0xaa, ioaddr->lbal_addr);
-
- nsect = ioread8(ioaddr->nsect_addr);
- lbal = ioread8(ioaddr->lbal_addr);
-
- if ((nsect == 0x55) && (lbal == 0xaa))
- return 1; /* we found a device */
-
- return 0; /* nothing found */
-}
-
/**
* ata_dev_classify - determine device type based on ATA-spec signature
* @tf: ATA taskfile register set for device to be identified
@@ -1147,75 +1115,6 @@ unsigned int ata_dev_classify(const struct ata_taskfile *tf)
}
/**
- * ata_dev_try_classify - Parse returned ATA device signature
- * @dev: ATA device to classify (starting at zero)
- * @present: device seems present
- * @r_err: Value of error register on completion
- *
- * After an event -- SRST, E.D.D., or SATA COMRESET -- occurs,
- * an ATA/ATAPI-defined set of values is placed in the ATA
- * shadow registers, indicating the results of device detection
- * and diagnostics.
- *
- * Select the ATA device, and read the values from the ATA shadow
- * registers. Then parse according to the Error register value,
- * and the spec-defined values examined by ata_dev_classify().
- *
- * LOCKING:
- * caller.
- *
- * RETURNS:
- * Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE.
- */
-unsigned int ata_dev_try_classify(struct ata_device *dev, int present,
- u8 *r_err)
-{
- struct ata_port *ap = dev->link->ap;
- struct ata_taskfile tf;
- unsigned int class;
- u8 err;
-
- ap->ops->dev_select(ap, dev->devno);
-
- memset(&tf, 0, sizeof(tf));
-
- ap->ops->tf_read(ap, &tf);
- err = tf.feature;
- if (r_err)
- *r_err = err;
-
- /* see if device passed diags: continue and warn later */
- if (err == 0)
- /* diagnostic fail : do nothing _YET_ */
- dev->horkage |= ATA_HORKAGE_DIAGNOSTIC;
- else if (err == 1)
- /* do nothing */ ;
- else if ((dev->devno == 0) && (err == 0x81))
- /* do nothing */ ;
- else
- return ATA_DEV_NONE;
-
- /* determine if device is ATA or ATAPI */
- class = ata_dev_classify(&tf);
-
- if (class == ATA_DEV_UNKNOWN) {
- /* If the device failed diagnostic, it's likely to
- * have reported incorrect device signature too.
- * Assume ATA device if the device seems present but
- * device signature is invalid with diagnostic
- * failure.
- */
- if (present && (dev->horkage & ATA_HORKAGE_DIAGNOSTIC))
- class = ATA_DEV_ATA;
- else
- class = ATA_DEV_NONE;
- } else if ((class == ATA_DEV_ATA) && (ata_chk_status(ap) == 0))
- class = ATA_DEV_NONE;
-
- return class;
-}
-
-/**
* ata_id_string - Convert IDENTIFY DEVICE page into string
* @id: IDENTIFY DEVICE results we will examine
* @s: string into which data is output
@@ -1293,7 +1192,7 @@ static u64 ata_id_n_sectors(const u16 *id)
}
}
-static u64 ata_tf_to_lba48(struct ata_taskfile *tf)
+u64 ata_tf_to_lba48(const struct ata_taskfile *tf)
{
u64 sectors = 0;
@@ -1304,10 +1203,10 @@ static u64 ata_tf_to_lba48(struct ata_taskfile *tf)
sectors |= (tf->lbam & 0xff) << 8;
sectors |= (tf->lbal & 0xff);
- return ++sectors;
+ return sectors;
}
-static u64 ata_tf_to_lba(struct ata_taskfile *tf)
+u64 ata_tf_to_lba(const struct ata_taskfile *tf)
{
u64 sectors = 0;
@@ -1316,7 +1215,7 @@ static u64 ata_tf_to_lba(struct ata_taskfile *tf)
sectors |= (tf->lbam & 0xff) << 8;
sectors |= (tf->lbal & 0xff);
- return ++sectors;
+ return sectors;
}
/**
@@ -1361,9 +1260,9 @@ static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
}
if (lba48)
- *max_sectors = ata_tf_to_lba48(&tf);
+ *max_sectors = ata_tf_to_lba48(&tf) + 1;
else
- *max_sectors = ata_tf_to_lba(&tf);
+ *max_sectors = ata_tf_to_lba(&tf) + 1;
if (dev->horkage & ATA_HORKAGE_HPA_SIZE)
(*max_sectors)--;
return 0;
@@ -1523,89 +1422,6 @@ static int ata_hpa_resize(struct ata_device *dev)
}
/**
- * ata_noop_dev_select - Select device 0/1 on ATA bus
- * @ap: ATA channel to manipulate
- * @device: ATA device (numbered from zero) to select
- *
- * This function performs no actual function.
- *
- * May be used as the dev_select() entry in ata_port_operations.
- *
- * LOCKING:
- * caller.
- */
-void ata_noop_dev_select(struct ata_port *ap, unsigned int device)
-{
-}
-
-
-/**
- * ata_std_dev_select - Select device 0/1 on ATA bus
- * @ap: ATA channel to manipulate
- * @device: ATA device (numbered from zero) to select
- *
- * Use the method defined in the ATA specification to
- * make either device 0, or device 1, active on the
- * ATA channel. Works with both PIO and MMIO.
- *
- * May be used as the dev_select() entry in ata_port_operations.
- *
- * LOCKING:
- * caller.
- */
-
-void ata_std_dev_select(struct ata_port *ap, unsigned int device)
-{
- u8 tmp;
-
- if (device == 0)
- tmp = ATA_DEVICE_OBS;
- else
- tmp = ATA_DEVICE_OBS | ATA_DEV1;
-
- iowrite8(tmp, ap->ioaddr.device_addr);
- ata_pause(ap); /* needed; also flushes, for mmio */
-}
-
-/**
- * ata_dev_select - Select device 0/1 on ATA bus
- * @ap: ATA channel to manipulate
- * @device: ATA device (numbered from zero) to select
- * @wait: non-zero to wait for Status register BSY bit to clear
- * @can_sleep: non-zero if context allows sleeping
- *
- * Use the method defined in the ATA specification to
- * make either device 0, or device 1, active on the
- * ATA channel.
- *
- * This is a high-level version of ata_std_dev_select(),
- * which additionally provides the services of inserting
- * the proper pauses and status polling, where needed.
- *
- * LOCKING:
- * caller.
- */
-
-void ata_dev_select(struct ata_port *ap, unsigned int device,
- unsigned int wait, unsigned int can_sleep)
-{
- if (ata_msg_probe(ap))
- ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, "
- "device %u, wait %u\n", device, wait);
-
- if (wait)
- ata_wait_idle(ap);
-
- ap->ops->dev_select(ap, device);
-
- if (wait) {
- if (can_sleep && ap->link.device[device].class == ATA_DEV_ATAPI)
- msleep(150);
- ata_wait_idle(ap);
- }
-}
-
-/**
* ata_dump_id - IDENTIFY DEVICE info debugging output
* @id: IDENTIFY DEVICE page to dump
*
@@ -1732,8 +1548,7 @@ unsigned long ata_id_xfermask(const u16 *id)
* LOCKING:
* Inherited from caller.
*/
-static void ata_pio_queue_task(struct ata_port *ap, void *data,
- unsigned long delay)
+void ata_pio_queue_task(struct ata_port *ap, void *data, unsigned long delay)
{
ap->port_task_data = data;
@@ -2097,7 +1912,6 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
if (ata_msg_ctl(ap))
ata_dev_printk(dev, KERN_DEBUG, "%s: ENTER\n", __func__);
- ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
retry:
ata_tf_init(dev, &tf);
@@ -2464,7 +2278,7 @@ int ata_dev_configure(struct ata_device *dev)
* changed notifications and ATAPI ANs.
*/
if ((ap->flags & ATA_FLAG_AN) && ata_id_has_atapi_AN(id) &&
- (!ap->nr_pmp_links ||
+ (!sata_pmp_attached(ap) ||
sata_scr_read(&ap->link, SCR_NOTIFICATION, &sntf) == 0)) {
unsigned int err_mask;
@@ -2558,9 +2372,6 @@ int ata_dev_configure(struct ata_device *dev)
}
}
- if (ata_msg_probe(ap))
- ata_dev_printk(dev, KERN_DEBUG, "%s: EXIT, drv_stat = 0x%x\n",
- __func__, ata_chk_status(ap));
return 0;
err_out_nosup:
@@ -3321,16 +3132,21 @@ static int ata_dev_set_mode(struct ata_device *dev)
if (rc)
return rc;
- /* Old CFA may refuse this command, which is just fine */
- if (dev->xfer_shift == ATA_SHIFT_PIO && ata_id_is_cfa(dev->id))
- ign_dev_err = 1;
-
- /* Some very old devices and some bad newer ones fail any kind of
- SET_XFERMODE request but support PIO0-2 timings and no IORDY */
- if (dev->xfer_shift == ATA_SHIFT_PIO && !ata_id_has_iordy(dev->id) &&
- dev->pio_mode <= XFER_PIO_2)
- ign_dev_err = 1;
-
+ if (dev->xfer_shift == ATA_SHIFT_PIO) {
+ /* Old CFA may refuse this command, which is just fine */
+ if (ata_id_is_cfa(dev->id))
+ ign_dev_err = 1;
+ /* Catch several broken garbage emulations plus some pre
+ ATA devices */
+ if (ata_id_major_version(dev->id) == 0 &&
+ dev->pio_mode <= XFER_PIO_2)
+ ign_dev_err = 1;
+ /* Some very old devices and some bad newer ones fail
+ any kind of SET_XFERMODE request but support PIO0-2
+ timings and no IORDY */
+ if (!ata_id_has_iordy(dev->id) && dev->pio_mode <= XFER_PIO_2)
+ ign_dev_err = 1;
+ }
/* Early MWDMA devices do DMA but don't allow DMA mode setting.
Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */
if (dev->xfer_shift == ATA_SHIFT_MWDMA &&
@@ -3474,170 +3290,73 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev)
}
/**
- * ata_tf_to_host - issue ATA taskfile to host controller
- * @ap: port to which command is being issued
- * @tf: ATA taskfile register set
- *
- * Issues ATA taskfile register set to ATA host controller,
- * with proper synchronization with interrupt handler and
- * other threads.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-
-static inline void ata_tf_to_host(struct ata_port *ap,
- const struct ata_taskfile *tf)
-{
- ap->ops->tf_load(ap, tf);
- ap->ops->exec_command(ap, tf);
-}
-
-/**
- * ata_busy_sleep - sleep until BSY clears, or timeout
- * @ap: port containing status register to be polled
- * @tmout_pat: impatience timeout
- * @tmout: overall timeout
- *
- * Sleep until ATA Status register bit BSY clears,
- * or a timeout occurs.
- *
- * LOCKING:
- * Kernel thread context (may sleep).
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-int ata_busy_sleep(struct ata_port *ap,
- unsigned long tmout_pat, unsigned long tmout)
-{
- unsigned long timer_start, timeout;
- u8 status;
-
- status = ata_busy_wait(ap, ATA_BUSY, 300);
- timer_start = jiffies;
- timeout = timer_start + tmout_pat;
- while (status != 0xff && (status & ATA_BUSY) &&
- time_before(jiffies, timeout)) {
- msleep(50);
- status = ata_busy_wait(ap, ATA_BUSY, 3);
- }
-
- if (status != 0xff && (status & ATA_BUSY))
- ata_port_printk(ap, KERN_WARNING,
- "port is slow to respond, please be patient "
- "(Status 0x%x)\n", status);
-
- timeout = timer_start + tmout;
- while (status != 0xff && (status & ATA_BUSY) &&
- time_before(jiffies, timeout)) {
- msleep(50);
- status = ata_chk_status(ap);
- }
-
- if (status == 0xff)
- return -ENODEV;
-
- if (status & ATA_BUSY) {
- ata_port_printk(ap, KERN_ERR, "port failed to respond "
- "(%lu secs, Status 0x%x)\n",
- tmout / HZ, status);
- return -EBUSY;
- }
-
- return 0;
-}
-
-/**
- * ata_wait_after_reset - wait before checking status after reset
- * @ap: port containing status register to be polled
+ * ata_wait_ready - wait for link to become ready
+ * @link: link to be waited on
* @deadline: deadline jiffies for the operation
+ * @check_ready: callback to check link readiness
*
- * After reset, we need to pause a while before reading status.
- * Also, certain combination of controller and device report 0xff
- * for some duration (e.g. until SATA PHY is up and running)
- * which is interpreted as empty port in ATA world. This
- * function also waits for such devices to get out of 0xff
- * status.
+ * Wait for @link to become ready. @check_ready should return
+ * positive number if @link is ready, 0 if it isn't, -ENODEV if
+ * link doesn't seem to be occupied, other errno for other error
+ * conditions.
*
- * LOCKING:
- * Kernel thread context (may sleep).
- */
-void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline)
-{
- unsigned long until = jiffies + ATA_TMOUT_FF_WAIT;
-
- if (time_before(until, deadline))
- deadline = until;
-
- /* Spec mandates ">= 2ms" before checking status. We wait
- * 150ms, because that was the magic delay used for ATAPI
- * devices in Hale Landis's ATADRVR, for the period of time
- * between when the ATA command register is written, and then
- * status is checked. Because waiting for "a while" before
- * checking status is fine, post SRST, we perform this magic
- * delay here as well.
- *
- * Old drivers/ide uses the 2mS rule and then waits for ready.
- */
- msleep(150);
-
- /* Wait for 0xff to clear. Some SATA devices take a long time
- * to clear 0xff after reset. For example, HHD424020F7SV00
- * iVDR needs >= 800ms while. Quantum GoVault needs even more
- * than that.
- *
- * Note that some PATA controllers (pata_ali) explode if
- * status register is read more than once when there's no
- * device attached.
- */
- if (ap->flags & ATA_FLAG_SATA) {
- while (1) {
- u8 status = ata_chk_status(ap);
-
- if (status != 0xff || time_after(jiffies, deadline))
- return;
-
- msleep(50);
- }
- }
-}
-
-/**
- * ata_wait_ready - sleep until BSY clears, or timeout
- * @ap: port containing status register to be polled
- * @deadline: deadline jiffies for the operation
- *
- * Sleep until ATA Status register bit BSY clears, or timeout
- * occurs.
+ * Transient -ENODEV conditions are allowed for
+ * ATA_TMOUT_FF_WAIT.
*
* LOCKING:
- * Kernel thread context (may sleep).
+ * EH context.
*
* RETURNS:
- * 0 on success, -errno otherwise.
+ * 0 if @linke is ready before @deadline; otherwise, -errno.
*/
-int ata_wait_ready(struct ata_port *ap, unsigned long deadline)
+int ata_wait_ready(struct ata_link *link, unsigned long deadline,
+ int (*check_ready)(struct ata_link *link))
{
unsigned long start = jiffies;
+ unsigned long nodev_deadline = start + ATA_TMOUT_FF_WAIT;
int warned = 0;
+ if (time_after(nodev_deadline, deadline))
+ nodev_deadline = deadline;
+
while (1) {
- u8 status = ata_chk_status(ap);
unsigned long now = jiffies;
+ int ready, tmp;
- if (!(status & ATA_BUSY))
+ ready = tmp = check_ready(link);
+ if (ready > 0)
return 0;
- if (!ata_link_online(&ap->link) && status == 0xff)
- return -ENODEV;
+
+ /* -ENODEV could be transient. Ignore -ENODEV if link
+ * is online. Also, some SATA devices take a long
+ * time to clear 0xff after reset. For example,
+ * HHD424020F7SV00 iVDR needs >= 800ms while Quantum
+ * GoVault needs even more than that. Wait for
+ * ATA_TMOUT_FF_WAIT on -ENODEV if link isn't offline.
+ *
+ * Note that some PATA controllers (pata_ali) explode
+ * if status register is read more than once when
+ * there's no device attached.
+ */
+ if (ready == -ENODEV) {
+ if (ata_link_online(link))
+ ready = 0;
+ else if ((link->ap->flags & ATA_FLAG_SATA) &&
+ !ata_link_offline(link) &&
+ time_before(now, nodev_deadline))
+ ready = 0;
+ }
+
+ if (ready)
+ return ready;
if (time_after(now, deadline))
return -EBUSY;
if (!warned && time_after(now, start + 5 * HZ) &&
(deadline - now > 3 * HZ)) {
- ata_port_printk(ap, KERN_WARNING,
- "port is slow to respond, please be patient "
- "(Status 0x%x)\n", status);
+ ata_link_printk(link, KERN_WARNING,
+ "link is slow to respond, please be patient "
+ "(ready=%d)\n", tmp);
warned = 1;
}
@@ -3645,179 +3364,26 @@ int ata_wait_ready(struct ata_port *ap, unsigned long deadline)
}
}
-static int ata_bus_post_reset(struct ata_port *ap, unsigned int devmask,
- unsigned long deadline)
-{
- struct ata_ioports *ioaddr = &ap->ioaddr;
- unsigned int dev0 = devmask & (1 << 0);
- unsigned int dev1 = devmask & (1 << 1);
- int rc, ret = 0;
-
- /* if device 0 was found in ata_devchk, wait for its
- * BSY bit to clear
- */
- if (dev0) {
- rc = ata_wait_ready(ap, deadline);
- if (rc) {
- if (rc != -ENODEV)
- return rc;
- ret = rc;
- }
- }
-
- /* if device 1 was found in ata_devchk, wait for register
- * access briefly, then wait for BSY to clear.
- */
- if (dev1) {
- int i;
-
- ap->ops->dev_select(ap, 1);
-
- /* Wait for register access. Some ATAPI devices fail
- * to set nsect/lbal after reset, so don't waste too
- * much time on it. We're gonna wait for !BSY anyway.
- */
- for (i = 0; i < 2; i++) {
- u8 nsect, lbal;
-
- nsect = ioread8(ioaddr->nsect_addr);
- lbal = ioread8(ioaddr->lbal_addr);
- if ((nsect == 1) && (lbal == 1))
- break;
- msleep(50); /* give drive a breather */
- }
-
- rc = ata_wait_ready(ap, deadline);
- if (rc) {
- if (rc != -ENODEV)
- return rc;
- ret = rc;
- }
- }
-
- /* is all this really necessary? */
- ap->ops->dev_select(ap, 0);
- if (dev1)
- ap->ops->dev_select(ap, 1);
- if (dev0)
- ap->ops->dev_select(ap, 0);
-
- return ret;
-}
-
-static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
- unsigned long deadline)
-{
- struct ata_ioports *ioaddr = &ap->ioaddr;
-
- DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
-
- /* software reset. causes dev0 to be selected */
- iowrite8(ap->ctl, ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
- iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
- udelay(20); /* FIXME: flush */
- iowrite8(ap->ctl, ioaddr->ctl_addr);
-
- /* wait a while before checking status */
- ata_wait_after_reset(ap, deadline);
-
- /* Before we perform post reset processing we want to see if
- * the bus shows 0xFF because the odd clown forgets the D7
- * pulldown resistor.
- */
- if (ata_chk_status(ap) == 0xFF)
- return -ENODEV;
-
- return ata_bus_post_reset(ap, devmask, deadline);
-}
-
/**
- * ata_bus_reset - reset host port and associated ATA channel
- * @ap: port to reset
+ * ata_wait_after_reset - wait for link to become ready after reset
+ * @link: link to be waited on
+ * @deadline: deadline jiffies for the operation
+ * @check_ready: callback to check link readiness
*
- * 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.
+ * Wait for @link to become ready after reset.
*
* LOCKING:
- * PCI/etc. bus probe sem.
- * Obtains host lock.
+ * EH context.
*
- * SIDE EFFECTS:
- * Sets ATA_FLAG_DISABLED if bus reset fails.
+ * RETURNS:
+ * 0 if @linke is ready before @deadline; otherwise, -errno.
*/
-
-void ata_bus_reset(struct ata_port *ap)
+extern int ata_wait_after_reset(struct ata_link *link, unsigned long deadline,
+ int (*check_ready)(struct ata_link *link))
{
- 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);
+ msleep(ATA_WAIT_AFTER_RESET_MSECS);
- /* select device 0 again */
- ap->ops->dev_select(ap, 0);
-
- /* issue bus reset */
- if (ap->flags & ATA_FLAG_SRST) {
- rc = ata_bus_softreset(ap, devmask, jiffies + 40 * HZ);
- if (rc && rc != -ENODEV)
- goto err_out;
- }
-
- /*
- * determine by signature whether we have ATA or ATAPI devices
- */
- device[0].class = ata_dev_try_classify(&device[0], dev0, &err);
- if ((slave_possible) && (err != 0x81))
- device[1].class = ata_dev_try_classify(&device[1], dev1, &err);
-
- /* is double-select really necessary? */
- if (device[1].class != ATA_DEV_NONE)
- ap->ops->dev_select(ap, 1);
- if (device[0].class != ATA_DEV_NONE)
- ap->ops->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:
- ata_port_printk(ap, KERN_ERR, "disabling port\n");
- ata_port_disable(ap);
-
- DPRINTK("EXIT\n");
+ return ata_wait_ready(link, deadline, check_ready);
}
/**
@@ -3906,7 +3472,7 @@ int sata_link_debounce(struct ata_link *link, const unsigned long *params,
int sata_link_resume(struct ata_link *link, const unsigned long *params,
unsigned long deadline)
{
- u32 scontrol;
+ u32 scontrol, serror;
int rc;
if ((rc = sata_scr_read(link, SCR_CONTROL, &scontrol)))
@@ -3922,7 +3488,25 @@ int sata_link_resume(struct ata_link *link, const unsigned long *params,
*/
msleep(200);
- return sata_link_debounce(link, params, deadline);
+ if ((rc = sata_link_debounce(link, params, deadline)))
+ return rc;
+
+ /* Clear SError. PMP and some host PHYs require this to
+ * operate and clearing should be done before checking PHY
+ * online status to avoid race condition (hotplugging between
+ * link resume and status check).
+ */
+ if (!(rc = sata_scr_read(link, SCR_ERROR, &serror)))
+ rc = sata_scr_write(link, SCR_ERROR, serror);
+ if (rc == 0 || rc == -EINVAL) {
+ unsigned long flags;
+
+ spin_lock_irqsave(link->ap->lock, flags);
+ link->eh_info.serror = 0;
+ spin_unlock_irqrestore(link->ap->lock, flags);
+ rc = 0;
+ }
+ return rc;
}
/**
@@ -3949,17 +3533,6 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
const unsigned long *timing = sata_ehc_deb_timing(ehc);
int rc;
- /* handle link resume */
- if ((ehc->i.flags & ATA_EHI_RESUME_LINK) &&
- (link->flags & ATA_LFLAG_HRST_TO_RESUME))
- ehc->i.action |= ATA_EH_HARDRESET;
-
- /* Some PMPs don't work with only SRST, force hardreset if PMP
- * is supported.
- */
- if (ap->flags & ATA_FLAG_PMP)
- ehc->i.action |= ATA_EH_HARDRESET;
-
/* if we're about to do hardreset, nothing more to do */
if (ehc->i.action & ATA_EH_HARDRESET)
return 0;
@@ -3973,88 +3546,30 @@ int ata_std_prereset(struct ata_link *link, unsigned long deadline)
"link for reset (errno=%d)\n", rc);
}
- /* Wait for !BSY if the controller can wait for the first D2H
- * Reg FIS and we don't know that no device is attached.
- */
- if (!(link->flags & ATA_LFLAG_SKIP_D2H_BSY) && !ata_link_offline(link)) {
- rc = ata_wait_ready(ap, deadline);
- if (rc && rc != -ENODEV) {
- ata_link_printk(link, KERN_WARNING, "device not ready "
- "(errno=%d), forcing hardreset\n", rc);
- ehc->i.action |= ATA_EH_HARDRESET;
- }
- }
+ /* no point in trying softreset on offline link */
+ if (ata_link_offline(link))
+ ehc->i.action &= ~ATA_EH_SOFTRESET;
return 0;
}
/**
- * ata_std_softreset - reset host port via ATA SRST
- * @link: ATA link to reset
- * @classes: resulting classes of attached devices
- * @deadline: deadline jiffies for the operation
- *
- * Reset host port using ATA SRST.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-int ata_std_softreset(struct ata_link *link, unsigned int *classes,
- unsigned long deadline)
-{
- struct ata_port *ap = link->ap;
- unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
- unsigned int devmask = 0;
- int rc;
- u8 err;
-
- DPRINTK("ENTER\n");
-
- if (ata_link_offline(link)) {
- classes[0] = ATA_DEV_NONE;
- goto out;
- }
-
- /* determine if device 0/1 are present */
- if (ata_devchk(ap, 0))
- devmask |= (1 << 0);
- if (slave_possible && ata_devchk(ap, 1))
- devmask |= (1 << 1);
-
- /* select device 0 again */
- ap->ops->dev_select(ap, 0);
-
- /* issue bus reset */
- DPRINTK("about to softreset, devmask=%x\n", devmask);
- rc = ata_bus_softreset(ap, devmask, deadline);
- /* if link is occupied, -ENODEV too is an error */
- if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
- ata_link_printk(link, KERN_ERR, "SRST failed (errno=%d)\n", rc);
- return rc;
- }
-
- /* determine by signature whether we have ATA or ATAPI devices */
- classes[0] = ata_dev_try_classify(&link->device[0],
- devmask & (1 << 0), &err);
- if (slave_possible && err != 0x81)
- classes[1] = ata_dev_try_classify(&link->device[1],
- devmask & (1 << 1), &err);
-
- out:
- DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
- return 0;
-}
-
-/**
* sata_link_hardreset - reset link via SATA phy reset
* @link: link to reset
* @timing: timing parameters { interval, duratinon, timeout } in msec
* @deadline: deadline jiffies for the operation
+ * @online: optional out parameter indicating link onlineness
+ * @check_ready: optional callback to check link readiness
*
* SATA phy-reset @link using DET bits of SControl register.
+ * After hardreset, link readiness is waited upon using
+ * ata_wait_ready() if @check_ready is specified. LLDs are
+ * allowed to not specify @check_ready and wait itself after this
+ * function returns. Device classification is LLD's
+ * responsibility.
+ *
+ * *@online is set to one iff reset succeeded and @link is online
+ * after reset.
*
* LOCKING:
* Kernel thread context (may sleep)
@@ -4063,13 +3578,17 @@ int ata_std_softreset(struct ata_link *link, unsigned int *classes,
* 0 on success, -errno otherwise.
*/
int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
- unsigned long deadline)
+ unsigned long deadline,
+ bool *online, int (*check_ready)(struct ata_link *))
{
u32 scontrol;
int rc;
DPRINTK("ENTER\n");
+ if (online)
+ *online = false;
+
if (sata_set_spd_needed(link)) {
/* SATA spec says nothing about how to reconfigure
* spd. To be on the safe side, turn off phy during
@@ -4103,77 +3622,69 @@ int sata_link_hardreset(struct ata_link *link, const unsigned long *timing,
/* bring link back */
rc = sata_link_resume(link, timing, deadline);
+ if (rc)
+ goto out;
+ /* if link is offline nothing more to do */
+ if (ata_link_offline(link))
+ goto out;
+
+ /* Link is online. From this point, -ENODEV too is an error. */
+ if (online)
+ *online = true;
+
+ if (sata_pmp_supported(link->ap) && ata_is_host_link(link)) {
+ /* If PMP is supported, we have to do follow-up SRST.
+ * Some PMPs don't send D2H Reg FIS after hardreset if
+ * the first port is empty. Wait only for
+ * ATA_TMOUT_PMP_SRST_WAIT.
+ */
+ if (check_ready) {
+ unsigned long pmp_deadline;
+
+ pmp_deadline = jiffies + ATA_TMOUT_PMP_SRST_WAIT;
+ if (time_after(pmp_deadline, deadline))
+ pmp_deadline = deadline;
+ ata_wait_ready(link, pmp_deadline, check_ready);
+ }
+ rc = -EAGAIN;
+ goto out;
+ }
+
+ rc = 0;
+ if (check_ready)
+ rc = ata_wait_ready(link, deadline, check_ready);
out:
+ if (rc && rc != -EAGAIN)
+ ata_link_printk(link, KERN_ERR,
+ "COMRESET failed (errno=%d)\n", rc);
DPRINTK("EXIT, rc=%d\n", rc);
return rc;
}
/**
- * sata_std_hardreset - reset host port via SATA phy reset
+ * sata_std_hardreset - COMRESET w/o waiting or classification
* @link: link to reset
* @class: resulting class of attached device
* @deadline: deadline jiffies for the operation
*
- * SATA phy-reset host port using DET bits of SControl register,
- * wait for !BSY and classify the attached device.
+ * Standard SATA COMRESET w/o waiting or classification.
*
* LOCKING:
* Kernel thread context (may sleep)
*
* RETURNS:
- * 0 on success, -errno otherwise.
+ * 0 if link offline, -EAGAIN if link online, -errno on errors.
*/
int sata_std_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
- struct ata_port *ap = link->ap;
const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
+ bool online;
int rc;
- DPRINTK("ENTER\n");
-
/* do hardreset */
- rc = sata_link_hardreset(link, timing, deadline);
- if (rc) {
- ata_link_printk(link, KERN_ERR,
- "COMRESET failed (errno=%d)\n", rc);
- return rc;
- }
-
- /* TODO: phy layer with polling, timeouts, etc. */
- if (ata_link_offline(link)) {
- *class = ATA_DEV_NONE;
- DPRINTK("EXIT, link offline\n");
- return 0;
- }
-
- /* wait a while before checking status */
- ata_wait_after_reset(ap, deadline);
-
- /* If PMP is supported, we have to do follow-up SRST. Note
- * that some PMPs don't send D2H Reg FIS after hardreset at
- * all if the first port is empty. Wait for it just for a
- * second and request follow-up SRST.
- */
- if (ap->flags & ATA_FLAG_PMP) {
- ata_wait_ready(ap, jiffies + HZ);
- return -EAGAIN;
- }
-
- rc = ata_wait_ready(ap, deadline);
- /* link occupied, -ENODEV too is an error */
- if (rc) {
- ata_link_printk(link, KERN_ERR,
- "COMRESET failed (errno=%d)\n", rc);
- return rc;
- }
-
- ap->ops->dev_select(ap, 0); /* probably unnecessary */
-
- *class = ata_dev_try_classify(link->device, 1, NULL);
-
- DPRINTK("EXIT, class=%u\n", *class);
- return 0;
+ rc = sata_link_hardreset(link, timing, deadline, &online, NULL);
+ return online ? -EAGAIN : rc;
}
/**
@@ -4190,35 +3701,11 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class,
*/
void ata_std_postreset(struct ata_link *link, unsigned int *classes)
{
- struct ata_port *ap = link->ap;
- u32 serror;
-
DPRINTK("ENTER\n");
/* print link status */
sata_print_link_status(link);
- /* clear SError */
- if (sata_scr_read(link, SCR_ERROR, &serror) == 0)
- sata_scr_write(link, SCR_ERROR, serror);
- link->eh_info.serror = 0;
-
- /* is double-select really necessary? */
- if (classes[0] != ATA_DEV_NONE)
- ap->ops->dev_select(ap, 1);
- if (classes[1] != ATA_DEV_NONE)
- ap->ops->dev_select(ap, 0);
-
- /* bail out if no device is present */
- if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
- DPRINTK("EXIT, no device\n");
- return;
- }
-
- /* set up device control */
- if (ap->ioaddr.ctl_addr)
- iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
-
DPRINTK("EXIT\n");
}
@@ -4528,6 +4015,53 @@ static int ata_is_40wire(struct ata_device *dev)
}
/**
+ * cable_is_40wire - 40/80/SATA decider
+ * @ap: port to consider
+ *
+ * This function encapsulates the policy for speed management
+ * in one place. At the moment we don't cache the result but
+ * there is a good case for setting ap->cbl to the result when
+ * we are called with unknown cables (and figuring out if it
+ * impacts hotplug at all).
+ *
+ * Return 1 if the cable appears to be 40 wire.
+ */
+
+static int cable_is_40wire(struct ata_port *ap)
+{
+ struct ata_link *link;
+ struct ata_device *dev;
+
+ /* If the controller thinks we are 40 wire, we are */
+ if (ap->cbl == ATA_CBL_PATA40)
+ return 1;
+ /* If the controller thinks we are 80 wire, we are */
+ if (ap->cbl == ATA_CBL_PATA80 || ap->cbl == ATA_CBL_SATA)
+ return 0;
+ /* If the system is known to be 40 wire short cable (eg laptop),
+ then we allow 80 wire modes even if the drive isn't sure */
+ if (ap->cbl == ATA_CBL_PATA40_SHORT)
+ return 0;
+ /* If the controller doesn't know we scan
+
+ - Note: We look for all 40 wire detects at this point.
+ Any 80 wire detect is taken to be 80 wire cable
+ because
+ - In many setups only the one drive (slave if present)
+ will give a valid detect
+ - If you have a non detect capable drive you don't
+ want it to colour the choice
+ */
+ ata_port_for_each_link(link, ap) {
+ ata_link_for_each_dev(dev, link) {
+ if (!ata_is_40wire(dev))
+ return 0;
+ }
+ }
+ return 1;
+}
+
+/**
* ata_dev_xfermask - Compute supported xfermask of the given device
* @dev: Device to compute xfermask for
*
@@ -4595,10 +4129,7 @@ static void ata_dev_xfermask(struct ata_device *dev)
*/
if (xfer_mask & (0xF8 << ATA_SHIFT_UDMA))
/* UDMA/44 or higher would be available */
- if ((ap->cbl == ATA_CBL_PATA40) ||
- (ata_is_40wire(dev) &&
- (ap->cbl == ATA_CBL_PATA_UNK ||
- ap->cbl == ATA_CBL_PATA80))) {
+ if (cable_is_40wire(ap)) {
ata_dev_printk(dev, KERN_WARNING,
"limited to UDMA/33 due to 40-wire cable\n");
xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
@@ -4759,112 +4290,6 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
}
/**
- * 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_check_atapi_dma - Check whether ATAPI DMA can be supported
* @qc: Metadata associated with taskfile to check
*
@@ -4924,40 +4349,6 @@ int ata_std_qc_defer(struct ata_queued_cmd *qc)
return ATA_DEFER_LINK;
}
-/**
- * ata_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_qc_prep(struct ata_queued_cmd *qc)
-{
- if (!(qc->flags & ATA_QCFLAG_DMAMAP))
- return;
-
- ata_fill_sg(qc);
-}
-
-/**
- * ata_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_dumb_qc_prep(struct ata_queued_cmd *qc)
-{
- if (!(qc->flags & ATA_QCFLAG_DMAMAP))
- return;
-
- ata_fill_sg_dumb(qc);
-}
-
void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }
/**
@@ -5036,698 +4427,6 @@ void swap_buf_le16(u16 *buf, unsigned int buf_words)
}
/**
- * ata_data_xfer - Transfer data by PIO
- * @dev: device to target
- * @buf: data buffer
- * @buflen: buffer length
- * @rw: read/write
- *
- * Transfer data from/to the device data register by PIO.
- *
- * LOCKING:
- * Inherited from caller.
- *
- * RETURNS:
- * Bytes consumed.
- */
-unsigned int ata_data_xfer(struct ata_device *dev, unsigned char *buf,
- unsigned int buflen, int rw)
-{
- struct ata_port *ap = dev->link->ap;
- void __iomem *data_addr = ap->ioaddr.data_addr;
- unsigned int words = buflen >> 1;
-
- /* Transfer multiple of 2 bytes */
- if (rw == READ)
- ioread16_rep(data_addr, buf, words);
- else
- iowrite16_rep(data_addr, buf, words);
-
- /* Transfer trailing 1 byte, if any. */
- if (unlikely(buflen & 0x01)) {
- __le16 align_buf[1] = { 0 };
- unsigned char *trailing_buf = buf + buflen - 1;
-
- if (rw == READ) {
- align_buf[0] = cpu_to_le16(ioread16(data_addr));
- memcpy(trailing_buf, align_buf, 1);
- } else {
- memcpy(align_buf, trailing_buf, 1);
- iowrite16(le16_to_cpu(align_buf[0]), data_addr);
- }
- words++;
- }
-
- return words << 1;
-}
-
-/**
- * ata_data_xfer_noirq - Transfer data by PIO
- * @dev: device to target
- * @buf: data buffer
- * @buflen: buffer length
- * @rw: read/write
- *
- * Transfer data from/to the device data register by PIO. Do the
- * transfer with interrupts disabled.
- *
- * LOCKING:
- * Inherited from caller.
- *
- * RETURNS:
- * Bytes consumed.
- */
-unsigned int ata_data_xfer_noirq(struct ata_device *dev, unsigned char *buf,
- unsigned int buflen, int rw)
-{
- unsigned long flags;
- unsigned int consumed;
-
- local_irq_save(flags);
- consumed = ata_data_xfer(dev, buf, buflen, rw);
- local_irq_restore(flags);
-
- return consumed;
-}
-
-
-/**
- * ata_pio_sector - Transfer a sector of data.
- * @qc: Command on going
- *
- * Transfer qc->sect_size bytes of data from/to the ATA device.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-static void ata_pio_sector(struct ata_queued_cmd *qc)
-{
- int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
- struct ata_port *ap = qc->ap;
- struct page *page;
- unsigned int offset;
- unsigned char *buf;
-
- if (qc->curbytes == qc->nbytes - qc->sect_size)
- ap->hsm_task_state = HSM_ST_LAST;
-
- page = sg_page(qc->cursg);
- offset = qc->cursg->offset + qc->cursg_ofs;
-
- /* get the current page and offset */
- page = nth_page(page, (offset >> PAGE_SHIFT));
- offset %= PAGE_SIZE;
-
- DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
-
- if (PageHighMem(page)) {
- unsigned long flags;
-
- /* FIXME: use a bounce buffer */
- local_irq_save(flags);
- buf = kmap_atomic(page, KM_IRQ0);
-
- /* do the actual data transfer */
- ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write);
-
- kunmap_atomic(buf, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = page_address(page);
- ap->ops->data_xfer(qc->dev, buf + offset, qc->sect_size, do_write);
- }
-
- qc->curbytes += qc->sect_size;
- qc->cursg_ofs += qc->sect_size;
-
- if (qc->cursg_ofs == qc->cursg->length) {
- qc->cursg = sg_next(qc->cursg);
- qc->cursg_ofs = 0;
- }
-}
-
-/**
- * ata_pio_sectors - Transfer one or many sectors.
- * @qc: Command on going
- *
- * Transfer one or many sectors of data from/to the
- * ATA device for the DRQ request.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-static void ata_pio_sectors(struct ata_queued_cmd *qc)
-{
- if (is_multi_taskfile(&qc->tf)) {
- /* READ/WRITE MULTIPLE */
- unsigned int nsect;
-
- WARN_ON(qc->dev->multi_count == 0);
-
- nsect = min((qc->nbytes - qc->curbytes) / qc->sect_size,
- qc->dev->multi_count);
- while (nsect--)
- ata_pio_sector(qc);
- } else
- ata_pio_sector(qc);
-
- ata_altstatus(qc->ap); /* flush */
-}
-
-/**
- * atapi_send_cdb - Write CDB bytes to hardware
- * @ap: Port to which ATAPI device is attached.
- * @qc: Taskfile currently active
- *
- * When device has indicated its readiness to accept
- * a CDB, this function is called. Send the CDB.
- *
- * LOCKING:
- * caller.
- */
-
-static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
-{
- /* send SCSI cdb */
- DPRINTK("send cdb\n");
- WARN_ON(qc->dev->cdb_len < 12);
-
- ap->ops->data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1);
- ata_altstatus(ap); /* flush */
-
- switch (qc->tf.protocol) {
- case ATAPI_PROT_PIO:
- ap->hsm_task_state = HSM_ST;
- break;
- case ATAPI_PROT_NODATA:
- ap->hsm_task_state = HSM_ST_LAST;
- break;
- case ATAPI_PROT_DMA:
- ap->hsm_task_state = HSM_ST_LAST;
- /* initiate bmdma */
- ap->ops->bmdma_start(qc);
- break;
- }
-}
-
-/**
- * __atapi_pio_bytes - Transfer data from/to the ATAPI device.
- * @qc: Command on going
- * @bytes: number of bytes
- *
- * Transfer Transfer data from/to the ATAPI device.
- *
- * LOCKING:
- * Inherited from caller.
- *
- */
-static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
-{
- int rw = (qc->tf.flags & ATA_TFLAG_WRITE) ? WRITE : READ;
- struct ata_port *ap = qc->ap;
- struct ata_device *dev = qc->dev;
- struct ata_eh_info *ehi = &dev->link->eh_info;
- struct scatterlist *sg;
- struct page *page;
- unsigned char *buf;
- unsigned int offset, count, consumed;
-
-next_sg:
- sg = qc->cursg;
- if (unlikely(!sg)) {
- ata_ehi_push_desc(ehi, "unexpected or too much trailing data "
- "buf=%u cur=%u bytes=%u",
- qc->nbytes, qc->curbytes, bytes);
- return -1;
- }
-
- page = sg_page(sg);
- offset = sg->offset + qc->cursg_ofs;
-
- /* get the current page and offset */
- page = nth_page(page, (offset >> PAGE_SHIFT));
- offset %= PAGE_SIZE;
-
- /* don't overrun current sg */
- count = min(sg->length - qc->cursg_ofs, bytes);
-
- /* don't cross page boundaries */
- count = min(count, (unsigned int)PAGE_SIZE - offset);
-
- DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
-
- if (PageHighMem(page)) {
- unsigned long flags;
-
- /* FIXME: use bounce buffer */
- local_irq_save(flags);
- buf = kmap_atomic(page, KM_IRQ0);
-
- /* do the actual data transfer */
- consumed = ap->ops->data_xfer(dev, buf + offset, count, rw);
-
- kunmap_atomic(buf, KM_IRQ0);
- local_irq_restore(flags);
- } else {
- buf = page_address(page);
- consumed = ap->ops->data_xfer(dev, buf + offset, count, rw);
- }
-
- bytes -= min(bytes, consumed);
- qc->curbytes += count;
- qc->cursg_ofs += count;
-
- if (qc->cursg_ofs == sg->length) {
- qc->cursg = sg_next(qc->cursg);
- qc->cursg_ofs = 0;
- }
-
- /* consumed can be larger than count only for the last transfer */
- WARN_ON(qc->cursg && count != consumed);
-
- if (bytes)
- goto next_sg;
- return 0;
-}
-
-/**
- * atapi_pio_bytes - Transfer data from/to the ATAPI device.
- * @qc: Command on going
- *
- * Transfer Transfer data from/to the ATAPI device.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-static void atapi_pio_bytes(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- struct ata_device *dev = qc->dev;
- struct ata_eh_info *ehi = &dev->link->eh_info;
- unsigned int ireason, bc_lo, bc_hi, bytes;
- int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
-
- /* Abuse qc->result_tf for temp storage of intermediate TF
- * here to save some kernel stack usage.
- * For normal completion, qc->result_tf is not relevant. For
- * error, qc->result_tf is later overwritten by ata_qc_complete().
- * So, the correctness of qc->result_tf is not affected.
- */
- ap->ops->tf_read(ap, &qc->result_tf);
- ireason = qc->result_tf.nsect;
- bc_lo = qc->result_tf.lbam;
- bc_hi = qc->result_tf.lbah;
- bytes = (bc_hi << 8) | bc_lo;
-
- /* shall be cleared to zero, indicating xfer of data */
- if (unlikely(ireason & (1 << 0)))
- goto atapi_check;
-
- /* make sure transfer direction matches expected */
- i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0;
- if (unlikely(do_write != i_write))
- goto atapi_check;
-
- if (unlikely(!bytes))
- goto atapi_check;
-
- VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes);
-
- if (unlikely(__atapi_pio_bytes(qc, bytes)))
- goto err_out;
- ata_altstatus(ap); /* flush */
-
- return;
-
- atapi_check:
- ata_ehi_push_desc(ehi, "ATAPI check failed (ireason=0x%x bytes=%u)",
- ireason, bytes);
- err_out:
- qc->err_mask |= AC_ERR_HSM;
- ap->hsm_task_state = HSM_ST_ERR;
-}
-
-/**
- * ata_hsm_ok_in_wq - Check if the qc can be handled in the workqueue.
- * @ap: the target ata_port
- * @qc: qc on going
- *
- * RETURNS:
- * 1 if ok in workqueue, 0 otherwise.
- */
-
-static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *qc)
-{
- if (qc->tf.flags & ATA_TFLAG_POLLING)
- return 1;
-
- if (ap->hsm_task_state == HSM_ST_FIRST) {
- if (qc->tf.protocol == ATA_PROT_PIO &&
- (qc->tf.flags & ATA_TFLAG_WRITE))
- return 1;
-
- if (ata_is_atapi(qc->tf.protocol) &&
- !(qc->dev->flags & ATA_DFLAG_CDB_INTR))
- return 1;
- }
-
- return 0;
-}
-
-/**
- * ata_hsm_qc_complete - finish a qc running on standard HSM
- * @qc: Command to complete
- * @in_wq: 1 if called from workqueue, 0 otherwise
- *
- * Finish @qc which is running on standard HSM.
- *
- * LOCKING:
- * If @in_wq is zero, spin_lock_irqsave(host lock).
- * Otherwise, none on entry and grabs host lock.
- */
-static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
-{
- struct ata_port *ap = qc->ap;
- unsigned long flags;
-
- if (ap->ops->error_handler) {
- if (in_wq) {
- spin_lock_irqsave(ap->lock, flags);
-
- /* EH might have kicked in while host lock is
- * released.
- */
- qc = ata_qc_from_tag(ap, qc->tag);
- if (qc) {
- if (likely(!(qc->err_mask & AC_ERR_HSM))) {
- ap->ops->irq_on(ap);
- ata_qc_complete(qc);
- } else
- ata_port_freeze(ap);
- }
-
- spin_unlock_irqrestore(ap->lock, flags);
- } else {
- if (likely(!(qc->err_mask & AC_ERR_HSM)))
- ata_qc_complete(qc);
- else
- ata_port_freeze(ap);
- }
- } else {
- if (in_wq) {
- spin_lock_irqsave(ap->lock, flags);
- ap->ops->irq_on(ap);
- ata_qc_complete(qc);
- spin_unlock_irqrestore(ap->lock, flags);
- } else
- ata_qc_complete(qc);
- }
-}
-
-/**
- * ata_hsm_move - move the HSM to the next state.
- * @ap: the target ata_port
- * @qc: qc on going
- * @status: current device status
- * @in_wq: 1 if called from workqueue, 0 otherwise
- *
- * RETURNS:
- * 1 when poll next status needed, 0 otherwise.
- */
-int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
- u8 status, int in_wq)
-{
- unsigned long flags = 0;
- int poll_next;
-
- WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
-
- /* Make sure ata_qc_issue_prot() does not throw things
- * like DMA polling into the workqueue. Notice that
- * in_wq is not equivalent to (qc->tf.flags & ATA_TFLAG_POLLING).
- */
- WARN_ON(in_wq != ata_hsm_ok_in_wq(ap, qc));
-
-fsm_start:
- DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n",
- ap->print_id, qc->tf.protocol, ap->hsm_task_state, status);
-
- switch (ap->hsm_task_state) {
- case HSM_ST_FIRST:
- /* Send first data block or PACKET CDB */
-
- /* If polling, we will stay in the work queue after
- * sending the data. Otherwise, interrupt handler
- * takes over after sending the data.
- */
- poll_next = (qc->tf.flags & ATA_TFLAG_POLLING);
-
- /* check device status */
- if (unlikely((status & ATA_DRQ) == 0)) {
- /* handle BSY=0, DRQ=0 as error */
- if (likely(status & (ATA_ERR | ATA_DF)))
- /* device stops HSM for abort/error */
- qc->err_mask |= AC_ERR_DEV;
- else
- /* HSM violation. Let EH handle this */
- qc->err_mask |= AC_ERR_HSM;
-
- ap->hsm_task_state = HSM_ST_ERR;
- goto fsm_start;
- }
-
- /* Device should not ask for data transfer (DRQ=1)
- * when it finds something wrong.
- * We ignore DRQ here and stop the HSM by
- * changing hsm_task_state to HSM_ST_ERR and
- * let the EH abort the command or reset the device.
- */
- if (unlikely(status & (ATA_ERR | ATA_DF))) {
- /* Some ATAPI tape drives forget to clear the ERR bit
- * when doing the next command (mostly request sense).
- * We ignore ERR here to workaround and proceed sending
- * the CDB.
- */
- if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) {
- ata_port_printk(ap, KERN_WARNING,
- "DRQ=1 with device error, "
- "dev_stat 0x%X\n", status);
- qc->err_mask |= AC_ERR_HSM;
- ap->hsm_task_state = HSM_ST_ERR;
- goto fsm_start;
- }
- }
-
- /* Send the CDB (atapi) or the first data block (ata pio out).
- * During the state transition, interrupt handler shouldn't
- * be invoked before the data transfer is complete and
- * hsm_task_state is changed. Hence, the following locking.
- */
- if (in_wq)
- spin_lock_irqsave(ap->lock, flags);
-
- if (qc->tf.protocol == ATA_PROT_PIO) {
- /* PIO data out protocol.
- * send first data block.
- */
-
- /* ata_pio_sectors() might change the state
- * to HSM_ST_LAST. so, the state is changed here
- * before ata_pio_sectors().
- */
- ap->hsm_task_state = HSM_ST;
- ata_pio_sectors(qc);
- } else
- /* send CDB */
- atapi_send_cdb(ap, qc);
-
- if (in_wq)
- spin_unlock_irqrestore(ap->lock, flags);
-
- /* if polling, ata_pio_task() handles the rest.
- * otherwise, interrupt handler takes over from here.
- */
- break;
-
- case HSM_ST:
- /* complete command or read/write the data register */
- if (qc->tf.protocol == ATAPI_PROT_PIO) {
- /* ATAPI PIO protocol */
- if ((status & ATA_DRQ) == 0) {
- /* No more data to transfer or device error.
- * Device error will be tagged in HSM_ST_LAST.
- */
- ap->hsm_task_state = HSM_ST_LAST;
- goto fsm_start;
- }
-
- /* Device should not ask for data transfer (DRQ=1)
- * when it finds something wrong.
- * We ignore DRQ here and stop the HSM by
- * changing hsm_task_state to HSM_ST_ERR and
- * let the EH abort the command or reset the device.
- */
- if (unlikely(status & (ATA_ERR | ATA_DF))) {
- ata_port_printk(ap, KERN_WARNING, "DRQ=1 with "
- "device error, dev_stat 0x%X\n",
- status);
- qc->err_mask |= AC_ERR_HSM;
- ap->hsm_task_state = HSM_ST_ERR;
- goto fsm_start;
- }
-
- atapi_pio_bytes(qc);
-
- if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
- /* bad ireason reported by device */
- goto fsm_start;
-
- } else {
- /* ATA PIO protocol */
- if (unlikely((status & ATA_DRQ) == 0)) {
- /* handle BSY=0, DRQ=0 as error */
- if (likely(status & (ATA_ERR | ATA_DF)))
- /* device stops HSM for abort/error */
- qc->err_mask |= AC_ERR_DEV;
- else
- /* HSM violation. Let EH handle this.
- * Phantom devices also trigger this
- * condition. Mark hint.
- */
- qc->err_mask |= AC_ERR_HSM |
- AC_ERR_NODEV_HINT;
-
- ap->hsm_task_state = HSM_ST_ERR;
- goto fsm_start;
- }
-
- /* For PIO reads, some devices may ask for
- * data transfer (DRQ=1) alone with ERR=1.
- * We respect DRQ here and transfer one
- * block of junk data before changing the
- * hsm_task_state to HSM_ST_ERR.
- *
- * For PIO writes, ERR=1 DRQ=1 doesn't make
- * sense since the data block has been
- * transferred to the device.
- */
- if (unlikely(status & (ATA_ERR | ATA_DF))) {
- /* data might be corrputed */
- qc->err_mask |= AC_ERR_DEV;
-
- if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
- ata_pio_sectors(qc);
- status = ata_wait_idle(ap);
- }
-
- if (status & (ATA_BUSY | ATA_DRQ))
- qc->err_mask |= AC_ERR_HSM;
-
- /* ata_pio_sectors() might change the
- * state to HSM_ST_LAST. so, the state
- * is changed after ata_pio_sectors().
- */
- ap->hsm_task_state = HSM_ST_ERR;
- goto fsm_start;
- }
-
- ata_pio_sectors(qc);
-
- if (ap->hsm_task_state == HSM_ST_LAST &&
- (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
- /* all data read */
- status = ata_wait_idle(ap);
- goto fsm_start;
- }
- }
-
- poll_next = 1;
- break;
-
- case HSM_ST_LAST:
- if (unlikely(!ata_ok(status))) {
- qc->err_mask |= __ac_err_mask(status);
- ap->hsm_task_state = HSM_ST_ERR;
- goto fsm_start;
- }
-
- /* no more data to transfer */
- DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n",
- ap->print_id, qc->dev->devno, status);
-
- WARN_ON(qc->err_mask);
-
- ap->hsm_task_state = HSM_ST_IDLE;
-
- /* complete taskfile transaction */
- ata_hsm_qc_complete(qc, in_wq);
-
- poll_next = 0;
- break;
-
- case HSM_ST_ERR:
- /* make sure qc->err_mask is available to
- * know what's wrong and recover
- */
- WARN_ON(qc->err_mask == 0);
-
- ap->hsm_task_state = HSM_ST_IDLE;
-
- /* complete taskfile transaction */
- ata_hsm_qc_complete(qc, in_wq);
-
- poll_next = 0;
- break;
- default:
- poll_next = 0;
- BUG();
- }
-
- return poll_next;
-}
-
-static void ata_pio_task(struct work_struct *work)
-{
- struct ata_port *ap =
- container_of(work, struct ata_port, port_task.work);
- struct ata_queued_cmd *qc = ap->port_task_data;
- u8 status;
- int poll_next;
-
-fsm_start:
- WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
-
- /*
- * This is purely heuristic. This is a fast path.
- * Sometimes when we enter, BSY will be cleared in
- * a chk-status or two. If not, the drive is probably seeking
- * or something. Snooze for a couple msecs, then
- * chk-status again. If still busy, queue delayed work.
- */
- status = ata_busy_wait(ap, ATA_BUSY, 5);
- if (status & ATA_BUSY) {
- msleep(2);
- status = ata_busy_wait(ap, ATA_BUSY, 10);
- if (status & ATA_BUSY) {
- ata_pio_queue_task(ap, qc, ATA_SHORT_PAUSE);
- return;
- }
- }
-
- /* move the HSM */
- poll_next = ata_hsm_move(ap, qc, status, 1);
-
- /* another command or interrupt handler
- * may be running at this point.
- */
- if (poll_next)
- goto fsm_start;
-}
-
-/**
* ata_qc_new - Request an available ATA command, for queueing
* @ap: Port associated with device @dev
* @dev: Device from whom we request an available command structure
@@ -5850,7 +4549,7 @@ static void fill_result_tf(struct ata_queued_cmd *qc)
struct ata_port *ap = qc->ap;
qc->result_tf.flags = qc->tf.flags;
- ap->ops->tf_read(ap, &qc->result_tf);
+ ap->ops->qc_fill_rtf(qc);
}
static void ata_verify_xfer(struct ata_queued_cmd *qc)
@@ -5960,7 +4659,6 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
* ata_qc_complete_multiple - Complete multiple qcs successfully
* @ap: port in question
* @qc_active: new qc_active mask
- * @finish_qc: LLDD callback invoked before completing a qc
*
* Complete in-flight commands. This functions is meant to be
* called from low-level driver's interrupt routine to complete
@@ -5973,8 +4671,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
* RETURNS:
* Number of completed commands on success, -errno otherwise.
*/
-int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active,
- void (*finish_qc)(struct ata_queued_cmd *))
+int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active)
{
int nr_done = 0;
u32 done_mask;
@@ -5995,8 +4692,6 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active,
continue;
if ((qc = ata_qc_from_tag(ap, i))) {
- if (finish_qc)
- finish_qc(qc);
ata_qc_complete(qc);
nr_done++;
}
@@ -6055,9 +4750,9 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
if (ata_sg_setup(qc))
goto sg_err;
- /* if device is sleeping, schedule softreset and abort the link */
+ /* if device is sleeping, schedule reset and abort the link */
if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) {
- link->eh_info.action |= ATA_EH_SOFTRESET;
+ link->eh_info.action |= ATA_EH_RESET;
ata_ehi_push_desc(&link->eh_info, "waking up from sleep");
ata_link_abort(link);
return;
@@ -6077,285 +4772,6 @@ err:
}
/**
- * ata_qc_issue_prot - issue taskfile to device in proto-dependent manner
- * @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.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- *
- * RETURNS:
- * Zero on success, AC_ERR_* mask on failure
- */
-
-unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
-
- /* 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;
- }
- }
-
- /* select the device */
- ata_dev_select(ap, qc->dev->devno, 1, 0);
-
- /* start the command */
- switch (qc->tf.protocol) {
- case ATA_PROT_NODATA:
- if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_qc_set_polling(qc);
-
- ata_tf_to_host(ap, &qc->tf);
- ap->hsm_task_state = HSM_ST_LAST;
-
- if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_pio_queue_task(ap, qc, 0);
-
- break;
-
- case ATA_PROT_DMA:
- WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
-
- ap->ops->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);
-
- ata_tf_to_host(ap, &qc->tf);
-
- if (qc->tf.flags & ATA_TFLAG_WRITE) {
- /* PIO data out protocol */
- ap->hsm_task_state = HSM_ST_FIRST;
- ata_pio_queue_task(ap, qc, 0);
-
- /* always send first data block using
- * the ata_pio_task() codepath.
- */
- } else {
- /* PIO data in protocol */
- ap->hsm_task_state = HSM_ST;
-
- if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_pio_queue_task(ap, qc, 0);
-
- /* if polling, ata_pio_task() handles the rest.
- * otherwise, interrupt handler takes over from here.
- */
- }
-
- break;
-
- case ATAPI_PROT_PIO:
- case ATAPI_PROT_NODATA:
- if (qc->tf.flags & ATA_TFLAG_POLLING)
- ata_qc_set_polling(qc);
-
- ata_tf_to_host(ap, &qc->tf);
-
- ap->hsm_task_state = HSM_ST_FIRST;
-
- /* send cdb by polling if no cdb interrupt */
- if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
- (qc->tf.flags & ATA_TFLAG_POLLING))
- ata_pio_queue_task(ap, qc, 0);
- break;
-
- case ATAPI_PROT_DMA:
- WARN_ON(qc->tf.flags & ATA_TFLAG_POLLING);
-
- ap->ops->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_pio_queue_task(ap, qc, 0);
- break;
-
- default:
- WARN_ON(1);
- return AC_ERR_SYSTEM;
- }
-
- return 0;
-}
-
-/**
- * ata_host_intr - Handle host interrupt for given (port, task)
- * @ap: Port on which interrupt arrived (possibly...)
- * @qc: Taskfile currently active in engine
- *
- * Handle host interrupt for given queued command. Currently,
- * only DMA interrupts are handled. All other commands are
- * handled via polling with interrupts disabled (nIEN bit).
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- *
- * RETURNS:
- * One if interrupt was handled, zero if not (shared irq).
- */
-
-inline unsigned int ata_host_intr(struct ata_port *ap,
- struct ata_queued_cmd *qc)
-{
- struct ata_eh_info *ehi = &ap->link.eh_info;
- u8 status, host_stat = 0;
-
- VPRINTK("ata%u: protocol %d task_state %d\n",
- ap->print_id, qc->tf.protocol, ap->hsm_task_state);
-
- /* Check whether we are expecting interrupt in this state */
- switch (ap->hsm_task_state) {
- case HSM_ST_FIRST:
- /* Some pre-ATAPI-4 devices assert INTRQ
- * at this state when ready to receive CDB.
- */
-
- /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
- * The flag was turned on only for atapi devices. No
- * need to check ata_is_atapi(qc->tf.protocol) again.
- */
- if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
- goto idle_irq;
- break;
- case HSM_ST_LAST:
- if (qc->tf.protocol == ATA_PROT_DMA ||
- qc->tf.protocol == ATAPI_PROT_DMA) {
- /* check status of DMA engine */
- host_stat = ap->ops->bmdma_status(ap);
- VPRINTK("ata%u: host_stat 0x%X\n",
- ap->print_id, host_stat);
-
- /* if it's not our irq... */
- if (!(host_stat & ATA_DMA_INTR))
- goto idle_irq;
-
- /* before we do anything else, clear DMA-Start bit */
- ap->ops->bmdma_stop(qc);
-
- if (unlikely(host_stat & ATA_DMA_ERR)) {
- /* error when transfering data to/from memory */
- qc->err_mask |= AC_ERR_HOST_BUS;
- ap->hsm_task_state = HSM_ST_ERR;
- }
- }
- break;
- case HSM_ST:
- break;
- default:
- goto idle_irq;
- }
-
- /* check altstatus */
- status = ata_altstatus(ap);
- if (status & ATA_BUSY)
- goto idle_irq;
-
- /* check main status, clearing INTRQ */
- status = ata_chk_status(ap);
- if (unlikely(status & ATA_BUSY))
- goto idle_irq;
-
- /* ack bmdma irq events */
- ap->ops->irq_clear(ap);
-
- ata_hsm_move(ap, qc, status, 0);
-
- if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
- qc->tf.protocol == ATAPI_PROT_DMA))
- ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
-
- return 1; /* irq handled */
-
-idle_irq:
- ap->stats.idle_irq++;
-
-#ifdef ATA_IRQ_TRAP
- if ((ap->stats.idle_irq % 1000) == 0) {
- ata_chk_status(ap);
- ap->ops->irq_clear(ap);
- ata_port_printk(ap, KERN_WARNING, "irq trap\n");
- return 1;
- }
-#endif
- return 0; /* irq not handled */
-}
-
-/**
- * ata_interrupt - Default ATA host interrupt handler
- * @irq: irq line (unused)
- * @dev_instance: pointer to our ata_host information structure
- *
- * Default interrupt handler for PCI IDE devices. Calls
- * ata_host_intr() for each port that is not disabled.
- *
- * LOCKING:
- * Obtains host lock during operation.
- *
- * RETURNS:
- * IRQ_NONE or IRQ_HANDLED.
- */
-
-irqreturn_t ata_interrupt(int irq, void *dev_instance)
-{
- struct ata_host *host = dev_instance;
- unsigned int i;
- unsigned int handled = 0;
- unsigned long flags;
-
- /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
- spin_lock_irqsave(&host->lock, flags);
-
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap;
-
- 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 |= ata_host_intr(ap, qc);
- }
- }
-
- spin_unlock_irqrestore(&host->lock, flags);
-
- return IRQ_RETVAL(handled);
-}
-
-/**
* sata_scr_valid - test whether SCRs are accessible
* @link: ATA link to test SCR accessibility for
*
@@ -6513,32 +4929,6 @@ int ata_link_offline(struct ata_link *link)
return 0;
}
-int ata_flush_cache(struct ata_device *dev)
-{
- unsigned int err_mask;
- u8 cmd;
-
- if (!ata_try_flush_cache(dev))
- return 0;
-
- if (dev->flags & ATA_DFLAG_FLUSH_EXT)
- cmd = ATA_CMD_FLUSH_EXT;
- else
- cmd = ATA_CMD_FLUSH;
-
- /* This is wrong. On a failed flush we get back the LBA of the lost
- sector and we should (assuming it wasn't aborted as unknown) issue
- a further flush command to continue the writeback until it
- does not error */
- err_mask = ata_do_simple_cmd(dev, cmd);
- if (err_mask) {
- ata_dev_printk(dev, KERN_ERR, "failed to flush cache\n");
- return -EIO;
- }
-
- return 0;
-}
-
#ifdef CONFIG_PM
static int ata_host_request_pm(struct ata_host *host, pm_message_t mesg,
unsigned int action, unsigned int ehi_flags,
@@ -6634,7 +5024,7 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
*/
void ata_host_resume(struct ata_host *host)
{
- ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET,
+ ata_host_request_pm(host, PMSG_ON, ATA_EH_RESET,
ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
host->dev->power.power_state = PMSG_ON;
@@ -6809,7 +5199,9 @@ 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);
+#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);
@@ -6959,8 +5351,6 @@ struct ata_host *ata_host_alloc_pinfo(struct device *dev,
if (!host->ops && (pi->port_ops != &ata_dummy_port_ops))
host->ops = pi->port_ops;
- if (!host->private_data && pi->private_data)
- host->private_data = pi->private_data;
}
return host;
@@ -6985,6 +5375,56 @@ static void ata_host_stop(struct device *gendev, void *res)
}
/**
+ * ata_finalize_port_ops - finalize ata_port_operations
+ * @ops: ata_port_operations to finalize
+ *
+ * An ata_port_operations can inherit from another ops and that
+ * ops can again inherit from another. This can go on as many
+ * times as necessary as long as there is no loop in the
+ * inheritance chain.
+ *
+ * Ops tables are finalized when the host is started. NULL or
+ * unspecified entries are inherited from the closet ancestor
+ * which has the method and the entry is populated with it.
+ * After finalization, the ops table directly points to all the
+ * methods and ->inherits is no longer necessary and cleared.
+ *
+ * Using ATA_OP_NULL, inheriting ops can force a method to NULL.
+ *
+ * LOCKING:
+ * None.
+ */
+static void ata_finalize_port_ops(struct ata_port_operations *ops)
+{
+ static spinlock_t lock = SPIN_LOCK_UNLOCKED;
+ const struct ata_port_operations *cur;
+ void **begin = (void **)ops;
+ void **end = (void **)&ops->inherits;
+ void **pp;
+
+ if (!ops || !ops->inherits)
+ return;
+
+ spin_lock(&lock);
+
+ for (cur = ops->inherits; cur; cur = cur->inherits) {
+ void **inherit = (void **)cur;
+
+ for (pp = begin; pp < end; pp++, inherit++)
+ if (!*pp)
+ *pp = *inherit;
+ }
+
+ for (pp = begin; pp < end; pp++)
+ if (IS_ERR(*pp))
+ *pp = NULL;
+
+ ops->inherits = NULL;
+
+ spin_unlock(&lock);
+}
+
+/**
* ata_host_start - start and freeze ports of an ATA host
* @host: ATA host to start ports for
*
@@ -7009,9 +5449,13 @@ int ata_host_start(struct ata_host *host)
if (host->flags & ATA_HOST_STARTED)
return 0;
+ ata_finalize_port_ops(host->ops);
+
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
+ ata_finalize_port_ops(ap->ops);
+
if (!host->ops && !ata_port_is_dummy(ap))
host->ops = ap->ops;
@@ -7073,7 +5517,7 @@ int ata_host_start(struct ata_host *host)
*/
/* KILLME - the only user left is ipr */
void ata_host_init(struct ata_host *host, struct device *dev,
- unsigned long flags, const struct ata_port_operations *ops)
+ unsigned long flags, struct ata_port_operations *ops)
{
spin_lock_init(&host->lock);
host->dev = dev;
@@ -7169,9 +5613,8 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
/* kick EH for boot probing */
spin_lock_irqsave(ap->lock, flags);
- ehi->probe_mask =
- (1 << ata_link_max_devices(&ap->link)) - 1;
- ehi->action |= ATA_EH_SOFTRESET;
+ ehi->probe_mask |= ATA_ALL_DEVICES;
+ ehi->action |= ATA_EH_RESET;
ehi->flags |= ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET;
ap->pflags &= ~ATA_PFLAG_INITIALIZING;
@@ -7336,33 +5779,6 @@ void ata_host_detach(struct ata_host *host)
ata_acpi_dissociate(host);
}
-/**
- * ata_std_ports - initialize ioaddr with standard port offsets.
- * @ioaddr: IO address structure to be initialized
- *
- * Utility function which initializes data_addr, error_addr,
- * feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
- * device_addr, status_addr, and command_addr to standard offsets
- * relative to cmd_addr.
- *
- * Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
- */
-
-void ata_std_ports(struct ata_ioports *ioaddr)
-{
- ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
- ioaddr->error_addr = ioaddr->cmd_addr + ATA_REG_ERR;
- ioaddr->feature_addr = ioaddr->cmd_addr + ATA_REG_FEATURE;
- ioaddr->nsect_addr = ioaddr->cmd_addr + ATA_REG_NSECT;
- ioaddr->lbal_addr = ioaddr->cmd_addr + ATA_REG_LBAL;
- ioaddr->lbam_addr = ioaddr->cmd_addr + ATA_REG_LBAM;
- ioaddr->lbah_addr = ioaddr->cmd_addr + ATA_REG_LBAH;
- ioaddr->device_addr = ioaddr->cmd_addr + ATA_REG_DEVICE;
- ioaddr->status_addr = ioaddr->cmd_addr + ATA_REG_STATUS;
- ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD;
-}
-
-
#ifdef CONFIG_PCI
/**
@@ -7749,33 +6165,20 @@ u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
/*
* Dummy port_ops
*/
-static void ata_dummy_noret(struct ata_port *ap) { }
-static int ata_dummy_ret0(struct ata_port *ap) { return 0; }
-static void ata_dummy_qc_noret(struct ata_queued_cmd *qc) { }
-
-static u8 ata_dummy_check_status(struct ata_port *ap)
+static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
{
- return ATA_DRDY;
+ return AC_ERR_SYSTEM;
}
-static unsigned int ata_dummy_qc_issue(struct ata_queued_cmd *qc)
+static void ata_dummy_error_handler(struct ata_port *ap)
{
- return AC_ERR_SYSTEM;
+ /* truly dummy */
}
-const struct ata_port_operations ata_dummy_port_ops = {
- .check_status = ata_dummy_check_status,
- .check_altstatus = ata_dummy_check_status,
- .dev_select = ata_noop_dev_select,
+struct ata_port_operations ata_dummy_port_ops = {
.qc_prep = ata_noop_qc_prep,
.qc_issue = ata_dummy_qc_issue,
- .freeze = ata_dummy_noret,
- .thaw = ata_dummy_noret,
- .error_handler = ata_dummy_noret,
- .post_internal_cmd = ata_dummy_qc_noret,
- .irq_clear = ata_dummy_noret,
- .port_start = ata_dummy_ret0,
- .port_stop = ata_dummy_noret,
+ .error_handler = ata_dummy_error_handler,
};
const struct ata_port_info ata_dummy_port_info = {
@@ -7791,10 +6194,11 @@ const struct ata_port_info ata_dummy_port_info = {
EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
EXPORT_SYMBOL_GPL(sata_deb_timing_long);
+EXPORT_SYMBOL_GPL(ata_base_port_ops);
+EXPORT_SYMBOL_GPL(sata_port_ops);
EXPORT_SYMBOL_GPL(ata_dummy_port_ops);
EXPORT_SYMBOL_GPL(ata_dummy_port_info);
EXPORT_SYMBOL_GPL(ata_std_bios_param);
-EXPORT_SYMBOL_GPL(ata_std_ports);
EXPORT_SYMBOL_GPL(ata_host_init);
EXPORT_SYMBOL_GPL(ata_host_alloc);
EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
@@ -7803,14 +6207,8 @@ EXPORT_SYMBOL_GPL(ata_host_register);
EXPORT_SYMBOL_GPL(ata_host_activate);
EXPORT_SYMBOL_GPL(ata_host_detach);
EXPORT_SYMBOL_GPL(ata_sg_init);
-EXPORT_SYMBOL_GPL(ata_hsm_move);
EXPORT_SYMBOL_GPL(ata_qc_complete);
EXPORT_SYMBOL_GPL(ata_qc_complete_multiple);
-EXPORT_SYMBOL_GPL(ata_qc_issue_prot);
-EXPORT_SYMBOL_GPL(ata_tf_load);
-EXPORT_SYMBOL_GPL(ata_tf_read);
-EXPORT_SYMBOL_GPL(ata_noop_dev_select);
-EXPORT_SYMBOL_GPL(ata_std_dev_select);
EXPORT_SYMBOL_GPL(sata_print_link_status);
EXPORT_SYMBOL_GPL(atapi_cmd_type);
EXPORT_SYMBOL_GPL(ata_tf_to_fis);
@@ -7822,37 +6220,17 @@ 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_check_status);
-EXPORT_SYMBOL_GPL(ata_altstatus);
-EXPORT_SYMBOL_GPL(ata_exec_command);
EXPORT_SYMBOL_GPL(ata_port_start);
-EXPORT_SYMBOL_GPL(ata_sff_port_start);
-EXPORT_SYMBOL_GPL(ata_interrupt);
EXPORT_SYMBOL_GPL(ata_do_set_mode);
-EXPORT_SYMBOL_GPL(ata_data_xfer);
-EXPORT_SYMBOL_GPL(ata_data_xfer_noirq);
EXPORT_SYMBOL_GPL(ata_std_qc_defer);
-EXPORT_SYMBOL_GPL(ata_qc_prep);
-EXPORT_SYMBOL_GPL(ata_dumb_qc_prep);
EXPORT_SYMBOL_GPL(ata_noop_qc_prep);
-EXPORT_SYMBOL_GPL(ata_bmdma_setup);
-EXPORT_SYMBOL_GPL(ata_bmdma_start);
-EXPORT_SYMBOL_GPL(ata_bmdma_irq_clear);
-EXPORT_SYMBOL_GPL(ata_bmdma_status);
-EXPORT_SYMBOL_GPL(ata_bmdma_stop);
-EXPORT_SYMBOL_GPL(ata_bmdma_freeze);
-EXPORT_SYMBOL_GPL(ata_bmdma_thaw);
-EXPORT_SYMBOL_GPL(ata_bmdma_drive_eh);
-EXPORT_SYMBOL_GPL(ata_bmdma_error_handler);
-EXPORT_SYMBOL_GPL(ata_bmdma_post_internal_cmd);
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);
EXPORT_SYMBOL_GPL(sata_link_debounce);
EXPORT_SYMBOL_GPL(sata_link_resume);
-EXPORT_SYMBOL_GPL(ata_bus_reset);
EXPORT_SYMBOL_GPL(ata_std_prereset);
-EXPORT_SYMBOL_GPL(ata_std_softreset);
EXPORT_SYMBOL_GPL(sata_link_hardreset);
EXPORT_SYMBOL_GPL(sata_std_hardreset);
EXPORT_SYMBOL_GPL(ata_std_postreset);
@@ -7861,15 +6239,11 @@ 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_busy_sleep);
-EXPORT_SYMBOL_GPL(ata_wait_after_reset);
-EXPORT_SYMBOL_GPL(ata_wait_ready);
EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
-EXPORT_SYMBOL_GPL(ata_host_intr);
EXPORT_SYMBOL_GPL(sata_scr_valid);
EXPORT_SYMBOL_GPL(sata_scr_read);
EXPORT_SYMBOL_GPL(sata_scr_write);
@@ -7892,11 +6266,6 @@ EXPORT_SYMBOL_GPL(ata_timing_cycle2mode);
#ifdef CONFIG_PCI
EXPORT_SYMBOL_GPL(pci_test_config_bits);
-EXPORT_SYMBOL_GPL(ata_pci_init_sff_host);
-EXPORT_SYMBOL_GPL(ata_pci_init_bmdma);
-EXPORT_SYMBOL_GPL(ata_pci_prepare_sff_host);
-EXPORT_SYMBOL_GPL(ata_pci_activate_sff_host);
-EXPORT_SYMBOL_GPL(ata_pci_init_one);
EXPORT_SYMBOL_GPL(ata_pci_remove_one);
#ifdef CONFIG_PM
EXPORT_SYMBOL_GPL(ata_pci_device_do_suspend);
@@ -7904,16 +6273,8 @@ EXPORT_SYMBOL_GPL(ata_pci_device_do_resume);
EXPORT_SYMBOL_GPL(ata_pci_device_suspend);
EXPORT_SYMBOL_GPL(ata_pci_device_resume);
#endif /* CONFIG_PM */
-EXPORT_SYMBOL_GPL(ata_pci_default_filter);
-EXPORT_SYMBOL_GPL(ata_pci_clear_simplex);
#endif /* CONFIG_PCI */
-EXPORT_SYMBOL_GPL(sata_pmp_qc_defer_cmd_switch);
-EXPORT_SYMBOL_GPL(sata_pmp_std_prereset);
-EXPORT_SYMBOL_GPL(sata_pmp_std_hardreset);
-EXPORT_SYMBOL_GPL(sata_pmp_std_postreset);
-EXPORT_SYMBOL_GPL(sata_pmp_do_eh);
-
EXPORT_SYMBOL_GPL(__ata_ehi_push_desc);
EXPORT_SYMBOL_GPL(ata_ehi_push_desc);
EXPORT_SYMBOL_GPL(ata_ehi_clear_desc);
@@ -7931,8 +6292,7 @@ EXPORT_SYMBOL_GPL(ata_eh_thaw_port);
EXPORT_SYMBOL_GPL(ata_eh_qc_complete);
EXPORT_SYMBOL_GPL(ata_eh_qc_retry);
EXPORT_SYMBOL_GPL(ata_do_eh);
-EXPORT_SYMBOL_GPL(ata_irq_on);
-EXPORT_SYMBOL_GPL(ata_dev_try_classify);
+EXPORT_SYMBOL_GPL(ata_std_error_handler);
EXPORT_SYMBOL_GPL(ata_cable_40wire);
EXPORT_SYMBOL_GPL(ata_cable_80wire);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index a5830329eda4..d94359a24d41 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -873,9 +873,9 @@ int sata_async_notification(struct ata_port *ap)
if (rc == 0)
sata_scr_write(&ap->link, SCR_NOTIFICATION, sntf);
- if (!ap->nr_pmp_links || rc) {
+ if (!sata_pmp_attached(ap) || rc) {
/* PMP is not attached or SNTF is not available */
- if (!ap->nr_pmp_links) {
+ if (!sata_pmp_attached(ap)) {
/* PMP is not attached. Check whether ATAPI
* AN is configured. If so, notify media
* change.
@@ -1079,19 +1079,6 @@ void ata_eh_about_to_do(struct ata_link *link, struct ata_device *dev,
spin_lock_irqsave(ap->lock, flags);
- /* Reset is represented by combination of actions and EHI
- * flags. Suck in all related bits before clearing eh_info to
- * avoid losing requested action.
- */
- if (action & ATA_EH_RESET_MASK) {
- ehc->i.action |= ehi->action & ATA_EH_RESET_MASK;
- ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK;
-
- /* make sure all reset actions are cleared & clear EHI flags */
- action |= ATA_EH_RESET_MASK;
- ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
- }
-
ata_eh_clear_action(link, dev, ehi, action);
if (!(ehc->i.flags & ATA_EHI_QUIET))
@@ -1117,12 +1104,6 @@ void ata_eh_done(struct ata_link *link, struct ata_device *dev,
{
struct ata_eh_context *ehc = &link->eh_context;
- /* if reset is complete, clear all reset actions & reset modifier */
- if (action & ATA_EH_RESET_MASK) {
- action |= ATA_EH_RESET_MASK;
- ehc->i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
- }
-
ata_eh_clear_action(link, dev, &ehc->i, action);
}
@@ -1329,20 +1310,20 @@ static void ata_eh_analyze_serror(struct ata_link *link)
if (serror & SERR_PERSISTENT) {
err_mask |= AC_ERR_ATA_BUS;
- action |= ATA_EH_HARDRESET;
+ action |= ATA_EH_RESET;
}
if (serror &
(SERR_DATA_RECOVERED | SERR_COMM_RECOVERED | SERR_DATA)) {
err_mask |= AC_ERR_ATA_BUS;
- action |= ATA_EH_SOFTRESET;
+ action |= ATA_EH_RESET;
}
if (serror & SERR_PROTOCOL) {
err_mask |= AC_ERR_HSM;
- action |= ATA_EH_SOFTRESET;
+ action |= ATA_EH_RESET;
}
if (serror & SERR_INTERNAL) {
err_mask |= AC_ERR_SYSTEM;
- action |= ATA_EH_HARDRESET;
+ action |= ATA_EH_RESET;
}
/* Determine whether a hotplug event has occurred. Both
@@ -1448,7 +1429,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
if ((stat & (ATA_BUSY | ATA_DRQ | ATA_DRDY)) != ATA_DRDY) {
qc->err_mask |= AC_ERR_HSM;
- return ATA_EH_SOFTRESET;
+ return ATA_EH_RESET;
}
if (stat & (ATA_ERR | ATA_DF))
@@ -1484,7 +1465,7 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
}
if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS))
- action |= ATA_EH_SOFTRESET;
+ action |= ATA_EH_RESET;
return action;
}
@@ -1685,7 +1666,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
if (verdict & ATA_EH_SPDN_SPEED_DOWN) {
/* speed down SATA link speed if possible */
if (sata_down_spd_limit(link) == 0) {
- action |= ATA_EH_HARDRESET;
+ action |= ATA_EH_RESET;
goto done;
}
@@ -1705,7 +1686,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
dev->spdn_cnt++;
if (ata_down_xfermask_limit(dev, sel) == 0) {
- action |= ATA_EH_SOFTRESET;
+ action |= ATA_EH_RESET;
goto done;
}
}
@@ -1719,7 +1700,7 @@ static unsigned int ata_eh_speed_down(struct ata_device *dev,
(dev->xfer_shift != ATA_SHIFT_PIO)) {
if (ata_down_xfermask_limit(dev, ATA_DNXFER_FORCE_PIO) == 0) {
dev->spdn_cnt = 0;
- action |= ATA_EH_SOFTRESET;
+ action |= ATA_EH_RESET;
goto done;
}
}
@@ -1764,9 +1745,9 @@ static void ata_eh_link_autopsy(struct ata_link *link)
ehc->i.serror |= serror;
ata_eh_analyze_serror(link);
} else if (rc != -EOPNOTSUPP) {
- /* SError read failed, force hardreset and probing */
- ata_ehi_schedule_probe(&ehc->i);
- ehc->i.action |= ATA_EH_HARDRESET;
+ /* SError read failed, force reset and probing */
+ ehc->i.probe_mask |= ATA_ALL_DEVICES;
+ ehc->i.action |= ATA_EH_RESET;
ehc->i.err_mask |= AC_ERR_OTHER;
}
@@ -1804,6 +1785,11 @@ static void ata_eh_link_autopsy(struct ata_link *link)
if (qc->flags & ATA_QCFLAG_SENSE_VALID)
qc->err_mask &= ~(AC_ERR_DEV | AC_ERR_OTHER);
+ /* determine whether the command is worth retrying */
+ if (!(qc->err_mask & AC_ERR_INVALID) &&
+ ((qc->flags & ATA_QCFLAG_IO) || qc->err_mask != AC_ERR_DEV))
+ qc->flags |= ATA_QCFLAG_RETRY;
+
/* accumulate error info */
ehc->i.dev = qc->dev;
all_err_mask |= qc->err_mask;
@@ -1814,7 +1800,7 @@ static void ata_eh_link_autopsy(struct ata_link *link)
/* enforce default EH actions */
if (ap->pflags & ATA_PFLAG_FROZEN ||
all_err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT))
- ehc->i.action |= ATA_EH_SOFTRESET;
+ ehc->i.action |= ATA_EH_RESET;
else if (((eflags & ATA_EFLAG_IS_IO) && all_err_mask) ||
(!(eflags & ATA_EFLAG_IS_IO) && (all_err_mask & ~AC_ERR_DEV)))
ehc->i.action |= ATA_EH_REVALIDATE;
@@ -1867,7 +1853,7 @@ void ata_eh_autopsy(struct ata_port *ap)
/* Autopsy of fanout ports can affect host link autopsy.
* Perform host link autopsy last.
*/
- if (ap->nr_pmp_links)
+ if (sata_pmp_attached(ap))
ata_eh_link_autopsy(&ap->link);
}
@@ -2066,41 +2052,29 @@ static int ata_do_reset(struct ata_link *link, ata_reset_fn_t reset,
classes[dev->devno] = ATA_DEV_UNKNOWN;
rc = reset(link, classes, deadline);
- if (rc)
- return rc;
- /* If any class isn't ATA_DEV_UNKNOWN, consider classification
- * is complete and convert all ATA_DEV_UNKNOWN to
- * ATA_DEV_NONE.
- */
+ /* convert all ATA_DEV_UNKNOWN to ATA_DEV_NONE */
ata_link_for_each_dev(dev, link)
- if (classes[dev->devno] != ATA_DEV_UNKNOWN)
- break;
-
- if (dev) {
- ata_link_for_each_dev(dev, link) {
- if (classes[dev->devno] == ATA_DEV_UNKNOWN)
- classes[dev->devno] = ATA_DEV_NONE;
- }
- }
+ if (classes[dev->devno] == ATA_DEV_UNKNOWN)
+ classes[dev->devno] = ATA_DEV_NONE;
- return 0;
+ return rc;
}
static int ata_eh_followup_srst_needed(struct ata_link *link,
int rc, int classify,
const unsigned int *classes)
{
- if (link->flags & ATA_LFLAG_NO_SRST)
+ if ((link->flags & ATA_LFLAG_NO_SRST) || ata_link_offline(link))
return 0;
- if (rc == -EAGAIN)
- return 1;
+ if (rc == -EAGAIN) {
+ if (classify)
+ return 1;
+ rc = 0;
+ }
if (rc != 0)
return 0;
- if ((link->ap->flags & ATA_FLAG_PMP) && ata_is_host_link(link))
- return 1;
- if (classify && !(link->flags & ATA_LFLAG_ASSUME_CLASS) &&
- classes[0] == ATA_DEV_UNKNOWN)
+ if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
return 1;
return 0;
}
@@ -2118,7 +2092,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
int try = 0;
struct ata_device *dev;
unsigned long deadline, now;
- unsigned int tmp_action;
ata_reset_fn_t reset;
unsigned long flags;
u32 sstatus;
@@ -2129,7 +2102,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
ap->pflags |= ATA_PFLAG_RESETTING;
spin_unlock_irqrestore(ap->lock, flags);
- ata_eh_about_to_do(link, NULL, ehc->i.action & ATA_EH_RESET_MASK);
+ ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
ata_link_for_each_dev(dev, link) {
/* If we issue an SRST then an ATA drive (not ATAPI)
@@ -2159,17 +2132,20 @@ int ata_eh_reset(struct ata_link *link, int classify,
goto done;
}
- /* Determine which reset to use and record in ehc->i.action.
- * prereset() may examine and modify it.
- */
- if (softreset && (!hardreset || (!(lflags & ATA_LFLAG_NO_SRST) &&
- !sata_set_spd_needed(link) &&
- !(ehc->i.action & ATA_EH_HARDRESET))))
- tmp_action = ATA_EH_SOFTRESET;
- else
- tmp_action = ATA_EH_HARDRESET;
-
- ehc->i.action = (ehc->i.action & ~ATA_EH_RESET_MASK) | tmp_action;
+ /* prefer hardreset */
+ ehc->i.action &= ~ATA_EH_RESET;
+ if (hardreset) {
+ reset = hardreset;
+ ehc->i.action = ATA_EH_HARDRESET;
+ } else if (softreset) {
+ reset = softreset;
+ ehc->i.action = ATA_EH_SOFTRESET;
+ } else {
+ ata_link_printk(link, KERN_ERR, "BUG: no reset method, "
+ "please report to linux-ide@vger.kernel.org\n");
+ dump_stack();
+ return -EINVAL;
+ }
if (prereset) {
rc = prereset(link, jiffies + ATA_EH_PRERESET_TIMEOUT);
@@ -2177,7 +2153,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
if (rc == -ENOENT) {
ata_link_printk(link, KERN_DEBUG,
"port disabled. ignoring.\n");
- ehc->i.action &= ~ATA_EH_RESET_MASK;
+ ehc->i.action &= ~ATA_EH_RESET;
ata_link_for_each_dev(dev, link)
classes[dev->devno] = ATA_DEV_NONE;
@@ -2190,12 +2166,8 @@ int ata_eh_reset(struct ata_link *link, int classify,
}
}
- /* prereset() might have modified ehc->i.action */
- if (ehc->i.action & ATA_EH_HARDRESET)
- reset = hardreset;
- else if (ehc->i.action & ATA_EH_SOFTRESET)
- reset = softreset;
- else {
+ /* prereset() might have cleared ATA_EH_RESET */
+ if (!(ehc->i.action & ATA_EH_RESET)) {
/* prereset told us not to reset, bang classes and return */
ata_link_for_each_dev(dev, link)
classes[dev->devno] = ATA_DEV_NONE;
@@ -2203,14 +2175,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
goto out;
}
- /* did prereset() screw up? if so, fix up to avoid oopsing */
- if (!reset) {
- if (softreset)
- reset = softreset;
- else
- reset = hardreset;
- }
-
retry:
deadline = jiffies + ata_eh_reset_timeouts[try++];
@@ -2240,7 +2204,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
goto fail;
}
- ata_eh_about_to_do(link, NULL, ATA_EH_RESET_MASK);
+ ata_eh_about_to_do(link, NULL, ATA_EH_RESET);
rc = ata_do_reset(link, reset, classes, deadline);
}
@@ -2248,21 +2212,6 @@ int ata_eh_reset(struct ata_link *link, int classify,
if (rc && rc != -EAGAIN)
goto fail;
- /* was classification successful? */
- if (classify && classes[0] == ATA_DEV_UNKNOWN &&
- !(lflags & ATA_LFLAG_ASSUME_CLASS)) {
- if (try < max_tries) {
- ata_link_printk(link, KERN_WARNING,
- "classification failed\n");
- rc = -EINVAL;
- goto fail;
- }
-
- ata_link_printk(link, KERN_WARNING,
- "classfication failed, assuming ATA\n");
- lflags |= ATA_LFLAG_ASSUME_ATA;
- }
-
done:
ata_link_for_each_dev(dev, link) {
/* After the reset, the device state is PIO 0 and the
@@ -2290,7 +2239,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
postreset(link, classes);
/* reset successful, schedule revalidation */
- ata_eh_done(link, NULL, ehc->i.action & ATA_EH_RESET_MASK);
+ ata_eh_done(link, NULL, ATA_EH_RESET);
ehc->i.action |= ATA_EH_REVALIDATE;
rc = 0;
@@ -2305,6 +2254,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
return rc;
fail:
+ /* if SCR isn't accessible on a fan-out port, PMP needs to be reset */
+ if (!ata_is_host_link(link) &&
+ sata_scr_read(link, SCR_STATUS, &sstatus))
+ rc = -ERESTART;
+
if (rc == -ERESTART || try >= max_tries)
goto out;
@@ -2515,6 +2469,7 @@ static int ata_link_nr_vacant(struct ata_link *link)
static int ata_eh_skip_recovery(struct ata_link *link)
{
+ struct ata_port *ap = link->ap;
struct ata_eh_context *ehc = &link->eh_context;
struct ata_device *dev;
@@ -2522,9 +2477,13 @@ static int ata_eh_skip_recovery(struct ata_link *link)
if (link->flags & ATA_LFLAG_DISABLED)
return 1;
- /* thaw frozen port, resume link and recover failed devices */
- if ((link->ap->pflags & ATA_PFLAG_FROZEN) ||
- (ehc->i.flags & ATA_EHI_RESUME_LINK) || ata_link_nr_enabled(link))
+ /* thaw frozen port and recover failed devices */
+ if ((ap->pflags & ATA_PFLAG_FROZEN) || ata_link_nr_enabled(link))
+ return 0;
+
+ /* reset at least once if reset is requested */
+ if ((ehc->i.action & ATA_EH_RESET) &&
+ !(ehc->i.flags & ATA_EHI_DID_RESET))
return 0;
/* skip if class codes for all vacant slots are ATA_DEV_NONE */
@@ -2548,7 +2507,7 @@ static int ata_eh_schedule_probe(struct ata_device *dev)
ata_eh_detach_dev(dev);
ata_dev_init(dev);
ehc->did_probe_mask |= (1 << dev->devno);
- ehc->i.action |= ATA_EH_SOFTRESET;
+ ehc->i.action |= ATA_EH_RESET;
ehc->saved_xfer_mode[dev->devno] = 0;
ehc->saved_ncq_enabled &= ~(1 << dev->devno);
@@ -2592,12 +2551,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
return 1;
} else {
- /* soft didn't work? be haaaaard */
- if (ehc->i.flags & ATA_EHI_DID_RESET)
- ehc->i.action |= ATA_EH_HARDRESET;
- else
- ehc->i.action |= ATA_EH_SOFTRESET;
-
+ ehc->i.action |= ATA_EH_RESET;
return 0;
}
}
@@ -2690,7 +2644,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
ehc->i.action = 0;
/* do we need to reset? */
- if (ehc->i.action & ATA_EH_RESET_MASK)
+ if (ehc->i.action & ATA_EH_RESET)
reset = 1;
ata_link_for_each_dev(dev, link)
@@ -2702,13 +2656,13 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
/* if PMP is attached, this function only deals with
* downstream links, port should stay thawed.
*/
- if (!ap->nr_pmp_links)
+ if (!sata_pmp_attached(ap))
ata_eh_freeze_port(ap);
ata_port_for_each_link(link, ap) {
struct ata_eh_context *ehc = &link->eh_context;
- if (!(ehc->i.action & ATA_EH_RESET_MASK))
+ if (!(ehc->i.action & ATA_EH_RESET))
continue;
rc = ata_eh_reset(link, ata_link_nr_vacant(link),
@@ -2721,7 +2675,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
}
}
- if (!ap->nr_pmp_links)
+ if (!sata_pmp_attached(ap))
ata_eh_thaw_port(ap);
}
@@ -2765,7 +2719,7 @@ dev_fail:
/* PMP reset requires working host port.
* Can't retry if it's frozen.
*/
- if (ap->nr_pmp_links)
+ if (sata_pmp_attached(ap))
goto out;
break;
}
@@ -2817,18 +2771,11 @@ void ata_eh_finish(struct ata_port *ap)
/* FIXME: Once EH migration is complete,
* generate sense data in this function,
* considering both err_mask and tf.
- *
- * There's no point in retrying invalid
- * (detected by libata) and non-IO device
- * errors (rejected by device). Finish them
- * immediately.
*/
- if ((qc->err_mask & AC_ERR_INVALID) ||
- (!(qc->flags & ATA_QCFLAG_IO) &&
- qc->err_mask == AC_ERR_DEV))
- ata_eh_qc_complete(qc);
- else
+ if (qc->flags & ATA_QCFLAG_RETRY)
ata_eh_qc_retry(qc);
+ else
+ ata_eh_qc_complete(qc);
} else {
if (qc->flags & ATA_QCFLAG_SENSE_VALID) {
ata_eh_qc_complete(qc);
@@ -2848,6 +2795,7 @@ void ata_eh_finish(struct ata_port *ap)
/**
* ata_do_eh - do standard error handling
* @ap: host port to handle error for
+ *
* @prereset: prereset method (can be NULL)
* @softreset: softreset method (can be NULL)
* @hardreset: hardreset method (can be NULL)
@@ -2878,6 +2826,27 @@ void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_eh_finish(ap);
}
+/**
+ * ata_std_error_handler - standard error handler
+ * @ap: host port to handle error for
+ *
+ * Standard error handler
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep).
+ */
+void ata_std_error_handler(struct ata_port *ap)
+{
+ struct ata_port_operations *ops = ap->ops;
+ 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))
+ hardreset = NULL;
+
+ ata_do_eh(ap, ops->prereset, ops->softreset, hardreset, ops->postreset);
+}
+
#ifdef CONFIG_PM
/**
* ata_eh_handle_port_suspend - perform port suspend operation
diff --git a/drivers/ata/libata-pmp.c b/drivers/ata/libata-pmp.c
index d91f5090ba9d..ff1822a7da38 100644
--- a/drivers/ata/libata-pmp.c
+++ b/drivers/ata/libata-pmp.c
@@ -11,6 +11,14 @@
#include <linux/libata.h>
#include "libata.h"
+const struct ata_port_operations sata_pmp_port_ops = {
+ .inherits = &sata_port_ops,
+ .pmp_prereset = ata_std_prereset,
+ .pmp_hardreset = sata_std_hardreset,
+ .pmp_postreset = ata_std_postreset,
+ .error_handler = sata_pmp_error_handler,
+};
+
/**
* sata_pmp_read - read PMP register
* @link: link to read PMP register for
@@ -176,140 +184,6 @@ int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val)
}
/**
- * sata_pmp_std_prereset - prepare PMP link for reset
- * @link: link to be reset
- * @deadline: deadline jiffies for the operation
- *
- * @link is about to be reset. Initialize it.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline)
-{
- struct ata_eh_context *ehc = &link->eh_context;
- const unsigned long *timing = sata_ehc_deb_timing(ehc);
- int rc;
-
- /* force HRST? */
- if (link->flags & ATA_LFLAG_NO_SRST)
- ehc->i.action |= ATA_EH_HARDRESET;
-
- /* handle link resume */
- if ((ehc->i.flags & ATA_EHI_RESUME_LINK) &&
- (link->flags & ATA_LFLAG_HRST_TO_RESUME))
- ehc->i.action |= ATA_EH_HARDRESET;
-
- /* if we're about to do hardreset, nothing more to do */
- if (ehc->i.action & ATA_EH_HARDRESET)
- return 0;
-
- /* resume link */
- rc = sata_link_resume(link, timing, deadline);
- if (rc) {
- /* phy resume failed */
- ata_link_printk(link, KERN_WARNING, "failed to resume link "
- "for reset (errno=%d)\n", rc);
- return rc;
- }
-
- /* clear SError bits including .X which blocks the port when set */
- rc = sata_scr_write(link, SCR_ERROR, 0xffffffff);
- if (rc) {
- ata_link_printk(link, KERN_ERR,
- "failed to clear SError (errno=%d)\n", rc);
- return rc;
- }
-
- return 0;
-}
-
-/**
- * sata_pmp_std_hardreset - standard hardreset method for PMP link
- * @link: link to be reset
- * @class: resulting class of attached device
- * @deadline: deadline jiffies for the operation
- *
- * Hardreset PMP port @link. Note that this function doesn't
- * wait for BSY clearance. There simply isn't a generic way to
- * wait the event. Instead, this function return -EAGAIN thus
- * telling libata-EH to followup with softreset.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- *
- * RETURNS:
- * 0 on success, -errno otherwise.
- */
-int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
-{
- const unsigned long *timing = sata_ehc_deb_timing(&link->eh_context);
- u32 tmp;
- int rc;
-
- DPRINTK("ENTER\n");
-
- /* do hardreset */
- rc = sata_link_hardreset(link, timing, deadline);
- if (rc) {
- ata_link_printk(link, KERN_ERR,
- "COMRESET failed (errno=%d)\n", rc);
- goto out;
- }
-
- /* clear SError bits including .X which blocks the port when set */
- rc = sata_scr_write(link, SCR_ERROR, 0xffffffff);
- if (rc) {
- ata_link_printk(link, KERN_ERR, "failed to clear SError "
- "during hardreset (errno=%d)\n", rc);
- goto out;
- }
-
- /* if device is present, follow up with srst to wait for !BSY */
- if (ata_link_online(link))
- rc = -EAGAIN;
- out:
- /* if SCR isn't accessible, we need to reset the PMP */
- if (rc && rc != -EAGAIN && sata_scr_read(link, SCR_STATUS, &tmp))
- rc = -ERESTART;
-
- DPRINTK("EXIT, rc=%d\n", rc);
- return rc;
-}
-
-/**
- * ata_std_postreset - standard postreset method for PMP link
- * @link: the target ata_link
- * @classes: classes of attached devices
- *
- * This function is invoked after a successful reset. Note that
- * the device might have been reset more than once using
- * different reset methods before postreset is invoked.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- */
-void sata_pmp_std_postreset(struct ata_link *link, unsigned int *class)
-{
- u32 serror;
-
- DPRINTK("ENTER\n");
-
- /* clear SError */
- if (sata_scr_read(link, SCR_ERROR, &serror) == 0)
- sata_scr_write(link, SCR_ERROR, serror);
-
- /* print link status */
- sata_print_link_status(link);
-
- DPRINTK("EXIT\n");
-}
-
-/**
* sata_pmp_read_gscr - read GSCR block of SATA PMP
* @dev: PMP device
* @gscr: buffer to read GSCR block into
@@ -444,9 +318,8 @@ static int sata_pmp_init_links(struct ata_port *ap, int nr_ports)
struct ata_eh_context *ehc = &link->eh_context;
link->flags = 0;
- ehc->i.probe_mask |= 1;
- ehc->i.action |= ATA_EH_SOFTRESET;
- ehc->i.flags |= ATA_EHI_RESUME_LINK;
+ ehc->i.probe_mask |= ATA_ALL_DEVICES;
+ ehc->i.action |= ATA_EH_RESET;
}
return 0;
@@ -462,9 +335,6 @@ static void sata_pmp_quirks(struct ata_port *ap)
if (vendor == 0x1095 && devid == 0x3726) {
/* sil3726 quirks */
ata_port_for_each_link(link, ap) {
- /* SError.N need a kick in the ass to get working */
- link->flags |= ATA_LFLAG_HRST_TO_RESUME;
-
/* class code report is unreliable */
if (link->pmp < 5)
link->flags |= ATA_LFLAG_ASSUME_ATA;
@@ -477,9 +347,6 @@ static void sata_pmp_quirks(struct ata_port *ap)
} else if (vendor == 0x1095 && devid == 0x4723) {
/* sil4723 quirks */
ata_port_for_each_link(link, ap) {
- /* SError.N need a kick in the ass to get working */
- link->flags |= ATA_LFLAG_HRST_TO_RESUME;
-
/* class code report is unreliable */
if (link->pmp < 2)
link->flags |= ATA_LFLAG_ASSUME_ATA;
@@ -492,9 +359,6 @@ static void sata_pmp_quirks(struct ata_port *ap)
} else if (vendor == 0x1095 && devid == 0x4726) {
/* sil4726 quirks */
ata_port_for_each_link(link, ap) {
- /* SError.N need a kick in the ass to get working */
- link->flags |= ATA_LFLAG_HRST_TO_RESUME;
-
/* Class code report is unreliable and SRST
* times out under certain configurations.
* Config device can be at port 0 or 5 and
@@ -522,13 +386,6 @@ static void sata_pmp_quirks(struct ata_port *ap)
* otherwise. Don't try hard to recover it.
*/
ap->pmp_link[ap->nr_pmp_links - 1].flags |= ATA_LFLAG_NO_RETRY;
- } else if (vendor == 0x11ab && devid == 0x4140) {
- /* Marvell 88SM4140 quirks. Fan-out ports require PHY
- * reset to work; other than that, it behaves very
- * nicely.
- */
- ata_port_for_each_link(link, ap)
- link->flags |= ATA_LFLAG_HRST_TO_RESUME;
}
}
@@ -554,7 +411,7 @@ int sata_pmp_attach(struct ata_device *dev)
int rc;
/* is it hanging off the right place? */
- if (!(ap->flags & ATA_FLAG_PMP)) {
+ if (!sata_pmp_supported(ap)) {
ata_dev_printk(dev, KERN_ERR,
"host does not support Port Multiplier\n");
return -EINVAL;
@@ -840,13 +697,12 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
retry:
ehc->classes[0] = ATA_DEV_UNKNOWN;
- if (ehc->i.action & ATA_EH_RESET_MASK) {
+ if (ehc->i.action & ATA_EH_RESET) {
struct ata_link *tlink;
ata_eh_freeze_port(ap);
/* reset */
- ehc->i.action = ATA_EH_HARDRESET;
rc = ata_eh_reset(link, 0, prereset, softreset, hardreset,
postreset);
if (rc) {
@@ -858,8 +714,12 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
ata_eh_thaw_port(ap);
/* PMP is reset, SErrors cannot be trusted, scan all */
- ata_port_for_each_link(tlink, ap)
- ata_ehi_schedule_probe(&tlink->eh_context.i);
+ ata_port_for_each_link(tlink, ap) {
+ struct ata_eh_context *ehc = &tlink->eh_context;
+
+ ehc->i.probe_mask |= ATA_ALL_DEVICES;
+ ehc->i.action |= ATA_EH_RESET;
+ }
}
/* If revalidation is requested, revalidate and reconfigure;
@@ -874,7 +734,7 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
tries--;
if (rc == -ENODEV) {
- ehc->i.probe_mask |= 1;
+ ehc->i.probe_mask |= ATA_ALL_DEVICES;
detach = 1;
/* give it just two more chances */
tries = min(tries, 2);
@@ -890,11 +750,11 @@ static int sata_pmp_eh_recover_pmp(struct ata_port *ap,
reval_failed = 1;
ata_dev_printk(dev, KERN_WARNING,
- "retrying hardreset%s\n",
+ "retrying reset%s\n",
sleep ? " in 5 secs" : "");
if (sleep)
ssleep(5);
- ehc->i.action |= ATA_EH_HARDRESET;
+ ehc->i.action |= ATA_EH_RESET;
goto retry;
} else {
ata_dev_printk(dev, KERN_ERR, "failed to recover PMP "
@@ -938,10 +798,8 @@ static int sata_pmp_eh_handle_disabled_links(struct ata_port *ap)
/* Some PMPs require hardreset sequence to get
* SError.N working.
*/
- if ((link->flags & ATA_LFLAG_HRST_TO_RESUME) &&
- (link->eh_context.i.flags & ATA_EHI_RESUME_LINK))
- sata_link_hardreset(link, sata_deb_timing_normal,
- jiffies + ATA_TMOUT_INTERNAL_QUICK);
+ sata_link_hardreset(link, sata_deb_timing_normal,
+ jiffies + ATA_TMOUT_INTERNAL_QUICK, NULL, NULL);
/* unconditionally clear SError.N */
rc = sata_scr_write(link, SCR_ERROR, SERR_PHYRDY_CHG);
@@ -987,14 +845,6 @@ static int sata_pmp_handle_link_fail(struct ata_link *link, int *link_tries)
/**
* sata_pmp_eh_recover - recover PMP-enabled port
* @ap: ATA port to recover
- * @prereset: prereset method (can be NULL)
- * @softreset: softreset method
- * @hardreset: hardreset method
- * @postreset: postreset method (can be NULL)
- * @pmp_prereset: PMP prereset method (can be NULL)
- * @pmp_softreset: PMP softreset method (can be NULL)
- * @pmp_hardreset: PMP hardreset method (can be NULL)
- * @pmp_postreset: PMP postreset method (can be NULL)
*
* Drive EH recovery operation for PMP enabled port @ap. This
* function recovers host and PMP ports with proper retrials and
@@ -1007,12 +857,9 @@ static int sata_pmp_handle_link_fail(struct ata_link *link, int *link_tries)
* RETURNS:
* 0 on success, -errno on failure.
*/
-static int sata_pmp_eh_recover(struct ata_port *ap,
- ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
- ata_reset_fn_t hardreset, ata_postreset_fn_t postreset,
- ata_prereset_fn_t pmp_prereset, ata_reset_fn_t pmp_softreset,
- ata_reset_fn_t pmp_hardreset, ata_postreset_fn_t pmp_postreset)
+static int sata_pmp_eh_recover(struct ata_port *ap)
{
+ struct ata_port_operations *ops = ap->ops;
int pmp_tries, link_tries[SATA_PMP_MAX_PORTS];
struct ata_link *pmp_link = &ap->link;
struct ata_device *pmp_dev = pmp_link->device;
@@ -1029,9 +876,9 @@ static int sata_pmp_eh_recover(struct ata_port *ap,
retry:
/* PMP attached? */
- if (!ap->nr_pmp_links) {
- rc = ata_eh_recover(ap, prereset, softreset, hardreset,
- postreset, NULL);
+ if (!sata_pmp_attached(ap)) {
+ rc = ata_eh_recover(ap, ops->prereset, ops->softreset,
+ ops->hardreset, ops->postreset, NULL);
if (rc) {
ata_link_for_each_dev(dev, &ap->link)
ata_dev_disable(dev);
@@ -1049,8 +896,8 @@ static int sata_pmp_eh_recover(struct ata_port *ap,
}
/* recover pmp */
- rc = sata_pmp_eh_recover_pmp(ap, prereset, softreset, hardreset,
- postreset);
+ rc = sata_pmp_eh_recover_pmp(ap, ops->prereset, ops->softreset,
+ ops->hardreset, ops->postreset);
if (rc)
goto pmp_fail;
@@ -1060,8 +907,8 @@ static int sata_pmp_eh_recover(struct ata_port *ap,
goto pmp_fail;
/* recover links */
- rc = ata_eh_recover(ap, pmp_prereset, pmp_softreset, pmp_hardreset,
- pmp_postreset, &link);
+ rc = ata_eh_recover(ap, ops->pmp_prereset, ops->pmp_softreset,
+ ops->pmp_hardreset, ops->pmp_postreset, &link);
if (rc)
goto link_fail;
@@ -1124,7 +971,7 @@ static int sata_pmp_eh_recover(struct ata_port *ap,
link_fail:
if (sata_pmp_handle_link_fail(link, link_tries)) {
- pmp_ehc->i.action |= ATA_EH_HARDRESET;
+ pmp_ehc->i.action |= ATA_EH_RESET;
goto retry;
}
@@ -1136,13 +983,13 @@ static int sata_pmp_eh_recover(struct ata_port *ap,
if (ap->pflags & ATA_PFLAG_UNLOADING)
return rc;
- if (!ap->nr_pmp_links)
+ if (!sata_pmp_attached(ap))
goto retry;
if (--pmp_tries) {
ata_port_printk(ap, KERN_WARNING,
"failed to recover PMP, retrying in 5 secs\n");
- pmp_ehc->i.action |= ATA_EH_HARDRESET;
+ pmp_ehc->i.action |= ATA_EH_RESET;
ssleep(5);
goto retry;
}
@@ -1157,16 +1004,8 @@ static int sata_pmp_eh_recover(struct ata_port *ap,
}
/**
- * sata_pmp_do_eh - do standard error handling for PMP-enabled host
+ * sata_pmp_error_handler - do standard error handling for PMP-enabled host
* @ap: host port to handle error for
- * @prereset: prereset method (can be NULL)
- * @softreset: softreset method
- * @hardreset: hardreset method
- * @postreset: postreset method (can be NULL)
- * @pmp_prereset: PMP prereset method (can be NULL)
- * @pmp_softreset: PMP softreset method (can be NULL)
- * @pmp_hardreset: PMP hardreset method (can be NULL)
- * @pmp_postreset: PMP postreset method (can be NULL)
*
* Perform standard error handling sequence for PMP-enabled host
* @ap.
@@ -1174,16 +1013,14 @@ static int sata_pmp_eh_recover(struct ata_port *ap,
* LOCKING:
* Kernel thread context (may sleep).
*/
-void sata_pmp_do_eh(struct ata_port *ap,
- ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
- ata_reset_fn_t hardreset, ata_postreset_fn_t postreset,
- ata_prereset_fn_t pmp_prereset, ata_reset_fn_t pmp_softreset,
- ata_reset_fn_t pmp_hardreset, ata_postreset_fn_t pmp_postreset)
+void sata_pmp_error_handler(struct ata_port *ap)
{
ata_eh_autopsy(ap);
ata_eh_report(ap);
- sata_pmp_eh_recover(ap, prereset, softreset, hardreset, postreset,
- pmp_prereset, pmp_softreset, pmp_hardreset,
- pmp_postreset);
+ sata_pmp_eh_recover(ap);
ata_eh_finish(ap);
}
+
+EXPORT_SYMBOL_GPL(sata_pmp_port_ops);
+EXPORT_SYMBOL_GPL(sata_pmp_qc_defer_cmd_switch);
+EXPORT_SYMBOL_GPL(sata_pmp_error_handler);
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 15795394b0a8..fedf62de9460 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2393,7 +2393,9 @@ static void atapi_request_sense(struct ata_queued_cmd *qc)
/* FIXME: is this needed? */
memset(cmd->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
- ap->ops->tf_read(ap, &qc->tf);
+#ifdef CONFIG_ATA_SFF
+ ap->ops->sff_tf_read(ap, &qc->tf);
+#endif
/* fill these in, for the case where they are -not- overwritten */
cmd->sense_buffer[0] = 0x70;
@@ -2615,7 +2617,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
static struct ata_device *ata_find_dev(struct ata_port *ap, int devno)
{
- if (ap->nr_pmp_links == 0) {
+ if (!sata_pmp_attached(ap)) {
if (likely(devno < ata_link_max_devices(&ap->link)))
return &ap->link.device[devno];
} else {
@@ -2632,7 +2634,7 @@ static struct ata_device *__ata_scsi_find_dev(struct ata_port *ap,
int devno;
/* skip commands not addressed to targets we simulate */
- if (ap->nr_pmp_links == 0) {
+ if (!sata_pmp_attached(ap)) {
if (unlikely(scsidev->channel || scsidev->lun))
return NULL;
devno = scsidev->id;
@@ -3490,7 +3492,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
if (lun != SCAN_WILD_CARD && lun)
return -EINVAL;
- if (ap->nr_pmp_links == 0) {
+ if (!sata_pmp_attached(ap)) {
if (channel != SCAN_WILD_CARD && channel)
return -EINVAL;
devno = id;
@@ -3507,8 +3509,8 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
ata_port_for_each_link(link, ap) {
struct ata_eh_info *ehi = &link->eh_info;
- ehi->probe_mask |= (1 << ata_link_max_devices(link)) - 1;
- ehi->action |= ATA_EH_SOFTRESET;
+ ehi->probe_mask |= ATA_ALL_DEVICES;
+ ehi->action |= ATA_EH_RESET;
}
} else {
struct ata_device *dev = ata_find_dev(ap, devno);
@@ -3516,8 +3518,7 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
if (dev) {
struct ata_eh_info *ehi = &dev->link->eh_info;
ehi->probe_mask |= 1 << dev->devno;
- ehi->action |= ATA_EH_SOFTRESET;
- ehi->flags |= ATA_EHI_RESUME_LINK;
+ ehi->action |= ATA_EH_RESET;
} else
rc = -EINVAL;
}
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 20dc572fb45a..15499522e642 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -35,11 +35,377 @@
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/libata.h>
+#include <linux/highmem.h>
#include "libata.h"
+const struct ata_port_operations ata_sff_port_ops = {
+ .inherits = &ata_base_port_ops,
+
+ .qc_prep = ata_sff_qc_prep,
+ .qc_issue = ata_sff_qc_issue,
+ .qc_fill_rtf = ata_sff_qc_fill_rtf,
+
+ .freeze = ata_sff_freeze,
+ .thaw = ata_sff_thaw,
+ .prereset = ata_sff_prereset,
+ .softreset = ata_sff_softreset,
+ .hardreset = sata_sff_hardreset,
+ .postreset = ata_sff_postreset,
+ .error_handler = ata_sff_error_handler,
+ .post_internal_cmd = ata_sff_post_internal_cmd,
+
+ .sff_dev_select = ata_sff_dev_select,
+ .sff_check_status = ata_sff_check_status,
+ .sff_tf_load = ata_sff_tf_load,
+ .sff_tf_read = ata_sff_tf_read,
+ .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,
+
+ .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
+ *
+ * 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
+ *
+ * Reads ATA taskfile status register for currently-selected device
+ * and return its value. This also clears pending interrupts
+ * from this device
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+u8 ata_sff_check_status(struct ata_port *ap)
+{
+ return ioread8(ap->ioaddr.status_addr);
+}
+
+/**
+ * ata_sff_altstatus - Read device alternate status reg
+ * @ap: port where the device is
+ *
+ * Reads ATA taskfile alternate status register for
+ * currently-selected device and return its value.
+ *
+ * Note: may NOT be used as the check_altstatus() entry in
+ * ata_port_operations.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+u8 ata_sff_altstatus(struct ata_port *ap)
+{
+ if (ap->ops->sff_check_altstatus)
+ return ap->ops->sff_check_altstatus(ap);
+
+ return ioread8(ap->ioaddr.altstatus_addr);
+}
+
+/**
+ * ata_sff_busy_sleep - sleep until BSY clears, or timeout
+ * @ap: port containing status register to be polled
+ * @tmout_pat: impatience timeout
+ * @tmout: overall timeout
+ *
+ * Sleep until ATA Status register bit BSY clears,
+ * or a timeout occurs.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_sff_busy_sleep(struct ata_port *ap,
+ unsigned long tmout_pat, unsigned long tmout)
+{
+ unsigned long timer_start, timeout;
+ u8 status;
+
+ status = ata_sff_busy_wait(ap, ATA_BUSY, 300);
+ timer_start = jiffies;
+ timeout = timer_start + tmout_pat;
+ while (status != 0xff && (status & ATA_BUSY) &&
+ time_before(jiffies, timeout)) {
+ msleep(50);
+ status = ata_sff_busy_wait(ap, ATA_BUSY, 3);
+ }
+
+ if (status != 0xff && (status & ATA_BUSY))
+ ata_port_printk(ap, KERN_WARNING,
+ "port is slow to respond, please be patient "
+ "(Status 0x%x)\n", status);
+
+ timeout = timer_start + tmout;
+ while (status != 0xff && (status & ATA_BUSY) &&
+ time_before(jiffies, timeout)) {
+ msleep(50);
+ status = ap->ops->sff_check_status(ap);
+ }
+
+ if (status == 0xff)
+ return -ENODEV;
+
+ if (status & ATA_BUSY) {
+ ata_port_printk(ap, KERN_ERR, "port failed to respond "
+ "(%lu secs, Status 0x%x)\n",
+ tmout / HZ, status);
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+static int ata_sff_check_ready(struct ata_link *link)
+{
+ u8 status = link->ap->ops->sff_check_status(link->ap);
+
+ if (!(status & ATA_BUSY))
+ return 1;
+ if (status == 0xff)
+ return -ENODEV;
+ return 0;
+}
+
+/**
+ * ata_sff_wait_ready - sleep until BSY clears, or timeout
+ * @link: SFF link to wait ready status for
+ * @deadline: deadline jiffies for the operation
+ *
+ * Sleep until ATA Status register bit BSY clears, or timeout
+ * occurs.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline)
+{
+ return ata_wait_ready(link, deadline, ata_sff_check_ready);
+}
+
+/**
+ * ata_sff_dev_select - Select device 0/1 on ATA bus
+ * @ap: ATA channel to manipulate
+ * @device: ATA device (numbered from zero) to select
+ *
+ * Use the method defined in the ATA specification to
+ * make either device 0, or device 1, active on the
+ * ATA channel. Works with both PIO and MMIO.
+ *
+ * May be used as the dev_select() entry in ata_port_operations.
+ *
+ * LOCKING:
+ * caller.
+ */
+void ata_sff_dev_select(struct ata_port *ap, unsigned int device)
+{
+ u8 tmp;
+
+ if (device == 0)
+ tmp = ATA_DEVICE_OBS;
+ else
+ tmp = ATA_DEVICE_OBS | ATA_DEV1;
+
+ iowrite8(tmp, ap->ioaddr.device_addr);
+ ata_sff_pause(ap); /* needed; also flushes, for mmio */
+}
+
+/**
+ * ata_dev_select - Select device 0/1 on ATA bus
+ * @ap: ATA channel to manipulate
+ * @device: ATA device (numbered from zero) to select
+ * @wait: non-zero to wait for Status register BSY bit to clear
+ * @can_sleep: non-zero if context allows sleeping
+ *
+ * Use the method defined in the ATA specification to
+ * make either device 0, or device 1, active on the
+ * ATA channel.
+ *
+ * This is a high-level version of ata_sff_dev_select(), which
+ * additionally provides the services of inserting the proper
+ * pauses and status polling, where needed.
+ *
+ * LOCKING:
+ * caller.
+ */
+void ata_dev_select(struct ata_port *ap, unsigned int device,
+ unsigned int wait, unsigned int can_sleep)
+{
+ if (ata_msg_probe(ap))
+ ata_port_printk(ap, KERN_INFO, "ata_dev_select: ENTER, "
+ "device %u, wait %u\n", device, wait);
+
+ if (wait)
+ ata_wait_idle(ap);
+
+ ap->ops->sff_dev_select(ap, device);
+
+ if (wait) {
+ if (can_sleep && ap->link.device[device].class == ATA_DEV_ATAPI)
+ msleep(150);
+ ata_wait_idle(ap);
+ }
+}
+
/**
- * ata_irq_on - Enable interrupts on a port.
+ * ata_sff_irq_on - Enable interrupts on a port.
* @ap: Port on which interrupts are enabled.
*
* Enable interrupts on a legacy IDE device using MMIO or PIO,
@@ -48,7 +414,7 @@
* LOCKING:
* Inherited from caller.
*/
-u8 ata_irq_on(struct ata_port *ap)
+u8 ata_sff_irq_on(struct ata_port *ap)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
u8 tmp;
@@ -60,13 +426,34 @@ u8 ata_irq_on(struct ata_port *ap)
iowrite8(ap->ctl, ioaddr->ctl_addr);
tmp = ata_wait_idle(ap);
- ap->ops->irq_clear(ap);
+ ap->ops->sff_irq_clear(ap);
return tmp;
}
/**
- * ata_tf_load - send taskfile registers to host controller
+ * 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
*
@@ -75,8 +462,7 @@ u8 ata_irq_on(struct ata_port *ap)
* LOCKING:
* Inherited from caller.
*/
-
-void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
@@ -126,26 +512,7 @@ void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
}
/**
- * ata_exec_command - issue ATA command to host controller
- * @ap: port to which command is being issued
- * @tf: ATA taskfile register set
- *
- * Issues ATA command, with proper synchronization with interrupt
- * handler / other threads.
- *
- * LOCKING:
- * spin_lock_irqsave(host lock)
- */
-void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
-{
- DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
-
- iowrite8(tf->command, ap->ioaddr.command_addr);
- ata_pause(ap);
-}
-
-/**
- * ata_tf_read - input device's ATA taskfile shadow registers
+ * ata_sff_tf_read - input device's ATA taskfile shadow registers
* @ap: Port from which input is read
* @tf: ATA taskfile register set for storing input
*
@@ -157,11 +524,11 @@ void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
* LOCKING:
* Inherited from caller.
*/
-void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+void ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
- tf->command = ata_check_status(ap);
+ tf->command = ata_sff_check_status(ap);
tf->feature = ioread8(ioaddr->error_addr);
tf->nsect = ioread8(ioaddr->nsect_addr);
tf->lbal = ioread8(ioaddr->lbal_addr);
@@ -185,165 +552,1028 @@ void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
}
/**
- * ata_check_status - Read device status reg & clear interrupt
- * @ap: port where the device is
+ * ata_sff_exec_command - issue ATA command to host controller
+ * @ap: port to which command is being issued
+ * @tf: ATA taskfile register set
*
- * Reads ATA taskfile status register for currently-selected device
- * and return its value. This also clears pending interrupts
- * from this device
+ * Issues ATA command, with proper synchronization with interrupt
+ * handler / other threads.
*
* LOCKING:
- * Inherited from caller.
+ * spin_lock_irqsave(host lock)
*/
-u8 ata_check_status(struct ata_port *ap)
+void ata_sff_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
{
- return ioread8(ap->ioaddr.status_addr);
+ DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
+
+ iowrite8(tf->command, ap->ioaddr.command_addr);
+ ata_sff_pause(ap);
}
/**
- * ata_altstatus - Read device alternate status reg
- * @ap: port where the device is
+ * ata_tf_to_host - issue ATA taskfile to host controller
+ * @ap: port to which command is being issued
+ * @tf: ATA taskfile register set
*
- * Reads ATA taskfile alternate status register for
- * currently-selected device and return its value.
+ * Issues ATA taskfile register set to ATA host controller,
+ * with proper synchronization with interrupt handler and
+ * other threads.
*
- * Note: may NOT be used as the check_altstatus() entry in
- * ata_port_operations.
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ */
+static inline void ata_tf_to_host(struct ata_port *ap,
+ const struct ata_taskfile *tf)
+{
+ ap->ops->sff_tf_load(ap, tf);
+ ap->ops->sff_exec_command(ap, tf);
+}
+
+/**
+ * ata_sff_data_xfer - Transfer data by PIO
+ * @dev: device to target
+ * @buf: data buffer
+ * @buflen: buffer length
+ * @rw: read/write
+ *
+ * Transfer data from/to the device data register by PIO.
*
* LOCKING:
* Inherited from caller.
+ *
+ * RETURNS:
+ * Bytes consumed.
*/
-u8 ata_altstatus(struct ata_port *ap)
+unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf,
+ unsigned int buflen, int rw)
{
- if (ap->ops->check_altstatus)
- return ap->ops->check_altstatus(ap);
+ struct ata_port *ap = dev->link->ap;
+ void __iomem *data_addr = ap->ioaddr.data_addr;
+ unsigned int words = buflen >> 1;
- return ioread8(ap->ioaddr.altstatus_addr);
+ /* Transfer multiple of 2 bytes */
+ if (rw == READ)
+ ioread16_rep(data_addr, buf, words);
+ else
+ iowrite16_rep(data_addr, buf, words);
+
+ /* Transfer trailing 1 byte, if any. */
+ if (unlikely(buflen & 0x01)) {
+ __le16 align_buf[1] = { 0 };
+ unsigned char *trailing_buf = buf + buflen - 1;
+
+ if (rw == READ) {
+ align_buf[0] = cpu_to_le16(ioread16(data_addr));
+ memcpy(trailing_buf, align_buf, 1);
+ } else {
+ memcpy(align_buf, trailing_buf, 1);
+ iowrite16(le16_to_cpu(align_buf[0]), data_addr);
+ }
+ words++;
+ }
+
+ return words << 1;
}
/**
- * ata_bmdma_setup - Set up PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
+ * ata_sff_data_xfer_noirq - Transfer data by PIO
+ * @dev: device to target
+ * @buf: data buffer
+ * @buflen: buffer length
+ * @rw: read/write
+ *
+ * Transfer data from/to the device data register by PIO. Do the
+ * transfer with interrupts disabled.
*
* LOCKING:
- * spin_lock_irqsave(host lock)
+ * Inherited from caller.
+ *
+ * RETURNS:
+ * Bytes consumed.
*/
-void ata_bmdma_setup(struct ata_queued_cmd *qc)
+unsigned int ata_sff_data_xfer_noirq(struct ata_device *dev, unsigned char *buf,
+ unsigned int buflen, int rw)
+{
+ unsigned long flags;
+ unsigned int consumed;
+
+ local_irq_save(flags);
+ consumed = ata_sff_data_xfer(dev, buf, buflen, rw);
+ local_irq_restore(flags);
+
+ return consumed;
+}
+
+/**
+ * ata_pio_sector - Transfer a sector of data.
+ * @qc: Command on going
+ *
+ * Transfer qc->sect_size bytes of data from/to the ATA device.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void ata_pio_sector(struct ata_queued_cmd *qc)
{
+ int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
struct ata_port *ap = qc->ap;
- unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
- u8 dmactl;
+ struct page *page;
+ unsigned int offset;
+ unsigned char *buf;
- /* 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);
+ if (qc->curbytes == qc->nbytes - qc->sect_size)
+ ap->hsm_task_state = HSM_ST_LAST;
- /* 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);
+ page = sg_page(qc->cursg);
+ offset = qc->cursg->offset + qc->cursg_ofs;
- /* issue r/w command */
- ap->ops->exec_command(ap, &qc->tf);
+ /* get the current page and offset */
+ page = nth_page(page, (offset >> PAGE_SHIFT));
+ offset %= PAGE_SIZE;
+
+ DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
+
+ if (PageHighMem(page)) {
+ unsigned long flags;
+
+ /* FIXME: use a bounce buffer */
+ local_irq_save(flags);
+ buf = kmap_atomic(page, KM_IRQ0);
+
+ /* do the actual data transfer */
+ ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size,
+ do_write);
+
+ kunmap_atomic(buf, KM_IRQ0);
+ local_irq_restore(flags);
+ } else {
+ buf = page_address(page);
+ ap->ops->sff_data_xfer(qc->dev, buf + offset, qc->sect_size,
+ do_write);
+ }
+
+ qc->curbytes += qc->sect_size;
+ qc->cursg_ofs += qc->sect_size;
+
+ if (qc->cursg_ofs == qc->cursg->length) {
+ qc->cursg = sg_next(qc->cursg);
+ qc->cursg_ofs = 0;
+ }
}
/**
- * ata_bmdma_start - Start a PCI IDE BMDMA transaction
- * @qc: Info associated with this ATA transaction.
+ * ata_pio_sectors - Transfer one or many sectors.
+ * @qc: Command on going
+ *
+ * Transfer one or many sectors of data from/to the
+ * ATA device for the DRQ request.
*
* LOCKING:
- * spin_lock_irqsave(host lock)
+ * Inherited from caller.
*/
-void ata_bmdma_start(struct ata_queued_cmd *qc)
+static void ata_pio_sectors(struct ata_queued_cmd *qc)
+{
+ if (is_multi_taskfile(&qc->tf)) {
+ /* READ/WRITE MULTIPLE */
+ unsigned int nsect;
+
+ WARN_ON(qc->dev->multi_count == 0);
+
+ nsect = min((qc->nbytes - qc->curbytes) / qc->sect_size,
+ qc->dev->multi_count);
+ while (nsect--)
+ ata_pio_sector(qc);
+ } else
+ ata_pio_sector(qc);
+
+ ata_sff_altstatus(qc->ap); /* flush */
+}
+
+/**
+ * atapi_send_cdb - Write CDB bytes to hardware
+ * @ap: Port to which ATAPI device is attached.
+ * @qc: Taskfile currently active
+ *
+ * When device has indicated its readiness to accept
+ * a CDB, this function is called. Send the CDB.
+ *
+ * LOCKING:
+ * caller.
+ */
+static void atapi_send_cdb(struct ata_port *ap, struct ata_queued_cmd *qc)
+{
+ /* send SCSI cdb */
+ DPRINTK("send cdb\n");
+ WARN_ON(qc->dev->cdb_len < 12);
+
+ ap->ops->sff_data_xfer(qc->dev, qc->cdb, qc->dev->cdb_len, 1);
+ ata_sff_altstatus(ap); /* flush */
+
+ switch (qc->tf.protocol) {
+ case ATAPI_PROT_PIO:
+ ap->hsm_task_state = HSM_ST;
+ break;
+ case ATAPI_PROT_NODATA:
+ ap->hsm_task_state = HSM_ST_LAST;
+ break;
+ case ATAPI_PROT_DMA:
+ ap->hsm_task_state = HSM_ST_LAST;
+ /* initiate bmdma */
+ ap->ops->bmdma_start(qc);
+ break;
+ }
+}
+
+/**
+ * __atapi_pio_bytes - Transfer data from/to the ATAPI device.
+ * @qc: Command on going
+ * @bytes: number of bytes
+ *
+ * Transfer Transfer data from/to the ATAPI device.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ *
+ */
+static int __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
{
+ int rw = (qc->tf.flags & ATA_TFLAG_WRITE) ? WRITE : READ;
struct ata_port *ap = qc->ap;
- u8 dmactl;
+ struct ata_device *dev = qc->dev;
+ struct ata_eh_info *ehi = &dev->link->eh_info;
+ struct scatterlist *sg;
+ struct page *page;
+ unsigned char *buf;
+ unsigned int offset, count, consumed;
+
+next_sg:
+ sg = qc->cursg;
+ if (unlikely(!sg)) {
+ ata_ehi_push_desc(ehi, "unexpected or too much trailing data "
+ "buf=%u cur=%u bytes=%u",
+ qc->nbytes, qc->curbytes, bytes);
+ return -1;
+ }
- /* 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);
+ page = sg_page(sg);
+ offset = sg->offset + qc->cursg_ofs;
- /* 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
+ /* get the current page and offset */
+ page = nth_page(page, (offset >> PAGE_SHIFT));
+ offset %= PAGE_SIZE;
+
+ /* don't overrun current sg */
+ count = min(sg->length - qc->cursg_ofs, bytes);
+
+ /* don't cross page boundaries */
+ count = min(count, (unsigned int)PAGE_SIZE - offset);
+
+ DPRINTK("data %s\n", qc->tf.flags & ATA_TFLAG_WRITE ? "write" : "read");
+
+ if (PageHighMem(page)) {
+ unsigned long flags;
+
+ /* FIXME: use bounce buffer */
+ local_irq_save(flags);
+ buf = kmap_atomic(page, KM_IRQ0);
+
+ /* do the actual data transfer */
+ consumed = ap->ops->sff_data_xfer(dev, buf + offset, count, rw);
+
+ kunmap_atomic(buf, KM_IRQ0);
+ local_irq_restore(flags);
+ } else {
+ buf = page_address(page);
+ consumed = ap->ops->sff_data_xfer(dev, buf + offset, count, rw);
+ }
+
+ bytes -= min(bytes, consumed);
+ qc->curbytes += count;
+ qc->cursg_ofs += count;
+
+ if (qc->cursg_ofs == sg->length) {
+ qc->cursg = sg_next(qc->cursg);
+ qc->cursg_ofs = 0;
+ }
+
+ /* consumed can be larger than count only for the last transfer */
+ WARN_ON(qc->cursg && count != consumed);
+
+ if (bytes)
+ goto next_sg;
+ return 0;
+}
+
+/**
+ * atapi_pio_bytes - Transfer data from/to the ATAPI device.
+ * @qc: Command on going
+ *
+ * Transfer Transfer data from/to the ATAPI device.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static void atapi_pio_bytes(struct ata_queued_cmd *qc)
+{
+ struct ata_port *ap = qc->ap;
+ struct ata_device *dev = qc->dev;
+ struct ata_eh_info *ehi = &dev->link->eh_info;
+ unsigned int ireason, bc_lo, bc_hi, bytes;
+ int i_write, do_write = (qc->tf.flags & ATA_TFLAG_WRITE) ? 1 : 0;
+
+ /* Abuse qc->result_tf for temp storage of intermediate TF
+ * here to save some kernel stack usage.
+ * For normal completion, qc->result_tf is not relevant. For
+ * error, qc->result_tf is later overwritten by ata_qc_complete().
+ * So, the correctness of qc->result_tf is not affected.
*/
+ ap->ops->sff_tf_read(ap, &qc->result_tf);
+ ireason = qc->result_tf.nsect;
+ bc_lo = qc->result_tf.lbam;
+ bc_hi = qc->result_tf.lbah;
+ bytes = (bc_hi << 8) | bc_lo;
+
+ /* shall be cleared to zero, indicating xfer of data */
+ if (unlikely(ireason & (1 << 0)))
+ goto atapi_check;
+
+ /* make sure transfer direction matches expected */
+ i_write = ((ireason & (1 << 1)) == 0) ? 1 : 0;
+ if (unlikely(do_write != i_write))
+ goto atapi_check;
+
+ if (unlikely(!bytes))
+ goto atapi_check;
+
+ VPRINTK("ata%u: xfering %d bytes\n", ap->print_id, bytes);
+
+ if (unlikely(__atapi_pio_bytes(qc, bytes)))
+ goto err_out;
+ ata_sff_altstatus(ap); /* flush */
+
+ return;
+
+ atapi_check:
+ ata_ehi_push_desc(ehi, "ATAPI check failed (ireason=0x%x bytes=%u)",
+ ireason, bytes);
+ err_out:
+ qc->err_mask |= AC_ERR_HSM;
+ ap->hsm_task_state = HSM_ST_ERR;
}
/**
- * ata_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
- * @ap: Port associated with this ATA transaction.
+ * ata_hsm_ok_in_wq - Check if the qc can be handled in the workqueue.
+ * @ap: the target ata_port
+ * @qc: qc on going
*
- * Clear interrupt and error flags in DMA status register.
+ * RETURNS:
+ * 1 if ok in workqueue, 0 otherwise.
+ */
+static inline int ata_hsm_ok_in_wq(struct ata_port *ap, struct ata_queued_cmd *qc)
+{
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ return 1;
+
+ if (ap->hsm_task_state == HSM_ST_FIRST) {
+ if (qc->tf.protocol == ATA_PROT_PIO &&
+ (qc->tf.flags & ATA_TFLAG_WRITE))
+ return 1;
+
+ if (ata_is_atapi(qc->tf.protocol) &&
+ !(qc->dev->flags & ATA_DFLAG_CDB_INTR))
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * ata_hsm_qc_complete - finish a qc running on standard HSM
+ * @qc: Command to complete
+ * @in_wq: 1 if called from workqueue, 0 otherwise
*
- * May be used as the irq_clear() entry in ata_port_operations.
+ * Finish @qc which is running on standard HSM.
*
* LOCKING:
- * spin_lock_irqsave(host lock)
+ * If @in_wq is zero, spin_lock_irqsave(host lock).
+ * Otherwise, none on entry and grabs host lock.
*/
-void ata_bmdma_irq_clear(struct ata_port *ap)
+static void ata_hsm_qc_complete(struct ata_queued_cmd *qc, int in_wq)
{
- void __iomem *mmio = ap->ioaddr.bmdma_addr;
+ struct ata_port *ap = qc->ap;
+ unsigned long flags;
- if (!mmio)
- return;
+ if (ap->ops->error_handler) {
+ if (in_wq) {
+ spin_lock_irqsave(ap->lock, flags);
+
+ /* EH might have kicked in while host lock is
+ * released.
+ */
+ qc = ata_qc_from_tag(ap, qc->tag);
+ if (qc) {
+ if (likely(!(qc->err_mask & AC_ERR_HSM))) {
+ ap->ops->sff_irq_on(ap);
+ ata_qc_complete(qc);
+ } else
+ ata_port_freeze(ap);
+ }
+
+ spin_unlock_irqrestore(ap->lock, flags);
+ } else {
+ if (likely(!(qc->err_mask & AC_ERR_HSM)))
+ ata_qc_complete(qc);
+ else
+ ata_port_freeze(ap);
+ }
+ } else {
+ if (in_wq) {
+ spin_lock_irqsave(ap->lock, flags);
+ ap->ops->sff_irq_on(ap);
+ ata_qc_complete(qc);
+ spin_unlock_irqrestore(ap->lock, flags);
+ } else
+ ata_qc_complete(qc);
+ }
+}
- iowrite8(ioread8(mmio + ATA_DMA_STATUS), mmio + ATA_DMA_STATUS);
+/**
+ * ata_sff_hsm_move - move the HSM to the next state.
+ * @ap: the target ata_port
+ * @qc: qc on going
+ * @status: current device status
+ * @in_wq: 1 if called from workqueue, 0 otherwise
+ *
+ * RETURNS:
+ * 1 when poll next status needed, 0 otherwise.
+ */
+int ata_sff_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
+ u8 status, int in_wq)
+{
+ unsigned long flags = 0;
+ int poll_next;
+
+ WARN_ON((qc->flags & ATA_QCFLAG_ACTIVE) == 0);
+
+ /* Make sure ata_sff_qc_issue() does not throw things
+ * like DMA polling into the workqueue. Notice that
+ * in_wq is not equivalent to (qc->tf.flags & ATA_TFLAG_POLLING).
+ */
+ WARN_ON(in_wq != ata_hsm_ok_in_wq(ap, qc));
+
+fsm_start:
+ DPRINTK("ata%u: protocol %d task_state %d (dev_stat 0x%X)\n",
+ ap->print_id, qc->tf.protocol, ap->hsm_task_state, status);
+
+ switch (ap->hsm_task_state) {
+ case HSM_ST_FIRST:
+ /* Send first data block or PACKET CDB */
+
+ /* If polling, we will stay in the work queue after
+ * sending the data. Otherwise, interrupt handler
+ * takes over after sending the data.
+ */
+ poll_next = (qc->tf.flags & ATA_TFLAG_POLLING);
+
+ /* check device status */
+ if (unlikely((status & ATA_DRQ) == 0)) {
+ /* handle BSY=0, DRQ=0 as error */
+ if (likely(status & (ATA_ERR | ATA_DF)))
+ /* device stops HSM for abort/error */
+ qc->err_mask |= AC_ERR_DEV;
+ else
+ /* HSM violation. Let EH handle this */
+ qc->err_mask |= AC_ERR_HSM;
+
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
+
+ /* Device should not ask for data transfer (DRQ=1)
+ * when it finds something wrong.
+ * We ignore DRQ here and stop the HSM by
+ * changing hsm_task_state to HSM_ST_ERR and
+ * let the EH abort the command or reset the device.
+ */
+ if (unlikely(status & (ATA_ERR | ATA_DF))) {
+ /* Some ATAPI tape drives forget to clear the ERR bit
+ * when doing the next command (mostly request sense).
+ * We ignore ERR here to workaround and proceed sending
+ * the CDB.
+ */
+ if (!(qc->dev->horkage & ATA_HORKAGE_STUCK_ERR)) {
+ ata_port_printk(ap, KERN_WARNING,
+ "DRQ=1 with device error, "
+ "dev_stat 0x%X\n", status);
+ qc->err_mask |= AC_ERR_HSM;
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
+ }
+
+ /* Send the CDB (atapi) or the first data block (ata pio out).
+ * During the state transition, interrupt handler shouldn't
+ * be invoked before the data transfer is complete and
+ * hsm_task_state is changed. Hence, the following locking.
+ */
+ if (in_wq)
+ spin_lock_irqsave(ap->lock, flags);
+
+ if (qc->tf.protocol == ATA_PROT_PIO) {
+ /* PIO data out protocol.
+ * send first data block.
+ */
+
+ /* ata_pio_sectors() might change the state
+ * to HSM_ST_LAST. so, the state is changed here
+ * before ata_pio_sectors().
+ */
+ ap->hsm_task_state = HSM_ST;
+ ata_pio_sectors(qc);
+ } else
+ /* send CDB */
+ atapi_send_cdb(ap, qc);
+
+ if (in_wq)
+ spin_unlock_irqrestore(ap->lock, flags);
+
+ /* if polling, ata_pio_task() handles the rest.
+ * otherwise, interrupt handler takes over from here.
+ */
+ break;
+
+ case HSM_ST:
+ /* complete command or read/write the data register */
+ if (qc->tf.protocol == ATAPI_PROT_PIO) {
+ /* ATAPI PIO protocol */
+ if ((status & ATA_DRQ) == 0) {
+ /* No more data to transfer or device error.
+ * Device error will be tagged in HSM_ST_LAST.
+ */
+ ap->hsm_task_state = HSM_ST_LAST;
+ goto fsm_start;
+ }
+
+ /* Device should not ask for data transfer (DRQ=1)
+ * when it finds something wrong.
+ * We ignore DRQ here and stop the HSM by
+ * changing hsm_task_state to HSM_ST_ERR and
+ * let the EH abort the command or reset the device.
+ */
+ if (unlikely(status & (ATA_ERR | ATA_DF))) {
+ ata_port_printk(ap, KERN_WARNING, "DRQ=1 with "
+ "device error, dev_stat 0x%X\n",
+ status);
+ qc->err_mask |= AC_ERR_HSM;
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
+
+ atapi_pio_bytes(qc);
+
+ if (unlikely(ap->hsm_task_state == HSM_ST_ERR))
+ /* bad ireason reported by device */
+ goto fsm_start;
+
+ } else {
+ /* ATA PIO protocol */
+ if (unlikely((status & ATA_DRQ) == 0)) {
+ /* handle BSY=0, DRQ=0 as error */
+ if (likely(status & (ATA_ERR | ATA_DF)))
+ /* device stops HSM for abort/error */
+ qc->err_mask |= AC_ERR_DEV;
+ else
+ /* HSM violation. Let EH handle this.
+ * Phantom devices also trigger this
+ * condition. Mark hint.
+ */
+ qc->err_mask |= AC_ERR_HSM |
+ AC_ERR_NODEV_HINT;
+
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
+
+ /* For PIO reads, some devices may ask for
+ * data transfer (DRQ=1) alone with ERR=1.
+ * We respect DRQ here and transfer one
+ * block of junk data before changing the
+ * hsm_task_state to HSM_ST_ERR.
+ *
+ * For PIO writes, ERR=1 DRQ=1 doesn't make
+ * sense since the data block has been
+ * transferred to the device.
+ */
+ if (unlikely(status & (ATA_ERR | ATA_DF))) {
+ /* data might be corrputed */
+ qc->err_mask |= AC_ERR_DEV;
+
+ if (!(qc->tf.flags & ATA_TFLAG_WRITE)) {
+ ata_pio_sectors(qc);
+ status = ata_wait_idle(ap);
+ }
+
+ if (status & (ATA_BUSY | ATA_DRQ))
+ qc->err_mask |= AC_ERR_HSM;
+
+ /* ata_pio_sectors() might change the
+ * state to HSM_ST_LAST. so, the state
+ * is changed after ata_pio_sectors().
+ */
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
+
+ ata_pio_sectors(qc);
+
+ if (ap->hsm_task_state == HSM_ST_LAST &&
+ (!(qc->tf.flags & ATA_TFLAG_WRITE))) {
+ /* all data read */
+ status = ata_wait_idle(ap);
+ goto fsm_start;
+ }
+ }
+
+ poll_next = 1;
+ break;
+
+ case HSM_ST_LAST:
+ if (unlikely(!ata_ok(status))) {
+ qc->err_mask |= __ac_err_mask(status);
+ ap->hsm_task_state = HSM_ST_ERR;
+ goto fsm_start;
+ }
+
+ /* no more data to transfer */
+ DPRINTK("ata%u: dev %u command complete, drv_stat 0x%x\n",
+ ap->print_id, qc->dev->devno, status);
+
+ WARN_ON(qc->err_mask);
+
+ ap->hsm_task_state = HSM_ST_IDLE;
+
+ /* complete taskfile transaction */
+ ata_hsm_qc_complete(qc, in_wq);
+
+ poll_next = 0;
+ break;
+
+ case HSM_ST_ERR:
+ /* make sure qc->err_mask is available to
+ * know what's wrong and recover
+ */
+ WARN_ON(qc->err_mask == 0);
+
+ ap->hsm_task_state = HSM_ST_IDLE;
+
+ /* complete taskfile transaction */
+ ata_hsm_qc_complete(qc, in_wq);
+
+ poll_next = 0;
+ break;
+ default:
+ poll_next = 0;
+ BUG();
+ }
+
+ return poll_next;
+}
+
+void ata_pio_task(struct work_struct *work)
+{
+ struct ata_port *ap =
+ container_of(work, struct ata_port, port_task.work);
+ struct ata_queued_cmd *qc = ap->port_task_data;
+ u8 status;
+ int poll_next;
+
+fsm_start:
+ WARN_ON(ap->hsm_task_state == HSM_ST_IDLE);
+
+ /*
+ * This is purely heuristic. This is a fast path.
+ * Sometimes when we enter, BSY will be cleared in
+ * a chk-status or two. If not, the drive is probably seeking
+ * or something. Snooze for a couple msecs, then
+ * chk-status again. If still busy, queue delayed work.
+ */
+ status = ata_sff_busy_wait(ap, ATA_BUSY, 5);
+ if (status & ATA_BUSY) {
+ msleep(2);
+ status = ata_sff_busy_wait(ap, ATA_BUSY, 10);
+ if (status & ATA_BUSY) {
+ ata_pio_queue_task(ap, qc, ATA_SHORT_PAUSE);
+ return;
+ }
+ }
+
+ /* move the HSM */
+ poll_next = ata_sff_hsm_move(ap, qc, status, 1);
+
+ /* another command or interrupt handler
+ * may be running at this point.
+ */
+ if (poll_next)
+ goto fsm_start;
}
/**
- * ata_bmdma_status - Read PCI IDE BMDMA status
- * @ap: Port associated with this ATA transaction.
+ * ata_sff_qc_issue - issue taskfile to device in proto-dependent manner
+ * @qc: command to issue to device
*
- * Read and return BMDMA status register.
+ * 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 bmdma_status() entry in ata_port_operations.
+ * May be used as the qc_issue() entry in ata_port_operations.
*
* LOCKING:
* spin_lock_irqsave(host lock)
+ *
+ * RETURNS:
+ * Zero on success, AC_ERR_* mask on failure
*/
-u8 ata_bmdma_status(struct ata_port *ap)
+unsigned int ata_sff_qc_issue(struct ata_queued_cmd *qc)
{
- return ioread8(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
+ struct ata_port *ap = qc->ap;
+
+ /* 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;
+ }
+ }
+
+ /* select the device */
+ ata_dev_select(ap, qc->dev->devno, 1, 0);
+
+ /* start the command */
+ switch (qc->tf.protocol) {
+ case ATA_PROT_NODATA:
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_qc_set_polling(qc);
+
+ ata_tf_to_host(ap, &qc->tf);
+ ap->hsm_task_state = HSM_ST_LAST;
+
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_pio_queue_task(ap, qc, 0);
+
+ 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);
+
+ ata_tf_to_host(ap, &qc->tf);
+
+ if (qc->tf.flags & ATA_TFLAG_WRITE) {
+ /* PIO data out protocol */
+ ap->hsm_task_state = HSM_ST_FIRST;
+ ata_pio_queue_task(ap, qc, 0);
+
+ /* always send first data block using
+ * the ata_pio_task() codepath.
+ */
+ } else {
+ /* PIO data in protocol */
+ ap->hsm_task_state = HSM_ST;
+
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_pio_queue_task(ap, qc, 0);
+
+ /* if polling, ata_pio_task() handles the rest.
+ * otherwise, interrupt handler takes over from here.
+ */
+ }
+
+ break;
+
+ case ATAPI_PROT_PIO:
+ case ATAPI_PROT_NODATA:
+ if (qc->tf.flags & ATA_TFLAG_POLLING)
+ ata_qc_set_polling(qc);
+
+ ata_tf_to_host(ap, &qc->tf);
+
+ ap->hsm_task_state = HSM_ST_FIRST;
+
+ /* send cdb by polling if no cdb interrupt */
+ if ((!(qc->dev->flags & ATA_DFLAG_CDB_INTR)) ||
+ (qc->tf.flags & ATA_TFLAG_POLLING))
+ ata_pio_queue_task(ap, qc, 0);
+ 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_pio_queue_task(ap, qc, 0);
+ break;
+
+ default:
+ WARN_ON(1);
+ return AC_ERR_SYSTEM;
+ }
+
+ return 0;
}
/**
- * ata_bmdma_stop - Stop PCI IDE BMDMA transfer
- * @qc: Command we are ending DMA for
+ * ata_sff_qc_fill_rtf - fill result TF using ->sff_tf_read
+ * @qc: qc to fill result TF for
*
- * Clears the ATA_DMA_START flag in the dma control register
+ * @qc is finished and result TF needs to be filled. Fill it
+ * using ->sff_tf_read.
*
- * May be used as the bmdma_stop() entry in ata_port_operations.
+ * LOCKING:
+ * spin_lock_irqsave(host lock)
+ *
+ * RETURNS:
+ * true indicating that result TF is successfully filled.
+ */
+bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc)
+{
+ qc->ap->ops->sff_tf_read(qc->ap, &qc->result_tf);
+ return true;
+}
+
+/**
+ * ata_sff_host_intr - Handle host interrupt for given (port, task)
+ * @ap: Port on which interrupt arrived (possibly...)
+ * @qc: Taskfile currently active in engine
+ *
+ * Handle host interrupt for given queued command. Currently,
+ * only DMA interrupts are handled. All other commands are
+ * handled via polling with interrupts disabled (nIEN bit).
*
* LOCKING:
* spin_lock_irqsave(host lock)
+ *
+ * RETURNS:
+ * One if interrupt was handled, zero if not (shared irq).
*/
-void ata_bmdma_stop(struct ata_queued_cmd *qc)
+inline unsigned int ata_sff_host_intr(struct ata_port *ap,
+ struct ata_queued_cmd *qc)
{
- struct ata_port *ap = qc->ap;
- void __iomem *mmio = ap->ioaddr.bmdma_addr;
+ struct ata_eh_info *ehi = &ap->link.eh_info;
+ u8 status, host_stat = 0;
- /* clear start/stop bit */
- iowrite8(ioread8(mmio + ATA_DMA_CMD) & ~ATA_DMA_START,
- mmio + ATA_DMA_CMD);
+ VPRINTK("ata%u: protocol %d task_state %d\n",
+ ap->print_id, qc->tf.protocol, ap->hsm_task_state);
- /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
- ata_altstatus(ap); /* dummy read */
+ /* Check whether we are expecting interrupt in this state */
+ switch (ap->hsm_task_state) {
+ case HSM_ST_FIRST:
+ /* Some pre-ATAPI-4 devices assert INTRQ
+ * at this state when ready to receive CDB.
+ */
+
+ /* Check the ATA_DFLAG_CDB_INTR flag is enough here.
+ * The flag was turned on only for atapi devices. No
+ * need to check ata_is_atapi(qc->tf.protocol) again.
+ */
+ if (!(qc->dev->flags & ATA_DFLAG_CDB_INTR))
+ goto idle_irq;
+ break;
+ case HSM_ST_LAST:
+ if (qc->tf.protocol == ATA_PROT_DMA ||
+ qc->tf.protocol == ATAPI_PROT_DMA) {
+ /* check status of DMA engine */
+ host_stat = ap->ops->bmdma_status(ap);
+ VPRINTK("ata%u: host_stat 0x%X\n",
+ ap->print_id, host_stat);
+
+ /* if it's not our irq... */
+ if (!(host_stat & ATA_DMA_INTR))
+ goto idle_irq;
+
+ /* before we do anything else, clear DMA-Start bit */
+ ap->ops->bmdma_stop(qc);
+
+ if (unlikely(host_stat & ATA_DMA_ERR)) {
+ /* error when transfering data to/from memory */
+ qc->err_mask |= AC_ERR_HOST_BUS;
+ ap->hsm_task_state = HSM_ST_ERR;
+ }
+ }
+ break;
+ case HSM_ST:
+ break;
+ default:
+ goto idle_irq;
+ }
+
+ /* check altstatus */
+ status = ata_sff_altstatus(ap);
+ if (status & ATA_BUSY)
+ goto idle_irq;
+
+ /* check main status, clearing INTRQ */
+ status = ap->ops->sff_check_status(ap);
+ if (unlikely(status & ATA_BUSY))
+ goto idle_irq;
+
+ /* ack bmdma irq events */
+ ap->ops->sff_irq_clear(ap);
+
+ ata_sff_hsm_move(ap, qc, status, 0);
+
+ if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
+ qc->tf.protocol == ATAPI_PROT_DMA))
+ ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
+
+ return 1; /* irq handled */
+
+idle_irq:
+ ap->stats.idle_irq++;
+
+#ifdef ATA_IRQ_TRAP
+ if ((ap->stats.idle_irq % 1000) == 0) {
+ ap->ops->sff_check_status(ap);
+ ap->ops->sff_irq_clear(ap);
+ ata_port_printk(ap, KERN_WARNING, "irq trap\n");
+ return 1;
+ }
+#endif
+ return 0; /* irq not handled */
+}
+
+/**
+ * ata_sff_interrupt - Default ATA host interrupt handler
+ * @irq: irq line (unused)
+ * @dev_instance: pointer to our ata_host information structure
+ *
+ * Default interrupt handler for PCI IDE devices. Calls
+ * ata_sff_host_intr() for each port that is not disabled.
+ *
+ * LOCKING:
+ * Obtains host lock during operation.
+ *
+ * RETURNS:
+ * IRQ_NONE or IRQ_HANDLED.
+ */
+irqreturn_t ata_sff_interrupt(int irq, void *dev_instance)
+{
+ struct ata_host *host = dev_instance;
+ unsigned int i;
+ unsigned int handled = 0;
+ unsigned long flags;
+
+ /* TODO: make _irqsave conditional on x86 PCI IDE legacy mode */
+ spin_lock_irqsave(&host->lock, flags);
+
+ for (i = 0; i < host->n_ports; i++) {
+ struct ata_port *ap;
+
+ 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 |= ata_sff_host_intr(ap, qc);
+ }
+ }
+
+ spin_unlock_irqrestore(&host->lock, flags);
+
+ return IRQ_RETVAL(handled);
}
/**
- * ata_bmdma_freeze - Freeze BMDMA controller port
+ * ata_sff_freeze - Freeze SFF controller port
* @ap: port to freeze
*
* Freeze BMDMA controller port.
@@ -351,7 +1581,7 @@ void ata_bmdma_stop(struct ata_queued_cmd *qc)
* LOCKING:
* Inherited from caller.
*/
-void ata_bmdma_freeze(struct ata_port *ap)
+void ata_sff_freeze(struct ata_port *ap)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -365,51 +1595,412 @@ void ata_bmdma_freeze(struct ata_port *ap)
* ATA_NIEN manipulation. Also, many controllers fail to mask
* previously pending IRQ on ATA_NIEN assertion. Clear it.
*/
- ata_chk_status(ap);
+ ap->ops->sff_check_status(ap);
- ap->ops->irq_clear(ap);
+ ap->ops->sff_irq_clear(ap);
}
/**
- * ata_bmdma_thaw - Thaw BMDMA controller port
+ * ata_sff_thaw - Thaw SFF controller port
* @ap: port to thaw
*
- * Thaw BMDMA controller port.
+ * Thaw SFF controller port.
*
* LOCKING:
* Inherited from caller.
*/
-void ata_bmdma_thaw(struct ata_port *ap)
+void ata_sff_thaw(struct ata_port *ap)
{
/* clear & re-enable interrupts */
- ata_chk_status(ap);
- ap->ops->irq_clear(ap);
- ap->ops->irq_on(ap);
+ ap->ops->sff_check_status(ap);
+ ap->ops->sff_irq_clear(ap);
+ ap->ops->sff_irq_on(ap);
+}
+
+/**
+ * ata_sff_prereset - prepare SFF link for reset
+ * @link: SFF link to be reset
+ * @deadline: deadline jiffies for the operation
+ *
+ * SFF link @link is about to be reset. Initialize it. It first
+ * calls ata_std_prereset() and wait for !BSY if the port is
+ * being softreset.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_sff_prereset(struct ata_link *link, unsigned long deadline)
+{
+ struct ata_eh_context *ehc = &link->eh_context;
+ int rc;
+
+ rc = ata_std_prereset(link, deadline);
+ if (rc)
+ return rc;
+
+ /* if we're about to do hardreset, nothing more to do */
+ if (ehc->i.action & ATA_EH_HARDRESET)
+ return 0;
+
+ /* wait for !BSY if we don't know that no device is attached */
+ if (!ata_link_offline(link)) {
+ rc = ata_sff_wait_ready(link, deadline);
+ if (rc && rc != -ENODEV) {
+ ata_link_printk(link, KERN_WARNING, "device not ready "
+ "(errno=%d), forcing hardreset\n", rc);
+ ehc->i.action |= ATA_EH_HARDRESET;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * ata_devchk - PATA device presence detection
+ * @ap: ATA channel to examine
+ * @device: Device to examine (starting at zero)
+ *
+ * This technique was originally described in
+ * Hale Landis's ATADRVR (www.ata-atapi.com), and
+ * later found its way into the ATA/ATAPI spec.
+ *
+ * Write a pattern to the ATA shadow registers,
+ * and if a device is present, it will respond by
+ * correctly storing and echoing back the
+ * ATA shadow register contents.
+ *
+ * LOCKING:
+ * caller.
+ */
+static unsigned int ata_devchk(struct ata_port *ap, unsigned int device)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+ u8 nsect, lbal;
+
+ ap->ops->sff_dev_select(ap, device);
+
+ iowrite8(0x55, ioaddr->nsect_addr);
+ iowrite8(0xaa, ioaddr->lbal_addr);
+
+ iowrite8(0xaa, ioaddr->nsect_addr);
+ iowrite8(0x55, ioaddr->lbal_addr);
+
+ iowrite8(0x55, ioaddr->nsect_addr);
+ iowrite8(0xaa, ioaddr->lbal_addr);
+
+ nsect = ioread8(ioaddr->nsect_addr);
+ lbal = ioread8(ioaddr->lbal_addr);
+
+ if ((nsect == 0x55) && (lbal == 0xaa))
+ return 1; /* we found a device */
+
+ return 0; /* nothing found */
+}
+
+/**
+ * ata_sff_dev_classify - Parse returned ATA device signature
+ * @dev: ATA device to classify (starting at zero)
+ * @present: device seems present
+ * @r_err: Value of error register on completion
+ *
+ * After an event -- SRST, E.D.D., or SATA COMRESET -- occurs,
+ * an ATA/ATAPI-defined set of values is placed in the ATA
+ * shadow registers, indicating the results of device detection
+ * and diagnostics.
+ *
+ * Select the ATA device, and read the values from the ATA shadow
+ * registers. Then parse according to the Error register value,
+ * and the spec-defined values examined by ata_dev_classify().
+ *
+ * LOCKING:
+ * caller.
+ *
+ * RETURNS:
+ * Device type - %ATA_DEV_ATA, %ATA_DEV_ATAPI or %ATA_DEV_NONE.
+ */
+unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
+ u8 *r_err)
+{
+ struct ata_port *ap = dev->link->ap;
+ struct ata_taskfile tf;
+ unsigned int class;
+ u8 err;
+
+ ap->ops->sff_dev_select(ap, dev->devno);
+
+ memset(&tf, 0, sizeof(tf));
+
+ ap->ops->sff_tf_read(ap, &tf);
+ err = tf.feature;
+ if (r_err)
+ *r_err = err;
+
+ /* see if device passed diags: continue and warn later */
+ if (err == 0)
+ /* diagnostic fail : do nothing _YET_ */
+ dev->horkage |= ATA_HORKAGE_DIAGNOSTIC;
+ else if (err == 1)
+ /* do nothing */ ;
+ else if ((dev->devno == 0) && (err == 0x81))
+ /* do nothing */ ;
+ else
+ return ATA_DEV_NONE;
+
+ /* determine if device is ATA or ATAPI */
+ class = ata_dev_classify(&tf);
+
+ if (class == ATA_DEV_UNKNOWN) {
+ /* If the device failed diagnostic, it's likely to
+ * have reported incorrect device signature too.
+ * Assume ATA device if the device seems present but
+ * device signature is invalid with diagnostic
+ * failure.
+ */
+ if (present && (dev->horkage & ATA_HORKAGE_DIAGNOSTIC))
+ class = ATA_DEV_ATA;
+ else
+ class = ATA_DEV_NONE;
+ } else if ((class == ATA_DEV_ATA) &&
+ (ap->ops->sff_check_status(ap) == 0))
+ class = ATA_DEV_NONE;
+
+ return class;
+}
+
+/**
+ * ata_sff_wait_after_reset - wait for devices to become ready after reset
+ * @link: SFF link which is just reset
+ * @devmask: mask of present devices
+ * @deadline: deadline jiffies for the operation
+ *
+ * Wait devices attached to SFF @link to become ready after
+ * reset. It contains preceding 150ms wait to avoid accessing TF
+ * status register too early.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep).
+ *
+ * RETURNS:
+ * 0 on success, -ENODEV if some or all of devices in @devmask
+ * don't seem to exist. -errno on other errors.
+ */
+int ata_sff_wait_after_reset(struct ata_link *link, unsigned int devmask,
+ unsigned long deadline)
+{
+ struct ata_port *ap = link->ap;
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+ unsigned int dev0 = devmask & (1 << 0);
+ unsigned int dev1 = devmask & (1 << 1);
+ int rc, ret = 0;
+
+ msleep(ATA_WAIT_AFTER_RESET_MSECS);
+
+ /* always check readiness of the master device */
+ rc = ata_sff_wait_ready(link, deadline);
+ /* -ENODEV means the odd clown forgot the D7 pulldown resistor
+ * and TF status is 0xff, bail out on it too.
+ */
+ if (rc)
+ return rc;
+
+ /* if device 1 was found in ata_devchk, wait for register
+ * access briefly, then wait for BSY to clear.
+ */
+ if (dev1) {
+ int i;
+
+ ap->ops->sff_dev_select(ap, 1);
+
+ /* Wait for register access. Some ATAPI devices fail
+ * to set nsect/lbal after reset, so don't waste too
+ * much time on it. We're gonna wait for !BSY anyway.
+ */
+ for (i = 0; i < 2; i++) {
+ u8 nsect, lbal;
+
+ nsect = ioread8(ioaddr->nsect_addr);
+ lbal = ioread8(ioaddr->lbal_addr);
+ if ((nsect == 1) && (lbal == 1))
+ break;
+ msleep(50); /* give drive a breather */
+ }
+
+ rc = ata_sff_wait_ready(link, deadline);
+ if (rc) {
+ if (rc != -ENODEV)
+ return rc;
+ ret = rc;
+ }
+ }
+
+ /* is all this really necessary? */
+ ap->ops->sff_dev_select(ap, 0);
+ if (dev1)
+ ap->ops->sff_dev_select(ap, 1);
+ if (dev0)
+ ap->ops->sff_dev_select(ap, 0);
+
+ return ret;
+}
+
+static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
+ unsigned long deadline)
+{
+ struct ata_ioports *ioaddr = &ap->ioaddr;
+
+ DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
+
+ /* software reset. causes dev0 to be selected */
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
+ udelay(20); /* FIXME: flush */
+ iowrite8(ap->ctl | ATA_SRST, ioaddr->ctl_addr);
+ udelay(20); /* FIXME: flush */
+ iowrite8(ap->ctl, ioaddr->ctl_addr);
+
+ /* wait the port to become ready */
+ return ata_sff_wait_after_reset(&ap->link, devmask, deadline);
+}
+
+/**
+ * ata_sff_softreset - reset host port via ATA SRST
+ * @link: ATA link to reset
+ * @classes: resulting classes of attached devices
+ * @deadline: deadline jiffies for the operation
+ *
+ * Reset host port using ATA SRST.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
+ unsigned long deadline)
+{
+ struct ata_port *ap = link->ap;
+ unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
+ unsigned int devmask = 0;
+ int rc;
+ u8 err;
+
+ DPRINTK("ENTER\n");
+
+ /* determine if device 0/1 are present */
+ if (ata_devchk(ap, 0))
+ devmask |= (1 << 0);
+ if (slave_possible && ata_devchk(ap, 1))
+ devmask |= (1 << 1);
+
+ /* select device 0 again */
+ ap->ops->sff_dev_select(ap, 0);
+
+ /* issue bus reset */
+ DPRINTK("about to softreset, devmask=%x\n", devmask);
+ rc = ata_bus_softreset(ap, devmask, deadline);
+ /* if link is occupied, -ENODEV too is an error */
+ if (rc && (rc != -ENODEV || sata_scr_valid(link))) {
+ ata_link_printk(link, KERN_ERR, "SRST failed (errno=%d)\n", rc);
+ return rc;
+ }
+
+ /* determine by signature whether we have ATA or ATAPI devices */
+ classes[0] = ata_sff_dev_classify(&link->device[0],
+ devmask & (1 << 0), &err);
+ if (slave_possible && err != 0x81)
+ classes[1] = ata_sff_dev_classify(&link->device[1],
+ devmask & (1 << 1), &err);
+
+ DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
+ return 0;
+}
+
+/**
+ * sata_sff_hardreset - reset host port via SATA phy reset
+ * @link: link to reset
+ * @class: resulting class of attached device
+ * @deadline: deadline jiffies for the operation
+ *
+ * SATA phy-reset host port using DET bits of SControl register,
+ * wait for !BSY and classify the attached device.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ *
+ * RETURNS:
+ * 0 on success, -errno otherwise.
+ */
+int sata_sff_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
+{
+ struct ata_eh_context *ehc = &link->eh_context;
+ const unsigned long *timing = sata_ehc_deb_timing(ehc);
+ bool online;
+ int rc;
+
+ rc = sata_link_hardreset(link, timing, deadline, &online,
+ ata_sff_check_ready);
+ if (online)
+ *class = ata_sff_dev_classify(link->device, 1, NULL);
+
+ DPRINTK("EXIT, class=%u\n", *class);
+ return rc;
}
/**
- * ata_bmdma_drive_eh - Perform EH with given methods for BMDMA controller
+ * ata_sff_postreset - SFF postreset callback
+ * @link: the target SFF ata_link
+ * @classes: classes of attached devices
+ *
+ * This function is invoked after a successful reset. It first
+ * calls ata_std_postreset() and performs SFF specific postreset
+ * processing.
+ *
+ * LOCKING:
+ * Kernel thread context (may sleep)
+ */
+void ata_sff_postreset(struct ata_link *link, unsigned int *classes)
+{
+ struct ata_port *ap = link->ap;
+
+ ata_std_postreset(link, classes);
+
+ /* is double-select really necessary? */
+ if (classes[0] != ATA_DEV_NONE)
+ ap->ops->sff_dev_select(ap, 1);
+ if (classes[1] != ATA_DEV_NONE)
+ ap->ops->sff_dev_select(ap, 0);
+
+ /* bail out if no device is present */
+ if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
+ DPRINTK("EXIT, no device\n");
+ return;
+ }
+
+ /* set up device control */
+ if (ap->ioaddr.ctl_addr)
+ iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
+}
+
+/**
+ * ata_sff_error_handler - Stock error handler for BMDMA controller
* @ap: port to handle error for
- * @prereset: prereset method (can be NULL)
- * @softreset: softreset method (can be NULL)
- * @hardreset: hardreset method (can be NULL)
- * @postreset: postreset method (can be NULL)
*
- * Handle error for ATA BMDMA controller. It can handle both
+ * Stock error handler for SFF controller. It can handle both
* PATA and SATA controllers. Many controllers should be able to
* use this EH as-is or with some added handling before and
* after.
*
- * This function is intended to be used for constructing
- * ->error_handler callback by low level drivers.
- *
* LOCKING:
* Kernel thread context (may sleep)
*/
-void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
- ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
- ata_postreset_fn_t postreset)
+void ata_sff_error_handler(struct ata_port *ap)
{
+ ata_reset_fn_t softreset = ap->ops->softreset;
+ ata_reset_fn_t hardreset = ap->ops->hardreset;
struct ata_queued_cmd *qc;
unsigned long flags;
int thaw = 0;
@@ -423,7 +2014,8 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ap->hsm_task_state = HSM_ST_IDLE;
- if (qc && (qc->tf.protocol == ATA_PROT_DMA ||
+ if (ap->ioaddr.bmdma_addr &&
+ qc && (qc->tf.protocol == ATA_PROT_DMA ||
qc->tf.protocol == ATAPI_PROT_DMA)) {
u8 host_stat;
@@ -442,9 +2034,9 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ap->ops->bmdma_stop(qc);
}
- ata_altstatus(ap);
- ata_chk_status(ap);
- ap->ops->irq_clear(ap);
+ ata_sff_altstatus(ap);
+ ap->ops->sff_check_status(ap);
+ ap->ops->sff_irq_clear(ap);
spin_unlock_irqrestore(ap->lock, flags);
@@ -452,40 +2044,27 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_eh_thaw_port(ap);
/* PIO and DMA engines have been stopped, perform recovery */
- ata_do_eh(ap, prereset, softreset, hardreset, postreset);
-}
-
-/**
- * ata_bmdma_error_handler - Stock error handler for BMDMA controller
- * @ap: port to handle error for
- *
- * Stock error handler for BMDMA controller.
- *
- * LOCKING:
- * Kernel thread context (may sleep)
- */
-void ata_bmdma_error_handler(struct ata_port *ap)
-{
- ata_reset_fn_t softreset = NULL, hardreset = NULL;
- if (ap->ioaddr.ctl_addr)
- softreset = ata_std_softreset;
- if (sata_scr_valid(&ap->link))
- hardreset = sata_std_hardreset;
+ /* Ignore ata_sff_softreset if ctl isn't accessible and
+ * built-in hardresets if SCR access isn't available.
+ */
+ if (softreset == ata_sff_softreset && !ap->ioaddr.ctl_addr)
+ softreset = NULL;
+ if (ata_is_builtin_hardreset(hardreset) && !sata_scr_valid(&ap->link))
+ hardreset = NULL;
- ata_bmdma_drive_eh(ap, ata_std_prereset, softreset, hardreset,
- ata_std_postreset);
+ ata_do_eh(ap, ap->ops->prereset, softreset, hardreset,
+ ap->ops->postreset);
}
/**
- * ata_bmdma_post_internal_cmd - Stock post_internal_cmd for
- * BMDMA controller
+ * ata_sff_post_internal_cmd - Stock post_internal_cmd for SFF controller
* @qc: internal command to clean up
*
* LOCKING:
* Kernel thread context (may sleep)
*/
-void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
+void ata_sff_post_internal_cmd(struct ata_queued_cmd *qc)
{
if (qc->ap->ioaddr.bmdma_addr)
ata_bmdma_stop(qc);
@@ -504,7 +2083,6 @@ void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc)
* LOCKING:
* Inherited from caller.
*/
-
int ata_sff_port_start(struct ata_port *ap)
{
if (ap->ioaddr.bmdma_addr)
@@ -512,24 +2090,262 @@ int ata_sff_port_start(struct ata_port *ap)
return 0;
}
-#ifdef CONFIG_PCI
+/**
+ * ata_sff_std_ports - initialize ioaddr with standard port offsets.
+ * @ioaddr: IO address structure to be initialized
+ *
+ * Utility function which initializes data_addr, error_addr,
+ * feature_addr, nsect_addr, lbal_addr, lbam_addr, lbah_addr,
+ * device_addr, status_addr, and command_addr to standard offsets
+ * relative to cmd_addr.
+ *
+ * Does not set ctl_addr, altstatus_addr, bmdma_addr, or scr_addr.
+ */
+void ata_sff_std_ports(struct ata_ioports *ioaddr)
+{
+ ioaddr->data_addr = ioaddr->cmd_addr + ATA_REG_DATA;
+ ioaddr->error_addr = ioaddr->cmd_addr + ATA_REG_ERR;
+ ioaddr->feature_addr = ioaddr->cmd_addr + ATA_REG_FEATURE;
+ ioaddr->nsect_addr = ioaddr->cmd_addr + ATA_REG_NSECT;
+ ioaddr->lbal_addr = ioaddr->cmd_addr + ATA_REG_LBAL;
+ ioaddr->lbam_addr = ioaddr->cmd_addr + ATA_REG_LBAM;
+ ioaddr->lbah_addr = ioaddr->cmd_addr + ATA_REG_LBAH;
+ ioaddr->device_addr = ioaddr->cmd_addr + ATA_REG_DEVICE;
+ ioaddr->status_addr = ioaddr->cmd_addr + ATA_REG_STATUS;
+ ioaddr->command_addr = ioaddr->cmd_addr + ATA_REG_CMD;
+}
-static int ata_resources_present(struct pci_dev *pdev, int port)
+unsigned long ata_bmdma_mode_filter(struct ata_device *adev,
+ unsigned long xfer_mask)
{
- int i;
+ /* Filter out DMA modes if the device has been configured by
+ the BIOS as PIO only */
- /* Check the PCI resources for this channel are enabled */
- port = port * 2;
- for (i = 0; i < 2; i ++) {
- if (pci_resource_start(pdev, port + i) == 0 ||
- pci_resource_len(pdev, port + i) == 0)
- return 0;
+ 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_altstatus(ap); /* dummy read */
+}
+
+/**
+ * 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.
+ *
+ * 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.
+ */
+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);
}
- return 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, jiffies + 40 * HZ);
+ 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:
+ ata_port_printk(ap, KERN_ERR, "disabling port\n");
+ ata_port_disable(ap);
+
+ DPRINTK("EXIT\n");
}
+#ifdef CONFIG_PCI
+
/**
- * ata_pci_init_bmdma - acquire PCI BMDMA resources and init ATA host
+ * 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.
@@ -540,7 +2356,7 @@ static int ata_resources_present(struct pci_dev *pdev, int port)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int ata_pci_init_bmdma(struct ata_host *host)
+int ata_pci_bmdma_init(struct ata_host *host)
{
struct device *gdev = host->dev;
struct pci_dev *pdev = to_pci_dev(gdev);
@@ -585,8 +2401,22 @@ int ata_pci_init_bmdma(struct ata_host *host)
return 0;
}
+static int ata_resources_present(struct pci_dev *pdev, int port)
+{
+ int i;
+
+ /* Check the PCI resources for this channel are enabled */
+ port = port * 2;
+ for (i = 0; i < 2; i ++) {
+ if (pci_resource_start(pdev, port + i) == 0 ||
+ pci_resource_len(pdev, port + i) == 0)
+ return 0;
+ }
+ return 1;
+}
+
/**
- * ata_pci_init_sff_host - acquire native PCI ATA resources and init host
+ * ata_pci_sff_init_host - acquire native PCI ATA resources and init host
* @host: target ATA host
*
* Acquire native PCI ATA resources for @host and initialize the
@@ -604,7 +2434,7 @@ int ata_pci_init_bmdma(struct ata_host *host)
* 0 if at least one port is initialized, -ENODEV if no port is
* available.
*/
-int ata_pci_init_sff_host(struct ata_host *host)
+int ata_pci_sff_init_host(struct ata_host *host)
{
struct device *gdev = host->dev;
struct pci_dev *pdev = to_pci_dev(gdev);
@@ -646,7 +2476,7 @@ int ata_pci_init_sff_host(struct ata_host *host)
ap->ioaddr.altstatus_addr =
ap->ioaddr.ctl_addr = (void __iomem *)
((unsigned long)iomap[base + 1] | ATA_PCI_CTL_OFS);
- ata_std_ports(&ap->ioaddr);
+ ata_sff_std_ports(&ap->ioaddr);
ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
(unsigned long long)pci_resource_start(pdev, base),
@@ -664,7 +2494,7 @@ int ata_pci_init_sff_host(struct ata_host *host)
}
/**
- * ata_pci_prepare_sff_host - helper to prepare native PCI ATA host
+ * ata_pci_sff_prepare_host - helper to prepare native PCI 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
@@ -678,7 +2508,7 @@ int ata_pci_init_sff_host(struct ata_host *host)
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int ata_pci_prepare_sff_host(struct pci_dev *pdev,
+int ata_pci_sff_prepare_host(struct pci_dev *pdev,
const struct ata_port_info * const * ppi,
struct ata_host **r_host)
{
@@ -696,12 +2526,12 @@ int ata_pci_prepare_sff_host(struct pci_dev *pdev,
goto err_out;
}
- rc = ata_pci_init_sff_host(host);
+ rc = ata_pci_sff_init_host(host);
if (rc)
goto err_out;
/* init DMA related stuff */
- rc = ata_pci_init_bmdma(host);
+ rc = ata_pci_bmdma_init(host);
if (rc)
goto err_bmdma;
@@ -722,7 +2552,7 @@ int ata_pci_prepare_sff_host(struct pci_dev *pdev,
}
/**
- * ata_pci_activate_sff_host - start SFF host, request IRQ and register it
+ * ata_pci_sff_activate_host - start SFF host, request IRQ and register it
* @host: target SFF ATA host
* @irq_handler: irq_handler used when requesting IRQ(s)
* @sht: scsi_host_template to use when registering the host
@@ -737,7 +2567,7 @@ int ata_pci_prepare_sff_host(struct pci_dev *pdev,
* RETURNS:
* 0 on success, -errno otherwise.
*/
-int ata_pci_activate_sff_host(struct ata_host *host,
+int ata_pci_sff_activate_host(struct ata_host *host,
irq_handler_t irq_handler,
struct scsi_host_template *sht)
{
@@ -815,9 +2645,11 @@ int ata_pci_activate_sff_host(struct ata_host *host,
}
/**
- * ata_pci_init_one - Initialize/register PCI IDE host controller
+ * ata_pci_sff_init_one - Initialize/register PCI IDE host 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 is a helper function which can be called from a driver's
* xxx_init_one() probe function if the hardware uses traditional
@@ -837,8 +2669,9 @@ int ata_pci_activate_sff_host(struct ata_host *host,
* RETURNS:
* Zero on success, negative on errno-based value on error.
*/
-int ata_pci_init_one(struct pci_dev *pdev,
- const struct ata_port_info * const * ppi)
+int ata_pci_sff_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 = NULL;
@@ -869,13 +2702,13 @@ int ata_pci_init_one(struct pci_dev *pdev,
goto out;
/* prepare and activate SFF host */
- rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
+ rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
if (rc)
goto out;
+ host->private_data = host_priv;
pci_set_master(pdev);
- rc = ata_pci_activate_sff_host(host, pi->port_ops->irq_handler,
- pi->sht);
+ rc = ata_pci_sff_activate_host(host, ata_sff_interrupt, sht);
out:
if (rc == 0)
devres_remove_group(&pdev->dev, NULL);
@@ -885,41 +2718,52 @@ int ata_pci_init_one(struct pci_dev *pdev,
return rc;
}
-/**
- * ata_pci_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_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;
-}
-
-unsigned long ata_pci_default_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;
-}
-
#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);
+EXPORT_SYMBOL_GPL(ata_sff_check_status);
+EXPORT_SYMBOL_GPL(ata_sff_altstatus);
+EXPORT_SYMBOL_GPL(ata_sff_busy_sleep);
+EXPORT_SYMBOL_GPL(ata_sff_wait_ready);
+EXPORT_SYMBOL_GPL(ata_sff_tf_load);
+EXPORT_SYMBOL_GPL(ata_sff_tf_read);
+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);
+EXPORT_SYMBOL_GPL(ata_sff_host_intr);
+EXPORT_SYMBOL_GPL(ata_sff_interrupt);
+EXPORT_SYMBOL_GPL(ata_sff_freeze);
+EXPORT_SYMBOL_GPL(ata_sff_thaw);
+EXPORT_SYMBOL_GPL(ata_sff_prereset);
+EXPORT_SYMBOL_GPL(ata_sff_dev_classify);
+EXPORT_SYMBOL_GPL(ata_sff_wait_after_reset);
+EXPORT_SYMBOL_GPL(ata_sff_softreset);
+EXPORT_SYMBOL_GPL(sata_sff_hardreset);
+EXPORT_SYMBOL_GPL(ata_sff_postreset);
+EXPORT_SYMBOL_GPL(ata_sff_error_handler);
+EXPORT_SYMBOL_GPL(ata_sff_post_internal_cmd);
+EXPORT_SYMBOL_GPL(ata_sff_port_start);
+EXPORT_SYMBOL_GPL(ata_sff_std_ports);
+EXPORT_SYMBOL_GPL(ata_bmdma_mode_filter);
+EXPORT_SYMBOL_GPL(ata_bmdma_setup);
+EXPORT_SYMBOL_GPL(ata_bmdma_start);
+EXPORT_SYMBOL_GPL(ata_bmdma_stop);
+EXPORT_SYMBOL_GPL(ata_bmdma_status);
+EXPORT_SYMBOL_GPL(ata_bus_reset);
+#ifdef CONFIG_PCI
+EXPORT_SYMBOL_GPL(ata_pci_bmdma_clear_simplex);
+EXPORT_SYMBOL_GPL(ata_pci_bmdma_init);
+EXPORT_SYMBOL_GPL(ata_pci_sff_init_host);
+EXPORT_SYMBOL_GPL(ata_pci_sff_prepare_host);
+EXPORT_SYMBOL_GPL(ata_pci_sff_activate_host);
+EXPORT_SYMBOL_GPL(ata_pci_sff_init_one);
+#endif /* CONFIG_PCI */
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index aa884f71a12a..4aeeabb10a47 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -38,6 +38,17 @@ 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() */
@@ -61,12 +72,16 @@ extern int libata_fua;
extern int libata_noacpi;
extern int libata_allow_tpm;
extern void ata_force_cbl(struct ata_port *ap);
+extern u64 ata_tf_to_lba(const struct ata_taskfile *tf);
+extern u64 ata_tf_to_lba48(const struct ata_taskfile *tf);
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
u64 block, u32 n_block, unsigned int tf_flags,
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,
@@ -77,6 +92,8 @@ extern unsigned ata_exec_internal_sg(struct ata_device *dev,
int dma_dir, struct scatterlist *sg,
unsigned int n_elem, unsigned long timeout);
extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
+extern int ata_wait_ready(struct ata_link *link, unsigned long deadline,
+ int (*check_ready)(struct ata_link *link));
extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
unsigned int flags, u16 *id);
extern int ata_dev_reread_id(struct ata_device *dev, unsigned int readid_flags);
@@ -91,10 +108,7 @@ extern void ata_qc_free(struct ata_queued_cmd *qc);
extern void ata_qc_issue(struct ata_queued_cmd *qc);
extern void __ata_qc_complete(struct ata_queued_cmd *qc);
extern int ata_check_atapi_dma(struct ata_queued_cmd *qc);
-extern void ata_dev_select(struct ata_port *ap, unsigned int device,
- unsigned int wait, unsigned int can_sleep);
extern void swap_buf_le16(u16 *buf, unsigned int buf_words);
-extern int ata_flush_cache(struct ata_device *dev);
extern void ata_dev_init(struct ata_device *dev);
extern void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp);
extern int sata_link_init_spd(struct ata_link *link);
@@ -165,11 +179,6 @@ extern void ata_schedule_scsi_eh(struct Scsi_Host *shost);
extern void ata_scsi_dev_rescan(struct work_struct *work);
extern int ata_bus_probe(struct ata_port *ap);
-/* libata-pmp.c */
-extern int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *val);
-extern int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val);
-extern int sata_pmp_attach(struct ata_device *dev);
-
/* libata-eh.c */
extern enum scsi_eh_timer_return ata_scsi_timed_out(struct scsi_cmnd *cmd);
extern void ata_scsi_error(struct Scsi_Host *host);
@@ -193,8 +202,34 @@ extern int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
struct ata_link **r_failed_disk);
extern void ata_eh_finish(struct ata_port *ap);
+/* libata-pmp.c */
+#ifdef CONFIG_SATA_PMP
+extern int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *val);
+extern int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val);
+extern int sata_pmp_attach(struct ata_device *dev);
+#else /* CONFIG_SATA_PMP */
+static inline int sata_pmp_scr_read(struct ata_link *link, int reg, u32 *val)
+{
+ return -EINVAL;
+}
+
+static inline int sata_pmp_scr_write(struct ata_link *link, int reg, u32 val)
+{
+ return -EINVAL;
+}
+
+static inline int sata_pmp_attach(struct ata_device *dev)
+{
+ return -EINVAL;
+}
+#endif /* CONFIG_SATA_PMP */
+
/* 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 */
#endif /* __LIBATA_H__ */
diff --git a/drivers/ata/pata_acpi.c b/drivers/ata/pata_acpi.c
index bdc3b9d7395c..c5f91e629945 100644
--- a/drivers/ata/pata_acpi.c
+++ b/drivers/ata/pata_acpi.c
@@ -47,7 +47,7 @@ static int pacpi_pre_reset(struct ata_link *link, unsigned long deadline)
if (ap->acpi_handle == NULL || ata_acpi_gtm(ap, &acpi->gtm) < 0)
return -ENODEV;
- return ata_std_prereset(link, deadline);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -68,20 +68,6 @@ static int pacpi_cable_detect(struct ata_port *ap)
}
/**
- * pacpi_error_handler - Setup and error handler
- * @ap: Port to handle
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void pacpi_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, pacpi_pre_reset, ata_std_softreset, NULL,
- ata_std_postreset);
-}
-
-/**
* pacpi_discover_modes - filter non ACPI modes
* @adev: ATA device
* @mask: proposed modes
@@ -120,7 +106,7 @@ static unsigned long pacpi_discover_modes(struct ata_port *ap, struct ata_device
static unsigned long pacpi_mode_filter(struct ata_device *adev, unsigned long mask)
{
struct pata_acpi *acpi = adev->link->ap->private_data;
- return ata_pci_default_filter(adev, mask & acpi->mask[adev->devno]);
+ return ata_bmdma_mode_filter(adev, mask & acpi->mask[adev->devno]);
}
/**
@@ -176,7 +162,7 @@ static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
/**
- * pacpi_qc_issue_prot - command issue
+ * pacpi_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
@@ -184,14 +170,14 @@ static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev)
* neccessary.
*/
-static unsigned int pacpi_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int pacpi_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
struct pata_acpi *acpi = ap->private_data;
if (acpi->gtm.flags & 0x10)
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
if (adev != acpi->last) {
pacpi_set_piomode(ap, adev);
@@ -199,7 +185,7 @@ static unsigned int pacpi_qc_issue_prot(struct ata_queued_cmd *qc)
pacpi_set_dmamode(ap, adev);
acpi->last = adev;
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
/**
@@ -232,57 +218,17 @@ static int pacpi_port_start(struct ata_port *ap)
}
static struct scsi_host_template pacpi_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- /* Use standard CHS mapping rules */
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations pacpi_ops = {
+static struct ata_port_operations pacpi_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .qc_issue = pacpi_qc_issue,
+ .cable_detect = pacpi_cable_detect,
+ .mode_filter = pacpi_mode_filter,
.set_piomode = pacpi_set_piomode,
.set_dmamode = pacpi_set_dmamode,
- .mode_filter = pacpi_mode_filter,
-
- /* Task file is PCI ATA format, use helpers */
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = pacpi_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = pacpi_cable_detect,
-
- /* BMDMA handling is PCI ATA format, use helpers */
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = pacpi_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- /* Timeout handling */
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- /* Generic PATA PCI ATA helpers */
+ .prereset = pacpi_pre_reset,
.port_start = pacpi_port_start,
};
@@ -304,7 +250,6 @@ static const struct ata_port_operations pacpi_ops = {
static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &pacpi_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f,
@@ -314,7 +259,7 @@ static int pacpi_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &pacpi_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &pacpi_sht, NULL);
}
static const struct pci_device_id pacpi_pci_tbl[] = {
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 511a830b6256..fcabe46f262b 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -121,7 +121,7 @@ static unsigned long ali_20_filter(struct ata_device *adev, unsigned long mask)
ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
if (strstr(model_num, "WDC"))
return mask &= ~ATA_MASK_UDMA;
- return ata_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, mask);
}
/**
@@ -339,21 +339,7 @@ static int ali_check_atapi_dma(struct ata_queued_cmd *qc)
}
static struct scsi_host_template ali_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
/*
@@ -361,29 +347,15 @@ static struct scsi_host_template ali_sht = {
*/
static struct ata_port_operations ali_early_port_ops = {
- .set_piomode = ali_set_piomode,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
.cable_detect = ata_cable_40wire,
+ .set_piomode = ali_set_piomode,
+};
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+static const struct ata_port_operations ali_dma_base_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .set_piomode = ali_set_piomode,
+ .set_dmamode = ali_set_dmamode,
};
/*
@@ -391,115 +363,31 @@ static struct ata_port_operations ali_early_port_ops = {
* detect
*/
static struct ata_port_operations ali_20_port_ops = {
- .set_piomode = ali_set_piomode,
- .set_dmamode = ali_set_dmamode,
+ .inherits = &ali_dma_base_ops,
+ .cable_detect = ata_cable_40wire,
.mode_filter = ali_20_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
.check_atapi_dma = ali_check_atapi_dma,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
.dev_config = ali_lock_sectors,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/*
* Port operations for DMA capable ALi with cable detect
*/
static struct ata_port_operations ali_c2_port_ops = {
- .set_piomode = ali_set_piomode,
- .set_dmamode = ali_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
+ .inherits = &ali_dma_base_ops,
.check_atapi_dma = ali_check_atapi_dma,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
- .dev_config = ali_lock_sectors,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = ali_c2_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .dev_config = ali_lock_sectors,
};
/*
* Port operations for DMA capable ALi with cable detect and LBA48
*/
static struct ata_port_operations ali_c5_port_ops = {
- .set_piomode = ali_set_piomode,
- .set_dmamode = ali_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
+ .inherits = &ali_dma_base_ops,
.check_atapi_dma = ali_check_atapi_dma,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
.dev_config = ali_warn_atapi_dma,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = ali_c2_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
@@ -561,7 +449,7 @@ static void ali_init_chipset(struct pci_dev *pdev)
}
pci_dev_put(isa_bridge);
pci_dev_put(north);
- ata_pci_clear_simplex(pdev);
+ ata_pci_bmdma_clear_simplex(pdev);
}
/**
* ali_init_one - discovery callback
@@ -575,14 +463,12 @@ static void ali_init_chipset(struct pci_dev *pdev)
static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info_early = {
- .sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &ali_early_port_ops
};
/* Revision 0x20 added DMA */
static const struct ata_port_info info_20 = {
- .sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -590,7 +476,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* Revision 0x20 with support logic added UDMA */
static const struct ata_port_info info_20_udma = {
- .sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -599,7 +484,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* Revision 0xC2 adds UDMA66 */
static const struct ata_port_info info_c2 = {
- .sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -608,7 +492,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* Revision 0xC3 is UDMA66 for now */
static const struct ata_port_info info_c3 = {
- .sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -617,7 +500,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* Revision 0xC4 is UDMA100 */
static const struct ata_port_info info_c4 = {
- .sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_PIO_LBA48,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -626,7 +508,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* Revision 0xC5 is UDMA133 with LBA48 DMA */
static const struct ata_port_info info_c5 = {
- .sht = &ali_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -637,6 +518,11 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
const struct ata_port_info *ppi[] = { NULL, NULL };
u8 tmp;
struct pci_dev *isa_bridge;
+ int rc;
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
/*
* The chipset revision selects the driver operations and
@@ -666,14 +552,21 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
ppi[0] = &info_20_udma;
pci_dev_put(isa_bridge);
}
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &ali_sht, NULL);
}
#ifdef CONFIG_PM
static int ali_reinit_one(struct pci_dev *pdev)
{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
ali_init_chipset(pdev);
- return ata_pci_device_resume(pdev);
+ ata_host_resume(host);
+ return 0;
}
#endif
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 4b8d9b592ca4..26665c396485 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -56,7 +56,9 @@ static void timing_setup(struct ata_port *ap, struct ata_device *adev, int offse
u8 t;
T = 1000000000 / amd_clock;
- UT = T / min_t(int, max_t(int, clock, 1), 2);
+ UT = T;
+ if (clock >= 2)
+ UT = T / 2;
if (ata_timing_compute(adev, speed, &at, T, UT) < 0) {
dev_printk(KERN_ERR, &pdev->dev, "unknown mode %d.\n", speed);
@@ -141,13 +143,7 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &amd_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-static void amd_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, amd_pre_reset, ata_std_softreset, NULL,
- ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
static int amd_cable_detect(struct ata_port *ap)
@@ -297,14 +293,7 @@ static int nv_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &nv_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-static void nv_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, nv_pre_reset,
- ata_std_softreset, NULL,
- ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -353,228 +342,66 @@ static void nv_host_stop(struct ata_host *host)
}
static struct scsi_host_template amd_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
+};
+
+static const struct ata_port_operations amd_base_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .prereset = amd_pre_reset,
};
static struct ata_port_operations amd33_port_ops = {
+ .inherits = &amd_base_port_ops,
+ .cable_detect = ata_cable_40wire,
.set_piomode = amd33_set_piomode,
.set_dmamode = amd33_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = amd_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
static struct ata_port_operations amd66_port_ops = {
+ .inherits = &amd_base_port_ops,
+ .cable_detect = ata_cable_unknown,
.set_piomode = amd66_set_piomode,
.set_dmamode = amd66_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = amd_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_unknown,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
static struct ata_port_operations amd100_port_ops = {
+ .inherits = &amd_base_port_ops,
+ .cable_detect = ata_cable_unknown,
.set_piomode = amd100_set_piomode,
.set_dmamode = amd100_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = amd_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_unknown,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
static struct ata_port_operations amd133_port_ops = {
+ .inherits = &amd_base_port_ops,
+ .cable_detect = amd_cable_detect,
.set_piomode = amd133_set_piomode,
.set_dmamode = amd133_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = amd_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = amd_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
+};
- .port_start = ata_sff_port_start,
+static const struct ata_port_operations nv_base_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = ata_cable_ignore,
+ .mode_filter = nv_mode_filter,
+ .prereset = nv_pre_reset,
+ .host_stop = nv_host_stop,
};
static struct ata_port_operations nv100_port_ops = {
+ .inherits = &nv_base_port_ops,
.set_piomode = nv100_set_piomode,
.set_dmamode = nv100_set_dmamode,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = nv_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_ignore,
- .mode_filter = nv_mode_filter,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
- .host_stop = nv_host_stop,
};
static struct ata_port_operations nv133_port_ops = {
+ .inherits = &nv_base_port_ops,
.set_piomode = nv133_set_piomode,
.set_dmamode = nv133_set_dmamode,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = nv_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_ignore,
- .mode_filter = nv_mode_filter,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
- .host_stop = nv_host_stop,
};
static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info[10] = {
{ /* 0: AMD 7401 */
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07, /* No SWDMA */
@@ -582,7 +409,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &amd33_port_ops
},
{ /* 1: Early AMD7409 - no swdma */
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -590,7 +416,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &amd66_port_ops
},
{ /* 2: AMD 7409, no swdma errata */
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -598,7 +423,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &amd66_port_ops
},
{ /* 3: AMD 7411 */
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -606,7 +430,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &amd100_port_ops
},
{ /* 4: AMD 7441 */
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -614,7 +437,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &amd100_port_ops
},
{ /* 5: AMD 8111*/
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -622,7 +444,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &amd133_port_ops
},
{ /* 6: AMD 8111 UDMA 100 (Serenade) */
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -630,7 +451,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &amd133_port_ops
},
{ /* 7: Nvidia Nforce */
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -638,7 +458,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &nv100_port_ops
},
{ /* 8: Nvidia Nforce2 and later */
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -646,7 +465,6 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &nv133_port_ops
},
{ /* 9: AMD CS5536 (Geode companion) */
- .sht = &amd_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -654,15 +472,20 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &amd100_port_ops
}
};
- struct ata_port_info pi;
- const struct ata_port_info *ppi[] = { &pi, NULL };
+ const struct ata_port_info *ppi[] = { NULL, NULL };
static int printed_version;
int type = id->driver_data;
+ void *hpriv = NULL;
u8 fifo;
+ int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
pci_read_config_byte(pdev, 0x41, &fifo);
/* Check for AMD7409 without swdma errata and if found adjust type */
@@ -677,10 +500,10 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
/*
* Okay, type is determined now. Apply type-specific workarounds.
*/
- pi = info[type];
+ ppi[0] = &info[type];
if (type < 3)
- ata_pci_clear_simplex(pdev);
+ ata_pci_bmdma_clear_simplex(pdev);
/* Check for AMD7411 */
if (type == 3)
@@ -696,16 +519,23 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
u32 udma;
pci_read_config_dword(pdev, 0x60, &udma);
- pi.private_data = (void *)(unsigned long)udma;
+ hpriv = (void *)(unsigned long)udma;
}
/* And fire it up */
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &amd_sht, hpriv);
}
#ifdef CONFIG_PM
static int amd_reinit_one(struct pci_dev *pdev)
{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
+
if (pdev->vendor == PCI_VENDOR_ID_AMD) {
u8 fifo;
pci_read_config_byte(pdev, 0x41, &fifo);
@@ -716,9 +546,11 @@ static int amd_reinit_one(struct pci_dev *pdev)
pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 ||
pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401)
- ata_pci_clear_simplex(pdev);
+ ata_pci_bmdma_clear_simplex(pdev);
}
- return ata_pci_device_resume(pdev);
+
+ ata_host_resume(host);
+ return 0;
}
#endif
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index d4218310327b..0f513bc11193 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -52,22 +52,7 @@ static int artop6210_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * artop6210_error_handler - Probe specified port on PATA host controller
- * @ap: Port to probe
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void artop6210_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, artop6210_pre_reset,
- ata_std_softreset, NULL,
- ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -93,7 +78,7 @@ static int artop6260_pre_reset(struct ata_link *link, unsigned long deadline)
if (pdev->device % 1 && !pci_test_config_bits(pdev, &artop_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -114,21 +99,6 @@ static int artop6260_cable_detect(struct ata_port *ap)
}
/**
- * artop6260_error_handler - Probe specified port on PATA host controller
- * @ap: Port to probe
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void artop6260_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, artop6260_pre_reset,
- ata_std_softreset, NULL,
- ata_std_postreset);
-}
-
-/**
* artop6210_load_piomode - Load a set of PATA PIO timings
* @ap: Port whose timings we are configuring
* @adev: Device
@@ -314,85 +284,23 @@ static void artop6260_set_dmamode (struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template artop_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations artop6210_ops = {
+static struct ata_port_operations artop6210_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = ata_cable_40wire,
.set_piomode = artop6210_set_piomode,
.set_dmamode = artop6210_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = artop6210_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .prereset = artop6210_pre_reset,
};
-static const struct ata_port_operations artop6260_ops = {
+static struct ata_port_operations artop6260_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = artop6260_cable_detect,
.set_piomode = artop6260_set_piomode,
.set_dmamode = artop6260_set_dmamode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = artop6260_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = artop6260_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .prereset = artop6260_pre_reset,
};
@@ -414,7 +322,6 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
{
static int printed_version;
static const struct ata_port_info info_6210 = {
- .sht = &artop_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -422,7 +329,6 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &artop6210_ops,
};
static const struct ata_port_info info_626x = {
- .sht = &artop_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -430,7 +336,6 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &artop6260_ops,
};
static const struct ata_port_info info_628x = {
- .sht = &artop_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -438,7 +343,6 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &artop6260_ops,
};
static const struct ata_port_info info_628x_fast = {
- .sht = &artop_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -446,11 +350,16 @@ static int artop_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &artop6260_ops,
};
const struct ata_port_info *ppi[] = { NULL, NULL };
+ int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
if (id->driver_data == 0) { /* 6210 variant */
ppi[0] = &info_6210;
ppi[1] = &ata_dummy_port_info;
@@ -491,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_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &artop_sht, NULL);
}
static const struct pci_device_id artop_pci_tbl[] = {
diff --git a/drivers/ata/pata_at32.c b/drivers/ata/pata_at32.c
index db057b183d60..3e8651d78952 100644
--- a/drivers/ata/pata_at32.c
+++ b/drivers/ata/pata_at32.c
@@ -166,52 +166,14 @@ static void pata_at32_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
}
-static void pata_at32_irq_clear(struct ata_port *ap)
-{
- /* No DMA controller yet */
-}
-
static struct scsi_host_template at32_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations at32_port_ops = {
- .set_piomode = pata_at32_set_piomode,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
.cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_clear = pata_at32_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_piomode = pata_at32_set_piomode,
};
static int __init pata_at32_init_one(struct device *dev,
@@ -261,7 +223,7 @@ static int __init pata_at32_init_one(struct device *dev,
host->private_data = info;
/* Register ATA device and return */
- return ata_host_activate(host, info->irq, ata_interrupt,
+ return ata_host_activate(host, info->irq, ata_sff_interrupt,
IRQF_SHARED | IRQF_TRIGGER_RISING,
&at32_sht);
}
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 408bdc1a9776..78738fb4223b 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -45,12 +45,7 @@ static int atiixp_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &atiixp_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-static void atiixp_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, atiixp_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
static int atiixp_cable_detect(struct ata_port *ap)
@@ -221,60 +216,26 @@ static void atiixp_bmdma_stop(struct ata_queued_cmd *qc)
}
static struct scsi_host_template atiixp_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
+ ATA_BMDMA_SHT(DRV_NAME),
.sg_tablesize = LIBATA_DUMB_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
static struct ata_port_operations atiixp_port_ops = {
- .set_piomode = atiixp_set_piomode,
- .set_dmamode = atiixp_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = atiixp_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = atiixp_cable_detect,
+ .inherits = &ata_bmdma_port_ops,
- .bmdma_setup = ata_bmdma_setup,
+ .qc_prep = ata_sff_dumb_qc_prep,
.bmdma_start = atiixp_bmdma_start,
.bmdma_stop = atiixp_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_dumb_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .cable_detect = atiixp_cable_detect,
+ .set_piomode = atiixp_set_piomode,
+ .set_dmamode = atiixp_set_dmamode,
+ .prereset = atiixp_pre_reset,
};
static int atiixp_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &atiixp_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x06, /* No MWDMA0 support */
@@ -282,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_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &atiixp_sht, NULL);
}
static const struct pci_device_id atiixp[] = {
diff --git a/drivers/ata/pata_bf54x.c b/drivers/ata/pata_bf54x.c
index 7f87f105c2f6..0a5ad98635b1 100644
--- a/drivers/ata/pata_bf54x.c
+++ b/drivers/ata/pata_bf54x.c
@@ -674,7 +674,7 @@ static void read_atapi_data(void __iomem *base,
* @ap: Port to which output is sent
* @tf: ATA taskfile register set
*
- * Note: Original code is ata_tf_load().
+ * Note: Original code is ata_sff_tf_load().
*/
static void bfin_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
@@ -745,7 +745,7 @@ static u8 bfin_check_status(struct ata_port *ap)
* @ap: Port from which input is read
* @tf: ATA taskfile register set for storing input
*
- * Note: Original code is ata_tf_read().
+ * Note: Original code is ata_sff_tf_read().
*/
static void bfin_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
@@ -775,7 +775,7 @@ static void bfin_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
* @ap: port to which command is being issued
* @tf: ATA taskfile register set
*
- * Note: Original code is ata_exec_command().
+ * Note: Original code is ata_sff_exec_command().
*/
static void bfin_exec_command(struct ata_port *ap,
@@ -785,7 +785,7 @@ static void bfin_exec_command(struct ata_port *ap,
dev_dbg(ap->dev, "ata%u: cmd 0x%X\n", ap->print_id, tf->command);
write_atapi_register(base, ATA_REG_CMD, tf->command);
- ata_pause(ap);
+ ata_sff_pause(ap);
}
/**
@@ -800,14 +800,14 @@ static u8 bfin_check_altstatus(struct ata_port *ap)
}
/**
- * bfin_std_dev_select - Select device 0/1 on ATA bus
+ * bfin_dev_select - Select device 0/1 on ATA bus
* @ap: ATA channel to manipulate
* @device: ATA device (numbered from zero) to select
*
- * Note: Original code is ata_std_dev_select().
+ * Note: Original code is ata_sff_dev_select().
*/
-static void bfin_std_dev_select(struct ata_port *ap, unsigned int device)
+static void bfin_dev_select(struct ata_port *ap, unsigned int device)
{
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
u8 tmp;
@@ -818,7 +818,7 @@ static void bfin_std_dev_select(struct ata_port *ap, unsigned int device)
tmp = ATA_DEVICE_OBS | ATA_DEV1;
write_atapi_register(base, ATA_REG_DEVICE, tmp);
- ata_pause(ap);
+ ata_sff_pause(ap);
}
/**
@@ -977,7 +977,7 @@ static unsigned int bfin_devchk(struct ata_port *ap,
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
u8 nsect, lbal;
- bfin_std_dev_select(ap, device);
+ bfin_dev_select(ap, device);
write_atapi_register(base, ATA_REG_NSECT, 0x55);
write_atapi_register(base, ATA_REG_LBAL, 0xaa);
@@ -1014,7 +1014,7 @@ static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask)
* BSY bit to clear
*/
if (dev0)
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ ata_sff_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
/* if device 1 was found in ata_devchk, wait for
* register access, then wait for BSY to clear
@@ -1023,7 +1023,7 @@ static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask)
while (dev1) {
u8 nsect, lbal;
- bfin_std_dev_select(ap, 1);
+ bfin_dev_select(ap, 1);
nsect = read_atapi_register(base, ATA_REG_NSECT);
lbal = read_atapi_register(base, ATA_REG_LBAL);
if ((nsect == 1) && (lbal == 1))
@@ -1035,14 +1035,14 @@ static void bfin_bus_post_reset(struct ata_port *ap, unsigned int devmask)
msleep(50); /* give drive a breather */
}
if (dev1)
- ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
+ ata_sff_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
/* is all this really necessary? */
- bfin_std_dev_select(ap, 0);
+ bfin_dev_select(ap, 0);
if (dev1)
- bfin_std_dev_select(ap, 1);
+ bfin_dev_select(ap, 1);
if (dev0)
- bfin_std_dev_select(ap, 0);
+ bfin_dev_select(ap, 0);
}
/**
@@ -1088,26 +1088,21 @@ static unsigned int bfin_bus_softreset(struct ata_port *ap,
}
/**
- * bfin_std_softreset - reset host port via ATA SRST
+ * bfin_softreset - reset host port via ATA SRST
* @ap: port to reset
* @classes: resulting classes of attached devices
*
- * Note: Original code is ata_std_softreset().
+ * Note: Original code is ata_sff_softreset().
*/
-static int bfin_std_softreset(struct ata_link *link, unsigned int *classes,
- unsigned long deadline)
+static int bfin_softreset(struct ata_link *link, unsigned int *classes,
+ unsigned long deadline)
{
struct ata_port *ap = link->ap;
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
unsigned int devmask = 0, err_mask;
u8 err;
- if (ata_link_offline(link)) {
- classes[0] = ATA_DEV_NONE;
- goto out;
- }
-
/* determine if device 0/1 are present */
if (bfin_devchk(ap, 0))
devmask |= (1 << 0);
@@ -1115,7 +1110,7 @@ static int bfin_std_softreset(struct ata_link *link, unsigned int *classes,
devmask |= (1 << 1);
/* select device 0 again */
- bfin_std_dev_select(ap, 0);
+ bfin_dev_select(ap, 0);
/* issue bus reset */
err_mask = bfin_bus_softreset(ap, devmask);
@@ -1126,13 +1121,12 @@ static int bfin_std_softreset(struct ata_link *link, unsigned int *classes,
}
/* determine by signature whether we have ATA or ATAPI devices */
- classes[0] = ata_dev_try_classify(&ap->link.device[0],
+ classes[0] = ata_sff_dev_classify(&ap->link.device[0],
devmask & (1 << 0), &err);
if (slave_possible && err != 0x81)
- classes[1] = ata_dev_try_classify(&ap->link.device[1],
+ classes[1] = ata_sff_dev_classify(&ap->link.device[1],
devmask & (1 << 1), &err);
- out:
return 0;
}
@@ -1167,7 +1161,7 @@ static unsigned char bfin_bmdma_status(struct ata_port *ap)
* @buflen: buffer length
* @write_data: read/write
*
- * Note: Original code is ata_data_xfer().
+ * Note: Original code is ata_sff_data_xfer().
*/
static unsigned int bfin_data_xfer(struct ata_device *dev, unsigned char *buf,
@@ -1206,7 +1200,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_bmdma_irq_clear().
+ * Note: Original code is ata_sff_irq_clear().
*/
static void bfin_irq_clear(struct ata_port *ap)
@@ -1223,7 +1217,7 @@ static void bfin_irq_clear(struct ata_port *ap)
* bfin_irq_on - Enable interrupts on a port.
* @ap: Port on which interrupts are enabled.
*
- * Note: Original code is ata_irq_on().
+ * Note: Original code is ata_sff_irq_on().
*/
static unsigned char bfin_irq_on(struct ata_port *ap)
@@ -1244,13 +1238,13 @@ static unsigned char bfin_irq_on(struct ata_port *ap)
}
/**
- * bfin_bmdma_freeze - Freeze DMA controller port
+ * bfin_freeze - Freeze DMA controller port
* @ap: port to freeze
*
- * Note: Original code is ata_bmdma_freeze().
+ * Note: Original code is ata_sff_freeze().
*/
-static void bfin_bmdma_freeze(struct ata_port *ap)
+static void bfin_freeze(struct ata_port *ap)
{
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
@@ -1264,19 +1258,19 @@ static void bfin_bmdma_freeze(struct ata_port *ap)
* ATA_NIEN manipulation. Also, many controllers fail to mask
* previously pending IRQ on ATA_NIEN assertion. Clear it.
*/
- ata_chk_status(ap);
+ ap->ops->sff_check_status(ap);
bfin_irq_clear(ap);
}
/**
- * bfin_bmdma_thaw - Thaw DMA controller port
+ * bfin_thaw - Thaw DMA controller port
* @ap: port to thaw
*
- * Note: Original code is ata_bmdma_thaw().
+ * Note: Original code is ata_sff_thaw().
*/
-void bfin_bmdma_thaw(struct ata_port *ap)
+void bfin_thaw(struct ata_port *ap)
{
bfin_check_status(ap);
bfin_irq_clear(ap);
@@ -1284,14 +1278,14 @@ void bfin_bmdma_thaw(struct ata_port *ap)
}
/**
- * bfin_std_postreset - standard postreset callback
+ * bfin_postreset - standard postreset callback
* @ap: the target ata_port
* @classes: classes of attached devices
*
- * Note: Original code is ata_std_postreset().
+ * Note: Original code is ata_sff_postreset().
*/
-static void bfin_std_postreset(struct ata_link *link, unsigned int *classes)
+static void bfin_postreset(struct ata_link *link, unsigned int *classes)
{
struct ata_port *ap = link->ap;
void __iomem *base = (void __iomem *)ap->ioaddr.ctl_addr;
@@ -1301,9 +1295,9 @@ static void bfin_std_postreset(struct ata_link *link, unsigned int *classes)
/* is double-select really necessary? */
if (classes[0] != ATA_DEV_NONE)
- bfin_std_dev_select(ap, 1);
+ bfin_dev_select(ap, 1);
if (classes[1] != ATA_DEV_NONE)
- bfin_std_dev_select(ap, 0);
+ bfin_dev_select(ap, 0);
/* bail out if no device is present */
if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
@@ -1314,17 +1308,6 @@ static void bfin_std_postreset(struct ata_link *link, unsigned int *classes)
write_atapi_register(base, ATA_REG_CTRL, ap->ctl);
}
-/**
- * bfin_error_handler - Stock error handler for DMA controller
- * @ap: port to handle error for
- */
-
-static void bfin_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, ata_std_prereset, bfin_std_softreset, NULL,
- bfin_std_postreset);
-}
-
static void bfin_port_stop(struct ata_port *ap)
{
dev_dbg(ap->dev, "in atapi port stop\n");
@@ -1357,51 +1340,40 @@ static int bfin_port_start(struct ata_port *ap)
}
static struct scsi_host_template bfin_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
+ ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = SG_NONE,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
static const struct ata_port_operations bfin_pata_ops = {
+ .inherits = &ata_sff_port_ops,
+
.set_piomode = bfin_set_piomode,
.set_dmamode = bfin_set_dmamode,
- .tf_load = bfin_tf_load,
- .tf_read = bfin_tf_read,
- .exec_command = bfin_exec_command,
- .check_status = bfin_check_status,
- .check_altstatus = bfin_check_altstatus,
- .dev_select = bfin_std_dev_select,
+ .sff_tf_load = bfin_tf_load,
+ .sff_tf_read = bfin_tf_read,
+ .sff_exec_command = bfin_exec_command,
+ .sff_check_status = bfin_check_status,
+ .sff_check_altstatus = bfin_check_altstatus,
+ .sff_dev_select = bfin_dev_select,
.bmdma_setup = bfin_bmdma_setup,
.bmdma_start = bfin_bmdma_start,
.bmdma_stop = bfin_bmdma_stop,
.bmdma_status = bfin_bmdma_status,
- .data_xfer = bfin_data_xfer,
+ .sff_data_xfer = bfin_data_xfer,
.qc_prep = ata_noop_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .freeze = bfin_bmdma_freeze,
- .thaw = bfin_bmdma_thaw,
- .error_handler = bfin_error_handler,
+ .freeze = bfin_freeze,
+ .thaw = bfin_thaw,
+ .softreset = bfin_softreset,
+ .postreset = bfin_postreset,
.post_internal_cmd = bfin_bmdma_stop,
- .irq_handler = ata_interrupt,
- .irq_clear = bfin_irq_clear,
- .irq_on = bfin_irq_on,
+ .sff_irq_clear = bfin_irq_clear,
+ .sff_irq_on = bfin_irq_on,
.port_start = bfin_port_start,
.port_stop = bfin_port_stop,
@@ -1409,7 +1381,6 @@ static const struct ata_port_operations bfin_pata_ops = {
static struct ata_port_info bfin_port_info[] = {
{
- .sht = &bfin_sht,
.flags = ATA_FLAG_SLAVE_POSS
| ATA_FLAG_MMIO
| ATA_FLAG_NO_LEGACY,
@@ -1536,7 +1507,7 @@ static int __devinit bfin_atapi_probe(struct platform_device *pdev)
}
if (ata_host_activate(host, platform_get_irq(pdev, 0),
- ata_interrupt, IRQF_SHARED, &bfin_sht) != 0) {
+ ata_sff_interrupt, IRQF_SHARED, &bfin_sht) != 0) {
peripheral_free_list(atapi_io_port);
dev_err(&pdev->dev, "Fail to attach ATAPI device\n");
return -ENODEV;
diff --git a/drivers/ata/pata_cmd640.c b/drivers/ata/pata_cmd640.c
index 43d198f90968..2de30b990278 100644
--- a/drivers/ata/pata_cmd640.c
+++ b/drivers/ata/pata_cmd640.c
@@ -107,8 +107,8 @@ static void cmd640_set_piomode(struct ata_port *ap, struct ata_device *adev)
pci_write_config_byte(pdev, arttim + 1, (t.active << 4) | t.recover);
} else {
/* Save the shared timings for channel, they will be loaded
- by qc_issue_prot. Reloading the setup time is expensive
- so we keep a merged one loaded */
+ by qc_issue. Reloading the setup time is expensive so we
+ keep a merged one loaded */
pci_read_config_byte(pdev, ARTIM23, &reg);
reg &= 0x3F;
reg |= t.setup;
@@ -119,14 +119,14 @@ static void cmd640_set_piomode(struct ata_port *ap, struct ata_device *adev)
/**
- * cmd640_qc_issue_prot - command preparation hook
+ * cmd640_qc_issue - command preparation hook
* @qc: Command to be issued
*
* Channel 1 has shared timings. We must reprogram the
* clock each drive 2/3 switch we do.
*/
-static unsigned int cmd640_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int cmd640_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -137,7 +137,7 @@ static unsigned int cmd640_qc_issue_prot(struct ata_queued_cmd *qc)
pci_write_config_byte(pdev, DRWTIM23, timing->reg58[adev->devno]);
timing->last = adev->devno;
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
/**
@@ -166,53 +166,16 @@ static int cmd640_port_start(struct ata_port *ap)
}
static struct scsi_host_template cmd640_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations cmd640_port_ops = {
- .set_piomode = cmd640_set_piomode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_bmdma_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,
.cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = cmd640_qc_issue_prot,
-
- /* In theory this is not needed once we kill the prefetcher */
- .data_xfer = ata_data_xfer_noirq,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
+ .set_piomode = cmd640_set_piomode,
.port_start = cmd640_port_start,
};
@@ -248,26 +211,36 @@ static void cmd640_hardware_init(struct pci_dev *pdev)
static int cmd640_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &cmd640_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &cmd640_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
+ int rc;
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
cmd640_hardware_init(pdev);
- return ata_pci_init_one(pdev, ppi);
+
+ return ata_pci_sff_init_one(pdev, ppi, &cmd640_sht, NULL);
}
+#ifdef CONFIG_PM
static int cmd640_reinit_one(struct pci_dev *pdev)
{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
cmd640_hardware_init(pdev);
-#ifdef CONFIG_PM
- return ata_pci_device_resume(pdev);
-#else
+ ata_host_resume(host);
return 0;
-#endif
}
+#endif
static const struct pci_device_id cmd640[] = {
{ PCI_VDEVICE(CMD, 0x640), 0 },
@@ -281,8 +254,8 @@ static struct pci_driver cmd640_pci_driver = {
.remove = ata_pci_remove_one,
#ifdef CONFIG_PM
.suspend = ata_pci_device_suspend,
-#endif
.resume = cmd640_reinit_one,
+#endif
};
static int __init cmd640_init(void)
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 7acbbd9ee469..ddd09b7d98c9 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -266,120 +266,30 @@ static void cmd646r1_bmdma_stop(struct ata_queued_cmd *qc)
}
static struct scsi_host_template cmd64x_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static struct ata_port_operations cmd64x_port_ops = {
+static const struct ata_port_operations cmd64x_base_ops = {
+ .inherits = &ata_bmdma_port_ops,
.set_piomode = cmd64x_set_piomode,
.set_dmamode = cmd64x_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
};
-static struct ata_port_operations cmd646r1_port_ops = {
- .set_piomode = cmd64x_set_piomode,
- .set_dmamode = cmd64x_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+static struct ata_port_operations cmd64x_port_ops = {
+ .inherits = &cmd64x_base_ops,
.cable_detect = ata_cable_40wire,
+};
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
+static struct ata_port_operations cmd646r1_port_ops = {
+ .inherits = &cmd64x_base_ops,
.bmdma_stop = cmd646r1_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
+ .cable_detect = ata_cable_40wire,
};
static struct ata_port_operations cmd648_port_ops = {
- .set_piomode = cmd64x_set_piomode,
- .set_dmamode = cmd64x_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = cmd648_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
+ .inherits = &cmd64x_base_ops,
.bmdma_stop = cmd648_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
+ .cable_detect = cmd648_cable_detect,
};
static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -388,21 +298,18 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct ata_port_info cmd_info[6] = {
{ /* CMD 643 - no UDMA */
- .sht = &cmd64x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 with broken UDMA */
- .sht = &cmd64x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 with working UDMA */
- .sht = &cmd64x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -410,14 +317,12 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &cmd64x_port_ops
},
{ /* CMD 646 rev 1 */
- .sht = &cmd64x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &cmd646r1_port_ops
},
{ /* CMD 648 */
- .sht = &cmd64x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -425,7 +330,6 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.port_ops = &cmd648_port_ops
},
{ /* CMD 649 */
- .sht = &cmd64x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -435,12 +339,17 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
const struct ata_port_info *ppi[] = { &cmd_info[id->driver_data], NULL };
u8 mrdmode;
+ int rc;
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xFF;
if (id->driver_data == 0) /* 643 */
- ata_pci_clear_simplex(pdev);
+ ata_pci_bmdma_clear_simplex(pdev);
if (pdev->device == PCI_DEVICE_ID_CMD_646) {
/* Does UDMA work ? */
@@ -464,13 +373,20 @@ 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_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &cmd64x_sht, NULL);
}
#ifdef CONFIG_PM
static int cmd64x_reinit_one(struct pci_dev *pdev)
{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
u8 mrdmode;
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
+
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
pci_read_config_byte(pdev, MRDMODE, &mrdmode);
mrdmode &= ~ 0x30; /* IRQ set up */
@@ -479,7 +395,8 @@ static int cmd64x_reinit_one(struct pci_dev *pdev)
#ifdef CONFIG_PPC
pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
#endif
- return ata_pci_device_resume(pdev);
+ ata_host_resume(host);
+ return 0;
}
#endif
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 7ed279b0a12e..1186bcd2781c 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -140,51 +140,16 @@ static void cs5520_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template cs5520_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
+ ATA_BMDMA_SHT(DRV_NAME),
.sg_tablesize = LIBATA_DUMB_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
static struct ata_port_operations cs5520_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .qc_prep = ata_sff_dumb_qc_prep,
+ .cable_detect = ata_cable_40wire,
.set_piomode = cs5520_set_piomode,
.set_dmamode = cs5520_set_dmamode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_dumb_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
@@ -203,6 +168,10 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
struct ata_ioports *ioaddr;
int i, rc;
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
/* IDE port enable bits */
pci_read_config_byte(pdev, 0x60, &pcicfg);
@@ -258,7 +227,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
ioaddr->ctl_addr = iomap[1];
ioaddr->altstatus_addr = iomap[1];
ioaddr->bmdma_addr = iomap[4];
- ata_std_ports(ioaddr);
+ ata_sff_std_ports(ioaddr);
ata_port_desc(host->ports[0],
"cmd 0x%x ctl 0x%x", cmd_port[0], ctl_port[0]);
@@ -269,7 +238,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
ioaddr->ctl_addr = iomap[3];
ioaddr->altstatus_addr = iomap[3];
ioaddr->bmdma_addr = iomap[4] + 8;
- ata_std_ports(ioaddr);
+ ata_sff_std_ports(ioaddr);
ata_port_desc(host->ports[1],
"cmd 0x%x ctl 0x%x", cmd_port[1], ctl_port[1]);
@@ -289,7 +258,7 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
continue;
rc = devm_request_irq(&pdev->dev, irq[ap->port_no],
- ata_interrupt, 0, DRV_NAME, host);
+ ata_sff_interrupt, 0, DRV_NAME, host);
if (rc)
return rc;
@@ -310,11 +279,20 @@ static int __devinit cs5520_init_one(struct pci_dev *pdev, const struct pci_devi
static int cs5520_reinit_one(struct pci_dev *pdev)
{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
u8 pcicfg;
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
+
pci_read_config_byte(pdev, 0x60, &pcicfg);
if ((pcicfg & 0x40) == 0)
pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
- return ata_pci_device_resume(pdev);
+
+ ata_host_resume(host);
+ return 0;
}
/**
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index e1818fdd9159..744beebaaf49 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -133,7 +133,7 @@ static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
/**
- * cs5530_qc_issue_prot - command issue
+ * cs5530_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
@@ -142,7 +142,7 @@ static void cs5530_set_dmamode(struct ata_port *ap, struct ata_device *adev)
* one MWDMA/UDMA bit.
*/
-static unsigned int cs5530_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int cs5530_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -157,59 +157,23 @@ static unsigned int cs5530_qc_issue_prot(struct ata_queued_cmd *qc)
cs5530_set_dmamode(ap, adev);
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static struct scsi_host_template cs5530_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_DUMB_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
+ .sg_tablesize = LIBATA_DUMB_MAX_PRD,
};
static struct ata_port_operations cs5530_port_ops = {
- .set_piomode = cs5530_set_piomode,
- .set_dmamode = cs5530_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_dumb_qc_prep,
- .qc_issue = cs5530_qc_issue_prot,
+ .inherits = &ata_bmdma_port_ops,
- .data_xfer = ata_data_xfer,
+ .qc_prep = ata_sff_dumb_qc_prep,
+ .qc_issue = cs5530_qc_issue,
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .cable_detect = ata_cable_40wire,
+ .set_piomode = cs5530_set_piomode,
+ .set_dmamode = cs5530_set_dmamode,
};
static const struct dmi_system_id palmax_dmi_table[] = {
@@ -334,7 +298,6 @@ fail_put:
static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &cs5530_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -343,12 +306,16 @@ static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* The docking connector doesn't do UDMA, and it seems not MWDMA */
static const struct ata_port_info info_palmax_secondary = {
- .sht = &cs5530_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &cs5530_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
+ int rc;
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
/* Chip initialisation */
if (cs5530_init_chip())
@@ -358,16 +325,25 @@ 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_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &cs5530_sht, NULL);
}
#ifdef CONFIG_PM
static int cs5530_reinit_one(struct pci_dev *pdev)
{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
+
/* If we fail on resume we are doomed */
if (cs5530_init_chip())
- BUG();
- return ata_pci_device_resume(pdev);
+ return -EIO;
+
+ ata_host_resume(host);
+ return 0;
}
#endif /* CONFIG_PM */
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 01324530d052..f1b6556f0483 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -158,55 +158,14 @@ static void cs5535_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template cs5535_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations cs5535_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = cs5535_cable_detect,
.set_piomode = cs5535_set_piomode,
.set_dmamode = cs5535_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = cs5535_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/**
@@ -222,7 +181,6 @@ static struct ata_port_operations cs5535_port_ops = {
static int cs5535_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &cs5535_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -241,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_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &cs5535_sht, NULL);
}
static const struct pci_device_id cs5535[] = {
diff --git a/drivers/ata/pata_cs5536.c b/drivers/ata/pata_cs5536.c
index 1c4ff9b52b5c..73f8332cb679 100644
--- a/drivers/ata/pata_cs5536.c
+++ b/drivers/ata/pata_cs5536.c
@@ -221,55 +221,14 @@ static void cs5536_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template cs5536_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations cs5536_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = cs5536_cable_detect,
.set_piomode = cs5536_set_piomode,
.set_dmamode = cs5536_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = cs5536_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
};
/**
@@ -282,7 +241,6 @@ static struct ata_port_operations cs5536_port_ops = {
static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &cs5536_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -303,7 +261,7 @@ static int cs5536_init_one(struct pci_dev *dev, const struct pci_device_id *id)
return -ENODEV;
}
- return ata_pci_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &cs5536_sht, NULL);
}
static const struct pci_device_id cs5536[] = {
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index fc5f9c4e5d87..a9c3218e22fd 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -110,61 +110,19 @@ static void cy82c693_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template cy82c693_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations cy82c693_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = ata_cable_40wire,
.set_piomode = cy82c693_set_piomode,
.set_dmamode = cy82c693_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &cy82c693_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -178,7 +136,7 @@ static int cy82c693_init_one(struct pci_dev *pdev, const struct pci_device_id *i
if (PCI_FUNC(pdev->devfn) != 1)
return -ENODEV;
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &cy82c693_sht, NULL);
}
static const struct pci_device_id cy82c693[] = {
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index dc33220fe5b2..9fba82976ba6 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -45,20 +45,7 @@ static int efar_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &efar_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * efar_probe_reset - Probe specified port on PATA host controller
- * @ap: Port to probe
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void efar_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, efar_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -233,53 +220,15 @@ static void efar_set_dmamode (struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template efar_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations efar_ops = {
+static struct ata_port_operations efar_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = efar_cable_detect,
.set_piomode = efar_set_piomode,
.set_dmamode = efar_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = efar_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = efar_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .prereset = efar_pre_reset,
};
@@ -301,7 +250,6 @@ static int efar_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
static const struct ata_port_info info = {
- .sht = &efar_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma1-2 */
@@ -314,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_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &efar_sht, NULL);
}
static const struct pci_device_id efar_pci_tbl[] = {
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index a742efa0da2b..f2b83eabc7c7 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -184,7 +184,7 @@ static unsigned long hpt366_filter(struct ata_device *adev, unsigned long mask)
if (hpt_dma_blacklisted(adev, "UDMA4", bad_ata66_4))
mask &= ~(0xF0 << ATA_SHIFT_UDMA);
}
- return ata_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, mask);
}
/**
@@ -290,21 +290,7 @@ static void hpt366_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template hpt36x_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
/*
@@ -312,37 +298,11 @@ static struct scsi_host_template hpt36x_sht = {
*/
static struct ata_port_operations hpt366_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = hpt36x_cable_detect,
+ .mode_filter = hpt366_filter,
.set_piomode = hpt366_set_piomode,
.set_dmamode = hpt366_set_dmamode,
- .mode_filter = hpt366_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = hpt36x_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/**
@@ -390,18 +350,22 @@ static void hpt36x_init_chipset(struct pci_dev *dev)
static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info_hpt366 = {
- .sht = &hpt36x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA4,
.port_ops = &hpt366_port_ops
};
- struct ata_port_info info = info_hpt366;
- const struct ata_port_info *ppi[] = { &info, NULL };
+ const struct ata_port_info *ppi[] = { &info_hpt366, NULL };
+ void *hpriv = NULL;
u32 class_rev;
u32 reg1;
+ int rc;
+
+ rc = pcim_enable_device(dev);
+ if (rc)
+ return rc;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xFF;
@@ -419,24 +383,31 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* info_hpt366 is safe against re-entry so we can scribble on it */
switch((reg1 & 0x700) >> 8) {
case 5:
- info.private_data = &hpt366_40;
+ hpriv = &hpt366_40;
break;
case 9:
- info.private_data = &hpt366_25;
+ hpriv = &hpt366_25;
break;
default:
- info.private_data = &hpt366_33;
+ hpriv = &hpt366_33;
break;
}
/* Now kick off ATA set up */
- return ata_pci_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &hpt36x_sht, hpriv);
}
#ifdef CONFIG_PM
static int hpt36x_reinit_one(struct pci_dev *dev)
{
+ struct ata_host *host = dev_get_drvdata(&dev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(dev);
+ if (rc)
+ return rc;
hpt36x_init_chipset(dev);
- return ata_pci_device_resume(dev);
+ ata_host_resume(host);
+ return 0;
}
#endif
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 9a10878b2ad8..42163998de9a 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -283,7 +283,7 @@ static unsigned long hpt370_filter(struct ata_device *adev, unsigned long mask)
if (hpt_dma_blacklisted(adev, "UDMA100", bad_ata100_5))
mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
- return ata_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, 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_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, mask);
}
/**
@@ -338,22 +338,10 @@ static int hpt37x_pre_reset(struct ata_link *link, unsigned long deadline)
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
- return ata_std_prereset(link, deadline);
+ return ata_sff_prereset(link, deadline);
}
-/**
- * hpt37x_error_handler - reset the hpt374
- * @ap: ATA port to reset
- *
- * Perform probe for HPT37x, except for HPT374 channel 2
- */
-
-static void hpt37x_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, hpt37x_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-static int hpt374_pre_reset(struct ata_link *link, unsigned long deadline)
+static int hpt374_fn1_pre_reset(struct ata_link *link, unsigned long deadline)
{
static const struct pci_bits hpt37x_enable_bits[] = {
{ 0x50, 1, 0x04, 0x04 },
@@ -386,26 +374,7 @@ static int hpt374_pre_reset(struct ata_link *link, unsigned long deadline)
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * hpt374_error_handler - reset the hpt374
- * @classes:
- *
- * The 374 cable detect is a little different due to the extra
- * channels. The function 0 channels work like usual but function 1
- * is special
- */
-
-static void hpt374_error_handler(struct ata_port *ap)
-{
- struct pci_dev *pdev = to_pci_dev(ap->host->dev);
-
- if (!(PCI_FUNC(pdev->devfn) & 1))
- hpt37x_error_handler(ap);
- else
- ata_bmdma_drive_eh(ap, hpt374_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -619,21 +588,7 @@ static void hpt37x_bmdma_stop(struct ata_queued_cmd *qc)
static struct scsi_host_template hpt37x_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
/*
@@ -641,36 +596,15 @@ static struct scsi_host_template hpt37x_sht = {
*/
static struct ata_port_operations hpt370_port_ops = {
- .set_piomode = hpt370_set_piomode,
- .set_dmamode = hpt370_set_dmamode,
- .mode_filter = hpt370_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
+ .inherits = &ata_bmdma_port_ops,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = hpt37x_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .bmdma_setup = ata_bmdma_setup,
.bmdma_start = hpt370_bmdma_start,
.bmdma_stop = hpt370_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
- .port_start = ata_sff_port_start,
+ .mode_filter = hpt370_filter,
+ .set_piomode = hpt370_set_piomode,
+ .set_dmamode = hpt370_set_dmamode,
+ .prereset = hpt37x_pre_reset,
};
/*
@@ -678,36 +612,8 @@ static struct ata_port_operations hpt370_port_ops = {
*/
static struct ata_port_operations hpt370a_port_ops = {
- .set_piomode = hpt370_set_piomode,
- .set_dmamode = hpt370_set_dmamode,
+ .inherits = &hpt370_port_ops,
.mode_filter = hpt370a_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = hpt37x_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = hpt370_bmdma_start,
- .bmdma_stop = hpt370_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/*
@@ -716,74 +622,23 @@ static struct ata_port_operations hpt370a_port_ops = {
*/
static struct ata_port_operations hpt372_port_ops = {
- .set_piomode = hpt372_set_piomode,
- .set_dmamode = hpt372_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
+ .inherits = &ata_bmdma_port_ops,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = hpt37x_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
.bmdma_stop = hpt37x_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
- .port_start = ata_sff_port_start,
+ .set_piomode = hpt372_set_piomode,
+ .set_dmamode = hpt372_set_dmamode,
+ .prereset = hpt37x_pre_reset,
};
/*
* Configuration for HPT374. Mode setting works like 372 and friends
- * but we have a different cable detection procedure.
+ * but we have a different cable detection procedure for function 1.
*/
-static struct ata_port_operations hpt374_port_ops = {
- .set_piomode = hpt372_set_piomode,
- .set_dmamode = hpt372_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = hpt374_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = hpt37x_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+static struct ata_port_operations hpt374_fn1_port_ops = {
+ .inherits = &hpt372_port_ops,
+ .prereset = hpt374_fn1_pre_reset,
};
/**
@@ -897,7 +752,6 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
/* HPT370 - UDMA100 */
static const struct ata_port_info info_hpt370 = {
- .sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -906,7 +760,6 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
};
/* HPT370A - UDMA100 */
static const struct ata_port_info info_hpt370a = {
- .sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -915,7 +768,6 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
};
/* HPT370 - UDMA100 */
static const struct ata_port_info info_hpt370_33 = {
- .sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -924,7 +776,6 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
};
/* HPT370A - UDMA100 */
static const struct ata_port_info info_hpt370a_33 = {
- .sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -933,28 +784,31 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
};
/* HPT371, 372 and friends - UDMA133 */
static const struct ata_port_info info_hpt372 = {
- .sht = &hpt37x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt372_port_ops
};
- /* HPT374 - UDMA100 */
- static const struct ata_port_info info_hpt374 = {
- .sht = &hpt37x_sht,
+ /* HPT374 - UDMA100, function 1 uses different prereset method */
+ static const struct ata_port_info info_hpt374_fn0 = {
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA5,
- .port_ops = &hpt374_port_ops
+ .port_ops = &hpt372_port_ops
+ };
+ static const struct ata_port_info info_hpt374_fn1 = {
+ .flags = ATA_FLAG_SLAVE_POSS,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA5,
+ .port_ops = &hpt374_fn1_port_ops
};
static const int MHz[4] = { 33, 40, 50, 66 };
- const struct ata_port_info *port;
void *private_data = NULL;
- struct ata_port_info port_info;
- const struct ata_port_info *ppi[] = { &port_info, NULL };
+ const struct ata_port_info *ppi[] = { NULL, NULL };
u8 irqmask;
u32 class_rev;
@@ -966,6 +820,11 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
const struct hpt_chip *chip_table;
int clock_slot;
+ int rc;
+
+ rc = pcim_enable_device(dev);
+ if (rc)
+ return rc;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xFF;
@@ -981,17 +840,17 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
switch(class_rev) {
case 3:
- port = &info_hpt370;
+ ppi[0] = &info_hpt370;
chip_table = &hpt370;
prefer_dpll = 0;
break;
case 4:
- port = &info_hpt370a;
+ ppi[0] = &info_hpt370a;
chip_table = &hpt370a;
prefer_dpll = 0;
break;
case 5:
- port = &info_hpt372;
+ ppi[0] = &info_hpt372;
chip_table = &hpt372;
break;
default:
@@ -1004,21 +863,21 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
/* 372N if rev >= 2*/
if (class_rev >= 2)
return -ENODEV;
- port = &info_hpt372;
+ ppi[0] = &info_hpt372;
chip_table = &hpt372a;
break;
case PCI_DEVICE_ID_TTI_HPT302:
/* 302N if rev > 1 */
if (class_rev > 1)
return -ENODEV;
- port = &info_hpt372;
+ ppi[0] = &info_hpt372;
/* Check this */
chip_table = &hpt302;
break;
case PCI_DEVICE_ID_TTI_HPT371:
if (class_rev > 1)
return -ENODEV;
- port = &info_hpt372;
+ ppi[0] = &info_hpt372;
chip_table = &hpt371;
/* Single channel device, master is not present
but the BIOS (or us for non x86) must mark it
@@ -1029,7 +888,10 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
break;
case PCI_DEVICE_ID_TTI_HPT374:
chip_table = &hpt374;
- port = &info_hpt374;
+ if (!(PCI_FUNC(dev->devfn) & 1))
+ *ppi = &info_hpt374_fn0;
+ else
+ *ppi = &info_hpt374_fn1;
break;
default:
printk(KERN_ERR "pata_hpt37x: PCI table is bogus please report (%d).\n", dev->device);
@@ -1108,7 +970,7 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
int dpll, adjust;
/* Compute DPLL */
- dpll = (port->udma_mask & 0xC0) ? 3 : 2;
+ dpll = (ppi[0]->udma_mask & 0xC0) ? 3 : 2;
f_low = (MHz[clock_slot] * 48) / MHz[dpll];
f_high = f_low + 2;
@@ -1148,19 +1010,16 @@ static int hpt37x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
* about lack of UDMA133 support on lower clocks
*/
- if (clock_slot < 2 && port == &info_hpt370)
- port = &info_hpt370_33;
- if (clock_slot < 2 && port == &info_hpt370a)
- port = &info_hpt370a_33;
+ if (clock_slot < 2 && ppi[0] == &info_hpt370)
+ ppi[0] = &info_hpt370_33;
+ if (clock_slot < 2 && ppi[0] == &info_hpt370a)
+ ppi[0] = &info_hpt370a_33;
printk(KERN_INFO "pata_hpt37x: %s using %dMHz bus clock.\n",
chip_table->name, MHz[clock_slot]);
}
/* Now kick off ATA set up */
- port_info = *port;
- port_info.private_data = private_data;
-
- return ata_pci_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &hpt37x_sht, private_data);
}
static const struct pci_device_id hpt37x[] = {
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 9f1c084f846f..d5c9fd7b82bb 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -148,7 +148,7 @@ static int hpt3x2n_cable_detect(struct ata_port *ap)
* Reset the hardware and state machine,
*/
-static int hpt3xn_pre_reset(struct ata_link *link, unsigned long deadline)
+static int hpt3x2n_pre_reset(struct ata_link *link, unsigned long deadline)
{
struct ata_port *ap = link->ap;
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
@@ -156,19 +156,7 @@ static int hpt3xn_pre_reset(struct ata_link *link, unsigned long deadline)
pci_write_config_byte(pdev, 0x50 + 4 * ap->port_no, 0x37);
udelay(100);
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * hpt3x2n_error_handler - probe the hpt3x2n bus
- * @ap: ATA port to reset
- *
- * Perform the probe reset handling for the 3x2N
- */
-
-static void hpt3x2n_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, hpt3xn_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -320,7 +308,7 @@ static int hpt3x2n_use_dpll(struct ata_port *ap, int writing)
return 0;
}
-static unsigned int hpt3x2n_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int hpt3x2n_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_taskfile *tf = &qc->tf;
struct ata_port *ap = qc->ap;
@@ -335,25 +323,11 @@ static unsigned int hpt3x2n_qc_issue_prot(struct ata_queued_cmd *qc)
hpt3x2n_set_clock(ap, 0x23);
}
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static struct scsi_host_template hpt3x2n_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
/*
@@ -361,37 +335,15 @@ static struct scsi_host_template hpt3x2n_sht = {
*/
static struct ata_port_operations hpt3x2n_port_ops = {
- .set_piomode = hpt3x2n_set_piomode,
- .set_dmamode = hpt3x2n_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = hpt3x2n_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = hpt3x2n_cable_detect,
+ .inherits = &ata_bmdma_port_ops,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
.bmdma_stop = hpt3x2n_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = hpt3x2n_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
+ .qc_issue = hpt3x2n_qc_issue,
- .port_start = ata_sff_port_start,
+ .cable_detect = hpt3x2n_cable_detect,
+ .set_piomode = hpt3x2n_set_piomode,
+ .set_dmamode = hpt3x2n_set_dmamode,
+ .prereset = hpt3x2n_pre_reset,
};
/**
@@ -488,15 +440,13 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
/* HPT372N and friends - UDMA133 */
static const struct ata_port_info info = {
- .sht = &hpt3x2n_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA6,
.port_ops = &hpt3x2n_port_ops
};
- struct ata_port_info port = info;
- const struct ata_port_info *ppi[] = { &port, NULL };
+ const struct ata_port_info *ppi[] = { &info, NULL };
u8 irqmask;
u32 class_rev;
@@ -505,6 +455,12 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
unsigned int f_low, f_high;
int adjust;
unsigned long iobase = pci_resource_start(dev, 4);
+ void *hpriv = NULL;
+ int rc;
+
+ rc = pcim_enable_device(dev);
+ if (rc)
+ return rc;
pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
class_rev &= 0xFF;
@@ -586,9 +542,8 @@ static int hpt3x2n_init_one(struct pci_dev *dev, const struct pci_device_id *id)
pci_mhz);
/* Set our private data up. We only need a few flags so we use
it directly */
- port.private_data = NULL;
if (pci_mhz > 60) {
- port.private_data = (void *)PCI66;
+ hpriv = (void *)PCI66;
/*
* On HPT371N, if ATA clock is 66 MHz we must set bit 2 in
* the MISC. register to stretch the UltraDMA Tss timing.
@@ -599,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_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &hpt3x2n_sht, hpriv);
}
static const struct pci_device_id hpt3x2n[] = {
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index cb8bdb6887de..f11a320337c0 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -102,58 +102,17 @@ static int hpt3x3_atapi_dma(struct ata_queued_cmd *qc)
}
static struct scsi_host_template hpt3x3_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations hpt3x3_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .check_atapi_dma= hpt3x3_atapi_dma,
+ .cable_detect = ata_cable_40wire,
.set_piomode = hpt3x3_set_piomode,
#if defined(CONFIG_PATA_HPT3X3_DMA)
.set_dmamode = hpt3x3_set_dmamode,
#endif
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .check_atapi_dma= hpt3x3_atapi_dma,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/**
@@ -189,7 +148,6 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
static int printed_version;
static const struct ata_port_info info = {
- .sht = &hpt3x3_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
#if defined(CONFIG_PATA_HPT3X3_DMA)
@@ -244,15 +202,15 @@ static int hpt3x3_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
ioaddr->altstatus_addr =
ioaddr->ctl_addr = base + offset_ctl[i];
ioaddr->scr_addr = NULL;
- ata_std_ports(ioaddr);
+ ata_sff_std_ports(ioaddr);
ioaddr->bmdma_addr = base + 8 * i;
ata_port_pbar_desc(ap, 4, -1, "ioport");
ata_port_pbar_desc(ap, 4, offset_cmd[i], "cmd");
}
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
- &hpt3x3_sht);
+ return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ IRQF_SHARED, &hpt3x3_sht);
}
#ifdef CONFIG_PM
diff --git a/drivers/ata/pata_icside.c b/drivers/ata/pata_icside.c
index f97068be2d79..17138436423d 100644
--- a/drivers/ata/pata_icside.c
+++ b/drivers/ata/pata_icside.c
@@ -250,7 +250,7 @@ static void pata_icside_bmdma_setup(struct ata_queued_cmd *qc)
set_dma_mode(state->dma, write ? DMA_MODE_WRITE : DMA_MODE_READ);
/* issue r/w command */
- ap->ops->exec_command(ap, &qc->tf);
+ ap->ops->sff_exec_command(ap, &qc->tf);
}
static void pata_icside_bmdma_start(struct ata_queued_cmd *qc)
@@ -270,7 +270,7 @@ static void pata_icside_bmdma_stop(struct ata_queued_cmd *qc)
disable_dma(state->dma);
/* see ata_bmdma_stop */
- ata_altstatus(ap);
+ ata_sff_altstatus(ap);
}
static u8 pata_icside_bmdma_status(struct ata_port *ap)
@@ -305,35 +305,18 @@ static int icside_dma_init(struct pata_icside_info *info)
static struct scsi_host_template pata_icside_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
+ ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = PATA_ICSIDE_MAX_SG,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
.dma_boundary = ~0, /* no dma boundaries */
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
-/* wish this was exported from libata-core */
-static void ata_dummy_noret(struct ata_port *port)
-{
-}
-
static void pata_icside_postreset(struct ata_link *link, unsigned int *classes)
{
struct ata_port *ap = link->ap;
struct pata_icside_state *state = ap->host->private_data;
if (classes[0] != ATA_DEV_NONE || classes[1] != ATA_DEV_NONE)
- return ata_std_postreset(link, classes);
+ return ata_sff_postreset(link, classes);
state->port[ap->port_no].disabled = 1;
@@ -349,42 +332,20 @@ static void pata_icside_postreset(struct ata_link *link, unsigned int *classes)
}
}
-static void pata_icside_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
- pata_icside_postreset);
-}
-
static struct ata_port_operations pata_icside_port_ops = {
- .set_dmamode = pata_icside_set_dmamode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
-
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = pata_icside_bmdma_setup,
- .bmdma_start = pata_icside_bmdma_start,
-
- .data_xfer = ata_data_xfer_noirq,
-
+ .inherits = &ata_sff_port_ops,
/* no need to build any PRD tables for DMA */
.qc_prep = ata_noop_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = pata_icside_error_handler,
- .post_internal_cmd = pata_icside_bmdma_stop,
-
- .irq_clear = ata_dummy_noret,
- .irq_on = ata_irq_on,
-
+ .sff_data_xfer = ata_sff_data_xfer_noirq,
+ .bmdma_setup = pata_icside_bmdma_setup,
+ .bmdma_start = pata_icside_bmdma_start,
.bmdma_stop = pata_icside_bmdma_stop,
.bmdma_status = pata_icside_bmdma_status,
+
+ .cable_detect = ata_cable_40wire,
+ .set_dmamode = pata_icside_set_dmamode,
+ .postreset = pata_icside_postreset,
+ .post_internal_cmd = pata_icside_bmdma_stop,
};
static void __devinit
@@ -520,7 +481,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_interrupt, 0,
+ return ata_host_activate(host, ec->irq, ata_sff_interrupt, 0,
&pata_icside_sht);
}
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 4320e7986321..6a111baab523 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -20,45 +20,12 @@
#define DRV_VERSION "0.2.2"
static struct scsi_host_template isapnp_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations isapnp_port_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
.cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/**
@@ -83,7 +50,7 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
if (pnp_irq_valid(idev, 0)) {
irq = pnp_irq(idev, 0);
- handler = ata_interrupt;
+ handler = ata_sff_interrupt;
}
/* allocate host */
@@ -111,7 +78,7 @@ static int isapnp_init_one(struct pnp_dev *idev, const struct pnp_device_id *dev
ap->ioaddr.ctl_addr = ctl_addr;
}
- ata_std_ports(&ap->ioaddr);
+ ata_sff_std_ports(&ap->ioaddr);
ata_port_desc(ap, "cmd 0x%llx ctl 0x%llx",
(unsigned long long)pnp_port_start(idev, 0),
diff --git a/drivers/ata/pata_it8213.c b/drivers/ata/pata_it8213.c
index e0c2cc29d0ca..c113d7c079c8 100644
--- a/drivers/ata/pata_it8213.c
+++ b/drivers/ata/pata_it8213.c
@@ -40,20 +40,7 @@ static int it8213_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &it8213_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * it8213_error_handler - Probe specified port on PATA host controller
- * @ap: Port to probe
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void it8213_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, it8213_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -243,53 +230,16 @@ static void it8213_set_dmamode (struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template it8213_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations it8213_ops = {
+
+static struct ata_port_operations it8213_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = it8213_cable_detect,
.set_piomode = it8213_set_piomode,
.set_dmamode = it8213_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = it8213_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = it8213_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .prereset = it8213_pre_reset,
};
@@ -311,7 +261,6 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
{
static int printed_version;
static const struct ata_port_info info = {
- .sht = &it8213_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -325,7 +274,7 @@ static int it8213_init_one (struct pci_dev *pdev, const struct pci_device_id *en
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &it8213_sht, NULL);
}
static const struct pci_device_id it8213_pci_tbl[] = {
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 257951d03dbb..e10816931b2f 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -395,11 +395,11 @@ static void it821x_passthru_dev_select(struct ata_port *ap,
it821x_program(ap, adev, itdev->pio[adev->devno]);
itdev->last_device = device;
}
- ata_std_dev_select(ap, device);
+ ata_sff_dev_select(ap, device);
}
/**
- * it821x_smart_qc_issue_prot - wrap qc issue prot
+ * it821x_smart_qc_issue - wrap qc issue prot
* @qc: command
*
* Wrap the command issue sequence for the IT821x. We need to
@@ -407,7 +407,7 @@ static void it821x_passthru_dev_select(struct ata_port *ap,
* usual happenings kick off
*/
-static unsigned int it821x_smart_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int it821x_smart_qc_issue(struct ata_queued_cmd *qc)
{
switch(qc->tf.command)
{
@@ -427,14 +427,14 @@ static unsigned int it821x_smart_qc_issue_prot(struct ata_queued_cmd *qc)
case ATA_CMD_ID_ATA:
/* Arguably should just no-op this one */
case ATA_CMD_SET_FEATURES:
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
printk(KERN_DEBUG "it821x: can't process command 0x%02X\n", qc->tf.command);
return AC_ERR_DEV;
}
/**
- * it821x_passthru_qc_issue_prot - wrap qc issue prot
+ * it821x_passthru_qc_issue - wrap qc issue prot
* @qc: command
*
* Wrap the command issue sequence for the IT821x. We need to
@@ -442,10 +442,10 @@ static unsigned int it821x_smart_qc_issue_prot(struct ata_queued_cmd *qc)
* usual happenings kick off
*/
-static unsigned int it821x_passthru_qc_issue_prot(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_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
/**
@@ -632,89 +632,34 @@ static int it821x_port_start(struct ata_port *ap)
}
static struct scsi_host_template it821x_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations it821x_smart_port_ops = {
- .set_mode = it821x_smart_set_mode,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .mode_filter = ata_pci_default_filter,
+ .inherits = &ata_bmdma_port_ops,
- .check_status = ata_check_status,
.check_atapi_dma= it821x_check_atapi_dma,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
- .dev_config = it821x_dev_config,
+ .qc_issue = it821x_smart_qc_issue,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = it821x_ident_hack,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = it821x_smart_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
+ .set_mode = it821x_smart_set_mode,
+ .dev_config = it821x_dev_config,
.port_start = it821x_port_start,
};
static struct ata_port_operations it821x_passthru_port_ops = {
- .set_piomode = it821x_passthru_set_piomode,
- .set_dmamode = it821x_passthru_set_dmamode,
- .mode_filter = ata_pci_default_filter,
+ .inherits = &ata_bmdma_port_ops,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
.check_atapi_dma= it821x_check_atapi_dma,
- .dev_select = it821x_passthru_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_unknown,
-
- .bmdma_setup = ata_bmdma_setup,
+ .sff_dev_select = it821x_passthru_dev_select,
.bmdma_start = it821x_passthru_bmdma_start,
.bmdma_stop = it821x_passthru_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = it821x_passthru_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
+ .qc_issue = it821x_passthru_qc_issue,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_handler = ata_interrupt,
- .irq_on = ata_irq_on,
+ .cable_detect = ata_cable_unknown,
+ .set_piomode = it821x_passthru_set_piomode,
+ .set_dmamode = it821x_passthru_set_dmamode,
.port_start = it821x_port_start,
};
@@ -742,14 +687,12 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
u8 conf;
static const struct ata_port_info info_smart = {
- .sht = &it821x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &it821x_smart_port_ops
};
static const struct ata_port_info info_passthru = {
- .sht = &it821x_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -759,6 +702,11 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
const struct ata_port_info *ppi[] = { NULL, NULL };
static char *mode[2] = { "pass through", "smart" };
+ int rc;
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
/* Force the card into bypass mode if so requested */
if (it8212_noraid) {
@@ -774,16 +722,23 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
else
ppi[0] = &info_smart;
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &it821x_sht, NULL);
}
#ifdef CONFIG_PM
static int it821x_reinit_one(struct pci_dev *pdev)
{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
/* Resume - turn raid back off if need be */
if (it8212_noraid)
it821x_disable_raid(pdev);
- return ata_pci_device_resume(pdev);
+ ata_host_resume(host);
+ return rc;
}
#endif
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
index 030878fedeb5..8a175f23b907 100644
--- a/drivers/ata/pata_ixp4xx_cf.c
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -88,48 +88,14 @@ static unsigned int ixp4xx_mmio_data_xfer(struct ata_device *dev,
}
static struct scsi_host_template ixp4xx_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations ixp4xx_port_ops = {
- .set_mode = ixp4xx_set_mode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ixp4xx_mmio_data_xfer,
+ .inherits = &ata_sff_port_ops,
+ .sff_data_xfer = ixp4xx_mmio_data_xfer,
.cable_detect = ata_cable_40wire,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
+ .set_mode = ixp4xx_set_mode,
};
static void ixp4xx_setup_port(struct ata_port *ap,
@@ -144,7 +110,7 @@ static void ixp4xx_setup_port(struct ata_port *ap,
ioaddr->altstatus_addr = data->cs1 + 0x06;
ioaddr->ctl_addr = data->cs1 + 0x06;
- ata_std_ports(ioaddr);
+ ata_sff_std_ports(ioaddr);
#ifndef __ARMEB__
@@ -220,7 +186,7 @@ static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
/* activate host */
- return ata_host_activate(host, irq, ata_interrupt, 0, &ixp4xx_sht);
+ return ata_host_activate(host, irq, ata_sff_interrupt, 0, &ixp4xx_sht);
}
static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 00bbbbd50e97..73b7596816b4 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -102,73 +102,18 @@ static int jmicron_pre_reset(struct ata_link *link, unsigned long deadline)
ap->cbl = ATA_CBL_SATA;
break;
}
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * jmicron_error_handler - Setup and error handler
- * @ap: Port to handle
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void jmicron_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, jmicron_pre_reset, ata_std_softreset, NULL,
- ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/* No PIO or DMA methods needed for this device */
static struct scsi_host_template jmicron_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- /* Use standard CHS mapping rules */
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations jmicron_ops = {
- /* Task file is PCI ATA format, use helpers */
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = jmicron_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- /* BMDMA handling is PCI ATA format, use helpers */
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- /* IRQ-related hooks */
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- /* Generic PATA PCI ATA helpers */
- .port_start = ata_port_start,
+static struct ata_port_operations jmicron_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .prereset = jmicron_pre_reset,
};
@@ -189,7 +134,6 @@ static const struct ata_port_operations jmicron_ops = {
static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &jmicron_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
@@ -200,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_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &jmicron_sht, NULL);
}
static const struct pci_device_id jmicron_pci_tbl[] = {
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index 50fe08ebe23c..7af4b29cc422 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -208,21 +208,12 @@ static int legacy_set_mode(struct ata_link *link, struct ata_device **unused)
}
static struct scsi_host_template legacy_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
+};
+
+static const struct ata_port_operations legacy_base_port_ops = {
+ .inherits = &ata_sff_port_ops,
+ .cable_detect = ata_cable_40wire,
};
/*
@@ -234,55 +225,14 @@ static struct scsi_host_template legacy_sht = {
*/
static struct ata_port_operations simple_port_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer_noirq,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .inherits = &legacy_base_port_ops,
+ .sff_data_xfer = ata_sff_data_xfer_noirq,
};
static struct ata_port_operations legacy_port_ops = {
+ .inherits = &legacy_base_port_ops,
+ .sff_data_xfer = ata_sff_data_xfer_noirq,
.set_mode = legacy_set_mode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
- .cable_detect = ata_cable_40wire,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer_noirq,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/*
@@ -367,36 +317,15 @@ static unsigned int pdc_data_xfer_vlb(struct ata_device *dev,
}
local_irq_restore(flags);
} else
- buflen = ata_data_xfer_noirq(dev, buf, buflen, rw);
+ buflen = ata_sff_data_xfer_noirq(dev, buf, buflen, rw);
return buflen;
}
static struct ata_port_operations pdc20230_port_ops = {
+ .inherits = &legacy_base_port_ops,
.set_piomode = pdc20230_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = pdc_data_xfer_vlb,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .sff_data_xfer = pdc_data_xfer_vlb,
};
/*
@@ -427,30 +356,8 @@ static void ht6560a_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
static struct ata_port_operations ht6560a_port_ops = {
+ .inherits = &legacy_base_port_ops,
.set_piomode = ht6560a_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer, /* Check vlb/noirq */
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/*
@@ -492,30 +399,8 @@ static void ht6560b_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
static struct ata_port_operations ht6560b_port_ops = {
+ .inherits = &legacy_base_port_ops,
.set_piomode = ht6560b_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer, /* FIXME: Check 32bit and noirq */
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/*
@@ -613,30 +498,8 @@ static void opti82c611a_set_piomode(struct ata_port *ap,
static struct ata_port_operations opti82c611a_port_ops = {
+ .inherits = &legacy_base_port_ops,
.set_piomode = opti82c611a_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/*
@@ -716,7 +579,7 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
/**
- * opt82c465mv_qc_issue_prot - command issue
+ * opt82c465mv_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
@@ -730,7 +593,7 @@ static void opti82c46x_set_piomode(struct ata_port *ap, struct ata_device *adev)
* FIXME: dual channel needs ->serialize support
*/
-static unsigned int opti82c46x_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int opti82c46x_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -741,34 +604,13 @@ static unsigned int opti82c46x_qc_issue_prot(struct ata_queued_cmd *qc)
&& ap->host->private_data != NULL)
opti82c46x_set_piomode(ap, adev);
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static struct ata_port_operations opti82c46x_port_ops = {
+ .inherits = &legacy_base_port_ops,
.set_piomode = opti82c46x_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = opti82c46x_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .qc_issue = opti82c46x_qc_issue,
};
static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
@@ -802,7 +644,7 @@ static void qdi6500_set_piomode(struct ata_port *ap, struct ata_device *adev)
* @irq: interrupt line
*
* In dual channel mode the 6580 has one clock per channel and we have
- * to software clockswitch in qc_issue_prot.
+ * to software clockswitch in qc_issue.
*/
static void qdi6580dp_set_piomode(struct ata_port *ap, struct ata_device *adev)
@@ -868,14 +710,14 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
/**
- * qdi_qc_issue_prot - command issue
+ * qdi_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings.
*/
-static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int qdi_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -888,7 +730,7 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
2 * ap->port_no);
}
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf,
@@ -917,7 +759,7 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf,
}
return (buflen + 3) & ~3;
} else
- return ata_data_xfer(adev, buf, buflen, rw);
+ return ata_sff_data_xfer(adev, buf, buflen, rw);
}
static int qdi_port(struct platform_device *dev,
@@ -930,84 +772,22 @@ static int qdi_port(struct platform_device *dev,
}
static struct ata_port_operations qdi6500_port_ops = {
+ .inherits = &legacy_base_port_ops,
.set_piomode = qdi6500_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = qdi_qc_issue_prot,
-
- .data_xfer = vlb32_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .qc_issue = qdi_qc_issue,
+ .sff_data_xfer = vlb32_data_xfer,
};
static struct ata_port_operations qdi6580_port_ops = {
+ .inherits = &legacy_base_port_ops,
.set_piomode = qdi6580_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = vlb32_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .sff_data_xfer = vlb32_data_xfer,
};
static struct ata_port_operations qdi6580dp_port_ops = {
+ .inherits = &legacy_base_port_ops,
.set_piomode = qdi6580dp_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = qdi_qc_issue_prot,
-
- .data_xfer = vlb32_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .sff_data_xfer = vlb32_data_xfer,
};
static DEFINE_SPINLOCK(winbond_lock);
@@ -1076,29 +856,9 @@ static int winbond_port(struct platform_device *dev,
}
static struct ata_port_operations winbond_port_ops = {
+ .inherits = &legacy_base_port_ops,
.set_piomode = winbond_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = vlb32_data_xfer,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .sff_data_xfer = vlb32_data_xfer,
};
static struct legacy_controller controllers[] = {
@@ -1256,13 +1016,13 @@ static __init int legacy_init_one(struct legacy_probe *probe)
ap->ioaddr.cmd_addr = io_addr;
ap->ioaddr.altstatus_addr = ctrl_addr;
ap->ioaddr.ctl_addr = ctrl_addr;
- ata_std_ports(&ap->ioaddr);
+ ata_sff_std_ports(&ap->ioaddr);
ap->host->private_data = ld;
ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io, io + 0x0206);
- ret = ata_host_activate(host, probe->irq, ata_interrupt, 0,
- &legacy_sht);
+ ret = ata_host_activate(host, probe->irq, ata_sff_interrupt, 0,
+ &legacy_sht);
if (ret)
goto fail;
ld->platform_dev = pdev;
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
index a81f25d87235..24a011b25024 100644
--- a/drivers/ata/pata_marvell.c
+++ b/drivers/ata/pata_marvell.c
@@ -55,7 +55,7 @@ static int marvell_pre_reset(struct ata_link *link, unsigned long deadline)
(!(devices & 0x10))) /* PATA enable ? */
return -ENOENT;
- return ata_std_prereset(link, deadline);
+ return ata_sff_prereset(link, deadline);
}
static int marvell_cable_detect(struct ata_port *ap)
@@ -75,71 +75,16 @@ static int marvell_cable_detect(struct ata_port *ap)
return 0; /* Our BUG macro needs the right markup */
}
-/**
- * marvell_error_handler - Setup and error handler
- * @ap: Port to handle
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void marvell_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset, NULL,
- ata_std_postreset);
-}
-
/* No PIO or DMA methods needed for this device */
static struct scsi_host_template marvell_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- /* Use standard CHS mapping rules */
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations marvell_ops = {
- /* Task file is PCI ATA format, use helpers */
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = marvell_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+static struct ata_port_operations marvell_ops = {
+ .inherits = &ata_bmdma_port_ops,
.cable_detect = marvell_cable_detect,
-
- /* BMDMA handling is PCI ATA format, use helpers */
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- /* Timeout handling */
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- /* Generic PATA PCI ATA helpers */
- .port_start = ata_sff_port_start,
+ .prereset = marvell_pre_reset,
};
@@ -160,7 +105,6 @@ static const struct ata_port_operations marvell_ops = {
static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &marvell_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
@@ -170,7 +114,6 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
.port_ops = &marvell_ops,
};
static const struct ata_port_info info_sata = {
- .sht = &marvell_sht,
/* Slave possible as its magically mapped not real */
.flags = ATA_FLAG_SLAVE_POSS,
@@ -185,7 +128,7 @@ static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *i
if (pdev->device == 0x6101)
ppi[1] = &ata_dummy_port_info;
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &marvell_sht, NULL);
}
static const struct pci_device_id marvell_pci_tbl[] = {
diff --git a/drivers/ata/pata_mpc52xx.c b/drivers/ata/pata_mpc52xx.c
index 5413ebfa72e5..bc79df6e7cb0 100644
--- a/drivers/ata/pata_mpc52xx.c
+++ b/drivers/ata/pata_mpc52xx.c
@@ -252,53 +252,19 @@ mpc52xx_ata_dev_select(struct ata_port *ap, unsigned int device)
if (device != priv->csel)
mpc52xx_ata_apply_timings(priv, device);
- ata_std_dev_select(ap,device);
+ ata_sff_dev_select(ap,device);
}
-static void
-mpc52xx_ata_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
- ata_std_postreset);
-}
-
-
-
static struct scsi_host_template mpc52xx_ata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .max_sectors = ATA_MAX_SECTORS,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations mpc52xx_ata_port_ops = {
- .set_piomode = mpc52xx_ata_set_piomode,
- .dev_select = mpc52xx_ata_dev_select,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = mpc52xx_ata_error_handler,
+ .inherits = &ata_sff_port_ops,
+ .sff_dev_select = mpc52xx_ata_dev_select,
.cable_detect = ata_cable_40wire,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
- .port_start = ata_port_start,
+ .set_piomode = mpc52xx_ata_set_piomode,
+ .post_internal_cmd = ATA_OP_NULL,
};
static int __devinit
@@ -339,7 +305,7 @@ mpc52xx_ata_init_one(struct device *dev, struct mpc52xx_ata_priv *priv,
ata_port_desc(ap, "ata_regs 0x%lx", raw_ata_regs);
/* activate host */
- return ata_host_activate(host, priv->ata_irq, ata_interrupt, 0,
+ return ata_host_activate(host, priv->ata_irq, ata_sff_interrupt, 0,
&mpc52xx_ata_sht);
}
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index c0d9e0cf208c..7d7e3fdab71f 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -55,21 +55,7 @@ static int mpiix_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &mpiix_enable_bits))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * mpiix_error_handler - probe reset
- * @ap: ATA port
- *
- * Perform the ATA probe and bus reset sequence plus specific handling
- * for this hardware. The MPIIX has the enable bits in a different place
- * to PIIX4 and friends. As a pure PIO device it has no cable detect
- */
-
-static void mpiix_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, mpiix_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -83,8 +69,8 @@ static void mpiix_error_handler(struct ata_port *ap)
*
* This would get very ugly because we can only program timing for one
* device at a time, the other gets PIO0. Fortunately libata calls
- * our qc_issue_prot command before a command is issued so we can
- * flip the timings back and forth to reduce the pain.
+ * our qc_issue command before a command is issued so we can flip the
+ * timings back and forth to reduce the pain.
*/
static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev)
@@ -124,7 +110,7 @@ static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
/**
- * mpiix_qc_issue_prot - command issue
+ * mpiix_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
@@ -134,7 +120,7 @@ static void mpiix_set_piomode(struct ata_port *ap, struct ata_device *adev)
* be made PIO0.
*/
-static unsigned int mpiix_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int mpiix_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -147,50 +133,19 @@ static unsigned int mpiix_qc_issue_prot(struct ata_queued_cmd *qc)
if (adev->pio_mode && adev != ap->private_data)
mpiix_set_piomode(ap, adev);
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static struct scsi_host_template mpiix_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations mpiix_port_ops = {
- .set_piomode = mpiix_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = mpiix_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
+ .qc_issue = mpiix_qc_issue,
.cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = mpiix_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_piomode = mpiix_set_piomode,
+ .prereset = mpiix_pre_reset,
};
static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -252,10 +207,10 @@ static int mpiix_init_one(struct pci_dev *dev, const struct pci_device_id *id)
ap->ioaddr.altstatus_addr = ctl_addr;
/* Let libata fill in the port details */
- ata_std_ports(&ap->ioaddr);
+ ata_sff_std_ports(&ap->ioaddr);
/* activate host */
- return ata_host_activate(host, irq, ata_interrupt, IRQF_SHARED,
+ return ata_host_activate(host, irq, ata_sff_interrupt, IRQF_SHARED,
&mpiix_sht);
}
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index 25c922abd554..d9719c8b9dbe 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -21,54 +21,12 @@
/* No PIO or DMA methods needed for this device */
static struct scsi_host_template netcell_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- /* Use standard CHS mapping rules */
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations netcell_ops = {
- /* Task file is PCI ATA format, use helpers */
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+static struct ata_port_operations netcell_ops = {
+ .inherits = &ata_bmdma_port_ops,
.cable_detect = ata_cable_80wire,
-
- /* BMDMA handling is PCI ATA format, use helpers */
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- /* IRQ-related hooks */
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- /* Generic PATA PCI ATA helpers */
- .port_start = ata_sff_port_start,
};
@@ -90,7 +48,6 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
{
static int printed_version;
static const struct ata_port_info info = {
- .sht = &netcell_sht,
.flags = ATA_FLAG_SLAVE_POSS,
/* Actually we don't really care about these as the
firmware deals with it */
@@ -100,16 +57,21 @@ static int netcell_init_one (struct pci_dev *pdev, const struct pci_device_id *e
.port_ops = &netcell_ops,
};
const struct ata_port_info *port_info[] = { &info, NULL };
+ int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
/* Any chip specific setup/optimisation/messages here */
- ata_pci_clear_simplex(pdev);
+ ata_pci_bmdma_clear_simplex(pdev);
/* And let the library code do the work */
- return ata_pci_init_one(pdev, port_info);
+ return ata_pci_sff_init_one(pdev, port_info, &netcell_sht, NULL);
}
static const struct pci_device_id netcell_pci_tbl[] = {
diff --git a/drivers/ata/pata_ninja32.c b/drivers/ata/pata_ninja32.c
index 15dd649f89ee..565e67cd13fa 100644
--- a/drivers/ata/pata_ninja32.c
+++ b/drivers/ata/pata_ninja32.c
@@ -73,60 +73,20 @@ static void ninja32_dev_select(struct ata_port *ap, unsigned int device)
struct ata_device *adev = &ap->link.device[device];
if (ap->private_data != adev) {
iowrite8(0xd6, ap->ioaddr.bmdma_addr + 0x1f);
- ata_std_dev_select(ap, device);
+ ata_sff_dev_select(ap, device);
ninja32_set_piomode(ap, adev);
}
}
static struct scsi_host_template ninja32_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations ninja32_port_ops = {
- .set_piomode = ninja32_set_piomode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ninja32_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_bmdma_port_ops,
+ .sff_dev_select = ninja32_dev_select,
.cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_piomode = ninja32_set_piomode,
};
static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id)
@@ -172,7 +132,7 @@ static int ninja32_init_one(struct pci_dev *dev, const struct pci_device_id *id)
ap->ioaddr.ctl_addr = base + 0x1E;
ap->ioaddr.altstatus_addr = base + 0x1E;
ap->ioaddr.bmdma_addr = base;
- ata_std_ports(&ap->ioaddr);
+ ata_sff_std_ports(&ap->ioaddr);
iowrite8(0x05, base + 0x01); /* Enable interrupt lines */
iowrite8(0xBE, base + 0x02); /* Burst, ?? setup */
@@ -182,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_interrupt,
+ return ata_host_activate(host, dev->irq, ata_sff_interrupt,
IRQF_SHARED, &ninja32_sht);
}
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 9fe66fd75017..76d2455bc453 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -50,21 +50,7 @@ static int ns87410_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &ns87410_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * ns87410_error_handler - probe reset
- * @ap: ATA port
- *
- * Perform the ATA probe and bus reset sequence plus specific handling
- * for this hardware. The MPIIX has the enable bits in a different place
- * to PIIX4 and friends. As a pure PIO device it has no cable detect
- */
-
-static void ns87410_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, ns87410_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -119,7 +105,7 @@ static void ns87410_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
/**
- * ns87410_qc_issue_prot - command issue
+ * ns87410_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
@@ -127,7 +113,7 @@ static void ns87410_set_piomode(struct ata_port *ap, struct ata_device *adev)
* necessary.
*/
-static unsigned int ns87410_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int ns87410_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -140,64 +126,30 @@ static unsigned int ns87410_qc_issue_prot(struct ata_queued_cmd *qc)
if (adev->pio_mode && adev != ap->private_data)
ns87410_set_piomode(ap, adev);
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static struct scsi_host_template ns87410_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations ns87410_port_ops = {
- .set_piomode = ns87410_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ns87410_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
+ .qc_issue = ns87410_qc_issue,
.cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ns87410_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_piomode = ns87410_set_piomode,
+ .prereset = ns87410_pre_reset,
};
static int ns87410_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &ns87410_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x0F,
.port_ops = &ns87410_port_ops
};
const struct ata_port_info *ppi[] = { &info, NULL };
- return ata_pci_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &ns87410_sht, NULL);
}
static const struct pci_device_id ns87410[] = {
diff --git a/drivers/ata/pata_ns87415.c b/drivers/ata/pata_ns87415.c
index d0e2e50823b1..ae92b0049bd5 100644
--- a/drivers/ata/pata_ns87415.c
+++ b/drivers/ata/pata_ns87415.c
@@ -138,7 +138,7 @@ static void ns87415_bmdma_setup(struct ata_queued_cmd *qc)
dmactl |= ATA_DMA_WR;
iowrite8(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
/* issue r/w command */
- ap->ops->exec_command(ap, &qc->tf);
+ ap->ops->sff_exec_command(ap, &qc->tf);
}
/**
@@ -172,14 +172,14 @@ static void ns87415_bmdma_stop(struct ata_queued_cmd *qc)
}
/**
- * ns87415_bmdma_irq_clear - Clear interrupt
+ * ns87415_irq_clear - Clear interrupt
* @ap: Channel to clear
*
* Erratum: Due to a chip bug regisers 02 and 0A bit 1 and 2 (the
* error bits) are reset by writing to register 00 or 08.
*/
-static void ns87415_bmdma_irq_clear(struct ata_port *ap)
+static void ns87415_irq_clear(struct ata_port *ap)
{
void __iomem *mmio = ap->ioaddr.bmdma_addr;
@@ -297,90 +297,32 @@ static u8 ns87560_bmdma_status(struct ata_port *ap)
{
return ns87560_read_buggy(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
}
-
-static const struct ata_port_operations ns87560_pata_ops = {
- .set_piomode = ns87415_set_piomode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ns87560_tf_read,
- .check_status = ns87560_check_status,
- .check_atapi_dma = ns87415_check_atapi_dma,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ns87415_bmdma_setup,
- .bmdma_start = ns87415_bmdma_start,
- .bmdma_stop = ns87415_bmdma_stop,
- .bmdma_status = ns87560_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ns87415_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
-};
-
#endif /* 87560 SuperIO Support */
+static struct ata_port_operations ns87415_pata_ops = {
+ .inherits = &ata_bmdma_port_ops,
-static const struct ata_port_operations ns87415_pata_ops = {
- .set_piomode = ns87415_set_piomode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
.check_atapi_dma = ns87415_check_atapi_dma,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
.bmdma_setup = ns87415_bmdma_setup,
.bmdma_start = ns87415_bmdma_start,
.bmdma_stop = ns87415_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
+ .sff_irq_clear = ns87415_irq_clear,
- .irq_handler = ata_interrupt,
- .irq_clear = ns87415_bmdma_irq_clear,
- .irq_on = ata_irq_on,
+ .cable_detect = ata_cable_40wire,
+ .set_piomode = ns87415_set_piomode,
+};
- .port_start = ata_sff_port_start,
+#if defined(CONFIG_SUPERIO)
+static struct ata_port_operations ns87560_pata_ops = {
+ .inherits = &ns87415_pata_ops,
+ .sff_tf_read = ns87560_tf_read,
+ .sff_check_status = ns87560_check_status,
+ .bmdma_status = ns87560_bmdma_status,
};
+#endif
static struct scsi_host_template ns87415_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
@@ -403,16 +345,15 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e
{
static int printed_version;
static const struct ata_port_info info = {
- .sht = &ns87415_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.port_ops = &ns87415_pata_ops,
};
const struct ata_port_info *ppi[] = { &info, NULL };
+ int rc;
#if defined(CONFIG_SUPERIO)
static const struct ata_port_info info87560 = {
- .sht = &ns87415_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
@@ -425,11 +366,16 @@ static int ns87415_init_one (struct pci_dev *pdev, const struct pci_device_id *e
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
/* Select 512 byte sectors */
pci_write_config_byte(pdev, 0x55, 0xEE);
/* Select PIO0 8bit clocking */
pci_write_config_byte(pdev, 0x54, 0xB7);
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &ns87415_sht, NULL);
}
static const struct pci_device_id ns87415_pci_tbl[] = {
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 44da09ace52c..e678af383d13 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -47,21 +47,7 @@ static int oldpiix_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &oldpiix_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * oldpiix_pata_error_handler - Probe specified port on PATA host controller
- * @ap: Port to probe
- * @classes:
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void oldpiix_pata_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, oldpiix_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -195,7 +181,7 @@ static void oldpiix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
}
/**
- * oldpiix_qc_issue_prot - command issue
+ * oldpiix_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
@@ -205,7 +191,7 @@ static void oldpiix_set_dmamode (struct ata_port *ap, struct ata_device *adev)
* be made PIO0.
*/
-static unsigned int oldpiix_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int oldpiix_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -215,58 +201,21 @@ static unsigned int oldpiix_qc_issue_prot(struct ata_queued_cmd *qc)
if (adev->dma_mode)
oldpiix_set_dmamode(ap, adev);
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static struct scsi_host_template oldpiix_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations oldpiix_pata_ops = {
+static struct ata_port_operations oldpiix_pata_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .qc_issue = oldpiix_qc_issue,
+ .cable_detect = ata_cable_40wire,
.set_piomode = oldpiix_set_piomode,
.set_dmamode = oldpiix_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = oldpiix_pata_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = oldpiix_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .prereset = oldpiix_pre_reset,
};
@@ -289,7 +238,6 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
{
static int printed_version;
static const struct ata_port_info info = {
- .sht = &oldpiix_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma1-2 */
@@ -301,7 +249,7 @@ static int oldpiix_init_one (struct pci_dev *pdev, const struct pci_device_id *e
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &oldpiix_sht, NULL);
}
static const struct pci_device_id oldpiix_pci_tbl[] = {
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index 8f79447b6151..fb2cf661b0e8 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -64,22 +64,7 @@ static int opti_pre_reset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &opti_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * opti_probe_reset - probe reset
- * @ap: ATA port
- *
- * Perform the ATA probe and bus reset sequence plus specific handling
- * for this hardware. The Opti needs little handling - we have no UDMA66
- * capability that needs cable detection. All we must do is check the port
- * is enabled.
- */
-
-static void opti_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, opti_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -165,58 +150,19 @@ static void opti_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template opti_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations opti_port_ops = {
- .set_piomode = opti_set_piomode,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = opti_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
.cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_piomode = opti_set_piomode,
+ .prereset = opti_pre_reset,
};
static int opti_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &opti_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &opti_port_ops
@@ -227,7 +173,7 @@ static int opti_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_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &opti_sht, NULL);
}
static const struct pci_device_id opti[] = {
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index f9b485a487ae..4cd744456313 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -64,22 +64,7 @@ static int optidma_pre_reset(struct ata_link *link, unsigned long deadline)
if (ap->port_no && !pci_test_config_bits(pdev, &optidma_enable_bits))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * optidma_probe_reset - probe reset
- * @ap: ATA port
- *
- * Perform the ATA probe and bus reset sequence plus specific handling
- * for this hardware. The Opti needs little handling - we have no UDMA66
- * capability that needs cable detection. All we must do is check the port
- * is enabled.
- */
-
-static void optidma_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, optidma_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -350,89 +335,22 @@ static int optidma_set_mode(struct ata_link *link, struct ata_device **r_failed)
}
static struct scsi_host_template optidma_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations optidma_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = ata_cable_40wire,
.set_piomode = optidma_set_pio_mode,
.set_dmamode = optidma_set_dma_mode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .error_handler = optidma_error_handler,
.set_mode = optidma_set_mode,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .prereset = optidma_pre_reset,
};
static struct ata_port_operations optiplus_port_ops = {
+ .inherits = &optidma_port_ops,
.set_piomode = optiplus_set_pio_mode,
.set_dmamode = optiplus_set_dma_mode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .error_handler = optidma_error_handler,
- .set_mode = optidma_set_mode,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/**
@@ -481,14 +399,12 @@ done_nomsg: /* Wrong chip revision */
static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info_82c700 = {
- .sht = &optidma_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &optidma_port_ops
};
static const struct ata_port_info info_82c700_udma = {
- .sht = &optidma_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -497,10 +413,15 @@ static int optidma_init_one(struct pci_dev *dev, const struct pci_device_id *id)
};
const struct ata_port_info *ppi[] = { &info_82c700, NULL };
static int printed_version;
+ int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &dev->dev, "version " DRV_VERSION "\n");
+ rc = pcim_enable_device(dev);
+ if (rc)
+ return rc;
+
/* Fixed location chipset magic */
inw(0x1F1);
inw(0x1F1);
@@ -509,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_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &optidma_sht, NULL);
}
static const struct pci_device_id optidma[] = {
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 3e7f6a9da28b..3d39f9dfec5a 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -128,71 +128,21 @@ static unsigned int ata_data_xfer_8bit(struct ata_device *dev,
static struct scsi_host_template pcmcia_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations pcmcia_port_ops = {
- .set_mode = pcmcia_set_mode,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
+ .sff_data_xfer = ata_sff_data_xfer_noirq,
.cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer_noirq,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_mode = pcmcia_set_mode,
};
static struct ata_port_operations pcmcia_8bit_port_ops = {
- .set_mode = pcmcia_set_mode_8bit,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
+ .sff_data_xfer = ata_data_xfer_8bit,
.cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer_8bit,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_mode = pcmcia_set_mode_8bit,
};
#define CS_CHECK(fn, ret) \
@@ -373,13 +323,13 @@ next_entry:
ap->ioaddr.cmd_addr = io_addr + 0x10 * p;
ap->ioaddr.altstatus_addr = ctl_addr + 0x10 * p;
ap->ioaddr.ctl_addr = ctl_addr + 0x10 * p;
- ata_std_ports(&ap->ioaddr);
+ ata_sff_std_ports(&ap->ioaddr);
ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx", io_base, ctl_base);
}
/* activate */
- ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_interrupt,
+ ret = ata_host_activate(host, pdev->irq.AssignedIRQ, ata_sff_interrupt,
IRQF_SHARED, &pcmcia_sht);
if (ret)
goto failed;
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index 511c89b9bae8..0e1c2c1134d3 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -63,7 +63,7 @@ enum {
};
static int pdc2027x_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
-static void pdc2027x_error_handler(struct ata_port *ap);
+static int pdc2027x_prereset(struct ata_link *link, unsigned long deadline);
static void pdc2027x_set_piomode(struct ata_port *ap, struct ata_device *adev);
static void pdc2027x_set_dmamode(struct ata_port *ap, struct ata_device *adev);
static int pdc2027x_check_atapi_dma(struct ata_queued_cmd *qc);
@@ -129,84 +129,22 @@ static struct pci_driver pdc2027x_pci_driver = {
};
static struct scsi_host_template pdc2027x_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations pdc2027x_pata100_ops = {
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
+ .inherits = &ata_bmdma_port_ops,
.check_atapi_dma = pdc2027x_check_atapi_dma,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = pdc2027x_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = pdc2027x_cable_detect,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .prereset = pdc2027x_prereset,
};
static struct ata_port_operations pdc2027x_pata133_ops = {
+ .inherits = &pdc2027x_pata100_ops,
+ .mode_filter = pdc2027x_mode_filter,
.set_piomode = pdc2027x_set_piomode,
.set_dmamode = pdc2027x_set_dmamode,
.set_mode = pdc2027x_set_mode,
- .mode_filter = pdc2027x_mode_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .check_atapi_dma = pdc2027x_check_atapi_dma,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = pdc2027x_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = pdc2027x_cable_detect,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
static struct ata_port_info pdc2027x_port_info[] = {
@@ -310,22 +248,7 @@ static int pdc2027x_prereset(struct ata_link *link, unsigned long deadline)
/* Check whether port enabled */
if (!pdc2027x_port_enabled(link->ap))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-/**
- * pdc2027x_error_handler - Perform reset on PATA port and classify
- * @ap: Port to reset
- *
- * Reset PATA phy and classify attached devices.
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void pdc2027x_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, pdc2027x_prereset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
/**
@@ -342,7 +265,7 @@ static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long
struct ata_device *pair = ata_dev_pair(adev);
if (adev->class != ATA_DEV_ATA || adev->devno == 0 || pair == NULL)
- return ata_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, mask);
/* Check for slave of a Maxtor at UDMA6 */
ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
@@ -351,7 +274,7 @@ static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long
if (strstr(model_num, "Maxtor") == NULL && pair->dma_mode == XFER_UDMA_6)
mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
- return ata_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, mask);
}
/**
@@ -836,8 +759,8 @@ static int __devinit pdc2027x_init_one(struct pci_dev *pdev, const struct pci_de
return -EIO;
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
- &pdc2027x_sht);
+ return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ IRQF_SHARED, &pdc2027x_sht);
}
/**
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index 3ed866723e0c..d2673060bc8d 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -262,94 +262,34 @@ static int pdc2026x_check_atapi_dma(struct ata_queued_cmd *qc)
}
static struct scsi_host_template pdc202xx_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations pdc2024x_port_ops = {
- .set_piomode = pdc202xx_set_piomode,
- .set_dmamode = pdc202xx_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .inherits = &ata_bmdma_port_ops,
+
+ .cable_detect = ata_cable_40wire,
+ .set_piomode = pdc202xx_set_piomode,
+ .set_dmamode = pdc202xx_set_dmamode,
};
static struct ata_port_operations pdc2026x_port_ops = {
- .set_piomode = pdc202xx_set_piomode,
- .set_dmamode = pdc202xx_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
- .dev_config = pdc2026x_dev_config,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = pdc2026x_cable_detect,
-
- .check_atapi_dma= pdc2026x_check_atapi_dma,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = pdc2026x_bmdma_start,
- .bmdma_stop = pdc2026x_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = pdc2026x_port_start,
+ .inherits = &pdc2024x_port_ops,
+
+ .check_atapi_dma = pdc2026x_check_atapi_dma,
+ .bmdma_start = pdc2026x_bmdma_start,
+ .bmdma_stop = pdc2026x_bmdma_stop,
+
+ .cable_detect = pdc2026x_cable_detect,
+ .dev_config = pdc2026x_dev_config,
+
+ .port_start = pdc2026x_port_start,
};
static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info[3] = {
{
- .sht = &pdc202xx_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -357,7 +297,6 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
.port_ops = &pdc2024x_port_ops
},
{
- .sht = &pdc202xx_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -365,7 +304,6 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
.port_ops = &pdc2026x_port_ops
},
{
- .sht = &pdc202xx_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -386,7 +324,7 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
return -ENODEV;
}
}
- return ata_pci_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &pdc202xx_sht, NULL);
}
static const struct pci_device_id pdc202xx[] = {
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
index aad7adc6ea56..6527c56c34a3 100644
--- a/drivers/ata/pata_platform.c
+++ b/drivers/ata/pata_platform.c
@@ -46,50 +46,16 @@ static int pata_platform_set_mode(struct ata_link *link, struct ata_device **unu
return 0;
}
-static int ata_dummy_ret0(struct ata_port *ap) { return 0; }
-
static struct scsi_host_template pata_platform_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations pata_platform_port_ops = {
- .set_mode = pata_platform_set_mode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
+ .sff_data_xfer = ata_sff_data_xfer_noirq,
.cable_detect = ata_cable_unknown,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer_noirq,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_dummy_ret0,
+ .set_mode = pata_platform_set_mode,
+ .port_start = ATA_OP_NULL,
};
static void pata_platform_setup_port(struct ata_ioports *ioaddr,
@@ -210,7 +176,7 @@ int __devinit __pata_platform_probe(struct device *dev,
(unsigned long long)ctl_res->start);
/* activate */
- return ata_host_activate(host, irq, irq ? ata_interrupt : NULL,
+ return ata_host_activate(host, irq, irq ? ata_sff_interrupt : NULL,
irq_flags, &pata_platform_sht);
}
EXPORT_SYMBOL_GPL(__pata_platform_probe);
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 9f308ed76cc8..bf45cf017753 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -102,14 +102,14 @@ static void qdi6580_set_piomode(struct ata_port *ap, struct ata_device *adev)
}
/**
- * qdi_qc_issue_prot - command issue
+ * qdi_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
* this interface so that we can load the correct ATA timings.
*/
-static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int qdi_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -121,7 +121,7 @@ static unsigned int qdi_qc_issue_prot(struct ata_queued_cmd *qc)
outb(qdi->clock[adev->devno], qdi->timing);
}
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static unsigned int qdi_data_xfer(struct ata_device *dev, unsigned char *buf,
@@ -148,79 +148,26 @@ static unsigned int qdi_data_xfer(struct ata_device *dev, unsigned char *buf,
buflen += 4 - slop;
}
} else
- buflen = ata_data_xfer(dev, buf, buflen, rw);
+ buflen = ata_sff_data_xfer(dev, buf, buflen, rw);
return buflen;
}
static struct scsi_host_template qdi_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations qdi6500_port_ops = {
- .set_piomode = qdi6500_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
+ .qc_issue = qdi_qc_issue,
+ .sff_data_xfer = qdi_data_xfer,
.cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = qdi_qc_issue_prot,
-
- .data_xfer = qdi_data_xfer,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_piomode = qdi6500_set_piomode,
};
static struct ata_port_operations qdi6580_port_ops = {
+ .inherits = &qdi6500_port_ops,
.set_piomode = qdi6580_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = qdi_qc_issue_prot,
-
- .data_xfer = qdi_data_xfer,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/**
@@ -276,7 +223,7 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
ap->ioaddr.cmd_addr = io_addr;
ap->ioaddr.altstatus_addr = ctl_addr;
ap->ioaddr.ctl_addr = ctl_addr;
- ata_std_ports(&ap->ioaddr);
+ ata_sff_std_ports(&ap->ioaddr);
ata_port_desc(ap, "cmd %lx ctl %lx", io, ctl);
@@ -292,7 +239,7 @@ static __init int qdi_init_one(unsigned long port, int type, unsigned long io, i
printk(KERN_INFO DRV_NAME": qd%d at 0x%lx.\n", type, io);
/* activate */
- ret = ata_host_activate(host, irq, ata_interrupt, 0, &qdi_sht);
+ ret = ata_host_activate(host, irq, ata_sff_interrupt, 0, &qdi_sht);
if (ret)
goto fail;
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 8109b08fc024..1c0d9fa7ee54 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -156,7 +156,7 @@ static void radisys_set_dmamode (struct ata_port *ap, struct ata_device *adev)
}
/**
- * radisys_qc_issue_prot - command issue
+ * radisys_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
@@ -166,7 +166,7 @@ static void radisys_set_dmamode (struct ata_port *ap, struct ata_device *adev)
* be made PIO0.
*/
-static unsigned int radisys_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int radisys_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -180,58 +180,20 @@ static unsigned int radisys_qc_issue_prot(struct ata_queued_cmd *qc)
radisys_set_piomode(ap, adev);
}
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static struct scsi_host_template radisys_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations radisys_pata_ops = {
+static struct ata_port_operations radisys_pata_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .qc_issue = radisys_qc_issue,
+ .cable_detect = ata_cable_unknown,
.set_piomode = radisys_set_piomode,
.set_dmamode = radisys_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_unknown,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = radisys_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
@@ -254,7 +216,6 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
{
static int printed_version;
static const struct ata_port_info info = {
- .sht = &radisys_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma1-2 */
@@ -267,7 +228,7 @@ static int radisys_init_one (struct pci_dev *pdev, const struct pci_device_id *e
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &radisys_sht, NULL);
}
static const struct pci_device_id radisys_pci_tbl[] = {
diff --git a/drivers/ata/pata_rb500_cf.c b/drivers/ata/pata_rb500_cf.c
index 4ce9b03fe6c8..800ae4601f44 100644
--- a/drivers/ata/pata_rb500_cf.c
+++ b/drivers/ata/pata_rb500_cf.c
@@ -57,7 +57,7 @@ static inline void rb500_pata_finish_io(struct ata_port *ap)
struct ata_host *ah = ap->host;
struct rb500_cf_info *info = ah->private_data;
- ata_altstatus(ap);
+ ata_sff_altstatus(ap);
ndelay(RB500_CF_IO_DELAY);
set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
@@ -109,7 +109,7 @@ static irqreturn_t rb500_pata_irq_handler(int irq, void *dev_instance)
if (gpio_get_value(info->gpio_line)) {
set_irq_type(info->irq, IRQ_TYPE_LEVEL_LOW);
if (!info->frozen)
- ata_interrupt(info->irq, dev_instance);
+ ata_sff_interrupt(info->irq, dev_instance);
} else {
set_irq_type(info->irq, IRQ_TYPE_LEVEL_HIGH);
}
@@ -117,58 +117,18 @@ static irqreturn_t rb500_pata_irq_handler(int irq, void *dev_instance)
return IRQ_HANDLED;
}
-static void rb500_pata_irq_clear(struct ata_port *ap)
-{
-}
-
-static int rb500_pata_port_start(struct ata_port *ap)
-{
- return 0;
-}
-
static struct ata_port_operations rb500_pata_port_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
-
- .exec_command = rb500_pata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
-
- .data_xfer = rb500_pata_data_xfer,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
+ .inherits = &ata_sff_port_ops,
+ .sff_exec_command = rb500_pata_exec_command,
+ .sff_data_xfer = rb500_pata_data_xfer,
.freeze = rb500_pata_freeze,
.thaw = rb500_pata_thaw,
- .error_handler = ata_bmdma_error_handler,
-
- .irq_handler = rb500_pata_irq_handler,
- .irq_clear = rb500_pata_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = rb500_pata_port_start,
};
/* ------------------------------------------------------------------------ */
static struct scsi_host_template rb500_pata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
- .proc_name = DRV_NAME,
-
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
+ ATA_PIO_SHT(DRV_NAME),
};
/* ------------------------------------------------------------------------ */
@@ -188,7 +148,7 @@ static void rb500_pata_setup_ports(struct ata_host *ah)
ap->ioaddr.ctl_addr = info->iobase + RB500_CF_REG_CTRL;
ap->ioaddr.altstatus_addr = info->iobase + RB500_CF_REG_CTRL;
- ata_std_ports(&ap->ioaddr);
+ ata_sff_std_ports(&ap->ioaddr);
ap->ioaddr.data_addr = info->iobase + RB500_CF_REG_DATA;
}
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index ba8a31c55edb..7dfd1f3f6f3a 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -53,53 +53,13 @@ static int rz1000_set_mode(struct ata_link *link, struct ata_device **unused)
static struct scsi_host_template rz1000_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations rz1000_port_ops = {
- .set_mode = rz1000_set_mode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
.cable_detect = ata_cable_40wire,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_mode = rz1000_set_mode,
};
static int rz1000_fifo_disable(struct pci_dev *pdev)
@@ -129,7 +89,6 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
{
static int printed_version;
static const struct ata_port_info info = {
- .sht = &rz1000_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &rz1000_port_ops
@@ -140,7 +99,7 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
if (rz1000_fifo_disable(pdev) == 0)
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &rz1000_sht, NULL);
printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n");
/* Not safe to use so skip */
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 725a8586cd6e..cbab397e3db7 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -151,7 +151,7 @@ static void sc1200_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
/**
- * sc1200_qc_issue_prot - command issue
+ * sc1200_qc_issue - command issue
* @qc: command pending
*
* Called when the libata layer is about to issue a command. We wrap
@@ -160,7 +160,7 @@ static void sc1200_set_dmamode(struct ata_port *ap, struct ata_device *adev)
* one MWDMA/UDMA bit.
*/
-static unsigned int sc1200_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int sc1200_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct ata_device *adev = qc->dev;
@@ -175,59 +175,21 @@ static unsigned int sc1200_qc_issue_prot(struct ata_queued_cmd *qc)
sc1200_set_dmamode(ap, adev);
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static struct scsi_host_template sc1200_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_DUMB_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
+ .sg_tablesize = LIBATA_DUMB_MAX_PRD,
};
static struct ata_port_operations sc1200_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .qc_prep = ata_sff_dumb_qc_prep,
+ .qc_issue = sc1200_qc_issue,
+ .cable_detect = ata_cable_40wire,
.set_piomode = sc1200_set_piomode,
.set_dmamode = sc1200_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_dumb_qc_prep,
- .qc_issue = sc1200_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/**
@@ -242,7 +204,6 @@ static struct ata_port_operations sc1200_port_ops = {
static int sc1200_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &sc1200_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -252,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_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &sc1200_sht, NULL);
}
static const struct pci_device_id sc1200[] = {
diff --git a/drivers/ata/pata_scc.c b/drivers/ata/pata_scc.c
index 6c016deeaed8..e965b251ca24 100644
--- a/drivers/ata/pata_scc.c
+++ b/drivers/ata/pata_scc.c
@@ -266,7 +266,7 @@ unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask)
printk(KERN_INFO "%s: limit ATAPI UDMA to UDMA4\n", DRV_NAME);
mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
- return ata_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, mask);
}
/**
@@ -274,7 +274,7 @@ unsigned long scc_mode_filter(struct ata_device *adev, unsigned long mask)
* @ap: Port to which output is sent
* @tf: ATA taskfile register set
*
- * Note: Original code is ata_tf_load().
+ * Note: Original code is ata_sff_tf_load().
*/
static void scc_tf_load (struct ata_port *ap, const struct ata_taskfile *tf)
@@ -341,7 +341,7 @@ static u8 scc_check_status (struct ata_port *ap)
* @ap: Port from which input is read
* @tf: ATA taskfile register set for storing input
*
- * Note: Original code is ata_tf_read().
+ * Note: Original code is ata_sff_tf_read().
*/
static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf)
@@ -373,7 +373,7 @@ static void scc_tf_read (struct ata_port *ap, struct ata_taskfile *tf)
* @ap: port to which command is being issued
* @tf: ATA taskfile register set
*
- * Note: Original code is ata_exec_command().
+ * Note: Original code is ata_sff_exec_command().
*/
static void scc_exec_command (struct ata_port *ap,
@@ -382,7 +382,7 @@ static void scc_exec_command (struct ata_port *ap,
DPRINTK("ata%u: cmd 0x%X\n", ap->print_id, tf->command);
out_be32(ap->ioaddr.command_addr, tf->command);
- ata_pause(ap);
+ ata_sff_pause(ap);
}
/**
@@ -396,14 +396,14 @@ static u8 scc_check_altstatus (struct ata_port *ap)
}
/**
- * scc_std_dev_select - Select device 0/1 on ATA bus
+ * scc_dev_select - Select device 0/1 on ATA bus
* @ap: ATA channel to manipulate
* @device: ATA device (numbered from zero) to select
*
- * Note: Original code is ata_std_dev_select().
+ * Note: Original code is ata_sff_dev_select().
*/
-static void scc_std_dev_select (struct ata_port *ap, unsigned int device)
+static void scc_dev_select (struct ata_port *ap, unsigned int device)
{
u8 tmp;
@@ -413,7 +413,7 @@ static void scc_std_dev_select (struct ata_port *ap, unsigned int device)
tmp = ATA_DEVICE_OBS | ATA_DEV1;
out_be32(ap->ioaddr.device_addr, tmp);
- ata_pause(ap);
+ ata_sff_pause(ap);
}
/**
@@ -441,7 +441,7 @@ static void scc_bmdma_setup (struct ata_queued_cmd *qc)
out_be32(mmio + SCC_DMA_CMD, dmactl);
/* issue r/w command */
- ap->ops->exec_command(ap, &qc->tf);
+ ap->ops->sff_exec_command(ap, &qc->tf);
}
/**
@@ -476,7 +476,7 @@ static unsigned int scc_devchk (struct ata_port *ap,
struct ata_ioports *ioaddr = &ap->ioaddr;
u8 nsect, lbal;
- ap->ops->dev_select(ap, device);
+ ap->ops->sff_dev_select(ap, device);
out_be32(ioaddr->nsect_addr, 0x55);
out_be32(ioaddr->lbal_addr, 0xaa);
@@ -497,57 +497,78 @@ static unsigned int scc_devchk (struct ata_port *ap,
}
/**
- * scc_bus_post_reset - PATA device post reset
+ * scc_wait_after_reset - wait for devices to become ready after reset
*
- * Note: Original code is ata_bus_post_reset().
+ * Note: Original code is ata_sff_wait_after_reset
*/
-static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask,
- unsigned long deadline)
+int scc_wait_after_reset(struct ata_link *link, unsigned int devmask,
+ unsigned long deadline)
{
+ struct ata_port *ap = link->ap;
struct ata_ioports *ioaddr = &ap->ioaddr;
unsigned int dev0 = devmask & (1 << 0);
unsigned int dev1 = devmask & (1 << 1);
- int rc;
-
- /* if device 0 was found in ata_devchk, wait for its
- * BSY bit to clear
+ int rc, ret = 0;
+
+ /* Spec mandates ">= 2ms" before checking status. We wait
+ * 150ms, because that was the magic delay used for ATAPI
+ * devices in Hale Landis's ATADRVR, for the period of time
+ * between when the ATA command register is written, and then
+ * status is checked. Because waiting for "a while" before
+ * checking status is fine, post SRST, we perform this magic
+ * delay here as well.
+ *
+ * Old drivers/ide uses the 2mS rule and then waits for ready.
*/
- if (dev0) {
- rc = ata_wait_ready(ap, deadline);
- if (rc && rc != -ENODEV)
- return rc;
- }
+ msleep(150);
- /* if device 1 was found in ata_devchk, wait for
- * register access, then wait for BSY to clear
+ /* always check readiness of the master device */
+ rc = ata_sff_wait_ready(link, deadline);
+ /* -ENODEV means the odd clown forgot the D7 pulldown resistor
+ * and TF status is 0xff, bail out on it too.
*/
- while (dev1) {
- u8 nsect, lbal;
+ if (rc)
+ return rc;
- ap->ops->dev_select(ap, 1);
- nsect = in_be32(ioaddr->nsect_addr);
- lbal = in_be32(ioaddr->lbal_addr);
- if ((nsect == 1) && (lbal == 1))
- break;
- if (time_after(jiffies, deadline))
- return -EBUSY;
- msleep(50); /* give drive a breather */
- }
+ /* if device 1 was found in ata_devchk, wait for register
+ * access briefly, then wait for BSY to clear.
+ */
if (dev1) {
- rc = ata_wait_ready(ap, deadline);
- if (rc && rc != -ENODEV)
- return rc;
+ int i;
+
+ ap->ops->sff_dev_select(ap, 1);
+
+ /* Wait for register access. Some ATAPI devices fail
+ * to set nsect/lbal after reset, so don't waste too
+ * much time on it. We're gonna wait for !BSY anyway.
+ */
+ for (i = 0; i < 2; i++) {
+ u8 nsect, lbal;
+
+ nsect = in_be32(ioaddr->nsect_addr);
+ lbal = in_be32(ioaddr->lbal_addr);
+ if ((nsect == 1) && (lbal == 1))
+ break;
+ msleep(50); /* give drive a breather */
+ }
+
+ rc = ata_sff_wait_ready(link, deadline);
+ if (rc) {
+ if (rc != -ENODEV)
+ return rc;
+ ret = rc;
+ }
}
/* is all this really necessary? */
- ap->ops->dev_select(ap, 0);
+ ap->ops->sff_dev_select(ap, 0);
if (dev1)
- ap->ops->dev_select(ap, 1);
+ ap->ops->sff_dev_select(ap, 1);
if (dev0)
- ap->ops->dev_select(ap, 0);
+ ap->ops->sff_dev_select(ap, 0);
- return 0;
+ return ret;
}
/**
@@ -570,32 +591,22 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
udelay(20);
out_be32(ioaddr->ctl_addr, ap->ctl);
- /* wait a while before checking status */
- ata_wait_after_reset(ap, deadline);
-
- /* Before we perform post reset processing we want to see if
- * the bus shows 0xFF because the odd clown forgets the D7
- * pulldown resistor.
- */
- if (scc_check_status(ap) == 0xFF)
- return 0;
-
- scc_bus_post_reset(ap, devmask, deadline);
+ scc_wait_after_reset(&ap->link, devmask, deadline);
return 0;
}
/**
- * scc_std_softreset - reset host port via ATA SRST
+ * scc_softreset - reset host port via ATA SRST
* @ap: port to reset
* @classes: resulting classes of attached devices
* @deadline: deadline jiffies for the operation
*
- * Note: Original code is ata_std_softreset().
+ * Note: Original code is ata_sff_softreset().
*/
-static int scc_std_softreset(struct ata_link *link, unsigned int *classes,
- unsigned long deadline)
+static int scc_softreset(struct ata_link *link, unsigned int *classes,
+ unsigned long deadline)
{
struct ata_port *ap = link->ap;
unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
@@ -604,11 +615,6 @@ static int scc_std_softreset(struct ata_link *link, unsigned int *classes,
DPRINTK("ENTER\n");
- if (ata_link_offline(link)) {
- classes[0] = ATA_DEV_NONE;
- goto out;
- }
-
/* determine if device 0/1 are present */
if (scc_devchk(ap, 0))
devmask |= (1 << 0);
@@ -616,7 +622,7 @@ static int scc_std_softreset(struct ata_link *link, unsigned int *classes,
devmask |= (1 << 1);
/* select device 0 again */
- ap->ops->dev_select(ap, 0);
+ ap->ops->sff_dev_select(ap, 0);
/* issue bus reset */
DPRINTK("about to softreset, devmask=%x\n", devmask);
@@ -628,13 +634,12 @@ static int scc_std_softreset(struct ata_link *link, unsigned int *classes,
}
/* determine by signature whether we have ATA or ATAPI devices */
- classes[0] = ata_dev_try_classify(&ap->link.device[0],
+ classes[0] = ata_sff_dev_classify(&ap->link.device[0],
devmask & (1 << 0), &err);
if (slave_possible && err != 0x81)
- classes[1] = ata_dev_try_classify(&ap->link.device[1],
+ classes[1] = ata_sff_dev_classify(&ap->link.device[1],
devmask & (1 << 1), &err);
- out:
DPRINTK("EXIT, classes[0]=%u [1]=%u\n", classes[0], classes[1]);
return 0;
}
@@ -695,7 +700,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc)
printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
/* TBD: SW reset */
- scc_std_softreset(&ap->link, &classes, deadline);
+ scc_softreset(&ap->link, &classes, deadline);
continue;
}
@@ -721,7 +726,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc)
in_be32(bmid_base + SCC_DMA_CMD) & ~ATA_DMA_START);
/* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
- ata_altstatus(ap); /* dummy read */
+ ata_sff_altstatus(ap); /* dummy read */
}
/**
@@ -742,7 +747,7 @@ static u8 scc_bmdma_status (struct ata_port *ap)
return host_stat;
/* errata A252,A308 workaround: Step4 */
- if ((ata_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ))
+ if ((ata_sff_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ))
return (host_stat | ATA_DMA_INTR);
/* errata A308 workaround Step5 */
@@ -773,7 +778,7 @@ static u8 scc_bmdma_status (struct ata_port *ap)
* @buflen: buffer length
* @rw: read/write
*
- * Note: Original code is ata_data_xfer().
+ * Note: Original code is ata_sff_data_xfer().
*/
static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf,
@@ -782,28 +787,28 @@ static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf,
struct ata_port *ap = dev->link->ap;
unsigned int words = buflen >> 1;
unsigned int i;
- u16 *buf16 = (u16 *) buf;
+ __le16 *buf16 = (__le16 *) buf;
void __iomem *mmio = ap->ioaddr.data_addr;
/* Transfer multiple of 2 bytes */
if (rw == READ)
for (i = 0; i < words; i++)
- buf16[i] = le16_to_cpu(in_be32(mmio));
+ buf16[i] = cpu_to_le16(in_be32(mmio));
else
for (i = 0; i < words; i++)
- out_be32(mmio, cpu_to_le16(buf16[i]));
+ out_be32(mmio, le16_to_cpu(buf16[i]));
/* Transfer trailing 1 byte, if any. */
if (unlikely(buflen & 0x01)) {
- u16 align_buf[1] = { 0 };
+ __le16 align_buf[1] = { 0 };
unsigned char *trailing_buf = buf + buflen - 1;
if (rw == READ) {
- align_buf[0] = le16_to_cpu(in_be32(mmio));
+ align_buf[0] = cpu_to_le16(in_be32(mmio));
memcpy(trailing_buf, align_buf, 1);
} else {
memcpy(align_buf, trailing_buf, 1);
- out_be32(mmio, cpu_to_le16(align_buf[0]));
+ out_be32(mmio, le16_to_cpu(align_buf[0]));
}
words++;
}
@@ -815,7 +820,7 @@ static unsigned int scc_data_xfer (struct ata_device *dev, unsigned char *buf,
* scc_irq_on - Enable interrupts on a port.
* @ap: Port on which interrupts are enabled.
*
- * Note: Original code is ata_irq_on().
+ * Note: Original code is ata_sff_irq_on().
*/
static u8 scc_irq_on (struct ata_port *ap)
@@ -829,19 +834,19 @@ static u8 scc_irq_on (struct ata_port *ap)
out_be32(ioaddr->ctl_addr, ap->ctl);
tmp = ata_wait_idle(ap);
- ap->ops->irq_clear(ap);
+ ap->ops->sff_irq_clear(ap);
return tmp;
}
/**
- * scc_bmdma_freeze - Freeze BMDMA controller port
+ * scc_freeze - Freeze BMDMA controller port
* @ap: port to freeze
*
- * Note: Original code is ata_bmdma_freeze().
+ * Note: Original code is ata_sff_freeze().
*/
-static void scc_bmdma_freeze (struct ata_port *ap)
+static void scc_freeze (struct ata_port *ap)
{
struct ata_ioports *ioaddr = &ap->ioaddr;
@@ -854,9 +859,9 @@ static void scc_bmdma_freeze (struct ata_port *ap)
* ATA_NIEN manipulation. Also, many controllers fail to mask
* previously pending IRQ on ATA_NIEN assertion. Clear it.
*/
- ata_chk_status(ap);
+ ap->ops->sff_check_status(ap);
- ap->ops->irq_clear(ap);
+ ap->ops->sff_irq_clear(ap);
}
/**
@@ -868,18 +873,18 @@ static void scc_bmdma_freeze (struct ata_port *ap)
static int scc_pata_prereset(struct ata_link *link, unsigned long deadline)
{
link->ap->cbl = ATA_CBL_PATA80;
- return ata_std_prereset(link, deadline);
+ return ata_sff_prereset(link, deadline);
}
/**
- * scc_std_postreset - standard postreset callback
+ * scc_postreset - standard postreset callback
* @ap: the target ata_port
* @classes: classes of attached devices
*
- * Note: Original code is ata_std_postreset().
+ * Note: Original code is ata_sff_postreset().
*/
-static void scc_std_postreset(struct ata_link *link, unsigned int *classes)
+static void scc_postreset(struct ata_link *link, unsigned int *classes)
{
struct ata_port *ap = link->ap;
@@ -887,9 +892,9 @@ static void scc_std_postreset(struct ata_link *link, unsigned int *classes)
/* is double-select really necessary? */
if (classes[0] != ATA_DEV_NONE)
- ap->ops->dev_select(ap, 1);
+ ap->ops->sff_dev_select(ap, 1);
if (classes[1] != ATA_DEV_NONE)
- ap->ops->dev_select(ap, 0);
+ ap->ops->sff_dev_select(ap, 0);
/* bail out if no device is present */
if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
@@ -905,24 +910,13 @@ static void scc_std_postreset(struct ata_link *link, unsigned int *classes)
}
/**
- * scc_error_handler - Stock error handler for BMDMA controller
- * @ap: port to handle error for
- */
-
-static void scc_error_handler (struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, scc_pata_prereset, scc_std_softreset, NULL,
- scc_std_postreset);
-}
-
-/**
- * scc_bmdma_irq_clear - Clear PCI IDE BMDMA interrupt.
+ * scc_irq_clear - Clear PCI IDE BMDMA interrupt.
* @ap: Port associated with this ATA transaction.
*
- * Note: Original code is ata_bmdma_irq_clear().
+ * Note: Original code is ata_sff_irq_clear().
*/
-static void scc_bmdma_irq_clear (struct ata_port *ap)
+static void scc_irq_clear (struct ata_port *ap)
{
void __iomem *mmio = ap->ioaddr.bmdma_addr;
@@ -968,52 +962,37 @@ static void scc_port_stop (struct ata_port *ap)
}
static struct scsi_host_template scc_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations scc_pata_ops = {
+static struct ata_port_operations scc_pata_ops = {
+ .inherits = &ata_bmdma_port_ops,
+
.set_piomode = scc_set_piomode,
.set_dmamode = scc_set_dmamode,
.mode_filter = scc_mode_filter,
- .tf_load = scc_tf_load,
- .tf_read = scc_tf_read,
- .exec_command = scc_exec_command,
- .check_status = scc_check_status,
- .check_altstatus = scc_check_altstatus,
- .dev_select = scc_std_dev_select,
+ .sff_tf_load = scc_tf_load,
+ .sff_tf_read = scc_tf_read,
+ .sff_exec_command = scc_exec_command,
+ .sff_check_status = scc_check_status,
+ .sff_check_altstatus = scc_check_altstatus,
+ .sff_dev_select = scc_dev_select,
.bmdma_setup = scc_bmdma_setup,
.bmdma_start = scc_bmdma_start,
.bmdma_stop = scc_bmdma_stop,
.bmdma_status = scc_bmdma_status,
- .data_xfer = scc_data_xfer,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .freeze = scc_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
+ .sff_data_xfer = scc_data_xfer,
- .error_handler = scc_error_handler,
+ .freeze = scc_freeze,
+ .prereset = scc_pata_prereset,
+ .softreset = scc_softreset,
+ .postreset = scc_postreset,
.post_internal_cmd = scc_bmdma_stop,
- .irq_clear = scc_bmdma_irq_clear,
- .irq_on = scc_irq_on,
+ .sff_irq_clear = scc_irq_clear,
+ .sff_irq_on = scc_irq_on,
.port_start = scc_port_start,
.port_stop = scc_port_stop,
@@ -1166,8 +1145,8 @@ 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_interrupt, IRQF_SHARED,
- &scc_sht);
+ return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ IRQF_SHARED, &scc_sht);
}
static struct pci_driver scc_pci_driver = {
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index a589c0fa0dbb..ffd26d0dc50d 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -199,7 +199,7 @@ static unsigned long serverworks_osb4_filter(struct ata_device *adev, unsigned l
{
if (adev->class == ATA_DEV_ATA)
mask &= ~ATA_MASK_UDMA;
- return ata_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, 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_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, mask);
/* Actually do need to check */
ata_id_c_string(adev->id, model_num, ATA_ID_PROD, sizeof(model_num));
@@ -228,7 +228,7 @@ static unsigned long serverworks_csb_filter(struct ata_device *adev, unsigned lo
if (!strcmp(p, model_num))
mask &= ~(0xE0 << ATA_SHIFT_UDMA);
}
- return ata_pci_default_filter(adev, mask);
+ return ata_bmdma_mode_filter(adev, mask);
}
/**
@@ -298,89 +298,20 @@ static void serverworks_set_dmamode(struct ata_port *ap, struct ata_device *adev
}
static struct scsi_host_template serverworks_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations serverworks_osb4_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = serverworks_cable_detect,
+ .mode_filter = serverworks_osb4_filter,
.set_piomode = serverworks_set_piomode,
.set_dmamode = serverworks_set_dmamode,
- .mode_filter = serverworks_osb4_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = serverworks_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
static struct ata_port_operations serverworks_csb_port_ops = {
- .set_piomode = serverworks_set_piomode,
- .set_dmamode = serverworks_set_dmamode,
+ .inherits = &serverworks_osb4_port_ops,
.mode_filter = serverworks_csb_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = serverworks_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
static int serverworks_fixup_osb4(struct pci_dev *pdev)
@@ -468,28 +399,24 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
{
static const struct ata_port_info info[4] = {
{ /* OSB4 */
- .sht = &serverworks_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x07,
.port_ops = &serverworks_osb4_port_ops
}, { /* OSB4 no UDMA */
- .sht = &serverworks_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = 0x00,
.port_ops = &serverworks_osb4_port_ops
}, { /* CSB5 */
- .sht = &serverworks_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA4,
.port_ops = &serverworks_csb_port_ops
}, { /* CSB5 - later revisions*/
- .sht = &serverworks_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -498,6 +425,11 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
}
};
const struct ata_port_info *ppi[] = { &info[id->driver_data], NULL };
+ int rc;
+
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
/* Force master latency timer to 64 PCI clocks */
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
@@ -527,24 +459,30 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
serverworks_fixup_ht1000(pdev);
if (pdev->device == PCI_DEVICE_ID_SERVERWORKS_CSB5IDE)
- ata_pci_clear_simplex(pdev);
+ ata_pci_bmdma_clear_simplex(pdev);
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &serverworks_sht, NULL);
}
#ifdef CONFIG_PM
static int serverworks_reinit_one(struct pci_dev *pdev)
{
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
+
/* Force master latency timer to 64 PCI clocks */
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
- switch (pdev->device)
- {
+ switch (pdev->device) {
case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
serverworks_fixup_osb4(pdev);
break;
case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
- ata_pci_clear_simplex(pdev);
+ ata_pci_bmdma_clear_simplex(pdev);
/* fall through */
case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
@@ -554,7 +492,9 @@ static int serverworks_reinit_one(struct pci_dev *pdev)
serverworks_fixup_ht1000(pdev);
break;
}
- return ata_pci_device_resume(pdev);
+
+ ata_host_resume(host);
+ return 0;
}
#endif
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 7c5b2dd9a1a1..720b8645f58a 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -192,54 +192,14 @@ static void sil680_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template sil680_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations sil680_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = sil680_cable_detect,
.set_piomode = sil680_set_piomode,
.set_dmamode = sil680_set_dmamode,
- .mode_filter = ata_pci_default_filter,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = sil680_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
/**
@@ -322,7 +282,6 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &sil680_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -330,7 +289,6 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
.port_ops = &sil680_port_ops
};
static const struct ata_port_info info_slow = {
- .sht = &sil680_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -346,6 +304,10 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
switch (sil680_init_chip(pdev, &try_mmio)) {
case 0:
ppi[0] = &info_slow;
@@ -388,28 +350,33 @@ static int __devinit sil680_init_one(struct pci_dev *pdev,
host->ports[0]->ioaddr.cmd_addr = mmio_base + 0x80;
host->ports[0]->ioaddr.ctl_addr = mmio_base + 0x8a;
host->ports[0]->ioaddr.altstatus_addr = mmio_base + 0x8a;
- ata_std_ports(&host->ports[0]->ioaddr);
+ ata_sff_std_ports(&host->ports[0]->ioaddr);
host->ports[1]->ioaddr.bmdma_addr = mmio_base + 0x08;
host->ports[1]->ioaddr.cmd_addr = mmio_base + 0xc0;
host->ports[1]->ioaddr.ctl_addr = mmio_base + 0xca;
host->ports[1]->ioaddr.altstatus_addr = mmio_base + 0xca;
- ata_std_ports(&host->ports[1]->ioaddr);
+ ata_sff_std_ports(&host->ports[1]->ioaddr);
/* Register & activate */
- return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
- &sil680_sht);
+ return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ IRQF_SHARED, &sil680_sht);
use_ioports:
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &sil680_sht, NULL);
}
#ifdef CONFIG_PM
static int sil680_reinit_one(struct pci_dev *pdev)
{
- int try_mmio;
+ struct ata_host *host = dev_get_drvdata(&pdev->dev);
+ int try_mmio, rc;
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
sil680_init_chip(pdev, &try_mmio);
- return ata_pci_device_resume(pdev);
+ ata_host_resume(host);
+ return 0;
}
#endif
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index dc7e91562e43..e82c66e8d31b 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -156,24 +156,11 @@ static int sis_pre_reset(struct ata_link *link, unsigned long deadline)
/* Clear the FIFO settings. We can't enable the FIFO until
we know we are poking at a disk */
pci_write_config_byte(pdev, 0x4B, 0);
- return ata_std_prereset(link, deadline);
+ return ata_sff_prereset(link, deadline);
}
/**
- * sis_error_handler - Probe specified port on PATA host controller
- * @ap: Port to probe
- *
- * LOCKING:
- * None (inherited from caller).
- */
-
-static void sis_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, sis_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-/**
* sis_set_fifo - Set RWP fifo bits for this device
* @ap: Port
* @adev: Device
@@ -514,217 +501,57 @@ static void sis_133_set_dmamode (struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template sis_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations sis_133_ops = {
+static struct ata_port_operations sis_133_for_sata_ops = {
+ .inherits = &ata_bmdma_port_ops,
.set_piomode = sis_133_set_piomode,
.set_dmamode = sis_133_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = sis_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = sis_133_cable_detect,
+};
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+static struct ata_port_operations sis_base_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .prereset = sis_pre_reset,
};
-static const struct ata_port_operations sis_133_for_sata_ops = {
+static struct ata_port_operations sis_133_ops = {
+ .inherits = &sis_base_ops,
.set_piomode = sis_133_set_piomode,
.set_dmamode = sis_133_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = sis_133_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
-static const struct ata_port_operations sis_133_early_ops = {
+static struct ata_port_operations sis_133_early_ops = {
+ .inherits = &sis_base_ops,
.set_piomode = sis_100_set_piomode,
.set_dmamode = sis_133_early_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = sis_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = sis_66_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
-static const struct ata_port_operations sis_100_ops = {
+static struct ata_port_operations sis_100_ops = {
+ .inherits = &sis_base_ops,
.set_piomode = sis_100_set_piomode,
.set_dmamode = sis_100_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = sis_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = sis_66_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
-static const struct ata_port_operations sis_66_ops = {
+static struct ata_port_operations sis_66_ops = {
+ .inherits = &sis_base_ops,
.set_piomode = sis_old_set_piomode,
.set_dmamode = sis_66_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
.cable_detect = sis_66_cable_detect,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = sis_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
-static const struct ata_port_operations sis_old_ops = {
+static struct ata_port_operations sis_old_ops = {
+ .inherits = &sis_base_ops,
.set_piomode = sis_old_set_piomode,
.set_dmamode = sis_old_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = sis_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
.cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
};
static const struct ata_port_info sis_info = {
- .sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07,
@@ -732,7 +559,6 @@ static const struct ata_port_info sis_info = {
.port_ops = &sis_old_ops,
};
static const struct ata_port_info sis_info33 = {
- .sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07,
@@ -740,42 +566,36 @@ static const struct ata_port_info sis_info33 = {
.port_ops = &sis_old_ops,
};
static const struct ata_port_info sis_info66 = {
- .sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA4, /* UDMA 66 */
.port_ops = &sis_66_ops,
};
static const struct ata_port_info sis_info100 = {
- .sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA5,
.port_ops = &sis_100_ops,
};
static const struct ata_port_info sis_info100_early = {
- .sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.udma_mask = ATA_UDMA5,
.pio_mask = 0x1f, /* pio0-4 */
.port_ops = &sis_66_ops,
};
static const struct ata_port_info sis_info133 = {
- .sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_ops,
};
const struct ata_port_info sis_info133_for_sata = {
- .sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &sis_133_for_sata_ops,
};
static const struct ata_port_info sis_info133_early = {
- .sht = &sis_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
@@ -857,11 +677,11 @@ static void sis_fixup(struct pci_dev *pdev, struct sis_chipset *sis)
static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
- struct ata_port_info port;
- const struct ata_port_info *ppi[] = { &port, NULL };
+ const struct ata_port_info *ppi[] = { NULL, NULL };
struct pci_dev *host = NULL;
struct sis_chipset *chipset = NULL;
struct sis_chipset *sets;
+ int rc;
static struct sis_chipset sis_chipsets[] = {
@@ -914,8 +734,11 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
dev_printk(KERN_DEBUG, &pdev->dev,
"version " DRV_VERSION "\n");
- /* We have to find the bridge first */
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+ /* We have to find the bridge first */
for (sets = &sis_chipsets[0]; sets->device; sets++) {
host = pci_get_device(PCI_VENDOR_ID_SI, sets->device, NULL);
if (host != NULL) {
@@ -994,12 +817,11 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if (chipset == NULL)
return -ENODEV;
- port = *chipset->info;
- port.private_data = chipset;
+ ppi[0] = chipset->info;
sis_fixup(pdev, chipset);
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &sis_sht, chipset);
}
static const struct pci_device_id sis_pci_tbl[] = {
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index 81ef207f8265..70d94fb28a5f 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -60,13 +60,7 @@ static int sl82c105_pre_reset(struct ata_link *link, unsigned long deadline)
if (ap->port_no && !pci_test_config_bits(pdev, &sl82c105_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
-}
-
-
-static void sl82c105_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, sl82c105_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
@@ -235,55 +229,17 @@ static int sl82c105_qc_defer(struct ata_queued_cmd *qc)
}
static struct scsi_host_template sl82c105_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations sl82c105_port_ops = {
- .set_piomode = sl82c105_set_piomode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = sl82c105_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
+ .inherits = &ata_bmdma_port_ops,
+ .qc_defer = sl82c105_qc_defer,
.bmdma_start = sl82c105_bmdma_start,
.bmdma_stop = sl82c105_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_defer = sl82c105_qc_defer,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .cable_detect = ata_cable_40wire,
+ .set_piomode = sl82c105_set_piomode,
+ .prereset = sl82c105_pre_reset,
};
/**
@@ -327,14 +283,12 @@ static int sl82c105_bridge_revision(struct pci_dev *pdev)
static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info_dma = {
- .sht = &sl82c105_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.port_ops = &sl82c105_port_ops
};
static const struct ata_port_info info_early = {
- .sht = &sl82c105_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.port_ops = &sl82c105_port_ops
@@ -344,6 +298,11 @@ static int sl82c105_init_one(struct pci_dev *dev, const struct pci_device_id *id
NULL };
u32 val;
int rev;
+ int rc;
+
+ rc = pcim_enable_device(dev);
+ if (rc)
+ return rc;
rev = sl82c105_bridge_revision(dev);
@@ -358,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_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &sl82c105_sht, NULL);
}
static const struct pci_device_id sl82c105[] = {
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index 403eafcffe12..b181261f2743 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -66,16 +66,11 @@ static int triflex_prereset(struct ata_link *link, unsigned long deadline)
if (!pci_test_config_bits(pdev, &triflex_enable_bits[ap->port_no]))
return -ENOENT;
- return ata_std_prereset(link, deadline);
+ return ata_sff_prereset(link, deadline);
}
-static void triflex_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, triflex_prereset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
/**
* triflex_load_timing - timing configuration
* @ap: ATA interface
@@ -180,60 +175,21 @@ static void triflex_bmdma_stop(struct ata_queued_cmd *qc)
}
static struct scsi_host_template triflex_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations triflex_port_ops = {
- .set_piomode = triflex_set_piomode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = triflex_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_40wire,
-
- .bmdma_setup = ata_bmdma_setup,
+ .inherits = &ata_bmdma_port_ops,
.bmdma_start = triflex_bmdma_start,
.bmdma_stop = triflex_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .cable_detect = ata_cable_40wire,
+ .set_piomode = triflex_set_piomode,
+ .prereset = triflex_prereset,
};
static int triflex_init_one(struct pci_dev *dev, const struct pci_device_id *id)
{
static const struct ata_port_info info = {
- .sht = &triflex_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -245,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_init_one(dev, ppi);
+ return ata_pci_sff_init_one(dev, ppi, &triflex_sht, NULL);
}
static const struct pci_device_id triflex[] = {
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index d119a68c388f..d4840748fb5c 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -210,23 +210,11 @@ static int via_pre_reset(struct ata_link *link, unsigned long deadline)
return -ENOENT;
}
- return ata_std_prereset(link, deadline);
+ return ata_sff_prereset(link, deadline);
}
/**
- * via_error_handler - reset for VIA chips
- * @ap: ATA port
- *
- * Handle the reset callback for the later chips with cable detect
- */
-
-static void via_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, via_pre_reset, ata_std_softreset, NULL, ata_std_postreset);
-}
-
-/**
* via_do_set_mode - set initial PIO mode data
* @ap: ATA interface
* @adev: ATA device
@@ -335,89 +323,20 @@ static void via_set_dmamode(struct ata_port *ap, struct ata_device *adev)
}
static struct scsi_host_template via_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct ata_port_operations via_port_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = via_cable_detect,
.set_piomode = via_set_piomode,
.set_dmamode = via_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = via_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = via_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .prereset = via_pre_reset,
};
static struct ata_port_operations via_port_ops_noirq = {
- .set_piomode = via_set_piomode,
- .set_dmamode = via_set_dmamode,
- .mode_filter = ata_pci_default_filter,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = via_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = via_cable_detect,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = ata_data_xfer_noirq,
-
- .irq_handler = ata_interrupt,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .inherits = &via_port_ops,
+ .sff_data_xfer = ata_sff_data_xfer_noirq,
};
/**
@@ -467,7 +386,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
{
/* Early VIA without UDMA support */
static const struct ata_port_info via_mwdma_info = {
- .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -475,7 +393,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* Ditto with IRQ masking required */
static const struct ata_port_info via_mwdma_info_borked = {
- .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -483,7 +400,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* VIA UDMA 33 devices (and borked 66) */
static const struct ata_port_info via_udma33_info = {
- .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -492,7 +408,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* VIA UDMA 66 devices */
static const struct ata_port_info via_udma66_info = {
- .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -501,7 +416,6 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* VIA UDMA 100 devices */
static const struct ata_port_info via_udma100_info = {
- .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
@@ -510,24 +424,27 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
};
/* UDMA133 with bad AST (All current 133) */
static const struct ata_port_info via_udma133_info = {
- .sht = &via_sht,
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
.udma_mask = ATA_UDMA6, /* FIXME: should check north bridge */
.port_ops = &via_port_ops
};
- struct ata_port_info type;
- const struct ata_port_info *ppi[] = { &type, NULL };
+ const struct ata_port_info *ppi[] = { NULL, NULL };
struct pci_dev *isa = NULL;
const struct via_isa_bridge *config;
static int printed_version;
u8 enable;
u32 timing;
+ int rc;
if (!printed_version++)
dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
+ rc = pcim_enable_device(pdev);
+ if (rc)
+ return rc;
+
/* To find out how the IDE will behave and what features we
actually have to look at the bridge not the IDE controller */
for (config = via_isa_bridges; config->id; config++)
@@ -561,25 +478,25 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
switch(config->flags & VIA_UDMA) {
case VIA_UDMA_NONE:
if (config->flags & VIA_NO_UNMASK)
- type = via_mwdma_info_borked;
+ ppi[0] = &via_mwdma_info_borked;
else
- type = via_mwdma_info;
+ ppi[0] = &via_mwdma_info;
break;
case VIA_UDMA_33:
- type = via_udma33_info;
+ ppi[0] = &via_udma33_info;
break;
case VIA_UDMA_66:
- type = via_udma66_info;
+ ppi[0] = &via_udma66_info;
/* The 66 MHz devices require we enable the clock */
pci_read_config_dword(pdev, 0x50, &timing);
timing |= 0x80008;
pci_write_config_dword(pdev, 0x50, timing);
break;
case VIA_UDMA_100:
- type = via_udma100_info;
+ ppi[0] = &via_udma100_info;
break;
case VIA_UDMA_133:
- type = via_udma133_info;
+ ppi[0] = &via_udma133_info;
break;
default:
WARN_ON(1);
@@ -594,9 +511,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 */
- type.private_data = (void *)config;
-
- return ata_pci_init_one(pdev, ppi);
+ return ata_pci_sff_init_one(pdev, ppi, &via_sht, (void *)config);
}
#ifdef CONFIG_PM
@@ -615,6 +530,11 @@ static int via_reinit_one(struct pci_dev *pdev)
u32 timing;
struct ata_host *host = dev_get_drvdata(&pdev->dev);
const struct via_isa_bridge *config = host->private_data;
+ int rc;
+
+ rc = ata_pci_device_do_resume(pdev);
+ if (rc)
+ return rc;
via_config_fifo(pdev, config->flags);
@@ -630,7 +550,9 @@ static int via_reinit_one(struct pci_dev *pdev)
timing &= ~0x80008;
pci_write_config_dword(pdev, 0x50, timing);
}
- return ata_pci_device_resume(pdev);
+
+ ata_host_resume(host);
+ return 0;
}
#endif
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
index 99c92eda217b..6e52a3573fbf 100644
--- a/drivers/ata/pata_winbond.c
+++ b/drivers/ata/pata_winbond.c
@@ -116,53 +116,20 @@ static unsigned int winbond_data_xfer(struct ata_device *dev,
buflen += 4 - slop;
}
} else
- buflen = ata_data_xfer(dev, buf, buflen, rw);
+ buflen = ata_sff_data_xfer(dev, buf, buflen, rw);
return buflen;
}
static struct scsi_host_template winbond_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_PIO_SHT(DRV_NAME),
};
static struct ata_port_operations winbond_port_ops = {
- .set_piomode = winbond_set_piomode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
+ .inherits = &ata_sff_port_ops,
+ .sff_data_xfer = winbond_data_xfer,
.cable_detect = ata_cable_40wire,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
-
- .data_xfer = winbond_data_xfer,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_sff_port_start,
+ .set_piomode = winbond_set_piomode,
};
/**
@@ -231,7 +198,7 @@ static __init int winbond_init_one(unsigned long port)
ap->ioaddr.cmd_addr = cmd_addr;
ap->ioaddr.altstatus_addr = ctl_addr;
ap->ioaddr.ctl_addr = ctl_addr;
- ata_std_ports(&ap->ioaddr);
+ ata_sff_std_ports(&ap->ioaddr);
/* hook in a private data structure per channel */
host->private_data = &winbond_data[nr_winbond_host];
@@ -239,7 +206,7 @@ static __init int winbond_init_one(unsigned long port)
winbond_data[nr_winbond_host].platform_dev = pdev;
/* activate */
- rc = ata_host_activate(host, 14 + i, ata_interrupt, 0,
+ rc = ata_host_activate(host, 14 + i, ata_sff_interrupt, 0,
&winbond_sht);
if (rc)
goto err_unregister;
diff --git a/drivers/ata/pdc_adma.c b/drivers/ata/pdc_adma.c
index 8e1b7e9c0ae4..be53545c9f64 100644
--- a/drivers/ata/pdc_adma.c
+++ b/drivers/ata/pdc_adma.c
@@ -131,56 +131,33 @@ struct adma_port_priv {
static int adma_ata_init_one(struct pci_dev *pdev,
const struct pci_device_id *ent);
static int adma_port_start(struct ata_port *ap);
-static void adma_host_stop(struct ata_host *host);
static void adma_port_stop(struct ata_port *ap);
static void adma_qc_prep(struct ata_queued_cmd *qc);
static unsigned int adma_qc_issue(struct ata_queued_cmd *qc);
static int adma_check_atapi_dma(struct ata_queued_cmd *qc);
-static void adma_bmdma_stop(struct ata_queued_cmd *qc);
-static u8 adma_bmdma_status(struct ata_port *ap);
-static void adma_irq_clear(struct ata_port *ap);
static void adma_freeze(struct ata_port *ap);
static void adma_thaw(struct ata_port *ap);
-static void adma_error_handler(struct ata_port *ap);
+static int adma_prereset(struct ata_link *link, unsigned long deadline);
static struct scsi_host_template adma_ata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
- .proc_name = DRV_NAME,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
+ ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = LIBATA_MAX_PRD,
.dma_boundary = ADMA_DMA_BOUNDARY,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .use_clustering = ENABLE_CLUSTERING,
- .emulated = ATA_SHT_EMULATED,
};
-static const struct ata_port_operations adma_ata_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
+static struct ata_port_operations adma_ata_ops = {
+ .inherits = &ata_sff_port_ops,
+
.check_atapi_dma = adma_check_atapi_dma,
- .data_xfer = ata_data_xfer,
.qc_prep = adma_qc_prep,
.qc_issue = adma_qc_issue,
+
.freeze = adma_freeze,
.thaw = adma_thaw,
- .error_handler = adma_error_handler,
- .irq_clear = adma_irq_clear,
- .irq_on = ata_irq_on,
+ .prereset = adma_prereset,
+
.port_start = adma_port_start,
.port_stop = adma_port_stop,
- .host_stop = adma_host_stop,
- .bmdma_stop = adma_bmdma_stop,
- .bmdma_status = adma_bmdma_status,
};
static struct ata_port_info adma_port_info[] = {
@@ -213,21 +190,6 @@ static int adma_check_atapi_dma(struct ata_queued_cmd *qc)
return 1; /* ATAPI DMA not yet supported */
}
-static void adma_bmdma_stop(struct ata_queued_cmd *qc)
-{
- /* nothing */
-}
-
-static u8 adma_bmdma_status(struct ata_port *ap)
-{
- return 0;
-}
-
-static void adma_irq_clear(struct ata_port *ap)
-{
- /* nothing */
-}
-
static void adma_reset_engine(struct ata_port *ap)
{
void __iomem *chan = ADMA_PORT_REGS(ap);
@@ -246,7 +208,7 @@ static void adma_reinit_engine(struct ata_port *ap)
/* mask/clear ATA interrupts */
writeb(ATA_NIEN, ap->ioaddr.ctl_addr);
- ata_check_status(ap);
+ ata_sff_check_status(ap);
/* reset the ADMA engine */
adma_reset_engine(ap);
@@ -281,7 +243,7 @@ static void adma_freeze(struct ata_port *ap)
/* mask/clear ATA interrupts */
writeb(ATA_NIEN, ap->ioaddr.ctl_addr);
- ata_check_status(ap);
+ ata_sff_check_status(ap);
/* reset ADMA to idle state */
writew(aPIOMD4 | aNIEN | aRSTADM, chan + ADMA_CONTROL);
@@ -304,13 +266,7 @@ static int adma_prereset(struct ata_link *link, unsigned long deadline)
pp->state = adma_state_mmio;
adma_reinit_engine(ap);
- return ata_std_prereset(link, deadline);
-}
-
-static void adma_error_handler(struct ata_port *ap)
-{
- ata_do_eh(ap, adma_prereset, ata_std_softreset, NULL,
- ata_std_postreset);
+ return ata_sff_prereset(link, deadline);
}
static int adma_fill_sg(struct ata_queued_cmd *qc)
@@ -366,7 +322,7 @@ static void adma_qc_prep(struct ata_queued_cmd *qc)
adma_enter_reg_mode(qc->ap);
if (qc->tf.protocol != ATA_PROT_DMA) {
- ata_qc_prep(qc);
+ ata_sff_qc_prep(qc);
return;
}
@@ -465,7 +421,7 @@ static unsigned int adma_qc_issue(struct ata_queued_cmd *qc)
}
pp->state = adma_state_mmio;
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static inline unsigned int adma_intr_pkt(struct ata_host *host)
@@ -536,7 +492,7 @@ static inline unsigned int adma_intr_mmio(struct ata_host *host)
if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) {
/* check main status, clearing INTRQ */
- u8 status = ata_check_status(ap);
+ u8 status = ata_sff_check_status(ap);
if ((status & ATA_BUSY))
continue;
DPRINTK("ata%u: protocol %d (dev_stat 0x%X)\n",
@@ -633,14 +589,6 @@ static void adma_port_stop(struct ata_port *ap)
adma_reset_engine(ap);
}
-static void adma_host_stop(struct ata_host *host)
-{
- unsigned int port_no;
-
- for (port_no = 0; port_no < ADMA_PORTS; ++port_no)
- adma_reset_engine(host->ports[port_no]);
-}
-
static void adma_host_init(struct ata_host *host, unsigned int chip_id)
{
unsigned int port_no;
diff --git a/drivers/ata/sata_fsl.c b/drivers/ata/sata_fsl.c
index 9d1e3cad4aa9..fddd346b1d57 100644
--- a/drivers/ata/sata_fsl.c
+++ b/drivers/ata/sata_fsl.c
@@ -35,7 +35,6 @@ enum {
SATA_FSL_HOST_FLAGS = (ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
ATA_FLAG_NCQ),
- SATA_FSL_HOST_LFLAGS = ATA_LFLAG_SKIP_D2H_BSY,
SATA_FSL_MAX_CMDS = SATA_FSL_QUEUE_DEPTH,
SATA_FSL_CMD_HDR_SIZE = 16, /* 4 DWORDS */
@@ -245,17 +244,6 @@ struct sata_fsl_port_priv {
dma_addr_t cmdslot_paddr;
struct command_desc *cmdentry;
dma_addr_t cmdentry_paddr;
-
- /*
- * SATA FSL controller has a Status FIS which should contain the
- * received D2H FIS & taskfile registers. This SFIS is present in
- * the command descriptor, and to have a ready reference to it,
- * we are caching it here, quite similar to what is done in H/W on
- * AHCI compliant devices by copying taskfile fields to a 32-bit
- * register.
- */
-
- struct ata_taskfile tf;
};
/*
@@ -465,6 +453,20 @@ static unsigned int sata_fsl_qc_issue(struct ata_queued_cmd *qc)
return 0;
}
+static bool sata_fsl_qc_fill_rtf(struct ata_queued_cmd *qc)
+{
+ struct sata_fsl_port_priv *pp = qc->ap->private_data;
+ struct sata_fsl_host_priv *host_priv = qc->ap->host->private_data;
+ void __iomem *hcr_base = host_priv->hcr_base;
+ unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
+ struct command_desc *cd;
+
+ cd = pp->cmdentry + tag;
+
+ ata_tf_from_fis(cd->sfis, &qc->result_tf);
+ return true;
+}
+
static int sata_fsl_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
u32 val)
{
@@ -556,38 +558,6 @@ static void sata_fsl_thaw(struct ata_port *ap)
ioread32(hcr_base + HCONTROL), ioread32(hcr_base + HSTATUS));
}
-/*
- * NOTE : 1st D2H FIS from device does not update sfis in command descriptor.
- */
-static inline void sata_fsl_cache_taskfile_from_d2h_fis(struct ata_queued_cmd
- *qc,
- struct ata_port *ap)
-{
- struct sata_fsl_port_priv *pp = ap->private_data;
- struct sata_fsl_host_priv *host_priv = ap->host->private_data;
- void __iomem *hcr_base = host_priv->hcr_base;
- unsigned int tag = sata_fsl_tag(qc->tag, hcr_base);
- struct command_desc *cd;
-
- cd = pp->cmdentry + tag;
-
- ata_tf_from_fis(cd->sfis, &pp->tf);
-}
-
-static u8 sata_fsl_check_status(struct ata_port *ap)
-{
- struct sata_fsl_port_priv *pp = ap->private_data;
-
- return pp->tf.command;
-}
-
-static void sata_fsl_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
- struct sata_fsl_port_priv *pp = ap->private_data;
-
- *tf = pp->tf;
-}
-
static int sata_fsl_port_start(struct ata_port *ap)
{
struct device *dev = ap->host->dev;
@@ -708,6 +678,15 @@ static unsigned int sata_fsl_dev_classify(struct ata_port *ap)
return ata_dev_classify(&tf);
}
+static int sata_fsl_prereset(struct ata_linke *link, unsigned long deadline)
+{
+ /* FIXME: Never skip softreset, sata_fsl_softreset() is
+ * combination of soft and hard resets. sata_fsl_softreset()
+ * needs to be splitted into soft and hard resets.
+ */
+ return 0;
+}
+
static int sata_fsl_softreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
@@ -913,16 +892,6 @@ err:
return -EIO;
}
-static void sata_fsl_error_handler(struct ata_port *ap)
-{
-
- DPRINTK("in xx_error_handler\n");
-
- /* perform recovery */
- ata_do_eh(ap, ata_std_prereset, sata_fsl_softreset, sata_std_hardreset,
- ata_std_postreset);
-}
-
static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc)
{
if (qc->flags & ATA_QCFLAG_FAILED)
@@ -934,11 +903,6 @@ static void sata_fsl_post_internal_cmd(struct ata_queued_cmd *qc)
}
}
-static void sata_fsl_irq_clear(struct ata_port *ap)
-{
- /* unused */
-}
-
static void sata_fsl_error_intr(struct ata_port *ap)
{
struct ata_link *link = &ap->link;
@@ -996,7 +960,7 @@ static void sata_fsl_error_intr(struct ata_port *ap)
/* handle fatal errors */
if (hstatus & FATAL_ERROR_DECODE) {
err_mask |= AC_ERR_ATA_BUS;
- action |= ATA_EH_SOFTRESET;
+ action |= ATA_EH_RESET;
/* how will fatal error interrupts be completed ?? */
freeze = 1;
}
@@ -1013,10 +977,9 @@ static void sata_fsl_error_intr(struct ata_port *ap)
/* record error info */
qc = ata_qc_from_tag(ap, link->active_tag);
- if (qc) {
- sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap);
+ if (qc)
qc->err_mask |= err_mask;
- } else
+ else
ehi->err_mask |= err_mask;
ehi->action |= action;
@@ -1029,14 +992,6 @@ static void sata_fsl_error_intr(struct ata_port *ap)
ata_port_abort(ap);
}
-static void sata_fsl_qc_complete(struct ata_queued_cmd *qc)
-{
- if (qc->flags & ATA_QCFLAG_RESULT_TF) {
- DPRINTK("xx_qc_complete called\n");
- sata_fsl_cache_taskfile_from_d2h_fis(qc, qc->ap);
- }
-}
-
static void sata_fsl_host_intr(struct ata_port *ap)
{
struct ata_link *link = &ap->link;
@@ -1077,10 +1032,8 @@ static void sata_fsl_host_intr(struct ata_port *ap)
for (i = 0; i < SATA_FSL_QUEUE_DEPTH; i++) {
if (qc_active & (1 << i)) {
qc = ata_qc_from_tag(ap, i);
- if (qc) {
- sata_fsl_qc_complete(qc);
+ if (qc)
ata_qc_complete(qc);
- }
DPRINTK
("completing ncq cmd,tag=%d,CC=0x%x,CA=0x%x\n",
i, ioread32(hcr_base + CC),
@@ -1096,10 +1049,8 @@ static void sata_fsl_host_intr(struct ata_port *ap)
DPRINTK("completing non-ncq cmd, tag=%d,CC=0x%x\n",
link->active_tag, ioread32(hcr_base + CC));
- if (qc) {
- sata_fsl_qc_complete(qc);
+ if (qc)
ata_qc_complete(qc);
- }
} else {
/* Spurious Interrupt!! */
DPRINTK("spurious interrupt!!, CC = 0x%x\n",
@@ -1197,41 +1148,26 @@ static int sata_fsl_init_controller(struct ata_host *host)
* scsi mid-layer and libata interface structures
*/
static struct scsi_host_template sata_fsl_sht = {
- .module = THIS_MODULE,
- .name = "sata_fsl",
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .change_queue_depth = ata_scsi_change_queue_depth,
+ ATA_NCQ_SHT("sata_fsl"),
.can_queue = SATA_FSL_QUEUE_DEPTH,
- .this_id = ATA_SHT_THIS_ID,
.sg_tablesize = SATA_FSL_MAX_PRD_USABLE,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = "sata_fsl",
.dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
static const struct ata_port_operations sata_fsl_ops = {
- .check_status = sata_fsl_check_status,
- .check_altstatus = sata_fsl_check_status,
- .dev_select = ata_noop_dev_select,
-
- .tf_read = sata_fsl_tf_read,
+ .inherits = &sata_port_ops,
.qc_prep = sata_fsl_qc_prep,
.qc_issue = sata_fsl_qc_issue,
- .irq_clear = sata_fsl_irq_clear,
+ .qc_fill_rtf = sata_fsl_qc_fill_rtf,
.scr_read = sata_fsl_scr_read,
.scr_write = sata_fsl_scr_write,
.freeze = sata_fsl_freeze,
.thaw = sata_fsl_thaw,
- .error_handler = sata_fsl_error_handler,
+ .prereset = sata_fsl_prereset,
+ .softreset = sata_fsl_softreset,
.post_internal_cmd = sata_fsl_post_internal_cmd,
.port_start = sata_fsl_port_start,
@@ -1241,7 +1177,6 @@ static const struct ata_port_operations sata_fsl_ops = {
static const struct ata_port_info sata_fsl_port_info[] = {
{
.flags = SATA_FSL_HOST_FLAGS,
- .link_flags = SATA_FSL_HOST_LFLAGS,
.pio_mask = 0x1f, /* pio 0-4 */
.udma_mask = 0x7f, /* udma 0-6 */
.port_ops = &sata_fsl_ops,
@@ -1297,11 +1232,6 @@ static int sata_fsl_probe(struct of_device *ofdev,
/* host->iomap is not used currently */
host->private_data = host_priv;
- /* setup port(s) */
-
- host->ports[0]->ioaddr.cmd_addr = host_priv->hcr_base;
- host->ports[0]->ioaddr.scr_addr = host_priv->ssr_base;
-
/* initialize host controller */
sata_fsl_init_controller(host);
diff --git a/drivers/ata/sata_inic162x.c b/drivers/ata/sata_inic162x.c
index 59e65edc5820..d27bb9a2568f 100644
--- a/drivers/ata/sata_inic162x.c
+++ b/drivers/ata/sata_inic162x.c
@@ -109,21 +109,7 @@ struct inic_port_priv {
};
static struct scsi_host_template inic_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static const int scr_map[] = {
@@ -236,7 +222,7 @@ static void inic_bmdma_setup(struct ata_queued_cmd *qc)
writeb(pp->cached_prdctl, port_base + PORT_PRD_CTL);
/* issue r/w command */
- ap->ops->exec_command(ap, &qc->tf);
+ ap->ops->sff_exec_command(ap, &qc->tf);
}
static void inic_bmdma_start(struct ata_queued_cmd *qc)
@@ -266,11 +252,6 @@ static u8 inic_bmdma_status(struct ata_port *ap)
return ATA_DMA_INTR;
}
-static void inic_irq_clear(struct ata_port *ap)
-{
- /* noop */
-}
-
static void inic_host_intr(struct ata_port *ap)
{
void __iomem *port_base = inic_port_base(ap);
@@ -286,14 +267,14 @@ static void inic_host_intr(struct ata_port *ap)
ata_qc_from_tag(ap, ap->link.active_tag);
if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
- ata_chk_status(ap); /* clear ATA interrupt */
+ ap->ops->sff_check_status(ap); /* clear ATA interrupt */
return;
}
- if (likely(ata_host_intr(ap, qc)))
+ if (likely(ata_sff_host_intr(ap, qc)))
return;
- ata_chk_status(ap); /* clear ATA interrupt */
+ ap->ops->sff_check_status(ap); /* clear ATA interrupt */
ata_port_printk(ap, KERN_WARNING, "unhandled "
"interrupt, irq_stat=%x\n", irq_stat);
return;
@@ -370,12 +351,12 @@ static unsigned int inic_qc_issue(struct ata_queued_cmd *qc)
*/
if (unlikely(qc->tf.command == ATA_CMD_ID_ATA ||
qc->tf.command == ATA_CMD_ID_ATAPI)) {
- u8 stat = ata_chk_status(ap);
+ u8 stat = ap->ops->sff_check_status(ap);
if (stat == 0x7f || stat == 0xff)
return AC_ERR_HSM;
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static void inic_freeze(struct ata_port *ap)
@@ -384,7 +365,7 @@ static void inic_freeze(struct ata_port *ap)
__inic_set_pirq_mask(ap, PIRQ_MASK_FREEZE);
- ata_chk_status(ap);
+ ap->ops->sff_check_status(ap);
writeb(0xff, port_base + PORT_IRQ_STAT);
readb(port_base + PORT_IRQ_STAT); /* flush */
@@ -394,7 +375,7 @@ static void inic_thaw(struct ata_port *ap)
{
void __iomem *port_base = inic_port_base(ap);
- ata_chk_status(ap);
+ ap->ops->sff_check_status(ap);
writeb(0xff, port_base + PORT_IRQ_STAT);
__inic_set_pirq_mask(ap, PIRQ_MASK_OTHER);
@@ -436,10 +417,8 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
if (ata_link_online(link)) {
struct ata_taskfile tf;
- /* wait a while before checking status */
- ata_wait_after_reset(ap, deadline);
-
- rc = ata_wait_ready(ap, deadline);
+ /* wait for link to become ready */
+ rc = ata_sff_wait_after_reset(link, 1, deadline);
/* link occupied, -ENODEV too is an error */
if (rc) {
ata_link_printk(link, KERN_WARNING, "device not ready "
@@ -447,10 +426,8 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
return rc;
}
- ata_tf_read(ap, &tf);
+ ata_sff_tf_read(ap, &tf);
*class = ata_dev_classify(&tf);
- if (*class == ATA_DEV_UNKNOWN)
- *class = ATA_DEV_NONE;
}
return 0;
@@ -471,8 +448,7 @@ static void inic_error_handler(struct ata_port *ap)
spin_unlock_irqrestore(ap->lock, flags);
/* PIO and DMA engines have been stopped, perform recovery */
- ata_do_eh(ap, ata_std_prereset, NULL, inic_hardreset,
- ata_std_postreset);
+ ata_std_error_handler(ap);
}
static void inic_post_internal_cmd(struct ata_queued_cmd *qc)
@@ -541,35 +517,26 @@ static int inic_port_start(struct ata_port *ap)
}
static struct ata_port_operations inic_port_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .scr_read = inic_scr_read,
- .scr_write = inic_scr_write,
+ .inherits = &ata_sff_port_ops,
.bmdma_setup = inic_bmdma_setup,
.bmdma_start = inic_bmdma_start,
.bmdma_stop = inic_bmdma_stop,
.bmdma_status = inic_bmdma_status,
-
- .irq_clear = inic_irq_clear,
- .irq_on = ata_irq_on,
-
- .qc_prep = ata_qc_prep,
.qc_issue = inic_qc_issue,
- .data_xfer = ata_data_xfer,
.freeze = inic_freeze,
.thaw = inic_thaw,
+ .softreset = ATA_OP_NULL, /* softreset is broken */
+ .hardreset = inic_hardreset,
.error_handler = inic_error_handler,
.post_internal_cmd = inic_post_internal_cmd,
.dev_config = inic_dev_config,
- .port_resume = inic_port_resume,
+ .scr_read = inic_scr_read,
+ .scr_write = inic_scr_write,
+ .port_resume = inic_port_resume,
.port_start = inic_port_start,
};
@@ -692,7 +659,7 @@ static int inic_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
((unsigned long)iomap[2 * i + 1] | ATA_PCI_CTL_OFS);
port->scr_addr = iomap[MMIO_BAR] + offset + PORT_SCR;
- ata_std_ports(port);
+ ata_sff_std_ports(port);
ata_port_pbar_desc(ap, MMIO_BAR, -1, "mmio");
ata_port_pbar_desc(ap, MMIO_BAR, offset, "port");
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c
index 6ebebde8454a..05ff8c776497 100644
--- a/drivers/ata/sata_mv.c
+++ b/drivers/ata/sata_mv.c
@@ -1,6 +1,7 @@
/*
* sata_mv.c - Marvell SATA support
*
+ * Copyright 2008: Marvell Corporation, all rights reserved.
* Copyright 2005: EMC Corporation, all rights reserved.
* Copyright 2005 Red Hat, Inc. All rights reserved.
*
@@ -39,7 +40,9 @@
5) Investigate problems with PCI Message Signalled Interrupts (MSI).
- 6) Add port multiplier support (intermediate)
+ 6) Cache frequently-accessed registers in mv_port_priv to reduce overhead.
+
+ 7) Fix/reenable hot plug/unplug (should happen as a side-effect of (2) above).
8) Develop a low-power-consumption strategy, and implement it.
@@ -61,7 +64,6 @@
*/
-
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
@@ -131,7 +133,7 @@ enum {
MV_FLAG_DUAL_HC = (1 << 30), /* two SATA Host Controllers */
MV_FLAG_IRQ_COALESCE = (1 << 29), /* IRQ coalescing capability */
/* SoC integrated controllers, no PCI interface */
- MV_FLAG_SOC = (1 << 28),
+ MV_FLAG_SOC = (1 << 28),
MV_COMMON_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
@@ -141,6 +143,7 @@ enum {
CRQB_FLAG_READ = (1 << 0),
CRQB_TAG_SHIFT = 1,
CRQB_IOID_SHIFT = 6, /* CRQB Gen-II/IIE IO Id shift */
+ CRQB_PMP_SHIFT = 12, /* CRQB Gen-II/IIE PMP shift */
CRQB_HOSTQ_SHIFT = 17, /* CRQB Gen-II/IIE HostQueTag shift */
CRQB_CMD_ADDR_SHIFT = 8,
CRQB_CMD_CS = (0x2 << 11),
@@ -199,7 +202,7 @@ enum {
TWSI_INT = (1 << 24),
HC_MAIN_RSVD = (0x7f << 25), /* bits 31-25 */
HC_MAIN_RSVD_5 = (0x1fff << 19), /* bits 31-19 */
- HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */
+ HC_MAIN_RSVD_SOC = (0x3fffffb << 6), /* bits 31-9, 7-6 */
HC_MAIN_MASKED_IRQS = (TRAN_LO_DONE | TRAN_HI_DONE |
PORTS_0_7_COAL_DONE | GPIO_INT | TWSI_INT |
HC_MAIN_RSVD),
@@ -223,13 +226,24 @@ enum {
SATA_STATUS_OFS = 0x300, /* ctrl, err regs follow status */
SATA_ACTIVE_OFS = 0x350,
SATA_FIS_IRQ_CAUSE_OFS = 0x364,
+
+ LTMODE_OFS = 0x30c,
+ LTMODE_BIT8 = (1 << 8), /* unknown, but necessary */
+
PHY_MODE3 = 0x310,
PHY_MODE4 = 0x314,
PHY_MODE2 = 0x330,
+ SATA_IFCTL_OFS = 0x344,
+ SATA_IFSTAT_OFS = 0x34c,
+ VENDOR_UNIQUE_FIS_OFS = 0x35c,
+
+ FIS_CFG_OFS = 0x360,
+ FIS_CFG_SINGLE_SYNC = (1 << 16), /* SYNC on DMA activation */
+
MV5_PHY_MODE = 0x74,
MV5_LT_MODE = 0x30,
MV5_PHY_CTL = 0x0C,
- SATA_INTERFACE_CTL = 0x050,
+ SATA_INTERFACE_CFG = 0x050,
MV_M2_PREAMP_MASK = 0x7e0,
@@ -240,6 +254,8 @@ enum {
EDMA_CFG_NCQ_GO_ON_ERR = (1 << 14), /* continue on error */
EDMA_CFG_RD_BRST_EXT = (1 << 11), /* read burst 512B */
EDMA_CFG_WR_BUFF_LEN = (1 << 13), /* write buffer 512B */
+ EDMA_CFG_EDMA_FBS = (1 << 16), /* EDMA FIS-Based Switching */
+ EDMA_CFG_FBS = (1 << 26), /* FIS-Based Switching */
EDMA_ERR_IRQ_CAUSE_OFS = 0x8,
EDMA_ERR_IRQ_MASK_OFS = 0xc,
@@ -282,7 +298,9 @@ enum {
EDMA_ERR_IRQ_TRANSIENT = EDMA_ERR_LNK_CTRL_RX_0 |
EDMA_ERR_LNK_CTRL_RX_1 |
EDMA_ERR_LNK_CTRL_RX_3 |
- EDMA_ERR_LNK_CTRL_TX,
+ EDMA_ERR_LNK_CTRL_TX |
+ /* temporary, until we fix hotplug: */
+ (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON),
EDMA_EH_FREEZE = EDMA_ERR_D_PAR |
EDMA_ERR_PRD_PAR |
@@ -298,6 +316,7 @@ enum {
EDMA_ERR_LNK_DATA_RX |
EDMA_ERR_LNK_DATA_TX |
EDMA_ERR_TRANS_PROTO,
+
EDMA_EH_FREEZE_5 = EDMA_ERR_D_PAR |
EDMA_ERR_PRD_PAR |
EDMA_ERR_DEV_DCON |
@@ -344,7 +363,6 @@ enum {
/* Port private flags (pp_flags) */
MV_PP_FLAG_EDMA_EN = (1 << 0), /* is EDMA engine enabled? */
MV_PP_FLAG_NCQ_EN = (1 << 1), /* is EDMA set up for NCQ? */
- MV_PP_FLAG_HAD_A_RESET = (1 << 2), /* 1st hard reset complete? */
};
#define IS_GEN_I(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_I)
@@ -461,7 +479,6 @@ struct mv_hw_ops {
void (*reset_bus)(struct ata_host *host, void __iomem *mmio);
};
-static void mv_irq_clear(struct ata_port *ap);
static int mv_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val);
static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val);
static int mv5_scr_read(struct ata_port *ap, unsigned int sc_reg_in, u32 *val);
@@ -471,7 +488,8 @@ static void mv_port_stop(struct ata_port *ap);
static void mv_qc_prep(struct ata_queued_cmd *qc);
static void mv_qc_prep_iie(struct ata_queued_cmd *qc);
static unsigned int mv_qc_issue(struct ata_queued_cmd *qc);
-static void mv_error_handler(struct ata_port *ap);
+static int mv_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
static void mv_eh_freeze(struct ata_port *ap);
static void mv_eh_thaw(struct ata_port *ap);
static void mv6_dev_config(struct ata_device *dev);
@@ -504,72 +522,46 @@ static void mv_soc_reset_flash(struct mv_host_priv *hpriv,
void __iomem *mmio);
static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio);
static void mv_reset_pci_bus(struct ata_host *host, void __iomem *mmio);
-static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
+static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no);
-static void mv_edma_cfg(struct mv_port_priv *pp, struct mv_host_priv *hpriv,
- void __iomem *port_mmio, int want_ncq);
-static int __mv_stop_dma(struct ata_port *ap);
+static int mv_stop_edma(struct ata_port *ap);
+static int mv_stop_edma_engine(void __iomem *port_mmio);
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq);
+
+static void mv_pmp_select(struct ata_port *ap, int pmp);
+static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+static int mv_softreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
/* .sg_tablesize is (MV_MAX_SG_CT / 2) in the structures below
* because we have to allow room for worst case splitting of
* PRDs for 64K boundaries in mv_fill_sg().
*/
static struct scsi_host_template mv5_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
+ ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = MV_MAX_SG_CT / 2,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = 1,
- .proc_name = DRV_NAME,
.dma_boundary = MV_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
static struct scsi_host_template mv6_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .change_queue_depth = ata_scsi_change_queue_depth,
+ ATA_NCQ_SHT(DRV_NAME),
.can_queue = MV_MAX_Q_DEPTH - 1,
- .this_id = ATA_SHT_THIS_ID,
.sg_tablesize = MV_MAX_SG_CT / 2,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = 1,
- .proc_name = DRV_NAME,
.dma_boundary = MV_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
-static const struct ata_port_operations mv5_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .cable_detect = ata_cable_sata,
+static struct ata_port_operations mv5_ops = {
+ .inherits = &ata_sff_port_ops,
.qc_prep = mv_qc_prep,
.qc_issue = mv_qc_issue,
- .data_xfer = ata_data_xfer,
-
- .irq_clear = mv_irq_clear,
- .irq_on = ata_irq_on,
- .error_handler = mv_error_handler,
.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,
@@ -578,61 +570,24 @@ static const struct ata_port_operations mv5_ops = {
.port_stop = mv_port_stop,
};
-static const struct ata_port_operations mv6_ops = {
+static struct ata_port_operations mv6_ops = {
+ .inherits = &mv5_ops,
+ .qc_defer = sata_pmp_qc_defer_cmd_switch,
.dev_config = mv6_dev_config,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .cable_detect = ata_cable_sata,
-
- .qc_prep = mv_qc_prep,
- .qc_issue = mv_qc_issue,
- .data_xfer = ata_data_xfer,
-
- .irq_clear = mv_irq_clear,
- .irq_on = ata_irq_on,
-
- .error_handler = mv_error_handler,
- .freeze = mv_eh_freeze,
- .thaw = mv_eh_thaw,
- .qc_defer = ata_std_qc_defer,
-
.scr_read = mv_scr_read,
.scr_write = mv_scr_write,
- .port_start = mv_port_start,
- .port_stop = mv_port_stop,
+ .pmp_hardreset = mv_pmp_hardreset,
+ .pmp_softreset = mv_softreset,
+ .softreset = mv_softreset,
+ .error_handler = sata_pmp_error_handler,
};
-static const struct ata_port_operations mv_iie_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .cable_detect = ata_cable_sata,
-
+static struct ata_port_operations mv_iie_ops = {
+ .inherits = &mv6_ops,
+ .qc_defer = ata_std_qc_defer, /* FIS-based switching */
+ .dev_config = ATA_OP_NULL,
.qc_prep = mv_qc_prep_iie,
- .qc_issue = mv_qc_issue,
- .data_xfer = ata_data_xfer,
-
- .irq_clear = mv_irq_clear,
- .irq_on = ata_irq_on,
-
- .error_handler = mv_error_handler,
- .freeze = mv_eh_freeze,
- .thaw = mv_eh_thaw,
- .qc_defer = ata_std_qc_defer,
-
- .scr_read = mv_scr_read,
- .scr_write = mv_scr_write,
-
- .port_start = mv_port_start,
- .port_stop = mv_port_stop,
};
static const struct ata_port_info mv_port_info[] = {
@@ -656,6 +611,7 @@ static const struct ata_port_info mv_port_info[] = {
},
{ /* chip_604x */
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+ ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
ATA_FLAG_NCQ,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
@@ -663,6 +619,7 @@ static const struct ata_port_info mv_port_info[] = {
},
{ /* chip_608x */
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+ ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
ATA_FLAG_NCQ | MV_FLAG_DUAL_HC,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
@@ -670,6 +627,7 @@ static const struct ata_port_info mv_port_info[] = {
},
{ /* chip_6042 */
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+ ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
ATA_FLAG_NCQ,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
@@ -677,16 +635,19 @@ static const struct ata_port_info mv_port_info[] = {
},
{ /* chip_7042 */
.flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+ ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
ATA_FLAG_NCQ,
.pio_mask = 0x1f, /* pio0-4 */
.udma_mask = ATA_UDMA6,
.port_ops = &mv_iie_ops,
},
{ /* chip_soc */
- .flags = MV_COMMON_FLAGS | MV_FLAG_SOC,
- .pio_mask = 0x1f, /* pio0-4 */
- .udma_mask = ATA_UDMA6,
- .port_ops = &mv_iie_ops,
+ .flags = MV_COMMON_FLAGS | MV_6XXX_FLAGS |
+ ATA_FLAG_PMP | ATA_FLAG_ACPI_SATA |
+ ATA_FLAG_NCQ | MV_FLAG_SOC,
+ .pio_mask = 0x1f, /* pio0-4 */
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &mv_iie_ops,
},
};
@@ -785,6 +746,14 @@ static inline void __iomem *mv_port_base(void __iomem *base, unsigned int port)
(mv_hardport_from_port(port) * MV_PORT_REG_SZ);
}
+static void __iomem *mv5_phy_base(void __iomem *mmio, unsigned int port)
+{
+ void __iomem *hc_mmio = mv_hc_base_from_port(mmio, port);
+ unsigned long ofs = (mv_hardport_from_port(port) + 1) * 0x100UL;
+
+ return hc_mmio + ofs;
+}
+
static inline void __iomem *mv_host_base(struct ata_host *host)
{
struct mv_host_priv *hpriv = host->private_data;
@@ -801,10 +770,6 @@ static inline int mv_get_hc_count(unsigned long port_flags)
return ((port_flags & MV_FLAG_DUAL_HC) ? 2 : 1);
}
-static void mv_irq_clear(struct ata_port *ap)
-{
-}
-
static void mv_set_edma_ptrs(void __iomem *port_mmio,
struct mv_host_priv *hpriv,
struct mv_port_priv *pp)
@@ -864,7 +829,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
int using_ncq = ((pp->pp_flags & MV_PP_FLAG_NCQ_EN) != 0);
if (want_ncq != using_ncq)
- __mv_stop_dma(ap);
+ mv_stop_edma(ap);
}
if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN)) {
struct mv_host_priv *hpriv = ap->host->private_data;
@@ -885,7 +850,7 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
hc_mmio + HC_IRQ_CAUSE_OFS);
}
- mv_edma_cfg(pp, hpriv, port_mmio, want_ncq);
+ mv_edma_cfg(ap, want_ncq);
/* clear FIS IRQ Cause */
writelfl(0, port_mmio + SATA_FIS_IRQ_CAUSE_OFS);
@@ -899,58 +864,42 @@ static void mv_start_dma(struct ata_port *ap, void __iomem *port_mmio,
}
/**
- * __mv_stop_dma - Disable eDMA engine
- * @ap: ATA channel to manipulate
- *
- * Verify the local cache of the eDMA state is accurate with a
- * WARN_ON.
+ * mv_stop_edma_engine - Disable eDMA engine
+ * @port_mmio: io base address
*
* LOCKING:
* Inherited from caller.
*/
-static int __mv_stop_dma(struct ata_port *ap)
+static int mv_stop_edma_engine(void __iomem *port_mmio)
{
- void __iomem *port_mmio = mv_ap_base(ap);
- struct mv_port_priv *pp = ap->private_data;
- u32 reg;
- int i, err = 0;
+ int i;
- if (pp->pp_flags & MV_PP_FLAG_EDMA_EN) {
- /* Disable EDMA if active. The disable bit auto clears.
- */
- writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
- pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
- } else {
- WARN_ON(EDMA_EN & readl(port_mmio + EDMA_CMD_OFS));
- }
+ /* Disable eDMA. The disable bit auto clears. */
+ writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
- /* now properly wait for the eDMA to stop */
- for (i = 1000; i > 0; i--) {
- reg = readl(port_mmio + EDMA_CMD_OFS);
+ /* Wait for the chip to confirm eDMA is off. */
+ for (i = 10000; i > 0; i--) {
+ u32 reg = readl(port_mmio + EDMA_CMD_OFS);
if (!(reg & EDMA_EN))
- break;
-
- udelay(100);
- }
-
- if (reg & EDMA_EN) {
- ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
- err = -EIO;
+ return 0;
+ udelay(10);
}
-
- return err;
+ return -EIO;
}
-static int mv_stop_dma(struct ata_port *ap)
+static int mv_stop_edma(struct ata_port *ap)
{
- unsigned long flags;
- int rc;
-
- spin_lock_irqsave(&ap->host->lock, flags);
- rc = __mv_stop_dma(ap);
- spin_unlock_irqrestore(&ap->host->lock, flags);
+ void __iomem *port_mmio = mv_ap_base(ap);
+ struct mv_port_priv *pp = ap->private_data;
- return rc;
+ if (!(pp->pp_flags & MV_PP_FLAG_EDMA_EN))
+ return 0;
+ pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
+ if (mv_stop_edma_engine(port_mmio)) {
+ ata_port_printk(ap, KERN_ERR, "Unable to stop eDMA\n");
+ return -EIO;
+ }
+ return 0;
}
#ifdef ATA_DEBUG
@@ -1074,18 +1023,50 @@ static int mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
static void mv6_dev_config(struct ata_device *adev)
{
/*
+ * Deal with Gen-II ("mv6") hardware quirks/restrictions:
+ *
+ * Gen-II does not support NCQ over a port multiplier
+ * (no FIS-based switching).
+ *
* We don't have hob_nsect when doing NCQ commands on Gen-II.
* See mv_qc_prep() for more info.
*/
- if (adev->flags & ATA_DFLAG_NCQ)
- if (adev->max_sectors > ATA_MAX_SECTORS)
+ if (adev->flags & ATA_DFLAG_NCQ) {
+ if (sata_pmp_attached(adev->link->ap))
+ adev->flags &= ~ATA_DFLAG_NCQ;
+ else if (adev->max_sectors > ATA_MAX_SECTORS)
adev->max_sectors = ATA_MAX_SECTORS;
+ }
}
-static void mv_edma_cfg(struct mv_port_priv *pp, struct mv_host_priv *hpriv,
- void __iomem *port_mmio, int want_ncq)
+static void mv_config_fbs(void __iomem *port_mmio, int enable_fbs)
+{
+ u32 old_fcfg, new_fcfg, old_ltmode, new_ltmode;
+ /*
+ * Various bit settings required for operation
+ * in FIS-based switching (fbs) mode on GenIIe:
+ */
+ old_fcfg = readl(port_mmio + FIS_CFG_OFS);
+ old_ltmode = readl(port_mmio + LTMODE_OFS);
+ if (enable_fbs) {
+ new_fcfg = old_fcfg | FIS_CFG_SINGLE_SYNC;
+ new_ltmode = old_ltmode | LTMODE_BIT8;
+ } else { /* disable fbs */
+ new_fcfg = old_fcfg & ~FIS_CFG_SINGLE_SYNC;
+ new_ltmode = old_ltmode & ~LTMODE_BIT8;
+ }
+ if (new_fcfg != old_fcfg)
+ writelfl(new_fcfg, port_mmio + FIS_CFG_OFS);
+ if (new_ltmode != old_ltmode)
+ writelfl(new_ltmode, port_mmio + LTMODE_OFS);
+}
+
+static void mv_edma_cfg(struct ata_port *ap, int want_ncq)
{
u32 cfg;
+ struct mv_port_priv *pp = ap->private_data;
+ struct mv_host_priv *hpriv = ap->host->private_data;
+ void __iomem *port_mmio = mv_ap_base(ap);
/* set up non-NCQ EDMA configuration */
cfg = EDMA_CFG_Q_DEPTH; /* always 0x1f for *all* chips */
@@ -1101,6 +1082,13 @@ static void mv_edma_cfg(struct mv_port_priv *pp, struct mv_host_priv *hpriv,
cfg |= (1 << 22); /* enab 4-entry host queue cache */
cfg |= (1 << 18); /* enab early completion */
cfg |= (1 << 17); /* enab cut-through (dis stor&forwrd) */
+
+ if (want_ncq && sata_pmp_attached(ap)) {
+ cfg |= EDMA_CFG_EDMA_FBS; /* FIS-based switching */
+ mv_config_fbs(port_mmio, 1);
+ } else {
+ mv_config_fbs(port_mmio, 0);
+ }
}
if (want_ncq) {
@@ -1156,8 +1144,6 @@ static int mv_port_start(struct ata_port *ap)
struct device *dev = ap->host->dev;
struct mv_host_priv *hpriv = ap->host->private_data;
struct mv_port_priv *pp;
- void __iomem *port_mmio = mv_ap_base(ap);
- unsigned long flags;
int tag;
pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
@@ -1190,18 +1176,6 @@ static int mv_port_start(struct ata_port *ap)
pp->sg_tbl_dma[tag] = pp->sg_tbl_dma[0];
}
}
-
- spin_lock_irqsave(&ap->host->lock, flags);
-
- mv_edma_cfg(pp, hpriv, port_mmio, 0);
- mv_set_edma_ptrs(port_mmio, hpriv, pp);
-
- spin_unlock_irqrestore(&ap->host->lock, flags);
-
- /* Don't turn on EDMA here...do it before DMA commands only. Else
- * we'll be unable to send non-data, PIO, etc due to restricted access
- * to shadow regs.
- */
return 0;
out_port_free_dma_mem:
@@ -1220,7 +1194,7 @@ out_port_free_dma_mem:
*/
static void mv_port_stop(struct ata_port *ap)
{
- mv_stop_dma(ap);
+ mv_stop_edma(ap);
mv_port_free_dma_mem(ap);
}
@@ -1306,6 +1280,7 @@ static void mv_qc_prep(struct ata_queued_cmd *qc)
flags |= CRQB_FLAG_READ;
WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
flags |= qc->tag << CRQB_TAG_SHIFT;
+ flags |= (qc->dev->link->pmp & 0xf) << CRQB_PMP_SHIFT;
/* get current queue index from software */
in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK;
@@ -1390,14 +1365,14 @@ static void mv_qc_prep_iie(struct ata_queued_cmd *qc)
(qc->tf.protocol != ATA_PROT_NCQ))
return;
- /* Fill in Gen IIE command request block
- */
+ /* Fill in Gen IIE command request block */
if (!(qc->tf.flags & ATA_TFLAG_WRITE))
flags |= CRQB_FLAG_READ;
WARN_ON(MV_MAX_Q_DEPTH <= qc->tag);
flags |= qc->tag << CRQB_TAG_SHIFT;
flags |= qc->tag << CRQB_HOSTQ_SHIFT;
+ flags |= (qc->dev->link->pmp & 0xf) << CRQB_PMP_SHIFT;
/* get current queue index from software */
in_index = pp->req_idx & MV_MAX_Q_DEPTH_MASK;
@@ -1455,12 +1430,14 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
if ((qc->tf.protocol != ATA_PROT_DMA) &&
(qc->tf.protocol != ATA_PROT_NCQ)) {
- /* We're about to send a non-EDMA capable command to the
+ /*
+ * We're about to send a non-EDMA capable command to the
* port. Turn off EDMA so there won't be problems accessing
* shadow block, etc registers.
*/
- __mv_stop_dma(ap);
- return ata_qc_issue_prot(qc);
+ mv_stop_edma(ap);
+ mv_pmp_select(ap, qc->dev->link->pmp);
+ return ata_sff_qc_issue(qc);
}
mv_start_dma(ap, port_mmio, pp, qc->tf.protocol);
@@ -1482,10 +1459,10 @@ static unsigned int mv_qc_issue(struct ata_queued_cmd *qc)
* @reset_allowed: bool: 0 == don't trigger from reset here
*
* In most cases, just clear the interrupt and move on. However,
- * some cases require an eDMA reset, which is done right before
- * the COMRESET in mv_phy_reset(). The SERR case requires a
- * clear of pending errors in the SATA SERROR register. Finally,
- * if the port disabled DMA, update our cached copy to match.
+ * some cases require an eDMA reset, which also performs a COMRESET.
+ * The SERR case requires a clear of pending errors in the SATA
+ * SERROR register. Finally, if the port disabled DMA,
+ * update our cached copy to match.
*
* LOCKING:
* Inherited from caller.
@@ -1524,14 +1501,14 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
EDMA_ERR_CRQB_PAR | EDMA_ERR_CRPB_PAR |
EDMA_ERR_INTRL_PAR)) {
err_mask |= AC_ERR_ATA_BUS;
- action |= ATA_EH_HARDRESET;
+ action |= ATA_EH_RESET;
ata_ehi_push_desc(ehi, "parity error");
}
if (edma_err_cause & (EDMA_ERR_DEV_DCON | EDMA_ERR_DEV_CON)) {
ata_ehi_hotplugged(ehi);
ata_ehi_push_desc(ehi, edma_err_cause & EDMA_ERR_DEV_DCON ?
"dev disconnect" : "dev connect");
- action |= ATA_EH_HARDRESET;
+ action |= ATA_EH_RESET;
}
if (IS_GEN_I(hpriv)) {
@@ -1555,7 +1532,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
sata_scr_read(&ap->link, SCR_ERROR, &serr);
sata_scr_write_flush(&ap->link, SCR_ERROR, serr);
err_mask = AC_ERR_ATA_BUS;
- action |= ATA_EH_HARDRESET;
+ action |= ATA_EH_RESET;
}
}
@@ -1564,7 +1541,7 @@ static void mv_err_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
if (!err_mask) {
err_mask = AC_ERR_OTHER;
- action |= ATA_EH_HARDRESET;
+ action |= ATA_EH_RESET;
}
ehi->serror |= serr;
@@ -1723,9 +1700,9 @@ static void mv_host_intr(struct ata_host *host, u32 relevant, unsigned int hc)
pp = ap->private_data;
shift = port << 1; /* (port * 2) */
- if (port >= MV_PORTS_PER_HC) {
+ if (port >= MV_PORTS_PER_HC)
shift++; /* skip bit 8 in the HC Main IRQ reg */
- }
+
have_err_bits = ((PORT0_ERR << shift) & relevant);
if (unlikely(have_err_bits)) {
@@ -1780,7 +1757,7 @@ static void mv_pci_error(struct ata_host *host, void __iomem *mmio)
ata_ehi_push_desc(ehi,
"PCI err cause 0x%08x", err_cause);
err_mask = AC_ERR_HOST_BUS;
- ehi->action = ATA_EH_HARDRESET;
+ ehi->action = ATA_EH_RESET;
qc = ata_qc_from_tag(ap, ap->link.active_tag);
if (qc)
qc->err_mask |= err_mask;
@@ -1814,6 +1791,7 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance)
void __iomem *mmio = hpriv->base;
u32 irq_stat, irq_mask;
+ /* Note to self: &host->lock == &ap->host->lock == ap->lock */
spin_lock(&host->lock);
irq_stat = readl(hpriv->main_cause_reg_addr);
@@ -1847,14 +1825,6 @@ out_unlock:
return IRQ_RETVAL(handled);
}
-static void __iomem *mv5_phy_base(void __iomem *mmio, unsigned int port)
-{
- void __iomem *hc_mmio = mv_hc_base_from_port(mmio, port);
- unsigned long ofs = (mv_hardport_from_port(port) + 1) * 0x100UL;
-
- return hc_mmio + ofs;
-}
-
static unsigned int mv5_scr_offset(unsigned int sc_reg_in)
{
unsigned int ofs;
@@ -1980,9 +1950,12 @@ static void mv5_reset_hc_port(struct mv_host_priv *hpriv, void __iomem *mmio,
{
void __iomem *port_mmio = mv_port_base(mmio, port);
- writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
-
- mv_channel_reset(hpriv, mmio, port);
+ /*
+ * The datasheet warns against setting ATA_RST when EDMA is active
+ * (but doesn't say what the problem might be). So we first try
+ * to disable the EDMA engine before doing the ATA_RST operation.
+ */
+ mv_reset_channel(hpriv, mmio, port);
ZERO(0x028); /* command */
writel(0x11f, port_mmio + EDMA_CFG_OFS);
@@ -2132,6 +2105,13 @@ static int mv6_reset_hc(struct mv_host_priv *hpriv, void __iomem *mmio,
printk(KERN_ERR DRV_NAME ": can't clear global reset\n");
rc = 1;
}
+ /*
+ * Temporary: wait 3 seconds before port-probing can happen,
+ * so that we don't miss finding sleepy SilXXXX port-multipliers.
+ * This can go away once hotplug is fully/correctly implemented.
+ */
+ if (rc == 0)
+ msleep(3000);
done:
return rc;
}
@@ -2200,14 +2180,15 @@ static void mv6_phy_errata(struct mv_host_priv *hpriv, void __iomem *mmio,
m4 = readl(port_mmio + PHY_MODE4);
if (hp_flags & MV_HP_ERRATA_60X1B2)
- tmp = readl(port_mmio + 0x310);
+ tmp = readl(port_mmio + PHY_MODE3);
+ /* workaround for errata FEr SATA#10 (part 1) */
m4 = (m4 & ~(1 << 1)) | (1 << 0);
writel(m4, port_mmio + PHY_MODE4);
if (hp_flags & MV_HP_ERRATA_60X1B2)
- writel(tmp, port_mmio + 0x310);
+ writel(tmp, port_mmio + PHY_MODE3);
}
/* Revert values of pre-emphasis and signal amps to the saved ones */
@@ -2255,9 +2236,12 @@ static void mv_soc_reset_hc_port(struct mv_host_priv *hpriv,
{
void __iomem *port_mmio = mv_port_base(mmio, port);
- writelfl(EDMA_DS, port_mmio + EDMA_CMD_OFS);
-
- mv_channel_reset(hpriv, mmio, port);
+ /*
+ * The datasheet warns against setting ATA_RST when EDMA is active
+ * (but doesn't say what the problem might be). So we first try
+ * to disable the EDMA engine before doing the ATA_RST operation.
+ */
+ mv_reset_channel(hpriv, mmio, port);
ZERO(0x028); /* command */
writel(0x101f, port_mmio + EDMA_CFG_OFS);
@@ -2314,25 +2298,39 @@ static void mv_soc_reset_bus(struct ata_host *host, void __iomem *mmio)
return;
}
-static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
+static void mv_setup_ifctl(void __iomem *port_mmio, int want_gen2i)
+{
+ u32 ifctl = readl(port_mmio + SATA_INTERFACE_CFG);
+
+ ifctl = (ifctl & 0xf7f) | 0x9b1000; /* from chip spec */
+ if (want_gen2i)
+ ifctl |= (1 << 7); /* enable gen2i speed */
+ writelfl(ifctl, port_mmio + SATA_INTERFACE_CFG);
+}
+
+/*
+ * Caller must ensure that EDMA is not active,
+ * by first doing mv_stop_edma() where needed.
+ */
+static void mv_reset_channel(struct mv_host_priv *hpriv, void __iomem *mmio,
unsigned int port_no)
{
void __iomem *port_mmio = mv_port_base(mmio, port_no);
+ mv_stop_edma_engine(port_mmio);
writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
- if (IS_GEN_II(hpriv)) {
- u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
- ifctl |= (1 << 7); /* enable gen2i speed */
- ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */
- writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL);
+ if (!IS_GEN_I(hpriv)) {
+ /* Enable 3.0gb/s link speed */
+ mv_setup_ifctl(port_mmio, 1);
}
-
- udelay(25); /* allow reset propagation */
-
- /* Spec never mentions clearing the bit. Marvell's driver does
- * clear the bit, however.
+ /*
+ * Strobing ATA_RST here causes a hard reset of the SATA transport,
+ * link, and physical layers. It resets all SATA interface registers
+ * (except for SATA_INTERFACE_CFG), and issues a COMRESET to the dev.
*/
+ writelfl(ATA_RST, port_mmio + EDMA_CMD_OFS);
+ udelay(25); /* allow reset propagation */
writelfl(0, port_mmio + EDMA_CMD_OFS);
hpriv->ops->phy_errata(hpriv, mmio, port_no);
@@ -2341,136 +2339,32 @@ static void mv_channel_reset(struct mv_host_priv *hpriv, void __iomem *mmio,
mdelay(1);
}
-/**
- * mv_phy_reset - Perform eDMA reset followed by COMRESET
- * @ap: ATA channel to manipulate
- *
- * Part of this is taken from __sata_phy_reset and modified to
- * not sleep since this routine gets called from interrupt level.
- *
- * LOCKING:
- * Inherited from caller. This is coded to safe to call at
- * interrupt level, i.e. it does not sleep.
- */
-static void mv_phy_reset(struct ata_port *ap, unsigned int *class,
- unsigned long deadline)
+static void mv_pmp_select(struct ata_port *ap, int pmp)
{
- struct mv_port_priv *pp = ap->private_data;
- struct mv_host_priv *hpriv = ap->host->private_data;
- void __iomem *port_mmio = mv_ap_base(ap);
- int retry = 5;
- u32 sstatus;
-
- VPRINTK("ENTER, port %u, mmio 0x%p\n", ap->port_no, port_mmio);
-
-#ifdef DEBUG
- {
- u32 sstatus, serror, scontrol;
-
- mv_scr_read(ap, SCR_STATUS, &sstatus);
- mv_scr_read(ap, SCR_ERROR, &serror);
- mv_scr_read(ap, SCR_CONTROL, &scontrol);
- DPRINTK("S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
- "SCtrl 0x%08x\n", sstatus, serror, scontrol);
- }
-#endif
-
- /* Issue COMRESET via SControl */
-comreset_retry:
- sata_scr_write_flush(&ap->link, SCR_CONTROL, 0x301);
- msleep(1);
-
- sata_scr_write_flush(&ap->link, SCR_CONTROL, 0x300);
- msleep(20);
+ if (sata_pmp_supported(ap)) {
+ void __iomem *port_mmio = mv_ap_base(ap);
+ u32 reg = readl(port_mmio + SATA_IFCTL_OFS);
+ int old = reg & 0xf;
- do {
- sata_scr_read(&ap->link, SCR_STATUS, &sstatus);
- if (((sstatus & 0x3) == 3) || ((sstatus & 0x3) == 0))
- break;
-
- msleep(1);
- } while (time_before(jiffies, deadline));
-
- /* work around errata */
- if (IS_GEN_II(hpriv) &&
- (sstatus != 0x0) && (sstatus != 0x113) && (sstatus != 0x123) &&
- (retry-- > 0))
- goto comreset_retry;
-
-#ifdef DEBUG
- {
- u32 sstatus, serror, scontrol;
-
- mv_scr_read(ap, SCR_STATUS, &sstatus);
- mv_scr_read(ap, SCR_ERROR, &serror);
- mv_scr_read(ap, SCR_CONTROL, &scontrol);
- DPRINTK("S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
- "SCtrl 0x%08x\n", sstatus, serror, scontrol);
- }
-#endif
-
- if (ata_link_offline(&ap->link)) {
- *class = ATA_DEV_NONE;
- return;
- }
-
- /* even after SStatus reflects that device is ready,
- * it seems to take a while for link to be fully
- * established (and thus Status no longer 0x80/0x7F),
- * so we poll a bit for that, here.
- */
- retry = 20;
- while (1) {
- u8 drv_stat = ata_check_status(ap);
- if ((drv_stat != 0x80) && (drv_stat != 0x7f))
- break;
- msleep(500);
- if (retry-- <= 0)
- break;
- if (time_after(jiffies, deadline))
- break;
+ if (old != pmp) {
+ reg = (reg & ~0xf) | pmp;
+ writelfl(reg, port_mmio + SATA_IFCTL_OFS);
+ }
}
-
- /* FIXME: if we passed the deadline, the following
- * code probably produces an invalid result
- */
-
- /* finally, read device signature from TF registers */
- *class = ata_dev_try_classify(ap->link.device, 1, NULL);
-
- writelfl(0, port_mmio + EDMA_ERR_IRQ_CAUSE_OFS);
-
- WARN_ON(pp->pp_flags & MV_PP_FLAG_EDMA_EN);
-
- VPRINTK("EXIT\n");
}
-static int mv_prereset(struct ata_link *link, unsigned long deadline)
+static int mv_pmp_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
{
- struct ata_port *ap = link->ap;
- struct mv_port_priv *pp = ap->private_data;
- struct ata_eh_context *ehc = &link->eh_context;
- int rc;
-
- rc = mv_stop_dma(ap);
- if (rc)
- ehc->i.action |= ATA_EH_HARDRESET;
-
- if (!(pp->pp_flags & MV_PP_FLAG_HAD_A_RESET)) {
- pp->pp_flags |= MV_PP_FLAG_HAD_A_RESET;
- ehc->i.action |= ATA_EH_HARDRESET;
- }
-
- /* if we're about to do hardreset, nothing more to do */
- if (ehc->i.action & ATA_EH_HARDRESET)
- return 0;
-
- if (ata_link_online(link))
- rc = ata_wait_ready(ap, deadline);
- else
- rc = -ENODEV;
+ mv_pmp_select(link->ap, sata_srst_pmp(link));
+ return sata_std_hardreset(link, class, deadline);
+}
- return rc;
+static int mv_softreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
+{
+ mv_pmp_select(link->ap, sata_srst_pmp(link));
+ return ata_sff_softreset(link, class, deadline);
}
static int mv_hardreset(struct ata_link *link, unsigned int *class,
@@ -2478,43 +2372,34 @@ static int mv_hardreset(struct ata_link *link, unsigned int *class,
{
struct ata_port *ap = link->ap;
struct mv_host_priv *hpriv = ap->host->private_data;
+ struct mv_port_priv *pp = ap->private_data;
void __iomem *mmio = hpriv->base;
+ int rc, attempts = 0, extra = 0;
+ u32 sstatus;
+ bool online;
- mv_stop_dma(ap);
-
- mv_channel_reset(hpriv, mmio, ap->port_no);
-
- mv_phy_reset(ap, class, deadline);
-
- return 0;
-}
-
-static void mv_postreset(struct ata_link *link, unsigned int *classes)
-{
- struct ata_port *ap = link->ap;
- u32 serr;
-
- /* print link status */
- sata_print_link_status(link);
-
- /* clear SError */
- sata_scr_read(link, SCR_ERROR, &serr);
- sata_scr_write_flush(link, SCR_ERROR, serr);
+ mv_reset_channel(hpriv, mmio, ap->port_no);
+ pp->pp_flags &= ~MV_PP_FLAG_EDMA_EN;
- /* bail out if no device is present */
- if (classes[0] == ATA_DEV_NONE && classes[1] == ATA_DEV_NONE) {
- DPRINTK("EXIT, no device\n");
- return;
- }
+ /* Workaround for errata FEr SATA#10 (part 2) */
+ do {
+ const unsigned long *timing =
+ sata_ehc_deb_timing(&link->eh_context);
- /* set up device control */
- iowrite8(ap->ctl, ap->ioaddr.ctl_addr);
-}
+ rc = sata_link_hardreset(link, timing, deadline + extra,
+ &online, NULL);
+ if (rc)
+ return rc;
+ sata_scr_read(link, SCR_STATUS, &sstatus);
+ if (!IS_GEN_I(hpriv) && ++attempts >= 5 && sstatus == 0x121) {
+ /* Force 1.5gb/s link speed and try again */
+ mv_setup_ifctl(mv_ap_base(ap), 0);
+ if (time_after(jiffies + HZ, deadline))
+ extra = HZ; /* only extend it once, max */
+ }
+ } while (sstatus != 0x0 && sstatus != 0x113 && sstatus != 0x123);
-static void mv_error_handler(struct ata_port *ap)
-{
- ata_do_eh(ap, mv_prereset, ata_std_softreset,
- mv_hardreset, mv_postreset);
+ return rc;
}
static void mv_eh_freeze(struct ata_port *ap)
@@ -2808,19 +2693,6 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx)
hpriv->ops->enable_leds(hpriv, mmio);
for (port = 0; port < host->n_ports; port++) {
- if (IS_GEN_II(hpriv)) {
- void __iomem *port_mmio = mv_port_base(mmio, port);
-
- u32 ifctl = readl(port_mmio + SATA_INTERFACE_CTL);
- ifctl |= (1 << 7); /* enable gen2i speed */
- ifctl = (ifctl & 0xfff) | 0x9b1000; /* from chip spec */
- writelfl(ifctl, port_mmio + SATA_INTERFACE_CTL);
- }
-
- hpriv->ops->phy_errata(hpriv, mmio, port);
- }
-
- for (port = 0; port < host->n_ports; port++) {
struct ata_port *ap = host->ports[port];
void __iomem *port_mmio = mv_port_base(mmio, port);
@@ -3192,7 +3064,7 @@ MODULE_DESCRIPTION("SCSI low-level driver for Marvell SATA controllers");
MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, mv_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-MODULE_ALIAS("platform:sata_mv");
+MODULE_ALIAS("platform:" DRV_NAME);
#ifdef CONFIG_PCI
module_param(msi, int, 0444);
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index ed5473bf7a0a..109b07495721 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -309,7 +309,8 @@ static void nv_nf2_freeze(struct ata_port *ap);
static void nv_nf2_thaw(struct ata_port *ap);
static void nv_ck804_freeze(struct ata_port *ap);
static void nv_ck804_thaw(struct ata_port *ap);
-static void nv_error_handler(struct ata_port *ap);
+static int nv_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
static int nv_adma_slave_config(struct scsi_device *sdev);
static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
@@ -385,157 +386,60 @@ static struct pci_driver nv_pci_driver = {
};
static struct scsi_host_template nv_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
static struct scsi_host_template nv_adma_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .change_queue_depth = ata_scsi_change_queue_depth,
+ ATA_NCQ_SHT(DRV_NAME),
.can_queue = NV_ADMA_MAX_CPBS,
- .this_id = ATA_SHT_THIS_ID,
.sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
.dma_boundary = NV_ADMA_DMA_BOUNDARY,
.slave_configure = nv_adma_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
static struct scsi_host_template nv_swncq_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .change_queue_depth = ata_scsi_change_queue_depth,
+ ATA_NCQ_SHT(DRV_NAME),
.can_queue = ATA_MAX_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
.sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
.slave_configure = nv_swncq_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
-static const struct ata_port_operations nv_generic_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = nv_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_data_xfer,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
+static struct ata_port_operations nv_generic_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .hardreset = nv_hardreset,
.scr_read = nv_scr_read,
.scr_write = nv_scr_write,
- .port_start = ata_port_start,
};
-static const struct ata_port_operations nv_nf2_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
+static struct ata_port_operations nv_nf2_ops = {
+ .inherits = &nv_generic_ops,
.freeze = nv_nf2_freeze,
.thaw = nv_nf2_thaw,
- .error_handler = nv_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_data_xfer,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
- .scr_read = nv_scr_read,
- .scr_write = nv_scr_write,
- .port_start = ata_port_start,
};
-static const struct ata_port_operations nv_ck804_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
+static struct ata_port_operations nv_ck804_ops = {
+ .inherits = &nv_generic_ops,
.freeze = nv_ck804_freeze,
.thaw = nv_ck804_thaw,
- .error_handler = nv_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_data_xfer,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
- .scr_read = nv_scr_read,
- .scr_write = nv_scr_write,
- .port_start = ata_port_start,
.host_stop = nv_ck804_host_stop,
};
-static const struct ata_port_operations nv_adma_ops = {
- .tf_load = ata_tf_load,
- .tf_read = nv_adma_tf_read,
+static struct ata_port_operations nv_adma_ops = {
+ .inherits = &nv_generic_ops,
+
.check_atapi_dma = nv_adma_check_atapi_dma,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
+ .sff_tf_read = nv_adma_tf_read,
.qc_defer = ata_std_qc_defer,
.qc_prep = nv_adma_qc_prep,
.qc_issue = nv_adma_qc_issue,
+ .sff_irq_clear = nv_adma_irq_clear,
+
.freeze = nv_adma_freeze,
.thaw = nv_adma_thaw,
.error_handler = nv_adma_error_handler,
.post_internal_cmd = nv_adma_post_internal_cmd,
- .data_xfer = ata_data_xfer,
- .irq_clear = nv_adma_irq_clear,
- .irq_on = ata_irq_on,
- .scr_read = nv_scr_read,
- .scr_write = nv_scr_write,
+
.port_start = nv_adma_port_start,
.port_stop = nv_adma_port_stop,
#ifdef CONFIG_PM
@@ -545,28 +449,17 @@ static const struct ata_port_operations nv_adma_ops = {
.host_stop = nv_adma_host_stop,
};
-static const struct ata_port_operations nv_swncq_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
+static struct ata_port_operations nv_swncq_ops = {
+ .inherits = &nv_generic_ops,
+
.qc_defer = ata_std_qc_defer,
.qc_prep = nv_swncq_qc_prep,
.qc_issue = nv_swncq_qc_issue,
+
.freeze = nv_mcp55_freeze,
.thaw = nv_mcp55_thaw,
.error_handler = nv_swncq_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .data_xfer = ata_data_xfer,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
- .scr_read = nv_scr_read,
- .scr_write = nv_scr_write,
+
#ifdef CONFIG_PM
.port_suspend = nv_swncq_port_suspend,
.port_resume = nv_swncq_port_resume,
@@ -574,63 +467,61 @@ static const struct ata_port_operations nv_swncq_ops = {
.port_start = nv_swncq_port_start,
};
+struct nv_pi_priv {
+ irq_handler_t irq_handler;
+ struct scsi_host_template *sht;
+};
+
+#define NV_PI_PRIV(_irq_handler, _sht) \
+ &(struct nv_pi_priv){ .irq_handler = _irq_handler, .sht = _sht }
+
static const struct ata_port_info nv_port_info[] = {
/* generic */
{
- .sht = &nv_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
- .link_flags = ATA_LFLAG_HRST_TO_RESUME,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_generic_ops,
- .irq_handler = nv_generic_interrupt,
+ .private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht),
},
/* nforce2/3 */
{
- .sht = &nv_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
- .link_flags = ATA_LFLAG_HRST_TO_RESUME,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_nf2_ops,
- .irq_handler = nv_nf2_interrupt,
+ .private_data = NV_PI_PRIV(nv_nf2_interrupt, &nv_sht),
},
/* ck804 */
{
- .sht = &nv_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
- .link_flags = ATA_LFLAG_HRST_TO_RESUME,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_ck804_ops,
- .irq_handler = nv_ck804_interrupt,
+ .private_data = NV_PI_PRIV(nv_ck804_interrupt, &nv_sht),
},
/* ADMA */
{
- .sht = &nv_adma_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO | ATA_FLAG_NCQ,
- .link_flags = ATA_LFLAG_HRST_TO_RESUME,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_adma_ops,
- .irq_handler = nv_adma_interrupt,
+ .private_data = NV_PI_PRIV(nv_adma_interrupt, &nv_adma_sht),
},
/* SWNCQ */
{
- .sht = &nv_swncq_sht,
.flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_NCQ,
- .link_flags = ATA_LFLAG_HRST_TO_RESUME,
.pio_mask = NV_PIO_MASK,
.mwdma_mask = NV_MWDMA_MASK,
.udma_mask = NV_UDMA_MASK,
.port_ops = &nv_swncq_ops,
- .irq_handler = nv_swncq_interrupt,
+ .private_data = NV_PI_PRIV(nv_swncq_interrupt, &nv_swncq_sht),
},
};
@@ -640,8 +531,8 @@ MODULE_LICENSE("GPL");
MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
MODULE_VERSION(DRV_VERSION);
-static int adma_enabled = 1;
-static int swncq_enabled;
+static int adma_enabled;
+static int swncq_enabled = 1;
static void nv_adma_register_mode(struct ata_port *ap)
{
@@ -839,7 +730,7 @@ static void nv_adma_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
ADMA mode could abort outstanding commands. */
nv_adma_register_mode(ap);
- ata_tf_read(ap, tf);
+ ata_sff_tf_read(ap, tf);
}
static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
@@ -929,7 +820,7 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
"notifier for tag %d with no cmd?\n",
cpb_num);
ehi->err_mask |= AC_ERR_HSM;
- ehi->action |= ATA_EH_SOFTRESET;
+ ehi->action |= ATA_EH_RESET;
ata_port_freeze(ap);
return 1;
}
@@ -953,12 +844,12 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
/* DEV interrupt w/ no active qc? */
if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
- ata_check_status(ap);
+ ata_sff_check_status(ap);
return 1;
}
/* handle interrupt */
- return ata_host_intr(ap, qc);
+ return ata_sff_host_intr(ap, qc);
}
static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
@@ -1137,7 +1028,7 @@ static void nv_adma_irq_clear(struct ata_port *ap)
u32 notifier_clears[2];
if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) {
- ata_bmdma_irq_clear(ap);
+ ata_sff_irq_clear(ap);
return;
}
@@ -1168,7 +1059,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_bmdma_post_internal_cmd(qc);
+ ata_sff_post_internal_cmd(qc);
}
static int nv_adma_port_start(struct ata_port *ap)
@@ -1445,7 +1336,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_qc_prep(qc);
+ ata_sff_qc_prep(qc);
return;
}
@@ -1504,7 +1395,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_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
} else
nv_adma_mode(qc->ap);
@@ -1545,11 +1436,11 @@ 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_host_intr(ap, qc);
+ handled += ata_sff_host_intr(ap, qc);
else
// No request pending? Clear interrupt status
// anyway, in case there's one pending.
- ap->ops->check_status(ap);
+ ap->ops->sff_check_status(ap);
}
}
@@ -1680,7 +1571,7 @@ static void nv_mcp55_freeze(struct ata_port *ap)
mask = readl(mmio_base + NV_INT_ENABLE_MCP55);
mask &= ~(NV_INT_ALL_MCP55 << shift);
writel(mask, mmio_base + NV_INT_ENABLE_MCP55);
- ata_bmdma_freeze(ap);
+ ata_sff_freeze(ap);
}
static void nv_mcp55_thaw(struct ata_port *ap)
@@ -1694,7 +1585,7 @@ static void nv_mcp55_thaw(struct ata_port *ap)
mask = readl(mmio_base + NV_INT_ENABLE_MCP55);
mask |= (NV_INT_MASK_MCP55 << shift);
writel(mask, mmio_base + NV_INT_ENABLE_MCP55);
- ata_bmdma_thaw(ap);
+ ata_sff_thaw(ap);
}
static int nv_hardreset(struct ata_link *link, unsigned int *class,
@@ -1706,13 +1597,7 @@ static int nv_hardreset(struct ata_link *link, unsigned int *class,
* some controllers. Don't classify on hardreset. For more
* info, see http://bugzilla.kernel.org/show_bug.cgi?id=3352
*/
- return sata_std_hardreset(link, &dummy, deadline);
-}
-
-static void nv_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
- nv_hardreset, ata_std_postreset);
+ return sata_sff_hardreset(link, &dummy, deadline);
}
static void nv_adma_error_handler(struct ata_port *ap)
@@ -1768,8 +1653,7 @@ static void nv_adma_error_handler(struct ata_port *ap)
readw(mmio + NV_ADMA_CTL); /* flush posted write */
}
- ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
- nv_hardreset, ata_std_postreset);
+ ata_sff_error_handler(ap);
}
static void nv_swncq_qc_to_dq(struct ata_port *ap, struct ata_queued_cmd *qc)
@@ -1855,7 +1739,7 @@ static void nv_swncq_ncq_stop(struct ata_port *ap)
pp->dhfis_bits, pp->dmafis_bits, pp->sdbfis_bits);
ata_port_printk(ap, KERN_ERR, "ATA_REG 0x%X ERR_REG 0x%X\n",
- ap->ops->check_status(ap),
+ ap->ops->sff_check_status(ap),
ioread8(ap->ioaddr.error_addr));
sactive = readl(pp->sactive_block);
@@ -1881,7 +1765,7 @@ static void nv_swncq_ncq_stop(struct ata_port *ap)
}
nv_swncq_pp_reinit(ap);
- ap->ops->irq_clear(ap);
+ ap->ops->sff_irq_clear(ap);
__ata_bmdma_stop(ap);
nv_swncq_irq_clear(ap, 0xffff);
}
@@ -1892,11 +1776,10 @@ static void nv_swncq_error_handler(struct ata_port *ap)
if (ap->link.sactive) {
nv_swncq_ncq_stop(ap);
- ehc->i.action |= ATA_EH_HARDRESET;
+ ehc->i.action |= ATA_EH_RESET;
}
- ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
- nv_hardreset, ata_std_postreset);
+ ata_sff_error_handler(ap);
}
#ifdef CONFIG_PM
@@ -2042,7 +1925,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_qc_prep(qc);
+ ata_sff_qc_prep(qc);
return;
}
@@ -2104,8 +1987,8 @@ static unsigned int nv_swncq_issue_atacmd(struct ata_port *ap,
pp->dmafis_bits &= ~(1 << qc->tag);
pp->qc_active |= (0x1 << qc->tag);
- ap->ops->tf_load(ap, &qc->tf); /* load tf registers */
- ap->ops->exec_command(ap, &qc->tf);
+ ap->ops->sff_tf_load(ap, &qc->tf); /* load tf registers */
+ ap->ops->sff_exec_command(ap, &qc->tf);
DPRINTK("Issued tag %u\n", qc->tag);
@@ -2118,7 +2001,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_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
DPRINTK("Enter\n");
@@ -2173,11 +2056,11 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
ata_ehi_clear_desc(ehi);
ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
ehi->err_mask |= AC_ERR_HOST_BUS;
- ehi->action |= ATA_EH_SOFTRESET;
+ ehi->action |= ATA_EH_RESET;
return -EINVAL;
}
- ap->ops->irq_clear(ap);
+ ap->ops->sff_irq_clear(ap);
__ata_bmdma_stop(ap);
sactive = readl(pp->sactive_block);
@@ -2188,7 +2071,7 @@ static int nv_swncq_sdbfis(struct ata_port *ap)
ata_ehi_push_desc(ehi, "illegal SWNCQ:qc_active transition"
"(%08x->%08x)", pp->qc_active, sactive);
ehi->err_mask |= AC_ERR_HSM;
- ehi->action |= ATA_EH_HARDRESET;
+ ehi->action |= ATA_EH_RESET;
return -EINVAL;
}
for (i = 0; i < ATA_MAX_QUEUE; i++) {
@@ -2299,7 +2182,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
u8 ata_stat;
int rc = 0;
- ata_stat = ap->ops->check_status(ap);
+ ata_stat = ap->ops->sff_check_status(ap);
nv_swncq_irq_clear(ap, fis);
if (!fis)
return;
@@ -2324,7 +2207,7 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
ata_ehi_push_desc(ehi, "Ata error. fis:0x%X", fis);
ehi->err_mask |= AC_ERR_DEV;
ehi->serror |= serror;
- ehi->action |= ATA_EH_SOFTRESET;
+ ehi->action |= ATA_EH_RESET;
ata_port_freeze(ap);
return;
}
@@ -2356,13 +2239,13 @@ static void nv_swncq_host_interrupt(struct ata_port *ap, u16 fis)
if (pp->ncq_flags & (ncq_saw_sdb | ncq_saw_backout)) {
ata_ehi_push_desc(ehi, "illegal fis transaction");
ehi->err_mask |= AC_ERR_HSM;
- ehi->action |= ATA_EH_HARDRESET;
+ ehi->action |= ATA_EH_RESET;
goto irq_error;
}
if (!(fis & NV_SWNCQ_IRQ_DMASETUP) &&
!(pp->ncq_flags & ncq_saw_dmas)) {
- ata_stat = ap->ops->check_status(ap);
+ ata_stat = ap->ops->sff_check_status(ap);
if (ata_stat & ATA_BUSY)
goto irq_exit;
@@ -2429,6 +2312,7 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
static int printed_version;
const struct ata_port_info *ppi[] = { NULL, NULL };
+ struct nv_pi_priv *ipriv;
struct ata_host *host;
struct nv_host_priv *hpriv;
int rc;
@@ -2465,7 +2349,8 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
ppi[0] = &nv_port_info[type];
- rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
+ ipriv = ppi[0]->private_data;
+ rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
@@ -2503,8 +2388,8 @@ static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
nv_swncq_host_init(host);
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ppi[0]->irq_handler,
- IRQF_SHARED, ppi[0]->sht);
+ return ata_host_activate(host, pdev->irq, ipriv->irq_handler,
+ IRQF_SHARED, ipriv->sht);
}
#ifdef CONFIG_PM
@@ -2600,5 +2485,5 @@ module_exit(nv_exit);
module_param_named(adma, adma_enabled, bool, 0444);
MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: true)");
module_param_named(swncq, swncq_enabled, bool, 0444);
-MODULE_PARM_DESC(swncq, "Enable use of SWNCQ (Default: false)");
+MODULE_PARM_DESC(swncq, "Enable use of SWNCQ (Default: true)");
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 11c1afea2db2..5a10dc5048ad 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -143,103 +143,57 @@ static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile
static int pdc_check_atapi_dma(struct ata_queued_cmd *qc);
static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc);
static void pdc_irq_clear(struct ata_port *ap);
-static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
+static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc);
static void pdc_freeze(struct ata_port *ap);
static void pdc_sata_freeze(struct ata_port *ap);
static void pdc_thaw(struct ata_port *ap);
static void pdc_sata_thaw(struct ata_port *ap);
-static void pdc_pata_error_handler(struct ata_port *ap);
-static void pdc_sata_error_handler(struct ata_port *ap);
+static void pdc_error_handler(struct ata_port *ap);
static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
static int pdc_pata_cable_detect(struct ata_port *ap);
static int pdc_sata_cable_detect(struct ata_port *ap);
static struct scsi_host_template pdc_ata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
+ ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = PDC_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
-static const struct ata_port_operations pdc_sata_ops = {
- .tf_load = pdc_tf_load_mmio,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = pdc_exec_command_mmio,
- .dev_select = ata_std_dev_select,
- .check_atapi_dma = pdc_check_atapi_dma,
+static const struct ata_port_operations pdc_common_ops = {
+ .inherits = &ata_sff_port_ops,
+ .sff_tf_load = pdc_tf_load_mmio,
+ .sff_exec_command = pdc_exec_command_mmio,
+ .check_atapi_dma = pdc_check_atapi_dma,
.qc_prep = pdc_qc_prep,
- .qc_issue = pdc_qc_issue_prot,
- .freeze = pdc_sata_freeze,
- .thaw = pdc_sata_thaw,
- .error_handler = pdc_sata_error_handler,
- .post_internal_cmd = pdc_post_internal_cmd,
- .cable_detect = pdc_sata_cable_detect,
- .data_xfer = ata_data_xfer,
- .irq_clear = pdc_irq_clear,
- .irq_on = ata_irq_on,
+ .qc_issue = pdc_qc_issue,
+ .sff_irq_clear = pdc_irq_clear,
- .scr_read = pdc_sata_scr_read,
- .scr_write = pdc_sata_scr_write,
- .port_start = pdc_sata_port_start,
+ .post_internal_cmd = pdc_post_internal_cmd,
+ .error_handler = pdc_error_handler,
};
-/* First-generation chips need a more restrictive ->check_atapi_dma op */
-static const struct ata_port_operations pdc_old_sata_ops = {
- .tf_load = pdc_tf_load_mmio,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = pdc_exec_command_mmio,
- .dev_select = ata_std_dev_select,
- .check_atapi_dma = pdc_old_sata_check_atapi_dma,
-
- .qc_prep = pdc_qc_prep,
- .qc_issue = pdc_qc_issue_prot,
+static struct ata_port_operations pdc_sata_ops = {
+ .inherits = &pdc_common_ops,
+ .cable_detect = pdc_sata_cable_detect,
.freeze = pdc_sata_freeze,
.thaw = pdc_sata_thaw,
- .error_handler = pdc_sata_error_handler,
- .post_internal_cmd = pdc_post_internal_cmd,
- .cable_detect = pdc_sata_cable_detect,
- .data_xfer = ata_data_xfer,
- .irq_clear = pdc_irq_clear,
- .irq_on = ata_irq_on,
-
.scr_read = pdc_sata_scr_read,
.scr_write = pdc_sata_scr_write,
.port_start = pdc_sata_port_start,
};
-static const struct ata_port_operations pdc_pata_ops = {
- .tf_load = pdc_tf_load_mmio,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = pdc_exec_command_mmio,
- .dev_select = ata_std_dev_select,
- .check_atapi_dma = pdc_check_atapi_dma,
+/* First-generation chips need a more restrictive ->check_atapi_dma op */
+static struct ata_port_operations pdc_old_sata_ops = {
+ .inherits = &pdc_sata_ops,
+ .check_atapi_dma = pdc_old_sata_check_atapi_dma,
+};
- .qc_prep = pdc_qc_prep,
- .qc_issue = pdc_qc_issue_prot,
+static struct ata_port_operations pdc_pata_ops = {
+ .inherits = &pdc_common_ops,
+ .cable_detect = pdc_pata_cable_detect,
.freeze = pdc_freeze,
.thaw = pdc_thaw,
- .error_handler = pdc_pata_error_handler,
- .post_internal_cmd = pdc_post_internal_cmd,
- .cable_detect = pdc_pata_cable_detect,
- .data_xfer = ata_data_xfer,
- .irq_clear = pdc_irq_clear,
- .irq_on = ata_irq_on,
-
.port_start = pdc_common_port_start,
};
@@ -451,7 +405,7 @@ static void pdc_atapi_pkt(struct ata_queued_cmd *qc)
u8 *cdb = qc->cdb;
struct pdc_port_priv *pp = ap->private_data;
u8 *buf = pp->pkt;
- u32 *buf32 = (u32 *) buf;
+ __le32 *buf32 = (__le32 *) buf;
unsigned int dev_sel, feature;
/* set control bits (byte 0), zero delay seq id (byte 3),
@@ -738,24 +692,12 @@ static void pdc_sata_thaw(struct ata_port *ap)
readl(host_mmio + hotplug_offset); /* flush */
}
-static void pdc_common_error_handler(struct ata_port *ap, ata_reset_fn_t hardreset)
+static void pdc_error_handler(struct ata_port *ap)
{
if (!(ap->pflags & ATA_PFLAG_FROZEN))
pdc_reset_port(ap);
- /* perform recovery */
- ata_do_eh(ap, ata_std_prereset, ata_std_softreset, hardreset,
- ata_std_postreset);
-}
-
-static void pdc_pata_error_handler(struct ata_port *ap)
-{
- pdc_common_error_handler(ap, NULL);
-}
-
-static void pdc_sata_error_handler(struct ata_port *ap)
-{
- pdc_common_error_handler(ap, sata_std_hardreset);
+ ata_std_error_handler(ap);
}
static void pdc_post_internal_cmd(struct ata_queued_cmd *qc)
@@ -952,7 +894,7 @@ static inline void pdc_packet_start(struct ata_queued_cmd *qc)
readl(ap->ioaddr.cmd_addr + PDC_PKT_SUBMIT); /* flush */
}
-static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int pdc_qc_issue(struct ata_queued_cmd *qc)
{
switch (qc->tf.protocol) {
case ATAPI_PROT_NODATA:
@@ -972,20 +914,20 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
break;
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON(tf->protocol == ATA_PROT_DMA || tf->protocol == ATAPI_PROT_DMA);
- ata_tf_load(ap, tf);
+ ata_sff_tf_load(ap, tf);
}
static void pdc_exec_command_mmio(struct ata_port *ap,
const struct ata_taskfile *tf)
{
WARN_ON(tf->protocol == ATA_PROT_DMA || tf->protocol == ATAPI_PROT_DMA);
- ata_exec_command(ap, tf);
+ ata_sff_exec_command(ap, tf);
}
static int pdc_check_atapi_dma(struct ata_queued_cmd *qc)
diff --git a/drivers/ata/sata_qstor.c b/drivers/ata/sata_qstor.c
index 91cc12c82040..1600107047cf 100644
--- a/drivers/ata/sata_qstor.c
+++ b/drivers/ata/sata_qstor.c
@@ -121,50 +121,38 @@ 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_irq_clear(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);
static void qs_error_handler(struct ata_port *ap);
static struct scsi_host_template qs_ata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
+ ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = QS_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ENABLE_CLUSTERING,
- .proc_name = DRV_NAME,
.dma_boundary = QS_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
-static const struct ata_port_operations qs_ata_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
+static struct ata_port_operations qs_ata_ops = {
+ .inherits = &ata_sff_port_ops,
+
.check_atapi_dma = qs_check_atapi_dma,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
+ .bmdma_stop = qs_bmdma_stop,
+ .bmdma_status = qs_bmdma_status,
.qc_prep = qs_qc_prep,
.qc_issue = qs_qc_issue,
- .data_xfer = ata_data_xfer,
+
.freeze = qs_freeze,
.thaw = qs_thaw,
+ .prereset = qs_prereset,
+ .softreset = ATA_OP_NULL,
.error_handler = qs_error_handler,
- .irq_clear = qs_irq_clear,
- .irq_on = ata_irq_on,
+ .post_internal_cmd = ATA_OP_NULL,
+
.scr_read = qs_scr_read,
.scr_write = qs_scr_write,
+
.port_start = qs_port_start,
.host_stop = qs_host_stop,
- .bmdma_stop = qs_bmdma_stop,
- .bmdma_status = qs_bmdma_status,
};
static const struct ata_port_info qs_port_info[] = {
@@ -211,11 +199,6 @@ static u8 qs_bmdma_status(struct ata_port *ap)
return 0;
}
-static void qs_irq_clear(struct ata_port *ap)
-{
- /* nothing */
-}
-
static inline void qs_enter_reg_mode(struct ata_port *ap)
{
u8 __iomem *chan = qs_mmio_base(ap->host) + (ap->port_no * 0x4000);
@@ -256,7 +239,7 @@ static int qs_prereset(struct ata_link *link, unsigned long deadline)
struct ata_port *ap = link->ap;
qs_reset_channel_logic(ap);
- return ata_std_prereset(link, deadline);
+ return ata_sff_prereset(link, deadline);
}
static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
@@ -270,8 +253,7 @@ static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
static void qs_error_handler(struct ata_port *ap)
{
qs_enter_reg_mode(ap);
- ata_do_eh(ap, qs_prereset, NULL, sata_std_hardreset,
- ata_std_postreset);
+ ata_std_error_handler(ap);
}
static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
@@ -321,7 +303,7 @@ static void qs_qc_prep(struct ata_queued_cmd *qc)
qs_enter_reg_mode(qc->ap);
if (qc->tf.protocol != ATA_PROT_DMA) {
- ata_qc_prep(qc);
+ ata_sff_qc_prep(qc);
return;
}
@@ -380,7 +362,7 @@ static unsigned int qs_qc_issue(struct ata_queued_cmd *qc)
}
pp->state = qs_state_mmio;
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static void qs_do_or_die(struct ata_queued_cmd *qc, u8 status)
@@ -469,7 +451,7 @@ static inline unsigned int qs_intr_mmio(struct ata_host *host)
* and pretend we knew it was ours.. (ugh).
* This does not affect packet mode.
*/
- ata_check_status(ap);
+ ata_sff_check_status(ap);
handled = 1;
continue;
}
@@ -477,7 +459,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_host_intr(ap, qc);
+ handled |= ata_sff_host_intr(ap, qc);
}
}
return handled;
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index 0b8191b52f97..88bf4212590f 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -60,7 +60,6 @@ enum {
SIL_DFL_PORT_FLAGS = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
ATA_FLAG_MMIO,
- SIL_DFL_LINK_FLAGS = ATA_LFLAG_HRST_TO_RESUME,
/*
* Controller IDs
@@ -168,54 +167,23 @@ static struct pci_driver sil_pci_driver = {
};
static struct scsi_host_template sil_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations sil_ops = {
+static struct ata_port_operations sil_ops = {
+ .inherits = &ata_bmdma_port_ops,
.dev_config = sil_dev_config,
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
.set_mode = sil_set_mode,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
.freeze = sil_freeze,
.thaw = sil_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
.scr_read = sil_scr_read,
.scr_write = sil_scr_write,
- .port_start = ata_port_start,
};
static const struct ata_port_info sil_port_info[] = {
/* sil_3112 */
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE,
- .link_flags = SIL_DFL_LINK_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA5,
@@ -225,7 +193,6 @@ static const struct ata_port_info sil_port_info[] = {
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_MOD15WRITE |
SIL_FLAG_NO_SATA_IRQ,
- .link_flags = SIL_DFL_LINK_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA5,
@@ -234,7 +201,6 @@ static const struct ata_port_info sil_port_info[] = {
/* sil_3512 */
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
- .link_flags = SIL_DFL_LINK_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA5,
@@ -243,7 +209,6 @@ static const struct ata_port_info sil_port_info[] = {
/* sil_3114 */
{
.flags = SIL_DFL_PORT_FLAGS | SIL_FLAG_RERR_ON_DMA_ACT,
- .link_flags = SIL_DFL_LINK_FLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA5,
@@ -404,7 +369,7 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
if (unlikely(!qc || (qc->tf.flags & ATA_TFLAG_POLLING))) {
/* this sometimes happens, just clear IRQ */
- ata_chk_status(ap);
+ ap->ops->sff_check_status(ap);
return;
}
@@ -440,15 +405,15 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
}
/* check main status, clearing INTRQ */
- status = ata_chk_status(ap);
+ status = ap->ops->sff_check_status(ap);
if (unlikely(status & ATA_BUSY))
goto err_hsm;
/* ack bmdma irq events */
- ata_bmdma_irq_clear(ap);
+ ata_sff_irq_clear(ap);
/* kick HSM in the ass */
- ata_hsm_move(ap, qc, status, 0);
+ ata_sff_hsm_move(ap, qc, status, 0);
if (unlikely(qc->err_mask) && ata_is_dma(qc->tf.protocol))
ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2);
@@ -515,8 +480,8 @@ static void sil_thaw(struct ata_port *ap)
u32 tmp;
/* clear IRQ */
- ata_chk_status(ap);
- ata_bmdma_irq_clear(ap);
+ ap->ops->sff_check_status(ap);
+ ata_sff_irq_clear(ap);
/* turn on SATA IRQ if supported */
if (!(ap->flags & SIL_FLAG_NO_SATA_IRQ))
@@ -690,7 +655,7 @@ static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
ioaddr->ctl_addr = mmio_base + sil_port[i].ctl;
ioaddr->bmdma_addr = mmio_base + sil_port[i].bmdma;
ioaddr->scr_addr = mmio_base + sil_port[i].scr;
- ata_std_ports(ioaddr);
+ ata_sff_std_ports(ioaddr);
ata_port_pbar_desc(ap, SIL_MMIO_BAR, -1, "mmio");
ata_port_pbar_desc(ap, SIL_MMIO_BAR, sil_port[i].tf, "tf");
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index df7988df7908..27a110110077 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -254,7 +254,6 @@ enum {
ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
ATA_FLAG_NCQ | ATA_FLAG_ACPI_SATA |
ATA_FLAG_AN | ATA_FLAG_PMP,
- SIL24_COMMON_LFLAGS = ATA_LFLAG_SKIP_D2H_BSY,
SIL24_FLAG_PCIX_IRQ_WOC = (1 << 24), /* IRQ loss errata on PCI-X */
IRQ_STAT_4PORTS = 0xf,
@@ -286,45 +285,45 @@ static struct sil24_cerr_info {
"device error via D2H FIS" },
[PORT_CERR_SDB] = { AC_ERR_DEV, 0,
"device error via SDB FIS" },
- [PORT_CERR_DATA] = { AC_ERR_ATA_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_DATA] = { AC_ERR_ATA_BUS, ATA_EH_RESET,
"error in data FIS" },
- [PORT_CERR_SEND] = { AC_ERR_ATA_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_SEND] = { AC_ERR_ATA_BUS, ATA_EH_RESET,
"failed to transmit command FIS" },
- [PORT_CERR_INCONSISTENT] = { AC_ERR_HSM, ATA_EH_SOFTRESET,
+ [PORT_CERR_INCONSISTENT] = { AC_ERR_HSM, ATA_EH_RESET,
"protocol mismatch" },
- [PORT_CERR_DIRECTION] = { AC_ERR_HSM, ATA_EH_SOFTRESET,
+ [PORT_CERR_DIRECTION] = { AC_ERR_HSM, ATA_EH_RESET,
"data directon mismatch" },
- [PORT_CERR_UNDERRUN] = { AC_ERR_HSM, ATA_EH_SOFTRESET,
+ [PORT_CERR_UNDERRUN] = { AC_ERR_HSM, ATA_EH_RESET,
"ran out of SGEs while writing" },
- [PORT_CERR_OVERRUN] = { AC_ERR_HSM, ATA_EH_SOFTRESET,
+ [PORT_CERR_OVERRUN] = { AC_ERR_HSM, ATA_EH_RESET,
"ran out of SGEs while reading" },
- [PORT_CERR_PKT_PROT] = { AC_ERR_HSM, ATA_EH_SOFTRESET,
+ [PORT_CERR_PKT_PROT] = { AC_ERR_HSM, ATA_EH_RESET,
"invalid data directon for ATAPI CDB" },
- [PORT_CERR_SGT_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_SOFTRESET,
+ [PORT_CERR_SGT_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_RESET,
"SGT not on qword boundary" },
- [PORT_CERR_SGT_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_SGT_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"PCI target abort while fetching SGT" },
- [PORT_CERR_SGT_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_SGT_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"PCI master abort while fetching SGT" },
- [PORT_CERR_SGT_PCIPERR] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_SGT_PCIPERR] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"PCI parity error while fetching SGT" },
- [PORT_CERR_CMD_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_SOFTRESET,
+ [PORT_CERR_CMD_BOUNDARY] = { AC_ERR_SYSTEM, ATA_EH_RESET,
"PRB not on qword boundary" },
- [PORT_CERR_CMD_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_CMD_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"PCI target abort while fetching PRB" },
- [PORT_CERR_CMD_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_CMD_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"PCI master abort while fetching PRB" },
- [PORT_CERR_CMD_PCIPERR] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_CMD_PCIPERR] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"PCI parity error while fetching PRB" },
- [PORT_CERR_XFR_UNDEF] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_XFR_UNDEF] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"undefined error while transferring data" },
- [PORT_CERR_XFR_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_XFR_TGTABRT] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"PCI target abort while transferring data" },
- [PORT_CERR_XFR_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_XFR_MSTABRT] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"PCI master abort while transferring data" },
- [PORT_CERR_XFR_PCIPERR] = { AC_ERR_HOST_BUS, ATA_EH_SOFTRESET,
+ [PORT_CERR_XFR_PCIPERR] = { AC_ERR_HOST_BUS, ATA_EH_RESET,
"PCI parity error while transferring data" },
- [PORT_CERR_SENDSERVICE] = { AC_ERR_HSM, ATA_EH_SOFTRESET,
+ [PORT_CERR_SENDSERVICE] = { AC_ERR_HSM, ATA_EH_RESET,
"FIS received while sending service FIS" },
};
@@ -337,23 +336,26 @@ static struct sil24_cerr_info {
struct sil24_port_priv {
union sil24_cmd_block *cmd_block; /* 32 cmd blocks */
dma_addr_t cmd_block_dma; /* DMA base addr for them */
- struct ata_taskfile tf; /* Cached taskfile registers */
int do_port_rst;
};
static void sil24_dev_config(struct ata_device *dev);
-static u8 sil24_check_status(struct ata_port *ap);
static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val);
static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
-static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
static int sil24_qc_defer(struct ata_queued_cmd *qc);
static void sil24_qc_prep(struct ata_queued_cmd *qc);
static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc);
-static void sil24_irq_clear(struct ata_port *ap);
+static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc);
static void sil24_pmp_attach(struct ata_port *ap);
static void sil24_pmp_detach(struct ata_port *ap);
static void sil24_freeze(struct ata_port *ap);
static void sil24_thaw(struct ata_port *ap);
+static int sil24_softreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+static int sil24_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
+static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline);
static void sil24_error_handler(struct ata_port *ap);
static void sil24_post_internal_cmd(struct ata_queued_cmd *qc);
static int sil24_port_start(struct ata_port *ap);
@@ -386,52 +388,36 @@ static struct pci_driver sil24_pci_driver = {
};
static struct scsi_host_template sil24_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .change_queue_depth = ata_scsi_change_queue_depth,
+ ATA_NCQ_SHT(DRV_NAME),
.can_queue = SIL24_MAX_CMDS,
- .this_id = ATA_SHT_THIS_ID,
.sg_tablesize = SIL24_MAX_SGE,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
-static const struct ata_port_operations sil24_ops = {
- .dev_config = sil24_dev_config,
-
- .check_status = sil24_check_status,
- .check_altstatus = sil24_check_status,
- .dev_select = ata_noop_dev_select,
-
- .tf_read = sil24_tf_read,
+static struct ata_port_operations sil24_ops = {
+ .inherits = &sata_pmp_port_ops,
.qc_defer = sil24_qc_defer,
.qc_prep = sil24_qc_prep,
.qc_issue = sil24_qc_issue,
+ .qc_fill_rtf = sil24_qc_fill_rtf,
- .irq_clear = sil24_irq_clear,
+ .freeze = sil24_freeze,
+ .thaw = sil24_thaw,
+ .softreset = sil24_softreset,
+ .hardreset = sil24_hardreset,
+ .pmp_softreset = sil24_softreset,
+ .pmp_hardreset = sil24_pmp_hardreset,
+ .error_handler = sil24_error_handler,
+ .post_internal_cmd = sil24_post_internal_cmd,
+ .dev_config = sil24_dev_config,
.scr_read = sil24_scr_read,
.scr_write = sil24_scr_write,
-
.pmp_attach = sil24_pmp_attach,
.pmp_detach = sil24_pmp_detach,
- .freeze = sil24_freeze,
- .thaw = sil24_thaw,
- .error_handler = sil24_error_handler,
- .post_internal_cmd = sil24_post_internal_cmd,
-
.port_start = sil24_port_start,
-
#ifdef CONFIG_PM
.port_resume = sil24_port_resume,
#endif
@@ -449,7 +435,6 @@ static const struct ata_port_info sil24_port_info[] = {
{
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(4) |
SIL24_FLAG_PCIX_IRQ_WOC,
- .link_flags = SIL24_COMMON_LFLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA5, /* udma0-5 */
@@ -458,7 +443,6 @@ static const struct ata_port_info sil24_port_info[] = {
/* sil_3132 */
{
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(2),
- .link_flags = SIL24_COMMON_LFLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA5, /* udma0-5 */
@@ -467,7 +451,6 @@ static const struct ata_port_info sil24_port_info[] = {
/* sil_3131/sil_3531 */
{
.flags = SIL24_COMMON_FLAGS | SIL24_NPORTS2FLAG(1),
- .link_flags = SIL24_COMMON_LFLAGS,
.pio_mask = 0x1f, /* pio0-4 */
.mwdma_mask = 0x07, /* mwdma0-2 */
.udma_mask = ATA_UDMA5, /* udma0-5 */
@@ -482,9 +465,19 @@ static int sil24_tag(int tag)
return tag;
}
+static unsigned long sil24_port_offset(struct ata_port *ap)
+{
+ return ap->port_no * PORT_REGS_SIZE;
+}
+
+static void __iomem *sil24_port_base(struct ata_port *ap)
+{
+ return ap->host->iomap[SIL24_PORT_BAR] + sil24_port_offset(ap);
+}
+
static void sil24_dev_config(struct ata_device *dev)
{
- void __iomem *port = dev->link->ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(dev->link->ap);
if (dev->cdb_len == 16)
writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
@@ -494,7 +487,7 @@ static void sil24_dev_config(struct ata_device *dev)
static void sil24_read_tf(struct ata_port *ap, int tag, struct ata_taskfile *tf)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
struct sil24_prb __iomem *prb;
u8 fis[6 * 4];
@@ -503,12 +496,6 @@ static void sil24_read_tf(struct ata_port *ap, int tag, struct ata_taskfile *tf)
ata_tf_from_fis(fis, tf);
}
-static u8 sil24_check_status(struct ata_port *ap)
-{
- struct sil24_port_priv *pp = ap->private_data;
- return pp->tf.command;
-}
-
static int sil24_scr_map[] = {
[SCR_CONTROL] = 0,
[SCR_STATUS] = 1,
@@ -518,7 +505,7 @@ static int sil24_scr_map[] = {
static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
{
- void __iomem *scr_addr = ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = sil24_port_base(ap) + PORT_SCONTROL;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr;
@@ -531,7 +518,7 @@ static int sil24_scr_read(struct ata_port *ap, unsigned sc_reg, u32 *val)
static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
{
- void __iomem *scr_addr = ap->ioaddr.scr_addr;
+ void __iomem *scr_addr = sil24_port_base(ap) + PORT_SCONTROL;
if (sc_reg < ARRAY_SIZE(sil24_scr_map)) {
void __iomem *addr;
@@ -542,15 +529,9 @@ static int sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val)
return -EINVAL;
}
-static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
- struct sil24_port_priv *pp = ap->private_data;
- *tf = pp->tf;
-}
-
static void sil24_config_port(struct ata_port *ap)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
/* configure IRQ WoC */
if (ap->flags & SIL24_FLAG_PCIX_IRQ_WOC)
@@ -575,7 +556,7 @@ static void sil24_config_port(struct ata_port *ap)
static void sil24_config_pmp(struct ata_port *ap, int attached)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
if (attached)
writel(PORT_CS_PMP_EN, port + PORT_CTRL_STAT);
@@ -585,7 +566,7 @@ static void sil24_config_pmp(struct ata_port *ap, int attached)
static void sil24_clear_pmp(struct ata_port *ap)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
int i;
writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_CLR);
@@ -600,12 +581,12 @@ static void sil24_clear_pmp(struct ata_port *ap)
static int sil24_init_port(struct ata_port *ap)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
struct sil24_port_priv *pp = ap->private_data;
u32 tmp;
/* clear PMP error status */
- if (ap->nr_pmp_links)
+ if (sata_pmp_attached(ap))
sil24_clear_pmp(ap);
writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
@@ -616,7 +597,7 @@ static int sil24_init_port(struct ata_port *ap)
if ((tmp & (PORT_CS_INIT | PORT_CS_RDY)) != PORT_CS_RDY) {
pp->do_port_rst = 1;
- ap->link.eh_context.i.action |= ATA_EH_HARDRESET;
+ ap->link.eh_context.i.action |= ATA_EH_RESET;
return -EIO;
}
@@ -628,7 +609,7 @@ static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp,
int is_cmd, u32 ctrl,
unsigned long timeout_msec)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
struct sil24_port_priv *pp = ap->private_data;
struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
dma_addr_t paddr = pp->cmd_block_dma;
@@ -670,10 +651,11 @@ static int sil24_exec_polled_cmd(struct ata_port *ap, int pmp,
return rc;
}
-static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
- int pmp, unsigned long deadline)
+static int sil24_softreset(struct ata_link *link, unsigned int *class,
+ unsigned long deadline)
{
struct ata_port *ap = link->ap;
+ int pmp = sata_srst_pmp(link);
unsigned long timeout_msec = 0;
struct ata_taskfile tf;
const char *reason;
@@ -681,12 +663,6 @@ static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
DPRINTK("ENTER\n");
- if (ata_link_offline(link)) {
- DPRINTK("PHY reports no device\n");
- *class = ATA_DEV_NONE;
- goto out;
- }
-
/* put the port into known state */
if (sil24_init_port(ap)) {
reason = "port not ready";
@@ -711,10 +687,6 @@ static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
sil24_read_tf(ap, 0, &tf);
*class = ata_dev_classify(&tf);
- if (*class == ATA_DEV_UNKNOWN)
- *class = ATA_DEV_NONE;
-
- out:
DPRINTK("EXIT, class=%u\n", *class);
return 0;
@@ -723,17 +695,11 @@ static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
return -EIO;
}
-static int sil24_softreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
-{
- return sil24_do_softreset(link, class, SATA_PMP_CTRL_PORT, deadline);
-}
-
static int sil24_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
struct ata_port *ap = link->ap;
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
struct sil24_port_priv *pp = ap->private_data;
int did_port_rst = 0;
const char *reason;
@@ -911,7 +877,7 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
{
struct ata_port *ap = qc->ap;
struct sil24_port_priv *pp = ap->private_data;
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
unsigned int tag = sil24_tag(qc->tag);
dma_addr_t paddr;
void __iomem *activate;
@@ -925,9 +891,10 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc)
return 0;
}
-static void sil24_irq_clear(struct ata_port *ap)
+static bool sil24_qc_fill_rtf(struct ata_queued_cmd *qc)
{
- /* unused */
+ sil24_read_tf(qc->ap, qc->tag, &qc->result_tf);
+ return true;
}
static void sil24_pmp_attach(struct ata_port *ap)
@@ -942,12 +909,6 @@ static void sil24_pmp_detach(struct ata_port *ap)
sil24_config_pmp(ap, 0);
}
-static int sil24_pmp_softreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline)
-{
- return sil24_do_softreset(link, class, link->pmp, deadline);
-}
-
static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
unsigned long deadline)
{
@@ -960,12 +921,12 @@ static int sil24_pmp_hardreset(struct ata_link *link, unsigned int *class,
return rc;
}
- return sata_pmp_std_hardreset(link, class, deadline);
+ return sata_std_hardreset(link, class, deadline);
}
static void sil24_freeze(struct ata_port *ap)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
/* Port-wide IRQ mask in HOST_CTRL doesn't really work, clear
* PORT_IRQ_ENABLE instead.
@@ -975,7 +936,7 @@ static void sil24_freeze(struct ata_port *ap)
static void sil24_thaw(struct ata_port *ap)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
u32 tmp;
/* clear IRQ */
@@ -988,7 +949,7 @@ static void sil24_thaw(struct ata_port *ap)
static void sil24_error_intr(struct ata_port *ap)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
struct sil24_port_priv *pp = ap->private_data;
struct ata_queued_cmd *qc = NULL;
struct ata_link *link;
@@ -1022,7 +983,7 @@ static void sil24_error_intr(struct ata_port *ap)
if (irq_stat & PORT_IRQ_UNK_FIS) {
ehi->err_mask |= AC_ERR_HSM;
- ehi->action |= ATA_EH_SOFTRESET;
+ ehi->action |= ATA_EH_RESET;
ata_ehi_push_desc(ehi, "unknown FIS");
freeze = 1;
}
@@ -1043,14 +1004,14 @@ static void sil24_error_intr(struct ata_port *ap)
*/
if (ap->nr_active_links >= 3) {
ehi->err_mask |= AC_ERR_OTHER;
- ehi->action |= ATA_EH_HARDRESET;
+ ehi->action |= ATA_EH_RESET;
ata_ehi_push_desc(ehi, "PMP DMA CS errata");
pp->do_port_rst = 1;
freeze = 1;
}
/* find out the offending link and qc */
- if (ap->nr_pmp_links) {
+ if (sata_pmp_attached(ap)) {
context = readl(port + PORT_CONTEXT);
pmp = (context >> 5) & 0xf;
@@ -1064,7 +1025,7 @@ static void sil24_error_intr(struct ata_port *ap)
irq_stat);
} else {
err_mask |= AC_ERR_HSM;
- action |= ATA_EH_HARDRESET;
+ action |= ATA_EH_RESET;
freeze = 1;
}
} else
@@ -1078,28 +1039,27 @@ static void sil24_error_intr(struct ata_port *ap)
if (ci && ci->desc) {
err_mask |= ci->err_mask;
action |= ci->action;
- if (action & ATA_EH_RESET_MASK)
+ if (action & ATA_EH_RESET)
freeze = 1;
ata_ehi_push_desc(ehi, "%s", ci->desc);
} else {
err_mask |= AC_ERR_OTHER;
- action |= ATA_EH_SOFTRESET;
+ action |= ATA_EH_RESET;
freeze = 1;
ata_ehi_push_desc(ehi, "unknown command error %d",
cerr);
}
/* record error info */
- if (qc) {
- sil24_read_tf(ap, qc->tag, &pp->tf);
+ if (qc)
qc->err_mask |= err_mask;
- } else
+ else
ehi->err_mask |= err_mask;
ehi->action |= action;
/* if PMP, resume */
- if (ap->nr_pmp_links)
+ if (sata_pmp_attached(ap))
writel(PORT_CS_PMP_RESUME, port + PORT_CTRL_STAT);
}
@@ -1114,18 +1074,9 @@ static void sil24_error_intr(struct ata_port *ap)
}
}
-static void sil24_finish_qc(struct ata_queued_cmd *qc)
-{
- struct ata_port *ap = qc->ap;
- struct sil24_port_priv *pp = ap->private_data;
-
- if (qc->flags & ATA_QCFLAG_RESULT_TF)
- sil24_read_tf(ap, qc->tag, &pp->tf);
-}
-
static inline void sil24_host_intr(struct ata_port *ap)
{
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
u32 slot_stat, qc_active;
int rc;
@@ -1147,13 +1098,13 @@ static inline void sil24_host_intr(struct ata_port *ap)
}
qc_active = slot_stat & ~HOST_SSTAT_ATTN;
- rc = ata_qc_complete_multiple(ap, qc_active, sil24_finish_qc);
+ rc = ata_qc_complete_multiple(ap, qc_active);
if (rc > 0)
return;
if (rc < 0) {
struct ata_eh_info *ehi = &ap->link.eh_info;
ehi->err_mask |= AC_ERR_HSM;
- ehi->action |= ATA_EH_SOFTRESET;
+ ehi->action |= ATA_EH_RESET;
ata_port_freeze(ap);
return;
}
@@ -1209,11 +1160,7 @@ static void sil24_error_handler(struct ata_port *ap)
if (sil24_init_port(ap))
ata_eh_freeze_port(ap);
- /* perform recovery */
- sata_pmp_do_eh(ap, ata_std_prereset, sil24_softreset, sil24_hardreset,
- ata_std_postreset, sata_pmp_std_prereset,
- sil24_pmp_softreset, sil24_pmp_hardreset,
- sata_pmp_std_postreset);
+ sata_pmp_error_handler(ap);
pp->do_port_rst = 0;
}
@@ -1239,8 +1186,6 @@ static int sil24_port_start(struct ata_port *ap)
if (!pp)
return -ENOMEM;
- pp->tf.command = ATA_DRDY;
-
cb = dmam_alloc_coherent(dev, cb_size, &cb_dma, GFP_KERNEL);
if (!cb)
return -ENOMEM;
@@ -1251,6 +1196,9 @@ static int sil24_port_start(struct ata_port *ap)
ap->private_data = pp;
+ ata_port_pbar_desc(ap, SIL24_HOST_BAR, -1, "host");
+ ata_port_pbar_desc(ap, SIL24_PORT_BAR, sil24_port_offset(ap), "port");
+
return 0;
}
@@ -1269,7 +1217,8 @@ static void sil24_init_controller(struct ata_host *host)
/* init ports */
for (i = 0; i < host->n_ports; i++) {
struct ata_port *ap = host->ports[i];
- void __iomem *port = ap->ioaddr.cmd_addr;
+ void __iomem *port = sil24_port_base(ap);
+
/* Initial PHY setting */
writel(0x20c, port + PORT_PHY_CFG);
@@ -1302,7 +1251,7 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
const struct ata_port_info *ppi[] = { &pi, NULL };
void __iomem * const *iomap;
struct ata_host *host;
- int i, rc;
+ int rc;
u32 tmp;
/* cause link error if sil24_cmd_block is sized wrongly */
@@ -1342,18 +1291,6 @@ static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return -ENOMEM;
host->iomap = iomap;
- for (i = 0; i < host->n_ports; i++) {
- struct ata_port *ap = host->ports[i];
- size_t offset = ap->port_no * PORT_REGS_SIZE;
- void __iomem *port = iomap[SIL24_PORT_BAR] + offset;
-
- host->ports[i]->ioaddr.cmd_addr = port;
- host->ports[i]->ioaddr.scr_addr = port + PORT_SCONTROL;
-
- ata_port_pbar_desc(ap, SIL24_HOST_BAR, -1, "host");
- ata_port_pbar_desc(ap, SIL24_PORT_BAR, offset, "port");
- }
-
/* configure and activate the device */
if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
rc = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index a01260a56432..6b8e45ba32e8 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -86,45 +86,13 @@ static struct pci_driver sis_pci_driver = {
};
static struct scsi_host_template sis_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations sis_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
+static struct ata_port_operations sis_ops = {
+ .inherits = &ata_bmdma_port_ops,
.scr_read = sis_scr_read,
.scr_write = sis_scr_write,
- .port_start = ata_port_start,
};
static const struct ata_port_info sis_port_info = {
@@ -341,7 +309,7 @@ static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
break;
}
- rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
+ rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
@@ -359,8 +327,8 @@ 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_interrupt, IRQF_SHARED,
- &sis_sht);
+ return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ IRQF_SHARED, &sis_sht);
}
static int __init sis_init(void)
diff --git a/drivers/ata/sata_svw.c b/drivers/ata/sata_svw.c
index 019e367b59fc..16aa6839aa5a 100644
--- a/drivers/ata/sata_svw.c
+++ b/drivers/ata/sata_svw.c
@@ -233,7 +233,7 @@ static void k2_bmdma_setup_mmio(struct ata_queued_cmd *qc)
/* issue r/w command if this is not a ATA DMA command*/
if (qc->tf.protocol != ATA_PROT_DMA)
- ap->ops->exec_command(ap, &qc->tf);
+ ap->ops->sff_exec_command(ap, &qc->tf);
}
/**
@@ -269,7 +269,7 @@ static void k2_bmdma_start_mmio(struct ata_queued_cmd *qc)
and the start command. */
/* issue r/w command if the access is to ATA*/
if (qc->tf.protocol == ATA_PROT_DMA)
- ap->ops->exec_command(ap, &qc->tf);
+ ap->ops->sff_exec_command(ap, &qc->tf);
}
@@ -327,50 +327,23 @@ static int k2_sata_proc_info(struct Scsi_Host *shost, char *page, char **start,
static struct scsi_host_template k2_sata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
+ ATA_BMDMA_SHT(DRV_NAME),
#ifdef CONFIG_PPC_OF
.proc_info = k2_sata_proc_info,
#endif
- .bios_param = ata_std_bios_param,
};
-static const struct ata_port_operations k2_sata_ops = {
- .tf_load = k2_sata_tf_load,
- .tf_read = k2_sata_tf_read,
- .check_status = k2_stat_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
+static struct ata_port_operations k2_sata_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .sff_tf_load = k2_sata_tf_load,
+ .sff_tf_read = k2_sata_tf_read,
+ .sff_check_status = k2_stat_check_status,
.check_atapi_dma = k2_sata_check_atapi_dma,
.bmdma_setup = k2_bmdma_setup_mmio,
.bmdma_start = k2_bmdma_start_mmio,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
.scr_read = k2_sata_scr_read,
.scr_write = k2_sata_scr_write,
- .port_start = ata_port_start,
};
static const struct ata_port_info k2_port_info[] = {
@@ -519,8 +492,8 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
writel(0x0, mmio_base + K2_SATA_SIM_OFFSET);
pci_set_master(pdev);
- return ata_host_activate(host, pdev->irq, ata_interrupt, IRQF_SHARED,
- &k2_sata_sht);
+ return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ IRQF_SHARED, &k2_sata_sht);
}
/* 0x240 is device ID for Apple K2 device
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c
index e3d56bc6726d..ec04b8d3c791 100644
--- a/drivers/ata/sata_sx4.c
+++ b/drivers/ata/sata_sx4.c
@@ -232,40 +232,30 @@ static void pdc20621_get_from_dimm(struct ata_host *host,
static void pdc20621_put_to_dimm(struct ata_host *host,
void *psource, u32 offset, u32 size);
static void pdc20621_irq_clear(struct ata_port *ap);
-static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc);
+static unsigned int pdc20621_qc_issue(struct ata_queued_cmd *qc);
static struct scsi_host_template pdc_sata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
+ ATA_BASE_SHT(DRV_NAME),
.sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
.dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
};
-static const struct ata_port_operations pdc_20621_ops = {
- .tf_load = pdc_tf_load_mmio,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = pdc_exec_command_mmio,
- .dev_select = ata_std_dev_select,
+/* TODO: inherit from base port_ops after converting to new EH */
+static struct ata_port_operations pdc_20621_ops = {
+ .sff_tf_load = pdc_tf_load_mmio,
+ .sff_tf_read = ata_sff_tf_read,
+ .sff_check_status = ata_sff_check_status,
+ .sff_exec_command = pdc_exec_command_mmio,
+ .sff_dev_select = ata_sff_dev_select,
.phy_reset = pdc_20621_phy_reset,
.qc_prep = pdc20621_qc_prep,
- .qc_issue = pdc20621_qc_issue_prot,
- .data_xfer = ata_data_xfer,
+ .qc_issue = pdc20621_qc_issue,
+ .qc_fill_rtf = ata_sff_qc_fill_rtf,
+ .sff_data_xfer = ata_sff_data_xfer,
.eng_timeout = pdc_eng_timeout,
- .irq_clear = pdc20621_irq_clear,
- .irq_on = ata_irq_on,
+ .sff_irq_clear = pdc20621_irq_clear,
+ .sff_irq_on = ata_sff_irq_on,
.port_start = pdc_port_start,
};
@@ -475,7 +465,7 @@ static void pdc20621_dma_prep(struct ata_queued_cmd *qc)
void __iomem *dimm_mmio = ap->host->iomap[PDC_DIMM_BAR];
unsigned int portno = ap->port_no;
unsigned int i, si, idx, total_len = 0, sgt_len;
- u32 *buf = (u32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
+ __le32 *buf = (__le32 *) &pp->dimm_buf[PDC_DIMM_HEADER_SZ];
WARN_ON(!(qc->flags & ATA_QCFLAG_DMAMAP));
@@ -693,7 +683,7 @@ static void pdc20621_packet_start(struct ata_queued_cmd *qc)
}
}
-static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc)
+static unsigned int pdc20621_qc_issue(struct ata_queued_cmd *qc)
{
switch (qc->tf.protocol) {
case ATA_PROT_DMA:
@@ -709,7 +699,7 @@ static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc)
break;
}
- return ata_qc_issue_prot(qc);
+ return ata_sff_qc_issue(qc);
}
static inline unsigned int pdc20621_host_intr(struct ata_port *ap,
@@ -781,7 +771,7 @@ static inline unsigned int pdc20621_host_intr(struct ata_port *ap,
/* command completion, but no data xfer */
} else if (qc->tf.protocol == ATA_PROT_NODATA) {
- status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+ status = ata_sff_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
DPRINTK("BUS_NODATA (drv_stat 0x%X)\n", status);
qc->err_mask |= ac_err_mask(status);
ata_qc_complete(qc);
@@ -890,7 +880,7 @@ static void pdc_eng_timeout(struct ata_port *ap)
break;
default:
- drv_stat = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+ drv_stat = ata_sff_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
ata_port_printk(ap, KERN_ERR,
"unknown timeout, cmd 0x%x stat 0x%x\n",
@@ -909,7 +899,7 @@ static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
{
WARN_ON(tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
- ata_tf_load(ap, tf);
+ ata_sff_tf_load(ap, tf);
}
@@ -917,7 +907,7 @@ static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile
{
WARN_ON(tf->protocol == ATA_PROT_DMA ||
tf->protocol == ATA_PROT_NODATA);
- ata_exec_command(ap, tf);
+ ata_sff_exec_command(ap, tf);
}
diff --git a/drivers/ata/sata_uli.c b/drivers/ata/sata_uli.c
index e710e71b7b92..f277cea904ce 100644
--- a/drivers/ata/sata_uli.c
+++ b/drivers/ata/sata_uli.c
@@ -76,50 +76,13 @@ static struct pci_driver uli_pci_driver = {
};
static struct scsi_host_template uli_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations uli_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
+static struct ata_port_operations uli_ops = {
+ .inherits = &ata_bmdma_port_ops,
.scr_read = uli_scr_read,
.scr_write = uli_scr_write,
-
- .port_start = ata_port_start,
};
static const struct ata_port_info uli_port_info = {
@@ -212,11 +175,11 @@ static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
host->private_data = hpriv;
/* the first two ports are standard SFF */
- rc = ata_pci_init_sff_host(host);
+ rc = ata_pci_sff_init_host(host);
if (rc)
return rc;
- rc = ata_pci_init_bmdma(host);
+ rc = ata_pci_bmdma_init(host);
if (rc)
return rc;
@@ -237,7 +200,7 @@ static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
((unsigned long)iomap[1] | ATA_PCI_CTL_OFS) + 4;
ioaddr->bmdma_addr = iomap[4] + 16;
hpriv->scr_cfg_addr[2] = ULI5287_BASE + ULI5287_OFFS*4;
- ata_std_ports(ioaddr);
+ ata_sff_std_ports(ioaddr);
ata_port_desc(host->ports[2],
"cmd 0x%llx ctl 0x%llx bmdma 0x%llx",
@@ -252,7 +215,7 @@ static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
((unsigned long)iomap[3] | ATA_PCI_CTL_OFS) + 4;
ioaddr->bmdma_addr = iomap[4] + 24;
hpriv->scr_cfg_addr[3] = ULI5287_BASE + ULI5287_OFFS*5;
- ata_std_ports(ioaddr);
+ ata_sff_std_ports(ioaddr);
ata_port_desc(host->ports[2],
"cmd 0x%llx ctl 0x%llx bmdma 0x%llx",
@@ -279,8 +242,8 @@ 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_interrupt, IRQF_SHARED,
- &uli_sht);
+ return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ IRQF_SHARED, &uli_sht);
}
static int __init uli_init(void)
diff --git a/drivers/ata/sata_via.c b/drivers/ata/sata_via.c
index 0d03f44824fb..96deeb354e16 100644
--- a/drivers/ata/sata_via.c
+++ b/drivers/ata/sata_via.c
@@ -71,7 +71,7 @@ static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
static void svia_noop_freeze(struct ata_port *ap);
-static void vt6420_error_handler(struct ata_port *ap);
+static int vt6420_prereset(struct ata_link *link, unsigned long deadline);
static int vt6421_pata_cable_detect(struct ata_port *ap);
static void vt6421_set_pio_mode(struct ata_port *ap, struct ata_device *adev);
static void vt6421_set_dma_mode(struct ata_port *ap, struct ata_device *adev);
@@ -100,110 +100,26 @@ static struct pci_driver svia_pci_driver = {
};
static struct scsi_host_template svia_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations vt6420_sata_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
+static struct ata_port_operations vt6420_sata_ops = {
+ .inherits = &ata_bmdma_port_ops,
.freeze = svia_noop_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = vt6420_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
+ .prereset = vt6420_prereset,
};
-static const struct ata_port_operations vt6421_pata_ops = {
+static struct ata_port_operations vt6421_pata_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .cable_detect = vt6421_pata_cable_detect,
.set_piomode = vt6421_set_pio_mode,
.set_dmamode = vt6421_set_dma_mode,
-
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = vt6421_pata_cable_detect,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
- .port_start = ata_port_start,
};
-static const struct ata_port_operations vt6421_sata_ops = {
- .tf_load = ata_tf_load,
- .tf_read = ata_tf_read,
- .check_status = ata_check_status,
- .exec_command = ata_exec_command,
- .dev_select = ata_std_dev_select,
-
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
-
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
-
- .freeze = ata_bmdma_freeze,
- .thaw = ata_bmdma_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .cable_detect = ata_cable_sata,
-
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
-
+static struct ata_port_operations vt6421_sata_ops = {
+ .inherits = &ata_bmdma_port_ops,
.scr_read = svia_scr_read,
.scr_write = svia_scr_write,
-
- .port_start = ata_port_start,
};
static const struct ata_port_info vt6420_port_info = {
@@ -257,8 +173,8 @@ static void svia_noop_freeze(struct ata_port *ap)
/* Some VIA controllers choke if ATA_NIEN is manipulated in
* certain way. Leave it alone and just clear pending IRQ.
*/
- ata_chk_status(ap);
- ata_bmdma_irq_clear(ap);
+ ap->ops->sff_check_status(ap);
+ ata_sff_irq_clear(ap);
}
/**
@@ -320,23 +236,17 @@ static int vt6420_prereset(struct ata_link *link, unsigned long deadline)
if (!online) {
/* tell EH to bail */
- ehc->i.action &= ~ATA_EH_RESET_MASK;
+ ehc->i.action &= ~ATA_EH_RESET;
return 0;
}
skip_scr:
/* wait for !BSY */
- ata_wait_ready(ap, deadline);
+ ata_sff_wait_ready(link, deadline);
return 0;
}
-static void vt6420_error_handler(struct ata_port *ap)
-{
- ata_bmdma_drive_eh(ap, vt6420_prereset, ata_std_softreset, NULL,
- ata_std_postreset);
-}
-
static int vt6421_pata_cable_detect(struct ata_port *ap)
{
struct pci_dev *pdev = to_pci_dev(ap->host->dev);
@@ -394,7 +304,7 @@ static void vt6421_init_addrs(struct ata_port *ap)
ioaddr->bmdma_addr = bmdma_addr;
ioaddr->scr_addr = vt6421_scr_addr(iomap[5], ap->port_no);
- ata_std_ports(ioaddr);
+ ata_sff_std_ports(ioaddr);
ata_port_pbar_desc(ap, ap->port_no, -1, "port");
ata_port_pbar_desc(ap, 4, ap->port_no * 8, "bmdma");
@@ -406,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_prepare_sff_host(pdev, ppi, &host);
+ rc = ata_pci_sff_prepare_host(pdev, ppi, &host);
if (rc)
return rc;
*r_host = host;
@@ -538,8 +448,8 @@ 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_interrupt, IRQF_SHARED,
- &svia_sht);
+ return ata_host_activate(host, pdev->irq, ata_sff_interrupt,
+ IRQF_SHARED, &svia_sht);
}
static int __init svia_init(void)
diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c
index 95ae3ed24a9d..f3d635c0a2e9 100644
--- a/drivers/ata/sata_vsc.c
+++ b/drivers/ata/sata_vsc.c
@@ -200,7 +200,7 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
struct ata_ioports *ioaddr = &ap->ioaddr;
u16 nsect, lbal, lbam, lbah, feature;
- tf->command = ata_check_status(ap);
+ tf->command = ata_sff_check_status(ap);
tf->device = readw(ioaddr->device_addr);
feature = readw(ioaddr->error_addr);
nsect = readw(ioaddr->nsect_addr);
@@ -243,7 +243,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_host_intr(ap, qc);
+ handled = ata_sff_host_intr(ap, qc);
/* We received an interrupt during a polled command,
* or some other spurious condition. Interrupt reporting
@@ -251,7 +251,7 @@ static void vsc_port_intr(u8 port_status, struct ata_port *ap)
* simply clear the interrupt
*/
if (unlikely(!handled))
- ata_chk_status(ap);
+ ap->ops->sff_check_status(ap);
}
/*
@@ -300,46 +300,18 @@ out:
static struct scsi_host_template vsc_sata_sht = {
- .module = THIS_MODULE,
- .name = DRV_NAME,
- .ioctl = ata_scsi_ioctl,
- .queuecommand = ata_scsi_queuecmd,
- .can_queue = ATA_DEF_QUEUE,
- .this_id = ATA_SHT_THIS_ID,
- .sg_tablesize = LIBATA_MAX_PRD,
- .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
- .emulated = ATA_SHT_EMULATED,
- .use_clustering = ATA_SHT_USE_CLUSTERING,
- .proc_name = DRV_NAME,
- .dma_boundary = ATA_DMA_BOUNDARY,
- .slave_configure = ata_scsi_slave_config,
- .slave_destroy = ata_scsi_slave_destroy,
- .bios_param = ata_std_bios_param,
+ ATA_BMDMA_SHT(DRV_NAME),
};
-static const struct ata_port_operations vsc_sata_ops = {
- .tf_load = vsc_sata_tf_load,
- .tf_read = vsc_sata_tf_read,
- .exec_command = ata_exec_command,
- .check_status = ata_check_status,
- .dev_select = ata_std_dev_select,
- .bmdma_setup = ata_bmdma_setup,
- .bmdma_start = ata_bmdma_start,
- .bmdma_stop = ata_bmdma_stop,
- .bmdma_status = ata_bmdma_status,
- .qc_prep = ata_qc_prep,
- .qc_issue = ata_qc_issue_prot,
- .data_xfer = ata_data_xfer,
+static struct ata_port_operations vsc_sata_ops = {
+ .inherits = &ata_bmdma_port_ops,
+ .sff_tf_load = vsc_sata_tf_load,
+ .sff_tf_read = vsc_sata_tf_read,
.freeze = vsc_freeze,
.thaw = vsc_thaw,
- .error_handler = ata_bmdma_error_handler,
- .post_internal_cmd = ata_bmdma_post_internal_cmd,
- .irq_clear = ata_bmdma_irq_clear,
- .irq_on = ata_irq_on,
.scr_read = vsc_sata_scr_read,
.scr_write = vsc_sata_scr_write,
- .port_start = ata_port_start,
};
static void __devinit vsc_sata_setup_port(struct ata_ioports *port,
diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c
index c72014a3e7d4..65dc18dea845 100644
--- a/drivers/scsi/ipr.c
+++ b/drivers/scsi/ipr.c
@@ -3937,7 +3937,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd * scsi_cmd)
if (ipr_is_gata(res) && res->sata_port) {
ap = res->sata_port->ap;
spin_unlock_irq(scsi_cmd->device->host->host_lock);
- ata_do_eh(ap, NULL, NULL, ipr_sata_reset, NULL);
+ ata_std_error_handler(ap);
spin_lock_irq(scsi_cmd->device->host->host_lock);
list_for_each_entry(ipr_cmd, &ioa_cfg->pending_q, queue) {
@@ -5041,33 +5041,6 @@ static void ipr_ata_post_internal(struct ata_queued_cmd *qc)
}
/**
- * ipr_tf_read - Read the current ATA taskfile for the ATA port
- * @ap: ATA port
- * @tf: destination ATA taskfile
- *
- * Return value:
- * none
- **/
-static void ipr_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
- struct ipr_sata_port *sata_port = ap->private_data;
- struct ipr_ioasa_gata *g = &sata_port->ioasa;
-
- tf->feature = g->error;
- tf->nsect = g->nsect;
- tf->lbal = g->lbal;
- tf->lbam = g->lbam;
- tf->lbah = g->lbah;
- tf->device = g->device;
- tf->command = g->status;
- tf->hob_nsect = g->hob_nsect;
- tf->hob_lbal = g->hob_lbal;
- tf->hob_lbam = g->hob_lbam;
- tf->hob_lbah = g->hob_lbah;
- tf->ctl = g->alt_status;
-}
-
-/**
* ipr_copy_sata_tf - Copy a SATA taskfile to an IOA data structure
* @regs: destination
* @tf: source ATA taskfile
@@ -5245,40 +5218,41 @@ static unsigned int ipr_qc_issue(struct ata_queued_cmd *qc)
}
/**
- * ipr_ata_check_status - Return last ATA status
- * @ap: ATA port
+ * ipr_qc_fill_rtf - Read result TF
+ * @qc: ATA queued command
*
* Return value:
- * ATA status
+ * true
**/
-static u8 ipr_ata_check_status(struct ata_port *ap)
+static bool ipr_qc_fill_rtf(struct ata_queued_cmd *qc)
{
- struct ipr_sata_port *sata_port = ap->private_data;
- return sata_port->ioasa.status;
-}
+ struct ipr_sata_port *sata_port = qc->ap->private_data;
+ struct ipr_ioasa_gata *g = &sata_port->ioasa;
+ struct ata_taskfile *tf = &qc->result_tf;
-/**
- * ipr_ata_check_altstatus - Return last ATA altstatus
- * @ap: ATA port
- *
- * Return value:
- * Alt ATA status
- **/
-static u8 ipr_ata_check_altstatus(struct ata_port *ap)
-{
- struct ipr_sata_port *sata_port = ap->private_data;
- return sata_port->ioasa.alt_status;
+ tf->feature = g->error;
+ tf->nsect = g->nsect;
+ tf->lbal = g->lbal;
+ tf->lbam = g->lbam;
+ tf->lbah = g->lbah;
+ tf->device = g->device;
+ tf->command = g->status;
+ tf->hob_nsect = g->hob_nsect;
+ tf->hob_lbal = g->hob_lbal;
+ tf->hob_lbam = g->hob_lbam;
+ tf->hob_lbah = g->hob_lbah;
+ tf->ctl = g->alt_status;
+
+ return true;
}
static struct ata_port_operations ipr_sata_ops = {
- .check_status = ipr_ata_check_status,
- .check_altstatus = ipr_ata_check_altstatus,
- .dev_select = ata_noop_dev_select,
.phy_reset = ipr_ata_phy_reset,
+ .hardreset = ipr_sata_reset,
.post_internal_cmd = ipr_ata_post_internal,
- .tf_read = ipr_tf_read,
.qc_prep = ata_noop_qc_prep,
.qc_issue = ipr_qc_issue,
+ .qc_fill_rtf = ipr_qc_fill_rtf,
.port_start = ata_sas_port_start,
.port_stop = ata_sas_port_stop
};
diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
index b0e5ac372a32..a4811e4106df 100644
--- a/drivers/scsi/libsas/sas_ata.c
+++ b/drivers/scsi/libsas/sas_ata.c
@@ -225,10 +225,12 @@ static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc)
return 0;
}
-static u8 sas_ata_check_status(struct ata_port *ap)
+static bool sas_ata_qc_fill_rtf(struct ata_queued_cmd *qc)
{
- struct domain_device *dev = ap->private_data;
- return dev->sata_dev.tf.command;
+ struct domain_device *dev = qc->ap->private_data;
+
+ memcpy(&qc->result_tf, &dev->sata_dev.tf, sizeof(qc->result_tf));
+ return true;
}
static void sas_ata_phy_reset(struct ata_port *ap)
@@ -292,12 +294,6 @@ static void sas_ata_post_internal(struct ata_queued_cmd *qc)
}
}
-static void sas_ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
-{
- struct domain_device *dev = ap->private_data;
- memcpy(tf, &dev->sata_dev.tf, sizeof (*tf));
-}
-
static int sas_ata_scr_write(struct ata_port *ap, unsigned int sc_reg_in,
u32 val)
{
@@ -348,14 +344,11 @@ static int sas_ata_scr_read(struct ata_port *ap, unsigned int sc_reg_in,
}
static struct ata_port_operations sas_sata_ops = {
- .check_status = sas_ata_check_status,
- .check_altstatus = sas_ata_check_status,
- .dev_select = ata_noop_dev_select,
.phy_reset = sas_ata_phy_reset,
.post_internal_cmd = sas_ata_post_internal,
- .tf_read = sas_ata_tf_read,
.qc_prep = ata_noop_qc_prep,
.qc_issue = sas_ata_qc_issue,
+ .qc_fill_rtf = sas_ata_qc_fill_rtf,
.port_start = ata_sas_port_start,
.port_stop = ata_sas_port_stop,
.scr_read = sas_ata_scr_read,
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 37ee881c42ac..165734a2dd47 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -122,6 +122,8 @@ enum {
ATAPI_MAX_DRAIN = 16 << 10,
+ ATA_ALL_DEVICES = (1 << ATA_MAX_DEVICES) - 1,
+
ATA_SHT_EMULATED = 1,
ATA_SHT_CMD_PER_LUN = 1,
ATA_SHT_THIS_ID = -1,
@@ -163,9 +165,6 @@ enum {
ATA_DEV_NONE = 9, /* no device */
/* struct ata_link flags */
- ATA_LFLAG_HRST_TO_RESUME = (1 << 0), /* hardreset to resume link */
- ATA_LFLAG_SKIP_D2H_BSY = (1 << 1), /* can't wait for the first D2H
- * Register FIS clearing BSY */
ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */
ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */
ATA_LFLAG_ASSUME_SEMB = (1 << 4), /* assume SEMB class */
@@ -225,6 +224,7 @@ enum {
ATA_QCFLAG_RESULT_TF = (1 << 4), /* result TF requested */
ATA_QCFLAG_CLEAR_EXCL = (1 << 5), /* clear excl_link on completion */
ATA_QCFLAG_QUIET = (1 << 6), /* don't report device error */
+ ATA_QCFLAG_RETRY = (1 << 7), /* retry after failure */
ATA_QCFLAG_FAILED = (1 << 16), /* cmd failed and is owned by EH */
ATA_QCFLAG_SENSE_VALID = (1 << 17), /* sense data valid */
@@ -249,6 +249,25 @@ enum {
*/
ATA_TMOUT_FF_WAIT = 4 * HZ / 5,
+ /* Spec mandates to wait for ">= 2ms" before checking status
+ * after reset. We wait 150ms, because that was the magic
+ * delay used for ATAPI devices in Hale Landis's ATADRVR, for
+ * the period of time between when the ATA command register is
+ * written, and then status is checked. Because waiting for
+ * "a while" before checking status is fine, post SRST, we
+ * perform this magic delay here as well.
+ *
+ * Old drivers/ide uses the 2mS rule and then waits for ready.
+ */
+ ATA_WAIT_AFTER_RESET_MSECS = 150,
+
+ /* If PMP is supported, we have to do follow-up SRST. As some
+ * PMPs don't send D2H Reg FIS after hardreset, LLDs are
+ * advised to wait only for the following duration before
+ * doing SRST.
+ */
+ ATA_TMOUT_PMP_SRST_WAIT = 1 * HZ,
+
/* ATA bus states */
BUS_UNKNOWN = 0,
BUS_DMA = 1,
@@ -292,17 +311,16 @@ enum {
/* reset / recovery action types */
ATA_EH_REVALIDATE = (1 << 0),
- ATA_EH_SOFTRESET = (1 << 1),
- ATA_EH_HARDRESET = (1 << 2),
+ ATA_EH_SOFTRESET = (1 << 1), /* meaningful only in ->prereset */
+ ATA_EH_HARDRESET = (1 << 2), /* meaningful only in ->prereset */
+ ATA_EH_RESET = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
ATA_EH_ENABLE_LINK = (1 << 3),
ATA_EH_LPM = (1 << 4), /* link power management action */
- ATA_EH_RESET_MASK = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
ATA_EH_PERDEV_MASK = ATA_EH_REVALIDATE,
/* ata_eh_info->flags */
ATA_EHI_HOTPLUGGED = (1 << 0), /* could have been hotplugged */
- ATA_EHI_RESUME_LINK = (1 << 1), /* resume link (reset modifier) */
ATA_EHI_NO_AUTOPSY = (1 << 2), /* no autopsy */
ATA_EHI_QUIET = (1 << 3), /* be quiet */
@@ -313,7 +331,6 @@ enum {
ATA_EHI_POST_SETMODE = (1 << 20), /* revaildating after setmode */
ATA_EHI_DID_RESET = ATA_EHI_DID_SOFTRESET | ATA_EHI_DID_HARDRESET,
- ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
/* max tries if error condition is still set after ->error_handler */
ATA_EH_MAX_TRIES = 5,
@@ -352,6 +369,22 @@ enum {
ATAPI_READ_CD = 2, /* READ CD [MSF] */
ATAPI_PASS_THRU = 3, /* SAT pass-thru */
ATAPI_MISC = 4, /* the rest */
+
+ /* Timing constants */
+ ATA_TIMING_SETUP = (1 << 0),
+ ATA_TIMING_ACT8B = (1 << 1),
+ ATA_TIMING_REC8B = (1 << 2),
+ ATA_TIMING_CYC8B = (1 << 3),
+ ATA_TIMING_8BIT = ATA_TIMING_ACT8B | ATA_TIMING_REC8B |
+ ATA_TIMING_CYC8B,
+ ATA_TIMING_ACTIVE = (1 << 4),
+ ATA_TIMING_RECOVER = (1 << 5),
+ ATA_TIMING_CYCLE = (1 << 6),
+ ATA_TIMING_UDMA = (1 << 7),
+ ATA_TIMING_ALL = ATA_TIMING_SETUP | ATA_TIMING_ACT8B |
+ ATA_TIMING_REC8B | ATA_TIMING_CYC8B |
+ ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER |
+ ATA_TIMING_CYCLE | ATA_TIMING_UDMA,
};
enum ata_xfer_mask {
@@ -412,6 +445,7 @@ enum link_pm {
};
extern struct class_device_attribute class_device_attr_link_power_management_policy;
+#ifdef CONFIG_ATA_SFF
struct ata_ioports {
void __iomem *cmd_addr;
void __iomem *data_addr;
@@ -429,6 +463,7 @@ struct ata_ioports {
void __iomem *bmdma_addr;
void __iomem *scr_addr;
};
+#endif /* CONFIG_ATA_SFF */
struct ata_host {
spinlock_t lock;
@@ -436,7 +471,7 @@ struct ata_host {
void __iomem * const *iomap;
unsigned int n_ports;
void *private_data;
- const struct ata_port_operations *ops;
+ struct ata_port_operations *ops;
unsigned long flags;
#ifdef CONFIG_ATA_ACPI
acpi_handle acpi_handle;
@@ -605,7 +640,7 @@ struct ata_link {
struct ata_port {
struct Scsi_Host *scsi_host; /* our co-allocated scsi host */
- const struct ata_port_operations *ops;
+ struct ata_port_operations *ops;
spinlock_t *lock;
unsigned long flags; /* ATA_FLAG_xxx */
unsigned int pflags; /* ATA_PFLAG_xxx */
@@ -615,7 +650,9 @@ struct ata_port {
struct ata_prd *prd; /* our SG list */
dma_addr_t prd_dma; /* and its DMA mapping */
+#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 */
@@ -667,81 +704,108 @@ struct ata_port {
u8 sector_buf[ATA_SECT_SIZE]; /* owned by EH */
};
-struct ata_port_operations {
- void (*dev_config) (struct ata_device *);
-
- void (*set_piomode) (struct ata_port *, struct ata_device *);
- void (*set_dmamode) (struct ata_port *, struct ata_device *);
- unsigned long (*mode_filter) (struct ata_device *, unsigned long);
-
- void (*tf_load) (struct ata_port *ap, const struct ata_taskfile *tf);
- void (*tf_read) (struct ata_port *ap, struct ata_taskfile *tf);
-
- void (*exec_command)(struct ata_port *ap, const struct ata_taskfile *tf);
- u8 (*check_status)(struct ata_port *ap);
- u8 (*check_altstatus)(struct ata_port *ap);
- void (*dev_select)(struct ata_port *ap, unsigned int device);
-
- void (*phy_reset) (struct ata_port *ap); /* obsolete */
- int (*set_mode) (struct ata_link *link, struct ata_device **r_failed_dev);
-
- int (*cable_detect) (struct ata_port *ap);
-
- int (*check_atapi_dma) (struct ata_queued_cmd *qc);
-
- void (*bmdma_setup) (struct ata_queued_cmd *qc);
- void (*bmdma_start) (struct ata_queued_cmd *qc);
-
- unsigned int (*data_xfer) (struct ata_device *dev, unsigned char *buf,
- unsigned int buflen, int rw);
-
- int (*qc_defer) (struct ata_queued_cmd *qc);
- void (*qc_prep) (struct ata_queued_cmd *qc);
- unsigned int (*qc_issue) (struct ata_queued_cmd *qc);
-
- /* port multiplier */
- void (*pmp_attach) (struct ata_port *ap);
- void (*pmp_detach) (struct ata_port *ap);
+/* The following initializer overrides a method to NULL whether one of
+ * its parent has the method defined or not. This is equivalent to
+ * ERR_PTR(-ENOENT). Unfortunately, ERR_PTR doesn't render a constant
+ * expression and thus can't be used as an initializer.
+ */
+#define ATA_OP_NULL (void *)(unsigned long)(-ENOENT)
- /* Error handlers. ->error_handler overrides ->eng_timeout and
- * indicates that new-style EH is in place.
+struct ata_port_operations {
+ /*
+ * Command execution
*/
- void (*eng_timeout) (struct ata_port *ap); /* obsolete */
-
- void (*freeze) (struct ata_port *ap);
- void (*thaw) (struct ata_port *ap);
- void (*error_handler) (struct ata_port *ap);
- void (*post_internal_cmd) (struct ata_queued_cmd *qc);
-
- irq_handler_t irq_handler;
- void (*irq_clear) (struct ata_port *);
- u8 (*irq_on) (struct ata_port *);
-
- int (*scr_read) (struct ata_port *ap, unsigned int sc_reg, u32 *val);
- int (*scr_write) (struct ata_port *ap, unsigned int sc_reg, u32 val);
+ int (*qc_defer)(struct ata_queued_cmd *qc);
+ int (*check_atapi_dma)(struct ata_queued_cmd *qc);
+ void (*qc_prep)(struct ata_queued_cmd *qc);
+ unsigned int (*qc_issue)(struct ata_queued_cmd *qc);
+ bool (*qc_fill_rtf)(struct ata_queued_cmd *qc);
+
+ /*
+ * Configuration and exception handling
+ */
+ int (*cable_detect)(struct ata_port *ap);
+ unsigned long (*mode_filter)(struct ata_device *dev, unsigned long xfer_mask);
+ void (*set_piomode)(struct ata_port *ap, struct ata_device *dev);
+ void (*set_dmamode)(struct ata_port *ap, struct ata_device *dev);
+ int (*set_mode)(struct ata_link *link, struct ata_device **r_failed_dev);
+
+ void (*dev_config)(struct ata_device *dev);
+
+ void (*freeze)(struct ata_port *ap);
+ void (*thaw)(struct ata_port *ap);
+ ata_prereset_fn_t prereset;
+ ata_reset_fn_t softreset;
+ ata_reset_fn_t hardreset;
+ ata_postreset_fn_t postreset;
+ ata_prereset_fn_t pmp_prereset;
+ ata_reset_fn_t pmp_softreset;
+ ata_reset_fn_t pmp_hardreset;
+ ata_postreset_fn_t pmp_postreset;
+ void (*error_handler)(struct ata_port *ap);
+ void (*post_internal_cmd)(struct ata_queued_cmd *qc);
+
+ /*
+ * Optional features
+ */
+ int (*scr_read)(struct ata_port *ap, unsigned int sc_reg, u32 *val);
+ int (*scr_write)(struct ata_port *ap, unsigned int sc_reg, u32 val);
+ void (*pmp_attach)(struct ata_port *ap);
+ void (*pmp_detach)(struct ata_port *ap);
+ int (*enable_pm)(struct ata_port *ap, enum link_pm policy);
+ void (*disable_pm)(struct ata_port *ap);
+
+ /*
+ * Start, stop, suspend and resume
+ */
+ int (*port_suspend)(struct ata_port *ap, pm_message_t mesg);
+ int (*port_resume)(struct ata_port *ap);
+ int (*port_start)(struct ata_port *ap);
+ void (*port_stop)(struct ata_port *ap);
+ void (*host_stop)(struct ata_host *host);
+
+#ifdef CONFIG_ATA_SFF
+ /*
+ * SFF / taskfile oriented ops
+ */
+ void (*sff_dev_select)(struct ata_port *ap, unsigned int device);
+ u8 (*sff_check_status)(struct ata_port *ap);
+ u8 (*sff_check_altstatus)(struct ata_port *ap);
+ void (*sff_tf_load)(struct ata_port *ap, const struct ata_taskfile *tf);
+ void (*sff_tf_read)(struct ata_port *ap, struct ata_taskfile *tf);
+ void (*sff_exec_command)(struct ata_port *ap,
+ const struct ata_taskfile *tf);
+ unsigned int (*sff_data_xfer)(struct ata_device *dev,
+ unsigned char *buf, unsigned int buflen, int rw);
+ u8 (*sff_irq_on)(struct ata_port *);
+ void (*sff_irq_clear)(struct ata_port *);
- int (*port_suspend) (struct ata_port *ap, pm_message_t mesg);
- int (*port_resume) (struct ata_port *ap);
- int (*enable_pm) (struct ata_port *ap, enum link_pm policy);
- void (*disable_pm) (struct ata_port *ap);
- int (*port_start) (struct ata_port *ap);
- void (*port_stop) (struct ata_port *ap);
+ 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_SFF */
- void (*host_stop) (struct ata_host *host);
+ /*
+ * Obsolete
+ */
+ void (*phy_reset)(struct ata_port *ap);
+ void (*eng_timeout)(struct ata_port *ap);
- void (*bmdma_stop) (struct ata_queued_cmd *qc);
- u8 (*bmdma_status) (struct ata_port *ap);
+ /*
+ * ->inherits must be the last field and all the preceding
+ * fields must be pointers.
+ */
+ const struct ata_port_operations *inherits;
};
struct ata_port_info {
- struct scsi_host_template *sht;
unsigned long flags;
unsigned long link_flags;
unsigned long pio_mask;
unsigned long mwdma_mask;
unsigned long udma_mask;
- const struct ata_port_operations *port_ops;
- irq_handler_t irq_handler;
+ struct ata_port_operations *port_ops;
void *private_data;
};
@@ -759,11 +823,14 @@ struct ata_timing {
#define FIT(v, vmin, vmax) max_t(short, min_t(short, v, vmax), vmin)
+/*
+ * Core layer - drivers/ata/libata-core.c
+ */
extern const unsigned long sata_deb_timing_normal[];
extern const unsigned long sata_deb_timing_hotplug[];
extern const unsigned long sata_deb_timing_long[];
-extern const struct ata_port_operations ata_dummy_port_ops;
+extern struct ata_port_operations ata_dummy_port_ops;
extern const struct ata_port_info ata_dummy_port_info;
static inline const unsigned long *
@@ -782,22 +849,21 @@ static inline int ata_port_is_dummy(struct ata_port *ap)
extern void sata_print_link_status(struct ata_link *link);
extern void ata_port_probe(struct ata_port *);
-extern void ata_bus_reset(struct ata_port *ap);
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,
+ int (*check_ready)(struct ata_link *link));
extern int sata_link_debounce(struct ata_link *link,
const unsigned long *params, unsigned long deadline);
extern int sata_link_resume(struct ata_link *link, const unsigned long *params,
unsigned long deadline);
-extern int ata_std_prereset(struct ata_link *link, unsigned long deadline);
-extern int ata_std_softreset(struct ata_link *link, unsigned int *classes,
- unsigned long deadline);
extern int sata_link_hardreset(struct ata_link *link,
- const unsigned long *timing, unsigned long deadline);
+ const unsigned long *timing, unsigned long deadline,
+ bool *online, int (*check_ready)(struct ata_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 void ata_std_ports(struct ata_ioports *ioaddr);
extern struct ata_host *ata_host_alloc(struct device *dev, int max_ports);
extern struct ata_host *ata_host_alloc_pinfo(struct device *dev,
@@ -810,7 +876,7 @@ extern int ata_host_activate(struct ata_host *host, int irq,
struct scsi_host_template *sht);
extern void ata_host_detach(struct ata_host *host);
extern void ata_host_init(struct ata_host *, struct device *,
- unsigned long, const struct ata_port_operations *);
+ unsigned long, struct ata_port_operations *);
extern int ata_scsi_detect(struct scsi_host_template *sht);
extern int ata_scsi_ioctl(struct scsi_device *dev, int cmd, void __user *arg);
extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *));
@@ -823,7 +889,6 @@ extern void ata_sas_port_stop(struct ata_port *ap);
extern int ata_sas_slave_configure(struct scsi_device *, struct ata_port *);
extern int ata_sas_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *),
struct ata_port *ap);
-extern unsigned int ata_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc);
extern int sata_scr_valid(struct ata_link *link);
extern int sata_scr_read(struct ata_link *link, int reg, u32 *val);
extern int sata_scr_write(struct ata_link *link, int reg, u32 val);
@@ -835,21 +900,9 @@ extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
extern void ata_host_resume(struct ata_host *host);
#endif
extern int ata_ratelimit(void);
-extern int ata_busy_sleep(struct ata_port *ap,
- unsigned long timeout_pat, unsigned long timeout);
-extern void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline);
-extern int ata_wait_ready(struct ata_port *ap, unsigned long deadline);
extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
unsigned long interval_msec,
unsigned long timeout_msec);
-extern unsigned int ata_dev_try_classify(struct ata_device *dev, int present,
- u8 *r_err);
-
-/*
- * Default driver ops implementations
- */
-extern void ata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
-extern void ata_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
extern int atapi_cmd_type(u8 opcode);
extern void ata_tf_to_fis(const struct ata_taskfile *tf,
u8 pmp, int is_cmd, u8 *fis);
@@ -864,23 +917,9 @@ 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 void ata_noop_dev_select(struct ata_port *ap, unsigned int device);
-extern void ata_std_dev_select(struct ata_port *ap, unsigned int device);
-extern u8 ata_check_status(struct ata_port *ap);
-extern u8 ata_altstatus(struct ata_port *ap);
-extern void ata_exec_command(struct ata_port *ap, const struct ata_taskfile *tf);
extern int ata_port_start(struct ata_port *ap);
-extern int ata_sff_port_start(struct ata_port *ap);
-extern irqreturn_t ata_interrupt(int irq, void *dev_instance);
-extern unsigned int ata_data_xfer(struct ata_device *dev,
- unsigned char *buf, unsigned int buflen, int rw);
-extern unsigned int ata_data_xfer_noirq(struct ata_device *dev,
- unsigned char *buf, unsigned int buflen, int rw);
extern int ata_std_qc_defer(struct ata_queued_cmd *qc);
-extern void ata_dumb_qc_prep(struct ata_queued_cmd *qc);
-extern void ata_qc_prep(struct ata_queued_cmd *qc);
extern void ata_noop_qc_prep(struct ata_queued_cmd *qc);
-extern unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc);
extern void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
unsigned int n_elem);
extern unsigned int ata_dev_classify(const struct ata_taskfile *tf);
@@ -889,24 +928,8 @@ extern void ata_id_string(const u16 *id, unsigned char *s,
unsigned int ofs, unsigned int len);
extern void ata_id_c_string(const u16 *id, unsigned char *s,
unsigned int ofs, unsigned int len);
-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_bmdma_irq_clear(struct ata_port *ap);
-extern void ata_bmdma_freeze(struct ata_port *ap);
-extern void ata_bmdma_thaw(struct ata_port *ap);
-extern void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
- ata_reset_fn_t softreset,
- ata_reset_fn_t hardreset,
- ata_postreset_fn_t postreset);
-extern void ata_bmdma_error_handler(struct ata_port *ap);
-extern void ata_bmdma_post_internal_cmd(struct ata_queued_cmd *qc);
-extern int ata_hsm_move(struct ata_port *ap, struct ata_queued_cmd *qc,
- u8 status, int in_wq);
extern void ata_qc_complete(struct ata_queued_cmd *qc);
-extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active,
- void (*finish_qc)(struct ata_queued_cmd *));
+extern int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active);
extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
void (*done)(struct scsi_cmnd *));
extern int ata_std_bios_param(struct scsi_device *sdev,
@@ -918,7 +941,6 @@ extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
int queue_depth);
extern struct ata_device *ata_dev_pair(struct ata_device *adev);
extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
-extern u8 ata_irq_on(struct ata_port *ap);
extern int ata_cable_40wire(struct ata_port *ap);
extern int ata_cable_80wire(struct ata_port *ap);
@@ -926,10 +948,7 @@ extern int ata_cable_sata(struct ata_port *ap);
extern int ata_cable_ignore(struct ata_port *ap);
extern int ata_cable_unknown(struct ata_port *ap);
-/*
- * Timing helpers
- */
-
+/* Timing helpers */
extern unsigned int ata_pio_need_iordy(const struct ata_device *);
extern const struct ata_timing *ata_timing_find_mode(u8 xfer_mode);
extern int ata_timing_compute(struct ata_device *, unsigned short,
@@ -939,24 +958,31 @@ extern void ata_timing_merge(const struct ata_timing *,
unsigned int);
extern u8 ata_timing_cycle2mode(unsigned int xfer_shift, int cycle);
-enum {
- ATA_TIMING_SETUP = (1 << 0),
- ATA_TIMING_ACT8B = (1 << 1),
- ATA_TIMING_REC8B = (1 << 2),
- ATA_TIMING_CYC8B = (1 << 3),
- ATA_TIMING_8BIT = ATA_TIMING_ACT8B | ATA_TIMING_REC8B |
- ATA_TIMING_CYC8B,
- ATA_TIMING_ACTIVE = (1 << 4),
- ATA_TIMING_RECOVER = (1 << 5),
- ATA_TIMING_CYCLE = (1 << 6),
- ATA_TIMING_UDMA = (1 << 7),
- ATA_TIMING_ALL = ATA_TIMING_SETUP | ATA_TIMING_ACT8B |
- ATA_TIMING_REC8B | ATA_TIMING_CYC8B |
- ATA_TIMING_ACTIVE | ATA_TIMING_RECOVER |
- ATA_TIMING_CYCLE | ATA_TIMING_UDMA,
+/* PCI */
+#ifdef CONFIG_PCI
+struct pci_dev;
+
+struct pci_bits {
+ unsigned int reg; /* PCI config register to read */
+ unsigned int width; /* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
+ unsigned long mask;
+ unsigned long val;
};
-/* libata-acpi.c */
+extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
+extern void ata_pci_remove_one(struct pci_dev *pdev);
+
+#ifdef CONFIG_PM
+extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg);
+extern int __must_check ata_pci_device_do_resume(struct pci_dev *pdev);
+extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
+extern int ata_pci_device_resume(struct pci_dev *pdev);
+#endif /* CONFIG_PM */
+#endif /* CONFIG_PCI */
+
+/*
+ * ACPI - drivers/ata/libata-acpi.c
+ */
#ifdef CONFIG_ATA_ACPI
static inline const struct ata_acpi_gtm *ata_acpi_init_gtm(struct ata_port *ap)
{
@@ -1000,56 +1026,8 @@ static inline int ata_acpi_cbl_80wire(struct ata_port *ap,
}
#endif
-#ifdef CONFIG_PCI
-struct pci_dev;
-
-extern int ata_pci_init_one(struct pci_dev *pdev,
- const struct ata_port_info * const * ppi);
-extern void ata_pci_remove_one(struct pci_dev *pdev);
-#ifdef CONFIG_PM
-extern void ata_pci_device_do_suspend(struct pci_dev *pdev, pm_message_t mesg);
-extern int __must_check ata_pci_device_do_resume(struct pci_dev *pdev);
-extern int ata_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
-extern int ata_pci_device_resume(struct pci_dev *pdev);
-#endif
-extern int ata_pci_clear_simplex(struct pci_dev *pdev);
-
-struct pci_bits {
- unsigned int reg; /* PCI config register to read */
- unsigned int width; /* 1 (8 bit), 2 (16 bit), 4 (32 bit) */
- unsigned long mask;
- unsigned long val;
-};
-
-extern int ata_pci_init_sff_host(struct ata_host *host);
-extern int ata_pci_init_bmdma(struct ata_host *host);
-extern int ata_pci_prepare_sff_host(struct pci_dev *pdev,
- const struct ata_port_info * const * ppi,
- struct ata_host **r_host);
-extern int ata_pci_activate_sff_host(struct ata_host *host,
- irq_handler_t irq_handler,
- struct scsi_host_template *sht);
-extern int pci_test_config_bits(struct pci_dev *pdev, const struct pci_bits *bits);
-extern unsigned long ata_pci_default_filter(struct ata_device *dev,
- unsigned long xfer_mask);
-#endif /* CONFIG_PCI */
-
-/*
- * PMP
- */
-extern int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc);
-extern int sata_pmp_std_prereset(struct ata_link *link, unsigned long deadline);
-extern int sata_pmp_std_hardreset(struct ata_link *link, unsigned int *class,
- unsigned long deadline);
-extern void sata_pmp_std_postreset(struct ata_link *link, unsigned int *class);
-extern void sata_pmp_do_eh(struct ata_port *ap,
- ata_prereset_fn_t prereset, ata_reset_fn_t softreset,
- ata_reset_fn_t hardreset, ata_postreset_fn_t postreset,
- ata_prereset_fn_t pmp_prereset, ata_reset_fn_t pmp_softreset,
- ata_reset_fn_t pmp_hardreset, ata_postreset_fn_t pmp_postreset);
-
/*
- * EH
+ * EH - drivers/ata/libata-eh.c
*/
extern void ata_port_schedule_eh(struct ata_port *ap);
extern int ata_link_abort(struct ata_link *link);
@@ -1066,6 +1044,92 @@ extern void ata_eh_qc_retry(struct ata_queued_cmd *qc);
extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
ata_postreset_fn_t postreset);
+extern void ata_std_error_handler(struct ata_port *ap);
+
+/*
+ * Base operations to inherit from and initializers for sht
+ *
+ * Operations
+ *
+ * base : Common to all libata drivers.
+ * sata : SATA controllers w/ native interface.
+ * pmp : SATA controllers w/ PMP support.
+ * sff : SFF ATA controllers w/o BMDMA support.
+ * bmdma : SFF ATA controllers w/ BMDMA support.
+ *
+ * sht initializers
+ *
+ * BASE : Common to all libata drivers. The user must set
+ * sg_tablesize and dma_boundary.
+ * PIO : SFF ATA controllers w/ only PIO support.
+ * BMDMA : SFF ATA controllers w/ BMDMA support. sg_tablesize and
+ * dma_boundary are set to BMDMA limits.
+ * NCQ : SATA controllers supporting NCQ. The user must set
+ * sg_tablesize, dma_boundary and can_queue.
+ */
+extern const struct ata_port_operations ata_base_port_ops;
+extern const struct ata_port_operations sata_port_ops;
+
+#define ATA_BASE_SHT(drv_name) \
+ .module = THIS_MODULE, \
+ .name = drv_name, \
+ .ioctl = ata_scsi_ioctl, \
+ .queuecommand = ata_scsi_queuecmd, \
+ .can_queue = ATA_DEF_QUEUE, \
+ .this_id = ATA_SHT_THIS_ID, \
+ .cmd_per_lun = ATA_SHT_CMD_PER_LUN, \
+ .emulated = ATA_SHT_EMULATED, \
+ .use_clustering = ATA_SHT_USE_CLUSTERING, \
+ .proc_name = drv_name, \
+ .slave_configure = ata_scsi_slave_config, \
+ .slave_destroy = ata_scsi_slave_destroy, \
+ .bios_param = ata_std_bios_param
+
+#define ATA_NCQ_SHT(drv_name) \
+ ATA_BASE_SHT(drv_name), \
+ .change_queue_depth = ata_scsi_change_queue_depth
+
+/*
+ * PMP helpers
+ */
+#ifdef CONFIG_SATA_PMP
+static inline bool sata_pmp_supported(struct ata_port *ap)
+{
+ return ap->flags & ATA_FLAG_PMP;
+}
+
+static inline bool sata_pmp_attached(struct ata_port *ap)
+{
+ return ap->nr_pmp_links != 0;
+}
+
+static inline int ata_is_host_link(const struct ata_link *link)
+{
+ return link == &link->ap->link;
+}
+#else /* CONFIG_SATA_PMP */
+static inline bool sata_pmp_supported(struct ata_port *ap)
+{
+ return false;
+}
+
+static inline bool sata_pmp_attached(struct ata_port *ap)
+{
+ return false;
+}
+
+static inline int ata_is_host_link(const struct ata_link *link)
+{
+ return 1;
+}
+#endif /* CONFIG_SATA_PMP */
+
+static inline int sata_srst_pmp(struct ata_link *link)
+{
+ if (sata_pmp_supported(link->ap) && ata_is_host_link(link))
+ return SATA_PMP_CTRL_PORT;
+ return link->pmp;
+}
/*
* printk helpers
@@ -1074,7 +1138,7 @@ extern void ata_do_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
printk("%sata%u: "fmt, lv, (ap)->print_id , ##args)
#define ata_link_printk(link, lv, fmt, args...) do { \
- if ((link)->ap->nr_pmp_links) \
+ if (sata_pmp_attached((link)->ap)) \
printk("%sata%u.%02u: "fmt, lv, (link)->ap->print_id, \
(link)->pmp , ##args); \
else \
@@ -1094,18 +1158,11 @@ extern void ata_ehi_push_desc(struct ata_eh_info *ehi, const char *fmt, ...)
__attribute__ ((format (printf, 2, 3)));
extern void ata_ehi_clear_desc(struct ata_eh_info *ehi);
-static inline void ata_ehi_schedule_probe(struct ata_eh_info *ehi)
-{
- ehi->flags |= ATA_EHI_RESUME_LINK;
- ehi->action |= ATA_EH_SOFTRESET;
- ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1;
-}
-
static inline void ata_ehi_hotplugged(struct ata_eh_info *ehi)
{
- ata_ehi_schedule_probe(ehi);
+ ehi->probe_mask |= (1 << ATA_MAX_DEVICES) - 1;
ehi->flags |= ATA_EHI_HOTPLUGGED;
- ehi->action |= ATA_EH_ENABLE_LINK;
+ ehi->action |= ATA_EH_RESET | ATA_EH_ENABLE_LINK;
ehi->err_mask |= AC_ERR_ATA_BUS;
}
@@ -1126,7 +1183,7 @@ static inline unsigned int ata_tag_valid(unsigned int tag)
static inline unsigned int ata_tag_internal(unsigned int tag)
{
- return tag == ATA_MAX_QUEUE - 1;
+ return tag == ATA_TAG_INTERNAL;
}
/*
@@ -1167,11 +1224,6 @@ static inline unsigned int ata_dev_absent(const struct ata_device *dev)
/*
* link helpers
*/
-static inline int ata_is_host_link(const struct ata_link *link)
-{
- return link == &link->ap->link;
-}
-
static inline int ata_link_max_devices(const struct ata_link *link)
{
if (ata_is_host_link(link) && link->ap->flags & ATA_FLAG_SLAVE_POSS)
@@ -1186,7 +1238,7 @@ static inline int ata_link_active(struct ata_link *link)
static inline struct ata_link *ata_port_first_link(struct ata_port *ap)
{
- if (ap->nr_pmp_links)
+ if (sata_pmp_attached(ap))
return ap->pmp_link;
return &ap->link;
}
@@ -1195,8 +1247,8 @@ static inline struct ata_link *ata_port_next_link(struct ata_link *link)
{
struct ata_port *ap = link->ap;
- if (link == &ap->link) {
- if (!ap->nr_pmp_links)
+ if (ata_is_host_link(link)) {
+ if (!sata_pmp_attached(ap))
return NULL;
return ap->pmp_link;
}
@@ -1222,11 +1274,6 @@ static inline struct ata_link *ata_port_next_link(struct ata_link *link)
for ((dev) = (link)->device + ata_link_max_devices(link) - 1; \
(dev) >= (link)->device || ((dev) = NULL); (dev)--)
-static inline u8 ata_chk_status(struct ata_port *ap)
-{
- return ap->ops->check_status(ap);
-}
-
/**
* ata_ncq_enabled - Test whether NCQ is enabled
* @dev: ATA device to test for
@@ -1243,74 +1290,6 @@ static inline int ata_ncq_enabled(struct ata_device *dev)
ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ;
}
-/**
- * ata_pause - Flush writes and pause 400 nanoseconds.
- * @ap: Port to wait for.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-static inline void ata_pause(struct ata_port *ap)
-{
- ata_altstatus(ap);
- ndelay(400);
-}
-
-
-/**
- * ata_busy_wait - Wait for a port status register
- * @ap: Port to wait for.
- * @bits: bits that must be clear
- * @max: number of 10uS waits to perform
- *
- * Waits up to max*10 microseconds for the selected bits in the port's
- * status register to be cleared.
- * Returns final value of status register.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
- unsigned int max)
-{
- u8 status;
-
- do {
- udelay(10);
- status = ata_chk_status(ap);
- max--;
- } while (status != 0xff && (status & bits) && (max > 0));
-
- return status;
-}
-
-
-/**
- * ata_wait_idle - Wait for a port to be idle.
- * @ap: Port to wait for.
- *
- * Waits up to 10ms for port's BUSY and DRQ signals to clear.
- * Returns final value of status register.
- *
- * LOCKING:
- * Inherited from caller.
- */
-
-static inline u8 ata_wait_idle(struct ata_port *ap)
-{
- u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
-
-#ifdef ATA_DEBUG
- if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ)))
- ata_port_printk(ap, KERN_DEBUG, "abnormal Status 0x%X\n",
- status);
-#endif
-
- return status;
-}
-
static inline void ata_qc_set_polling(struct ata_queued_cmd *qc)
{
qc->tf.ctl |= ATA_NIEN;
@@ -1403,4 +1382,171 @@ static inline struct ata_port *ata_shost_to_port(struct Scsi_Host *host)
return *(struct ata_port **)&host->hostdata[0];
}
+
+/**************************************************************************
+ * PMP - drivers/ata/libata-pmp.c
+ */
+#ifdef CONFIG_SATA_PMP
+
+extern const struct ata_port_operations sata_pmp_port_ops;
+
+extern int sata_pmp_qc_defer_cmd_switch(struct ata_queued_cmd *qc);
+extern void sata_pmp_error_handler(struct ata_port *ap);
+
+#else /* CONFIG_SATA_PMP */
+
+#define sata_pmp_port_ops sata_port_ops
+#define sata_pmp_qc_defer_cmd_switch ata_std_qc_defer
+#define sata_pmp_error_handler ata_std_error_handler
+
+#endif /* CONFIG_SATA_PMP */
+
+
+/**************************************************************************
+ * SFF - drivers/ata/libata-sff.c
+ */
+#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) \
+ ATA_BASE_SHT(drv_name), \
+ .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_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 u8 ata_sff_altstatus(struct ata_port *ap);
+extern int ata_sff_busy_sleep(struct ata_port *ap,
+ unsigned long timeout_pat, unsigned long timeout);
+extern int ata_sff_wait_ready(struct ata_link *link, unsigned long deadline);
+extern void ata_sff_tf_load(struct ata_port *ap, const struct ata_taskfile *tf);
+extern void ata_sff_tf_read(struct ata_port *ap, struct ata_taskfile *tf);
+extern void ata_sff_exec_command(struct ata_port *ap,
+ const struct ata_taskfile *tf);
+extern unsigned int ata_sff_data_xfer(struct ata_device *dev,
+ unsigned char *buf, unsigned int buflen, int rw);
+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);
+extern bool ata_sff_qc_fill_rtf(struct ata_queued_cmd *qc);
+extern unsigned int ata_sff_host_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);
+extern void ata_sff_thaw(struct ata_port *ap);
+extern int ata_sff_prereset(struct ata_link *link, unsigned long deadline);
+extern unsigned int ata_sff_dev_classify(struct ata_device *dev, int present,
+ u8 *r_err);
+extern int ata_sff_wait_after_reset(struct ata_link *link, unsigned int devmask,
+ unsigned long deadline);
+extern int ata_sff_softreset(struct ata_link *link, unsigned int *classes,
+ unsigned long deadline);
+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 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,
+ struct ata_host **r_host);
+extern int ata_pci_sff_activate_host(struct ata_host *host,
+ irq_handler_t irq_handler,
+ struct scsi_host_template *sht);
+extern int ata_pci_sff_init_one(struct pci_dev *pdev,
+ const struct ata_port_info * const * ppi,
+ struct scsi_host_template *sht, void *host_priv);
+#endif /* CONFIG_PCI */
+
+/**
+ * ata_sff_pause - Flush writes and pause 400 nanoseconds.
+ * @ap: Port to wait for.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static inline void ata_sff_pause(struct ata_port *ap)
+{
+ ata_sff_altstatus(ap);
+ ndelay(400);
+}
+
+/**
+ * ata_sff_busy_wait - Wait for a port status register
+ * @ap: Port to wait for.
+ * @bits: bits that must be clear
+ * @max: number of 10uS waits to perform
+ *
+ * Waits up to max*10 microseconds for the selected bits in the port's
+ * status register to be cleared.
+ * Returns final value of status register.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static inline u8 ata_sff_busy_wait(struct ata_port *ap, unsigned int bits,
+ unsigned int max)
+{
+ u8 status;
+
+ do {
+ udelay(10);
+ status = ap->ops->sff_check_status(ap);
+ max--;
+ } while (status != 0xff && (status & bits) && (max > 0));
+
+ return status;
+}
+
+/**
+ * ata_wait_idle - Wait for a port to be idle.
+ * @ap: Port to wait for.
+ *
+ * Waits up to 10ms for port's BUSY and DRQ signals to clear.
+ * Returns final value of status register.
+ *
+ * LOCKING:
+ * Inherited from caller.
+ */
+static inline u8 ata_wait_idle(struct ata_port *ap)
+{
+ u8 status = ata_sff_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
+
+#ifdef ATA_DEBUG
+ if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ)))
+ ata_port_printk(ap, KERN_DEBUG, "abnormal Status 0x%X\n",
+ status);
+#endif
+
+ return status;
+}
+#endif /* CONFIG_ATA_SFF */
+
#endif /* __LINUX_LIBATA_H__ */