8683cfdc9273dd77e1c4e89886a7052de103591avboxsync/* $Id$ */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync/** @file
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * Virtual SCSI driver: MMC LUN implementation (CD/DVD-ROM)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2012 Oracle Corporation
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync *
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * available from http://www.virtualbox.org. This file is free software;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * you can redistribute it and/or modify it under the terms of the GNU
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * General Public License (GPL) as published by the Free Software
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync/*******************************************************************************
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync* Header Files *
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync*******************************************************************************/
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync#define LOG_GROUP LOG_GROUP_VSCSI
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync#include <VBox/log.h>
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync#include <VBox/err.h>
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync#include <VBox/types.h>
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync#include <VBox/vscsi.h>
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync#include <iprt/assert.h>
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync#include <iprt/mem.h>
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync#include <iprt/string.h>
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync#include "VSCSIInternal.h"
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync/**
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * MMC LUN instance
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsynctypedef struct VSCSILUNMMC
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync{
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /** Core LUN structure */
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync VSCSILUNINT Core;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /** Size of the virtual disk. */
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync uint64_t cSectors;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /** Sector size. */
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync uint32_t cbSector;
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync /** Medium locked indicator. */
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync bool fLocked;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync} VSCSILUNMMC, *PVSCSILUNMMC;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsyncDECLINLINE(void) mmcLBA2MSF(uint8_t *pbBuf, uint32_t iLBA)
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync{
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync iLBA += 150;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync pbBuf[0] = (iLBA / 75) / 60;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync pbBuf[1] = (iLBA / 75) % 60;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync pbBuf[2] = iLBA % 75;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync}
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsyncDECLINLINE(uint32_t) mmcMSF2LBA(const uint8_t *pbBuf)
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync{
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync return (pbBuf[0] * 60 + pbBuf[1]) * 75 + pbBuf[2];
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync}
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync/* Fabricate normal TOC information. */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsyncstatic int mmcReadTOCNormal(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint16_t cbMaxTransfer, bool fMSF)
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync{
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync PVSCSILUNMMC pVScsiLunMmc = (PVSCSILUNMMC)pVScsiLun;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync uint8_t aReply[32];
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync uint8_t *pbBuf = aReply;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync uint8_t *q;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync uint8_t iStartTrack;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync uint32_t cbSize;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync iStartTrack = pVScsiReq->pbCDB[6];
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync if (iStartTrack > 1 && iStartTrack != 0xaa)
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync {
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync return vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync }
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync q = pbBuf + 2;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 1; /* first session */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 1; /* last session */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync if (iStartTrack <= 1)
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync {
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 0; /* reserved */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 0x14; /* ADR, CONTROL */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 1; /* track number */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 0; /* reserved */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync if (fMSF)
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync {
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 0; /* reserved */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync mmcLBA2MSF(q, 0);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync q += 3;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync }
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync else
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync {
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync /* sector 0 */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync vscsiH2BEU32(q, 0);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync q += 4;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync }
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync }
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync /* lead out track */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 0; /* reserved */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 0x14; /* ADR, CONTROL */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 0xaa; /* track number */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 0; /* reserved */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync if (fMSF)
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync {
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync *q++ = 0; /* reserved */
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync mmcLBA2MSF(q, pVScsiLunMmc->cSectors);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync q += 3;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync }
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync else
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync {
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync vscsiH2BEU32(q, pVScsiLunMmc->cSectors);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync q += 4;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync }
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync cbSize = q - pbBuf;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync Assert(cbSize <= sizeof(aReply));
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync vscsiH2BEU16(pbBuf, cbSize - 2);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync if (cbSize < cbMaxTransfer)
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync cbMaxTransfer = cbSize;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, cbMaxTransfer);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync return vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync}
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync/* Fabricate session information. */
a9205f11b268f45a18a89049148ff266bcf687a3vboxsyncstatic int mmcReadTOCMulti(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint16_t cbMaxTransfer, bool fMSF)
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync{
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync PVSCSILUNMMC pVScsiLunMmc = (PVSCSILUNMMC)pVScsiLun;
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync uint8_t aReply[32];
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync uint8_t *pbBuf = aReply;
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync /* multi session: only a single session defined */
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync memset(pbBuf, 0, 12);
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync pbBuf[1] = 0x0a;
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync pbBuf[2] = 0x01; /* first complete session number */
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync pbBuf[3] = 0x01; /* last complete session number */
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync pbBuf[5] = 0x14; /* ADR, CONTROL */
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync pbBuf[6] = 1; /* first track in last complete session */
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync if (fMSF)
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync {
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync pbBuf[8] = 0; /* reserved */
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync mmcLBA2MSF(pbBuf + 8, 0);
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync }
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync else
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync {
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync /* sector 0 */
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync vscsiH2BEU32(pbBuf + 8, 0);
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync }
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, 12);
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync return vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync}
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsyncstatic int vscsiLunMmcInit(PVSCSILUNINT pVScsiLun)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync{
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync PVSCSILUNMMC pVScsiLunMmc = (PVSCSILUNMMC)pVScsiLun;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint64_t cbDisk = 0;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync int rc = VINF_SUCCESS;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync pVScsiLunMmc->cbSector = 2048; /* Default to 2K sectors. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rc = vscsiLunMediumGetSize(pVScsiLun, &cbDisk);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync if (RT_SUCCESS(rc))
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync pVScsiLunMmc->cSectors = cbDisk / pVScsiLunMmc->cbSector;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync return rc;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync}
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsyncstatic int vscsiLunMmcDestroy(PVSCSILUNINT pVScsiLun)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync{
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync PVSCSILUNMMC pVScsiLunMmc = (PVSCSILUNMMC)pVScsiLun;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync return VINF_SUCCESS;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync}
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsyncstatic int vscsiLunMmcReqProcess(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync{
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync PVSCSILUNMMC pVScsiLunMmc = (PVSCSILUNMMC)pVScsiLun;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync VSCSIIOREQTXDIR enmTxDir = VSCSIIOREQTXDIR_INVALID;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint64_t uLbaStart = 0;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint32_t cSectorTransfer = 0;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync int rc = VINF_SUCCESS;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync int rcReq = SCSI_STATUS_OK;
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync unsigned uCmd = pVScsiReq->pbCDB[0];
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync
1e9e76e4273dcc2e3d560a0f3605c46f0013eb7bvboxsync /*
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync * GET CONFIGURATION, GET EVENT/STATUS NOTIFICATION, INQUIRY, and REQUEST SENSE commands
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync * operate even when a unit attention condition exists for initiator; every other command
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync * needs to report CHECK CONDITION in that case.
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync */
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync if (!pVScsiLunMmc->Core.fReady && uCmd != SCSI_INQUIRY)
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync {
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync /*
1e9e76e4273dcc2e3d560a0f3605c46f0013eb7bvboxsync * A note on media changes: As long as a medium is not present, the unit remains in
1e9e76e4273dcc2e3d560a0f3605c46f0013eb7bvboxsync * the 'not ready' state. Technically the unit becomes 'ready' soon after a medium
1e9e76e4273dcc2e3d560a0f3605c46f0013eb7bvboxsync * is inserted; however, we internally keep the 'not ready' state until we've had
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync * a chance to report the UNIT ATTENTION status indicating a media change.
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync */
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync if (pVScsiLunMmc->Core.fMediaPresent)
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync {
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_UNIT_ATTENTION,
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync SCSI_ASC_MEDIUM_MAY_HAVE_CHANGED, 0x00);
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync pVScsiLunMmc->Core.fReady = true;
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync }
1e9e76e4273dcc2e3d560a0f3605c46f0013eb7bvboxsync else
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_NOT_READY,
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync SCSI_ASC_MEDIUM_NOT_PRESENT, 0x00);
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync }
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync else
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync switch (uCmd)
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync {
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync case SCSI_TEST_UNIT_READY:
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync Assert(!pVScsiLunMmc->Core.fReady); /* Only should get here if LUN isn't ready. */
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_NOT_READY, SCSI_ASC_MEDIUM_NOT_PRESENT, 0x00);
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync break;
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_INQUIRY:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync SCSIINQUIRYDATA ScsiInquiryReply;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync memset(&ScsiInquiryReply, 0, sizeof(ScsiInquiryReply));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync ScsiInquiryReply.cbAdditional = 31;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync ScsiInquiryReply.fRMB = 1; /* Removable. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync ScsiInquiryReply.u5PeripheralDeviceType = SCSI_INQUIRY_DATA_PERIPHERAL_DEVICE_TYPE_CD_DVD;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync ScsiInquiryReply.u3PeripheralQualifier = SCSI_INQUIRY_DATA_PERIPHERAL_QUALIFIER_CONNECTED;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync ScsiInquiryReply.u3AnsiVersion = 0x05; /* MMC-?? compliant */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync ScsiInquiryReply.fCmdQue = 1; /* Command queuing supported. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync ScsiInquiryReply.fWBus16 = 1;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiPadStr(ScsiInquiryReply.achVendorId, "VBOX", 8);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiPadStr(ScsiInquiryReply.achProductId, "CD-ROM", 16);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiPadStr(ScsiInquiryReply.achProductLevel, "1.0", 4);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, (uint8_t *)&ScsiInquiryReply, sizeof(SCSIINQUIRYDATA));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_READ_CAPACITY:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t aReply[8];
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync memset(aReply, 0, sizeof(aReply));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /*
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * If sector size exceeds the maximum value that is
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync * able to be stored in 4 bytes return 0xffffffff in this field
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync if (pVScsiLunMmc->cSectors > UINT32_C(0xffffffff))
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiH2BEU32(aReply, UINT32_C(0xffffffff));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync else
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiH2BEU32(aReply, pVScsiLunMmc->cSectors - 1);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiH2BEU32(&aReply[4], pVScsiLunMmc->cbSector);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_MODE_SENSE_6:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t uModePage = pVScsiReq->pbCDB[2] & 0x3f;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t aReply[24];
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t *pu8ReplyPos;
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync bool fValid = false;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync memset(aReply, 0, sizeof(aReply));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync aReply[0] = 4; /* Reply length 4. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync aReply[1] = 0; /* Default media type. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync aReply[2] = RT_BIT(4); /* Caching supported. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync aReply[3] = 0; /* Block descriptor length. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync pu8ReplyPos = aReply + 4;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync if ((uModePage == 0x08) || (uModePage == 0x3f))
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync memset(pu8ReplyPos, 0, 20);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync *pu8ReplyPos++ = 0x08; /* Page code. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync *pu8ReplyPos++ = 0x12; /* Size of the page. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync *pu8ReplyPos++ = 0x4; /* Write cache enabled. */
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync fValid = true;
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync } else if (uModePage == 0) {
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync fValid = true;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync /* Querying unknown pages must fail. */
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync if (fValid) {
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync } else {
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
1ba7c786d0f14158d76aaaf8e6eb1ee410179d3fvboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_MODE_SELECT_6:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /* @todo: implement!! */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_READ_6:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync enmTxDir = VSCSIIOREQTXDIR_READ;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uLbaStart = ((uint64_t) pVScsiReq->pbCDB[3]
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync | (pVScsiReq->pbCDB[2] << 8)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync | ((pVScsiReq->pbCDB[1] & 0x1f) << 16));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync cSectorTransfer = pVScsiReq->pbCDB[4];
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_READ_10:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync enmTxDir = VSCSIIOREQTXDIR_READ;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uLbaStart = vscsiBE2HU32(&pVScsiReq->pbCDB[2]);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync cSectorTransfer = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_READ_12:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync enmTxDir = VSCSIIOREQTXDIR_READ;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uLbaStart = vscsiBE2HU32(&pVScsiReq->pbCDB[2]);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync cSectorTransfer = vscsiBE2HU32(&pVScsiReq->pbCDB[6]);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_READ_16:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync enmTxDir = VSCSIIOREQTXDIR_READ;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uLbaStart = vscsiBE2HU64(&pVScsiReq->pbCDB[2]);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync cSectorTransfer = vscsiBE2HU32(&pVScsiReq->pbCDB[10]);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_READ_BUFFER:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t uDataMode = pVScsiReq->pbCDB[1] & 0x1f;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync switch (uDataMode)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case 0x00:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case 0x01:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case 0x02:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case 0x03:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case 0x0a:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case 0x0b:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t aReply[4];
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /* We do not implement an echo buffer. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync memset(aReply, 0, sizeof(aReply));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case 0x1a:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case 0x1c:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync default:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync AssertMsgFailed(("Invalid data mode\n"));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_VERIFY_10:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_START_STOP_UNIT:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_LOG_SENSE:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint16_t cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t uPageCode = pVScsiReq->pbCDB[2] & 0x3f;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t uSubPageCode = pVScsiReq->pbCDB[3];
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync switch (uPageCode)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case 0x00:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync if (uSubPageCode == 0)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t aReply[4];
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync aReply[0] = 0;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync aReply[1] = 0;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync aReply[2] = 0;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync aReply[3] = 0;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync default:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_SERVICE_ACTION_IN_16:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync switch (pVScsiReq->pbCDB[1] & 0x1f)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync case SCSI_SVC_ACTION_IN_READ_CAPACITY_16:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uint8_t aReply[32];
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync memset(aReply, 0, sizeof(aReply));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiH2BEU64(aReply, pVScsiLunMmc->cSectors - 1);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiH2BEU32(&aReply[8], pVScsiLunMmc->cbSector);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /* Leave the rest 0 */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, sizeof(aReply));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync default:
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00); /* Don't know if this is correct */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync break;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync case SCSI_PREVENT_ALLOW_MEDIUM_REMOVAL:
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync {
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync pVScsiLunMmc->fLocked = pVScsiReq->pbCDB[4] & 1;
5761ae063fc6a6dcc410a6b56ddc286ba16855c8vboxsync vscsiLunMediumSetLock(pVScsiLun, pVScsiLunMmc->fLocked);
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync break;
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync }
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync case SCSI_READ_TOC_PMA_ATIP:
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync {
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync uint8_t format;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync uint16_t cbMax;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync bool fMSF;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync format = pVScsiReq->pbCDB[2] & 0x0f;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync cbMax = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync fMSF = (pVScsiReq->pbCDB[1] >> 1) & 1;
1e9e76e4273dcc2e3d560a0f3605c46f0013eb7bvboxsync switch (format)
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync {
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync case 0x00:
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync mmcReadTOCNormal(pVScsiLun, pVScsiReq, cbMax, fMSF);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync break;
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync case 0x01:
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync mmcReadTOCMulti(pVScsiLun, pVScsiReq, cbMax, fMSF);
a9205f11b268f45a18a89049148ff266bcf687a3vboxsync break;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync default:
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync }
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync break;
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync }
bdec40b10acfe9f798021b508a0a7b8c786fc193vboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync default:
6155eed17648a45b8fb30c4df2a47cfb9ffc6a5cvboxsync //AssertMsgFailed(("Command %#x [%s] not implemented\n", pVScsiReq->pbCDB[0], SCSICmdText(pVScsiReq->pbCDB[0])));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE, 0x00);
5cece736b63cc917f3781c8c7e46fd3ea98c4e20vboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync if (enmTxDir != VSCSIIOREQTXDIR_INVALID)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync LogFlow(("%s: uLbaStart=%llu cSectorTransfer=%u\n",
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync __FUNCTION__, uLbaStart, cSectorTransfer));
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync if (RT_UNLIKELY(uLbaStart + cSectorTransfer > pVScsiLunMmc->cSectors))
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_LOGICAL_BLOCK_OOR, 0x00);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, false, VINF_SUCCESS);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
1e9e76e4273dcc2e3d560a0f3605c46f0013eb7bvboxsync else if (!cSectorTransfer)
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /* A 0 transfer length is not an error. */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, false, VINF_SUCCESS);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync else
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync {
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /* Enqueue new I/O request */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync rc = vscsiIoReqTransferEnqueue(pVScsiLun, pVScsiReq, enmTxDir,
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync uLbaStart * pVScsiLunMmc->cbSector,
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync cSectorTransfer * pVScsiLunMmc->cbSector);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync }
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync else /* Request completed */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiDeviceReqComplete(pVScsiLun->pVScsiDevice, pVScsiReq, rcReq, false, VINF_SUCCESS);
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync return rc;
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync}
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync
8683cfdc9273dd77e1c4e89886a7052de103591avboxsyncVSCSILUNDESC g_VScsiLunTypeMmc =
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync{
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /** enmLunType */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync VSCSILUNTYPE_MMC,
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /** pcszDescName */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync "MMC",
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /** cbLun */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync sizeof(VSCSILUNMMC),
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /** pfnVScsiLunInit */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiLunMmcInit,
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /** pfnVScsiLunDestroy */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiLunMmcDestroy,
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync /** pfnVScsiLunReqProcess */
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync vscsiLunMmcReqProcess
8683cfdc9273dd77e1c4e89886a7052de103591avboxsync};