Add MODESENSE6/10 and MODESELECT6/10 support

This commit is contained in:
Ronnie Sahlberg
2013-07-20 14:05:20 -07:00
parent e556a0399b
commit fd38ff4bfc
8 changed files with 232 additions and 8 deletions

View File

@@ -824,10 +824,19 @@ iscsi_modeselect6_task(struct iscsi_context *iscsi, int lun,
int pf, int sp, struct scsi_mode_page *mp,
iscsi_command_cb cb, void *private_data);
EXTERN 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);
EXTERN struct scsi_task *
iscsi_modesense6_task(struct iscsi_context *iscsi, int lun, int dbd,
int pc, int page_code, int sub_page_code,
unsigned char alloc_len, iscsi_command_cb cb,
void *private_data);
EXTERN 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 unmap_list {
uint64_t lba;
@@ -880,11 +889,20 @@ EXTERN struct scsi_task *
iscsi_modeselect6_sync(struct iscsi_context *iscsi, int lun,
int pf, int sp, struct scsi_mode_page *mp);
EXTERN struct scsi_task *
iscsi_modeselect10_sync(struct iscsi_context *iscsi, int lun,
int pf, int sp, struct scsi_mode_page *mp);
EXTERN struct scsi_task *
iscsi_modesense6_sync(struct iscsi_context *iscsi, int lun, int dbd,
int pc, int page_code, int sub_page_code,
unsigned char alloc_len);
EXTERN 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);
EXTERN struct scsi_task *
iscsi_reportluns_sync(struct iscsi_context *iscsi, int report_type,
int alloc_len);

View File

@@ -50,6 +50,8 @@ enum scsi_opcode {
SCSI_OPCODE_UNMAP = 0x42,
SCSI_OPCODE_READTOC = 0x43,
SCSI_OPCODE_SANITIZE = 0x48,
SCSI_OPCODE_MODESELECT10 = 0x55,
SCSI_OPCODE_MODESENSE10 = 0x5A,
SCSI_OPCODE_PERSISTENT_RESERVE_IN = 0x5E,
SCSI_OPCODE_PERSISTENT_RESERVE_OUT = 0x5F,
SCSI_OPCODE_READ16 = 0x88,
@@ -626,7 +628,7 @@ struct scsi_inquiry_device_identification {
};
/*
* MODESENSE6
* MODESENSE
*/
enum scsi_modesense_page_control {
SCSI_MODESENSE_PC_CURRENT = 0x00,
@@ -762,9 +764,17 @@ EXTERN struct scsi_task *scsi_cdb_modesense6(int dbd,
int sub_page_code,
unsigned char alloc_len);
EXTERN 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);
EXTERN struct scsi_task *scsi_cdb_modeselect6(int pf, int sp, int param_len);
EXTERN struct scsi_task *scsi_cdb_modeselect10(int pf, int sp, int param_len);
EXTERN struct scsi_data *
scsi_modesense_dataout_marshall(struct scsi_task *task,
struct scsi_mode_page *mp,

View File

@@ -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,

View File

@@ -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

View File

@@ -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

View File

@@ -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:

View File

@@ -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;
}

View File

@@ -177,18 +177,18 @@ int main(int argc, char *argv[])
}
sense_task = iscsi_modesense6_sync(iscsi, iscsi_url->lun,
1, SCSI_MODESENSE_PC_CURRENT,
sense_task = iscsi_modesense10_sync(iscsi, iscsi_url->lun,
0, 1, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODESENSE_PAGECODE_CONTROL,
0, 255);
if (sense_task == NULL) {
printf("Failed to send MODE_SENSE6 command: %s\n",
printf("Failed to send MODE_SENSE10 command: %s\n",
iscsi_get_error(iscsi));
ret = 10;
goto finished;
}
if (sense_task->status != SCSI_STATUS_GOOD) {
printf("MODE_SENSE6 failed: %s\n",
printf("MODE_SENSE10 failed: %s\n",
iscsi_get_error(iscsi));
ret = 10;
goto finished;
@@ -220,16 +220,16 @@ int main(int argc, char *argv[])
}
printf("Turning SWP %s\n", (swp == 1) ? "ON" : "OFF");
select_task = iscsi_modeselect6_sync(iscsi, iscsi_url->lun,
select_task = iscsi_modeselect10_sync(iscsi, iscsi_url->lun,
1, 0, mp);
if (select_task == NULL) {
printf("Failed to send MODE_SELECT6 command: %s\n",
printf("Failed to send MODE_SELECT10 command: %s\n",
iscsi_get_error(iscsi));
ret = 10;
goto finished;
}
if (select_task->status != SCSI_STATUS_GOOD) {
printf("MODE_SELECT6 failed: %s\n",
printf("MODE_SELECT10 failed: %s\n",
iscsi_get_error(iscsi));
ret = 10;
goto finished;