Merge branch 'for-next' into for-linus
[safe/jmp/linux-2.6] / drivers / scsi / sd.c
index 5d94772..83881df 100644 (file)
@@ -1196,19 +1196,10 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                SCpnt->result = 0;
                memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE);
                break;
-       case ABORTED_COMMAND:
-               if (sshdr.asc == 0x10) { /* DIF: Disk detected corruption */
-                       scsi_print_result(SCpnt);
-                       scsi_print_sense("sd", SCpnt);
+       case ABORTED_COMMAND: /* DIF: Target detected corruption */
+       case ILLEGAL_REQUEST: /* DIX: Host detected corruption */
+               if (sshdr.asc == 0x10)
                        good_bytes = sd_completed_bytes(SCpnt);
-               }
-               break;
-       case ILLEGAL_REQUEST:
-               if (sshdr.asc == 0x10) { /* DIX: HBA detected corruption */
-                       scsi_print_result(SCpnt);
-                       scsi_print_sense("sd", SCpnt);
-                       good_bytes = sd_completed_bytes(SCpnt);
-               }
                break;
        default:
                break;
@@ -1218,8 +1209,19 @@ static int sd_done(struct scsi_cmnd *SCpnt)
                sd_dif_complete(SCpnt, good_bytes);
 
        if (scsi_host_dif_capable(sdkp->device->host, sdkp->protection_type)
-           == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd)
+           == SD_DIF_TYPE2_PROTECTION && SCpnt->cmnd != SCpnt->request->cmd) {
+
+               /* We have to print a failed command here as the
+                * extended CDB gets freed before scsi_io_completion()
+                * is called.
+                */
+               if (result)
+                       scsi_print_command(SCpnt);
+
                mempool_free(SCpnt->cmnd, sd_cdb_pool);
+               SCpnt->cmnd = NULL;
+               SCpnt->cmd_len = 0;
+       }
 
        return good_bytes;
 }
@@ -1946,13 +1948,13 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
 {
        struct request_queue *q = sdkp->disk->queue;
        unsigned int sector_sz = sdkp->device->sector_size;
-       char *buffer;
+       const int vpd_len = 32;
+       unsigned char *buffer = kmalloc(vpd_len, GFP_KERNEL);
 
-       /* Block Limits VPD */
-       buffer = scsi_get_vpd_page(sdkp->device, 0xb0);
-
-       if (buffer == NULL)
-               return;
+       if (!buffer ||
+           /* Block Limits VPD */
+           scsi_get_vpd_page(sdkp->device, 0xb0, buffer, vpd_len))
+               goto out;
 
        blk_queue_io_min(sdkp->disk->queue,
                         get_unaligned_be16(&buffer[6]) * sector_sz);
@@ -1984,6 +1986,7 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
                                get_unaligned_be32(&buffer[32]) & ~(1 << 31);
        }
 
+ out:
        kfree(buffer);
 }
 
@@ -1993,20 +1996,23 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
  */
 static void sd_read_block_characteristics(struct scsi_disk *sdkp)
 {
-       char *buffer;
+       unsigned char *buffer;
        u16 rot;
+       const int vpd_len = 32;
 
-       /* Block Device Characteristics VPD */
-       buffer = scsi_get_vpd_page(sdkp->device, 0xb1);
+       buffer = kmalloc(vpd_len, GFP_KERNEL);
 
-       if (buffer == NULL)
-               return;
+       if (!buffer ||
+           /* Block Device Characteristics VPD */
+           scsi_get_vpd_page(sdkp->device, 0xb1, buffer, vpd_len))
+               goto out;
 
        rot = get_unaligned_be16(&buffer[4]);
 
        if (rot == 1)
                queue_flag_set_unlocked(QUEUE_FLAG_NONROT, sdkp->disk->queue);
 
+ out:
        kfree(buffer);
 }