aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorJames Morris <jmorris@namei.org>2009-03-23 19:52:46 -0400
committerJames Morris <jmorris@namei.org>2009-03-23 19:52:46 -0400
commit703a3cd72817e99201cef84a8a7aecc60b2b3581 (patch)
tree3e943755178ff410694722bb031f523136fbc432 /drivers/scsi/sd.c
parentdf7f54c012b92ec93d56b68547351dcdf8a163d3 (diff)
parent8e0ee43bc2c3e19db56a4adaa9a9b04ce885cd84 (diff)
Merge branch 'master' into next
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c33
1 files changed, 18 insertions, 15 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index d57566b8be0a..4970ae4a62d6 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -107,6 +107,7 @@ static void scsi_disk_release(struct device *cdev);
107static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); 107static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *);
108static void sd_print_result(struct scsi_disk *, int); 108static void sd_print_result(struct scsi_disk *, int);
109 109
110static DEFINE_SPINLOCK(sd_index_lock);
110static DEFINE_IDA(sd_index_ida); 111static DEFINE_IDA(sd_index_ida);
111 112
112/* This semaphore is used to mediate the 0->1 reference get in the 113/* This semaphore is used to mediate the 0->1 reference get in the
@@ -1166,23 +1167,19 @@ sd_spinup_disk(struct scsi_disk *sdkp)
1166 /* 1167 /*
1167 * The device does not want the automatic start to be issued. 1168 * The device does not want the automatic start to be issued.
1168 */ 1169 */
1169 if (sdkp->device->no_start_on_add) { 1170 if (sdkp->device->no_start_on_add)
1170 break; 1171 break;
1171 }
1172
1173 /*
1174 * If manual intervention is required, or this is an
1175 * absent USB storage device, a spinup is meaningless.
1176 */
1177 if (sense_valid &&
1178 sshdr.sense_key == NOT_READY &&
1179 sshdr.asc == 4 && sshdr.ascq == 3) {
1180 break; /* manual intervention required */
1181 1172
1182 /* 1173 if (sense_valid && sshdr.sense_key == NOT_READY) {
1183 * Issue command to spin up drive when not ready 1174 if (sshdr.asc == 4 && sshdr.ascq == 3)
1184 */ 1175 break; /* manual intervention required */
1185 } else if (sense_valid && sshdr.sense_key == NOT_READY) { 1176 if (sshdr.asc == 4 && sshdr.ascq == 0xb)
1177 break; /* standby */
1178 if (sshdr.asc == 4 && sshdr.ascq == 0xc)
1179 break; /* unavailable */
1180 /*
1181 * Issue command to spin up drive when not ready
1182 */
1186 if (!spintime) { 1183 if (!spintime) {
1187 sd_printk(KERN_NOTICE, sdkp, "Spinning up disk..."); 1184 sd_printk(KERN_NOTICE, sdkp, "Spinning up disk...");
1188 cmd[0] = START_STOP; 1185 cmd[0] = START_STOP;
@@ -1914,7 +1911,9 @@ static int sd_probe(struct device *dev)
1914 if (!ida_pre_get(&sd_index_ida, GFP_KERNEL)) 1911 if (!ida_pre_get(&sd_index_ida, GFP_KERNEL))
1915 goto out_put; 1912 goto out_put;
1916 1913
1914 spin_lock(&sd_index_lock);
1917 error = ida_get_new(&sd_index_ida, &index); 1915 error = ida_get_new(&sd_index_ida, &index);
1916 spin_unlock(&sd_index_lock);
1918 } while (error == -EAGAIN); 1917 } while (error == -EAGAIN);
1919 1918
1920 if (error) 1919 if (error)
@@ -1936,7 +1935,9 @@ static int sd_probe(struct device *dev)
1936 return 0; 1935 return 0;
1937 1936
1938 out_free_index: 1937 out_free_index:
1938 spin_lock(&sd_index_lock);
1939 ida_remove(&sd_index_ida, index); 1939 ida_remove(&sd_index_ida, index);
1940 spin_unlock(&sd_index_lock);
1940 out_put: 1941 out_put:
1941 put_disk(gd); 1942 put_disk(gd);
1942 out_free: 1943 out_free:
@@ -1986,7 +1987,9 @@ static void scsi_disk_release(struct device *dev)
1986 struct scsi_disk *sdkp = to_scsi_disk(dev); 1987 struct scsi_disk *sdkp = to_scsi_disk(dev);
1987 struct gendisk *disk = sdkp->disk; 1988 struct gendisk *disk = sdkp->disk;
1988 1989
1990 spin_lock(&sd_index_lock);
1989 ida_remove(&sd_index_ida, sdkp->index); 1991 ida_remove(&sd_index_ida, sdkp->index);
1992 spin_unlock(&sd_index_lock);
1990 1993
1991 disk->private_data = NULL; 1994 disk->private_data = NULL;
1992 put_disk(disk); 1995 put_disk(disk);