* added definitions for SCSI_OP_VERIFY_* op commands

* added support READ_12/16 and WRITE_12/16 in ata and scsi_periph, this enables read/write on block offsets greater than 2TB


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39278 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Jérôme Duval
2010-11-02 20:56:20 +00:00
parent db2b2bd629
commit f058886908
3 changed files with 64 additions and 3 deletions
+4 -1
View File
@@ -166,6 +166,7 @@
#define SCSI_OP_READ_6 0x08
#define SCSI_OP_WRITE_6 0x0a
#define SCSI_OP_INQUIRY 0x12
#define SCSI_OP_VERIFY_6 0x13
#define SCSI_OP_MODE_SELECT_6 0x15
#define SCSI_OP_RESERVE 0x16
#define SCSI_OP_RELEASE 0x17
@@ -178,7 +179,7 @@
#define SCSI_OP_READ_10 0x28
#define SCSI_OP_WRITE_10 0x2a
#define SCSI_OP_POSITION_TO_ELEMENT 0x2b
#define SCSI_OP_VERIFY 0x2f
#define SCSI_OP_VERIFY_10 0x2f
#define SCSI_OP_SYNCHRONIZE_CACHE 0x35
#define SCSI_OP_WRITE_BUFFER 0x3b
#define SCSI_OP_READ_BUFFER 0x3c
@@ -193,11 +194,13 @@
#define SCSI_OP_MODE_SENSE_10 0x5A
#define SCSI_OP_READ_16 0x88
#define SCSI_OP_WRITE_16 0x8a
#define SCSI_OP_VERIFY_16 0x8f
#define SCSI_OP_SERVICE_ACTION_IN 0x9e
#define SCSI_OP_SERVICE_ACTION_OUT 0x9f
#define SCSI_OP_MOVE_MEDIUM 0xa5
#define SCSI_OP_READ_12 0xa8
#define SCSI_OP_WRITE_12 0xaa
#define SCSI_OP_VERIFY_12 0xaf
#define SCSI_OP_READ_ELEMENT_STATUS 0xb8
#define SCSI_OP_SCAN 0xba
#define SCSI_OP_READ_CD 0xbe
@@ -311,6 +311,40 @@ ATADevice::ExecuteIO(ATARequest *request)
return B_OK;
}
}
case SCSI_OP_READ_12:
case SCSI_OP_WRITE_12:
{
scsi_cmd_rw_12 *command = (scsi_cmd_rw_12 *)ccb->cdb;
uint32 address = B_BENDIAN_TO_HOST_INT32(command->lba);
uint32 sectorCount = B_BENDIAN_TO_HOST_INT32(command->length);
request->SetIsWrite(command->opcode == SCSI_OP_WRITE_12);
if (sectorCount > 0)
return ExecuteReadWrite(request, address, sectorCount);
else {
// we cannot transfer zero blocks (apart from LBA48)
request->SetStatus(SCSI_REQ_CMP);
return B_OK;
}
}
case SCSI_OP_READ_16:
case SCSI_OP_WRITE_16:
{
scsi_cmd_rw_16 *command = (scsi_cmd_rw_16 *)ccb->cdb;
uint64 address = B_BENDIAN_TO_HOST_INT64(command->lba);
uint32 sectorCount = B_BENDIAN_TO_HOST_INT32(command->length);
request->SetIsWrite(command->opcode == SCSI_OP_WRITE_16);
if (sectorCount > 0)
return ExecuteReadWrite(request, address, sectorCount);
else {
// we cannot transfer zero blocks (apart from LBA48)
request->SetStatus(SCSI_REQ_CMP);
return B_OK;
}
}
}
TRACE("command not implemented\n");
+26 -2
View File
@@ -119,7 +119,7 @@ read_write(scsi_periph_device_info *device, scsi_ccb *request,
do {
size_t numBytes;
bool isReadWrite10;
bool isReadWrite10 = false;
request->flags = isWrite ? SCSI_DIR_OUT : SCSI_DIR_IN;
@@ -177,7 +177,7 @@ read_write(scsi_periph_device_info *device, scsi_ccb *request,
cmd->length = numBlocks;
request->cdb_length = sizeof(*cmd);
} else {
} else if (offset + numBlocks < 0x100000000LL && numBlocks <= 0x10000) {
scsi_cmd_rw_10 *cmd = (scsi_cmd_rw_10 *)request->cdb;
isReadWrite10 = true;
@@ -190,6 +190,30 @@ read_write(scsi_periph_device_info *device, scsi_ccb *request,
cmd->lba = B_HOST_TO_BENDIAN_INT32(pos);
cmd->length = B_HOST_TO_BENDIAN_INT16(numBlocks);
request->cdb_length = sizeof(*cmd);
} else if (offset + numBlocks < 0x100000000LL && numBlocks <= 0x10000000) {
scsi_cmd_rw_12 *cmd = (scsi_cmd_rw_12 *)request->cdb;
memset(cmd, 0, sizeof(*cmd));
cmd->opcode = isWrite ? SCSI_OP_WRITE_12 : SCSI_OP_READ_12;
cmd->relative_address = 0;
cmd->force_unit_access = 0;
cmd->disable_page_out = 0;
cmd->lba = B_HOST_TO_BENDIAN_INT32(pos);
cmd->length = B_HOST_TO_BENDIAN_INT32(numBlocks);
request->cdb_length = sizeof(*cmd);
} else {
scsi_cmd_rw_16 *cmd = (scsi_cmd_rw_16 *)request->cdb;
memset(cmd, 0, sizeof(*cmd));
cmd->opcode = isWrite ? SCSI_OP_WRITE_16 : SCSI_OP_READ_16;
cmd->force_unit_access_non_volatile = 0;
cmd->force_unit_access = 0;
cmd->disable_page_out = 0;
cmd->lba = B_HOST_TO_BENDIAN_INT64(offset);
cmd->length = B_HOST_TO_BENDIAN_INT32(numBlocks);
request->cdb_length = sizeof(*cmd);
}