Author: korli Date: 2010-11-02 21:56:20 +0100 (Tue, 02 Nov 2010) New Revision: 39278 Changeset: http://dev.haiku-os.org/changeset/39278 Modified: haiku/trunk/headers/private/drivers/scsi_cmds.h haiku/trunk/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp haiku/trunk/src/add-ons/kernel/generic/scsi_periph/io.cpp Log: * 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 Modified: haiku/trunk/headers/private/drivers/scsi_cmds.h =================================================================== --- haiku/trunk/headers/private/drivers/scsi_cmds.h 2010-11-02 20:22:48 UTC (rev 39277) +++ haiku/trunk/headers/private/drivers/scsi_cmds.h 2010-11-02 20:56:20 UTC (rev 39278) @@ -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 Modified: haiku/trunk/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp 2010-11-02 20:22:48 UTC (rev 39277) +++ haiku/trunk/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp 2010-11-02 20:56:20 UTC (rev 39278) @@ -311,6 +311,40 @@ 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"); Modified: haiku/trunk/src/add-ons/kernel/generic/scsi_periph/io.cpp =================================================================== --- haiku/trunk/src/add-ons/kernel/generic/scsi_periph/io.cpp 2010-11-02 20:22:48 UTC (rev 39277) +++ haiku/trunk/src/add-ons/kernel/generic/scsi_periph/io.cpp 2010-11-02 20:56:20 UTC (rev 39278) @@ -119,7 +119,7 @@ do { size_t numBytes; - bool isReadWrite10; + bool isReadWrite10 = false; request->flags = isWrite ? SCSI_DIR_OUT : SCSI_DIR_IN; @@ -177,7 +177,7 @@ 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; @@ -191,6 +191,30 @@ 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); } // TODO: last chance to detect errors that occured during concurrent accesses