[libata] ARM: add ixp4xx PATA driver
[powerpc.git] / drivers / ata / libata-core.c
index dce6565..f531a89 100644 (file)
@@ -870,7 +870,11 @@ static unsigned int ata_id_xfermask(const u16 *id)
                 * the PIO timing number for the maximum. Turn it into
                 * a mask.
                 */
-               pio_mask = (2 << (id[ATA_ID_OLD_PIO_MODES] & 0xFF)) - 1 ;
+               u8 mode = id[ATA_ID_OLD_PIO_MODES] & 0xFF;
+               if (mode < 5)   /* Valid PIO range */
+                       pio_mask = (2 << mode) - 1;
+               else
+                       pio_mask = 1;
 
                /* But wait.. there's more. Design your standards by
                 * committee and you too can get a free iordy field to
@@ -1341,7 +1345,10 @@ static void ata_dev_config_ncq(struct ata_device *dev,
                desc[0] = '\0';
                return;
        }
-
+       if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) {
+               snprintf(desc, desc_sz, "NCQ (not used)");
+               return;
+       }
        if (ap->flags & ATA_FLAG_NCQ) {
                hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
                dev->flags |= ATA_DFLAG_NCQ;
@@ -1370,7 +1377,6 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
 /**
  *     ata_dev_configure - Configure the specified ATA/ATAPI device
  *     @dev: Target device to configure
- *     @print_info: Enable device info printout
  *
  *     Configure @dev according to @dev->id.  Generic and low-level
  *     driver specific fixups are also applied.
@@ -1381,9 +1387,10 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
  *     RETURNS:
  *     0 on success, -errno otherwise
  */
-int ata_dev_configure(struct ata_device *dev, int print_info)
+int ata_dev_configure(struct ata_device *dev)
 {
        struct ata_port *ap = dev->ap;
+       int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
        const u16 *id = dev->id;
        unsigned int xfer_mask;
        char revbuf[7];         /* XYZ-99\0 */
@@ -1526,6 +1533,11 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
                                       cdb_intr_string);
        }
 
+       /* determine max_sectors */
+       dev->max_sectors = ATA_MAX_SECTORS;
+       if (dev->flags & ATA_DFLAG_LBA48)
+               dev->max_sectors = ATA_MAX_SECTORS_LBA48;
+
        if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
                /* Let the user know. We don't want to disallow opens for
                   rescue purposes, or in case the vendor is just a blithering
@@ -1631,7 +1643,9 @@ int ata_bus_probe(struct ata_port *ap)
                if (rc)
                        goto fail;
 
-               rc = ata_dev_configure(dev, 1);
+               ap->eh_context.i.flags |= ATA_EHI_PRINTINFO;
+               rc = ata_dev_configure(dev);
+               ap->eh_context.i.flags &= ~ATA_EHI_PRINTINFO;
                if (rc)
                        goto fail;
        }
@@ -2149,6 +2163,7 @@ int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0)
 
 static int ata_dev_set_mode(struct ata_device *dev)
 {
+       struct ata_eh_context *ehc = &dev->ap->eh_context;
        unsigned int err_mask;
        int rc;
 
@@ -2163,7 +2178,9 @@ static int ata_dev_set_mode(struct ata_device *dev)
                return -EIO;
        }
 
+       ehc->i.flags |= ATA_EHI_POST_SETMODE;
        rc = ata_dev_revalidate(dev, 0);
+       ehc->i.flags &= ~ATA_EHI_POST_SETMODE;
        if (rc)
                return rc;
 
@@ -2321,11 +2338,14 @@ static inline void ata_tf_to_host(struct ata_port *ap,
  *     Sleep until ATA Status register bit BSY clears,
  *     or a timeout occurs.
  *
- *     LOCKING: None.
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ *
+ *     RETURNS:
+ *     0 on success, -errno otherwise.
  */
