Loading drivers/target/target_core_cdb.c +59 −46 Original line number Diff line number Diff line Loading @@ -680,8 +680,9 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) } static int target_emulate_inquiry(struct se_cmd *cmd) target_emulate_inquiry(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; unsigned char *buf; unsigned char *cdb = cmd->t_task_cdb; Loading Loading @@ -721,8 +722,9 @@ target_emulate_inquiry(struct se_cmd *cmd) } static int target_emulate_readcapacity(struct se_cmd *cmd) target_emulate_readcapacity(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; unsigned char *buf; unsigned long long blocks_long = dev->transport->get_blocks(dev); Loading Loading @@ -755,8 +757,9 @@ target_emulate_readcapacity(struct se_cmd *cmd) } static int target_emulate_readcapacity_16(struct se_cmd *cmd) target_emulate_readcapacity_16(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; unsigned char *buf; unsigned long long blocks = dev->transport->get_blocks(dev); Loading Loading @@ -923,13 +926,15 @@ target_modesense_dpofua(unsigned char *buf, int type) } static int target_emulate_modesense(struct se_cmd *cmd, int ten) target_emulate_modesense(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; char *cdb = cmd->t_task_cdb; unsigned char *rbuf; int type = dev->transport->get_device_type(dev); int offset = (ten) ? 8 : 4; int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); int offset = ten ? 8 : 4; int length = 0; unsigned char buf[SE_MODE_PAGE_BUF]; Loading Loading @@ -999,8 +1004,9 @@ target_emulate_modesense(struct se_cmd *cmd, int ten) } static int target_emulate_request_sense(struct se_cmd *cmd) target_emulate_request_sense(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; unsigned char *cdb = cmd->t_task_cdb; unsigned char *buf; u8 ua_asc = 0, ua_ascq = 0; Loading Loading @@ -1079,6 +1085,12 @@ target_emulate_unmap(struct se_task *task) int ret = 0, offset; unsigned short dl, bd_dl; if (!dev->transport->do_discard) { pr_err("UNMAP emulation not supported for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } /* First UNMAP block descriptor starts at 8 byte offset */ offset = 8; size -= 8; Loading Loading @@ -1119,13 +1131,28 @@ 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, u32 num_blocks) target_emulate_write_same(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; sector_t range; sector_t lba = cmd->t_task_lba; u32 num_blocks; int ret; if (!dev->transport->do_discard) { pr_err("WRITE_SAME emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } if (cmd->t_task_cdb[0] == WRITE_SAME) num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]); else if (cmd->t_task_cdb[0] == WRITE_SAME_16) num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]); else /* WRITE_SAME_32 via VARIABLE_LENGTH_CMD */ num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]); /* * Use the explicit range when non zero is supplied, otherwise calculate * the remaining range based on ->get_blocks() - starting LBA. Loading @@ -1147,6 +1174,21 @@ target_emulate_write_same(struct se_task *task, u32 num_blocks) return 0; } static int target_emulate_synchronize_cache(struct se_task *task) { struct se_device *dev = task->task_se_cmd->se_dev; if (!dev->transport->do_sync_cache) { pr_err("SYNCHRONIZE_CACHE emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } dev->transport->do_sync_cache(task); return 0; } int transport_emulate_control_cdb(struct se_task *task) { Loading @@ -1157,21 +1199,21 @@ transport_emulate_control_cdb(struct se_task *task) switch (cmd->t_task_cdb[0]) { case INQUIRY: ret = target_emulate_inquiry(cmd); ret = target_emulate_inquiry(task); break; case READ_CAPACITY: ret = target_emulate_readcapacity(cmd); ret = target_emulate_readcapacity(task); break; case MODE_SENSE: ret = target_emulate_modesense(cmd, 0); ret = target_emulate_modesense(task); break; case MODE_SENSE_10: ret = target_emulate_modesense(cmd, 1); ret = target_emulate_modesense(task); break; case SERVICE_ACTION_IN: switch (cmd->t_task_cdb[1] & 0x1f) { case SAI_READ_CAPACITY_16: ret = target_emulate_readcapacity_16(cmd); ret = target_emulate_readcapacity_16(task); break; default: pr_err("Unsupported SA: 0x%02x\n", Loading @@ -1180,47 +1222,23 @@ transport_emulate_control_cdb(struct se_task *task) } break; case REQUEST_SENSE: ret = target_emulate_request_sense(cmd); ret = target_emulate_request_sense(task); break; case UNMAP: if (!dev->transport->do_discard) { pr_err("UNMAP emulation not supported for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } ret = target_emulate_unmap(task); break; case WRITE_SAME: if (!dev->transport->do_discard) { pr_err("WRITE_SAME emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } ret = target_emulate_write_same(task, get_unaligned_be16(&cmd->t_task_cdb[7])); ret = target_emulate_write_same(task); break; case WRITE_SAME_16: if (!dev->transport->do_discard) { pr_err("WRITE_SAME_16 emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } ret = target_emulate_write_same(task, get_unaligned_be32(&cmd->t_task_cdb[10])); ret = target_emulate_write_same(task); break; case VARIABLE_LENGTH_CMD: service_action = get_unaligned_be16(&cmd->t_task_cdb[8]); switch (service_action) { case WRITE_SAME_32: if (!dev->transport->do_discard) { pr_err("WRITE_SAME_32 SA emulation not" " supported for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } ret = target_emulate_write_same(task, get_unaligned_be32(&cmd->t_task_cdb[28])); ret = target_emulate_write_same(task); break; default: pr_err("Unsupported VARIABLE_LENGTH_CMD SA:" Loading @@ -1230,12 +1248,7 @@ transport_emulate_control_cdb(struct se_task *task) break; case SYNCHRONIZE_CACHE: case 0x91: /* SYNCHRONIZE_CACHE_16: */ if (!dev->transport->do_sync_cache) { pr_err("SYNCHRONIZE_CACHE emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } dev->transport->do_sync_cache(task); ret = target_emulate_synchronize_cache(task); break; case ALLOW_MEDIUM_REMOVAL: case ERASE: Loading Loading
drivers/target/target_core_cdb.c +59 −46 Original line number Diff line number Diff line Loading @@ -680,8 +680,9 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf) } static int target_emulate_inquiry(struct se_cmd *cmd) target_emulate_inquiry(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; unsigned char *buf; unsigned char *cdb = cmd->t_task_cdb; Loading Loading @@ -721,8 +722,9 @@ target_emulate_inquiry(struct se_cmd *cmd) } static int target_emulate_readcapacity(struct se_cmd *cmd) target_emulate_readcapacity(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; unsigned char *buf; unsigned long long blocks_long = dev->transport->get_blocks(dev); Loading Loading @@ -755,8 +757,9 @@ target_emulate_readcapacity(struct se_cmd *cmd) } static int target_emulate_readcapacity_16(struct se_cmd *cmd) target_emulate_readcapacity_16(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; unsigned char *buf; unsigned long long blocks = dev->transport->get_blocks(dev); Loading Loading @@ -923,13 +926,15 @@ target_modesense_dpofua(unsigned char *buf, int type) } static int target_emulate_modesense(struct se_cmd *cmd, int ten) target_emulate_modesense(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; char *cdb = cmd->t_task_cdb; unsigned char *rbuf; int type = dev->transport->get_device_type(dev); int offset = (ten) ? 8 : 4; int ten = (cmd->t_task_cdb[0] == MODE_SENSE_10); int offset = ten ? 8 : 4; int length = 0; unsigned char buf[SE_MODE_PAGE_BUF]; Loading Loading @@ -999,8 +1004,9 @@ target_emulate_modesense(struct se_cmd *cmd, int ten) } static int target_emulate_request_sense(struct se_cmd *cmd) target_emulate_request_sense(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; unsigned char *cdb = cmd->t_task_cdb; unsigned char *buf; u8 ua_asc = 0, ua_ascq = 0; Loading Loading @@ -1079,6 +1085,12 @@ target_emulate_unmap(struct se_task *task) int ret = 0, offset; unsigned short dl, bd_dl; if (!dev->transport->do_discard) { pr_err("UNMAP emulation not supported for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } /* First UNMAP block descriptor starts at 8 byte offset */ offset = 8; size -= 8; Loading Loading @@ -1119,13 +1131,28 @@ 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, u32 num_blocks) target_emulate_write_same(struct se_task *task) { struct se_cmd *cmd = task->task_se_cmd; struct se_device *dev = cmd->se_dev; sector_t range; sector_t lba = cmd->t_task_lba; u32 num_blocks; int ret; if (!dev->transport->do_discard) { pr_err("WRITE_SAME emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } if (cmd->t_task_cdb[0] == WRITE_SAME) num_blocks = get_unaligned_be16(&cmd->t_task_cdb[7]); else if (cmd->t_task_cdb[0] == WRITE_SAME_16) num_blocks = get_unaligned_be32(&cmd->t_task_cdb[10]); else /* WRITE_SAME_32 via VARIABLE_LENGTH_CMD */ num_blocks = get_unaligned_be32(&cmd->t_task_cdb[28]); /* * Use the explicit range when non zero is supplied, otherwise calculate * the remaining range based on ->get_blocks() - starting LBA. Loading @@ -1147,6 +1174,21 @@ target_emulate_write_same(struct se_task *task, u32 num_blocks) return 0; } static int target_emulate_synchronize_cache(struct se_task *task) { struct se_device *dev = task->task_se_cmd->se_dev; if (!dev->transport->do_sync_cache) { pr_err("SYNCHRONIZE_CACHE emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } dev->transport->do_sync_cache(task); return 0; } int transport_emulate_control_cdb(struct se_task *task) { Loading @@ -1157,21 +1199,21 @@ transport_emulate_control_cdb(struct se_task *task) switch (cmd->t_task_cdb[0]) { case INQUIRY: ret = target_emulate_inquiry(cmd); ret = target_emulate_inquiry(task); break; case READ_CAPACITY: ret = target_emulate_readcapacity(cmd); ret = target_emulate_readcapacity(task); break; case MODE_SENSE: ret = target_emulate_modesense(cmd, 0); ret = target_emulate_modesense(task); break; case MODE_SENSE_10: ret = target_emulate_modesense(cmd, 1); ret = target_emulate_modesense(task); break; case SERVICE_ACTION_IN: switch (cmd->t_task_cdb[1] & 0x1f) { case SAI_READ_CAPACITY_16: ret = target_emulate_readcapacity_16(cmd); ret = target_emulate_readcapacity_16(task); break; default: pr_err("Unsupported SA: 0x%02x\n", Loading @@ -1180,47 +1222,23 @@ transport_emulate_control_cdb(struct se_task *task) } break; case REQUEST_SENSE: ret = target_emulate_request_sense(cmd); ret = target_emulate_request_sense(task); break; case UNMAP: if (!dev->transport->do_discard) { pr_err("UNMAP emulation not supported for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } ret = target_emulate_unmap(task); break; case WRITE_SAME: if (!dev->transport->do_discard) { pr_err("WRITE_SAME emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } ret = target_emulate_write_same(task, get_unaligned_be16(&cmd->t_task_cdb[7])); ret = target_emulate_write_same(task); break; case WRITE_SAME_16: if (!dev->transport->do_discard) { pr_err("WRITE_SAME_16 emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } ret = target_emulate_write_same(task, get_unaligned_be32(&cmd->t_task_cdb[10])); ret = target_emulate_write_same(task); break; case VARIABLE_LENGTH_CMD: service_action = get_unaligned_be16(&cmd->t_task_cdb[8]); switch (service_action) { case WRITE_SAME_32: if (!dev->transport->do_discard) { pr_err("WRITE_SAME_32 SA emulation not" " supported for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } ret = target_emulate_write_same(task, get_unaligned_be32(&cmd->t_task_cdb[28])); ret = target_emulate_write_same(task); break; default: pr_err("Unsupported VARIABLE_LENGTH_CMD SA:" Loading @@ -1230,12 +1248,7 @@ transport_emulate_control_cdb(struct se_task *task) break; case SYNCHRONIZE_CACHE: case 0x91: /* SYNCHRONIZE_CACHE_16: */ if (!dev->transport->do_sync_cache) { pr_err("SYNCHRONIZE_CACHE emulation not supported" " for: %s\n", dev->transport->name); return PYX_TRANSPORT_UNKNOWN_SAM_OPCODE; } dev->transport->do_sync_cache(task); ret = target_emulate_synchronize_cache(task); break; case ALLOW_MEDIUM_REMOVAL: case ERASE: Loading