VirtualBox

Changeset 38710 in vbox for trunk/src/VBox/Devices


Ignore:
Timestamp:
Sep 11, 2011 7:46:38 PM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
73954
Message:

DevATA: Simplified non-present device port read handling.

File:
1 edited

Legend:

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

    r38664 r38710  
    40044004#endif /* IN_RING3 */
    40054005
     4006/*
     4007 * Note: There are four distinct cases of port I/O handling depending on
     4008 * which devices (if any) are attached to an IDE channel:
     4009 *
     4010 *  1) No device attached. No response to writes or reads (i.e. reads return
     4011 *     all bits set).
     4012 *
     4013 *  2) Both devices attached. Reads and writes are processed normally.
     4014 *
     4015 *  3) Device 0 only. If device 0 is selected, normal behavior applies. But
     4016 *     if Device 1 is selected, writes are still directed to Device 0 (except
     4017 *     commands are not executed), reads from control/command registers are
     4018 *     directed to Device 0, but status/alt status reads return 0. If Device 1
     4019 *     is a PACKET device, all reads return 0. See ATAPI-6 clause 9.16.1 and
     4020 *     Table 18 in clause 7.1.
     4021 *
     4022 *  4) Device 1 only - non-standard(!). Device 1 can't tell if Device 0 is
     4023 *     present or not and behaves the same. That means if Device 0 is selected,
     4024 *     Device 1 responds to writes (except commands are not executed) but does
     4025 *     not respond to reads. If Device 1 selected, normal behavior applies.
     4026 *     See ATAPI-6 clause 9.16.2 and Table 15 in clause 7.1.
     4027 */
     4028
    40064029static int ataIOPortWriteU8(PATACONTROLLER pCtl, uint32_t addr, uint32_t val)
    40074030{
    4008     Log2(("%s: write addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
     4031    Log2(("%s: LUN#%d write addr=%#x val=%#04x\n", __FUNCTION__, pCtl->aIfs[pCtl->iSelectedIf].iLUN, addr, val));
    40094032    addr &= 7;
    40104033    switch (addr)
     
    40954118        default:
    40964119        case 7: /* command */
    4097             /* ignore commands to non existant slave */
     4120            /* ignore commands to non-existent device */
    40984121            if (pCtl->iSelectedIf && !pCtl->aIfs[pCtl->iSelectedIf].pDrvBlock)
    40994122                break;
     
    41124135{
    41134136    ATADevState *s = &pCtl->aIfs[pCtl->iSelectedIf];
    4114     uint32_t val;
    4115     bool fHOB;
    4116 
     4137    uint32_t    val;
     4138    bool        fHOB;
     4139
     4140    /* Check if the guest is reading from a non-existent device. */
     4141    if (!s->pDrvBlock)
     4142    {
     4143        if (pCtl->iSelectedIf)  /* Device 1 selected, Device 0 responding for it. */
     4144        {
     4145            if (!pCtl->aIfs[0].pDrvBlock)   /* @todo: this case should never get here! */
     4146            {
     4147                Log2(("%s: addr=%#x: no device on channel\n", __FUNCTION__, addr));
     4148                return VERR_IOM_IOPORT_UNUSED;
     4149            }
     4150            if (((addr & 7) != 1) && pCtl->aIfs[0].fATAPI) {
     4151                Log2(("%s: addr=%#x, val=0: LUN#%d not attached/LUN#%d ATAPI\n", __FUNCTION__, addr,
     4152                                s->iLUN, pCtl->aIfs[0].iLUN));
     4153                *pu32 = 0;
     4154                return VINF_SUCCESS;
     4155            }
     4156            /* Else handle normally. */
     4157        }
     4158        else                    /* Device 0 selected (but not present). */
     4159        {
     4160            Log2(("%s: addr=%#x: LUN#%d not attached\n", __FUNCTION__, addr, s->iLUN));
     4161            return VERR_IOM_IOPORT_UNUSED;
     4162        }
     4163    }
    41174164    fHOB = !!(s->uATARegDevCtl & (1 << 7));
    41184165    switch (addr & 7)
     
    41334180            break;
    41344181        case 2: /* sector count */
    4135             if (!s->pDrvBlock)
    4136                 val = 0;
    4137             else if (fHOB)
     4182            if (fHOB)
    41384183                val = s->uATARegNSectorHOB;
    41394184            else
     
    41414186            break;
    41424187        case 3: /* sector number */
    4143             if (!s->pDrvBlock)
    4144                 val = 0;
    4145             else if (fHOB)
     4188            if (fHOB)
    41464189                val = s->uATARegSectorHOB;
    41474190            else
     
    41494192            break;
    41504193        case 4: /* cylinder low */
    4151             if (!s->pDrvBlock)
    4152                 val = 0;
    4153             else if (fHOB)
     4194            if (fHOB)
    41544195                val = s->uATARegLCylHOB;
    41554196            else
     
    41574198            break;
    41584199        case 5: /* cylinder high */
    4159             if (!s->pDrvBlock)
    4160                 val = 0;
    4161             else if (fHOB)
     4200            if (fHOB)
    41624201                val = s->uATARegHCylHOB;
    41634202            else
     
    42514290        }
    42524291    }
    4253     Log2(("%s: addr=%#x val=%#04x\n", __FUNCTION__, addr, val));
     4292    Log2(("%s: LUN#%d addr=%#x val=%#04x\n", __FUNCTION__, s->iLUN, addr, val));
    42544293    *pu32 = val;
    42554294    return VINF_SUCCESS;
Note: See TracChangeset for help on using the changeset viewer.

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