-
-unsigned int ata_busy_sleep (struct ata_port *ap,
-                            unsigned long tmout_pat, unsigned long tmout)
+int ata_busy_sleep(struct ata_port *ap,
+                  unsigned long tmout_pat, unsigned long tmout)
 {
        unsigned long timer_start, timeout;
        u8 status;
@@ -2333,27 +2353,32 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
        status = ata_busy_wait(ap, ATA_BUSY, 300);
        timer_start = jiffies;
        timeout = timer_start + tmout_pat;
-       while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) {
+       while (status != 0xff && (status & ATA_BUSY) &&
+              time_before(jiffies, timeout)) {
                msleep(50);
                status = ata_busy_wait(ap, ATA_BUSY, 3);
        }
 
-       if (status & ATA_BUSY)
+       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 & ATA_BUSY) && (time_before(jiffies, timeout))) {
+       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 1;
+               return -EBUSY;
        }
 
        return 0;
@@ -2444,10 +2469,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
         * the bus shows 0xFF because the odd clown forgets the D7
         * pulldown resistor.
         */
-       if (ata_check_status(ap) == 0xFF) {
-               ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n");
-               return AC_ERR_OTHER;
-       }
+       if (ata_check_status(ap) == 0xFF)
+               return 0;
 
        ata_bus_post_reset(ap, devmask);
 
@@ -2773,9 +2796,9 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
 }
 
 /**
- *     sata_std_hardreset - reset host port via SATA phy reset
+ *     sata_port_hardreset - reset port via SATA phy reset
  *     @ap: port to reset
- *     @class: resulting class of attached device
+ *     @timing: timing parameters { interval, duratinon, timeout } in msec
  *
  *     SATA phy-reset host port using DET bits of SControl register.
  *
@@ -2785,10 +2808,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
  *     RETURNS:
  *     0 on success, -errno otherwise.
  */
-int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
+int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
 {
-       struct ata_eh_context *ehc = &ap->eh_context;
-       const unsigned long *timing = sata_ehc_deb_timing(ehc);
        u32 scontrol;
        int rc;
 
@@ -2801,24 +2822,24 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
                 * and Sil3124.
                 */
                if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
-                       return rc;
+                       goto out;
 
                scontrol = (scontrol & 0x0f0) | 0x304;
 
                if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
-                       return rc;
+                       goto out;
 
                sata_set_spd(ap);
        }
 
        /* issue phy wake/reset */
        if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
-               return rc;
+               goto out;
 
        scontrol = (scontrol & 0x0f0) | 0x301;
 
        if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol)))
-               return rc;
+               goto out;
 
        /* Couldn't find anything in SATA I/II specs, but AHCI-1.1
         * 10.4.2 says at least 1 ms.
@@ -2826,7 +2847,40 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
        msleep(1);
 
        /* bring phy back */
-       sata_phy_resume(ap, timing);
+       rc = sata_phy_resume(ap, timing);
+ out:
+       DPRINTK("EXIT, rc=%d\n", rc);
+       return rc;
+}
+
+/**
+ *     sata_std_hardreset - reset host port via SATA phy reset
+ *     @ap: port to reset
+ *     @class: resulting class of attached device
+ *
+ *     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_std_hardreset(struct ata_port *ap, unsigned int *class)
+{
+       const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
+       int rc;
+
+       DPRINTK("ENTER\n");
+
+       /* do hardreset */
+       rc = sata_port_hardreset(ap, timing);
+       if (rc) {
+               ata_port_printk(ap, KERN_ERR,
+                               "COMRESET failed (errno=%d)\n", rc);
+               return rc;
+       }
 
        /* TODO: phy layer with polling, timeouts, etc. */
        if (ata_port_offline(ap)) {
@@ -3001,7 +3055,7 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
        memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
 
        /* configure device according to the new ID */
-       rc = ata_dev_configure(dev, 0);
+       rc = ata_dev_configure(dev);
        if (rc == 0)
                return 0;
 
@@ -3010,37 +3064,55 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
        return rc;
 }
 
