* 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:
@@ -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");
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user