Add support for READ6
This commit is contained in:
@@ -130,6 +130,36 @@ void read10_cb(struct iscsi_context *iscsi, int status, void *command_data, void
|
|||||||
scsi_free_scsi_task(task);
|
scsi_free_scsi_task(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void read6_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data)
|
||||||
|
{
|
||||||
|
struct client_state *clnt = (struct client_state *)private_data;
|
||||||
|
struct scsi_task *task = command_data;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (status == SCSI_STATUS_CHECK_CONDITION) {
|
||||||
|
printf("Read6 failed with sense key:%d ascq:%04x\n", task->sense.key, task->sense.ascq);
|
||||||
|
scsi_free_scsi_task(task);
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("READ6 successful. Block content:\n");
|
||||||
|
for (i=0;i<task->datain.size;i++) {
|
||||||
|
printf("%02x ", task->datain.data[i]);
|
||||||
|
if (i%16==15)
|
||||||
|
printf("\n");
|
||||||
|
if (i==69)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
printf("...\n");
|
||||||
|
|
||||||
|
if (iscsi_read10_task(iscsi, clnt->lun, 0, clnt->block_size, clnt->block_size, read10_cb, private_data) == NULL) {
|
||||||
|
printf("failed to send read10 command\n");
|
||||||
|
scsi_free_scsi_task(task);
|
||||||
|
exit(10);
|
||||||
|
}
|
||||||
|
scsi_free_scsi_task(task);
|
||||||
|
}
|
||||||
|
|
||||||
void readcapacity10_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data)
|
void readcapacity10_cb(struct iscsi_context *iscsi, int status, void *command_data, void *private_data)
|
||||||
{
|
{
|
||||||
struct client_state *clnt = (struct client_state *)private_data;
|
struct client_state *clnt = (struct client_state *)private_data;
|
||||||
@@ -159,8 +189,8 @@ void readcapacity10_cb(struct iscsi_context *iscsi, int status, void *command_da
|
|||||||
clnt->block_size = rc10->block_size;
|
clnt->block_size = rc10->block_size;
|
||||||
printf("READCAPACITY10 successful. Size:%d blocks blocksize:%d. Read first block\n", rc10->lba, rc10->block_size);
|
printf("READCAPACITY10 successful. Size:%d blocks blocksize:%d. Read first block\n", rc10->lba, rc10->block_size);
|
||||||
|
|
||||||
if (iscsi_read10_task(iscsi, clnt->lun, 0, clnt->block_size, clnt->block_size, read10_cb, private_data) == NULL) {
|
if (iscsi_read6_task(iscsi, clnt->lun, 0, clnt->block_size, clnt->block_size, read6_cb, private_data) == NULL) {
|
||||||
printf("failed to send read10 command\n");
|
printf("failed to send read6 command\n");
|
||||||
scsi_free_scsi_task(task);
|
scsi_free_scsi_task(task);
|
||||||
exit(10);
|
exit(10);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -572,6 +572,11 @@ iscsi_synchronizecache10_task(struct iscsi_context *iscsi, int lun,
|
|||||||
int immed, iscsi_command_cb cb,
|
int immed, iscsi_command_cb cb,
|
||||||
void *private_data);
|
void *private_data);
|
||||||
struct scsi_task *
|
struct scsi_task *
|
||||||
|
iscsi_read6_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
||||||
|
uint32_t datalen, int blocksize, iscsi_command_cb cb,
|
||||||
|
void *private_data);
|
||||||
|
|
||||||
|
struct scsi_task *
|
||||||
iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
||||||
uint32_t datalen, int blocksize, iscsi_command_cb cb,
|
uint32_t datalen, int blocksize, iscsi_command_cb cb,
|
||||||
void *private_data);
|
void *private_data);
|
||||||
@@ -605,6 +610,10 @@ struct scsi_task *
|
|||||||
iscsi_inquiry_sync(struct iscsi_context *iscsi, int lun, int evpd,
|
iscsi_inquiry_sync(struct iscsi_context *iscsi, int lun, int evpd,
|
||||||
int page_code, int maxsize);
|
int page_code, int maxsize);
|
||||||
|
|
||||||
|
struct scsi_task *
|
||||||
|
iscsi_read6_sync(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
||||||
|
uint32_t datalen, int blocksize);
|
||||||
|
|
||||||
struct scsi_task *
|
struct scsi_task *
|
||||||
iscsi_read10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
iscsi_read10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
||||||
uint32_t datalen, int blocksize);
|
uint32_t datalen, int blocksize);
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
enum scsi_opcode {
|
enum scsi_opcode {
|
||||||
SCSI_OPCODE_TESTUNITREADY = 0x00,
|
SCSI_OPCODE_TESTUNITREADY = 0x00,
|
||||||
|
SCSI_OPCODE_READ6 = 0x08,
|
||||||
SCSI_OPCODE_INQUIRY = 0x12,
|
SCSI_OPCODE_INQUIRY = 0x12,
|
||||||
SCSI_OPCODE_MODESENSE6 = 0x1a,
|
SCSI_OPCODE_MODESENSE6 = 0x1a,
|
||||||
SCSI_OPCODE_READCAPACITY10 = 0x25,
|
SCSI_OPCODE_READCAPACITY10 = 0x25,
|
||||||
@@ -69,6 +70,10 @@ enum scsi_xfer_dir {
|
|||||||
struct scsi_reportluns_params {
|
struct scsi_reportluns_params {
|
||||||
int report_type;
|
int report_type;
|
||||||
};
|
};
|
||||||
|
struct scsi_read6_params {
|
||||||
|
uint32_t lba;
|
||||||
|
uint32_t num_blocks;
|
||||||
|
};
|
||||||
struct scsi_read10_params {
|
struct scsi_read10_params {
|
||||||
uint32_t lba;
|
uint32_t lba;
|
||||||
uint32_t num_blocks;
|
uint32_t num_blocks;
|
||||||
@@ -122,6 +127,7 @@ struct scsi_task {
|
|||||||
int expxferlen;
|
int expxferlen;
|
||||||
unsigned char cdb[SCSI_CDB_MAX_SIZE];
|
unsigned char cdb[SCSI_CDB_MAX_SIZE];
|
||||||
union {
|
union {
|
||||||
|
struct scsi_read6_params read6;
|
||||||
struct scsi_read10_params read10;
|
struct scsi_read10_params read10;
|
||||||
struct scsi_write10_params write10;
|
struct scsi_write10_params write10;
|
||||||
struct scsi_readcapacity10_params readcapacity10;
|
struct scsi_readcapacity10_params readcapacity10;
|
||||||
|
|||||||
@@ -582,6 +582,34 @@ iscsi_readcapacity10_task(struct iscsi_context *iscsi, int lun, int lba,
|
|||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct scsi_task *
|
||||||
|
iscsi_read6_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
||||||
|
uint32_t datalen, int blocksize,
|
||||||
|
iscsi_command_cb cb, void *private_data)
|
||||||
|
{
|
||||||
|
struct scsi_task *task;
|
||||||
|
|
||||||
|
if (datalen % blocksize != 0) {
|
||||||
|
iscsi_set_error(iscsi, "Datalen:%d is not a multiple of "
|
||||||
|
"the blocksize:%d.", datalen, blocksize);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
task = scsi_cdb_read6(lba, datalen, blocksize);
|
||||||
|
if (task == NULL) {
|
||||||
|
iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
|
||||||
|
"read6 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 *
|
struct scsi_task *
|
||||||
iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
iscsi_read10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
||||||
uint32_t datalen, int blocksize,
|
uint32_t datalen, int blocksize,
|
||||||
|
|||||||
@@ -505,6 +505,50 @@ scsi_inquiry_datain_unmarshall(struct scsi_task *task)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* READ6
|
||||||
|
*/
|
||||||
|
struct scsi_task *
|
||||||
|
scsi_cdb_read6(uint32_t lba, uint32_t xferlen, int blocksize)
|
||||||
|
{
|
||||||
|
struct scsi_task *task;
|
||||||
|
int num_blocks;
|
||||||
|
|
||||||
|
num_blocks = xferlen/blocksize;
|
||||||
|
if (num_blocks > 265) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lba > 0x1fffff) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
task = malloc(sizeof(struct scsi_task));
|
||||||
|
if (task == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(task, 0, sizeof(struct scsi_task));
|
||||||
|
task->cdb[0] = SCSI_OPCODE_READ6;
|
||||||
|
task->cdb_size = 6;
|
||||||
|
|
||||||
|
task->cdb[1] = (lba>>16)&0x1f;
|
||||||
|
task->cdb[2] = (lba>> 8)&0xff;
|
||||||
|
task->cdb[3] = (lba )&0xff;
|
||||||
|
|
||||||
|
if (num_blocks < 256) {
|
||||||
|
task->cdb[4] = num_blocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
task->xfer_dir = SCSI_XFER_READ;
|
||||||
|
task->expxferlen = xferlen;
|
||||||
|
|
||||||
|
task->params.read6.lba = lba;
|
||||||
|
task->params.read6.num_blocks = num_blocks;
|
||||||
|
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* READ10
|
* READ10
|
||||||
*/
|
*/
|
||||||
|
|||||||
20
lib/sync.c
20
lib/sync.c
@@ -216,6 +216,26 @@ iscsi_inquiry_sync(struct iscsi_context *iscsi, int lun, int evpd,
|
|||||||
return state.task;
|
return state.task;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct scsi_task *
|
||||||
|
iscsi_read6_sync(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
||||||
|
uint32_t datalen, int blocksize)
|
||||||
|
{
|
||||||
|
struct iscsi_sync_state state;
|
||||||
|
|
||||||
|
memset(&state, 0, sizeof(state));
|
||||||
|
|
||||||
|
if (iscsi_read6_task(iscsi, lun, lba, datalen, blocksize,
|
||||||
|
scsi_sync_cb, &state) == NULL) {
|
||||||
|
iscsi_set_error(iscsi,
|
||||||
|
"Failed to send Read6 command");
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
event_loop(iscsi, &state);
|
||||||
|
|
||||||
|
return state.task;
|
||||||
|
}
|
||||||
|
|
||||||
struct scsi_task *
|
struct scsi_task *
|
||||||
iscsi_read10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
iscsi_read10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba,
|
||||||
uint32_t datalen, int blocksize)
|
uint32_t datalen, int blocksize)
|
||||||
|
|||||||
Reference in New Issue
Block a user