Add PREFETCH10/16 implementations

This commit is contained in:
Ronnie Sahlberg
2012-05-03 06:21:49 +10:00
parent c02a952911
commit 733b97f4b8
5 changed files with 169 additions and 0 deletions

View File

@@ -924,6 +924,49 @@ iscsi_synchronizecache10_task(struct iscsi_context *iscsi, int lun, int lba,
return task;
}
struct scsi_task *
iscsi_prefetch10_task(struct iscsi_context *iscsi, int lun, uint32_t lba,
int num_blocks, int immed, int group,
iscsi_command_cb cb, void *private_data)
{
struct scsi_task *task;
task = scsi_cdb_prefetch10(lba, num_blocks, immed, group);
if (task == NULL) {
iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
"prefetch10 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_prefetch16_task(struct iscsi_context *iscsi, int lun, uint64_t lba,
int num_blocks, int immed, int group,
iscsi_command_cb cb, void *private_data)
{
struct scsi_task *task;
task = scsi_cdb_prefetch16(lba, num_blocks, immed, group);
if (task == NULL) {
iscsi_set_error(iscsi, "Out-of-memory: Failed to create "
"prefetch16 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_writesame10_task(struct iscsi_context *iscsi, int lun,

View File

@@ -1288,6 +1288,68 @@ scsi_cdb_synchronizecache10(int lba, int num_blocks, int syncnv, int immed)
}
/*
* PREFETCH10
*/
struct scsi_task *
scsi_cdb_prefetch10(uint32_t lba, int num_blocks, int immed, int group)
{
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_PREFETCH10;
if (immed) {
task->cdb[1] |= 0x02;
}
*(uint32_t *)&task->cdb[2] = htonl(lba);
task->cdb[6] |= group & 0x1f;
*(uint16_t *)&task->cdb[7] = htons(num_blocks);
task->cdb_size = 10;
task->xfer_dir = SCSI_XFER_NONE;
task->expxferlen = 0;
return task;
}
/*
* PREFETCH16
*/
struct scsi_task *
scsi_cdb_prefetch16(uint64_t lba, int num_blocks, int immed, int group)
{
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_PREFETCH16;
if (immed) {
task->cdb[1] |= 0x02;
}
*(uint32_t *)&task->cdb[2] = htonl(lba >> 32);
*(uint32_t *)&task->cdb[6] = htonl(lba & 0xffffffff);
*(uint32_t *)&task->cdb[10] = htonl(num_blocks);
task->cdb[14] |= group & 0x1f;
task->cdb_size = 16;
task->xfer_dir = SCSI_XFER_NONE;
task->expxferlen = 0;
return task;
}
/*
* SERVICEACTIONIN16
*/

View File

@@ -375,6 +375,48 @@ iscsi_synchronizecache10_sync(struct iscsi_context *iscsi, int lun, int lba,
return state.task;
}
struct scsi_task *
iscsi_prefetch10_sync(struct iscsi_context *iscsi, int lun, uint32_t lba,
int num_blocks, int immed, int group)
{
struct iscsi_sync_state state;
memset(&state, 0, sizeof(state));
if (iscsi_prefetch10_task(iscsi, lun, lba, num_blocks,
immed, group,
scsi_sync_cb, &state) == NULL) {
iscsi_set_error(iscsi,
"Failed to send PreFetch10 command");
return NULL;
}
event_loop(iscsi, &state);
return state.task;
}
struct scsi_task *
iscsi_prefetch16_sync(struct iscsi_context *iscsi, int lun, uint64_t lba,
int num_blocks, int immed, int group)
{
struct iscsi_sync_state state;
memset(&state, 0, sizeof(state));
if (iscsi_prefetch16_task(iscsi, lun, lba, num_blocks,
immed, group,
scsi_sync_cb, &state) == NULL) {
iscsi_set_error(iscsi,
"Failed to send PreFetch16 command");
return NULL;
}
event_loop(iscsi, &state);
return state.task;
}
struct scsi_task *
iscsi_write10_sync(struct iscsi_context *iscsi, int lun, unsigned char *data, uint32_t datalen, uint32_t lba,
int fua, int fuanv, int blocksize)