diff options
Diffstat (limited to 'drivers/ata/sata_sil24.c')
-rw-r--r-- | drivers/ata/sata_sil24.c | 116 |
1 files changed, 48 insertions, 68 deletions
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c index df7988df7908..67df1d753305 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" }, }; @@ -349,11 +348,18 @@ 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 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_softreset(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 +392,38 @@ 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, +static struct ata_port_operations sil24_ops = { + .inherits = &sata_pmp_port_ops, .check_status = sil24_check_status, .check_altstatus = sil24_check_status, - .dev_select = ata_noop_dev_select, - .tf_read = sil24_tf_read, - .qc_defer = sil24_qc_defer, .qc_prep = sil24_qc_prep, .qc_issue = sil24_qc_issue, - .irq_clear = sil24_irq_clear, + .freeze = sil24_freeze, + .thaw = sil24_thaw, + .softreset = sil24_softreset, + .hardreset = sil24_hardreset, + .pmp_softreset = sil24_pmp_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 +441,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 +449,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 +457,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 */ @@ -616,7 +605,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; } @@ -925,11 +914,6 @@ static unsigned int sil24_qc_issue(struct ata_queued_cmd *qc) return 0; } -static void sil24_irq_clear(struct ata_port *ap) -{ - /* unused */ -} - static void sil24_pmp_attach(struct ata_port *ap) { sil24_config_pmp(ap, 1); @@ -1022,7 +1006,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,7 +1027,7 @@ 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; @@ -1064,7 +1048,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,12 +1062,12 @@ 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); @@ -1153,7 +1137,7 @@ static inline void sil24_host_intr(struct ata_port *ap) 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 +1193,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; } |