aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata')
-rw-r--r--drivers/ata/libata-core.c2
-rw-r--r--drivers/ata/libata-scsi.c63
-rw-r--r--drivers/ata/libata.h2
3 files changed, 49 insertions, 18 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 05922e9f4fad..35b621293831 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -6453,7 +6453,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
6453 for (i = 0; i < host->n_ports; i++) { 6453 for (i = 0; i < host->n_ports; i++) {
6454 struct ata_port *ap = host->ports[i]; 6454 struct ata_port *ap = host->ports[i];
6455 6455
6456 ata_scsi_scan_host(ap); 6456 ata_scsi_scan_host(ap, 1);
6457 } 6457 }
6458 6458
6459 return 0; 6459 return 0;
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index cfde22da07ac..12ac0b511f79 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2947,17 +2947,22 @@ int ata_scsi_add_hosts(struct ata_host *host, struct scsi_host_template *sht)
2947 return rc; 2947 return rc;
2948} 2948}
2949 2949
2950void ata_scsi_scan_host(struct ata_port *ap) 2950void ata_scsi_scan_host(struct ata_port *ap, int sync)
2951{ 2951{
2952 int tries = 5;
2953 struct ata_device *last_failed_dev = NULL;
2954 struct ata_device *dev;
2952 unsigned int i; 2955 unsigned int i;
2953 2956
2954 if (ap->flags & ATA_FLAG_DISABLED) 2957 if (ap->flags & ATA_FLAG_DISABLED)
2955 return; 2958 return;
2956 2959
2960 repeat:
2957 for (i = 0; i < ATA_MAX_DEVICES; i++) { 2961 for (i = 0; i < ATA_MAX_DEVICES; i++) {
2958 struct ata_device *dev = &ap->device[i];
2959 struct scsi_device *sdev; 2962 struct scsi_device *sdev;
2960 2963
2964 dev = &ap->device[i];
2965
2961 if (!ata_dev_enabled(dev) || dev->sdev) 2966 if (!ata_dev_enabled(dev) || dev->sdev)
2962 continue; 2967 continue;
2963 2968
@@ -2967,6 +2972,45 @@ void ata_scsi_scan_host(struct ata_port *ap)
2967 scsi_device_put(sdev); 2972 scsi_device_put(sdev);
2968 } 2973 }
2969 } 2974 }
2975
2976 /* If we scanned while EH was in progress or allocation
2977 * failure occurred, scan would have failed silently. Check
2978 * whether all devices are attached.
2979 */
2980 for (i = 0; i < ATA_MAX_DEVICES; i++) {
2981 dev = &ap->device[i];
2982 if (ata_dev_enabled(dev) && !dev->sdev)
2983 break;
2984 }
2985 if (i == ATA_MAX_DEVICES)
2986 return;
2987
2988 /* we're missing some SCSI devices */
2989 if (sync) {
2990 /* If caller requested synchrnous scan && we've made
2991 * any progress, sleep briefly and repeat.
2992 */
2993 if (dev != last_failed_dev) {
2994 msleep(100);
2995 last_failed_dev = dev;
2996 goto repeat;
2997 }
2998
2999 /* We might be failing to detect boot device, give it
3000 * a few more chances.
3001 */
3002 if (--tries) {
3003 msleep(100);
3004 goto repeat;
3005 }
3006
3007 ata_port_printk(ap, KERN_ERR, "WARNING: synchronous SCSI scan "
3008 "failed without making any progress,\n"
3009 " switching to async\n");
3010 }
3011
3012 queue_delayed_work(ata_aux_wq, &ap->hotplug_task,
3013 round_jiffies_relative(HZ));
2970} 3014}
2971 3015
2972/** 3016/**
@@ -3093,20 +3137,7 @@ void ata_scsi_hotplug(struct work_struct *work)
3093 } 3137 }
3094 3138
3095 /* scan for new ones */ 3139 /* scan for new ones */
3096 ata_scsi_scan_host(ap); 3140 ata_scsi_scan_host(ap, 0);
3097
3098 /* If we scanned while EH was in progress, scan would have
3099 * failed silently. Requeue if there are enabled but
3100 * unattached devices.
3101 */
3102 for (i = 0; i < ATA_MAX_DEVICES; i++) {
3103 struct ata_device *dev = &ap->device[i];
3104 if (ata_dev_enabled(dev) && !dev->sdev) {
3105 queue_delayed_work(ata_aux_wq, &ap->hotplug_task,
3106 round_jiffies_relative(HZ));
3107 break;
3108 }
3109 }
3110 3141
3111 DPRINTK("EXIT\n"); 3142 DPRINTK("EXIT\n");
3112} 3143}
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index ba17fc5f2e99..48836b22ce2f 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -112,7 +112,7 @@ static inline int ata_acpi_on_devcfg(struct ata_device *adev) { return 0; }
112/* libata-scsi.c */ 112/* libata-scsi.c */
113extern int ata_scsi_add_hosts(struct ata_host *host, 113extern int ata_scsi_add_hosts(struct ata_host *host,
114 struct scsi_host_template *sht); 114 struct scsi_host_template *sht);
115extern void ata_scsi_scan_host(struct ata_port *ap); 115extern void ata_scsi_scan_host(struct ata_port *ap, int sync);
116extern int ata_scsi_offline_dev(struct ata_device *dev); 116extern int ata_scsi_offline_dev(struct ata_device *dev);
117extern void ata_scsi_hotplug(struct work_struct *work); 117extern void ata_scsi_hotplug(struct work_struct *work);
118extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf, 118extern unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf,