aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sd.c
diff options
context:
space:
mode:
authorJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-07-03 10:41:12 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2006-07-03 10:41:12 -0400
commitc4e00fac42f268ed0a547cdd1d12bb8399864040 (patch)
tree1a54d87be2066c49b71a03764fcb4fc7f9c68c41 /drivers/scsi/sd.c
parent29454dde27d8e340bb1987bad9aa504af7081eba (diff)
parentd6b0c53723753fc0cfda63f56735b225c43e1e9a (diff)
Merge ../scsi-misc-2.6
Conflicts: drivers/scsi/nsp32.c drivers/scsi/pcmcia/nsp_cs.c Removal of randomness flag conflicts with SA_ -> IRQF_ global replacement. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r--drivers/scsi/sd.c169
1 files changed, 88 insertions, 81 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index ea38757d12e5..3225d31449e1 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -207,6 +207,23 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf,
207 return count; 207 return count;
208} 208}
209 209
210static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf,
211 size_t count)
212{
213 struct scsi_disk *sdkp = to_scsi_disk(cdev);
214 struct scsi_device *sdp = sdkp->device;
215
216 if (!capable(CAP_SYS_ADMIN))
217 return -EACCES;
218
219 if (sdp->type != TYPE_DISK)
220 return -EINVAL;
221
222 sdp->allow_restart = simple_strtoul(buf, NULL, 10);
223
224 return count;
225}
226
210static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf) 227static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf)
211{ 228{
212 struct scsi_disk *sdkp = to_scsi_disk(cdev); 229 struct scsi_disk *sdkp = to_scsi_disk(cdev);
@@ -222,10 +239,19 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf)
222 return snprintf(buf, 20, "%u\n", sdkp->DPOFUA); 239 return snprintf(buf, 20, "%u\n", sdkp->DPOFUA);
223} 240}
224 241
242static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf)
243{
244 struct scsi_disk *sdkp = to_scsi_disk(cdev);
245
246 return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart);
247}
248
225static struct class_device_attribute sd_disk_attrs[] = { 249static struct class_device_attribute sd_disk_attrs[] = {
226 __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type, 250 __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
227 sd_store_cache_type), 251 sd_store_cache_type),
228 __ATTR(FUA, S_IRUGO, sd_show_fua, NULL), 252 __ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
253 __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart,
254 sd_store_allow_restart),
229 __ATTR_NULL, 255 __ATTR_NULL,
230}; 256};
231 257
@@ -890,11 +916,10 @@ static struct block_device_operations sd_fops = {
890static void sd_rw_intr(struct scsi_cmnd * SCpnt) 916static void sd_rw_intr(struct scsi_cmnd * SCpnt)
891{ 917{
892 int result = SCpnt->result; 918 int result = SCpnt->result;
893 int this_count = SCpnt->request_bufflen; 919 unsigned int xfer_size = SCpnt->request_bufflen;
894 int good_bytes = (result == 0 ? this_count : 0); 920 unsigned int good_bytes = result ? 0 : xfer_size;
895 sector_t block_sectors = 1; 921 u64 start_lba = SCpnt->request->sector;
896 u64 first_err_block; 922 u64 bad_lba;
897 sector_t error_sector;
898 struct scsi_sense_hdr sshdr; 923 struct scsi_sense_hdr sshdr;
899 int sense_valid = 0; 924 int sense_valid = 0;
900 int sense_deferred = 0; 925 int sense_deferred = 0;
@@ -905,7 +930,6 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
905 if (sense_valid) 930 if (sense_valid)
906 sense_deferred = scsi_sense_is_deferred(&sshdr); 931 sense_deferred = scsi_sense_is_deferred(&sshdr);
907 } 932 }
908
909#ifdef CONFIG_SCSI_LOGGING 933#ifdef CONFIG_SCSI_LOGGING
910 SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n", 934 SCSI_LOG_HLCOMPLETE(1, printk("sd_rw_intr: %s: res=0x%x\n",
911 SCpnt->request->rq_disk->disk_name, result)); 935 SCpnt->request->rq_disk->disk_name, result));
@@ -915,89 +939,72 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt)
915 sshdr.sense_key, sshdr.asc, sshdr.ascq)); 939 sshdr.sense_key, sshdr.asc, sshdr.ascq));
916 } 940 }
917#endif 941#endif
918 /* 942 if (driver_byte(result) != DRIVER_SENSE &&
919 Handle MEDIUM ERRORs that indicate partial success. Since this is a 943 (!sense_valid || sense_deferred))
920 relatively rare error condition, no care is taken to avoid 944 goto out;
921 unnecessary additional work such as memcpy's that could be avoided.
922 */
923 if (driver_byte(result) != 0 &&
924 sense_valid && !sense_deferred) {
925 switch (sshdr.sense_key) {
926 case MEDIUM_ERROR:
927 if (!blk_fs_request(SCpnt->request))
928 break;
929 info_valid = scsi_get_sense_info_fld(
930 SCpnt->sense_buffer, SCSI_SENSE_BUFFERSIZE,
931 &first_err_block);
932 /*
933 * May want to warn and skip if following cast results
934 * in actual truncation (if sector_t < 64 bits)
935 */
936 error_sector = (sector_t)first_err_block;
937 if (SCpnt->request->bio != NULL)
938 block_sectors = bio_sectors(SCpnt->request->bio);
939 switch (SCpnt->device->sector_size) {
940 case 1024:
941 error_sector <<= 1;
942 if (block_sectors < 2)
943 block_sectors = 2;
944 break;
945 case 2048:
946 error_sector <<= 2;
947 if (block_sectors < 4)
948 block_sectors = 4;
949 break;
950 case 4096:
951 error_sector <<=3;
952 if (block_sectors < 8)
953 block_sectors = 8;
954 break;
955 case 256:
956 error_sector >>= 1;
957 break;
958 default:
959 break;
960 }
961 945
962 error_sector &= ~(block_sectors - 1); 946 switch (sshdr.sense_key) {
963 good_bytes = (error_sector - SCpnt->request->sector) << 9; 947 case HARDWARE_ERROR:
964 if (good_bytes < 0 || good_bytes >= this_count) 948 case MEDIUM_ERROR:
965 good_bytes = 0; 949 if (!blk_fs_request(SCpnt->request))
950 goto out;
951 info_valid = scsi_get_sense_info_fld(SCpnt->sense_buffer,
952 SCSI_SENSE_BUFFERSIZE,
953 &bad_lba);
954 if (!info_valid)
955 goto out;
956 if (xfer_size <= SCpnt->device->sector_size)
957 goto out;
958 switch (SCpnt->device->sector_size) {
959 case 256:
960 start_lba <<= 1;
966 break; 961 break;
967 962 case 512:
968 case RECOVERED_ERROR: /* an error occurred, but it recovered */
969 case NO_SENSE: /* LLDD got sense data */
970 /*
971 * Inform the user, but make sure that it's not treated
972 * as a hard error.
973 */
974 scsi_print_sense("sd", SCpnt);
975 SCpnt->result = 0;
976 memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
977 good_bytes = this_count;
978 break; 963 break;
979 964 case 1024:
980 case ILLEGAL_REQUEST: 965 start_lba >>= 1;
981 if (SCpnt->device->use_10_for_rw && 966 break;
982 (SCpnt->cmnd[0] == READ_10 || 967 case 2048:
983 SCpnt->cmnd[0] == WRITE_10)) 968 start_lba >>= 2;
984 SCpnt->device->use_10_for_rw = 0; 969 break;
985 if (SCpnt->device->use_10_for_ms && 970 case 4096:
986 (SCpnt->cmnd[0] == MODE_SENSE_10 || 971 start_lba >>= 3;
987 SCpnt->cmnd[0] == MODE_SELECT_10))
988 SCpnt->device->use_10_for_ms = 0;
989 break; 972 break;
990
991 default: 973 default:
974 /* Print something here with limiting frequency. */
975 goto out;
992 break; 976 break;
993 } 977 }
978 /* This computation should always be done in terms of
979 * the resolution of the device's medium.
980 */
981 good_bytes = (bad_lba - start_lba)*SCpnt->device->sector_size;
982 break;
983 case RECOVERED_ERROR:
984 case NO_SENSE:
985 /* Inform the user, but make sure that it's not treated
986 * as a hard error.
987 */
988 scsi_print_sense("sd", SCpnt);
989 SCpnt->result = 0;
990 memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
991 good_bytes = xfer_size;
992 break;
993 case ILLEGAL_REQUEST:
994 if (SCpnt->device->use_10_for_rw &&
995 (SCpnt->cmnd[0] == READ_10 ||
996 SCpnt->cmnd[0] == WRITE_10))
997 SCpnt->device->use_10_for_rw = 0;
998 if (SCpnt->device->use_10_for_ms &&
999 (SCpnt->cmnd[0] == MODE_SENSE_10 ||
1000 SCpnt->cmnd[0] == MODE_SELECT_10))
1001 SCpnt->device->use_10_for_ms = 0;
1002 break;
1003 default:
1004 break;
994 } 1005 }
995 /* 1006 out:
996 * This calls the generic completion function, now that we know 1007 scsi_io_completion(SCpnt, good_bytes);
997 * how many actual sectors finished, and how many sectors we need
998 * to say have failed.
999 */
1000 scsi_io_completion(SCpnt, good_bytes, block_sectors << 9);
1001} 1008}
1002 1009
1003static int media_not_present(struct scsi_disk *sdkp, 1010static int media_not_present(struct scsi_disk *sdkp,