Modesense6 decoding bugs, start preparing for modesense10 decoding

This commit is contained in:
Ronnie Sahlberg
2013-07-08 01:31:03 -07:00
parent e31e0ce58d
commit 9e9ca71247
3 changed files with 74 additions and 52 deletions

View File

@@ -743,9 +743,10 @@ struct scsi_mode_page {
};
struct scsi_mode_sense {
uint8_t mode_data_length;
uint16_t mode_data_length;
uint8_t medium_type;
uint8_t device_specific_parameter;
uint8_t longlba;
uint8_t block_descriptor_length;
struct scsi_mode_page *pages;
};

View File

@@ -2238,11 +2238,15 @@ scsi_modesense_get_page(struct scsi_mode_sense *ms,
* modesense6 datain structure
*/
static int
scsi_modesense6_datain_getfullsize(struct scsi_task *task)
scsi_modesense_datain_getfullsize(struct scsi_task *task, int is_modesense6)
{
int len;
len = task_get_uint8(task, 0) + 1;
if (is_modesense6) {
len = task_get_uint8(task, 0) + 1;
} else {
len = task_get_uint16(task, 0) + 2;
}
return len;
}
@@ -2250,14 +2254,14 @@ scsi_modesense6_datain_getfullsize(struct scsi_task *task)
static void
scsi_parse_mode_caching(struct scsi_task *task, int pos, struct scsi_mode_page *mp)
{
mp->caching.ic = task_get_uint8(task, pos) & 0x80;
mp->caching.abpf = task_get_uint8(task, pos) & 0x40;
mp->caching.cap = task_get_uint8(task, pos) & 0x20;
mp->caching.disc = task_get_uint8(task, pos) & 0x10;
mp->caching.size = task_get_uint8(task, pos) & 0x08;
mp->caching.wce = task_get_uint8(task, pos) & 0x04;
mp->caching.mf = task_get_uint8(task, pos) & 0x02;
mp->caching.rcd = task_get_uint8(task, pos) & 0x01;
mp->caching.ic = !!(task_get_uint8(task, pos) & 0x80);
mp->caching.abpf = !!(task_get_uint8(task, pos) & 0x40);
mp->caching.cap = !!(task_get_uint8(task, pos) & 0x20);
mp->caching.disc = !!(task_get_uint8(task, pos) & 0x10);
mp->caching.size = !!(task_get_uint8(task, pos) & 0x08);
mp->caching.wce = !!(task_get_uint8(task, pos) & 0x04);
mp->caching.mf = !!(task_get_uint8(task, pos) & 0x02);
mp->caching.rcd = !!(task_get_uint8(task, pos) & 0x01);
mp->caching.demand_read_retention_priority =
(task_get_uint8(task, pos + 1) >> 4) & 0x0f;
@@ -2270,10 +2274,10 @@ scsi_parse_mode_caching(struct scsi_task *task, int pos, struct scsi_mode_page *
mp->caching.maximum_prefetch = task_get_uint16(task, pos + 6);
mp->caching.maximum_prefetch_ceiling = task_get_uint16(task, pos + 8);
mp->caching.fsw = task_get_uint8(task, pos + 10) & 0x80;
mp->caching.lbcss = task_get_uint8(task, pos + 10) & 0x40;
mp->caching.dra = task_get_uint8(task, pos + 10) & 0x20;
mp->caching.nv_dis = task_get_uint8(task, pos + 10) & 0x01;
mp->caching.fsw = !!(task_get_uint8(task, pos + 10) & 0x80);
mp->caching.lbcss = !!(task_get_uint8(task, pos + 10) & 0x40);
mp->caching.dra = !!(task_get_uint8(task, pos + 10) & 0x20);
mp->caching.nv_dis = !!(task_get_uint8(task, pos + 10) & 0x01);
mp->caching.number_of_cache_segments = task_get_uint8(task, pos + 11);
mp->caching.cache_segment_size = task_get_uint16(task, pos + 12);
@@ -2283,28 +2287,28 @@ static void
scsi_parse_mode_control(struct scsi_task *task, int pos, struct scsi_mode_page *mp)
{
mp->control.tst = (task_get_uint8(task, pos) >> 5) & 0x07;
mp->control.tmf_only = task_get_uint8(task, pos) & 0x10;
mp->control.dpicz = task_get_uint8(task, pos) & 0x08;
mp->control.d_sense = task_get_uint8(task, pos) & 0x04;
mp->control.gltsd = task_get_uint8(task, pos) & 0x02;
mp->control.rlec = task_get_uint8(task, pos) & 0x01;
mp->control.tmf_only = !!(task_get_uint8(task, pos) & 0x10);
mp->control.dpicz = !!(task_get_uint8(task, pos) & 0x08);
mp->control.d_sense = !!(task_get_uint8(task, pos) & 0x04);
mp->control.gltsd = !!(task_get_uint8(task, pos) & 0x02);
mp->control.rlec = !!(task_get_uint8(task, pos) & 0x01);
mp->control.queue_algorithm_modifier =
(task_get_uint8(task, pos + 1) >> 4) & 0x0f;
mp->control.nuar = task_get_uint8(task, pos + 1) & 0x08;
mp->control.qerr = (task_get_uint8(task, pos + 1) >> 1) & 0x03;
mp->control.vs = task_get_uint8(task, pos + 2) & 0x80;
mp->control.rac = task_get_uint8(task, pos + 2) & 0x40;
mp->control.vs = !!(task_get_uint8(task, pos + 2) & 0x80);
mp->control.rac = !!(task_get_uint8(task, pos + 2) & 0x40);
mp->control.ua_intlck_ctrl =
(task_get_uint8(task, pos + 2) >> 4) & 0x0f;
mp->control.swp = task_get_uint8(task, pos + 2) & 0x08;
mp->control.swp = !!(task_get_uint8(task, pos + 2) & 0x08);
mp->control.ato = task_get_uint8(task, pos + 3) & 0x80;
mp->control.tas = task_get_uint8(task, pos + 3) & 0x40;
mp->control.atmpe = task_get_uint8(task, pos + 3) & 0x20;
mp->control.swp = task_get_uint8(task, pos + 3) & 0x10;
mp->control.autoload_mode = task_get_uint8(task, pos + 2) & 0x07;
mp->control.ato = !!(task_get_uint8(task, pos + 3) & 0x80);
mp->control.tas = !!(task_get_uint8(task, pos + 3) & 0x40);
mp->control.atmpe = !!(task_get_uint8(task, pos + 3) & 0x20);
mp->control.rwwp = !!(task_get_uint8(task, pos + 3) & 0x10);
mp->control.autoload_mode = !!(task_get_uint8(task, pos + 3) & 0x07);
mp->control.busy_timeout_period =
task_get_uint16(task, pos + 6);
@@ -2328,11 +2332,11 @@ scsi_parse_mode_disconnect_reconnect(struct scsi_task *task, int pos, struct scs
mp->disconnect_reconnect.maximum_burst_size =
task_get_uint16(task, pos + 8);
mp->disconnect_reconnect.emdp =
task_get_uint8(task, pos + 10) & 0x80;
!!(task_get_uint8(task, pos + 10) & 0x80);
mp->disconnect_reconnect.fair_arbitration =
(task_get_uint8(task, pos + 10) >> 4) & 0x0f;
mp->disconnect_reconnect.dimm =
task_get_uint8(task, pos + 10) & 0x08;
!!(task_get_uint8(task, pos + 10) & 0x08);
mp->disconnect_reconnect.dtdc =
task_get_uint8(task, pos + 10) & 0x07;
mp->disconnect_reconnect.first_burst_size =
@@ -2342,13 +2346,13 @@ scsi_parse_mode_disconnect_reconnect(struct scsi_task *task, int pos, struct scs
static void
scsi_parse_mode_informational_exceptions_control(struct scsi_task *task, int pos, struct scsi_mode_page *mp)
{
mp->iec.perf = task_get_uint8(task, pos) & 0x80;
mp->iec.ebf = task_get_uint8(task, pos) & 0x20;
mp->iec.ewasc = task_get_uint8(task, pos) & 0x10;
mp->iec.dexcpt = task_get_uint8(task, pos) & 0x08;
mp->iec.test = task_get_uint8(task, pos) & 0x04;
mp->iec.ebackerr = task_get_uint8(task, pos) & 0x02;
mp->iec.logerr = task_get_uint8(task, pos) & 0x01;
mp->iec.perf = !!(task_get_uint8(task, pos) & 0x80);
mp->iec.ebf = !!(task_get_uint8(task, pos) & 0x20);
mp->iec.ewasc = !!(task_get_uint8(task, pos) & 0x10);
mp->iec.dexcpt = !!(task_get_uint8(task, pos) & 0x08);
mp->iec.test = !!(task_get_uint8(task, pos) & 0x04);
mp->iec.ebackerr = !!(task_get_uint8(task, pos) & 0x02);
mp->iec.logerr = !!(task_get_uint8(task, pos) & 0x01);
mp->iec.mrie = task_get_uint8(task, pos + 1) & 0x0f;
mp->iec.interval_timer = task_get_uint32(task, pos + 2);
mp->iec.report_count = task_get_uint32(task, pos + 6);
@@ -2359,12 +2363,19 @@ scsi_parse_mode_informational_exceptions_control(struct scsi_task *task, int pos
* parse and unmarshall the mode sense data in buffer
*/
static struct scsi_mode_sense *
scsi_modesense_datain_unmarshall(struct scsi_task *task)
scsi_modesense_datain_unmarshall(struct scsi_task *task, int is_modesense6)
{
struct scsi_mode_sense *ms;
int hdr_len;
int pos;
if (task->datain.size < 4) {
if (is_modesense6) {
hdr_len = 4;
} else {
hdr_len = 8;
}
if (task->datain.size < hdr_len) {
return NULL;
}
@@ -2373,17 +2384,26 @@ scsi_modesense_datain_unmarshall(struct scsi_task *task)
return NULL;
}
ms->mode_data_length = task_get_uint8(task, 0);
ms->medium_type = task_get_uint8(task, 1);
ms->device_specific_parameter = task_get_uint8(task, 2);
ms->block_descriptor_length = task_get_uint8(task, 3);
ms->pages = NULL;
if (is_modesense6) {
ms->mode_data_length = task_get_uint8(task, 0);
ms->medium_type = task_get_uint8(task, 1);
ms->device_specific_parameter = task_get_uint8(task, 2);
ms->block_descriptor_length = task_get_uint8(task, 3);
ms->pages = NULL;
} else {
ms->mode_data_length = task_get_uint16(task, 0);
ms->medium_type = task_get_uint8(task, 2);
ms->device_specific_parameter = task_get_uint8(task, 3);
ms->longlba = task_get_uint8(task, 4) & 0x01;
ms->block_descriptor_length = task_get_uint16(task, 6);
ms->pages = NULL;
}
if (ms->mode_data_length + 1 > task->datain.size) {
return NULL;
}
pos = 4 + ms->block_descriptor_length;
pos = hdr_len + ms->block_descriptor_length;
while (pos < task->datain.size) {
struct scsi_mode_page *mp;
@@ -2397,12 +2417,13 @@ scsi_modesense_datain_unmarshall(struct scsi_task *task)
pos++;
if (mp->spf) {
mp->subpage_code = task_get_uint8(task, pos++);
mp->len = task_get_uint16(task, pos);
pos += 2;
mp->subpage_code = task_get_uint8(task, pos);
mp->len = task_get_uint16(task, pos + 1);
pos += 3;
} else {
mp->subpage_code = 0;
mp->len = task_get_uint8(task, pos++);
mp->len = task_get_uint8(task, pos);
pos++;
}
switch (mp->page_code) {
@@ -3022,7 +3043,7 @@ scsi_datain_getfullsize(struct scsi_task *task)
case SCSI_OPCODE_INQUIRY:
return scsi_inquiry_datain_getfullsize(task);
case SCSI_OPCODE_MODESENSE6:
return scsi_modesense6_datain_getfullsize(task);
return scsi_modesense_datain_getfullsize(task, 1);
case SCSI_OPCODE_READCAPACITY10:
return scsi_readcapacity10_datain_getfullsize(task);
case SCSI_OPCODE_SYNCHRONIZECACHE10:
@@ -3048,7 +3069,7 @@ scsi_datain_unmarshall(struct scsi_task *task)
case SCSI_OPCODE_INQUIRY:
return scsi_inquiry_datain_unmarshall(task);
case SCSI_OPCODE_MODESENSE6:
return scsi_modesense_datain_unmarshall(task);
return scsi_modesense_datain_unmarshall(task, 1);
case SCSI_OPCODE_READCAPACITY10:
return scsi_readcapacity10_datain_unmarshall(task);
case SCSI_OPCODE_SYNCHRONIZECACHE10:

View File

@@ -176,7 +176,7 @@ int main(int argc, char *argv[])
sense_task = iscsi_modesense6_sync(iscsi, iscsi_url->lun,
0, SCSI_MODESENSE_PC_CURRENT,
1, SCSI_MODESENSE_PC_CURRENT,
SCSI_MODESENSE_PAGECODE_CONTROL,
0, 255);
if (sense_task == NULL) {