VirtualBox

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


Ignore:
Timestamp:
Feb 21, 2011 11:26:58 AM (14 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
70138
Message:

BusLogic: Fix a few emulation bugs and add more debugging code

File:
1 edited

Legend:

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

    r35768 r36030  
    1616 */
    1717
    18 /* Implemented looking at the driver source in the linux kernel (drivers/scsi/BusLogic.[ch]). 
     18/* Implemented looking at the driver source in the linux kernel (drivers/scsi/BusLogic.[ch]).
    1919 * See also: http://www.drdobbs.com/184410111
    2020 */
     
    406406    R3PTRTYPE(volatile PBUSLOGICTASKSTATE) pTasksRedoHead;
    407407
     408#ifdef LOG_ENABLED
     409# if HC_ARCH_BITS == 64
     410    uint32_t                        Alignment4;
     411# endif
     412
     413    volatile uint32_t               cInMailboxesReady;
     414#endif
     415
    408416} BUSLOGIC, *PBUSLOGIC;
    409417
     
    817825
    818826#if defined(IN_RING3)
     827
     828/**
     829 * Advances the mailbox pointer to the next slot.
     830 */
     831DECLINLINE(void) buslogicOutgoingMailboxAdvance(PBUSLOGIC pBusLogic)
     832{
     833    pBusLogic->uMailboxOutgoingPositionCurrent = (pBusLogic->uMailboxOutgoingPositionCurrent + 1) % pBusLogic->cMailbox;
     834}
     835
     836/**
     837 * Returns the physical address of the next outgoing mailbox to process.
     838 */
     839DECLINLINE(RTGCPHYS) buslogicOutgoingMailboxGetGCPhys(PBUSLOGIC pBusLogic)
     840{
     841    return pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->uMailboxOutgoingPositionCurrent * sizeof(Mailbox));
     842}
     843
    819844/**
    820845 * Initialize local RAM of host adapter with default values.
     
    944969    RTGCPHYS GCPhysAddrCCB = (RTGCPHYS)pTaskState->MailboxGuest.u32PhysAddrCCB;
    945970
     971    LogFlowFunc(("Completing CCB %RGp\n", GCPhysAddrCCB));
     972
    946973    /* Update CCB. */
    947974    pTaskState->CommandControlBlockGuest.uHostAdapterStatus = uHostAdapterStatus;
     
    949976    PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrCCB, &pTaskState->CommandControlBlockGuest, sizeof(CommandControlBlock));
    950977
     978#ifdef RT_STRICT
     979    Mailbox Tmp;
     980    PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxIncoming, &Tmp, sizeof(Mailbox));
     981    Assert(Tmp.u.in.uCompletionCode == BUSLOGIC_MAILBOX_INCOMING_COMPLETION_FREE);
     982#endif
     983
    951984    /* Update mailbox. */
    952985    PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxIncoming, &pTaskState->MailboxGuest, sizeof(Mailbox));
     
    956989    if (pBusLogic->uMailboxIncomingPositionCurrent >= pBusLogic->cMailbox)
    957990        pBusLogic->uMailboxIncomingPositionCurrent = 0;
     991
     992#ifdef LOG_ENABLED
     993    ASMAtomicIncU32(&pBusLogic->cInMailboxesReady);
     994#endif
    958995
    959996    pBusLogic->regInterrupt |= BUSLOGIC_REGISTER_INTERRUPT_INCOMING_MAILBOX_LOADED;
     
    16111648            if (rc != VINF_SUCCESS)
    16121649                return rc;
     1650
     1651#ifdef LOG_ENABLED
     1652            uint32_t cMailboxesReady = ASMAtomicXchgU32(&pBusLogic->cInMailboxesReady, 0);
     1653            Log(("%u incoming mailboxes are ready when this interrupt was cleared\n", cMailboxesReady));
     1654#endif
    16131655
    16141656            if (uVal & BUSLOGIC_REGISTER_CONTROL_INTERRUPT_RESET)
     
    22792321    if (!pBusLogic->fStrictRoundRobinMode)
    22802322    {
    2281         /* Search for a filled mailbox. */
     2323        /* Search for a filled mailbox - stop if we have scanned all mailboxes. */
     2324        uint8_t uMailboxPosCur = pBusLogic->uMailboxOutgoingPositionCurrent;
     2325
    22822326        do
    22832327        {
    22842328            /* Fetch mailbox from guest memory. */
    2285             GCPhysAddrMailboxCurrent = pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->uMailboxOutgoingPositionCurrent * sizeof(Mailbox));
     2329            GCPhysAddrMailboxCurrent = buslogicOutgoingMailboxGetGCPhys(pBusLogic);
    22862330
    22872331            PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent,
    22882332                              &pTaskState->MailboxGuest, sizeof(Mailbox));
    22892333
    2290             pBusLogic->uMailboxOutgoingPositionCurrent++;
    2291 
    2292             /* Check if we reached the end and start from the beginning if so. */
    2293             if (pBusLogic->uMailboxOutgoingPositionCurrent >= pBusLogic->cMailbox)
    2294                 pBusLogic->uMailboxOutgoingPositionCurrent = 0;
    2295         } while (pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE);
     2334            /* Check the next mailbox. */
     2335            buslogicOutgoingMailboxAdvance(pBusLogic);
     2336        } while (   pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE
     2337                 && uMailboxPosCur != pBusLogic->uMailboxOutgoingPositionCurrent);
    22962338    }
    22972339    else
    22982340    {
    22992341        /* Fetch mailbox from guest memory. */
    2300         GCPhysAddrMailboxCurrent = pBusLogic->GCPhysAddrMailboxOutgoingBase + (pBusLogic->uMailboxOutgoingPositionCurrent * sizeof(Mailbox));
     2342        GCPhysAddrMailboxCurrent = buslogicOutgoingMailboxGetGCPhys(pBusLogic);
    23012343
    23022344        PDMDevHlpPhysRead(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent,
     
    23042346    }
    23052347
     2348    /*
     2349     * Check if the mailbox is actually loaded.
     2350     * It might be possible that the guest notified us without
     2351     * a loaded mailbox. Do nothing in that case but leave a
     2352     * log entry.
     2353     */
     2354    if (pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE)
     2355    {
     2356        Log(("No loaded mailbox left\n"));
     2357        RTMemCacheFree(pBusLogic->hTaskCache, pTaskState);
     2358        return VERR_NO_DATA;
     2359    }
     2360
     2361    LogFlow(("Got loaded mailbox at slot %u, CCB phys %RGp\n", pBusLogic->uMailboxOutgoingPositionCurrent, pTaskState->MailboxGuest.u32PhysAddrCCB));
    23062362#ifdef DEBUG
    23072363    buslogicDumpMailboxInfo(&pTaskState->MailboxGuest, true);
    23082364#endif
    23092365
     2366    /* We got the mailbox, mark it as free in the guest. */
     2367    uint8_t uActionCode = BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE;
     2368    PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent + RT_OFFSETOF(Mailbox, u.out.uActionCode), &uActionCode, sizeof(uActionCode));
     2369
    23102370    if (pTaskState->MailboxGuest.u.out.uActionCode == BUSLOGIC_MAILBOX_OUTGOING_ACTION_START_COMMAND)
    23112371        rc = buslogicDeviceSCSIRequestSetup(pBusLogic, pTaskState);
     
    23192379    AssertRC(rc);
    23202380
    2321     /* We got the mailbox, mark it as free in the guest. */
    2322     pTaskState->MailboxGuest.u.out.uActionCode = BUSLOGIC_MAILBOX_OUTGOING_ACTION_FREE;
    2323     PDMDevHlpPhysWrite(pBusLogic->CTX_SUFF(pDevIns), GCPhysAddrMailboxCurrent, &pTaskState->MailboxGuest, sizeof(Mailbox));
    2324 
     2381    /* Advance to the next mailbox. */
    23252382    if (pBusLogic->fStrictRoundRobinMode)
    2326     {
    2327         pBusLogic->uMailboxOutgoingPositionCurrent++;
    2328 
    2329         /* Check if we reached the end and start from the beginning if so. */
    2330         if (pBusLogic->uMailboxOutgoingPositionCurrent >= pBusLogic->cMailbox)
    2331             pBusLogic->uMailboxOutgoingPositionCurrent = 0;
    2332     }
     2383        buslogicOutgoingMailboxAdvance(pBusLogic);
    23332384
    23342385    return rc;
     
    23472398{
    23482399    PBUSLOGIC  pBusLogic = PDMINS_2_DATA(pDevIns, PBUSLOGIC);
    2349     uint32_t cMailboxesReady = 0;
    23502400
    23512401    /* Reset notification send flag now. */
    23522402    Assert(pBusLogic->fNotificationSend);
    23532403    ASMAtomicXchgBool(&pBusLogic->fNotificationSend, false);
    2354 
    2355     /*
    2356      * It is possible that there is a notification send but that there is no mailbox ready
    2357      * in the SMP case. Just do nothing.
    2358      */
    2359     cMailboxesReady = ASMAtomicXchgU32(&pBusLogic->cMailboxesReady, 0);
    2360     if (!cMailboxesReady)
    2361         return true;
     2404    ASMAtomicXchgU32(&pBusLogic->cMailboxesReady, 0); /* @todo: Actually not required anymore but to stay compatible with older saved states. */
    23622405
    23632406    /* Process mailboxes. */
     2407    int rc;
    23642408    do
    23652409    {
    2366         int rc;
    2367 
    23682410        rc = buslogicProcessMailboxNext(pBusLogic);
    2369         AssertMsgRC(rc, ("Processing mailbox failed rc=%Rrc\n", rc));
    2370     } while (--cMailboxesReady > 0);
     2411        AssertMsg(RT_SUCCESS(rc) || rc == VERR_NO_DATA, ("Processing mailbox failed rc=%Rrc\n", rc));
     2412    } while (RT_SUCCESS(rc));
    23712413
    23722414    return true;
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