Add MODESENSE6/10 and MODESELECT6/10 support
This commit is contained in:
@@ -1241,6 +1241,45 @@ iscsi_modeselect6_task(struct iscsi_context *iscsi, int lun,
|
||||
return task;
|
||||
}
|
||||
|
||||
struct scsi_task *
|
||||
iscsi_modeselect10_task(struct iscsi_context *iscsi, int lun,
|
||||
int pf, int sp, struct scsi_mode_page *mp,
|
||||
iscsi_command_cb cb, void *private_data)
|
||||
{
|
||||
struct scsi_task *task;
|
||||
struct scsi_data *data;
|
||||
struct iscsi_data d;
|
||||
|
||||
task = scsi_cdb_modeselect10(pf, sp, 255);
|
||||
if (task == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
|
||||
"modeselect10 cdb.");
|
||||
return NULL;
|
||||
}
|
||||
data = scsi_modesense_dataout_marshall(task, mp, 0);
|
||||
if (data == NULL) {
|
||||
iscsi_set_error(iscsi, "Error: Failed to marshall "
|
||||
"modesense dataout buffer.");
|
||||
scsi_free_scsi_task(task);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
d.data = data->data;
|
||||
d.size = data->size;
|
||||
task->cdb[7] = data->size >> 8;
|
||||
task->cdb[8] = data->size & 0xff;
|
||||
|
||||
task->expxferlen = data->size;
|
||||
|
||||
if (iscsi_scsi_command_async(iscsi, lun, task, cb,
|
||||
&d, private_data) != 0) {
|
||||
scsi_free_scsi_task(task);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
struct scsi_task *
|
||||
iscsi_modesense6_task(struct iscsi_context *iscsi, int lun, int dbd, int pc,
|
||||
int page_code, int sub_page_code,
|
||||
@@ -1265,6 +1304,31 @@ iscsi_modesense6_task(struct iscsi_context *iscsi, int lun, int dbd, int pc,
|
||||
return task;
|
||||
}
|
||||
|
||||
struct scsi_task *
|
||||
iscsi_modesense10_task(struct iscsi_context *iscsi, int lun,
|
||||
int llbaa, int dbd, int pc,
|
||||
int page_code, int sub_page_code,
|
||||
unsigned char alloc_len,
|
||||
iscsi_command_cb cb, void *private_data)
|
||||
{
|
||||
struct scsi_task *task;
|
||||
|
||||
task = scsi_cdb_modesense10(llbaa, dbd, pc, page_code, sub_page_code,
|
||||
alloc_len);
|
||||
if (task == NULL) {
|
||||
iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
|
||||
"modesense10 cdb.");
|
||||
return NULL;
|
||||
}
|
||||
if (iscsi_scsi_command_async(iscsi, lun, task, cb,
|
||||
NULL, private_data) != 0) {
|
||||
scsi_free_scsi_task(task);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
struct scsi_task *
|
||||
iscsi_startstopunit_task(struct iscsi_context *iscsi, int lun,
|
||||
int immed, int pcm, int pc,
|
||||
|
||||
@@ -25,8 +25,12 @@ iscsi_logout_async
|
||||
iscsi_logout_sync
|
||||
iscsi_modeselect6_sync
|
||||
iscsi_modeselect6_task
|
||||
iscsi_modeselect10_sync
|
||||
iscsi_modeselect10_task
|
||||
iscsi_modesense6_sync
|
||||
iscsi_modesense6_task
|
||||
iscsi_modesense10_sync
|
||||
iscsi_modesense10_task
|
||||
iscsi_nop_out_async
|
||||
iscsi_parse_full_url
|
||||
iscsi_parse_portal_url
|
||||
@@ -154,7 +158,9 @@ scsi_association_to_str
|
||||
scsi_cdb_inquiry
|
||||
scsi_cdb_get_lba_status
|
||||
scsi_cdb_modeselect6
|
||||
scsi_cdb_modeselect10
|
||||
scsi_cdb_modesense6
|
||||
scsi_cdb_modesense10
|
||||
scsi_cdb_persistent_reserve_in
|
||||
scsi_cdb_persistent_reserve_out
|
||||
scsi_cdb_prefetch10
|
||||
|
||||
@@ -23,8 +23,12 @@ iscsi_logout_async
|
||||
iscsi_logout_sync
|
||||
iscsi_modeselect6_sync
|
||||
iscsi_modeselect6_task
|
||||
iscsi_modeselect10_sync
|
||||
iscsi_modeselect10_task
|
||||
iscsi_modesense6_sync
|
||||
iscsi_modesense6_task
|
||||
iscsi_modesense10_sync
|
||||
iscsi_modesense10_task
|
||||
iscsi_nop_out_async
|
||||
iscsi_parse_full_url
|
||||
iscsi_parse_portal_url
|
||||
@@ -152,7 +156,9 @@ scsi_association_to_str
|
||||
scsi_cdb_inquiry
|
||||
scsi_cdb_get_lba_status
|
||||
scsi_cdb_modeselect6
|
||||
scsi_cdb_modeselect10
|
||||
scsi_cdb_modesense6
|
||||
scsi_cdb_modesense10
|
||||
scsi_cdb_persistent_reserve_in
|
||||
scsi_cdb_persistent_reserve_out
|
||||
scsi_cdb_prefetch10
|
||||
|
||||
@@ -2181,6 +2181,46 @@ scsi_cdb_modesense6(int dbd, enum scsi_modesense_page_control pc,
|
||||
return task;
|
||||
}
|
||||
|
||||
/*
|
||||
* MODESENSE10
|
||||
*/
|
||||
struct scsi_task *
|
||||
scsi_cdb_modesense10(int llbaa, int dbd, enum scsi_modesense_page_control pc,
|
||||
enum scsi_modesense_page_code page_code,
|
||||
int sub_page_code, unsigned char alloc_len)
|
||||
{
|
||||
struct scsi_task *task;
|
||||
|
||||
task = malloc(sizeof(struct scsi_task));
|
||||
if (task == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(task, 0, sizeof(struct scsi_task));
|
||||
task->cdb[0] = SCSI_OPCODE_MODESENSE10;
|
||||
|
||||
if (llbaa) {
|
||||
task->cdb[1] |= 0x10;
|
||||
}
|
||||
if (dbd) {
|
||||
task->cdb[1] |= 0x08;
|
||||
}
|
||||
task->cdb[2] = pc<<6 | page_code;
|
||||
task->cdb[3] = sub_page_code;
|
||||
|
||||
scsi_set_uint16(&task->cdb[7], alloc_len);
|
||||
|
||||
task->cdb_size = 10;
|
||||
if (alloc_len != 0) {
|
||||
task->xfer_dir = SCSI_XFER_READ;
|
||||
} else {
|
||||
task->xfer_dir = SCSI_XFER_NONE;
|
||||
}
|
||||
task->expxferlen = alloc_len;
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
/*
|
||||
* MODESELECT6
|
||||
*/
|
||||
@@ -2216,6 +2256,42 @@ scsi_cdb_modeselect6(int pf, int sp, int param_len)
|
||||
return task;
|
||||
}
|
||||
|
||||
/*
|
||||
* MODESELECT10
|
||||
*/
|
||||
struct scsi_task *
|
||||
scsi_cdb_modeselect10(int pf, int sp, int param_len)
|
||||
{
|
||||
struct scsi_task *task;
|
||||
|
||||
task = malloc(sizeof(struct scsi_task));
|
||||
if (task == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(task, 0, sizeof(struct scsi_task));
|
||||
task->cdb[0] = SCSI_OPCODE_MODESELECT10;
|
||||
|
||||
if (pf) {
|
||||
task->cdb[1] |= 0x10;
|
||||
}
|
||||
if (sp) {
|
||||
task->cdb[1] |= 0x01;
|
||||
}
|
||||
|
||||
scsi_set_uint16(&task->cdb[7], param_len);
|
||||
|
||||
task->cdb_size = 10;
|
||||
if (param_len != 0) {
|
||||
task->xfer_dir = SCSI_XFER_WRITE;
|
||||
} else {
|
||||
task->xfer_dir = SCSI_XFER_NONE;
|
||||
}
|
||||
task->expxferlen = param_len;
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
struct scsi_mode_page *
|
||||
scsi_modesense_get_page(struct scsi_mode_sense *ms,
|
||||
enum scsi_modesense_page_code page_code,
|
||||
@@ -3062,6 +3138,8 @@ scsi_datain_unmarshall(struct scsi_task *task)
|
||||
return scsi_inquiry_datain_unmarshall(task);
|
||||
case SCSI_OPCODE_MODESENSE6:
|
||||
return scsi_modesense_datain_unmarshall(task, 1);
|
||||
case SCSI_OPCODE_MODESENSE10:
|
||||
return scsi_modesense_datain_unmarshall(task, 0);
|
||||
case SCSI_OPCODE_READCAPACITY10:
|
||||
return scsi_readcapacity10_datain_unmarshall(task);
|
||||
case SCSI_OPCODE_SYNCHRONIZECACHE10:
|
||||
|
||||
42
lib/sync.c
42
lib/sync.c
@@ -1176,6 +1176,26 @@ iscsi_modeselect6_sync(struct iscsi_context *iscsi, int lun,
|
||||
return state.task;
|
||||
}
|
||||
|
||||
struct scsi_task *
|
||||
iscsi_modeselect10_sync(struct iscsi_context *iscsi, int lun,
|
||||
int pf, int sp, struct scsi_mode_page *mp)
|
||||
{
|
||||
struct iscsi_sync_state state;
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
|
||||
if (iscsi_modeselect10_task(iscsi, lun, pf, sp, mp,
|
||||
scsi_sync_cb, &state) == NULL) {
|
||||
iscsi_set_error(iscsi,
|
||||
"Failed to send MODE_SELECT10 command");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
event_loop(iscsi, &state);
|
||||
|
||||
return state.task;
|
||||
}
|
||||
|
||||
struct scsi_task *
|
||||
iscsi_modesense6_sync(struct iscsi_context *iscsi, int lun, int dbd,
|
||||
int pc, int page_code, int sub_page_code,
|
||||
@@ -1196,3 +1216,25 @@ iscsi_modesense6_sync(struct iscsi_context *iscsi, int lun, int dbd,
|
||||
|
||||
return state.task;
|
||||
}
|
||||
|
||||
struct scsi_task *
|
||||
iscsi_modesense10_sync(struct iscsi_context *iscsi, int lun, int llbaa, int dbd,
|
||||
int pc, int page_code, int sub_page_code,
|
||||
unsigned char alloc_len)
|
||||
{
|
||||
struct iscsi_sync_state state;
|
||||
|
||||
memset(&state, 0, sizeof(state));
|
||||
|
||||
if (iscsi_modesense10_task(iscsi, lun, llbaa, dbd, pc,
|
||||
page_code, sub_page_code, alloc_len,
|
||||
scsi_sync_cb, &state) == NULL) {
|
||||
iscsi_set_error(iscsi,
|
||||
"Failed to send MODE_SENSE10 command");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
event_loop(iscsi, &state);
|
||||
|
||||
return state.task;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user