From 96647a898d62d699808316238dfb933d960413f2 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 00:55:46 +0200 Subject: Merging upstream version 7.0.16-dfsg. Signed-off-by: Daniel Baumann --- src/VBox/Devices/Storage/DevAHCI.cpp | 8 +- src/VBox/Devices/Storage/DevBusLogic.cpp | 13 ++- src/VBox/Devices/Storage/DevLsiLogicSCSI.cpp | 9 +- src/VBox/Devices/Storage/VSCSI/VSCSIDevice.cpp | 49 ++++++++- src/VBox/Devices/Storage/VSCSI/VSCSIInternal.h | 22 ++++ src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp | 111 +++++++++++++++++++++ src/VBox/Devices/Storage/VSCSI/VSCSILunSbc.cpp | 133 +++++++++++++++++++++---- src/VBox/Devices/Storage/VSCSI/VSCSILunSsc.cpp | 2 + 8 files changed, 313 insertions(+), 34 deletions(-) (limited to 'src/VBox/Devices/Storage') 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 */ -- cgit v1.2.3