VirtualBox

Changeset 32088 in vbox for trunk/src


Ignore:
Timestamp:
Aug 30, 2010 12:26:18 PM (14 years ago)
Author:
vboxsync
Message:

ATA/Passthrough: Fix audio CDs. Try to retrieve the track type during a READ TOC/PMA/ATIP command and set the correct sector size for a READ CD command

Location:
trunk/src/VBox/Devices
Files:
2 edited

Legend:

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

    r32082 r32088  
    9898#define ATA_EVENT_STATUS_MEDIA_CHANGED          3    /**< medium was removed + new medium was inserted */
    9999#define ATA_EVENT_STATUS_MEDIA_EJECT_REQUESTED  4    /**< medium eject requested (eject button pressed) */
     100
     101/* Media track type */
     102#define ATA_MEDIA_TYPE_UNKNOWN                  0    /**< unknown CD type */
     103#define ATA_MEDIA_TYPE_DATA                     1    /**< Data CD */
     104#define ATA_MEDIA_TYPE_CDDA                     2    /**< CD-DA  (audio) CD type */
    100105
    101106/**
     
    207212    volatile uint32_t MediaEventStatus;
    208213
    209     uint32_t Alignment0;
     214    /** Media type if known. */
     215    volatile uint32_t MediaTrackType;
    210216
    211217    /** The status LED state for this drive. */
     
    18781884}
    18791885
     1886/**
     1887 * Sets the given media track type.
     1888 */
     1889static uint32_t ataMediumTypeSet(ATADevState *s, uint32_t MediaTrackType)
     1890{
     1891    return ASMAtomicXchgU32(&s->MediaTrackType, MediaTrackType);
     1892}
    18801893
    18811894static bool atapiPassthroughSS(ATADevState *s)
     
    20342047                ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 16, "CD-ROM", 16);
    20352048                ataSCSIPadStr(s->CTX_SUFF(pbIOBuffer) + 32, "1.0", 4);
     2049            }
     2050            else if (s->aATAPICmd[0] == SCSI_READ_TOC_PMA_ATIP)
     2051            {
     2052                /* Set the media type if we can detect it. */
     2053                uint8_t *pbBuf = s->CTX_SUFF(pbIOBuffer);
     2054
     2055                /** @todo: Implemented only for formatted TOC now. */
     2056                if (   (s->aATAPICmd[1] & 0xf) == 0
     2057                    && cbTransfer >= 6)
     2058                {
     2059                    uint32_t NewMediaType;
     2060                    uint32_t OldMediaType;
     2061
     2062                    if (pbBuf[5] & 0x4)
     2063                        NewMediaType = ATA_MEDIA_TYPE_DATA;
     2064                    else
     2065                        NewMediaType = ATA_MEDIA_TYPE_CDDA;
     2066
     2067                    OldMediaType = ataMediumTypeSet(s, NewMediaType);
     2068
     2069                    if (OldMediaType != NewMediaType)
     2070                        LogRel(("PIIX3 ATA: LUN#%d: CD-ROM passthrough, detected %s CD\n",
     2071                                s->iLUN,
     2072                                NewMediaType == ATA_MEDIA_TYPE_DATA
     2073                                ? "data"
     2074                                : "audio"));
     2075                }
     2076                else /* Play safe and set to unknown. */
     2077                    ataMediumTypeSet(s, ATA_MEDIA_TYPE_UNKNOWN);
    20362078            }
    20372079            if (cbTransfer)
     
    31893231            goto sendcmd;
    31903232        case SCSI_READ_CD:
    3191             s->cbATAPISector = 2048; /**< @todo this size is not always correct */
     3233        {
     3234            /* Get sector size based on the expected sector type field. */
     3235            switch ((pbPacket[1] >> 2) & 0x7)
     3236            {
     3237                case 0x0: /* All types. */
     3238                    if (ASMAtomicReadU32(&s->MediaTrackType) == ATA_MEDIA_TYPE_CDDA)
     3239                        s->cbATAPISector = 2352;
     3240                    else
     3241                        s->cbATAPISector = 2048; /* Might be incorrect if we couldn't determine the type. */
     3242                    break;
     3243                case 0x1: /* CD-DA */
     3244                    s->cbATAPISector = 2352;
     3245                    break;
     3246                case 0x2: /* Mode 1 */
     3247                    s->cbATAPISector = 2048;
     3248                    break;
     3249                case 0x3: /* Mode 2 formless */
     3250                    s->cbATAPISector = 2336;
     3251                    break;
     3252                case 0x4: /* Mode 2 form 1 */
     3253                    s->cbATAPISector = 2048;
     3254                    break;
     3255                case 0x5: /* Mode 2 form 2 */
     3256                    s->cbATAPISector = 2324;
     3257                    break;
     3258                default: /* Reserved */
     3259                    AssertMsgFailed(("Unknown sector type\n"));
     3260                    s->cbATAPISector = 0; /** @todo we should probably fail the command here already. */
     3261            }
     3262
    31923263            cbTransfer = ataBE2H_U24(pbPacket + 6) * s->cbATAPISector;
    31933264            uTxDir = PDMBLOCKTXDIR_FROM_DEVICE;
    31943265            goto sendcmd;
     3266        }
    31953267        case SCSI_READ_CD_MSF:
    31963268            cSectors = ataMSF2LBA(pbPacket + 6) - ataMSF2LBA(pbPacket + 3);
     
    34353507}
    34363508
    3437 
    34383509/**
    34393510 * Called when a media is mounted.
     
    34613532        pIf->cNotifiedMediaChange = 2;
    34623533    ataMediumInserted(pIf);
     3534    ataMediumTypeSet(pIf, ATA_MEDIA_TYPE_UNKNOWN);
    34633535}
    34643536
     
    34813553    pIf->cNotifiedMediaChange = 4;
    34823554    ataMediumRemoved(pIf);
     3555    ataMediumTypeSet(pIf, ATA_MEDIA_TYPE_UNKNOWN);
    34833556}
    34843557
     
    34973570    s->cNotifiedMediaChange = 0;
    34983571    ASMAtomicWriteU32(&s->MediaEventStatus, ATA_EVENT_STATUS_UNCHANGED);
     3572    ASMAtomicWriteU32(&s->MediaTrackType, ATA_MEDIA_TYPE_UNKNOWN);
    34993573    ataUnsetIRQ(s);
    35003574
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r32069 r32088  
    713713    GEN_CHECK_OFF(ATADevState, cNotifiedMediaChange);
    714714    GEN_CHECK_OFF(ATADevState, MediaEventStatus);
     715    GEN_CHECK_OFF(ATADevState, MediaTrackType);
    715716    GEN_CHECK_OFF(ATADevState, Led);
    716717    GEN_CHECK_OFF(ATADevState, cbIOBuffer);
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