OSDN Git Service

[PATCH] sata_nv: convert to new EH
authorTejun Heo <htejun@gmail.com>
Sat, 17 Jun 2006 06:49:56 +0000 (15:49 +0900)
committerJeff Garzik <jeff@garzik.org>
Tue, 20 Jun 2006 08:59:22 +0000 (04:59 -0400)
Convert to new EH.

Signed-off-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
drivers/scsi/sata_nv.c

index 94cb179..2a1bd85 100644 (file)
@@ -68,6 +68,9 @@ enum {
 
        NV_INT_PORT_SHIFT               = 4,    /* each port occupies 4 bits */
 
+       NV_INT_ALL                      = 0x0f,
+       NV_INT_MASK                     = NV_INT_DEV,
+
        /* INT_CONFIG */
        NV_INT_CONFIG                   = 0x12,
        NV_INT_CONFIG_METHD             = 0x01, // 0 = INT, 1 = SMI
@@ -88,6 +91,12 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance,
 static u32 nv_scr_read (struct ata_port *ap, unsigned int sc_reg);
 static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
 
+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);
+
 enum nv_host_type
 {
        GENERIC,
@@ -166,14 +175,16 @@ static const struct ata_port_operations nv_generic_ops = {
        .exec_command           = ata_exec_command,
        .check_status           = ata_check_status,
        .dev_select             = ata_std_dev_select,
-       .phy_reset              = sata_phy_reset,
        .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,
-       .eng_timeout            = ata_eng_timeout,
+       .freeze                 = ata_bmdma_freeze,
+       .thaw                   = ata_bmdma_thaw,
+       .error_handler          = nv_error_handler,
+       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
        .data_xfer              = ata_pio_data_xfer,
        .irq_handler            = nv_generic_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
@@ -191,14 +202,16 @@ static const struct ata_port_operations nv_nf2_ops = {
        .exec_command           = ata_exec_command,
        .check_status           = ata_check_status,
        .dev_select             = ata_std_dev_select,
-       .phy_reset              = sata_phy_reset,
        .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,
-       .eng_timeout            = ata_eng_timeout,
+       .freeze                 = nv_nf2_freeze,
+       .thaw                   = nv_nf2_thaw,
+       .error_handler          = nv_error_handler,
+       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
        .data_xfer              = ata_pio_data_xfer,
        .irq_handler            = nv_nf2_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
@@ -216,14 +229,16 @@ static const struct ata_port_operations nv_ck804_ops = {
        .exec_command           = ata_exec_command,
        .check_status           = ata_check_status,
        .dev_select             = ata_std_dev_select,
-       .phy_reset              = sata_phy_reset,
        .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,
-       .eng_timeout            = ata_eng_timeout,
+       .freeze                 = nv_ck804_freeze,
+       .thaw                   = nv_ck804_thaw,
+       .error_handler          = nv_error_handler,
+       .post_internal_cmd      = ata_bmdma_post_internal_cmd,
        .data_xfer              = ata_pio_data_xfer,
        .irq_handler            = nv_ck804_interrupt,
        .irq_clear              = ata_bmdma_irq_clear,
@@ -234,22 +249,11 @@ static const struct ata_port_operations nv_ck804_ops = {
        .host_stop              = nv_ck804_host_stop,
 };
 
-/* FIXME: The hardware provides the necessary SATA PHY controls
- * to support ATA_FLAG_SATA_RESET.  However, it is currently
- * necessary to disable that flag, to solve misdetection problems.
- * See http://bugme.osdl.org/show_bug.cgi?id=3352 for more info.
- *
- * This problem really needs to be investigated further.  But in the
- * meantime, we avoid ATA_FLAG_SATA_RESET to get people working.
- */
 static struct ata_port_info nv_port_info[] = {
        /* generic */
        {
                .sht            = &nv_sht,
-               .host_flags     = ATA_FLAG_SATA |
-                                 /* ATA_FLAG_SATA_RESET | */
-                                 ATA_FLAG_SRST |
-                                 ATA_FLAG_NO_LEGACY,
+               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
                .pio_mask       = NV_PIO_MASK,
                .mwdma_mask     = NV_MWDMA_MASK,
                .udma_mask      = NV_UDMA_MASK,
@@ -258,10 +262,7 @@ static struct ata_port_info nv_port_info[] = {
        /* nforce2/3 */
        {
                .sht            = &nv_sht,
-               .host_flags     = ATA_FLAG_SATA |
-                                 /* ATA_FLAG_SATA_RESET | */
-                                 ATA_FLAG_SRST |
-                                 ATA_FLAG_NO_LEGACY,
+               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
                .pio_mask       = NV_PIO_MASK,
                .mwdma_mask     = NV_MWDMA_MASK,
                .udma_mask      = NV_UDMA_MASK,
@@ -270,10 +271,7 @@ static struct ata_port_info nv_port_info[] = {
        /* ck804 */
        {
                .sht            = &nv_sht,
-               .host_flags     = ATA_FLAG_SATA |
-                                 /* ATA_FLAG_SATA_RESET | */
-                                 ATA_FLAG_SRST |
-                                 ATA_FLAG_NO_LEGACY,
+               .host_flags     = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY,
                .pio_mask       = NV_PIO_MASK,
                .mwdma_mask     = NV_MWDMA_MASK,
                .udma_mask      = NV_UDMA_MASK,
@@ -410,6 +408,71 @@ static void nv_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
        iowrite32(val, (void __iomem *)ap->ioaddr.scr_addr + (sc_reg * 4));
 }
 
+static void nv_nf2_freeze(struct ata_port *ap)
+{
+       unsigned long scr_addr = ap->host_set->ports[0]->ioaddr.scr_addr;
+       int shift = ap->port_no * NV_INT_PORT_SHIFT;
+       u8 mask;
+
+       mask = inb(scr_addr + NV_INT_ENABLE);
+       mask &= ~(NV_INT_ALL << shift);
+       outb(mask, scr_addr + NV_INT_ENABLE);
+}
+
+static void nv_nf2_thaw(struct ata_port *ap)
+{
+       unsigned long scr_addr = ap->host_set->ports[0]->ioaddr.scr_addr;
+       int shift = ap->port_no * NV_INT_PORT_SHIFT;
+       u8 mask;
+
+       outb(NV_INT_ALL << shift, scr_addr + NV_INT_STATUS);
+
+       mask = inb(scr_addr + NV_INT_ENABLE);
+       mask |= (NV_INT_MASK << shift);
+       outb(mask, scr_addr + NV_INT_ENABLE);
+}
+
+static void nv_ck804_freeze(struct ata_port *ap)
+{
+       void __iomem *mmio_base = ap->host_set->mmio_base;
+       int shift = ap->port_no * NV_INT_PORT_SHIFT;
+       u8 mask;
+
+       mask = readb(mmio_base + NV_INT_ENABLE_CK804);
+       mask &= ~(NV_INT_ALL << shift);
+       writeb(mask, mmio_base + NV_INT_ENABLE_CK804);
+}
+
+static void nv_ck804_thaw(struct ata_port *ap)
+{
+       void __iomem *mmio_base = ap->host_set->mmio_base;
+       int shift = ap->port_no * NV_INT_PORT_SHIFT;
+       u8 mask;
+
+       writeb(NV_INT_ALL << shift, mmio_base + NV_INT_STATUS_CK804);
+
+       mask = readb(mmio_base + NV_INT_ENABLE_CK804);
+       mask |= (NV_INT_MASK << shift);
+       writeb(mask, mmio_base + NV_INT_ENABLE_CK804);
+}
+
+static int nv_hardreset(struct ata_port *ap, unsigned int *class)
+{
+       unsigned int dummy;
+
+       /* SATA hardreset fails to retrieve proper device signature on
+        * some controllers.  Don't classify on hardreset.  For more
+        * info, see http://bugme.osdl.org/show_bug.cgi?id=3352
+        */
+       return sata_std_hardreset(ap, &dummy);
+}
+
+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);
+}
+
 static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version = 0;