target: refactor transport_emulate_control_cdb
Encapsulate each CDB emulation into a function of its own, to prepare setting ->exectute_task to these routines. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Nicholas Bellinger <nab@linux-iscsi.org>
This commit is contained in:
parent
e76a35d6c8
commit
6ed5a55790
|
@ -680,8 +680,9 @@ target_emulate_evpd_00(struct se_cmd *cmd, unsigned char *buf)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
struct se_device *dev = cmd->se_dev;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
unsigned char *cdb = cmd->t_task_cdb;
|
unsigned char *cdb = cmd->t_task_cdb;
|
||||||
|
@ -721,8 +722,9 @@ target_emulate_inquiry(struct se_cmd *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
struct se_device *dev = cmd->se_dev;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
unsigned long long blocks_long = dev->transport->get_blocks(dev);
|
unsigned long long blocks_long = dev->transport->get_blocks(dev);
|
||||||
|
@ -755,8 +757,9 @@ target_emulate_readcapacity(struct se_cmd *cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
struct se_device *dev = cmd->se_dev;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
unsigned long long blocks = dev->transport->get_blocks(dev);
|
unsigned long long blocks = dev->transport->get_blocks(dev);
|
||||||
|
@ -923,13 +926,15 @@ target_modesense_dpofua(unsigned char *buf, int type)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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;
|
struct se_device *dev = cmd->se_dev;
|
||||||
char *cdb = cmd->t_task_cdb;
|
char *cdb = cmd->t_task_cdb;
|
||||||
unsigned char *rbuf;
|
unsigned char *rbuf;
|
||||||
int type = dev->transport->get_device_type(dev);
|
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;
|
int length = 0;
|
||||||
unsigned char buf[SE_MODE_PAGE_BUF];
|
unsigned char buf[SE_MODE_PAGE_BUF];
|
||||||
|
|
||||||
|
@ -999,8 +1004,9 @@ target_emulate_modesense(struct se_cmd *cmd, int ten)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
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 *cdb = cmd->t_task_cdb;
|
||||||
unsigned char *buf;
|
unsigned char *buf;
|
||||||
u8 ua_asc = 0, ua_ascq = 0;
|
u8 ua_asc = 0, ua_ascq = 0;
|
||||||
|
@ -1079,6 +1085,12 @@ target_emulate_unmap(struct se_task *task)
|
||||||
int ret = 0, offset;
|
int ret = 0, offset;
|
||||||
unsigned short dl, bd_dl;
|
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 */
|
/* First UNMAP block descriptor starts at 8 byte offset */
|
||||||
offset = 8;
|
offset = 8;
|
||||||
size -= 8;
|
size -= 8;
|
||||||
|
@ -1119,13 +1131,28 @@ err:
|
||||||
* Note this is not used for TCM/pSCSI passthrough
|
* Note this is not used for TCM/pSCSI passthrough
|
||||||
*/
|
*/
|
||||||
static int
|
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_cmd *cmd = task->task_se_cmd;
|
||||||
struct se_device *dev = cmd->se_dev;
|
struct se_device *dev = cmd->se_dev;
|
||||||
sector_t range;
|
sector_t range;
|
||||||
sector_t lba = cmd->t_task_lba;
|
sector_t lba = cmd->t_task_lba;
|
||||||
|
u32 num_blocks;
|
||||||
int ret;
|
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
|
* Use the explicit range when non zero is supplied, otherwise calculate
|
||||||
* the remaining range based on ->get_blocks() - starting LBA.
|
* the remaining range based on ->get_blocks() - starting LBA.
|
||||||
|
@ -1147,6 +1174,21 @@ target_emulate_write_same(struct se_task *task, u32 num_blocks)
|
||||||
return 0;
|
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
|
int
|
||||||
transport_emulate_control_cdb(struct se_task *task)
|
transport_emulate_control_cdb(struct se_task *task)
|
||||||
{
|
{
|
||||||
|
@ -1157,21 +1199,21 @@ transport_emulate_control_cdb(struct se_task *task)
|
||||||
|
|
||||||
switch (cmd->t_task_cdb[0]) {
|
switch (cmd->t_task_cdb[0]) {
|
||||||
case INQUIRY:
|
case INQUIRY:
|
||||||
ret = target_emulate_inquiry(cmd);
|
ret = target_emulate_inquiry(task);
|
||||||
break;
|
break;
|
||||||
case READ_CAPACITY:
|
case READ_CAPACITY:
|
||||||
ret = target_emulate_readcapacity(cmd);
|
ret = target_emulate_readcapacity(task);
|
||||||
break;
|
break;
|
||||||
case MODE_SENSE:
|
case MODE_SENSE:
|
||||||
ret = target_emulate_modesense(cmd, 0);
|
ret = target_emulate_modesense(task);
|
||||||
break;
|
break;
|
||||||
case MODE_SENSE_10:
|
case MODE_SENSE_10:
|
||||||
ret = target_emulate_modesense(cmd, 1);
|
ret = target_emulate_modesense(task);
|
||||||
break;
|
break;
|
||||||
case SERVICE_ACTION_IN:
|
case SERVICE_ACTION_IN:
|
||||||
switch (cmd->t_task_cdb[1] & 0x1f) {
|
switch (cmd->t_task_cdb[1] & 0x1f) {
|
||||||
case SAI_READ_CAPACITY_16:
|
case SAI_READ_CAPACITY_16:
|
||||||
ret = target_emulate_readcapacity_16(cmd);
|
ret = target_emulate_readcapacity_16(task);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("Unsupported SA: 0x%02x\n",
|
pr_err("Unsupported SA: 0x%02x\n",
|
||||||
|
@ -1180,47 +1222,23 @@ transport_emulate_control_cdb(struct se_task *task)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case REQUEST_SENSE:
|
case REQUEST_SENSE:
|
||||||
ret = target_emulate_request_sense(cmd);
|
ret = target_emulate_request_sense(task);
|
||||||
break;
|
break;
|
||||||
case UNMAP:
|
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);
|
ret = target_emulate_unmap(task);
|
||||||
break;
|
break;
|
||||||
case WRITE_SAME:
|
case WRITE_SAME:
|
||||||
if (!dev->transport->do_discard) {
|
ret = target_emulate_write_same(task);
|
||||||
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]));
|
|
||||||
break;
|
break;
|
||||||
case WRITE_SAME_16:
|
case WRITE_SAME_16:
|
||||||
if (!dev->transport->do_discard) {
|
ret = target_emulate_write_same(task);
|
||||||
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]));
|
|
||||||
break;
|
break;
|
||||||
case VARIABLE_LENGTH_CMD:
|
case VARIABLE_LENGTH_CMD:
|
||||||
service_action =
|
service_action =
|
||||||
get_unaligned_be16(&cmd->t_task_cdb[8]);
|
get_unaligned_be16(&cmd->t_task_cdb[8]);
|
||||||
switch (service_action) {
|
switch (service_action) {
|
||||||
case WRITE_SAME_32:
|
case WRITE_SAME_32:
|
||||||
if (!dev->transport->do_discard) {
|
ret = target_emulate_write_same(task);
|
||||||
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]));
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_err("Unsupported VARIABLE_LENGTH_CMD SA:"
|
pr_err("Unsupported VARIABLE_LENGTH_CMD SA:"
|
||||||
|
@ -1230,12 +1248,7 @@ transport_emulate_control_cdb(struct se_task *task)
|
||||||
break;
|
break;
|
||||||
case SYNCHRONIZE_CACHE:
|
case SYNCHRONIZE_CACHE:
|
||||||
case 0x91: /* SYNCHRONIZE_CACHE_16: */
|
case 0x91: /* SYNCHRONIZE_CACHE_16: */
|
||||||
if (!dev->transport->do_sync_cache) {
|
ret = target_emulate_synchronize_cache(task);
|
||||||
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);
|
|
||||||
break;
|
break;
|
||||||
case ALLOW_MEDIUM_REMOVAL:
|
case ALLOW_MEDIUM_REMOVAL:
|
||||||
case ERASE:
|
case ERASE:
|
||||||
|
|
Loading…
Reference in a new issue