X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=drivers%2Ftarget%2Ftarget_core_cdb.c;h=8d5a0fc3a22053a8632ec9e7af856c4339b87611;hb=dd3a5ad8e0c8706659f02c4a72b8c87f6f7ab479;hp=7f19c8b7b84c704c0ab74ffdef7a19dca63737e2;hpb=dc87c55120b0a5b0c4d731183f8bb348981aba65;p=firefly-linux-kernel-4.4.55.git diff --git a/drivers/target/target_core_cdb.c b/drivers/target/target_core_cdb.c index 7f19c8b7b84c..8d5a0fc3a220 100644 --- a/drivers/target/target_core_cdb.c +++ b/drivers/target/target_core_cdb.c @@ -64,9 +64,9 @@ target_fill_alua_data(struct se_port *port, unsigned char *buf) static int target_emulate_inquiry_std(struct se_cmd *cmd) { - struct se_lun *lun = SE_LUN(cmd); - struct se_device *dev = SE_DEV(cmd); - unsigned char *buf = cmd->t_task->t_task_buf; + struct se_lun *lun = cmd->se_lun; + struct se_device *dev = cmd->se_dev; + unsigned char *buf = cmd->t_task.t_task_buf; /* * Make sure we at least have 6 bytes of INQUIRY response @@ -75,7 +75,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd) if (cmd->data_length < 6) { printk(KERN_ERR "SCSI Inquiry payload length: %u" " too small for EVPD=0\n", cmd->data_length); - return -1; + return -EINVAL; } buf[0] = dev->transport->get_device_type(dev); @@ -86,7 +86,7 @@ target_emulate_inquiry_std(struct se_cmd *cmd) /* * Enable SCCS and TPGS fields for Emulated ALUA */ - if (T10_ALUA(dev->se_sub_dev)->alua_type == SPC3_ALUA_EMULATED) + if (dev->se_sub_dev->t10_alua.alua_type == SPC3_ALUA_EMULATED) target_fill_alua_data(lun->lun_sep, buf); if (cmd->data_length < 8) { @@ -107,9 +107,9 @@ target_emulate_inquiry_std(struct se_cmd *cmd) snprintf((unsigned char *)&buf[8], 8, "LIO-ORG"); snprintf((unsigned char *)&buf[16], 16, "%s", - &DEV_T10_WWN(dev)->model[0]); + &dev->se_sub_dev->t10_wwn.model[0]); snprintf((unsigned char *)&buf[32], 4, "%s", - &DEV_T10_WWN(dev)->revision[0]); + &dev->se_sub_dev->t10_wwn.revision[0]); buf[4] = 31; /* Set additional length to 31 */ return 0; } @@ -128,7 +128,7 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) * Registered Extended LUN WWN has been set via ConfigFS * during device creation/restart. */ - if (SE_DEV(cmd)->se_sub_dev->su_dev_flags & + if (cmd->se_dev->se_sub_dev->su_dev_flags & SDF_EMULATED_VPD_UNIT_SERIAL) { buf[3] = 3; buf[5] = 0x80; @@ -143,7 +143,7 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) static int target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) { - struct se_device *dev = SE_DEV(cmd); + struct se_device *dev = cmd->se_dev; u16 len = 0; buf[1] = 0x80; @@ -152,7 +152,7 @@ target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) u32 unit_serial_len; unit_serial_len = - strlen(&DEV_T10_WWN(dev)->unit_serial[0]); + strlen(&dev->se_sub_dev->t10_wwn.unit_serial[0]); unit_serial_len++; /* For NULL Terminator */ if (((len + 4) + unit_serial_len) > cmd->data_length) { @@ -162,7 +162,7 @@ target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) return 0; } len += sprintf((unsigned char *)&buf[4], "%s", - &DEV_T10_WWN(dev)->unit_serial[0]); + &dev->se_sub_dev->t10_wwn.unit_serial[0]); len++; /* Extra Byte for NULL Terminator */ buf[3] = len; } @@ -176,15 +176,15 @@ target_emulate_evpd_80(struct se_cmd *cmd, unsigned char *buf) static int target_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) { - struct se_device *dev = SE_DEV(cmd); - struct se_lun *lun = SE_LUN(cmd); + struct se_device *dev = cmd->se_dev; + struct se_lun *lun = cmd->se_lun; struct se_port *port = NULL; struct se_portal_group *tpg = NULL; struct t10_alua_lu_gp_member *lu_gp_mem; struct t10_alua_tg_pt_gp *tg_pt_gp; struct t10_alua_tg_pt_gp_member *tg_pt_gp_mem; unsigned char binary, binary_new; - unsigned char *prod = &DEV_T10_WWN(dev)->model[0]; + unsigned char *prod = &dev->se_sub_dev->t10_wwn.model[0]; u32 prod_len; u32 unit_serial_len, off = 0; int i; @@ -238,11 +238,11 @@ target_emulate_evpd_83(struct se_cmd *cmd, unsigned char *buf) * VENDOR_SPECIFIC_IDENTIFIER_EXTENTION */ binary = transport_asciihex_to_binaryhex( - &DEV_T10_WWN(dev)->unit_serial[0]); + &dev->se_sub_dev->t10_wwn.unit_serial[0]); buf[off++] |= (binary & 0xf0) >> 4; for (i = 0; i < 24; i += 2) { binary_new = transport_asciihex_to_binaryhex( - &DEV_T10_WWN(dev)->unit_serial[i+2]); + &dev->se_sub_dev->t10_wwn.unit_serial[i+2]); buf[off] = (binary & 0x0f) << 4; buf[off++] |= (binary_new & 0xf0) >> 4; binary = binary_new; @@ -263,7 +263,7 @@ check_t10_vend_desc: if (dev->se_sub_dev->su_dev_flags & SDF_EMULATED_VPD_UNIT_SERIAL) { unit_serial_len = - strlen(&DEV_T10_WWN(dev)->unit_serial[0]); + strlen(&dev->se_sub_dev->t10_wwn.unit_serial[0]); unit_serial_len++; /* For NULL Terminator */ if ((len + (id_len + 4) + @@ -274,7 +274,7 @@ check_t10_vend_desc: } id_len += sprintf((unsigned char *)&buf[off+12], "%s:%s", prod, - &DEV_T10_WWN(dev)->unit_serial[0]); + &dev->se_sub_dev->t10_wwn.unit_serial[0]); } buf[off] = 0x2; /* ASCII */ buf[off+1] = 0x1; /* T10 Vendor ID */ @@ -312,7 +312,7 @@ check_port: goto check_tpgi; } buf[off] = - (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4); + (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); buf[off++] |= 0x1; /* CODE SET == Binary */ buf[off] = 0x80; /* Set PIV=1 */ /* Set ASSOICATION == target port: 01b */ @@ -335,7 +335,7 @@ check_port: * section 7.5.1 Table 362 */ check_tpgi: - if (T10_ALUA(dev->se_sub_dev)->alua_type != + if (dev->se_sub_dev->t10_alua.alua_type != SPC3_ALUA_EMULATED) goto check_scsi_name; @@ -357,7 +357,7 @@ check_tpgi: spin_unlock(&tg_pt_gp_mem->tg_pt_gp_mem_lock); buf[off] = - (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4); + (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); buf[off++] |= 0x1; /* CODE SET == Binary */ buf[off] = 0x80; /* Set PIV=1 */ /* Set ASSOICATION == target port: 01b */ @@ -409,7 +409,7 @@ check_lu_gp: * section 7.5.1 Table 362 */ check_scsi_name: - scsi_name_len = strlen(TPG_TFO(tpg)->tpg_get_wwn(tpg)); + scsi_name_len = strlen(tpg->se_tpg_tfo->tpg_get_wwn(tpg)); /* UTF-8 ",t,0x<16-bit TPGT>" + NULL Terminator */ scsi_name_len += 10; /* Check for 4-byte padding */ @@ -424,7 +424,7 @@ check_scsi_name: goto set_len; } buf[off] = - (TPG_TFO(tpg)->get_fabric_proto_ident(tpg) << 4); + (tpg->se_tpg_tfo->get_fabric_proto_ident(tpg) << 4); buf[off++] |= 0x3; /* CODE SET == UTF-8 */ buf[off] = 0x80; /* Set PIV=1 */ /* Set ASSOICATION == target port: 01b */ @@ -438,9 +438,9 @@ check_scsi_name: * Target Port, this means ",t,0x in * UTF-8 encoding. */ - tpgt = TPG_TFO(tpg)->tpg_get_tag(tpg); + tpgt = tpg->se_tpg_tfo->tpg_get_tag(tpg); scsi_name_len = sprintf(&buf[off], "%s,t,0x%04x", - TPG_TFO(tpg)->tpg_get_wwn(tpg), tpgt); + tpg->se_tpg_tfo->tpg_get_wwn(tpg), tpgt); scsi_name_len += 1 /* Include NULL terminator */; /* * The null-terminated, null-padded (see 4.4.2) SCSI @@ -477,7 +477,7 @@ target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) buf[5] = 0x07; /* If WriteCache emulation is enabled, set V_SUP */ - if (DEV_ATTRIB(SE_DEV(cmd))->emulate_write_cache > 0) + if (cmd->se_dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) buf[6] = 0x01; return 0; } @@ -486,7 +486,7 @@ target_emulate_evpd_86(struct se_cmd *cmd, unsigned char *buf) static int target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) { - struct se_device *dev = SE_DEV(cmd); + struct se_device *dev = cmd->se_dev; int have_tp = 0; /* @@ -494,14 +494,14 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) * emulate_tpu=1 or emulate_tpws=1 we will be expect a * different page length for Thin Provisioning. */ - if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws) + if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) have_tp = 1; if (cmd->data_length < (0x10 + 4)) { printk(KERN_INFO "Received data_length: %u" " too small for EVPD 0xb0\n", cmd->data_length); - return -1; + return -EINVAL; } if (have_tp && cmd->data_length < (0x3c + 4)) { @@ -523,12 +523,12 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) /* * Set MAXIMUM TRANSFER LENGTH */ - put_unaligned_be32(DEV_ATTRIB(dev)->max_sectors, &buf[8]); + put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_sectors, &buf[8]); /* * Set OPTIMAL TRANSFER LENGTH */ - put_unaligned_be32(DEV_ATTRIB(dev)->optimal_sectors, &buf[12]); + put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.optimal_sectors, &buf[12]); /* * Exit now if we don't support TP or the initiator sent a too @@ -540,25 +540,25 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) /* * Set MAXIMUM UNMAP LBA COUNT */ - put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_lba_count, &buf[20]); + put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_unmap_lba_count, &buf[20]); /* * Set MAXIMUM UNMAP BLOCK DESCRIPTOR COUNT */ - put_unaligned_be32(DEV_ATTRIB(dev)->max_unmap_block_desc_count, + put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.max_unmap_block_desc_count, &buf[24]); /* * Set OPTIMAL UNMAP GRANULARITY */ - put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity, &buf[28]); + put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.unmap_granularity, &buf[28]); /* * UNMAP GRANULARITY ALIGNMENT */ - put_unaligned_be32(DEV_ATTRIB(dev)->unmap_granularity_alignment, + put_unaligned_be32(dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment, &buf[32]); - if (DEV_ATTRIB(dev)->unmap_granularity_alignment != 0) + if (dev->se_sub_dev->se_dev_attrib.unmap_granularity_alignment != 0) buf[32] |= 0x80; /* Set the UGAVALID bit */ return 0; @@ -568,7 +568,7 @@ target_emulate_evpd_b0(struct se_cmd *cmd, unsigned char *buf) static int target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) { - struct se_device *dev = SE_DEV(cmd); + struct se_device *dev = cmd->se_dev; /* * From sbc3r22 section 6.5.4 Thin Provisioning VPD page: @@ -602,7 +602,7 @@ target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) * the UNMAP command (see 5.25). A TPU bit set to zero indicates * that the device server does not support the UNMAP command. */ - if (DEV_ATTRIB(dev)->emulate_tpu != 0) + if (dev->se_sub_dev->se_dev_attrib.emulate_tpu != 0) buf[5] = 0x80; /* @@ -611,7 +611,7 @@ target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) * A TPWS bit set to zero indicates that the device server does not * support the use of the WRITE SAME (16) command to unmap LBAs. */ - if (DEV_ATTRIB(dev)->emulate_tpws != 0) + if (dev->se_sub_dev->se_dev_attrib.emulate_tpws != 0) buf[5] |= 0x40; return 0; @@ -620,9 +620,9 @@ target_emulate_evpd_b2(struct se_cmd *cmd, unsigned char *buf) static int target_emulate_inquiry(struct se_cmd *cmd) { - struct se_device *dev = SE_DEV(cmd); - unsigned char *buf = cmd->t_task->t_task_buf; - unsigned char *cdb = cmd->t_task->t_task_cdb; + struct se_device *dev = cmd->se_dev; + unsigned char *buf = cmd->t_task.t_task_buf; + unsigned char *cdb = cmd->t_task.t_task_cdb; if (!(cdb[1] & 0x1)) return target_emulate_inquiry_std(cmd); @@ -637,7 +637,7 @@ target_emulate_inquiry(struct se_cmd *cmd) if (cmd->data_length < 4) { printk(KERN_ERR "SCSI Inquiry payload length: %u" " too small for EVPD=1\n", cmd->data_length); - return -1; + return -EINVAL; } buf[0] = dev->transport->get_device_type(dev); @@ -656,7 +656,7 @@ target_emulate_inquiry(struct se_cmd *cmd) return target_emulate_evpd_b2(cmd, buf); default: printk(KERN_ERR "Unknown VPD Code: 0x%02x\n", cdb[2]); - return -1; + return -EINVAL; } return 0; @@ -665,8 +665,8 @@ target_emulate_inquiry(struct se_cmd *cmd) static int target_emulate_readcapacity(struct se_cmd *cmd) { - struct se_device *dev = SE_DEV(cmd); - unsigned char *buf = cmd->t_task->t_task_buf; + struct se_device *dev = cmd->se_dev; + unsigned char *buf = cmd->t_task.t_task_buf; unsigned long long blocks_long = dev->transport->get_blocks(dev); u32 blocks; @@ -679,14 +679,14 @@ target_emulate_readcapacity(struct se_cmd *cmd) buf[1] = (blocks >> 16) & 0xff; buf[2] = (blocks >> 8) & 0xff; buf[3] = blocks & 0xff; - buf[4] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff; - buf[5] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff; - buf[6] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff; - buf[7] = DEV_ATTRIB(dev)->block_size & 0xff; + buf[4] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff; + buf[5] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff; + buf[6] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; + buf[7] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; /* * Set max 32-bit blocks to signal SERVICE ACTION READ_CAPACITY_16 */ - if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws) + if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) put_unaligned_be32(0xFFFFFFFF, &buf[0]); return 0; @@ -695,8 +695,8 @@ target_emulate_readcapacity(struct se_cmd *cmd) static int target_emulate_readcapacity_16(struct se_cmd *cmd) { - struct se_device *dev = SE_DEV(cmd); - unsigned char *buf = cmd->t_task->t_task_buf; + struct se_device *dev = cmd->se_dev; + unsigned char *buf = cmd->t_task.t_task_buf; unsigned long long blocks = dev->transport->get_blocks(dev); buf[0] = (blocks >> 56) & 0xff; @@ -707,15 +707,15 @@ target_emulate_readcapacity_16(struct se_cmd *cmd) buf[5] = (blocks >> 16) & 0xff; buf[6] = (blocks >> 8) & 0xff; buf[7] = blocks & 0xff; - buf[8] = (DEV_ATTRIB(dev)->block_size >> 24) & 0xff; - buf[9] = (DEV_ATTRIB(dev)->block_size >> 16) & 0xff; - buf[10] = (DEV_ATTRIB(dev)->block_size >> 8) & 0xff; - buf[11] = DEV_ATTRIB(dev)->block_size & 0xff; + buf[8] = (dev->se_sub_dev->se_dev_attrib.block_size >> 24) & 0xff; + buf[9] = (dev->se_sub_dev->se_dev_attrib.block_size >> 16) & 0xff; + buf[10] = (dev->se_sub_dev->se_dev_attrib.block_size >> 8) & 0xff; + buf[11] = dev->se_sub_dev->se_dev_attrib.block_size & 0xff; /* * Set Thin Provisioning Enable bit following sbc3r22 in section * READ CAPACITY (16) byte 14 if emulate_tpu or emulate_tpws is enabled. */ - if (DEV_ATTRIB(dev)->emulate_tpu || DEV_ATTRIB(dev)->emulate_tpws) + if (dev->se_sub_dev->se_dev_attrib.emulate_tpu || dev->se_sub_dev->se_dev_attrib.emulate_tpws) buf[14] = 0x80; return 0; @@ -765,8 +765,8 @@ target_modesense_control(struct se_device *dev, unsigned char *p) * for a BUSY, TASK SET FULL, or RESERVATION CONFLICT status regardless * to the number of commands completed with one of those status codes. */ - p[4] = (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 2) ? 0x30 : - (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00; + p[4] = (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 2) ? 0x30 : + (dev->se_sub_dev->se_dev_attrib.emulate_ua_intlck_ctrl == 1) ? 0x20 : 0x00; /* * From spc4r17, section 7.4.6 Control mode Page * @@ -779,7 +779,7 @@ target_modesense_control(struct se_device *dev, unsigned char *p) * which the command was received shall be completed with TASK ABORTED * status (see SAM-4). */ - p[5] = (DEV_ATTRIB(dev)->emulate_tas) ? 0x40 : 0x00; + p[5] = (dev->se_sub_dev->se_dev_attrib.emulate_tas) ? 0x40 : 0x00; p[8] = 0xff; p[9] = 0xff; p[11] = 30; @@ -792,7 +792,7 @@ target_modesense_caching(struct se_device *dev, unsigned char *p) { p[0] = 0x08; p[1] = 0x12; - if (DEV_ATTRIB(dev)->emulate_write_cache > 0) + if (dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) p[2] = 0x04; /* Write Cache Enable */ p[12] = 0x20; /* Disabled Read Ahead */ @@ -830,9 +830,9 @@ target_modesense_dpofua(unsigned char *buf, int type) static int target_emulate_modesense(struct se_cmd *cmd, int ten) { - struct se_device *dev = SE_DEV(cmd); - char *cdb = cmd->t_task->t_task_cdb; - unsigned char *rbuf = cmd->t_task->t_task_buf; + struct se_device *dev = cmd->se_dev; + char *cdb = cmd->t_task.t_task_cdb; + unsigned char *rbuf = cmd->t_task.t_task_buf; int type = dev->transport->get_device_type(dev); int offset = (ten) ? 8 : 4; int length = 0; @@ -867,13 +867,13 @@ target_emulate_modesense(struct se_cmd *cmd, int ten) buf[0] = (offset >> 8) & 0xff; buf[1] = offset & 0xff; - if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || + if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || (cmd->se_deve && (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) target_modesense_write_protect(&buf[3], type); - if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) && - (DEV_ATTRIB(dev)->emulate_fua_write > 0)) + if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && + (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) target_modesense_dpofua(&buf[3], type); if ((offset + 2) > cmd->data_length) @@ -883,13 +883,13 @@ target_emulate_modesense(struct se_cmd *cmd, int ten) offset -= 1; buf[0] = offset & 0xff; - if ((SE_LUN(cmd)->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || + if ((cmd->se_lun->lun_access & TRANSPORT_LUNFLAGS_READ_ONLY) || (cmd->se_deve && (cmd->se_deve->lun_flags & TRANSPORT_LUNFLAGS_READ_ONLY))) target_modesense_write_protect(&buf[2], type); - if ((DEV_ATTRIB(dev)->emulate_write_cache > 0) && - (DEV_ATTRIB(dev)->emulate_fua_write > 0)) + if ((dev->se_sub_dev->se_dev_attrib.emulate_write_cache > 0) && + (dev->se_sub_dev->se_dev_attrib.emulate_fua_write > 0)) target_modesense_dpofua(&buf[2], type); if ((offset + 1) > cmd->data_length) @@ -903,8 +903,8 @@ target_emulate_modesense(struct se_cmd *cmd, int ten) static int target_emulate_request_sense(struct se_cmd *cmd) { - unsigned char *cdb = cmd->t_task->t_task_cdb; - unsigned char *buf = cmd->t_task->t_task_buf; + unsigned char *cdb = cmd->t_task.t_task_cdb; + unsigned char *buf = cmd->t_task.t_task_buf; u8 ua_asc = 0, ua_ascq = 0; if (cdb[1] & 0x01) { @@ -963,10 +963,10 @@ target_emulate_request_sense(struct se_cmd *cmd) static int target_emulate_unmap(struct se_task *task) { - struct se_cmd *cmd = TASK_CMD(task); - struct se_device *dev = SE_DEV(cmd); - unsigned char *buf = cmd->t_task->t_task_buf, *ptr = NULL; - unsigned char *cdb = &cmd->t_task->t_task_cdb[0]; + struct se_cmd *cmd = task->task_se_cmd; + struct se_device *dev = cmd->se_dev; + unsigned char *buf = cmd->t_task.t_task_buf, *ptr = NULL; + unsigned char *cdb = &cmd->t_task.t_task_cdb[0]; sector_t lba; unsigned int size = cmd->data_length, range; int ret, offset; @@ -991,7 +991,7 @@ target_emulate_unmap(struct se_task *task) if (ret < 0) { printk(KERN_ERR "blkdev_issue_discard() failed: %d\n", ret); - return -1; + return ret; } ptr += 16; @@ -1008,23 +1008,35 @@ target_emulate_unmap(struct se_task *task) * Note this is not used for TCM/pSCSI passthrough */ static int -target_emulate_write_same(struct se_task *task) +target_emulate_write_same(struct se_task *task, int write_same32) { - struct se_cmd *cmd = TASK_CMD(task); - struct se_device *dev = SE_DEV(cmd); - sector_t lba = cmd->t_task->t_task_lba; - unsigned int range; + struct se_cmd *cmd = task->task_se_cmd; + struct se_device *dev = cmd->se_dev; + sector_t range, lba = cmd->t_task.t_task_lba; + unsigned int num_blocks; int ret; + /* + * Extract num_blocks from the WRITE_SAME_* CDB. Then use the explict + * range when non zero is supplied, otherwise calculate the remaining + * range based on ->get_blocks() - starting LBA. + */ + if (write_same32) + num_blocks = get_unaligned_be32(&cmd->t_task.t_task_cdb[28]); + else + num_blocks = get_unaligned_be32(&cmd->t_task.t_task_cdb[10]); - range = (cmd->data_length / DEV_ATTRIB(dev)->block_size); + if (num_blocks != 0) + range = num_blocks; + else + range = (dev->transport->get_blocks(dev) - lba); - printk(KERN_INFO "WRITE_SAME UNMAP: LBA: %llu Range: %u\n", - (unsigned long long)lba, range); + printk(KERN_INFO "WRITE_SAME UNMAP: LBA: %llu Range: %llu\n", + (unsigned long long)lba, (unsigned long long)range); ret = dev->transport->do_discard(dev, lba, range); if (ret < 0) { printk(KERN_INFO "blkdev_issue_discard() failed for WRITE_SAME\n"); - return -1; + return ret; } task->task_scsi_status = GOOD; @@ -1035,12 +1047,12 @@ target_emulate_write_same(struct se_task *task) int transport_emulate_control_cdb(struct se_task *task) { - struct se_cmd *cmd = TASK_CMD(task); - struct se_device *dev = SE_DEV(cmd); + struct se_cmd *cmd = task->task_se_cmd; + struct se_device *dev = cmd->se_dev; unsigned short service_action; int ret = 0; - switch (cmd->t_task->t_task_cdb[0]) { + switch (cmd->t_task.t_task_cdb[0]) { case INQUIRY: ret = target_emulate_inquiry(cmd); break; @@ -1054,13 +1066,13 @@ transport_emulate_control_cdb(struct se_task *task) ret = target_emulate_modesense(cmd, 1); break; case SERVICE_ACTION_IN: - switch (cmd->t_task->t_task_cdb[1] & 0x1f) { + switch (cmd->t_task.t_task_cdb[1] & 0x1f) { case SAI_READ_CAPACITY_16: ret = target_emulate_readcapacity_16(cmd); break; default: printk(KERN_ERR "Unsupported SA: 0x%02x\n", - cmd->t_task->t_task_cdb[1] & 0x1f); + cmd->t_task.t_task_cdb[1] & 0x1f); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } break; @@ -1081,11 +1093,11 @@ transport_emulate_control_cdb(struct se_task *task) " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } - ret = target_emulate_write_same(task); + ret = target_emulate_write_same(task, 0); break; case VARIABLE_LENGTH_CMD: service_action = - get_unaligned_be16(&cmd->t_task->t_task_cdb[8]); + get_unaligned_be16(&cmd->t_task.t_task_cdb[8]); switch (service_action) { case WRITE_SAME_32: if (!dev->transport->do_discard) { @@ -1094,7 +1106,7 @@ transport_emulate_control_cdb(struct se_task *task) dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } - ret = target_emulate_write_same(task); + ret = target_emulate_write_same(task, 1); break; default: printk(KERN_ERR "Unsupported VARIABLE_LENGTH_CMD SA:" @@ -1124,7 +1136,7 @@ transport_emulate_control_cdb(struct se_task *task) break; default: printk(KERN_ERR "Unsupported SCSI Opcode: 0x%02x for %s\n", - cmd->t_task->t_task_cdb[0], dev->transport->name); + cmd->t_task.t_task_cdb[0], dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; }