-static const char * const ata_dma_blacklist [] = {
-       "WDC AC11000H", NULL,
-       "WDC AC22100H", NULL,
-       "WDC AC32500H", NULL,
-       "WDC AC33100H", NULL,
-       "WDC AC31600H", NULL,
-       "WDC AC32100H", "24.09P07",
-       "WDC AC23200L", "21.10N21",
-       "Compaq CRD-8241B",  NULL,
-       "CRD-8400B", NULL,
-       "CRD-8480B", NULL,
-       "CRD-8482B", NULL,
-       "CRD-84", NULL,
-       "SanDisk SDP3B", NULL,
-       "SanDisk SDP3B-64", NULL,
-       "SANYO CD-ROM CRD", NULL,
-       "HITACHI CDR-8", NULL,
-       "HITACHI CDR-8335", NULL,
-       "HITACHI CDR-8435", NULL,
-       "Toshiba CD-ROM XM-6202B", NULL,
-       "TOSHIBA CD-ROM XM-1702BC", NULL,
-       "CD-532E-A", NULL,
-       "E-IDE CD-ROM CR-840", NULL,
-       "CD-ROM Drive/F5A", NULL,
-       "WPI CDD-820", NULL,
-       "SAMSUNG CD-ROM SC-148C", NULL,
-       "SAMSUNG CD-ROM SC", NULL,
-       "SanDisk SDP3B-64", NULL,
-       "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,
-       "_NEC DV5800A", NULL,
-       "SAMSUNG CD-ROM SN-124", "N001"
+struct ata_blacklist_entry {
+       const char *model_num;
+       const char *model_rev;
+       unsigned long horkage;
+};
+
+static const struct ata_blacklist_entry ata_device_blacklist [] = {
+       /* Devices with DMA related problems under Linux */
+       { "WDC AC11000H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC22100H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC32500H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC33100H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC31600H",       NULL,           ATA_HORKAGE_NODMA },
+       { "WDC AC32100H",       "24.09P07",     ATA_HORKAGE_NODMA },
+       { "WDC AC23200L",       "21.10N21",     ATA_HORKAGE_NODMA },
+       { "Compaq CRD-8241B",   NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-8400B",          NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-8480B",          NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-8482B",          NULL,           ATA_HORKAGE_NODMA },
+       { "CRD-84",             NULL,           ATA_HORKAGE_NODMA },
+       { "SanDisk SDP3B",      NULL,           ATA_HORKAGE_NODMA },
+       { "SanDisk SDP3B-64",   NULL,           ATA_HORKAGE_NODMA },
+       { "SANYO CD-ROM CRD",   NULL,           ATA_HORKAGE_NODMA },
+       { "HITACHI CDR-8",      NULL,           ATA_HORKAGE_NODMA },
+       { "HITACHI CDR-8335",   NULL,           ATA_HORKAGE_NODMA },
+       { "HITACHI CDR-8435",   NULL,           ATA_HORKAGE_NODMA },
+       { "Toshiba CD-ROM XM-6202B", NULL,      ATA_HORKAGE_NODMA },
+       { "TOSHIBA CD-ROM XM-1702BC", NULL,     ATA_HORKAGE_NODMA },
+       { "CD-532E-A",          NULL,           ATA_HORKAGE_NODMA },
+       { "E-IDE CD-ROM CR-840",NULL,           ATA_HORKAGE_NODMA },
+       { "CD-ROM Drive/F5A",   NULL,           ATA_HORKAGE_NODMA },
+       { "WPI CDD-820",        NULL,           ATA_HORKAGE_NODMA },
+       { "SAMSUNG CD-ROM SC-148C", NULL,       ATA_HORKAGE_NODMA },
+       { "SAMSUNG CD-ROM SC",  NULL,           ATA_HORKAGE_NODMA },
+       { "SanDisk SDP3B-64",   NULL,           ATA_HORKAGE_NODMA },
+       { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA },
+       { "_NEC DV5800A",       NULL,           ATA_HORKAGE_NODMA },
+       { "SAMSUNG CD-ROM SN-124","N001",       ATA_HORKAGE_NODMA },
+
+       /* Devices we expect to fail diagnostics */
+
+       /* Devices where NCQ should be avoided */
+       /* NCQ is slow */
+        { "WDC WD740ADFD-00",   NULL,          ATA_HORKAGE_NONCQ },
+
+       /* Devices with NCQ limits */
+
+       /* End Marker */
+       { }
 };
 
 static int ata_strim(char *s, size_t len)
@@ -3055,20 +3127,12 @@ static int ata_strim(char *s, size_t len)
        return len;
 }
 
-static int ata_dma_blacklisted(const struct ata_device *dev)
+unsigned long ata_device_blacklisted(const struct ata_device *dev)
 {
        unsigned char model_num[40];
        unsigned char model_rev[16];
        unsigned int nlen, rlen;
-       int i;
-
-       /* We don't support polling DMA.
-        * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
-        * if the LLDD handles only interrupts in the HSM_ST_LAST state.
-        */
-       if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
-           (dev->flags & ATA_DFLAG_CDB_INTR))
-               return 1;
+       const struct ata_blacklist_entry *ad = ata_device_blacklist;
 
        ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
                          sizeof(model_num));
