]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/ata/libata-scsi.c
[IPG]: add IP1000A driver to kernel tree
[linux-2.6-omap-h63xx.git] / drivers / ata / libata-scsi.c
index c228df298bd898ae6e1379d31dc6d6c9dc41eb1a..e83647651b31f1e12368ec53deaef317cfb33c09 100644 (file)
@@ -768,7 +768,7 @@ static void ata_scsi_dev_config(struct scsi_device *sdev,
         * Decrement max hw segments accordingly.
         */
        if (dev->class == ATA_DEV_ATAPI) {
-               request_queue_t *q = sdev->request_queue;
+               struct request_queue *q = sdev->request_queue;
                blk_queue_max_hw_segments(q, q->max_hw_segments - 1);
        }
 
@@ -2384,11 +2384,6 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        int using_pio = (dev->flags & ATA_DFLAG_PIO);
        int nodata = (scmd->sc_data_direction == DMA_NONE);
 
-       if (!using_pio)
-               /* Check whether ATAPI DMA is safe */
-               if (ata_check_atapi_dma(qc))
-                       using_pio = 1;
-
        memset(qc->cdb, 0, dev->cdb_len);
        memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len);
 
@@ -2401,19 +2396,22 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        }
 
        qc->tf.command = ATA_CMD_PACKET;
+       qc->nbytes = scmd->request_bufflen;
+
+       /* check whether ATAPI DMA is safe */
+       if (!using_pio && ata_check_atapi_dma(qc))
+               using_pio = 1;
 
-       /* no data, or PIO data xfer */
        if (using_pio || nodata) {
+               /* no data, or PIO data xfer */
                if (nodata)
                        qc->tf.protocol = ATA_PROT_ATAPI_NODATA;
                else
                        qc->tf.protocol = ATA_PROT_ATAPI;
                qc->tf.lbam = (8 * 1024) & 0xff;
                qc->tf.lbah = (8 * 1024) >> 8;
-       }
-
-       /* DMA data xfer */
-       else {
+       } else {
+               /* DMA data xfer */
                qc->tf.protocol = ATA_PROT_ATAPI_DMA;
                qc->tf.feature |= ATAPI_PKT_DMA;
 
@@ -2422,8 +2420,6 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
                        qc->tf.feature |= ATAPI_DMADIR;
        }
 
-       qc->nbytes = scmd->request_bufflen;
-
        return 0;
 }
 
@@ -2624,7 +2620,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
                        ata_dev_printk(dev, KERN_WARNING,
                                       "invalid multi_count %u ignored\n",
                                       multi_count);
-       }       
+       }
 
        /* READ/WRITE LONG use a non-standard sect_size */
        qc->sect_size = ATA_SECT_SIZE;
@@ -2951,17 +2947,22 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
        return rc;
 }
 
-void ata_scsi_scan_host(struct ata_port *ap)
+void ata_scsi_scan_host(struct ata_port *ap, int sync)
 {
+       int tries = 5;
+       struct ata_device *last_failed_dev = NULL;
+       struct ata_device *dev;
        unsigned int i;
 
        if (ap->flags & ATA_FLAG_DISABLED)
                return;
 
+ repeat:
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->device[i];
                struct scsi_device *sdev;
 
+               dev = &ap->device[i];
+
                if (!ata_dev_enabled(dev) || dev->sdev)
                        continue;
 
@@ -2971,6 +2972,45 @@ void ata_scsi_scan_host(struct ata_port *ap)
                        scsi_device_put(sdev);
                }
        }
+
+       /* If we scanned while EH was in progress or allocation
+        * failure occurred, scan would have failed silently.  Check
+        * whether all devices are attached.
+        */
+       for (i = 0; i < ATA_MAX_DEVICES; i++) {
+               dev = &ap->device[i];
+               if (ata_dev_enabled(dev) && !dev->sdev)
+                       break;
+       }
+       if (i == ATA_MAX_DEVICES)
+               return;
+
+       /* we're missing some SCSI devices */
+       if (sync) {
+               /* If caller requested synchrnous scan && we've made
+                * any progress, sleep briefly and repeat.
+                */
+               if (dev != last_failed_dev) {
+                       msleep(100);
+                       last_failed_dev = dev;
+                       goto repeat;
+               }
+
+               /* We might be failing to detect boot device, give it
+                * a few more chances.
+                */
+               if (--tries) {
+                       msleep(100);
+                       goto repeat;
+               }
+
+               ata_port_printk(ap, KERN_ERR, "WARNING: synchronous SCSI scan "
+                               "failed without making any progress,\n"
+                               "                  switching to async\n");
+       }
+
+       queue_delayed_work(ata_aux_wq, &ap->hotplug_task,
+                          round_jiffies_relative(HZ));
 }
 
 /**
@@ -3097,20 +3137,7 @@ void ata_scsi_hotplug(struct work_struct *work)
        }
 
        /* scan for new ones */
-       ata_scsi_scan_host(ap);
-
-       /* If we scanned while EH was in progress, scan would have
-        * failed silently.  Requeue if there are enabled but
-        * unattached devices.
-        */
-       for (i = 0; i < ATA_MAX_DEVICES; i++) {
-               struct ata_device *dev = &ap->device[i];
-               if (ata_dev_enabled(dev) && !dev->sdev) {
-                       queue_delayed_work(ata_aux_wq, &ap->hotplug_task,
-                               round_jiffies_relative(HZ));
-                       break;
-               }
-       }
+       ata_scsi_scan_host(ap, 0);
 
        DPRINTK("EXIT\n");
 }