VirtualBox

Changeset 43587 in vbox for trunk/src/VBox/Devices/Storage


Ignore:
Timestamp:
Oct 9, 2012 7:50:16 PM (12 years ago)
Author:
vboxsync
Message:

VSCSI-MMC: Added very basic READ TOC support. FreeBSD 6.4 insists on it.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp

    r40500 r43587  
    4545} VSCSILUNMMC, *PVSCSILUNMMC;
    4646
     47
     48DECLINLINE(void) mmcLBA2MSF(uint8_t *pbBuf, uint32_t iLBA)
     49{
     50    iLBA += 150;
     51    pbBuf[0] = (iLBA / 75) / 60;
     52    pbBuf[1] = (iLBA / 75) % 60;
     53    pbBuf[2] = iLBA % 75;
     54}
     55
     56DECLINLINE(uint32_t) mmcMSF2LBA(const uint8_t *pbBuf)
     57{
     58    return (pbBuf[0] * 60 + pbBuf[1]) * 75 + pbBuf[2];
     59}
     60
     61
     62/* Fabricate TOC information. */
     63static int mmcReadTOCNormal(PVSCSILUNINT pVScsiLun, PVSCSIREQINT pVScsiReq, uint16_t cbMaxTransfer, bool fMSF)
     64{
     65    PVSCSILUNMMC    pVScsiLunMmc = (PVSCSILUNMMC)pVScsiLun;
     66    uint8_t         aReply[32];
     67    uint8_t         *pbBuf = aReply;
     68    uint8_t         *q;
     69    uint8_t         iStartTrack;
     70    uint32_t        cbSize;
     71
     72    iStartTrack = pVScsiReq->pbCDB[6];
     73    if (iStartTrack > 1 && iStartTrack != 0xaa)
     74    {
     75        return vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
     76    }
     77    q = pbBuf + 2;
     78    *q++ = 1;   /* first session */
     79    *q++ = 1;   /* last session */
     80    if (iStartTrack <= 1)
     81    {
     82        *q++ = 0;       /* reserved */
     83        *q++ = 0x14;    /* ADR, CONTROL */
     84        *q++ = 1;       /* track number */
     85        *q++ = 0;       /* reserved */
     86        if (fMSF)
     87        {
     88            *q++ = 0;   /* reserved */
     89            mmcLBA2MSF(q, 0);
     90            q += 3;
     91        }
     92        else
     93        {
     94            /* sector 0 */
     95            vscsiH2BEU32(q, 0);
     96            q += 4;
     97        }
     98    }
     99    /* lead out track */
     100    *q++ = 0;       /* reserved */
     101    *q++ = 0x14;    /* ADR, CONTROL */
     102    *q++ = 0xaa;    /* track number */
     103    *q++ = 0;       /* reserved */
     104    if (fMSF)
     105    {
     106        *q++ = 0;   /* reserved */
     107        mmcLBA2MSF(q, pVScsiLunMmc->cSectors);
     108        q += 3;
     109    }
     110    else
     111    {
     112        vscsiH2BEU32(q, pVScsiLunMmc->cSectors);
     113        q += 4;
     114    }
     115    cbSize = q - pbBuf;
     116    Assert(cbSize <= sizeof(aReply));
     117    vscsiH2BEU16(pbBuf, cbSize - 2);
     118    if (cbSize < cbMaxTransfer)
     119        cbMaxTransfer = cbSize;
     120
     121    RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, aReply, cbMaxTransfer);
     122
     123    return vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
     124}
     125
    47126static int vscsiLunMmcInit(PVSCSILUNINT pVScsiLun)
    48127{
     
    271350            break;
    272351        }
     352        case SCSI_READ_TOC_PMA_ATIP:
     353        {
     354            uint8_t     format;
     355            uint16_t    cbMax;
     356            bool        fMSF;
     357
     358            format = pVScsiReq->pbCDB[2] & 0x0f;
     359            cbMax  = vscsiBE2HU16(&pVScsiReq->pbCDB[7]);
     360            fMSF   = (pVScsiReq->pbCDB[1] >> 1) & 1;
     361            switch (format)
     362            {
     363                case 0x00:
     364                    mmcReadTOCNormal(pVScsiLun, pVScsiReq, cbMax, fMSF);
     365                    break;
     366                default:
     367                    rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
     368            }
     369            break;
     370        }
    273371
    274372        default:
    275             //AssertMsgFailed(("Command %#x [%s] not implemented\n", pRequest->pbCDB[0], SCSICmdText(pRequest->pbCDB[0])));
     373            //AssertMsgFailed(("Command %#x [%s] not implemented\n", pVScsiReq->pbCDB[0], SCSICmdText(pVScsiReq->pbCDB[0])));
    276374            rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST, SCSI_ASC_ILLEGAL_OPCODE, 0x00);
    277375    }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette