[PATCH] libata: ata_dev_init_params() fixes
[sfrench/cifs-2.6.git] / drivers / scsi / libata-core.c
index d279666dcb38a72b5176079076ad9f71d83039c5..21b0ed583b8a7273e5391c8d221c634d031fb578 100644 (file)
@@ -62,7 +62,9 @@
 #include "libata.h"
 
 static unsigned int ata_dev_init_params(struct ata_port *ap,
-                                       struct ata_device *dev);
+                                       struct ata_device *dev,
+                                       u16 heads,
+                                       u16 sectors);
 static void ata_set_mode(struct ata_port *ap);
 static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
                                         struct ata_device *dev);
@@ -1081,9 +1083,8 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
  *
  *     Read ID data from the specified device.  ATA_CMD_ID_ATA is
  *     performed on ATA devices and ATA_CMD_ID_ATAPI on ATAPI
- *     devices.  This function also takes care of EDD signature
- *     misreporting (to be removed once EDD support is gone) and
- *     issues ATA_CMD_INIT_DEV_PARAMS for pre-ATA4 drives.
+ *     devices.  This function also issues ATA_CMD_INIT_DEV_PARAMS
+ *     for pre-ATA4 drives.
  *
  *     LOCKING:
  *     Kernel thread context (may sleep)
@@ -1095,7 +1096,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
                           unsigned int *p_class, int post_reset, u16 **p_id)
 {
        unsigned int class = *p_class;
-       unsigned int using_edd;
        struct ata_taskfile tf;
        unsigned int err_mask = 0;
        u16 *id;
@@ -1104,12 +1104,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
 
        DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno);
 
-       if (ap->ops->probe_reset ||
-           ap->flags & (ATA_FLAG_SRST | ATA_FLAG_SATA_RESET))
-               using_edd = 0;
-       else
-               using_edd = 1;
-
        ata_dev_select(ap, dev->devno, 1, 1); /* select device 0/1 */
 
        id = kmalloc(sizeof(id[0]) * ATA_ID_WORDS, GFP_KERNEL);
@@ -1139,39 +1133,16 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
 
        err_mask = ata_exec_internal(ap, dev, &tf, DMA_FROM_DEVICE,
                                     id, sizeof(id[0]) * ATA_ID_WORDS);
-
        if (err_mask) {
                rc = -EIO;
                reason = "I/O error";
-
-               if (err_mask & ~AC_ERR_DEV)
-                       goto err_out;
-
-               /*
-                * arg!  EDD works for all test cases, but seems to return
-                * the ATA signature for some ATAPI devices.  Until the
-                * reason for this is found and fixed, we fix up the mess
-                * here.  If IDENTIFY DEVICE returns command aborted
-                * (as ATAPI devices do), then we issue an
-                * IDENTIFY PACKET DEVICE.
-                *
-                * ATA software reset (SRST, the default) does not appear
-                * to have this problem.
-                */
-               if ((using_edd) && (class == ATA_DEV_ATA)) {
-                       u8 err = tf.feature;
-                       if (err & ATA_ABORTED) {
-                               class = ATA_DEV_ATAPI;
-                               goto retry;
-                       }
-               }
                goto err_out;
        }
 
        swap_buf_le16(id, ATA_ID_WORDS);
 
        /* sanity check */
