diff options
Diffstat (limited to 'drivers/scsi/scsi_debug.c')
-rw-r--r-- | drivers/scsi/scsi_debug.c | 31 |
1 files changed, 16 insertions, 15 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index d81158b71326..2e32a4c09fbc 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c | |||
@@ -3044,18 +3044,12 @@ resp_comp_write(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | |||
3044 | u8 num; | 3044 | u8 num; |
3045 | unsigned long iflags; | 3045 | unsigned long iflags; |
3046 | int ret; | 3046 | int ret; |
3047 | int retval = 0; | ||
3047 | 3048 | ||
3048 | lba = get_unaligned_be32(cmd + 2); | 3049 | lba = get_unaligned_be64(cmd + 2); |
3049 | num = cmd[13]; /* 1 to a maximum of 255 logical blocks */ | 3050 | num = cmd[13]; /* 1 to a maximum of 255 logical blocks */ |
3050 | if (0 == num) | 3051 | if (0 == num) |
3051 | return 0; /* degenerate case, not an error */ | 3052 | return 0; /* degenerate case, not an error */ |
3052 | dnum = 2 * num; | ||
3053 | arr = kzalloc(dnum * lb_size, GFP_ATOMIC); | ||
3054 | if (NULL == arr) { | ||
3055 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, | ||
3056 | INSUFF_RES_ASCQ); | ||
3057 | return check_condition_result; | ||
3058 | } | ||
3059 | if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && | 3053 | if (scsi_debug_dif == SD_DIF_TYPE2_PROTECTION && |
3060 | (cmd[1] & 0xe0)) { | 3054 | (cmd[1] & 0xe0)) { |
3061 | mk_sense_invalid_opcode(scp); | 3055 | mk_sense_invalid_opcode(scp); |
@@ -3078,6 +3072,13 @@ resp_comp_write(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | |||
3078 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); | 3072 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); |
3079 | return check_condition_result; | 3073 | return check_condition_result; |
3080 | } | 3074 | } |
3075 | dnum = 2 * num; | ||
3076 | arr = kzalloc(dnum * lb_size, GFP_ATOMIC); | ||
3077 | if (NULL == arr) { | ||
3078 | mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, | ||
3079 | INSUFF_RES_ASCQ); | ||
3080 | return check_condition_result; | ||
3081 | } | ||
3081 | 3082 | ||
3082 | write_lock_irqsave(&atomic_rw, iflags); | 3083 | write_lock_irqsave(&atomic_rw, iflags); |
3083 | 3084 | ||
@@ -3088,24 +3089,24 @@ resp_comp_write(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) | |||
3088 | ret = do_device_access(scp, 0, dnum, true); | 3089 | ret = do_device_access(scp, 0, dnum, true); |
3089 | fake_storep = fake_storep_hold; | 3090 | fake_storep = fake_storep_hold; |
3090 | if (ret == -1) { | 3091 | if (ret == -1) { |
3091 | write_unlock_irqrestore(&atomic_rw, iflags); | 3092 | retval = DID_ERROR << 16; |
3092 | kfree(arr); | 3093 | goto cleanup; |
3093 | return DID_ERROR << 16; | ||
3094 | } else if ((ret < (dnum * lb_size)) && | 3094 | } else if ((ret < (dnum * lb_size)) && |
3095 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) | 3095 | (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)) |
3096 | sdev_printk(KERN_INFO, scp->device, "%s: compare_write: cdb " | 3096 | sdev_printk(KERN_INFO, scp->device, "%s: compare_write: cdb " |
3097 | "indicated=%u, IO sent=%d bytes\n", my_name, | 3097 | "indicated=%u, IO sent=%d bytes\n", my_name, |
3098 | dnum * lb_size, ret); | 3098 | dnum * lb_size, ret); |
3099 | if (!comp_write_worker(lba, num, arr)) { | 3099 | if (!comp_write_worker(lba, num, arr)) { |
3100 | write_unlock_irqrestore(&atomic_rw, iflags); | ||
3101 | kfree(arr); | ||
3102 | mk_sense_buffer(scp, MISCOMPARE, MISCOMPARE_VERIFY_ASC, 0); | 3100 | mk_sense_buffer(scp, MISCOMPARE, MISCOMPARE_VERIFY_ASC, 0); |
3103 | return check_condition_result; | 3101 | retval = check_condition_result; |
3102 | goto cleanup; | ||
3104 | } | 3103 | } |
3105 | if (scsi_debug_lbp()) | 3104 | if (scsi_debug_lbp()) |
3106 | map_region(lba, num); | 3105 | map_region(lba, num); |
3106 | cleanup: | ||
3107 | write_unlock_irqrestore(&atomic_rw, iflags); | 3107 | write_unlock_irqrestore(&atomic_rw, iflags); |
3108 | return 0; | 3108 | kfree(arr); |
3109 | return retval; | ||
3109 | } | 3110 | } |
3110 | 3111 | ||
3111 | struct unmap_block_desc { | 3112 | struct unmap_block_desc { |