diff options
Diffstat (limited to 'drivers/scsi/sd.c')
-rw-r--r-- | drivers/scsi/sd.c | 54 |
1 files changed, 30 insertions, 24 deletions
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 255da53e5a01..1dd4d8407694 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -1196,19 +1196,10 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1196 | SCpnt->result = 0; | 1196 | SCpnt->result = 0; |
1197 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); | 1197 | memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); |
1198 | break; | 1198 | break; |
1199 | case ABORTED_COMMAND: | 1199 | case ABORTED_COMMAND: /* DIF: Target detected corruption */ |
1200 | if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */ | 1200 | case ILLEGAL_REQUEST: /* DIX: Host detected corruption */ |
1201 | scsi_print_result(SCpnt); | 1201 | if (sshdr.asc == 0x10) |
1202 | scsi_print_sense("sd", SCpnt); | ||
1203 | good_bytes = sd_completed_bytes(SCpnt); | 1202 | good_bytes = sd_completed_bytes(SCpnt); |
1204 | } | ||
1205 | break; | ||
1206 | case ILLEGAL_REQUEST: | ||
1207 | if (sshdr.asc == 0x10) { /* DIX: HBA detected corruption */ | ||
1208 | scsi_print_result(SCpnt); | ||
1209 | scsi_print_sense("sd", SCpnt); | ||
1210 | good_bytes = sd_completed_bytes(SCpnt); | ||
1211 | } | ||
1212 | break; | 1203 | break; |
1213 | default: | 1204 | default: |
1214 | break; | 1205 | break; |
@@ -1218,8 +1209,19 @@ static int sd_done(struct scsi_cmnd *SCpnt) | |||
1218 | sd_dif_complete(SCpnt, good_bytes); | 1209 | sd_dif_complete(SCpnt, good_bytes); |
1219 | 1210 | ||
1220 | if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type) | 1211 | if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type) |
1221 | == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) | 1212 | == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) { |
1213 | |||
1214 | /* We have to print a failed command here as the | ||
1215 | * extended CDB gets freed before scsi_io_completion() | ||
1216 | * is called. | ||
1217 | */ | ||
1218 | if (result) | ||
1219 | scsi_print_command(SCpnt); | ||
1220 | |||
1222 | mempool_free(SCpnt->cmnd, sd_cdb_pool); | 1221 | mempool_free(SCpnt->cmnd, sd_cdb_pool); |
1222 | SCpnt->cmnd = NULL; | ||
1223 | SCpnt->cmd_len = 0; | ||
1224 | } | ||
1223 | 1225 | ||
1224 | return good_bytes; | 1226 | return good_bytes; |
1225 | } | 1227 | } |
@@ -1946,13 +1948,13 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
1946 | { | 1948 | { |
1947 | struct request_queue *q = sdkp->disk->queue; | 1949 | struct request_queue *q = sdkp->disk->queue; |
1948 | unsigned int sector_sz = sdkp->device->sector_size; | 1950 | unsigned int sector_sz = sdkp->device->sector_size; |
1949 | char *buffer; | 1951 | const int vpd_len = 32; |
1952 | unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL); | ||
1950 | 1953 | ||
1951 | /* Block Limits VPD */ | 1954 | if (!buffer || |
1952 | buffer = scsi_get_vpd_page(sdkp->device, 0xb0); | 1955 | /* Block Limits VPD */ |
1953 | 1956 | scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len)) | |
1954 | if (buffer == NULL) | 1957 | goto out; |
1955 | return; | ||
1956 | 1958 | ||
1957 | blk_queue_io_min(sdkp->disk->queue, | 1959 | blk_queue_io_min(sdkp->disk->queue, |
1958 | get_unaligned_be16(&buffer[6]) * sector_sz); | 1960 | get_unaligned_be16(&buffer[6]) * sector_sz); |
@@ -1984,6 +1986,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
1984 | get_unaligned_be32(&buffer[32]) & ~(1 << 31); | 1986 | get_unaligned_be32(&buffer[32]) & ~(1 << 31); |
1985 | } | 1987 | } |
1986 | 1988 | ||
1989 | out: | ||
1987 | kfree(buffer); | 1990 | kfree(buffer); |
1988 | } | 1991 | } |
1989 | 1992 | ||
@@ -1993,20 +1996,23 @@ static void sd_read_block_limits(struct scsi_disk *sdkp) | |||
1993 | */ | 1996 | */ |
1994 | static void sd_read_block_characteristics(struct scsi_disk *sdkp) | 1997 | static void sd_read_block_characteristics(struct scsi_disk *sdkp) |
1995 | { | 1998 | { |
1996 | char *buffer; | 1999 | unsigned char *buffer; |
1997 | u16 rot; | 2000 | u16 rot; |
2001 | const int vpd_len = 32; | ||
1998 | 2002 | ||
1999 | /* Block Device Characteristics VPD */ | 2003 | buffer = kmalloc(vpd_len, GFP_KERNEL); |
2000 | buffer = scsi_get_vpd_page(sdkp->device, 0xb1); | ||
2001 | 2004 | ||
2002 | if (buffer == NULL) | 2005 | if (!buffer || |
2003 | return; | 2006 | /* Block Device Characteristics VPD */ |
2007 | scsi_get_vpd_page(sdkp->device, 0xb1, buffer, vpd_len)) | ||
2008 | goto out; | ||
2004 | 2009 | ||
2005 | rot = get_unaligned_be16(&buffer[4]); | 2010 | rot = get_unaligned_be16(&buffer[4]); |
2006 | 2011 | ||
2007 | if (rot == 1) | 2012 | if (rot == 1) |
2008 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue); | 2013 | queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue); |
2009 | 2014 | ||
2015 | out: | ||
2010 | kfree(buffer); | 2016 | kfree(buffer); |
2011 | } | 2017 | } |
2012 | 2018 | ||