summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/Storage
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/Storage')
-rw-r--r--src/VBox/Devices/Storage/DevAHCI.cpp8
-rw-r--r--src/VBox/Devices/Storage/DevBusLogic.cpp13
-rw-r--r--src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp9
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp49
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h22
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp111
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp133
-rw-r--r--src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp2
8 files changed, 313 insertions, 34 deletions
diff --git a/src/VBox/Devices/Storage/DevAHCI.cpp b/src/VBox/Devices/Storage/DevAHCI.cpp
index 199dc04f..f77f5c28 100644
--- a/src/VBox/Devices/Storage/DevAHCI.cpp
+++ b/src/VBox/Devices/Storage/DevAHCI.cpp
@@ -1912,7 +1912,7 @@ static VBOXSTRICTRC PortInvalid_r(PPDMDEVINS pDevIns, PAHCI pThis, PAHCIPORT pAh
{
RT_NOREF(pDevIns, pThis, pAhciPort, iReg, pu32Value);
ahciLog(("%s: Read denied!!! iReg=%u\n", __FUNCTION__, iReg));
- return VINF_SUCCESS;
+ return VINF_IOM_MMIO_UNUSED_00;
}
/**
@@ -2356,10 +2356,10 @@ ahciLegacyFakeWrite(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t
static DECLCALLBACK(VBOXSTRICTRC)
ahciLegacyFakeRead(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb)
{
- /** @todo we should set *pu32 to something. */
- RT_NOREF(pDevIns, pvUser, offPort, pu32, cb);
+ *pu32 = 0;
+ RT_NOREF(pDevIns, pvUser, offPort, cb);
ASSERT_GUEST_MSG_FAILED(("Should not happen\n"));
- return VINF_SUCCESS;
+ return VERR_IOM_IOPORT_UNUSED;
}
diff --git a/src/VBox/Devices/Storage/DevBusLogic.cpp b/src/VBox/Devices/Storage/DevBusLogic.cpp
index a5cf9f9a..21f59250 100644
--- a/src/VBox/Devices/Storage/DevBusLogic.cpp
+++ b/src/VBox/Devices/Storage/DevBusLogic.cpp
@@ -979,10 +979,12 @@ typedef struct ESCMD
unsigned char uReserved2 : 3;
/** Length of the SCSI CDB. */
uint8_t cbCDB;
- /** The SCSI CDB. (A CDB can be 12 bytes long.) */
- uint8_t abCDB[12];
+ /** The SCSI CDB. (A CDB from our BIOS can be up to 16 bytes long
+ * which works with our emulation even though the original BusLogic HBA
+ * supports only 12 byte CDBs). */
+ uint8_t abCDB[16];
} ESCMD, *PESCMD;
-AssertCompileSize(ESCMD, 24);
+AssertCompileSize(ESCMD, 28);
/**
* Task state for a CCB request.
@@ -3161,7 +3163,8 @@ static int buslogicR3DeviceSCSIRequestSetup(PPDMDEVINS pDevIns, PBUSLOGIC pThis,
blPhysReadMeta(pDevIns, pThis, GCPhysAddrCCB, &CCBGuest, sizeof(CCB32));
uTargetIdCCB = pThis->fMbxIs24Bit ? CCBGuest.o.uTargetId : CCBGuest.n.uTargetId;
- if (RT_LIKELY(uTargetIdCCB < RT_ELEMENTS(pThisCC->aDeviceStates)))
+ if ( RT_LIKELY(uTargetIdCCB < RT_ELEMENTS(pThisCC->aDeviceStates))
+ && CCBGuest.c.cbCDB <= RT_ELEMENTS(CCBGuest.c.abCDB))
{
PBUSLOGICDEVICE pTgtDev = &pThisCC->aDeviceStates[uTargetIdCCB];
@@ -3378,7 +3381,7 @@ static void buslogicR3ProcessBiosReq(PPDMDEVINS pDevIns, PBUSLOGIC pThis, PBUSLO
PESCMD pCmd = (PESCMD)pThis->aCommandBuffer;
if (RT_LIKELY( pCmd->uTargetId < RT_ELEMENTS(pThisCC->aDeviceStates)
- && pCmd->cbCDB <= 16))
+ && pCmd->cbCDB <= RT_ELEMENTS(pCmd->abCDB)))
{
PBUSLOGICDEVICE pTgtDev = &pThisCC->aDeviceStates[pCmd->uTargetId];
diff --git a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
index b089f3c4..626f531d 100644
--- a/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
+++ b/src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp
@@ -2295,7 +2295,8 @@ static int lsilogicR3ProcessSCSIIORequest(PPDMDEVINS pDevIns, PLSILOGICSCSI pThi
{
PLSILOGICDEVICE pTgtDev = &pThisCC->paDeviceStates[pGuestReq->SCSIIO.u8TargetID];
- if (pTgtDev->pDrvBase)
+ if ( pTgtDev->pDrvBase
+ && pGuestReq->SCSIIO.u8CDBLength <= RT_ELEMENTS(pGuestReq->SCSIIO.au8CDB))
{
/* Allocate and prepare a new request. */
PDMMEDIAEXIOREQ hIoReq;
@@ -2364,12 +2365,12 @@ static int lsilogicR3ProcessSCSIIORequest(PPDMDEVINS pDevIns, PLSILOGICSCSI pThi
if (g_cLogged++ < MAX_REL_LOG_ERRORS)
{
- LogRel(("LsiLogic#%d: %d/%d (Bus/Target) doesn't exist\n", pDevIns->iInstance,
- pGuestReq->SCSIIO.u8TargetID, pGuestReq->SCSIIO.u8Bus));
+ LogRel(("LsiLogic#%d: %d/%d/%d (Bus/Target/CDBLength) doesn't exist\n", pDevIns->iInstance,
+ pGuestReq->SCSIIO.u8TargetID, pGuestReq->SCSIIO.u8Bus, pGuestReq->SCSIIO.u8CDBLength));
/* Log the CDB too */
LogRel(("LsiLogic#%d: Guest issued CDB {%#x",
pDevIns->iInstance, pGuestReq->SCSIIO.au8CDB[0]));
- for (unsigned i = 1; i < pGuestReq->SCSIIO.u8CDBLength; i++)
+ for (unsigned i = 1; i < RT_MIN(pGuestReq->SCSIIO.u8CDBLength, RT_ELEMENTS(pGuestReq->SCSIIO.au8CDB)); i++)
LogRel((", %#x", pGuestReq->SCSIIO.au8CDB[i]));
LogRel(("}\n"));
}
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
index a2864b84..2b8a9a07 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp
@@ -67,6 +67,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
{
bool fProcessed = true;
+ if (!pVScsiReq->cbCDB)
+ {
+ *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ return true;
+ }
+
switch (pVScsiReq->pbCDB[0])
{
case SCSI_INQUIRY:
@@ -92,6 +99,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
}
case SCSI_REPORT_LUNS:
{
+ if (pVScsiReq->cbCDB < 10)
+ {
+ *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ break;
+ }
+
/*
* If allocation length is less than 16 bytes SPC compliant devices have
* to return an error.
@@ -127,6 +141,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
}
case SCSI_REQUEST_SENSE:
{
+ if (pVScsiReq->cbCDB < 5)
+ {
+ *prcReq = vscsiReqSenseErrorSet(&pVScsiDevice->VScsiSense, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ break;
+ }
+
vscsiReqSetXferDir(pVScsiReq, VSCSIXFERDIR_T2I);
vscsiReqSetXferSize(pVScsiReq, pVScsiReq->pbCDB[4]);
@@ -140,6 +161,13 @@ static bool vscsiDeviceReqProcess(PVSCSIDEVICEINT pVScsiDevice, PVSCSIREQINT pVS
#if 0
case SCSI_MAINTENANCE_IN:
{
+ if (pVScsiReq->cbCDB < 8)
+ {
+ *prcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+ break;
+ }
+
if (pVScsiReq->pbCDB[1] == SCSI_MAINTENANCE_IN_REPORT_SUPP_OPC)
{
/*
@@ -374,7 +402,26 @@ VBOXDDU_DECL(int) VSCSIDeviceReqEnqueue(VSCSIDEVICE hVScsiDevice, VSCSIREQ hVScs
if (vscsiDeviceLunIsPresent(pVScsiDevice, pVScsiReq->iLun))
{
PVSCSILUNINT pVScsiLun = pVScsiDevice->papVScsiLun[pVScsiReq->iLun];
- rc = pVScsiLun->pVScsiLunDesc->pfnVScsiLunReqProcess(pVScsiLun, pVScsiReq);
+ PVSCSILUNDESC pVScsiLunDesc = pVScsiLun->pVScsiLunDesc;
+ uint8_t const bOpc = pVScsiReq->pbCDB[0];
+ uint8_t const cbCdbMin = pVScsiLunDesc->pacbCdbOpc[bOpc];
+
+ /* Fail if the opcode is not supported or the CDB is too short. */
+ if ( cbCdbMin != VSCSI_LUN_CDB_SZ_INVALID
+ && pVScsiReq->cbCDB >= cbCdbMin)
+ rc = pVScsiLunDesc->pfnVScsiLunReqProcess(pVScsiLun, pVScsiReq);
+ else
+ {
+ /*
+ * CDB length is smaller than what the LUN expects, respond with an
+ * ILLEGAL OPCODE error.
+ */
+ vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
+ SCSI_ASC_ILLEGAL_OPCODE, 0x00);
+
+ vscsiDeviceReqComplete(pVScsiDevice, pVScsiReq,
+ SCSI_STATUS_CHECK_CONDITION, false, VINF_SUCCESS);
+ }
}
else
{
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h b/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
index 71924d1d..b4af0cb5 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h
@@ -241,6 +241,25 @@ typedef const VSCSILUNSUPOPC *PCVSCSILUNSUPOPC;
{ a_u8Opc, a_u16SvcAction, VSCSI_LUN_SUP_OPC_SVC_ACTION_REQUIRED, a_pszOpc, a_cbCdb, a_pbCdbUsage, 0, 0, 0}
/** @} */
+/** @name Helper macros to specify a range of not supported CDB opcodes for the entries pointed
+ * to by VSCSILUNDESC::pacbCdbOpc.
+ * @{ */
+#define VSCSI_LUN_CDB_SZ_INVALID 0
+#define VSCSI_LUN_CDB_SZ_INVALID_X2 \
+ VSCSI_LUN_CDB_SZ_INVALID, \
+ VSCSI_LUN_CDB_SZ_INVALID
+#define VSCSI_LUN_CDB_SZ_INVALID_X4 \
+ VSCSI_LUN_CDB_SZ_INVALID_X2, \
+ VSCSI_LUN_CDB_SZ_INVALID_X2
+#define VSCSI_LUN_CDB_SZ_INVALID_X8 \
+ VSCSI_LUN_CDB_SZ_INVALID_X4, \
+ VSCSI_LUN_CDB_SZ_INVALID_X4
+#define VSCSI_LUN_CDB_SZ_INVALID_X16 \
+ VSCSI_LUN_CDB_SZ_INVALID_X8, \
+ VSCSI_LUN_CDB_SZ_INVALID_X8
+/** @} */
+
+
/**
* Virtual SCSI LUN descriptor.
*/
@@ -252,6 +271,9 @@ typedef struct VSCSILUNDESC
const char *pcszDescName;
/** LUN type size */
size_t cbLun;
+ /** Pointer to the array holding the CDB length indexed by the opcode.
+ * A 0 entry means opcode not supported (CDB must be at least 1 byte big). */
+ const uint8_t *pacbCdbOpc;
/** Number of entries in the supported operation codes array. */
uint32_t cSupOpcInfo;
/** Pointer to the array of supported operation codes for the
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp
index 66d76e22..24fc6a33 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp
@@ -1770,6 +1770,115 @@ static DECLCALLBACK(int) vscsiLunMmcMediumRemoved(PVSCSILUNINT pVScsiLun)
}
+/**
+ * The supported operation codes for the MMC LUN type.
+ *
+ * @note This gives the minimum size required by our implementation
+ * which may be smaller than what the spec defines (for example
+ * we do not access the control byte at the end).
+ */
+static uint8_t s_acbCdbOpc[] =
+{
+ 1, /**< 0x00 TEST UNIT READY */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x01 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x02 - 0x03 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x04 - 0x07 Invalid */
+ 5, /**< 0x08 READ (6) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x09 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x0a - 0x0b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x0c - 0x0f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x10 - 0x11 Invalid */
+ 5, /**< 0x12 INQUIRY */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x13 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x14 Invalid */
+ 5, /**< 0x15 MODE SELECT (6) */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x16 - 0x17 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x18 - 0x19 Invalid */
+ 5, /**< 0x1a MODE SENSE (6) */
+ 5, /**< 0x1b START STOP UNIT */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x1c - 0x1d Invalid */
+ 5, /**< 0x1e PREVENT ALLOW MEDIUM REMOVAL */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x1f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x20 - 0x23 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x24 Invalid */
+ 1, /**< 0x25 READ CAPACITY */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x26 - 0x27 Invalid */
+ 9, /**< 0x28 READ (10) */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x29 - 0x2a Invalid */
+ 6, /**< 0x2b SEEK (10) */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x2c - 0x2d Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x2e Invalid */
+ 5, /**< 0x2f VERIFY (10) */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x30 - 0x37 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x38 - 0x3b Invalid */
+ 8, /**< 0x3c READ BUFFER */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x3d Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x3e - 0x3f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x40 - 0x41 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x42 Invalid */
+ 9, /**< 0x43 READ TOC PMA ATIP */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x44 - 0x45 Invalid */
+ 9, /**< 0x46 GET CONFIGURATION */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x47 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x48 - 0x49 Invalid */
+ 9, /**< 0x4a GET EVENT STATUS NOTIFICATION */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x4b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x4c Invalid */
+ 9, /**< 0x4d LOG SENSE */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x4e - 0x4f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x50 Invalid */
+ 9, /**< 0x51 READ DISC INFORMATION */
+ 9, /**< 0x52 READ TRACK INFORMATION */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x53 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x54 - 0x57 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x58 - 0x59 Invalid */
+ 9, /**< 0x5a MODE SENSE (10) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x5b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x5c - 0x5f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x60 - 0x6f Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x70 - 0x7f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x80 - 0x87 Invalid */
+ 14, /**< 0x88 READ (16) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x89 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x8a - 0x8b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x8c - 0x8f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x90 - 0x97 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x98 - 0x9b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x9c - 0x9d Invalid */
+ 2, /**< 0x9e SERVICE ACTION IN (16) (at least 2). */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x9f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0xa0 - 0xa7 Invalid */
+ 10, /**< 0xa8 READ (12) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xa9 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0xaa - 0xab Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xac Invalid */
+ 10, /**< 0xad READ DVD STRUCTURE */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0xae - 0xaf Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0xb0 - 0xb7 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0xb8 - 0xbb Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xbc Invalid */
+ 10, /**< 0xbd MECHANISM STATUS */
+ 10, /**< 0xbe READ CD */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xbf Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xc0 - 0xcf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xd0 - 0xdf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xe0 - 0xef Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16 /**< 0xf0 - 0xff Invalid */
+};
+AssertCompileSize(s_acbCdbOpc, 256 * sizeof(uint8_t));
+
+
VSCSILUNDESC g_VScsiLunTypeMmc =
{
/** enmLunType */
@@ -1778,6 +1887,8 @@ VSCSILUNDESC g_VScsiLunTypeMmc =
"MMC",
/** cbLun */
sizeof(VSCSILUNMMC),
+ /** pacbCdbOpc */
+ &s_acbCdbOpc[0],
/** cSupOpcInfo */
0,
/** paSupOpcInfo */
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
index 3769c4f6..3fb5436e 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp
@@ -230,30 +230,35 @@ static DECLCALLBACK(int) vscsiLunSbcReqProcess(PVSCSILUNINT pVScsiLun, PVSCSIREQ
SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
else
{
- SCSIINQUIRYDATA ScsiInquiryReply;
+ if (pVScsiReq->cbCDB >= 5)
+ {
+ SCSIINQUIRYDATA ScsiInquiryReply;
- vscsiReqSetXferSize(pVScsiReq, RT_MIN(sizeof(SCSIINQUIRYDATA), scsiBE2H_U16(&pVScsiReq->pbCDB[3])));
- memset(&ScsiInquiryReply, 0, sizeof(ScsiInquiryReply));
+ vscsiReqSetXferSize(pVScsiReq, RT_MIN(sizeof(SCSIINQUIRYDATA), scsiBE2H_U16(&pVScsiReq->pbCDB[3])));
+ memset(&ScsiInquiryReply, 0, sizeof(ScsiInquiryReply));
- ScsiInquiryReply.cbAdditional = 31;
- ScsiInquiryReply.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS;
- ScsiInquiryReply.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_CONNECTED;
- ScsiInquiryReply.u3AnsiVersion = 0x05; /* SPC-4 compliant */
- ScsiInquiryReply.fCmdQue = 1; /* Command queuing supported. */
- ScsiInquiryReply.fWBus16 = 1;
+ ScsiInquiryReply.cbAdditional = 31;
+ ScsiInquiryReply.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_DIRECT_ACCESS;
+ ScsiInquiryReply.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_CONNECTED;
+ ScsiInquiryReply.u3AnsiVersion = 0x05; /* SPC-4 compliant */
+ ScsiInquiryReply.fCmdQue = 1; /* Command queuing supported. */
+ ScsiInquiryReply.fWBus16 = 1;
- const char *pszVendorId = "VBOX";
- const char *pszProductId = "HARDDISK";
- const char *pszProductLevel = "1.0";
- int rcTmp = vscsiLunQueryInqStrings(pVScsiLun, &pszVendorId, &pszProductId, &pszProductLevel);
- Assert(RT_SUCCESS(rcTmp) || rcTmp == VERR_NOT_FOUND); RT_NOREF(rcTmp);
+ const char *pszVendorId = "VBOX";
+ const char *pszProductId = "HARDDISK";
+ const char *pszProductLevel = "1.0";
+ int rcTmp = vscsiLunQueryInqStrings(pVScsiLun, &pszVendorId, &pszProductId, &pszProductLevel);
+ Assert(RT_SUCCESS(rcTmp) || rcTmp == VERR_NOT_FOUND); RT_NOREF(rcTmp);
- scsiPadStrS(ScsiInquiryReply.achVendorId, pszVendorId, 8);
- scsiPadStrS(ScsiInquiryReply.achProductId, pszProductId, 16);
- scsiPadStrS(ScsiInquiryReply.achProductLevel, pszProductLevel, 4);
+ scsiPadStrS(ScsiInquiryReply.achVendorId, pszVendorId, 8);
+ scsiPadStrS(ScsiInquiryReply.achProductId, pszProductId, 16);
+ scsiPadStrS(ScsiInquiryReply.achProductLevel, pszProductLevel, 4);
- RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, (uint8_t *)&ScsiInquiryReply, sizeof(SCSIINQUIRYDATA));
- rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
+ RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, (uint8_t *)&ScsiInquiryReply, sizeof(SCSIINQUIRYDATA));
+ rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
+ }
+ else
+ rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INVALID_MESSAGE, 0x00);
}
break;
}
@@ -419,7 +424,7 @@ static DECLCALLBACK(int) vscsiLunSbcReqProcess(PVSCSILUNINT pVScsiLun, PVSCSIREQ
uint8_t uDataMode = pVScsiReq->pbCDB[1] & 0x1f;
vscsiReqSetXferDir(pVScsiReq, VSCSIXFERDIR_T2I);
- vscsiReqSetXferSize(pVScsiReq, scsiBE2H_U16(&pVScsiReq->pbCDB[6]));
+ vscsiReqSetXferSize(pVScsiReq, scsiBE2H_U24(&pVScsiReq->pbCDB[6]));
switch (uDataMode)
{
@@ -627,6 +632,92 @@ static DECLCALLBACK(int) vscsiLunSbcReqProcess(PVSCSILUNINT pVScsiLun, PVSCSIREQ
return rc;
}
+
+/**
+ * The supported operation codes for the SBC LUN type.
+ *
+ * @note This gives the minimum size required by our implementation
+ * which may be smaller than what the spec defines (for example
+ * we do not access the control byte at the end).
+ */
+static uint8_t s_acbCdbOpc[] =
+{
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x00 - 0x07 Invalid */
+ 5, /**< 0x08 READ (6) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x09 Invalid */
+ 5, /**< 0x0a WRITE (6) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x0b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x0c - 0x0f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x10 - 0x11 Invalid */
+ 3, /**< 0x12 INQUIRY (at least 3) */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x13 - 0x14 Invalid */
+ 5, /**< 0x15 MODE SELECT (6) */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x16 - 0x19 Invalid */
+ 5, /**< 0x1a MODE SENSE (6) */
+ 1, /**< 0x1b START STOP UNIT */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x1c - 0x1f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x20 - 0x23 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x24 Invalid */
+ 1, /**< 0x25 READ CAPACITY */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x26 - 0x27 Invalid */
+ 9, /**< 0x28 READ (10) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x29 Invalid */
+ 9, /**< 0x2a WRITE (10) */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x2b - 0x2e Invalid */
+ 1, /**< 0x2f VERIFY (10) */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x30 - 0x33 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x34 Invalid */
+ 1, /**< 0x35 SYNCHRONIZE CACHE */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x36 - 0x39 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x3a - 0x3b Invalid */
+ 8, /**< 0x3c READ BUFFER */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x3d Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x3e - 0x3f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x40 - 0x41 Invalid */
+ 9, /**< 0x42 UNMAP */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x43 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x44 - 0x4b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x4c Invalid */
+ 9, /**< 0x4d LOG SENSE */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x4e - 0x4f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x50 - 0x5f Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x60 - 0x6f Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0x70 - 0x7f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x80 - 0x87 Invalid */
+ 14, /**< 0x88 READ (16) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x89 Invalid */
+ 14, /**< 0x8a WRITE (16) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x8b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x8c - 0x8f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0x90 - 0x97 Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0x98 - 0x9b Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X2, /**< 0x9c - 0x9d Invalid */
+ 2, /**< 0x9e SERVICE ACTION IN (16) (at least 2). */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0x9f Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X8, /**< 0xa0 - 0xa7 Invalid */
+ 10, /**< 0xa8 READ (12) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xa9 Invalid */
+ 10, /**< 0xaa WRITE (12) */
+ VSCSI_LUN_CDB_SZ_INVALID, /**< 0xab Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X4, /**< 0xac - 0xaf Invalid */
+
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xb0 - 0xbf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xc0 - 0xcf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xd0 - 0xdf Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16, /**< 0xe0 - 0xef Invalid */
+ VSCSI_LUN_CDB_SZ_INVALID_X16 /**< 0xf0 - 0xff Invalid */
+};
+AssertCompileSize(s_acbCdbOpc, 256 * sizeof(uint8_t));
+
+
VSCSILUNDESC g_VScsiLunTypeSbc =
{
/** enmLunType */
@@ -635,6 +726,8 @@ VSCSILUNDESC g_VScsiLunTypeSbc =
"SBC",
/** cbLun */
sizeof(VSCSILUNSBC),
+ /** pacbCdbOpc */
+ &s_acbCdbOpc[0],
/** cSupOpcInfo */
0,
/** paSupOpcInfo */
diff --git a/src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp b/src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp
index 4c659a2d..a190ff65 100644
--- a/src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp
+++ b/src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp
@@ -450,6 +450,8 @@ VSCSILUNDESC g_VScsiLunTypeSsc =
"SSC",
/** cbLun */
sizeof(VSCSILUNSSC),
+ /** pacbCdbOpc */
+ NULL,
/** cSupOpcInfo */
0,
/** paSupOpcInfo */