aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-01-14 19:29:49 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2011-01-14 19:29:49 -0500
commit38567333a6dabd0f2b4150e9fb6dd8e3ba2985e5 (patch)
tree1101e3df845ce804035335f80ef3467397bd5373 /drivers/scsi
parentde23be5f3580f7b9b52cad6633bb3a3cd13abafe (diff)
parentc66ac9db8d4ad9994a02b3e933ea2ccc643e1fe5 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-post-merge-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-post-merge-2.6: [SCSI] target: Add LIO target core v4.0.0-rc6 [SCSI] sd,sr: kill compat SDEV_MEDIA_CHANGE event [SCSI] sd: implement sd_check_events()
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/sd.c103
-rw-r--r--drivers/scsi/sd.h1
-rw-r--r--drivers/scsi/sr.c4
3 files changed, 50 insertions, 58 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index b65e65aa07eb..e56730214c05 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -990,30 +990,51 @@ out:
990 990
991static void set_media_not_present(struct scsi_disk *sdkp) 991static void set_media_not_present(struct scsi_disk *sdkp)
992{ 992{
993 sdkp->media_present = 0; 993 if (sdkp->media_present)
994 sdkp->capacity = 0; 994 sdkp->device->changed = 1;
995 sdkp->device->changed = 1; 995
996 if (sdkp->device->removable) {
997 sdkp->media_present = 0;
998 sdkp->capacity = 0;
999 }
1000}
1001
1002static int media_not_present(struct scsi_disk *sdkp,
1003 struct scsi_sense_hdr *sshdr)
1004{
1005 if (!scsi_sense_valid(sshdr))
1006 return 0;
1007
1008 /* not invoked for commands that could return deferred errors */
1009 switch (sshdr->sense_key) {
1010 case UNIT_ATTENTION:
1011 case NOT_READY:
1012 /* medium not present */
1013 if (sshdr->asc == 0x3A) {
1014 set_media_not_present(sdkp);
1015 return 1;
1016 }
1017 }
1018 return 0;
996} 1019}
997 1020
998/** 1021/**
999 * sd_media_changed - check if our medium changed 1022 * sd_check_events - check media events
1000 * @disk: kernel device descriptor 1023 * @disk: kernel device descriptor
1024 * @clearing: disk events currently being cleared
1001 * 1025 *
1002 * Returns 0 if not applicable or no change; 1 if change 1026 * Returns mask of DISK_EVENT_*.
1003 * 1027 *
1004 * Note: this function is invoked from the block subsystem. 1028 * Note: this function is invoked from the block subsystem.
1005 **/ 1029 **/
1006static int sd_media_changed(struct gendisk *disk) 1030static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing)
1007{ 1031{
1008 struct scsi_disk *sdkp = scsi_disk(disk); 1032 struct scsi_disk *sdkp = scsi_disk(disk);
1009 struct scsi_device *sdp = sdkp->device; 1033 struct scsi_device *sdp = sdkp->device;
1010 struct scsi_sense_hdr *sshdr = NULL; 1034 struct scsi_sense_hdr *sshdr = NULL;
1011 int retval; 1035 int retval;
1012 1036
1013 SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); 1037 SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n"));
1014
1015 if (!sdp->removable)
1016 return 0;
1017 1038
1018 /* 1039 /*
1019 * If the device is offline, don't send any commands - just pretend as 1040 * If the device is offline, don't send any commands - just pretend as
@@ -1043,40 +1064,32 @@ static int sd_media_changed(struct gendisk *disk)
1043 sshdr); 1064 sshdr);
1044 } 1065 }
1045 1066
1046 if (retval) { 1067 /* failed to execute TUR, assume media not present */
1068 if (host_byte(retval)) {
1047 set_media_not_present(sdkp); 1069 set_media_not_present(sdkp);
1048 goto out; 1070 goto out;
1049 } 1071 }
1050 1072
1073 if (media_not_present(sdkp, sshdr))
1074 goto out;
1075
1051 /* 1076 /*
1052 * For removable scsi disk we have to recognise the presence 1077 * For removable scsi disk we have to recognise the presence
1053 * of a disk in the drive. This is kept in the struct scsi_disk 1078 * of a disk in the drive.
1054 * struct and tested at open ! Daniel Roche (dan@lectra.fr)
1055 */ 1079 */
1080 if (!sdkp->media_present)
1081 sdp->changed = 1;
1056 sdkp->media_present = 1; 1082 sdkp->media_present = 1;
1057
1058out: 1083out:
1059 /* 1084 /*
1060 * Report a media change under the following conditions: 1085 * sdp->changed is set under the following conditions:
1061 *
1062 * Medium is present now and wasn't present before.
1063 * Medium wasn't present before and is present now.
1064 * Medium was present at all times, but it changed while
1065 * we weren't looking (sdp->changed is set).
1066 * 1086 *
1067 * If there was no medium before and there is no medium now then 1087 * Medium present state has changed in either direction.
1068 * don't report a change, even if a medium was inserted and removed 1088 * Device has indicated UNIT_ATTENTION.
1069 * while we weren't looking.
1070 */ 1089 */
1071 retval = (sdkp->media_present != sdkp->previous_state ||
1072 (sdkp->media_present && sdp->changed));
1073 if (retval)
1074 sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL);
1075 sdkp->previous_state = sdkp->media_present;
1076
1077 /* sdp->changed indicates medium was changed or is not present */
1078 sdp->changed = !sdkp->media_present;
1079 kfree(sshdr); 1090 kfree(sshdr);
1091 retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0;
1092 sdp->changed = 0;
1080 return retval; 1093 return retval;
1081} 1094}
1082 1095
@@ -1169,7 +1182,7 @@ static const struct block_device_operations sd_fops = {
1169#ifdef CONFIG_COMPAT 1182#ifdef CONFIG_COMPAT
1170 .compat_ioctl = sd_compat_ioctl, 1183 .compat_ioctl = sd_compat_ioctl,
1171#endif 1184#endif
1172 .media_changed = sd_media_changed, 1185 .check_events = sd_check_events,
1173 .revalidate_disk = sd_revalidate_disk, 1186 .revalidate_disk = sd_revalidate_disk,
1174 .unlock_native_capacity = sd_unlock_native_capacity, 1187 .unlock_native_capacity = sd_unlock_native_capacity,
1175}; 1188};
@@ -1312,23 +1325,6 @@ static int sd_done(struct scsi_cmnd *SCpnt)
1312 return good_bytes; 1325 return good_bytes;
1313} 1326}
1314 1327
1315static int media_not_present(struct scsi_disk *sdkp,
1316 struct scsi_sense_hdr *sshdr)
1317{
1318
1319 if (!scsi_sense_valid(sshdr))
1320 return 0;
1321 /* not invoked for commands that could return deferred errors */
1322 if (sshdr->sense_key != NOT_READY &&
1323 sshdr->sense_key != UNIT_ATTENTION)
1324 return 0;
1325 if (sshdr->asc != 0x3A) /* medium not present */
1326 return 0;
1327
1328 set_media_not_present(sdkp);
1329 return 1;
1330}
1331
1332/* 1328/*
1333 * spinup disk - called only in sd_revalidate_disk() 1329 * spinup disk - called only in sd_revalidate_disk()
1334 */ 1330 */
@@ -1503,7 +1499,7 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
1503 */ 1499 */
1504 if (sdp->removable && 1500 if (sdp->removable &&
1505 sense_valid && sshdr->sense_key == NOT_READY) 1501 sense_valid && sshdr->sense_key == NOT_READY)
1506 sdp->changed = 1; 1502 set_media_not_present(sdkp);
1507 1503
1508 /* 1504 /*
1509 * We used to set media_present to 0 here to indicate no media 1505 * We used to set media_present to 0 here to indicate no media
@@ -2389,8 +2385,10 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
2389 2385
2390 gd->driverfs_dev = &sdp->sdev_gendev; 2386 gd->driverfs_dev = &sdp->sdev_gendev;
2391 gd->flags = GENHD_FL_EXT_DEVT; 2387 gd->flags = GENHD_FL_EXT_DEVT;
2392 if (sdp->removable) 2388 if (sdp->removable) {
2393 gd->flags |= GENHD_FL_REMOVABLE; 2389 gd->flags |= GENHD_FL_REMOVABLE;
2390 gd->events |= DISK_EVENT_MEDIA_CHANGE;
2391 }
2394 2392
2395 add_disk(gd); 2393 add_disk(gd);
2396 sd_dif_config_host(sdkp); 2394 sd_dif_config_host(sdkp);
@@ -2472,7 +2470,6 @@ static int sd_probe(struct device *dev)
2472 sdkp->disk = gd; 2470 sdkp->disk = gd;
2473 sdkp->index = index; 2471 sdkp->index = index;
2474 atomic_set(&sdkp->openers, 0); 2472 atomic_set(&sdkp->openers, 0);
2475 sdkp->previous_state = 1;
2476 2473
2477 if (!sdp->request_queue->rq_timeout) { 2474 if (!sdp->request_queue->rq_timeout) {
2478 if (sdp->type != TYPE_MOD) 2475 if (sdp->type != TYPE_MOD)
diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h
index 55488faf0815..c9d8f6ca49e2 100644
--- a/drivers/scsi/sd.h
+++ b/drivers/scsi/sd.h
@@ -55,7 +55,6 @@ struct scsi_disk {
55 u8 media_present; 55 u8 media_present;
56 u8 write_prot; 56 u8 write_prot;
57 u8 protection_type;/* Data Integrity Field */ 57 u8 protection_type;/* Data Integrity Field */
58 unsigned previous_state : 1;
59 unsigned ATO : 1; /* state of disk ATO bit */ 58 unsigned ATO : 1; /* state of disk ATO bit */
60 unsigned WCE : 1; /* state of disk WCE bit */ 59 unsigned WCE : 1; /* state of disk WCE bit */
61 unsigned RCD : 1; /* state of disk RCD bit, unused */ 60 unsigned RCD : 1; /* state of disk RCD bit, unused */
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index be6baf8ad704..aefadc6a1607 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -249,10 +249,6 @@ skip_tur:
249 cd->device->changed = 0; 249 cd->device->changed = 0;
250 } 250 }
251 251
252 /* for backward compatibility */
253 if (events & DISK_EVENT_MEDIA_CHANGE)
254 sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE,
255 GFP_KERNEL);
256 return events; 252 return events;
257} 253}
258 254