]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/sata_sil24.c
libata: replace tf_read with qc_fill_rtf for non-SFF drivers
[linux-2.6-omap-h63xx.git] / drivers / ata / sata_sil24.c
index b4b1f91ea693942f3292bcdbb885e11405c89376..51a7c06803df58279a0df9249dbfa45a88100ead 100644 (file)
@@ -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" },
 };
 
@@ -345,15 +344,22 @@ 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_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,
-
-       .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,
 
+       .sff_check_status       = sil24_check_status,
+       .sff_check_altstatus    = sil24_check_status,
        .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_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 */
@@ -542,12 +531,6 @@ 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;
@@ -616,7 +599,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,9 +908,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)
@@ -960,7 +944,7 @@ 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)
@@ -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);
@@ -1114,15 +1098,6 @@ 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;
@@ -1147,13 +1122,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 +1184,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;
 }
@@ -1234,7 +1205,6 @@ static int sil24_port_start(struct ata_port *ap)
        union sil24_cmd_block *cb;
        size_t cb_size = sizeof(*cb) * SIL24_MAX_CMDS;
        dma_addr_t cb_dma;
-       int rc;
 
        pp = devm_kzalloc(dev, sizeof(*pp), GFP_KERNEL);
        if (!pp)
@@ -1247,10 +1217,6 @@ static int sil24_port_start(struct ata_port *ap)
                return -ENOMEM;
        memset(cb, 0, cb_size);
 
-       rc = ata_pad_alloc(ap, dev);
-       if (rc)
-               return rc;
-
        pp->cmd_block = cb;
        pp->cmd_block_dma = cb_dma;