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:
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user