VirtualBox

Ignore:
Timestamp:
Mar 13, 2017 4:20:30 PM (8 years ago)
Author:
vboxsync
Message:

Devices/Storage/VSCSI: Implement READ CD command for MMC driver

File:
1 edited

Legend:

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

    r66058 r66063  
    829829    int             rcReq = SCSI_STATUS_OK;
    830830    unsigned        uCmd = pVScsiReq->pbCDB[0];
     831    PCRTSGSEG       paSegs = pVScsiReq->SgBuf.paSegs;
     832    unsigned        cSegs  = pVScsiReq->SgBuf.cSegs;
    831833
    832834    LogFlowFunc(("pVScsiLun=%#p{.fReady=%RTbool, .fMediaPresent=%RTbool} pVScsiReq=%#p{.pbCdb[0]=%#x}\n",
     
    997999                uLbaStart       = scsiBE2H_U64(&pVScsiReq->pbCDB[2]);
    9981000                cSectorTransfer = scsiBE2H_U32(&pVScsiReq->pbCDB[10]);
     1001                break;
     1002            }
     1003            case SCSI_READ_CD:
     1004            {
     1005                uLbaStart       = scsiBE2H_U32(&pVScsiReq->pbCDB[2]);
     1006                cSectorTransfer = (pVScsiReq->pbCDB[6] << 16) | (pVScsiReq->pbCDB[7] << 8) | pVScsiReq->pbCDB[8];
     1007                switch (pVScsiReq->pbCDB[9] & 0xf8)
     1008                {
     1009                    case 0x00:
     1010                        /* nothing */
     1011                        rcReq = vscsiLunReqSenseOkSet(pVScsiLun, pVScsiReq);
     1012                        break;
     1013                    case 0x10:
     1014                        /* normal read */
     1015                        enmTxDir = VSCSIIOREQTXDIR_READ;
     1016                        break;
     1017                    case 0xf8:
     1018                    {
     1019                        /*
     1020                         * Read all data, sector size is 2352.
     1021                         * Rearrange the buffer and fill the gaps with the sync bytes.
     1022                         */
     1023                        /* Count the number of segments for the buffer we require. */
     1024                        RTSGBUF SgBuf;
     1025                        bool fBufTooSmall = false;
     1026                        uint32_t cSegsNew = 0;
     1027                        RTSgBufClone(&SgBuf, &pVScsiReq->SgBuf);
     1028                        for (uint32_t uLba = (uint32_t)uLbaStart; uLba < uLbaStart + cSectorTransfer; uLba++)
     1029                        {
     1030                            size_t cbTmp = RTSgBufAdvance(&SgBuf, 16);
     1031                            if (cbTmp < 16)
     1032                            {
     1033                                fBufTooSmall = true;
     1034                                break;
     1035                            }
     1036
     1037                            cbTmp = 2048;
     1038                            while (cbTmp)
     1039                            {
     1040                                size_t cbBuf = cbTmp;
     1041                                RTSgBufGetNextSegment(&SgBuf, &cbBuf);
     1042                                if (!cbBuf)
     1043                                {
     1044                                    fBufTooSmall = true;
     1045                                    break;
     1046                                }
     1047
     1048                                cbTmp -= cbBuf;
     1049                                cSegsNew++;
     1050                            }
     1051
     1052                            cbTmp = RTSgBufAdvance(&SgBuf, 280);
     1053                            if (cbTmp < 280)
     1054                            {
     1055                                fBufTooSmall = true;
     1056                                break;
     1057                            }
     1058                        }
     1059
     1060                        if (!fBufTooSmall)
     1061                        {
     1062                            PRTSGSEG paSegsNew = (PRTSGSEG)RTMemAllocZ(cSegsNew * sizeof(RTSGSEG));
     1063                            if (paSegsNew)
     1064                            {
     1065                                enmTxDir = VSCSIIOREQTXDIR_READ;
     1066
     1067                                uint32_t idxSeg = 0;
     1068                                for (uint32_t uLba = (uint32_t)uLbaStart; uLba < uLbaStart + cSectorTransfer; uLba++)
     1069                                {
     1070                                    /* Sync bytes, see 4.2.3.8 CD Main Channel Block Formats */
     1071                                    uint8_t abBuf[16];
     1072                                    abBuf[0] = 0x00;
     1073                                    memset(&abBuf[1], 0xff, 10);
     1074                                    abBuf[11] = 0x00;
     1075                                    /* MSF */
     1076                                    scsiLBA2MSF(&abBuf[12], uLba);
     1077                                    abBuf[15] = 0x01; /* mode 1 data */
     1078                                    RTSgBufCopyFromBuf(&pVScsiReq->SgBuf, &abBuf[0], sizeof(abBuf));
     1079
     1080                                    size_t cbTmp = 2048;
     1081                                    while (cbTmp)
     1082                                    {
     1083                                        size_t cbBuf = cbTmp;
     1084                                        paSegsNew[idxSeg].pvSeg = RTSgBufGetNextSegment(&pVScsiReq->SgBuf, &cbBuf);
     1085                                        paSegsNew[idxSeg].cbSeg = cbBuf;
     1086                                        idxSeg++;
     1087
     1088                                        cbTmp -= cbBuf;
     1089                                    }
     1090
     1091                                    /**
     1092                                     * @todo: maybe compute ECC and parity, layout is:
     1093                                     * 2072 4   EDC
     1094                                     * 2076 172 P parity symbols
     1095                                     * 2248 104 Q parity symbols
     1096                                     */
     1097                                    RTSgBufSet(&pVScsiReq->SgBuf, 0, 280);
     1098                                }
     1099
     1100                                paSegs = paSegsNew;
     1101                                cSegs  = cSegsNew;
     1102                            }
     1103                            else
     1104                                rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
     1105                                                                 SCSI_ASC_LOGICAL_BLOCK_OOR, 0x00);
     1106                        }
     1107                        else
     1108                            rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
     1109                                                             SCSI_ASC_LOGICAL_BLOCK_OOR, 0x00);
     1110                        break;
     1111                    }
     1112                    default:
     1113                        rcReq = vscsiLunReqSenseErrorSet(pVScsiLun, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
     1114                                                         SCSI_ASC_INV_FIELD_IN_CMD_PACKET, 0x00);
     1115                        break;
     1116                }
    9991117                break;
    10001118            }
     
    12641382        {
    12651383            /* Enqueue new I/O request */
    1266             rc = vscsiIoReqTransferEnqueue(pVScsiLun, pVScsiReq, enmTxDir,
    1267                                            uLbaStart * pVScsiLunMmc->cbSector,
    1268                                            cSectorTransfer * pVScsiLunMmc->cbSector);
     1384            rc = vscsiIoReqTransferEnqueueEx(pVScsiLun, pVScsiReq, enmTxDir,
     1385                                             uLbaStart * pVScsiLunMmc->cbSector,
     1386                                             paSegs, cSegs, cSectorTransfer * pVScsiLunMmc->cbSector);
    12691387        }
    12701388    }
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