]> err.no Git - linux-2.6/blobdiff - drivers/scsi/libata-core.c
[PATCH] libata-dev: add flush task to ata_exec_internal()
[linux-2.6] / drivers / scsi / libata-core.c
index 5a0b67a602df237ea5c9d4998d87712178749bbf..a28569d0081dfe6e052f63573e4147182c43dfe3 100644 (file)
@@ -71,7 +71,7 @@ static unsigned int ata_dev_xfermask(struct ata_port *ap,
 static unsigned int ata_unique_id = 1;
 static struct workqueue_struct *ata_wq;
 
-int atapi_enabled = 0;
+int atapi_enabled = 1;
 module_param(atapi_enabled, int, 0444);
 MODULE_PARM_DESC(atapi_enabled, "Enable discovery of ATAPI devices (0=off, 1=on)");
 
@@ -819,7 +819,10 @@ static unsigned int ata_id_xfermask(const u16 *id)
        }
 
        mwdma_mask = id[ATA_ID_MWDMA_MODES] & 0x07;
-       udma_mask = id[ATA_ID_UDMA_MODES] & 0xff;
+
+       udma_mask = 0;
+       if (id[ATA_ID_FIELD_VALID] & (1 << 2))
+               udma_mask = id[ATA_ID_UDMA_MODES] & 0xff;
 
        return ata_pack_xfermask(pio_mask, mwdma_mask, udma_mask);
 }
