Implement READ/WRITE_12/16 and a simple test for read16
Signed-off-by: Ronnie Sahlberg <ronniesahlberg@gmail.com>
This commit is contained in:
@@ -675,11 +675,104 @@ scsi_cdb_read10(uint32_t lba, uint32_t xferlen, int blocksize)
|
||||
return task;
|
||||
}
|
||||
|
||||
/*
|
||||
* READ12
|
||||
*/
|
||||
struct scsi_task *
|
||||
scsi_cdb_read12(uint32_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number)
|
||||
{
|
||||
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_READ12;
|
||||
|
||||
task->cdb[1] |= ((rdprotect & 0x07) << 5);
|
||||
if (dpo) {
|
||||
task->cdb[1] |= 0x10;
|
||||
}
|
||||
if (fua) {
|
||||
task->cdb[1] |= 0x08;
|
||||
}
|
||||
if (fua_nv) {
|
||||
task->cdb[1] |= 0x02;
|
||||
}
|
||||
|
||||
*(uint32_t *)&task->cdb[2] = htonl(lba);
|
||||
*(uint32_t *)&task->cdb[6] = htonl(xferlen/blocksize);
|
||||
|
||||
task->cdb[10] |= (group_number & 0x1f);
|
||||
|
||||
task->cdb_size = 12;
|
||||
if (xferlen != 0) {
|
||||
task->xfer_dir = SCSI_XFER_READ;
|
||||
} else {
|
||||
task->xfer_dir = SCSI_XFER_NONE;
|
||||
}
|
||||
task->expxferlen = xferlen;
|
||||
|
||||
task->params.read12.lba = lba;
|
||||
task->params.read12.num_blocks = xferlen/blocksize;
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
/*
|
||||
* READ16
|
||||
*/
|
||||
struct scsi_task *
|
||||
scsi_cdb_read16(uint64_t lba, uint32_t xferlen, int blocksize, int rdprotect, int dpo, int fua, int fua_nv, int group_number)
|
||||
{
|
||||
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_READ16;
|
||||
|
||||
task->cdb[1] |= ((rdprotect & 0x07) << 5);
|
||||
if (dpo) {
|
||||
task->cdb[1] |= 0x10;
|
||||
}
|
||||
if (fua) {
|
||||
task->cdb[1] |= 0x08;
|
||||
}
|
||||
if (fua_nv) {
|
||||
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(xferlen/blocksize);
|
||||
|
||||
task->cdb[14] |= (group_number & 0x1f);
|
||||
|
||||
task->cdb_size = 16;
|
||||
if (xferlen != 0) {
|
||||
task->xfer_dir = SCSI_XFER_READ;
|
||||
} else {
|
||||
task->xfer_dir = SCSI_XFER_NONE;
|
||||
}
|
||||
task->expxferlen = xferlen;
|
||||
|
||||
task->params.read16.lba = lba;
|
||||
task->params.read16.num_blocks = xferlen/blocksize;
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
/*
|
||||
* WRITE10
|
||||
*/
|
||||
struct scsi_task *
|
||||
scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fuanv, int blocksize)
|
||||
scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fua_nv, int blocksize)
|
||||
{
|
||||
struct scsi_task *task;
|
||||
|
||||
@@ -694,7 +787,7 @@ scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fuanv, int blocksi
|
||||
if (fua) {
|
||||
task->cdb[1] |= 0x08;
|
||||
}
|
||||
if (fuanv) {
|
||||
if (fua_nv) {
|
||||
task->cdb[1] |= 0x02;
|
||||
}
|
||||
|
||||
@@ -715,6 +808,98 @@ scsi_cdb_write10(uint32_t lba, uint32_t xferlen, int fua, int fuanv, int blocksi
|
||||
return task;
|
||||
}
|
||||
|
||||
/*
|
||||
* WRITE12
|
||||
*/
|
||||
struct scsi_task *
|
||||
scsi_cdb_write12(uint32_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number)
|
||||
{
|
||||
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_WRITE12;
|
||||
|
||||
task->cdb[1] |= ((wrprotect & 0x07) << 5);
|
||||
if (dpo) {
|
||||
task->cdb[1] |= 0x10;
|
||||
}
|
||||
if (fua) {
|
||||
task->cdb[1] |= 0x08;
|
||||
}
|
||||
if (fua_nv) {
|
||||
task->cdb[1] |= 0x02;
|
||||
}
|
||||
|
||||
*(uint32_t *)&task->cdb[2] = htonl(lba);
|
||||
*(uint32_t *)&task->cdb[6] = htonl(xferlen/blocksize);
|
||||
|
||||
task->cdb[10] |= (group_number & 0x1f);
|
||||
|
||||
task->cdb_size = 12;
|
||||
if (xferlen != 0) {
|
||||
task->xfer_dir = SCSI_XFER_WRITE;
|
||||
} else {
|
||||
task->xfer_dir = SCSI_XFER_NONE;
|
||||
}
|
||||
task->expxferlen = xferlen;
|
||||
|
||||
task->params.write12.lba = lba;
|
||||
task->params.write12.num_blocks = xferlen/blocksize;
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
/*
|
||||
* WRITE16
|
||||
*/
|
||||
struct scsi_task *
|
||||
scsi_cdb_write16(uint64_t lba, uint32_t xferlen, int blocksize, int wrprotect, int dpo, int fua, int fua_nv, int group_number)
|
||||
{
|
||||
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_WRITE16;
|
||||
|
||||
task->cdb[1] |= ((wrprotect & 0x07) << 5);
|
||||
if (dpo) {
|
||||
task->cdb[1] |= 0x10;
|
||||
}
|
||||
if (fua) {
|
||||
task->cdb[1] |= 0x08;
|
||||
}
|
||||
if (fua_nv) {
|
||||
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(xferlen/blocksize);
|
||||
|
||||
task->cdb[14] |= (group_number & 0x1f);
|
||||
|
||||
task->cdb_size = 16;
|
||||
if (xferlen != 0) {
|
||||
task->xfer_dir = SCSI_XFER_WRITE;
|
||||
} else {
|
||||
task->xfer_dir = SCSI_XFER_NONE;
|
||||
}
|
||||
task->expxferlen = xferlen;
|
||||
|
||||
task->params.write16.lba = lba;
|
||||
task->params.write16.num_blocks = xferlen/blocksize;
|
||||
|
||||
return task;
|
||||
}
|
||||
|
||||
/*
|
||||
* VERIFY10
|
||||
|
||||
Reference in New Issue
Block a user