Add support to unmarshall a CDB into a structure and update iscsi-dd

Add two new helper functions scsi_get_uint32() and scsi_get_uint16()
This commit is contained in:
Ronnie Sahlberg
2012-11-20 19:00:55 -08:00
parent e691f9cc2b
commit 890471c8cc
5 changed files with 69 additions and 3 deletions

View File

@@ -85,6 +85,7 @@ void read10_cb(struct iscsi_context *iscsi _U_, int status, void *command_data,
struct client *client = (struct client *)private_data;
struct scsi_task *task = command_data;
struct write_task *wt;
struct scsi_read10_cdb *read10_cdb;
if (status == SCSI_STATUS_CHECK_CONDITION) {
printf("Read10 failed with sense key:%d ascq:%04x\n", task->sense.key, task->sense.ascq);
@@ -95,9 +96,14 @@ void read10_cb(struct iscsi_context *iscsi _U_, int status, void *command_data,
wt->rt = task;
wt->client = client;
read10_cdb = scsi_cdb_unmarshall(task);
if (read10_cdb == NULL) {
printf("Failed to unmarshall READ10 CDB.\n");
exit(10);
}
if (iscsi_write10_task(client->dst_iscsi,
client->dst_lun,
task->params.read10.lba,
read10_cdb->lba,
task->datain.data,
task->datain.size,
client->dst_blocksize,

View File

@@ -657,8 +657,21 @@ struct scsi_report_supported_op_codes {
struct scsi_command_descriptor descriptors[0];
};
struct scsi_read10_cdb {
enum scsi_opcode opcode;
uint8_t rdprotect;
uint8_t dpo;
uint8_t fua;
uint8_t fua_nv;
uint32_t lba;
uint8_t group;
uint16_t transfer_length;
uint8_t control;
};
EXTERN int scsi_datain_getfullsize(struct scsi_task *task);
EXTERN void *scsi_datain_unmarshall(struct scsi_task *task);
EXTERN void *scsi_cdb_unmarshall(struct scsi_task *task);
EXTERN struct scsi_task *scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize);
EXTERN struct scsi_task *scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number);

View File

@@ -163,6 +163,7 @@ scsi_cdb_writesame16
scsi_codeset_to_str
scsi_datain_getfullsize
scsi_datain_unmarshall
scsi_cdb_unmarshall
scsi_designator_type_to_str
scsi_devqualifier_to_str
scsi_devtype_to_str

View File

@@ -161,6 +161,7 @@ scsi_cdb_writesame16
scsi_codeset_to_str
scsi_datain_getfullsize
scsi_datain_unmarshall
scsi_cdb_unmarshall
scsi_designator_type_to_str
scsi_devqualifier_to_str
scsi_devtype_to_str

View File

@@ -15,8 +15,8 @@
along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* would be nice if this could grow into a full blown library for scsi to
* 1, build a CDB
* would be nice if this could grow into a full blown library to
* 1, build and unmarshall a CDB
* 2, check how big a complete data-in structure needs to be
* 3, unmarshall data-in into a real structure
* 4, marshall a real structure into a data-out blob
@@ -160,6 +160,18 @@ scsi_sense_ascq_str(int ascq)
return value_string_find(ascqs, ascq);
}
static uint32_t
scsi_get_uint32(unsigned char *c)
{
return ntohl(*(uint32_t *)c);
}
static uint16_t
scsi_get_uint16(unsigned char *c)
{
return ntohs(*(uint16_t *)c);
}
/*
* TESTUNITREADY
*/
@@ -2298,6 +2310,39 @@ scsi_datain_unmarshall(struct scsi_task *task)
}
static struct scsi_read10_cdb *
scsi_read10_cdb_unmarshall(struct scsi_task *task)
{
struct scsi_read10_cdb *read10;
read10 = scsi_malloc(task, sizeof(struct scsi_read10_cdb));
if (read10 == NULL) {
return NULL;
}
read10->opcode = SCSI_OPCODE_READ10;
read10->rdprotect = (task->cdb[1] >> 5) & 0x7;
read10->dpo = !!(task->cdb[1] & 0x10);
read10->fua = !!(task->cdb[1] & 0x08);
read10->fua_nv = !!(task->cdb[1] & 0x02);
read10->lba = scsi_get_uint32(&task->cdb[2]);
read10->group = task->cdb[6] & 0x1f;
read10->transfer_length = scsi_get_uint16(&task->cdb[7]);
read10->control = task->cdb[9];
return read10;
}
void *
scsi_cdb_unmarshall(struct scsi_task *task)
{
switch (task->cdb[0]) {
case SCSI_OPCODE_READ10:
return scsi_read10_cdb_unmarshall(task);
}
return NULL;
}
const char *
scsi_devtype_to_str(enum scsi_inquiry_peripheral_device_type type)
{