@@ -959,6 +962,8 @@ ata_exec_internal(struct ata_port *ap, struct ata_device *dev,
        spin_unlock_irqrestore(&ap->host_set->lock, flags);
 
        if (!wait_for_completion_timeout(&wait, ATA_TMOUT_INTERNAL)) {
+               ata_port_flush_task(ap);
+
                spin_lock_irqsave(&ap->host_set->lock, flags);
 
                /* We're racing with irq here.  If we lose, the
@@ -1117,12 +1122,6 @@ static int ata_dev_read_id(struct ata_port *ap, struct ata_device *dev,
 
        swap_buf_le16(id, ATA_ID_WORDS);
 
-       /* print device capabilities */
-       printk(KERN_DEBUG "ata%u: dev %u cfg "
-              "49:%04x 82:%04x 83:%04x 84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
-              ap->id, dev->devno,
-              id[49], id[82], id[83], id[84], id[85], id[86], id[87], id[88]);
-
        /* sanity check */
        if ((class == ATA_DEV_ATA) != ata_id_is_ata(id)) {
                rc = -EINVAL;
@@ -1190,6 +1189,7 @@ static inline u8 ata_dev_knobble(const struct ata_port *ap,
 static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
                             int print_info)
 {
+       const u16 *id = dev->id;
        unsigned int xfer_mask;
        int i, rc;
 
@@ -1201,6 +1201,13 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
 
        DPRINTK("ENTER, host %u, dev %u\n", ap->id, dev->devno);
 
+       /* print device capabilities */
+       if (print_info)
+               printk(KERN_DEBUG "ata%u: dev %u cfg 49:%04x 82:%04x 83:%04x "
+                      "84:%04x 85:%04x 86:%04x 87:%04x 88:%04x\n",
+                      ap->id, dev->devno, id[49], id[82], id[83],
+                      id[84], id[85], id[86], id[87], id[88]);
+
        /* initialize to-be-configured parameters */
        dev->flags = 0;
        dev->max_sectors = 0;
@@ -1215,27 +1222,27 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
         */
 
        /* we require DMA support (bits 8 of word 49) */
-       if (!ata_id_has_dma(dev->id)) {
+       if (!ata_id_has_dma(id)) {
                printk(KERN_DEBUG "ata%u: no dma\n", ap->id);
                rc = -EINVAL;
                goto err_out_nosup;
        }
 
        /* find max transfer mode; for printk only */
-       xfer_mask = ata_id_xfermask(dev->id);
+       xfer_mask = ata_id_xfermask(id);
 
-       ata_dump_id(dev->id);
+       ata_dump_id(id);
 
        /* ATA-specific feature tests */
        if (dev->class == ATA_DEV_ATA) {
-               dev->n_sectors = ata_id_n_sectors(dev->id);
+               dev->n_sectors = ata_id_n_sectors(id);
 
-               if (ata_id_has_lba(dev->id)) {
+               if (ata_id_has_lba(id)) {
                        const char *lba_desc;
 
                        lba_desc = "LBA";
                        dev->flags |= ATA_DFLAG_LBA;
-                       if (ata_id_has_lba48(dev->id)) {
+                       if (ata_id_has_lba48(id)) {
                                dev->flags |= ATA_DFLAG_LBA48;
                                lba_desc = "LBA48";
                        }
@@ -1245,7 +1252,7 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
                                printk(KERN_INFO "ata%u: dev %u ATA-%d, "
                                       "max %s, %Lu sectors: %s\n",
                                       ap->id, dev->devno,
-                                      ata_id_major_version(dev->id),
+                                      ata_id_major_version(id),
                                       ata_mode_string(xfer_mask),
                                       (unsigned long long)dev->n_sectors,
                                       lba_desc);
@@ -1253,15 +1260,15 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
                        /* CHS */
 
                        /* Default translation */
-                       dev->cylinders  = dev->id[1];
-                       dev->heads      = dev->id[3];
-                       dev->sectors    = dev->id[6];
+                       dev->cylinders  = id[1];
+                       dev->heads      = id[3];
+                       dev->sectors    = id[6];
 
-                       if (ata_id_current_chs_valid(dev->id)) {
+                       if (ata_id_current_chs_valid(id)) {
                                /* Current CHS translation is valid. */
-                               dev->cylinders = dev->id[54];
-                               dev->heads     = dev->id[55];
-                               dev->sectors   = dev->id[56];
+                               dev->cylinders = id[54];
+                               dev->heads     = id[55];
+                               dev->sectors   = id[56];
                        }
 
                        /* print device info to dmesg */
@@ -1269,7 +1276,7 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
                                printk(KERN_INFO "ata%u: dev %u ATA-%d, "
                                       "max %s, %Lu sectors: CHS %u/%u/%u\n",
                                       ap->id, dev->devno,
-                                      ata_id_major_version(dev->id),
+                                      ata_id_major_version(id),
                                       ata_mode_string(xfer_mask),
                                       (unsigned long long)dev->n_sectors,
                                       dev->cylinders, dev->heads, dev->sectors);
@@ -1280,7 +1287,7 @@ static int ata_dev_configure(struct ata_port *ap, struct ata_device *dev,
 
        /* ATAPI-specific feature tests */
        else if (dev->class == ATA_DEV_ATAPI) {
-               rc = atapi_cdb_len(dev->id);
+               rc = atapi_cdb_len(id);
                if ((rc < 12) || (rc > ATAPI_CDB_LEN)) {
                        printk(KERN_WARNING "ata%u: unsupported CDB len\n", ap->id);
                        rc = -EINVAL;
@@ -1344,32 +1351,30 @@ static int ata_bus_probe(struct ata_port *ap)
 
        ata_port_probe(ap);
 
-       /* reset */
-       if (ap->ops->probe_reset) {
-               for (i = 0; i < ATA_MAX_DEVICES; i++)
-                       classes[i] = ATA_DEV_UNKNOWN;
+       /* reset and determine device classes */
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               classes[i] = ATA_DEV_UNKNOWN;
 
+       if (ap->ops->probe_reset) {
                rc = ap->ops->probe_reset(ap, classes);
                if (rc) {
                        printk("ata%u: reset failed (errno=%d)\n", ap->id, rc);
                        return rc;
                }
-
-               for (i = 0; i < ATA_MAX_DEVICES; i++)
-                       if (classes[i] == ATA_DEV_UNKNOWN)
-                               classes[i] = ATA_DEV_NONE;
        } else {
                ap->ops->phy_reset(ap);
 
-               for (i = 0; i < ATA_MAX_DEVICES; i++) {
-                       if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
+               if (!(ap->flags & ATA_FLAG_PORT_DISABLED))
+                       for (i = 0; i < ATA_MAX_DEVICES; i++)
                                classes[i] = ap->device[i].class;
-                       else
-                               ap->device[i].class = ATA_DEV_UNKNOWN;
-               }
+
                ata_port_probe(ap);
        }
 
+       for (i = 0; i < ATA_MAX_DEVICES; i++)
+               if (classes[i] == ATA_DEV_UNKNOWN)
+                       classes[i] = ATA_DEV_NONE;
+
        /* read IDENTIFY page and configure devices */
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];