@@ -3077,17 +3141,30 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
        nlen = ata_strim(model_num, sizeof(model_num));
        rlen = ata_strim(model_rev, sizeof(model_rev));
 
-       for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) {
-               if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) {
-                       if (ata_dma_blacklist[i+1] == NULL)
-                               return 1;
-                       if (!strncmp(ata_dma_blacklist[i], model_rev, rlen))
-                               return 1;
+       while (ad->model_num) {
+               if (!strncmp(ad->model_num, model_num, nlen)) {
+                       if (ad->model_rev == NULL)
+                               return ad->horkage;
+                       if (!strncmp(ad->model_rev, model_rev, rlen))
+                               return ad->horkage;
                }
+               ad++;
        }
        return 0;
 }
 
+static int ata_dma_blacklisted(const struct ata_device *dev)
+{
+       /* We don't support polling DMA.
+        * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
+        * if the LLDD handles only interrupts in the HSM_ST_LAST state.
+        */
+       if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
+           (dev->flags & ATA_DFLAG_CDB_INTR))
+               return 1;
+       return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0;
+}
+
 /**
  *     ata_dev_xfermask - Compute supported xfermask of the given device
  *     @dev: Device to compute xfermask for
@@ -3115,6 +3192,13 @@ static void ata_dev_xfermask(struct ata_device *dev)
         */
        if (ap->cbl == ATA_CBL_PATA40)
                xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
+       /* Apply drive side cable rule. Unknown or 80 pin cables reported
+        * host side are checked drive side as well. Cases where we know a
+        * 40wire cable is used safely for 80 are not checked here.
+        */
+        if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80))
+               xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
+
 
        xfer_mask &= ata_pack_xfermask(dev->pio_mask,
                                       dev->mwdma_mask, dev->udma_mask);
@@ -4857,7 +4941,6 @@ idle_irq:
  *     ata_interrupt - Default ATA host interrupt handler
  *     @irq: irq line (unused)
  *     @dev_instance: pointer to our ata_host information structure
- *     @regs: unused
  *
  *     Default interrupt handler for PCI IDE devices.  Calls
  *     ata_host_intr() for each port that is not disabled.
@@ -4869,7 +4952,7 @@ idle_irq:
  *     IRQ_NONE or IRQ_HANDLED.
  */
 
-irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
+irqreturn_t ata_interrupt (int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        unsigned int i;
@@ -5954,7 +6037,7 @@ static void __exit ata_exit(void)
        destroy_workqueue(ata_aux_wq);
 }
 
-module_init(ata_init);
+subsys_initcall(ata_init);
 module_exit(ata_exit);
 
 static unsigned long ratelimit_time;
@@ -6117,9 +6200,9 @@ EXPORT_SYMBOL_GPL(__sata_phy_reset);
 EXPORT_SYMBOL_GPL(ata_bus_reset);
 EXPORT_SYMBOL_GPL(ata_std_prereset);
 EXPORT_SYMBOL_GPL(ata_std_softreset);
+EXPORT_SYMBOL_GPL(sata_port_hardreset);
 EXPORT_SYMBOL_GPL(sata_std_hardreset);
 EXPORT_SYMBOL_GPL(ata_std_postreset);
-EXPORT_SYMBOL_GPL(ata_dev_revalidate);
 EXPORT_SYMBOL_GPL(ata_dev_classify);
 EXPORT_SYMBOL_GPL(ata_dev_pair);
 EXPORT_SYMBOL_GPL(ata_port_disable);
@@ -6144,6 +6227,7 @@ EXPORT_SYMBOL_GPL(ata_host_suspend);
 EXPORT_SYMBOL_GPL(ata_host_resume);
 EXPORT_SYMBOL_GPL(ata_id_string);
 EXPORT_SYMBOL_GPL(ata_id_c_string);
+EXPORT_SYMBOL_GPL(ata_device_blacklisted);
 EXPORT_SYMBOL_GPL(ata_scsi_simulate);
 
 EXPORT_SYMBOL_GPL(ata_pio_need_iordy);