diff options
Diffstat (limited to 'drivers/ata/libata-scsi.c')
-rw-r--r-- | drivers/ata/libata-scsi.c | 63 |
1 files changed, 47 insertions, 16 deletions
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 | ||
2950 | void ata_scsi_scan_host(struct ata_port *ap) | 2950 | void 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 | } |