-       if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) {
+       if ((class == ATA_DEV_ATA) != (ata_id_is_ata(id) | ata_id_is_cfa(id))) {
                rc = -EINVAL;
                reason = "device reports illegal type";
                goto err_out;
@@ -1187,7 +1158,7 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
                 * Some drives were very specific about that exact sequence.
                 */
                if (ata_id_major_version(id) < 4 || !ata_id_has_lba(id)) {
-                       err_mask = ata_dev_init_params(ap, dev);
+                       err_mask = ata_dev_init_params(ap, dev, id[3], id[6]);
                        if (err_mask) {
                                rc = -EIO;
                                reason = "INIT_DEV_PARAMS failed";
@@ -1440,7 +1411,11 @@ static int ata_bus_probe(struct ata_port *ap)
        if (!found)
                goto err_out_disable;
 
-       ata_set_mode(ap);
+       if (ap->ops->set_mode)
+               ap->ops->set_mode(ap);
+       else
+               ata_set_mode(ap);
+
        if (ap->flags & ATA_FLAG_PORT_DISABLED)
                goto err_out_disable;
 
@@ -1845,7 +1820,7 @@ static void ata_host_set_dma(struct ata_port *ap)
  */
 static void ata_set_mode(struct ata_port *ap)
 {
-       int i, rc;
+       int i, rc, used_dma = 0;
 
        /* step 1: calculate xfer_mask */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
@@ -1863,6 +1838,9 @@ static void ata_set_mode(struct ata_port *ap)
                dma_mask = ata_pack_xfermask(0, dev->mwdma_mask, dev->udma_mask);
                dev->pio_mode = ata_xfer_mask2mode(pio_mask);
                dev->dma_mode = ata_xfer_mask2mode(dma_mask);
+
+               if (dev->dma_mode)
+                       used_dma = 1;
        }
 
        /* step 2: always set host PIO timings */
@@ -1884,6 +1862,17 @@ static void ata_set_mode(struct ata_port *ap)
                        goto err_out;
        }
 
+       /*
+        *      Record simplex status. If we selected DMA then the other
+        *      host channels are not permitted to do so.
+        */
+
+       if (used_dma && (ap->host_set->flags & ATA_HOST_SIMPLEX))
+               ap->host_set->simplex_claimed = 1;
+
+       /*
+        *      Chip specific finalisation
+        */
        if (ap->ops->post_set_mode)
                ap->ops->post_set_mode(ap);
 
@@ -2005,45 +1994,6 @@ static void ata_bus_post_reset(struct ata_port *ap, unsigned int devmask)
                ap->ops->dev_select(ap, 0);
 }
 
-/**
- *     ata_bus_edd - Issue EXECUTE DEVICE DIAGNOSTIC command.
- *     @ap: Port to reset and probe
- *
- *     Use the EXECUTE DEVICE DIAGNOSTIC command to reset and
- *     probe the bus.  Not often used these days.
- *
- *     LOCKING:
- *     PCI/etc. bus probe sem.
- *     Obtains host_set lock.
- *
- */
-
-static unsigned int ata_bus_edd(struct ata_port *ap)
-{
-       struct ata_taskfile tf;
-       unsigned long flags;
-
-       /* set up execute-device-diag (bus reset) taskfile */
-       /* also, take interrupts to a known state (disabled) */
-       DPRINTK("execute-device-diag\n");
-       ata_tf_init(ap, &tf, 0);
-       tf.ctl |= ATA_NIEN;
-       tf.command = ATA_CMD_EDD;
-       tf.protocol = ATA_PROT_NODATA;
-
-       /* do bus reset */
-       spin_lock_irqsave(&ap->host_set->lock, flags);
-       ata_tf_to_host(ap, &tf);
-       spin_unlock_irqrestore(&ap->host_set->lock, flags);
-
-       /* spec says at least 2ms.  but who knows with those
-        * crazy ATAPI devices...
-        */
-       msleep(150);
-
-       return ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
-}
-
 static unsigned int ata_bus_softreset(struct ata_port *ap,
                                      unsigned int devmask)
 {
@@ -2078,13 +2028,12 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
         */
        msleep(150);
 
-
        /* Before we perform post reset processing we want to see if
-          the bus shows 0xFF because the odd clown forgets the D7 pulldown
-          resistor */
-
+        * the bus shows 0xFF because the odd clown forgets the D7
+        * pulldown resistor.
+        */
        if (ata_check_status(ap) == 0xFF)
-               return 1;       /* Positive is failure for some reason */
+               return AC_ERR_OTHER;
 
        ata_bus_post_reset(ap, devmask);
 
@@ -2116,7 +2065,7 @@ void ata_bus_reset(struct ata_port *ap)
        struct ata_ioports *ioaddr = &ap->ioaddr;
        unsigned int slave_possible = ap->flags & ATA_FLAG_SLAVE_POSS;
        u8 err;
-       unsigned int dev0, dev1 = 0, rc = 0, devmask = 0;
+       unsigned int dev0, dev1 = 0, devmask = 0;
 
        DPRINTK("ENTER, host %u, port %u\n", ap->id, ap->port_no);
 
@@ -2139,18 +2088,8 @@ void ata_bus_reset(struct ata_port *ap)
 
        /* issue bus reset */
        if (ap->flags & ATA_FLAG_SRST)
-               rc = ata_bus_softreset(ap, devmask);
-       else if ((ap->flags & ATA_FLAG_SATA_RESET) == 0) {
-               /* set up device control */
-               if (ap->flags & ATA_FLAG_MMIO)
-                       writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
-               else
-                       outb(ap->ctl, ioaddr->ctl_addr);
-               rc = ata_bus_edd(ap);
-       }
-
-       if (rc)
-               goto err_out;
+               if (ata_bus_softreset(ap, devmask))
+                       goto err_out;
 
        /*
         * determine by signature whether we have ATA or ATAPI devices
@@ -2223,9 +2162,9 @@ static int sata_phy_resume(struct ata_port *ap)
  *     so makes reset sequence different from the original
  *     ->phy_reset implementation and Jeff nervous.  :-P
  */
-extern void ata_std_probeinit(struct ata_port *ap)
+void ata_std_probeinit(struct ata_port *ap)
 {
-       if (ap->flags & ATA_FLAG_SATA && ap->ops->scr_read) {
+       if ((ap->flags & ATA_FLAG_SATA) && ap->ops->scr_read) {
                sata_phy_resume(ap);
                if (sata_dev_present(ap))
                        ata_busy_sleep(ap, ATA_TMOUT_BOOT_QUICK, ATA_TMOUT_BOOT);
@@ -2714,18 +2653,23 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
  *     known limits including host controller limits, device
  *     blacklist, etc...
  *
+ *     FIXME: The current implementation limits all transfer modes to
+ *     the fastest of the lowested device on the port.  This is not
+ *     required on most controllers.
+ *
  *     LOCKING:
  *     None.
  */
 static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
 {
+       struct ata_host_set *hs = ap->host_set;
        unsigned long xfer_mask;
        int i;
 
        xfer_mask = ata_pack_xfermask(ap->pio_mask, ap->mwdma_mask,
                                      ap->udma_mask);
 
-       /* use port-wide xfermask for now */
+       /* FIXME: Use port-wide xfermask for now */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *d = &ap->device[i];
                if (!ata_dev_present(d))
@@ -2735,12 +2679,23 @@ static void ata_dev_xfermask(struct ata_port *ap, struct ata_device *dev)
                xfer_mask &= ata_id_xfermask(d->id);
                if (ata_dma_blacklisted(d))
                        xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
+               /* Apply cable rule here. Don't apply it early because when
+                  we handle hot plug the cable type can itself change */
+               if (ap->cbl == ATA_CBL_PATA40)
+                       xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
        }
 
        if (ata_dma_blacklisted(dev))
                printk(KERN_WARNING "ata%u: dev %u is on DMA blacklist, "
                       "disabling DMA\n", ap->id, dev->devno);
 
+       if (hs->flags & ATA_HOST_SIMPLEX) {
+               if (hs->simplex_claimed)
+                       xfer_mask &= ~(ATA_MASK_MWDMA | ATA_MASK_UDMA);
+       }
+       if (ap->ops->mode_filter)
+               xfer_mask = ap->ops->mode_filter(ap, dev, xfer_mask);
+
        ata_unpack_xfermask(xfer_mask, &dev->pio_mask, &dev->mwdma_mask,
                            &dev->udma_mask);
 }
@@ -2795,16 +2750,16 @@ static unsigned int ata_dev_set_xfermode(struct ata_port *ap,
  */
 
 static unsigned int ata_dev_init_params(struct ata_port *ap,
-                                       struct ata_device *dev)
+                                       struct ata_device *dev,
+                                       u16 heads,
+                                       u16 sectors)
 {
        struct ata_taskfile tf;
        unsigned int err_mask;
-       u16 sectors = dev->id[6];
-       u16 heads   = dev->id[3];
 
        /* Number of sectors per track 1-255. Number of heads 1-16 */
        if (sectors < 1 || sectors > 255 || heads < 1 || heads > 16)
-               return 0;
+               return AC_ERR_INVALID;
 
        /* set up init dev params taskfile */
        DPRINTK("init dev params \n");
@@ -4536,6 +4491,14 @@ static struct ata_port * ata_host_add(const struct ata_probe_ent *ent,
        int rc;
 
        DPRINTK("ENTER\n");
+
+       if (!ent->port_ops->probe_reset &&
+           !(ent->host_flags & (ATA_FLAG_SATA_RESET | ATA_FLAG_SRST))) {
+               printk(KERN_ERR "ata%u: no reset mechanism available\n",
+                      port_no);
+               return NULL;
+       }
+
        host = scsi_host_alloc(ent->sht, sizeof(struct ata_port));
        if (!host)
                return NULL;
@@ -4596,6 +4559,7 @@ int ata_device_add(const struct ata_probe_ent *ent)
        host_set->mmio_base = ent->mmio_base;
        host_set->private_data = ent->private_data;
        host_set->ops = ent->port_ops;
+       host_set->flags = ent->host_set_flags;
 
        /* register each port bound to this device */
        for (i = 0; i < ent->n_ports; i++) {