VirtualBox

Changeset 77010 in vbox


Ignore:
Timestamp:
Jan 27, 2019 9:45:05 AM (6 years ago)
Author:
vboxsync
Message:

DevATA: Clear interrupt when command register is written (ATA requirement). Also rely on the internal interrupt pending state more, to avoid unnecessary PDM calls (see bugref:5869).

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

Legend:

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

    r76553 r77010  
    10561056# endif /* IN_RING3 */
    10571057
     1058/**
     1059 * Set the internal interrupt pending status, update INTREQ as appropriate.
     1060 *
     1061 * @param   s           Pointer to the ATA device state data.
     1062 */
    10581063static void ataHCSetIRQ(ATADevState *s)
    10591064{
     
    10611066    PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
    10621067
    1063     if (!(s->uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ))
    1064     {
    1065         Log2(("%s: LUN#%d asserting IRQ\n", __FUNCTION__, s->iLUN));
    1066         /* The BMDMA unit unconditionally sets BM_STATUS_INT if the interrupt
    1067          * line is asserted. It monitors the line for a rising edge. */
    1068         if (!s->fIrqPending)
     1068    if (!s->fIrqPending) {
     1069        if (!(s->uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ))
     1070        {
     1071            Log2(("%s: LUN#%d asserting IRQ\n", __FUNCTION__, s->iLUN));
     1072            /* The BMDMA unit unconditionally sets BM_STATUS_INT if the interrupt
     1073             * line is asserted. It monitors the line for a rising edge. */
    10691074            pCtl->BmDma.u8Status |= BM_STATUS_INT;
    1070         /* Only actually set the IRQ line if updating the currently selected drive. */
    1071         if (s == &pCtl->aIfs[pCtl->iSelectedIf])
    1072         {
    1073             /** @todo experiment with adaptive IRQ delivery: for reads it is
    1074              * better to wait for IRQ delivery, as it reduces latency. */
    1075             if (pCtl->irq == 16)
    1076                 PDMDevHlpPCISetIrq(pDevIns, 0, 1);
    1077             else
    1078                 PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 1);
    1079         }
    1080     }
    1081     s->fIrqPending = true;
     1075            /* Only actually set the IRQ line if updating the currently selected drive. */
     1076            if (s == &pCtl->aIfs[pCtl->iSelectedIf])
     1077            {
     1078                /** @todo experiment with adaptive IRQ delivery: for reads it is
     1079                 * better to wait for IRQ delivery, as it reduces latency. */
     1080                if (pCtl->irq == 16)
     1081                    PDMDevHlpPCISetIrq(pDevIns, 0, 1);
     1082                else
     1083                    PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 1);
     1084            }
     1085        }
     1086        s->fIrqPending = true;
     1087    }
    10821088}
    10831089
    10841090#endif /* IN_RING0 || IN_RING3 */
    10851091
     1092/**
     1093 * Clear the internal interrupt pending status, update INTREQ as appropriate.
     1094 *
     1095 * @param   s           Pointer to the ATA device state data.
     1096 */
    10861097static void ataUnsetIRQ(ATADevState *s)
    10871098{
     
    10891100    PPDMDEVINS pDevIns = ATADEVSTATE_2_DEVINS(s);
    10901101
    1091     if (!(s->uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ))
    1092     {
    1093         Log2(("%s: LUN#%d deasserting IRQ\n", __FUNCTION__, s->iLUN));
    1094         /* Only actually unset the IRQ line if updating the currently selected drive. */
    1095         if (s == &pCtl->aIfs[pCtl->iSelectedIf])
    1096         {
    1097             if (pCtl->irq == 16)
    1098                 PDMDevHlpPCISetIrq(pDevIns, 0, 0);
    1099             else
    1100                 PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 0);
    1101         }
    1102     }
    1103     s->fIrqPending = false;
     1102    if (s->fIrqPending) {
     1103        if (!(s->uATARegDevCtl & ATA_DEVCTL_DISABLE_IRQ))
     1104        {
     1105            Log2(("%s: LUN#%d deasserting IRQ\n", __FUNCTION__, s->iLUN));
     1106            /* Only actually unset the IRQ line if updating the currently selected drive. */
     1107            if (s == &pCtl->aIfs[pCtl->iSelectedIf])
     1108            {
     1109                if (pCtl->irq == 16)
     1110                    PDMDevHlpPCISetIrq(pDevIns, 0, 0);
     1111                else
     1112                    PDMDevHlpISASetIrq(pDevIns, pCtl->irq, 0);
     1113            }
     1114        }
     1115        s->fIrqPending = false;
     1116    }
    11041117}
    11051118
     
    44124425            return VINF_IOM_R3_IOPORT_WRITE;
    44134426#else /* IN_RING3 */
     4427            ataUnsetIRQ(&pCtl->aIfs[pCtl->iSelectedIf]);
    44144428            ataR3ParseCmd(&pCtl->aIfs[pCtl->iSelectedIf], val);
    44154429#endif /* !IN_RING3 */
  • trunk/src/VBox/Devices/Storage/VSCSI/VSCSILunMmc.cpp

    r76553 r77010  
    6060/** Unknown media type. */
    6161#define MMC_MEDIA_TYPE_UNKNOWN          0
     62/** Medium is a DVD. */
     63#define MMC_MEDIA_TYPE_DVD              2
    6264/** Door closed, no media. */
    6365#define MMC_MEDIA_TYPE_NO_DISC       0x70
     
    586588        case 0x30:
    587589        case 0x31:
     590            /* For a CD, these must fail. */
     591#if 0
     592            if (pVScsiLunMmc->u32MediaTrackType != MMC_MEDIA_TYPE_DVD)
     593                return vscsiLunReqSenseErrorSet(&pVScsiLunMmc->Core, pVScsiReq, SCSI_SENSE_ILLEGAL_REQUEST,
     594                                                SCSI_ASC_CANNOT_READ_MEDIUM, SCSI_ASCQ_INCOMPATIBLE_FORMAT);
     595#endif
     596            RT_FALL_THRU();
    588597        case 0xff:
    589598            if (pVScsiReq->pbCDB[1] == 0)
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