|
@@ -2947,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;
|
|
|
|
|
@@ -2967,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));
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -3093,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");
|
|
|
}
|