VSCSILunMmc.cpp revision bdec40b10acfe9f798021b508a0a7b8c786fc193
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Virtual SCSI driver: MMC LUN implementation (CD/DVD-ROM)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Copyright (C) 2006-2011 Oracle Corporation
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * available from http://www.virtualbox.org. This file is free software;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * you can redistribute it and/or modify it under the terms of the GNU
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * General Public License (GPL) as published by the Free Software
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync/*******************************************************************************
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync* Header Files *
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync*******************************************************************************/
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * MMC LUN instance
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsynctypedef struct VSCSILUNMMC
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Core LUN structure */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Size of the virtual disk. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Sector size. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** Medium locked indicator. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync PVSCSILUNMMC pVScsiLunMmc = (PVSCSILUNMMC)pVScsiLun;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync pVScsiLunMmc->cbSector = 2048; /* Default to 2K sectors. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync pVScsiLunMmc->cSectors = cbDisk / pVScsiLunMmc->cbSector;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic int vscsiLunMmcDestroy(PVSCSILUNINT pVScsiLun)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync PVSCSILUNMMC pVScsiLunMmc = (PVSCSILUNMMC)pVScsiLun;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsyncstatic int vscsiLunMmcReqProcess(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq)
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync PVSCSILUNMMC pVScsiLunMmc = (PVSCSILUNMMC)pVScsiLun;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync VSCSIIOREQTXDIR enmTxDir = VSCSIIOREQTXDIR_INVALID;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync memset(&ScsiInquiryReply, 0, sizeof(ScsiInquiryReply));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync ScsiInquiryReply.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_CD_DVD;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync ScsiInquiryReply.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_CONNECTED;
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync ScsiInquiryReply.u3AnsiVersion = 0x05; /* MMC-?? compliant */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync ScsiInquiryReply.fCmdQue = 1; /* Command queuing supported. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync vscsiPadStr(ScsiInquiryReply.achVendorId, "VBOX", 8);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync vscsiPadStr(ScsiInquiryReply.achProductId, "CD-ROM", 16);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync vscsiPadStr(ScsiInquiryReply.achProductLevel, "1.0", 4);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, (uint8_t *)&ScsiInquiryReply, sizeof(SCSIINQUIRYDATA));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * If sector size exceeds the maximum value that is
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync * able to be stored in 4 bytes return 0xffffffff in this field
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
968c867cc19737e4e1fd97c396fcf75a3d52dd27vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* @todo: implement!! */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync cSectorTransfer = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
b84a3f2aac9529d5c5840512b12d81bc62d0e665vboxsync cSectorTransfer = vscsiBE2HU32(&pVScsiReq->pbCDB[6]);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync cSectorTransfer = vscsiBE2HU32(&pVScsiReq->pbCDB[10]);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* We do not implement an echo buffer. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync uint16_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
968c867cc19737e4e1fd97c396fcf75a3d52dd27vboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
b84a3f2aac9529d5c5840512b12d81bc62d0e665vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
1823a2b6757096c699825898c33f8d93089a1b4bvboxsync /* Leave the rest 0 */
1823a2b6757096c699825898c33f8d93089a1b4bvboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00); /* Don't know if this is correct */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync //AssertMsgFailed(("Command %#x [%s] not implemented\n", pRequest->pbCDB[0], SCSICmdText(pRequest->pbCDB[0])));
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE, 0x00);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync LogFlow(("%s: uLbaStart=%llu cSectorTransfer=%u\n",
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync if (RT_UNLIKELY(uLbaStart + cSectorTransfer > pVScsiLunMmc->cSectors))
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR, 0x00);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, false, VINF_SUCCESS);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /* A 0 transfer length is not an error. */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
b84a3f2aac9529d5c5840512b12d81bc62d0e665vboxsync vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, false, VINF_SUCCESS);
968c867cc19737e4e1fd97c396fcf75a3d52dd27vboxsync /* Enqueue new I/O request */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync rc = vscsiIoReqTransferEnqueue(pVScsiLun, pVScsiReq, enmTxDir,
1823a2b6757096c699825898c33f8d93089a1b4bvboxsync else /* Request completed */
1823a2b6757096c699825898c33f8d93089a1b4bvboxsync vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, false, VINF_SUCCESS);
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** enmLunType */
968c867cc19737e4e1fd97c396fcf75a3d52dd27vboxsync /** pcszDescName */
968c867cc19737e4e1fd97c396fcf75a3d52dd27vboxsync /** cbLun */
0b74a2f80aba476dc8be8bc1c63891fc53945986vboxsync /** pfnVScsiLunInit */
968c867cc19737e4e1fd97c396fcf75a3d52dd27vboxsync /** pfnVScsiLunDestroy */
968c867cc19737e4e1fd97c396fcf75a3d52dd27vboxsync /** pfnVScsiLunReqProcess */