sata_mv: Clean up hard coded array size calculation.
[safe/jmp/linux-2.6] / drivers / ata / pata_scc.c
index 2b9da71..4257d6b 100644 (file)
@@ -8,7 +8,7 @@
  *  Copyright 2003-2005 Jeff Garzik
  *  Copyright (C) 1998-1999 Andrzej Krzysztofowicz, Author and Maintainer
  *  Copyright (C) 1998-2000 Andre Hedrick <andre@linux-ide.org>
- *  Copyright (C) 2003 Red Hat Inc <alan@redhat.com>
+ *  Copyright (C) 2003 Red Hat Inc
  *
  * and drivers/ata/ahci.c:
  *  Copyright 2004-2005 Red Hat, Inc.
@@ -210,7 +210,6 @@ static void scc_set_piomode (struct ata_port *ap, struct ata_device *adev)
  *     scc_set_dmamode - Initialize host controller PATA DMA timings
  *     @ap: Port whose timings we are configuring
  *     @adev: um
- *     @udma: udma mode, 0 - 6
  *
  *     Set UDMA mode for device.
  *
@@ -497,47 +496,68 @@ 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;
+       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.
+        */
+       msleep(150);
 
-       /* if device 0 was found in ata_devchk, wait for its
-        * BSY bit 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.
         */
-       if (dev0) {
-               rc = ata_sff_wait_ready(ap, deadline);
-               if (rc && rc != -ENODEV)
-                       return rc;
-       }
+       if (rc)
+               return rc;
 
-       /* if device 1 was found in ata_devchk, wait for
-        * register access, then wait for BSY to clear
+       /* if device 1 was found in ata_devchk, wait for register
+        * access briefly, then wait for BSY to clear.
         */
-       while (dev1) {
-               u8 nsect, lbal;
+       if (dev1) {
+               int i;
 
                ap->ops->sff_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 (dev1) {
-               rc = ata_sff_wait_ready(ap, deadline);
-               if (rc && rc != -ENODEV)
-                       return rc;
+
+               /* 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? */
@@ -547,7 +567,7 @@ static int scc_bus_post_reset(struct ata_port *ap, unsigned int devmask,
        if (dev0)
                ap->ops->sff_dev_select(ap, 0);
 
-       return 0;
+       return ret;
 }
 
 /**
@@ -570,17 +590,7 @@ 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_sff_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;
 }
@@ -604,11 +614,6 @@ static int scc_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);
@@ -634,7 +639,6 @@ static int scc_softreset(struct ata_link *link, unsigned int *classes,
                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;
 }
@@ -691,7 +695,7 @@ static void scc_bmdma_stop (struct ata_queued_cmd *qc)
 
                if (reg & INTSTS_BMSINT) {
                        unsigned int classes;
-                       unsigned long deadline = jiffies + ATA_TMOUT_BOOT;
+                       unsigned long deadline = ata_deadline(jiffies, ATA_TMOUT_BOOT);
                        printk(KERN_WARNING "%s: Internal Bus Error\n", DRV_NAME);
                        out_be32(bmid_base + SCC_DMA_INTST, INTSTS_BMSINT);
                        /* TBD: SW reset */
@@ -721,7 +725,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_sff_altstatus(ap);  /* dummy read */
+       ata_sff_dma_pause(ap);  /* dummy read */
 }
 
 /**
@@ -742,7 +746,8 @@ static u8 scc_bmdma_status (struct ata_port *ap)
                return host_stat;
 
        /* errata A252,A308 workaround: Step4 */
-       if ((ata_sff_altstatus(ap) & ATA_ERR) && (int_status & INTSTS_INTRQ))
+       if ((scc_check_altstatus(ap) & ATA_ERR)
+                                       && (int_status & INTSTS_INTRQ))
                return (host_stat | ATA_DMA_INTR);
 
        /* errata A308 workaround Step5 */
@@ -996,8 +1001,8 @@ static struct ata_port_operations scc_pata_ops = {
 static struct ata_port_info scc_port_info[] = {
        {
                .flags          = ATA_FLAG_SLAVE_POSS | ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY,
-               .pio_mask       = 0x1f, /* pio0-4 */
-               .mwdma_mask     = 0x00,
+               .pio_mask       = ATA_PIO4,
+               /* No MWDMA */
                .udma_mask      = ATA_UDMA6,
                .port_ops       = &scc_pata_ops,
        },