VirtualBox

Changeset 45789 in vbox


Ignore:
Timestamp:
Apr 28, 2013 9:26:56 AM (12 years ago)
Author:
vboxsync
Message:

Storage/LsiLogic: Make NetWare work with the emulation

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

Legend:

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

    r45025 r45789  
    4545*******************************************************************************/
    4646/** The current saved state version. */
    47 #define LSILOGIC_SAVED_STATE_VERSION          3
     47#define LSILOGIC_SAVED_STATE_VERSION                4
     48/** The saved state version used by VirtualBox before the doorbell status flag
     49 * was changed from bool to a 32bit enum. */
     50#define LSILOGIC_SAVED_STATE_VERSION_BOOL_DOORBELL  3
    4851/** The saved state version used by VirtualBox before SAS support was added. */
    49 #define LSILOGIC_SAVED_STATE_VERSION_PRE_SAS  2
     52#define LSILOGIC_SAVED_STATE_VERSION_PRE_SAS        2
    5053/** The saved state version used by VirtualBox 3.0 and earlier.  It does not
    5154 * include the device config part. */
    52 #define LSILOGIC_SAVED_STATE_VERSION_VBOX_30  1
     55#define LSILOGIC_SAVED_STATE_VERSION_VBOX_30        1
    5356
    5457/** Maximum number of entries in the release log. */
     
    6164*   Structures and Typedefs                                                    *
    6265*******************************************************************************/
     66
    6367/**
    6468 * Reply data.
     
    143147    LSILOGICWHOINIT      enmWhoInit;
    144148    /** Flag whether we are in doorbell function. */
    145     bool                 fDoorbellInProgress;
     149    LSILOGICDOORBELLSTATE enmDoorbellState;
    146150    /** Flag whether diagnostic access is enabled. */
    147151    bool                 fDiagnosticEnabled;
    148 
    149152    /** Flag whether a notification was send to R3. */
    150153    bool                 fNotificationSend;
    151 
    152154    /** Flag whether the guest enabled event notification from the IOC. */
    153155    bool                 fEventNotificationEnabled;
    154 
    155 #if HC_ARCH_BITS == 64
    156     uint32_t             Alignment0;
    157 #endif
    158156
    159157    /** Queue to send tasks to R3. - R3 ptr */
     
    499497{
    500498    pThis->enmState = LSILOGICSTATE_RESET;
     499    pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE;
    501500
    502501    /* The interrupts are masked out. */
     
    584583    LogFlowFunc(("pThis=%#p u32MessageContext=%#x\n", pThis, u32MessageContext));
    585584
    586     AssertMsg(!pThis->fDoorbellInProgress, ("We are in a doorbell function\n"));
     585    AssertMsg(pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_NOT_IN_USE, ("We are in a doorbell function\n"));
    587586
    588587    /* Write message context ID into reply post queue. */
     
    663662     * we are ready to send the reply.
    664663     */
    665     if (pThis->fDoorbellInProgress && !fForceReplyFifo)
     664    if (pThis->enmDoorbellState != LSILOGICDOORBELLSTATE_NOT_IN_USE && !fForceReplyFifo)
    666665    {
    667666        /* Set size of the reply in 16bit words. The size in the reply is in 32bit dwords. */
     
    732731        if (fForceReplyFifo)
    733732        {
    734             pThis->fDoorbellInProgress = false;
     733            pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE;
    735734            lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
    736735        }
     
    744743#endif
    745744    }
     745}
     746
     747/**
     748 * Returns the number of frames in the reply free queue.
     749 *
     750 * @returns Number of frames in the reply free queue.
     751 * @param   pThis    Pointer to the LsiLogic device state.
     752 */
     753DECLINLINE(uint32_t) lsilogicReplyFreeQueueGetFrameCount(PLSILOGICSCSI pThis)
     754{
     755    uint32_t cReplyFrames = 0;
     756
     757    if (pThis->uReplyFreeQueueNextAddressRead <= pThis->uReplyFreeQueueNextEntryFreeWrite)
     758        cReplyFrames = pThis->uReplyFreeQueueNextEntryFreeWrite - pThis->uReplyFreeQueueNextAddressRead;
     759    else
     760        cReplyFrames = pThis->cReplyQueueEntries - pThis->uReplyFreeQueueNextAddressRead + pThis->uReplyFreeQueueNextEntryFreeWrite;
     761
     762    return cReplyFrames;
    746763}
    747764
     
    10261043             * Because the guest is not continuing execution while we are here we can skip this.
    10271044             */
    1028             if (!pThis->fDoorbellInProgress)
     1045            if (pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_NOT_IN_USE)
    10291046            {
    10301047                uint32_t uFunction = LSILOGIC_REG_DOORBELL_GET_FUNCTION(u32);
     
    10321049                switch (uFunction)
    10331050                {
     1051                    case LSILOGIC_DOORBELL_FUNCTION_IO_UNIT_RESET:
    10341052                    case LSILOGIC_DOORBELL_FUNCTION_IOC_MSG_UNIT_RESET:
    10351053                    {
     1054                        /*
     1055                         * The I/O unit reset does much more on real hardware like
     1056                         * reloading the firmware, nothing we need to do here,
     1057                         * so this is like the IOC message unit reset.
     1058                         */
    10361059                        pThis->enmState = LSILOGICSTATE_RESET;
    10371060
     
    10471070                        pThis->uRequestQueueNextEntryFreeWrite = 0;
    10481071                        pThis->uRequestQueueNextAddressRead = 0;
    1049                         pThis->enmState = LSILOGICSTATE_READY;
    1050                         break;
    1051                     }
    1052                     case LSILOGIC_DOORBELL_FUNCTION_IO_UNIT_RESET:
    1053                     {
    1054                         AssertMsgFailed(("todo\n"));
     1072
     1073                        /* Only the IOC message unit reset transisionts to the ready state. */
     1074                        if (uFunction == LSILOGIC_DOORBELL_FUNCTION_IOC_MSG_UNIT_RESET)
     1075                            pThis->enmState = LSILOGICSTATE_READY;
    10551076                        break;
    10561077                    }
     
    10611082                        AssertMsg(pThis->cMessage <= RT_ELEMENTS(pThis->aMessage),
    10621083                                  ("Message doesn't fit into the buffer, cMessage=%u", pThis->cMessage));
    1063                         pThis->fDoorbellInProgress = true;
     1084                        pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_FN_HANDSHAKE;
    10641085                        /* Update the interrupt status to notify the guest that a doorbell function was started. */
    10651086                        lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
     
    10681089                    case LSILOGIC_DOORBELL_FUNCTION_REPLY_FRAME_REMOVAL:
    10691090                    {
    1070                         AssertMsgFailed(("todo\n"));
     1091                        pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_LOW;
     1092                        /* Update the interrupt status to notify the guest that a doorbell function was started. */
     1093                        lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
    10711094                        break;
    10721095                    }
     
    10751098                }
    10761099            }
    1077             else
     1100            else if (pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_FN_HANDSHAKE)
    10781101            {
    10791102                /*
     
    11171140             * is updated afterwards anyway.
    11181141             */
    1119             if (   (pThis->fDoorbellInProgress)
     1142            if (   (pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_FN_HANDSHAKE)
    11201143                && (pThis->cMessage == pThis->iMessage))
    11211144            {
     
    11241147                    /* Reply finished. Reset doorbell in progress status. */
    11251148                    Log(("%s: Doorbell function finished\n", __FUNCTION__));
    1126                     pThis->fDoorbellInProgress = false;
     1149                    pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE;
    11271150                }
     1151                ASMAtomicOrU32(&pThis->uInterruptStatus, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
     1152            }
     1153            else if (   pThis->enmDoorbellState != LSILOGICDOORBELLSTATE_NOT_IN_USE
     1154                     && pThis->enmDoorbellState != LSILOGICDOORBELLSTATE_FN_HANDSHAKE)
     1155            {
     1156                /* Reply frame removal, check whether the reply free queue is empty. */
     1157                if (   pThis->uReplyFreeQueueNextAddressRead == pThis->uReplyFreeQueueNextEntryFreeWrite
     1158                    && pThis->enmDoorbellState == LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW)
     1159                    pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE;
    11281160                ASMAtomicOrU32(&pThis->uInterruptStatus, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
    11291161            }
     
    12321264        {
    12331265            u32  = LSILOGIC_REG_DOORBELL_SET_STATE(pThis->enmState);
    1234             u32 |= LSILOGIC_REG_DOORBELL_SET_USED(pThis->fDoorbellInProgress);
     1266            u32 |= LSILOGIC_REG_DOORBELL_SET_USED(pThis->enmDoorbellState);
    12351267            u32 |= LSILOGIC_REG_DOORBELL_SET_WHOINIT(pThis->enmWhoInit);
    12361268            /*
     
    12391271             * during one read.
    12401272             */
    1241             if (pThis->fDoorbellInProgress)
     1273            switch (pThis->enmDoorbellState)
    12421274            {
    1243                 /* Return next 16bit value. */
    1244                 u32 |= pThis->ReplyBuffer.au16Reply[pThis->uNextReplyEntryRead++];
     1275                case LSILOGICDOORBELLSTATE_NOT_IN_USE:
     1276                    /* We return the status code of the I/O controller. */
     1277                    u32 |= pThis->u16IOCFaultCode;
     1278                    break;
     1279                case LSILOGICDOORBELLSTATE_FN_HANDSHAKE:
     1280                    /* Return next 16bit value. */
     1281                    u32 |= pThis->ReplyBuffer.au16Reply[pThis->uNextReplyEntryRead++];
     1282                    lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
     1283                    break;
     1284                case LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_LOW:
     1285                {
     1286                    uint32_t cReplyFrames = lsilogicReplyFreeQueueGetFrameCount(pThis);
     1287
     1288                    u32 |= cReplyFrames & UINT32_C(0xffff);
     1289                    pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_HIGH;
     1290                    lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
     1291                    break;
     1292                }
     1293                case LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_HIGH:
     1294                {
     1295                    uint32_t cReplyFrames = lsilogicReplyFreeQueueGetFrameCount(pThis);
     1296
     1297                    u32 |= cReplyFrames >> 16;
     1298                    pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW;
     1299                    lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
     1300                    break;
     1301                }
     1302                case LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW:
     1303                    if (pThis->uReplyFreeQueueNextEntryFreeWrite != pThis->uReplyFreeQueueNextAddressRead)
     1304                    {
     1305                        u32 |= pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead] & UINT32_C(0xffff);
     1306                        pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH;
     1307                        lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
     1308                    }
     1309                    break;
     1310                case LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH:
     1311                    u32 |= pThis->CTX_SUFF(pReplyFreeQueueBase)[pThis->uReplyFreeQueueNextAddressRead] >> 16;
     1312                    pThis->uReplyFreeQueueNextAddressRead++;
     1313                    pThis->uReplyFreeQueueNextAddressRead %= pThis->cReplyQueueEntries;
     1314                    pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW;
     1315                    lsilogicSetInterrupt(pThis, LSILOGIC_REG_HOST_INTR_STATUS_SYSTEM_DOORBELL);
     1316                    break;
     1317                default:
     1318                    AssertMsgFailed(("Invalid doorbell state %d\n", pThis->enmDoorbellState));
    12451319            }
    1246             else
    1247             {
    1248                 /* We return the status code of the I/O controller. */
    1249                 u32 |= pThis->u16IOCFaultCode;
    1250             }
     1320
    12511321            break;
    12521322        }
     
    20222092        if (pTargetDevice->pDrvBase)
    20232093        {
    2024             uint32_t uChainOffset;
    2025 
    2026             /* Create Scatter gather list. */
    2027             uChainOffset = pTaskState->GuestRequest.SCSIIO.u8ChainOffset;
    2028 
    2029             if (uChainOffset)
    2030                 uChainOffset = uChainOffset * sizeof(uint32_t) - sizeof(MptSCSIIORequest);
    2031 
    2032             rc = lsilogicR3ScatterGatherListCreate(pThis, pTaskState,
    2033                                                  pTaskState->GCPhysMessageFrameAddr + sizeof(MptSCSIIORequest),
    2034                                                  uChainOffset);
    2035             AssertRC(rc);
     2094
     2095            if (pTaskState->GuestRequest.SCSIIO.u32DataLength)
     2096            {
     2097                uint32_t uChainOffset;
     2098
     2099                /* Create Scatter gather list. */
     2100                uChainOffset = pTaskState->GuestRequest.SCSIIO.u8ChainOffset;
     2101
     2102                if (uChainOffset)
     2103                    uChainOffset = uChainOffset * sizeof(uint32_t) - sizeof(MptSCSIIORequest);
     2104
     2105                rc = lsilogicR3ScatterGatherListCreate(pThis, pTaskState,
     2106                                                       pTaskState->GCPhysMessageFrameAddr + sizeof(MptSCSIIORequest),
     2107                                                       uChainOffset);
     2108                AssertRC(rc);
     2109            }
    20362110
    20372111# if 0
     
    21342208    if (fRedo)
    21352209    {
    2136         if (!pTaskState->fBIOS)
     2210        if (!pTaskState->fBIOS && pTaskState->PDMScsiRequest.cbScatterGather)
    21372211            lsilogicR3ScatterGatherListDestroy(pThis, pTaskState);
    21382212
     
    21712245                                  : pTaskState->PDMScsiRequest.cbSenseBuffer);
    21722246# endif
    2173             lsilogicR3ScatterGatherListDestroy(pThis, pTaskState);
     2247            if (pTaskState->PDMScsiRequest.cbScatterGather)
     2248                lsilogicR3ScatterGatherListDestroy(pThis, pTaskState);
    21742249
    21752250
     
    39804055    pHlp->pfnPrintf(pHlp, "enmState=%u\n", pThis->enmState);
    39814056    pHlp->pfnPrintf(pHlp, "enmWhoInit=%u\n", pThis->enmWhoInit);
    3982     pHlp->pfnPrintf(pHlp, "fDoorbellInProgress=%RTbool\n", pThis->fDoorbellInProgress);
     4057    pHlp->pfnPrintf(pHlp, "enmDoorbellState=%d\n", pThis->enmDoorbellState);
    39834058    pHlp->pfnPrintf(pHlp, "fDiagnosticEnabled=%RTbool\n", pThis->fDiagnosticEnabled);
    39844059    pHlp->pfnPrintf(pHlp, "fNotificationSend=%RTbool\n", pThis->fNotificationSend);
     
    41634238    SSMR3PutU32   (pSSM, pThis->enmState);
    41644239    SSMR3PutU32   (pSSM, pThis->enmWhoInit);
    4165     SSMR3PutBool  (pSSM, pThis->fDoorbellInProgress);
     4240    SSMR3PutU32   (pSSM, pThis->enmDoorbellState);
    41664241    SSMR3PutBool  (pSSM, pThis->fDiagnosticEnabled);
    41674242    SSMR3PutBool  (pSSM, pThis->fNotificationSend);
     
    43754450    SSMR3GetU32   (pSSM, (uint32_t *)&pThis->enmState);
    43764451    SSMR3GetU32   (pSSM, (uint32_t *)&pThis->enmWhoInit);
    4377     SSMR3GetBool  (pSSM, &pThis->fDoorbellInProgress);
     4452    if (uVersion <= LSILOGIC_SAVED_STATE_VERSION_BOOL_DOORBELL)
     4453    {
     4454        bool fDoorbellInProgress = false;
     4455
     4456        /*
     4457         * The doorbell status flag distinguishes only between
     4458         * doorbell not in use or a Function handshake is currently in progress.
     4459         */
     4460        SSMR3GetBool  (pSSM, &fDoorbellInProgress);
     4461        if (fDoorbellInProgress)
     4462            pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_FN_HANDSHAKE;
     4463        else
     4464            pThis->enmDoorbellState = LSILOGICDOORBELLSTATE_NOT_IN_USE;
     4465    }
     4466    else
     4467        SSMR3GetU32(pSSM, (uint32_t *)&pThis->enmDoorbellState);
    43784468    SSMR3GetBool  (pSSM, &pThis->fDiagnosticEnabled);
    43794469    SSMR3GetBool  (pSSM, &pThis->fNotificationSend);
  • trunk/src/VBox/Devices/Storage/DevLsiLogicSCSI.h

    r44528 r45789  
    34663466
    34673467/**
     3468 * Doorbell state.
     3469 */
     3470typedef enum LSILOGICDOORBELLSTATE
     3471{
     3472    /** Invalid value. */
     3473    LSILOGICDOORBELLSTATE_INVALID = 0,
     3474    /** Doorbell not in use. */
     3475    LSILOGICDOORBELLSTATE_NOT_IN_USE,
     3476    /** Reply frame removal, transfer number of entries, low 16bits. */
     3477    LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_LOW,
     3478    /** Reply frame removal, transfer number of entries, high 16bits. */
     3479    LSILOGICDOORBELLSTATE_RFR_FRAME_COUNT_HIGH,
     3480    /** Reply frame removal, remove next free frame, low part. */
     3481    LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_LOW,
     3482    /** Reply frame removal, remove next free frame, high part. */
     3483    LSILOGICDOORBELLSTATE_RFR_NEXT_FRAME_HIGH,
     3484    /** Function handshake. */
     3485    LSILOGICDOORBELLSTATE_FN_HANDSHAKE,
     3486    /** 32bit hack. */
     3487    LSILOGICDOORBELLSTATE_32BIT_HACK = 0x7fffffff
     3488} LSILOGICDOORBELLSTATE;
     3489/** Pointer to a doorbell state. */
     3490typedef LSILOGICDOORBELLSTATE *PLSILOGICDOORBELLSTATE;
     3491
     3492
     3493/**
    34683494 * IOC status codes.
    34693495 */
     
    34913517#define LSILOGIC_REG_DOORBELL 0x00
    34923518# define LSILOGIC_REG_DOORBELL_SET_STATE(enmState)     (((enmState) & 0x0f) << 28)
    3493 # define LSILOGIC_REG_DOORBELL_SET_USED(fUsed)         (((fUsed) ? 1 : 0) << 27)
     3519# define LSILOGIC_REG_DOORBELL_SET_USED(enmDoorbell)   (((enmDoorbell != LSILOGICDOORBELLSTATE_NOT_IN_USE) ? 1 : 0) << 27)
    34943520# define LSILOGIC_REG_DOORBELL_SET_WHOINIT(enmWhoInit) (((enmWhoInit) & 0x07) << 24)
    34953521# define LSILOGIC_REG_DOORBELL_SET_FAULT_CODE(u16Code) (u16Code)
  • trunk/src/VBox/Devices/testcase/tstDeviceStructSizeRC.cpp

    r45646 r45789  
    15601560    GEN_CHECK_OFF(LSILOGICSCSI, enmState);
    15611561    GEN_CHECK_OFF(LSILOGICSCSI, enmWhoInit);
    1562     GEN_CHECK_OFF(LSILOGICSCSI, fDoorbellInProgress);
     1562    GEN_CHECK_OFF(LSILOGICSCSI, enmDoorbellState);
    15631563    GEN_CHECK_OFF(LSILOGICSCSI, fDiagnosticEnabled);
    15641564    GEN_CHECK_OFF(LSILOGICSCSI, fNotificationSend);
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