diff options
Diffstat (limited to 'drivers/ata')
80 files changed, 4330 insertions, 8460 deletions
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig index 25aba69..292aa9a 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 0511e6f..1fbc2aa 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 b1eb4e2..739ba3f 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 2053420..47aeccd 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 fae8404..b7c38ee 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 bf98a56..8c1cfc6 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 be95fdb..733eb94 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 a583032..d94359a 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 d91f509..ff1822a 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 1579539..f3c69a8 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -2332,11 +2332,7 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq) { cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; - cmd->sense_buffer[0] = 0x70; /* fixed format, current */ - cmd->sense_buffer[2] = sk; - cmd->sense_buffer[7] = 18 - 8; /* additional sense length */ - cmd->sense_buffer[12] = asc; - cmd->sense_buffer[13] = ascq; + scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq); } /** @@ -2393,7 +2389,10 @@ 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 + if (ap->ops->sff_tf_read) + 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 +2614,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 +2631,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 +3489,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 +3506,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 +3515,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 20dc572..1549952 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 aa884f7..4aeeabb 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 bdc3b9d..c5f91e6 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 ce830fe..fcabe46 100644 --- a/drivers/ata/pata_ali.c +++ b/drivers/ata/pata_ali.c @@ -36,7 +36,7 @@ #define DRV_NAME "pata_ali" #define DRV_VERSION "0.7.5" -int ali_atapi_dma = 0; +static int ali_atapi_dma = 0; module_param_named(atapi_dma, ali_atapi_dma, int, 0644); MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)"); @@ -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 4b8d9b59..26665c3 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 d421831..0f513bc 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 db057b1..3e8651d 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 408bdc1..78738fb 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 7f87f10..0a5ad98 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 43d198f..2de30b9 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 &= 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 7acbbd9..ddd09b7 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 7ed279b..1186bcd 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 e1818fd..744beeb 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 0132453..f1b6556 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 1c4ff9b..73f8332 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 fc5f9c4..a9c3218 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 dc33220..9fba829 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 a742efa..f2b83ea 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 9a10878..4216399 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 9f1c084..d5c9fd7 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 cb8bdb6..f11a320 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 f97068b..1713843 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 4320e79..6a111ba 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 e0c2cc2..c113d7c 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 257951d..e108169 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 030878f..8a175f2 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 00bbbbd..73b7596 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 50fe08e..7af4b29 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 a81f25d..24a011b 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 5413ebf..bc79df6 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 c0d9e0c..7d7e3fd 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 25c922a..d9719c8 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 15dd649..565e67c 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 9fe66fd..76d2455 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 d0e2e50..ae92b00 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 44da09a..e678af3 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 8f79447..fb2cf66 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 f9b485a..4cd7444 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 3e7f6a9..3d39f9d 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 511c89b..0e1c2c1 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 3ed8667..d267306 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 aad7adc..6527c56 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 9f308ed..bf45cf0 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 8109b08..1c0d9fa 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 4ce9b03..800ae46 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 ba8a31c..7dfd1f3 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 725a858..cbab397 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 6c016de..e965b25 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 a589c0f..ffd26d0 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 7c5b2dd..720b864 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 dc7e915..e82c66e 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 81ef207..70d94fb 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 403eafc..b181261 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 d119a68..d484074 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 99c92ed..6e52a35 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 8e1b7e9..be53545 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 9d1e3ca..fddd346 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 59e65ed..d27bb9a 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 83584b6..d52ce11 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> @@ -132,7 +134,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 | @@ -142,6 +144,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), @@ -200,7 +203,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), @@ -224,13 +227,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, @@ -241,6 +255,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, @@ -283,7 +299,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 | @@ -299,6 +317,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 | @@ -345,7 +364,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) @@ -465,7 +483,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); @@ -475,7 +492,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); @@ -508,72 +526,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, @@ -582,61 +574,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[] = { @@ -660,6 +615,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, @@ -667,6 +623,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, @@ -674,6 +631,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, @@ -681,16 +639,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, }, }; @@ -789,6 +750,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; @@ -805,10 +774,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) @@ -868,7 +833,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; @@ -889,7 +854,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); @@ -903,58 +868,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 @@ -1078,18 +1027,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 */ @@ -1105,6 +1086,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) { @@ -1160,8 +1148,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); @@ -1194,18 +1180,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: @@ -1224,7 +1198,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); } @@ -1310,6 +1284,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; @@ -1394,14 +1369,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; @@ -1459,12 +1434,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); @@ -1486,10 +1463,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. @@ -1528,14 +1505,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)) { @@ -1559,7 +1536,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; } } @@ -1568,7 +1545,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; @@ -1727,9 +1704,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)) { @@ -1784,7 +1761,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; @@ -1818,6 +1795,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); @@ -1851,14 +1829,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; @@ -1984,9 +1954,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); @@ -2136,6 +2109,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; } @@ -2204,14 +2184,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 */ @@ -2259,9 +2240,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); @@ -2318,25 +2302,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); @@ -2345,136 +2343,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, @@ -2482,43 +2376,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) @@ -2812,19 +2697,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); @@ -3223,7 +3095,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 ed5473b..109b074 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 11c1afe..5a10dc5 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 91cc12c..1600107 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 0b8191b..88bf421 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 df7988d..27a1101 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 a01260a..6b8e45b 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 840d1c4..16aa683 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 @@ -531,8 +504,8 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en * */ static const struct pci_device_id k2_sata_pci_tbl[] = { { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 }, - { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 }, + { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw8 }, + { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw4 }, { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 }, { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 }, { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 }, diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index e3d56bc..ec04b8d 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 e710e71..f277cea 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 0d03f44..96deeb3 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 95ae3ed..f3d635c 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, |