VirtualBox

Changeset 45959 in vbox for trunk/src


Ignore:
Timestamp:
May 8, 2013 8:27:08 PM (12 years ago)
Author:
vboxsync
Message:

Storage/LsiLogic: Start cleaning up the implementation, rework I/O buffer handling and rename pTaskState to pLsiReq

File:
1 edited

Legend:

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

    r45899 r45959  
    6060#define LSILOGIC_RTGCPHYS_FROM_U32(Hi, Lo)         ( (RTGCPHYS)RT_MAKE_U64(Lo, Hi) )
    6161
     62/** Upper number a buffer is freed if it was too big before. */
     63#define LSILOGIC_MAX_ALLOC_TOO_MUCH 20
    6264
    6365/*******************************************************************************
    6466*   Structures and Typedefs                                                    *
    6567*******************************************************************************/
     68
     69/**
     70 * I/O buffer copy worker.
     71 *
     72 * @returns nothing.
     73 * @param   pDevIns     Device instance data.
     74 * @param   GCPhysIoBuf Guest physical address of the I/O buffer.
     75 * @param   pvBuf       R3 buffer pointer.
     76 * @param   cbCopy      How much to copy.
     77 */
     78typedef DECLCALLBACK(void) FNLSILOGICIOBUFCOPY(PPDMDEVINS pDevIns, RTGCPHYS GCPhysIoBuf,
     79                                               void *pvBuf, size_t cbCopy);
     80/** Pointer to a I/O buffer copy worker. */
     81typedef FNLSILOGICIOBUFCOPY *PFNLSILOGICIOBUFCOPY;
    6682
    6783/**
     
    121137
    122138/** Pointer to a task state. */
    123 typedef struct LSILOGICTASKSTATE *PLSILOGICTASKSTATE;
     139typedef struct LSILOGICREQ *PLSILOGICREQ;
    124140
    125141/**
     
    294310    bool                            afPAdding2[HC_ARCH_BITS == 32 ? 2 : 6];
    295311    /** List of tasks which can be redone. */
    296     R3PTRTYPE(volatile PLSILOGICTASKSTATE) pTasksRedoHead;
     312    R3PTRTYPE(volatile PLSILOGICREQ) pTasksRedoHead;
    297313
    298314} LSILOGISCSI;
     
    301317
    302318/**
    303  * Scatter gather list entry data.
    304  */
    305 typedef struct LSILOGICTASKSTATESGENTRY
    306 {
    307     /** Flag whether the buffer in the list is from the guest or an
    308      *  allocated temporary buffer because the segments in the guest
    309      *  are not sector aligned.
    310      */
    311     bool     fGuestMemory;
    312     /** Flag whether the buffer contains data or is the destination for the transfer. */
    313     bool     fBufferContainsData;
    314     /** Pointer to the start of the buffer. */
    315     void    *pvBuf;
    316     /** Size of the buffer. */
    317     uint32_t cbBuf;
    318     /** Flag dependent data. */
    319     union
    320     {
    321         /** Data to handle direct mappings of guest buffers. */
    322         PGMPAGEMAPLOCK  PageLock;
    323         /** The segment in the guest which is not sector aligned. */
    324         RTGCPHYS        GCPhysAddrBufferUnaligned;
    325     } u;
    326 } LSILOGICTASKSTATESGENTRY;
    327 /** Pointer to a scatter/gather list entry. */
    328 typedef LSILOGICTASKSTATESGENTRY *PLSILOGICTASKSTATESGENTRY;
    329 
    330 /**
    331319 * Task state object which holds all necessary data while
    332320 * processing the request from the guest.
    333321 */
    334 typedef struct LSILOGICTASKSTATE
     322typedef struct LSILOGICREQ
    335323{
    336324    /** Next in the redo list. */
    337     PLSILOGICTASKSTATE         pRedoNext;
     325    PLSILOGICREQ               pRedoNext;
    338326    /** Target device. */
    339327    PLSILOGICDEVICE            pTargetDevice;
     
    347335     *  Used to read the S/G entries in the second step. */
    348336    RTGCPHYS                   GCPhysMessageFrameAddr;
    349     /** Number of scatter gather list entries. */
    350     uint32_t                   cSGListEntries;
    351     /** How many entries would fit into the sg list. */
    352     uint32_t                   cSGListSize;
    353     /** How many times the list was too big. */
    354     uint32_t                   cSGListTooBig;
    355     /** Pointer to the first entry of the scatter gather list. */
    356     PRTSGSEG                   pSGListHead;
    357     /** How many entries would fit into the sg info list. */
    358     uint32_t                   cSGInfoSize;
    359     /** Number of entries for the information entries. */
    360     uint32_t                   cSGInfoEntries;
    361     /** How many times the list was too big. */
    362     uint32_t                   cSGInfoTooBig;
    363     /** Pointer to the first mapping information entry. */
    364     PLSILOGICTASKSTATESGENTRY  paSGEntries;
    365     /** Size of the temporary buffer for unaligned guest segments. */
    366     uint32_t                   cbBufferUnaligned;
    367     /** Pointer to the temporary buffer. */
    368     void                      *pvBufferUnaligned;
     337    /** Physical start address of the S/G list. */
     338    RTGCPHYS                   GCPhysSgStart;
     339    /** Chain offset */
     340    uint32_t                   cChainOffset;
     341    /** Segment describing the I/O buffer. */
     342    RTSGSEG                    SegIoBuf;
     343    /** Additional memory allocation for this task. */
     344    void                      *pvAlloc;
     345    /** Siize of the allocation. */
     346    size_t                     cbAlloc;
     347    /** Number of times we had too much memory allocated for the request. */
     348    unsigned                   cAllocTooMuch;
    369349    /** Pointer to the sense buffer. */
    370350    uint8_t                    abSenseBuffer[18];
    371351    /** Flag whether the request was issued from the BIOS. */
    372352    bool                       fBIOS;
    373 } LSILOGICTASKSTATE;
     353} LSILOGICREQ;
    374354
    375355
     
    469449    }
    470450    else
    471     {
    472451        Log(("%s: We are already in FAULT state\n"));
    473     }
    474452}
    475453
     
    597575
    598576    PDMCritSectLeave(&pThis->ReplyPostQueueCritSect);
    599 }
    600 
    601 static void lsilogicR3TaskStateClear(PLSILOGICTASKSTATE pTaskState)
    602 {
    603     RTMemFree(pTaskState->pSGListHead);
    604     RTMemFree(pTaskState->paSGEntries);
    605     if (pTaskState->pvBufferUnaligned)
    606         RTMemPageFree(pTaskState->pvBufferUnaligned, pTaskState->cbBufferUnaligned);
    607     pTaskState->cSGListSize = 0;
    608     pTaskState->cSGInfoSize = 0;
    609     pTaskState->cSGInfoEntries = 0;
    610     pTaskState->cSGListTooBig  = 0;
    611     pTaskState->pSGListHead = NULL;
    612     pTaskState->paSGEntries = NULL;
    613     pTaskState->pvBufferUnaligned = NULL;
    614     pTaskState->cbBufferUnaligned = 0;
    615 }
    616 
    617 /**
    618  * @callback_method_impl{FNMEMCACHECTOR}
    619  */
    620 static DECLCALLBACK(int) lsilogicR3TaskStateCtor(RTMEMCACHE hMemCache, void *pvObj, void *pvUser)
    621 {
    622     memset(pvObj, 0, sizeof(LSILOGICTASKSTATE));
    623     return VINF_SUCCESS;
    624 }
    625 
    626 /**
    627  * @callback_method_impl{FNMEMCACHEDTOR}
    628  */
    629 static DECLCALLBACK(void) lsilogicR3TaskStateDtor(RTMEMCACHE hMemCache, void *pvObj, void *pvUser)
    630 {
    631     PLSILOGICTASKSTATE pTaskState = (PLSILOGICTASKSTATE)pvObj;
    632     lsilogicR3TaskStateClear(pTaskState);
    633577}
    634578
     
    14541398#ifdef IN_RING3
    14551399
    1456 /**
    1457  * Copies a contiguous buffer into the scatter gather list provided by the guest.
    1458  *
    1459  * @returns nothing
    1460  * @param   pTaskState    Pointer to the task state which contains the SGL.
    1461  * @param   pvBuf         Pointer to the buffer to copy.
    1462  * @param   cbCopy        Number of bytes to copy.
    1463  */
    1464 static void lsilogicR3ScatterGatherListCopyFromBuffer(PLSILOGICTASKSTATE pTaskState, void *pvBuf, size_t cbCopy)
    1465 {
    1466     unsigned cSGEntry = 0;
    1467     PRTSGSEG pSGEntry = &pTaskState->pSGListHead[cSGEntry];
    1468     uint8_t *pu8Buf = (uint8_t *)pvBuf;
    1469 
    1470     while (cSGEntry < pTaskState->cSGListEntries)
    1471     {
    1472         size_t cbToCopy = (cbCopy < pSGEntry->cbSeg) ? cbCopy : pSGEntry->cbSeg;
    1473 
    1474         memcpy(pSGEntry->pvSeg, pu8Buf, cbToCopy);
    1475 
    1476         cbCopy -= cbToCopy;
    1477         /* We finished. */
    1478         if (!cbCopy)
    1479             break;
    1480 
    1481         /* Advance the buffer. */
    1482         pu8Buf += cbToCopy;
    1483 
    1484         /* Go to the next entry in the list. */
    1485         pSGEntry++;
    1486         cSGEntry++;
    1487     }
    1488 }
    1489 
    1490 /**
    1491  * Copy a temporary buffer into a part of the guest scatter gather list
    1492  * described by the given descriptor entry.
    1493  *
    1494  * @returns nothing.
    1495  * @param   pDevIns    Pointer to the device instance data.
    1496  * @param   pSGInfo    Pointer to the segment info structure which describes the guest segments
    1497  *                     to write to which are unaligned.
    1498  */
    1499 static void lsilogicR3CopyFromBufferIntoSGList(PPDMDEVINS pDevIns, PLSILOGICTASKSTATESGENTRY pSGInfo)
    1500 {
    1501     RTGCPHYS GCPhysBuffer = pSGInfo->u.GCPhysAddrBufferUnaligned;
    1502 
    1503     AssertMsg(!pSGInfo->fGuestMemory, ("This is not possible\n"));
    1504 
    1505     /* Copy into SG entry. */
    1506     PDMDevHlpPCIPhysWrite(pDevIns, GCPhysBuffer, pSGInfo->pvBuf, pSGInfo->cbBuf);
    1507 
    1508 }
    1509 
    1510 /**
    1511  * Copy a part of the guest scatter gather list into a temporary buffer.
    1512  *
    1513  * @returns nothing.
    1514  * @param   pDevIns    Pointer to the device instance data.
    1515  * @param   pSGInfo    Pointer to the segment info structure which describes the guest segments
    1516  *                     to read from which are unaligned.
    1517  */
    1518 static void lsilogicR3CopyFromSGListIntoBuffer(PPDMDEVINS pDevIns, PLSILOGICTASKSTATESGENTRY pSGInfo)
    1519 {
    1520     RTGCPHYS GCPhysBuffer = pSGInfo->u.GCPhysAddrBufferUnaligned;
    1521 
    1522     AssertMsg(!pSGInfo->fGuestMemory, ("This is not possible\n"));
    1523 
    1524     /* Copy into temporary buffer. */
    1525     PDMDevHlpPhysRead(pDevIns, GCPhysBuffer, pSGInfo->pvBuf, pSGInfo->cbBuf);
    1526 }
    1527 
    1528 static int lsilogicR3ScatterGatherListAllocate(PLSILOGICTASKSTATE pTaskState, uint32_t cSGList, uint32_t cSGInfo, uint32_t cbUnaligned)
    1529 {
    1530     if (pTaskState->cSGListSize < cSGList)
    1531     {
    1532         /* The entries are not allocated yet or the number is too small. */
    1533         if (pTaskState->cSGListSize)
    1534             RTMemFree(pTaskState->pSGListHead);
    1535 
    1536         /* Allocate R3 scatter gather list. */
    1537         pTaskState->pSGListHead = (PRTSGSEG)RTMemAllocZ(cSGList * sizeof(RTSGSEG));
    1538         if (!pTaskState->pSGListHead)
    1539             return VERR_NO_MEMORY;
    1540 
    1541         /* Reset usage statistics. */
    1542         pTaskState->cSGListSize     = cSGList;
    1543         pTaskState->cSGListEntries  = cSGList;
    1544         pTaskState->cSGListTooBig = 0;
    1545     }
    1546     else if (pTaskState->cSGListSize > cSGList)
    1547     {
    1548         /*
    1549          * The list is too big. Increment counter.
    1550          * So that the destroying function can free
    1551          * the list if it is too big too many times
    1552          * in a row.
    1553          */
    1554         pTaskState->cSGListEntries = cSGList;
    1555         pTaskState->cSGListTooBig++;
    1556     }
    1557     else
    1558     {
    1559         /*
    1560          * Needed entries matches current size.
    1561          * Reset counter.
    1562          */
    1563         pTaskState->cSGListEntries = cSGList;
    1564         pTaskState->cSGListTooBig  = 0;
    1565     }
    1566 
    1567     if (pTaskState->cSGInfoSize < cSGInfo)
    1568     {
    1569         /* The entries are not allocated yet or the number is too small. */
    1570         if (pTaskState->cSGInfoSize)
    1571             RTMemFree(pTaskState->paSGEntries);
    1572 
    1573         pTaskState->paSGEntries = (PLSILOGICTASKSTATESGENTRY)RTMemAllocZ(cSGInfo * sizeof(LSILOGICTASKSTATESGENTRY));
    1574         if (!pTaskState->paSGEntries)
    1575             return VERR_NO_MEMORY;
    1576 
    1577         /* Reset usage statistics. */
    1578         pTaskState->cSGInfoSize = cSGInfo;
    1579         pTaskState->cSGInfoEntries  = cSGInfo;
    1580         pTaskState->cSGInfoTooBig = 0;
    1581     }
    1582     else if (pTaskState->cSGInfoSize > cSGInfo)
    1583     {
    1584         /*
    1585          * The list is too big. Increment counter.
    1586          * So that the destroying function can free
    1587          * the list if it is too big too many times
    1588          * in a row.
    1589          */
    1590         pTaskState->cSGInfoEntries = cSGInfo;
    1591         pTaskState->cSGInfoTooBig++;
    1592     }
    1593     else
    1594     {
    1595         /*
    1596          * Needed entries matches current size.
    1597          * Reset counter.
    1598          */
    1599         pTaskState->cSGInfoEntries  = cSGInfo;
    1600         pTaskState->cSGInfoTooBig = 0;
    1601     }
    1602 
    1603 
    1604     if (pTaskState->cbBufferUnaligned < cbUnaligned)
    1605     {
    1606         if (pTaskState->pvBufferUnaligned)
    1607             RTMemPageFree(pTaskState->pvBufferUnaligned, pTaskState->cbBufferUnaligned);
    1608 
    1609         Log(("%s: Allocating buffer for unaligned segments cbUnaligned=%u\n", __FUNCTION__, cbUnaligned));
    1610 
    1611         pTaskState->pvBufferUnaligned = RTMemPageAlloc(cbUnaligned);
    1612         if (!pTaskState->pvBufferUnaligned)
    1613             return VERR_NO_MEMORY;
    1614 
    1615         pTaskState->cbBufferUnaligned = cbUnaligned;
    1616     }
    1617 
    1618     /* Make debugging easier. */
    1619 # ifdef LOG_ENABLED
    1620     memset(pTaskState->pSGListHead, 0, pTaskState->cSGListSize * sizeof(RTSGSEG));
    1621     memset(pTaskState->paSGEntries, 0, pTaskState->cSGInfoSize * sizeof(LSILOGICTASKSTATESGENTRY));
    1622     if (pTaskState->pvBufferUnaligned)
    1623         memset(pTaskState->pvBufferUnaligned, 0, pTaskState->cbBufferUnaligned);
    1624 # endif
    1625     return VINF_SUCCESS;
    1626 }
    1627 
    1628 /**
    1629  * Destroy a scatter gather list.
    1630  *
    1631  * @returns nothing.
    1632  * @param   pThis       Pointer to the LsiLogic device state.
    1633  * @param   pTaskState  Pointer to the task state.
    1634  */
    1635 static void lsilogicR3ScatterGatherListDestroy(PLSILOGICSCSI pThis, PLSILOGICTASKSTATE pTaskState)
    1636 {
    1637     PPDMDEVINS                pDevIns     = pThis->CTX_SUFF(pDevIns);
    1638     PLSILOGICTASKSTATESGENTRY pSGInfoCurr = pTaskState->paSGEntries;
    1639 
    1640     for (unsigned i = 0; i < pTaskState->cSGInfoEntries; i++)
    1641     {
    1642         if (pSGInfoCurr->fGuestMemory)
    1643         {
    1644             /* Release the lock. */
    1645             PDMDevHlpPhysReleasePageMappingLock(pDevIns, &pSGInfoCurr->u.PageLock);
    1646         }
    1647         else if (!pSGInfoCurr->fBufferContainsData)
    1648         {
    1649             /* Copy the data into the guest segments now. */
    1650             lsilogicR3CopyFromBufferIntoSGList(pThis->CTX_SUFF(pDevIns), pSGInfoCurr);
    1651         }
    1652 
    1653         pSGInfoCurr++;
    1654     }
    1655 
    1656     /* Free allocated memory if the list was too big too many times. */
    1657     if (pTaskState->cSGListTooBig >= LSILOGIC_NR_OF_ALLOWED_BIGGER_LISTS)
    1658         lsilogicR3TaskStateClear(pTaskState);
    1659 }
    1660 
    16611400# ifdef LOG_ENABLED
    16621401/**
     
    17161455# endif /* LOG_ENABLED */
    17171456
    1718 /**
    1719  * Create scatter gather list descriptors.
     1457static void lsilogicSgBufWalker(PPDMDEVINS pDevIns, PLSILOGICREQ pLsiReq, size_t cbCopy,
     1458                                PFNLSILOGICIOBUFCOPY pfnIoBufCopy)
     1459{
     1460    bool     fEndOfList = false;
     1461    RTGCPHYS GCPhysSgEntryNext = pLsiReq->GCPhysSgStart;
     1462    RTGCPHYS GCPhysSegmentStart = pLsiReq->GCPhysSgStart;
     1463    uint32_t cChainOffsetNext = pLsiReq->cChainOffset;
     1464    uint8_t *pbBuf = (uint8_t *)pLsiReq->SegIoBuf.pvSeg;
     1465
     1466    /* Go through the list until we reach the end. */
     1467    while (   !fEndOfList
     1468           && cbCopy)
     1469    {
     1470        bool fEndOfSegment = false;
     1471
     1472        while (   !fEndOfSegment
     1473               && cbCopy)
     1474        {
     1475            MptSGEntryUnion SGEntry;
     1476
     1477            Log(("%s: Reading SG entry from %RGp\n", __FUNCTION__, GCPhysSgEntryNext));
     1478
     1479            /* Read the entry. */
     1480            PDMDevHlpPhysRead(pDevIns, GCPhysSgEntryNext, &SGEntry, sizeof(MptSGEntryUnion));
     1481
     1482# ifdef LOG_ENABLED
     1483            lsilogicDumpSGEntry(&SGEntry);
     1484# endif
     1485
     1486            AssertMsg(SGEntry.Simple32.u2ElementType == MPTSGENTRYTYPE_SIMPLE, ("Invalid SG entry type\n"));
     1487
     1488            /* Check if this is a zero element and abort. */
     1489            if (   !SGEntry.Simple32.u24Length
     1490                && SGEntry.Simple32.fEndOfList
     1491                && SGEntry.Simple32.fEndOfBuffer)
     1492                return;
     1493
     1494            uint32_t cbCopyThis           = SGEntry.Simple32.u24Length;
     1495            RTGCPHYS GCPhysAddrDataBuffer = SGEntry.Simple32.u32DataBufferAddressLow;
     1496
     1497            if (SGEntry.Simple32.f64BitAddress)
     1498            {
     1499                GCPhysAddrDataBuffer |= ((uint64_t)SGEntry.Simple64.u32DataBufferAddressHigh) << 32;
     1500                GCPhysSgEntryNext += sizeof(MptSGEntrySimple64);
     1501            }
     1502            else
     1503                GCPhysSgEntryNext += sizeof(MptSGEntrySimple32);
     1504
     1505
     1506            pfnIoBufCopy(pDevIns, GCPhysAddrDataBuffer, pbBuf, cbCopyThis);
     1507            pbBuf      += cbCopyThis;
     1508            cbCopyThis -= cbCopyThis;
     1509
     1510            /* Check if we reached the end of the list. */
     1511            if (SGEntry.Simple32.fEndOfList)
     1512            {
     1513                /* We finished. */
     1514                fEndOfSegment = true;
     1515                fEndOfList = true;
     1516            }
     1517            else if (SGEntry.Simple32.fLastElement)
     1518                fEndOfSegment = true;
     1519        } /* while (!fEndOfSegment) */
     1520
     1521        /* Get next chain element. */
     1522        if (cChainOffsetNext)
     1523        {
     1524            MptSGEntryChain SGEntryChain;
     1525
     1526            PDMDevHlpPhysRead(pDevIns, GCPhysSegmentStart + cChainOffsetNext, &SGEntryChain, sizeof(MptSGEntryChain));
     1527
     1528            AssertMsg(SGEntryChain.u2ElementType == MPTSGENTRYTYPE_CHAIN, ("Invalid SG entry type\n"));
     1529
     1530           /* Set the next address now. */
     1531            GCPhysSgEntryNext = SGEntryChain.u32SegmentAddressLow;
     1532            if (SGEntryChain.f64BitAddress)
     1533                GCPhysSgEntryNext |= ((uint64_t)SGEntryChain.u32SegmentAddressHigh) << 32;
     1534
     1535            GCPhysSegmentStart = GCPhysSgEntryNext;
     1536            cChainOffsetNext   = SGEntryChain.u8NextChainOffset * sizeof(uint32_t);
     1537        }
     1538    } /* while (!fEndOfList) */
     1539}
     1540
     1541static DECLCALLBACK(void) lsilogicCopyFromGuest(PPDMDEVINS pDevIns, RTGCPHYS GCPhysIoBuf,
     1542                                                void *pvBuf, size_t cbCopy)
     1543{
     1544    PDMDevHlpPhysRead(pDevIns, GCPhysIoBuf, pvBuf, cbCopy);
     1545}
     1546
     1547static DECLCALLBACK(void) lsilogicCopyToGuest(PPDMDEVINS pDevIns, RTGCPHYS GCPhysIoBuf,
     1548                                              void *pvBuf, size_t cbCopy)
     1549{
     1550    PDMDevHlpPCIPhysWrite(pDevIns, GCPhysIoBuf, pvBuf, cbCopy);
     1551}
     1552
     1553/**
     1554 * Copy from a guest S/G buffer to the I/O buffer.
     1555 *
     1556 * @returns nothing.
     1557 * @param   pDevIns      Device instance data.
     1558 * @param   pLsiReq      Request data.
     1559 * @param   cbCopy       How much to copy over.
     1560 */
     1561DECLINLINE(void) lsilogicCopyFromSgBuf(PPDMDEVINS pDevIns, PLSILOGICREQ pLsiReq, size_t cbCopy)
     1562{
     1563    lsilogicSgBufWalker(pDevIns, pLsiReq, cbCopy, lsilogicCopyFromGuest);
     1564}
     1565
     1566/**
     1567 * Copy from an I/O buffer to the guest S/G buffer.
     1568 *
     1569 * @returns nothing.
     1570 * @param   pDevIns      Device instance data.
     1571 * @param   pLsiReq      Request data.
     1572 * @param   cbCopy       How much to copy over.
     1573 */
     1574DECLINLINE(void) lsilogicCopyToSgBuf(PPDMDEVINS pDevIns, PLSILOGICREQ pLsiReq, size_t cbCopy)
     1575{
     1576    lsilogicSgBufWalker(pDevIns, pLsiReq, cbCopy, lsilogicCopyToGuest);
     1577}
     1578
     1579/**
     1580 * Allocates memory for the given request using already allocated memory if possible.
     1581 *
     1582 * @returns Pointer to the memory or NULL on failure
     1583 * @param   pLsiReq     The request to allocate memory for.
     1584 * @param   cb          The amount of memory to allocate.
     1585 */
     1586static void *lsilogicReqMemAlloc(PLSILOGICREQ pLsiReq, size_t cb)
     1587{
     1588    if (pLsiReq->cbAlloc > cb)
     1589        pLsiReq->cAllocTooMuch++;
     1590    else if (pLsiReq->cbAlloc < cb)
     1591    {
     1592        if (pLsiReq->cbAlloc)
     1593            RTMemPageFree(pLsiReq->pvAlloc, pLsiReq->cbAlloc);
     1594
     1595        pLsiReq->cbAlloc = RT_ALIGN_Z(cb, _4K);
     1596        pLsiReq->pvAlloc = RTMemPageAlloc(pLsiReq->cbAlloc);
     1597        pLsiReq->cAllocTooMuch = 0;
     1598        if (RT_UNLIKELY(!pLsiReq->pvAlloc))
     1599            pLsiReq->cbAlloc = 0;
     1600    }
     1601
     1602    return pLsiReq->pvAlloc;
     1603}
     1604
     1605/**
     1606 * Frees memory allocated for the given request.
     1607 *
     1608 * @returns nothing.
     1609 * @param   pLsiReq     The request.
     1610 */
     1611static void lsilogicReqMemFree(PLSILOGICREQ pLsiReq)
     1612{
     1613    if (pLsiReq->cAllocTooMuch >= LSILOGIC_MAX_ALLOC_TOO_MUCH)
     1614    {
     1615        RTMemPageFree(pLsiReq->pvAlloc, pLsiReq->cbAlloc);
     1616        pLsiReq->cbAlloc = 0;
     1617        pLsiReq->cAllocTooMuch = 0;
     1618    }
     1619}
     1620
     1621/**
     1622 * Allocate I/O memory and copies the guest buffer for writes.
    17201623 *
    17211624 * @returns VBox status code.
    1722  * @param   pThis           Pointer to the LsiLogic device state.
    1723  * @param   pTaskState      Pointer to the task state.
    1724  * @param   GCPhysSGLStart  Guest physical address of the first SG entry.
    1725  * @param   uChainOffset    Offset in bytes from the beginning of the SGL segment to the chain element.
    1726  * @thread  EMT
    1727  */
    1728 static int lsilogicR3ScatterGatherListCreate(PLSILOGICSCSI pThis, PLSILOGICTASKSTATE pTaskState,
    1729                                              RTGCPHYS GCPhysSGLStart, uint32_t uChainOffset)
    1730 {
    1731     int                        rc           = VINF_SUCCESS;
    1732     PPDMDEVINS                 pDevIns      = pThis->CTX_SUFF(pDevIns);
    1733     PVM                        pVM          = PDMDevHlpGetVM(pDevIns);
    1734     bool                       fUnaligned;     /* Flag whether the current buffer is unaligned. */
    1735     uint32_t                   cbUnaligned;    /* Size of the unaligned buffers. */
    1736     uint32_t                   cSGEntriesR3 = 0;
    1737     uint32_t                   cSGInfo      = 0;
    1738     uint32_t                   cbSegment    = 0;
    1739     PLSILOGICTASKSTATESGENTRY  pSGInfoCurr  = NULL;
    1740     uint8_t                   *pu8BufferUnalignedPos = NULL;
    1741     uint8_t                   *pbBufferUnalignedSGInfoPos = NULL;
    1742     uint32_t                   cbUnalignedComplete = 0;
    1743     bool                       fDoMapping = false;
    1744     bool                       fEndOfList;
    1745     RTGCPHYS                   GCPhysSGEntryNext;
    1746     RTGCPHYS                   GCPhysSegmentStart;
    1747     uint32_t                   uChainOffsetNext;
    1748 
    1749     /*
    1750      * Two passes - one to count needed scatter gather list entries and needed unaligned
    1751      * buffers and one to actually map the SG list into R3.
    1752      */
    1753     for (int i = 0; i < 2; i++)
    1754     {
    1755         fUnaligned      = false;
    1756         cbUnaligned     = 0;
    1757         fEndOfList      = false;
    1758 
    1759         GCPhysSGEntryNext  = GCPhysSGLStart;
    1760         uChainOffsetNext   = uChainOffset;
    1761         GCPhysSegmentStart = GCPhysSGLStart;
    1762 
    1763         if (fDoMapping)
    1764         {
    1765             Log(("%s: cSGInfo=%u\n", __FUNCTION__, cSGInfo));
    1766 
    1767             /* The number of needed SG entries in R3 is known. Allocate needed memory. */
    1768             rc = lsilogicR3ScatterGatherListAllocate(pTaskState, cSGInfo, cSGInfo, cbUnalignedComplete);
    1769             AssertMsgRC(rc, ("Failed to allocate scatter gather array rc=%Rrc\n", rc));
    1770 
    1771             /* We are now able to map the pages into R3. */
    1772             pSGInfoCurr = pTaskState->paSGEntries;
    1773             /* Initialize first segment to remove the need for additional if checks later in the code. */
    1774             pSGInfoCurr->fGuestMemory= false;
    1775             pu8BufferUnalignedPos = (uint8_t *)pTaskState->pvBufferUnaligned;
    1776             pbBufferUnalignedSGInfoPos = pu8BufferUnalignedPos;
    1777         }
    1778 
    1779         /* Go through the list until we reach the end. */
    1780         while (!fEndOfList)
    1781         {
    1782             bool fEndOfSegment = false;
    1783 
    1784             while (!fEndOfSegment)
    1785             {
    1786                 MptSGEntryUnion SGEntry;
    1787 
    1788                 Log(("%s: Reading SG entry from %RGp\n", __FUNCTION__, GCPhysSGEntryNext));
    1789 
    1790                 /* Read the entry. */
    1791                 PDMDevHlpPhysRead(pDevIns, GCPhysSGEntryNext, &SGEntry, sizeof(MptSGEntryUnion));
    1792 
    1793 # ifdef LOG_ENABLED
    1794                 lsilogicDumpSGEntry(&SGEntry);
    1795 # endif
    1796 
    1797                 AssertMsg(SGEntry.Simple32.u2ElementType == MPTSGENTRYTYPE_SIMPLE, ("Invalid SG entry type\n"));
    1798 
    1799                 /* Check if this is a zero element. */
    1800                 if (   !SGEntry.Simple32.u24Length
    1801                     && SGEntry.Simple32.fEndOfList
    1802                     && SGEntry.Simple32.fEndOfBuffer)
    1803                 {
    1804                     pTaskState->cSGListEntries = 0;
    1805                     pTaskState->cSGInfoEntries = 0;
    1806                     return VINF_SUCCESS;
    1807                 }
    1808 
    1809                 uint32_t cbDataToTransfer     = SGEntry.Simple32.u24Length;
    1810                 bool     fBufferContainsData  = !!SGEntry.Simple32.fBufferContainsData;
    1811                 RTGCPHYS GCPhysAddrDataBuffer = SGEntry.Simple32.u32DataBufferAddressLow;
    1812 
    1813                 if (SGEntry.Simple32.f64BitAddress)
    1814                 {
    1815                     GCPhysAddrDataBuffer |= ((uint64_t)SGEntry.Simple64.u32DataBufferAddressHigh) << 32;
    1816                     GCPhysSGEntryNext += sizeof(MptSGEntrySimple64);
    1817                 }
    1818                 else
    1819                     GCPhysSGEntryNext += sizeof(MptSGEntrySimple32);
    1820 
    1821                 if (fDoMapping)
    1822                 {
    1823                     pSGInfoCurr->fGuestMemory = false;
    1824                     pSGInfoCurr->fBufferContainsData = fBufferContainsData;
    1825                     pSGInfoCurr->cbBuf = cbDataToTransfer;
    1826                     pSGInfoCurr->pvBuf = pbBufferUnalignedSGInfoPos;
    1827                     pbBufferUnalignedSGInfoPos += cbDataToTransfer;
    1828                     pSGInfoCurr->u.GCPhysAddrBufferUnaligned = GCPhysAddrDataBuffer;
    1829                     if (fBufferContainsData)
    1830                         lsilogicR3CopyFromSGListIntoBuffer(pDevIns, pSGInfoCurr);
    1831                     pSGInfoCurr++;
    1832                 }
    1833                 else
    1834                 {
    1835                     cbUnalignedComplete += cbDataToTransfer;
    1836                     cSGInfo++;
    1837                 }
    1838 
    1839                 /* Check if we reached the end of the list. */
    1840                 if (SGEntry.Simple32.fEndOfList)
    1841                 {
    1842                     /* We finished. */
    1843                     fEndOfSegment = true;
    1844                     fEndOfList = true;
    1845                 }
    1846                 else if (SGEntry.Simple32.fLastElement)
    1847                 {
    1848                     fEndOfSegment = true;
    1849                 }
    1850             } /* while (!fEndOfSegment) */
    1851 
    1852             /* Get next chain element. */
    1853             if (uChainOffsetNext)
    1854             {
    1855                 MptSGEntryChain SGEntryChain;
    1856 
    1857                 PDMDevHlpPhysRead(pDevIns, GCPhysSegmentStart + uChainOffsetNext, &SGEntryChain, sizeof(MptSGEntryChain));
    1858 
    1859                 AssertMsg(SGEntryChain.u2ElementType == MPTSGENTRYTYPE_CHAIN, ("Invalid SG entry type\n"));
    1860 
    1861                /* Set the next address now. */
    1862                 GCPhysSGEntryNext = SGEntryChain.u32SegmentAddressLow;
    1863                 if (SGEntryChain.f64BitAddress)
    1864                     GCPhysSGEntryNext |= ((uint64_t)SGEntryChain.u32SegmentAddressHigh) << 32;
    1865 
    1866                 GCPhysSegmentStart = GCPhysSGEntryNext;
    1867                 uChainOffsetNext   = SGEntryChain.u8NextChainOffset * sizeof(uint32_t);
    1868             }
    1869 
    1870         } /* while (!fEndOfList) */
    1871 
    1872         fDoMapping = true;
    1873         if (fUnaligned)
    1874             cbUnalignedComplete += cbUnaligned;
    1875     }
    1876 
    1877     uint32_t    cSGEntries;
    1878     PRTSGSEG    pSGEntryCurr = pTaskState->pSGListHead;
    1879     pSGInfoCurr              = pTaskState->paSGEntries;
    1880 
    1881     /* Initialize first entry. */
    1882     pSGEntryCurr->pvSeg = pSGInfoCurr->pvBuf;
    1883     pSGEntryCurr->cbSeg = pSGInfoCurr->cbBuf;
    1884     pSGInfoCurr++;
    1885     cSGEntries = 1;
    1886 
    1887     /* Construct the scatter gather list. */
    1888     for (unsigned i = 0; i < (pTaskState->cSGInfoEntries-1); i++)
    1889     {
    1890         if (pSGEntryCurr->cbSeg % 512 != 0)
    1891         {
    1892             AssertMsg((uint8_t *)pSGEntryCurr->pvSeg + pSGEntryCurr->cbSeg == pSGInfoCurr->pvBuf,
    1893                       ("Buffer ist not sector aligned but the buffer addresses are not adjacent\n"));
    1894 
    1895             pSGEntryCurr->cbSeg += pSGInfoCurr->cbBuf;
    1896         }
    1897         else
    1898         {
    1899             if (((uint8_t *)pSGEntryCurr->pvSeg + pSGEntryCurr->cbSeg) == pSGInfoCurr->pvBuf)
    1900             {
    1901                 pSGEntryCurr->cbSeg += pSGInfoCurr->cbBuf;
    1902             }
    1903             else
    1904             {
    1905                 pSGEntryCurr++;
    1906                 cSGEntries++;
    1907                 pSGEntryCurr->pvSeg = pSGInfoCurr->pvBuf;
    1908                 pSGEntryCurr->cbSeg = pSGInfoCurr->cbBuf;
    1909             }
    1910         }
    1911 
    1912         pSGInfoCurr++;
    1913     }
    1914 
    1915     pTaskState->cSGListEntries = cSGEntries;
    1916 
    1917     return rc;
    1918 }
    1919 
    1920 /*
    1921  * Disabled because the sense buffer provided by the LsiLogic driver for Windows XP
    1922  * crosses page boundaries.
    1923  */
    1924 # if 0
    1925 /**
    1926  * Free the sense buffer.
     1625 * @param   pDevIns     The device instance.
     1626 * @param   pLsiReq     The request state.
     1627 * @param   cbTransfer  Amount of bytes to allocate.
     1628 */
     1629static int lsilogicIoBufAllocate(PPDMDEVINS pDevIns, PLSILOGICREQ pLsiReq,
     1630                                 size_t cbTransfer)
     1631{
     1632    uint8_t uTxDir = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_GET(pLsiReq->GuestRequest.SCSIIO.u32Control);
     1633
     1634    AssertMsg(   uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE
     1635              || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ,
     1636              ("Allocating I/O memory for a non I/O request is not allowed\n"));
     1637
     1638    pLsiReq->SegIoBuf.pvSeg = lsilogicReqMemAlloc(pLsiReq, cbTransfer);
     1639    if (!pLsiReq->SegIoBuf.pvSeg)
     1640        return VERR_NO_MEMORY;
     1641
     1642    pLsiReq->SegIoBuf.cbSeg = cbTransfer;
     1643    if (uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE)
     1644        lsilogicCopyFromSgBuf(pDevIns, pLsiReq, cbTransfer);
     1645
     1646    return VINF_SUCCESS;
     1647}
     1648
     1649/**
     1650 * Frees the I/O memory of the given request and updates the guest buffer if necessary.
    19271651 *
    19281652 * @returns nothing.
    1929  * @param   pTaskState   Pointer to the task state.
    1930  */
    1931 static void lsilogicFreeGCSenseBuffer(PLSILOGICSCSI pThis, PLSILOGICTASKSTATE pTaskState)
    1932 {
    1933     PVM pVM = PDMDevHlpGetVM(pThis->CTX_SUFF(pDevIns));
    1934 
    1935     PGMPhysReleasePageMappingLock(pVM, &pTaskState->PageLockSense);
    1936     pTaskState->pbSenseBuffer = NULL;
    1937 }
    1938 
    1939 /**
    1940  * Map the sense buffer into R3.
    1941  *
    1942  * @returns VBox status code.
    1943  * @param   pTaskState    Pointer to the task state.
    1944  * @note Current assumption is that the sense buffer is not scattered and does not cross a page boundary.
    1945  */
    1946 static int lsilogicR3MapGCSenseBufferIntoR3(PLSILOGICSCSI pThis, PLSILOGICTASKSTATE pTaskState)
    1947 {
    1948     int rc = VINF_SUCCESS;
    1949     PPDMDEVINS pDevIns = pThis->CTX_SUFF(pDevIns);
    1950     RTGCPHYS GCPhysAddrSenseBuffer;
    1951 
    1952     GCPhysAddrSenseBuffer = pTaskState->GuestRequest.SCSIIO.u32SenseBufferLowAddress;
    1953     GCPhysAddrSenseBuffer |= ((uint64_t)pThis->u32SenseBufferHighAddr << 32);
    1954 
    1955 # ifdef RT_STRICT
    1956     uint32_t cbSenseBuffer = pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength;
    1957 # endif
    1958     RTGCPHYS GCPhysAddrSenseBufferBase = PAGE_ADDRESS(GCPhysAddrSenseBuffer);
    1959 
    1960     AssertMsg(GCPhysAddrSenseBuffer >= GCPhysAddrSenseBufferBase,
    1961               ("Impossible GCPhysAddrSenseBuffer < GCPhysAddrSenseBufferBase\n"));
    1962 
    1963     /* Sanity checks for the assumption. */
    1964     AssertMsg(((GCPhysAddrSenseBuffer + cbSenseBuffer) <= (GCPhysAddrSenseBufferBase + PAGE_SIZE)),
    1965               ("Sense buffer crosses page boundary\n"));
    1966 
    1967     rc = PDMDevHlpPhysGCPhys2CCPtr(pDevIns, GCPhysAddrSenseBufferBase, (void **)&pTaskState->pbSenseBuffer, &pTaskState->PageLockSense);
    1968     AssertMsgRC(rc, ("Mapping sense buffer failed rc=%Rrc\n", rc));
    1969 
    1970     /* Correct start address of the sense buffer. */
    1971     pTaskState->pbSenseBuffer += (GCPhysAddrSenseBuffer - GCPhysAddrSenseBufferBase);
    1972 
    1973     return rc;
    1974 }
    1975 # endif
     1653 * @param   pDevIns      The device instance.
     1654 * @param   pLsiReq      The request state.
     1655 * @param   fCopyToGuest Flag whether to update the guest buffer if necessary.
     1656 *                       Nothing is copied if false even if the request was a read.
     1657 */
     1658static void lsilogicIoBufFree(PPDMDEVINS pDevIns, PLSILOGICREQ pLsiReq,
     1659                              bool fCopyToGuest)
     1660{
     1661    uint8_t uTxDir = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_GET(pLsiReq->GuestRequest.SCSIIO.u32Control);
     1662
     1663    AssertMsg(   uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE
     1664              || uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ,
     1665              ("Allocating I/O memory for a non I/O request is not allowed\n"));
     1666
     1667    if (   uTxDir == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ
     1668        && fCopyToGuest)
     1669        lsilogicCopyToSgBuf(pDevIns, pLsiReq, pLsiReq->SegIoBuf.cbSeg);
     1670
     1671    lsilogicReqMemFree(pLsiReq);
     1672    pLsiReq->SegIoBuf.pvSeg = NULL;
     1673    pLsiReq->SegIoBuf.cbSeg = 0;
     1674}
    19761675
    19771676# ifdef LOG_ENABLED
     
    20601759 * @returns VBox status code.
    20611760 * @param   pThis       Pointer to the LsiLogic device state.
    2062  * @param   pTaskState  Pointer to the task state data.
    2063  */
    2064 static int lsilogicR3ProcessSCSIIORequest(PLSILOGICSCSI pThis, PLSILOGICTASKSTATE pTaskState)
     1761 * @param   pLsiReq  Pointer to the task state data.
     1762 */
     1763static int lsilogicR3ProcessSCSIIORequest(PLSILOGICSCSI pThis, PLSILOGICREQ pLsiReq)
    20651764{
    20661765    int rc = VINF_SUCCESS;
    20671766
    20681767# ifdef LOG_ENABLED
    2069     lsilogicR3DumpSCSIIORequest(&pTaskState->GuestRequest.SCSIIO);
     1768    lsilogicR3DumpSCSIIORequest(&pLsiReq->GuestRequest.SCSIIO);
    20701769# endif
    20711770
    2072     pTaskState->fBIOS = false;
    2073 
    2074     if (RT_LIKELY(   (pTaskState->GuestRequest.SCSIIO.u8TargetID < pThis->cDeviceStates)
    2075                   && (pTaskState->GuestRequest.SCSIIO.u8Bus == 0)))
     1771    pLsiReq->fBIOS = false;
     1772    pLsiReq->GCPhysSgStart = pLsiReq->GCPhysMessageFrameAddr + sizeof(MptSCSIIORequest);
     1773    pLsiReq->cChainOffset  = pLsiReq->GuestRequest.SCSIIO.u8ChainOffset;
     1774    if (pLsiReq->cChainOffset)
     1775        pLsiReq->cChainOffset = pLsiReq->cChainOffset * sizeof(uint32_t) - sizeof(MptSCSIIORequest);
     1776
     1777    if (RT_LIKELY(   (pLsiReq->GuestRequest.SCSIIO.u8TargetID < pThis->cDeviceStates)
     1778                  && (pLsiReq->GuestRequest.SCSIIO.u8Bus == 0)))
    20761779    {
    20771780        PLSILOGICDEVICE pTargetDevice;
    2078         pTargetDevice = &pThis->paDeviceStates[pTaskState->GuestRequest.SCSIIO.u8TargetID];
     1781        pTargetDevice = &pThis->paDeviceStates[pLsiReq->GuestRequest.SCSIIO.u8TargetID];
    20791782
    20801783        if (pTargetDevice->pDrvBase)
    20811784        {
    20821785
    2083             if (pTaskState->GuestRequest.SCSIIO.u32DataLength)
     1786            if (pLsiReq->GuestRequest.SCSIIO.u32DataLength)
    20841787            {
    2085                 uint32_t uChainOffset;
    2086 
    2087                 /* Create Scatter gather list. */
    2088                 uChainOffset = pTaskState->GuestRequest.SCSIIO.u8ChainOffset;
    2089 
    2090                 if (uChainOffset)
    2091                     uChainOffset = uChainOffset * sizeof(uint32_t) - sizeof(MptSCSIIORequest);
    2092 
    2093                 rc = lsilogicR3ScatterGatherListCreate(pThis, pTaskState,
    2094                                                        pTaskState->GCPhysMessageFrameAddr + sizeof(MptSCSIIORequest),
    2095                                                        uChainOffset);
    2096                 AssertRC(rc);
     1788
     1789                rc = lsilogicIoBufAllocate(pThis->CTX_SUFF(pDevIns), pLsiReq,
     1790                                                           pLsiReq->GuestRequest.SCSIIO.u32DataLength);
     1791                AssertRC(rc); /** @todo: Insufficient resources error. */
     1792            }
     1793
     1794            /* Setup the SCSI request. */
     1795            pLsiReq->pTargetDevice                        = pTargetDevice;
     1796            pLsiReq->PDMScsiRequest.uLogicalUnit          = pLsiReq->GuestRequest.SCSIIO.au8LUN[1];
     1797
     1798            uint8_t uDataDirection = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_GET(pLsiReq->GuestRequest.SCSIIO.u32Control);
     1799
     1800            if (uDataDirection == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE)
     1801                pLsiReq->PDMScsiRequest.uDataDirection    = PDMSCSIREQUESTTXDIR_NONE;
     1802            else if (uDataDirection == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE)
     1803                pLsiReq->PDMScsiRequest.uDataDirection    = PDMSCSIREQUESTTXDIR_TO_DEVICE;
     1804            else if (uDataDirection == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ)
     1805                pLsiReq->PDMScsiRequest.uDataDirection    = PDMSCSIREQUESTTXDIR_FROM_DEVICE;
     1806
     1807            pLsiReq->PDMScsiRequest.cbCDB                 = pLsiReq->GuestRequest.SCSIIO.u8CDBLength;
     1808            pLsiReq->PDMScsiRequest.pbCDB                 = pLsiReq->GuestRequest.SCSIIO.au8CDB;
     1809            pLsiReq->PDMScsiRequest.cbScatterGather       = pLsiReq->GuestRequest.SCSIIO.u32DataLength;
     1810            if (pLsiReq->PDMScsiRequest.cbScatterGather)
     1811            {
     1812                pLsiReq->PDMScsiRequest.cScatterGatherEntries = 1;
     1813                pLsiReq->PDMScsiRequest.paScatterGatherHead   = &pLsiReq->SegIoBuf;
    20971814            }
    20981815            else
    2099                 pTaskState->cSGListEntries = 0;
    2100 
    2101 # if 0
    2102             /* Map sense buffer. */
    2103             rc = lsilogicR3MapGCSenseBufferIntoR3(pThis, pTaskState);
    2104             AssertRC(rc);
    2105 # endif
    2106 
    2107             /* Setup the SCSI request. */
    2108             pTaskState->pTargetDevice                        = pTargetDevice;
    2109             pTaskState->PDMScsiRequest.uLogicalUnit          = pTaskState->GuestRequest.SCSIIO.au8LUN[1];
    2110 
    2111             uint8_t uDataDirection = MPT_SCSIIO_REQUEST_CONTROL_TXDIR_GET(pTaskState->GuestRequest.SCSIIO.u32Control);
    2112 
    2113             if (uDataDirection == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_NONE)
    2114                 pTaskState->PDMScsiRequest.uDataDirection    = PDMSCSIREQUESTTXDIR_NONE;
    2115             else if (uDataDirection == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_WRITE)
    2116                 pTaskState->PDMScsiRequest.uDataDirection    = PDMSCSIREQUESTTXDIR_TO_DEVICE;
    2117             else if (uDataDirection == MPT_SCSIIO_REQUEST_CONTROL_TXDIR_READ)
    2118                 pTaskState->PDMScsiRequest.uDataDirection    = PDMSCSIREQUESTTXDIR_FROM_DEVICE;
    2119 
    2120             pTaskState->PDMScsiRequest.cbCDB                 = pTaskState->GuestRequest.SCSIIO.u8CDBLength;
    2121             pTaskState->PDMScsiRequest.pbCDB                 = pTaskState->GuestRequest.SCSIIO.au8CDB;
    2122             pTaskState->PDMScsiRequest.cbScatterGather       = pTaskState->GuestRequest.SCSIIO.u32DataLength;
    2123             pTaskState->PDMScsiRequest.cScatterGatherEntries = pTaskState->cSGListEntries;
    2124             pTaskState->PDMScsiRequest.paScatterGatherHead   = pTaskState->pSGListHead;
    2125             pTaskState->PDMScsiRequest.cbSenseBuffer         = sizeof(pTaskState->abSenseBuffer);
    2126             memset(pTaskState->abSenseBuffer, 0, pTaskState->PDMScsiRequest.cbSenseBuffer);
    2127             pTaskState->PDMScsiRequest.pbSenseBuffer         = pTaskState->abSenseBuffer;
    2128             pTaskState->PDMScsiRequest.pvUser                = pTaskState;
     1816            {
     1817                pLsiReq->PDMScsiRequest.cScatterGatherEntries = 0;
     1818                pLsiReq->PDMScsiRequest.paScatterGatherHead   = NULL;
     1819            }
     1820            pLsiReq->PDMScsiRequest.cbSenseBuffer         = sizeof(pLsiReq->abSenseBuffer);
     1821            memset(pLsiReq->abSenseBuffer, 0, pLsiReq->PDMScsiRequest.cbSenseBuffer);
     1822            pLsiReq->PDMScsiRequest.pbSenseBuffer         = pLsiReq->abSenseBuffer;
     1823            pLsiReq->PDMScsiRequest.pvUser                = pLsiReq;
    21291824
    21301825            ASMAtomicIncU32(&pTargetDevice->cOutstandingRequests);
    2131             rc = pTargetDevice->pDrvSCSIConnector->pfnSCSIRequestSend(pTargetDevice->pDrvSCSIConnector, &pTaskState->PDMScsiRequest);
     1826            rc = pTargetDevice->pDrvSCSIConnector->pfnSCSIRequestSend(pTargetDevice->pDrvSCSIConnector, &pLsiReq->PDMScsiRequest);
    21321827            AssertMsgRC(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc));
    21331828            return VINF_SUCCESS;
     
    21361831        {
    21371832            /* Device is not present report SCSI selection timeout. */
    2138             pTaskState->IOCReply.SCSIIOError.u16IOCStatus = MPT_SCSI_IO_ERROR_IOCSTATUS_DEVICE_NOT_THERE;
     1833            pLsiReq->IOCReply.SCSIIOError.u16IOCStatus = MPT_SCSI_IO_ERROR_IOCSTATUS_DEVICE_NOT_THERE;
    21391834        }
    21401835    }
     
    21421837    {
    21431838        /* Report out of bounds target ID or bus. */
    2144         if (pTaskState->GuestRequest.SCSIIO.u8Bus != 0)
    2145             pTaskState->IOCReply.SCSIIOError.u16IOCStatus = MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_BUS;
     1839        if (pLsiReq->GuestRequest.SCSIIO.u8Bus != 0)
     1840            pLsiReq->IOCReply.SCSIIOError.u16IOCStatus = MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_BUS;
    21461841        else
    2147             pTaskState->IOCReply.SCSIIOError.u16IOCStatus = MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_TARGETID;
     1842            pLsiReq->IOCReply.SCSIIOError.u16IOCStatus = MPT_SCSI_IO_ERROR_IOCSTATUS_INVALID_TARGETID;
    21481843    }
    21491844
     
    21531848    {
    21541849        LogRel(("LsiLogic#%d: %d/%d (Bus/Target) doesn't exist\n", pThis->CTX_SUFF(pDevIns)->iInstance,
    2155                 pTaskState->GuestRequest.SCSIIO.u8TargetID, pTaskState->GuestRequest.SCSIIO.u8Bus));
     1850                pLsiReq->GuestRequest.SCSIIO.u8TargetID, pLsiReq->GuestRequest.SCSIIO.u8Bus));
    21561851        /* Log the CDB too  */
    21571852        LogRel(("LsiLogic#%d: Guest issued CDB {%#x",
    2158                 pThis->CTX_SUFF(pDevIns)->iInstance, pTaskState->GuestRequest.SCSIIO.au8CDB[0]));
    2159         for (unsigned i = 1; i < pTaskState->GuestRequest.SCSIIO.u8CDBLength; i++)
    2160             LogRel((", %#x", pTaskState->GuestRequest.SCSIIO.au8CDB[i]));
     1853                pThis->CTX_SUFF(pDevIns)->iInstance, pLsiReq->GuestRequest.SCSIIO.au8CDB[0]));
     1854        for (unsigned i = 1; i < pLsiReq->GuestRequest.SCSIIO.u8CDBLength; i++)
     1855            LogRel((", %#x", pLsiReq->GuestRequest.SCSIIO.au8CDB[i]));
    21611856        LogRel(("}\n"));
    21621857    }
    21631858
    21641859    /* The rest is equal to both errors. */
    2165     pTaskState->IOCReply.SCSIIOError.u8TargetID          = pTaskState->GuestRequest.SCSIIO.u8TargetID;
    2166     pTaskState->IOCReply.SCSIIOError.u8Bus               = pTaskState->GuestRequest.SCSIIO.u8Bus;
    2167     pTaskState->IOCReply.SCSIIOError.u8MessageLength     = sizeof(MptSCSIIOErrorReply) / 4;
    2168     pTaskState->IOCReply.SCSIIOError.u8Function          = pTaskState->GuestRequest.SCSIIO.u8Function;
    2169     pTaskState->IOCReply.SCSIIOError.u8CDBLength         = pTaskState->GuestRequest.SCSIIO.u8CDBLength;
    2170     pTaskState->IOCReply.SCSIIOError.u8SenseBufferLength = pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength;
    2171     pTaskState->IOCReply.SCSIIOError.u32MessageContext   = pTaskState->GuestRequest.SCSIIO.u32MessageContext;
    2172     pTaskState->IOCReply.SCSIIOError.u8SCSIStatus        = SCSI_STATUS_OK;
    2173     pTaskState->IOCReply.SCSIIOError.u8SCSIState         = MPT_SCSI_IO_ERROR_SCSI_STATE_TERMINATED;
    2174     pTaskState->IOCReply.SCSIIOError.u32IOCLogInfo       = 0;
    2175     pTaskState->IOCReply.SCSIIOError.u32TransferCount    = 0;
    2176     pTaskState->IOCReply.SCSIIOError.u32SenseCount       = 0;
    2177     pTaskState->IOCReply.SCSIIOError.u32ResponseInfo     = 0;
    2178 
    2179     lsilogicFinishAddressReply(pThis, &pTaskState->IOCReply, false);
    2180     RTMemCacheFree(pThis->hTaskCache, pTaskState);
     1860    pLsiReq->IOCReply.SCSIIOError.u8TargetID          = pLsiReq->GuestRequest.SCSIIO.u8TargetID;
     1861    pLsiReq->IOCReply.SCSIIOError.u8Bus               = pLsiReq->GuestRequest.SCSIIO.u8Bus;
     1862    pLsiReq->IOCReply.SCSIIOError.u8MessageLength     = sizeof(MptSCSIIOErrorReply) / 4;
     1863    pLsiReq->IOCReply.SCSIIOError.u8Function          = pLsiReq->GuestRequest.SCSIIO.u8Function;
     1864    pLsiReq->IOCReply.SCSIIOError.u8CDBLength         = pLsiReq->GuestRequest.SCSIIO.u8CDBLength;
     1865    pLsiReq->IOCReply.SCSIIOError.u8SenseBufferLength = pLsiReq->GuestRequest.SCSIIO.u8SenseBufferLength;
     1866    pLsiReq->IOCReply.SCSIIOError.u32MessageContext   = pLsiReq->GuestRequest.SCSIIO.u32MessageContext;
     1867    pLsiReq->IOCReply.SCSIIOError.u8SCSIStatus        = SCSI_STATUS_OK;
     1868    pLsiReq->IOCReply.SCSIIOError.u8SCSIState         = MPT_SCSI_IO_ERROR_SCSI_STATE_TERMINATED;
     1869    pLsiReq->IOCReply.SCSIIOError.u32IOCLogInfo       = 0;
     1870    pLsiReq->IOCReply.SCSIIOError.u32TransferCount    = 0;
     1871    pLsiReq->IOCReply.SCSIIOError.u32SenseCount       = 0;
     1872    pLsiReq->IOCReply.SCSIIOError.u32ResponseInfo     = 0;
     1873
     1874    lsilogicFinishAddressReply(pThis, &pLsiReq->IOCReply, false);
     1875    RTMemCacheFree(pThis->hTaskCache, pLsiReq);
    21811876
    21821877    return rc;
     
    21901885                                                              int rcCompletion, bool fRedo, int rcReq)
    21911886{
    2192     PLSILOGICTASKSTATE pTaskState      = (PLSILOGICTASKSTATE)pSCSIRequest->pvUser;
    2193     PLSILOGICDEVICE    pLsiLogicDevice = pTaskState->pTargetDevice;
     1887    PLSILOGICREQ pLsiReq      = (PLSILOGICREQ)pSCSIRequest->pvUser;
     1888    PLSILOGICDEVICE    pLsiLogicDevice = pLsiReq->pTargetDevice;
    21941889    PLSILOGICSCSI      pThis       = pLsiLogicDevice->CTX_SUFF(pLsiLogic);
    21951890
     
    21981893    if (fRedo)
    21991894    {
    2200         if (!pTaskState->fBIOS && pTaskState->PDMScsiRequest.cbScatterGather)
    2201             lsilogicR3ScatterGatherListDestroy(pThis, pTaskState);
     1895        if (!pLsiReq->fBIOS && pLsiReq->PDMScsiRequest.cbScatterGather)
     1896            lsilogicIoBufFree(pThis->CTX_SUFF(pDevIns), pLsiReq, false /* fCopyToGuest */);
    22021897
    22031898        /* Add to the list. */
    22041899        do
    22051900        {
    2206             pTaskState->pRedoNext = ASMAtomicReadPtrT(&pThis->pTasksRedoHead, PLSILOGICTASKSTATE);
    2207         } while (!ASMAtomicCmpXchgPtr(&pThis->pTasksRedoHead, pTaskState, pTaskState->pRedoNext));
     1901            pLsiReq->pRedoNext = ASMAtomicReadPtrT(&pThis->pTasksRedoHead, PLSILOGICREQ);
     1902        } while (!ASMAtomicCmpXchgPtr(&pThis->pTasksRedoHead, pLsiReq, pLsiReq->pRedoNext));
    22081903
    22091904        /* Suspend the VM if not done already. */
     
    22131908    else
    22141909    {
    2215         if (RT_UNLIKELY(pTaskState->fBIOS))
     1910        if (RT_UNLIKELY(pLsiReq->fBIOS))
    22161911        {
    22171912            int rc = vboxscsiRequestFinished(&pThis->VBoxSCSI, pSCSIRequest, rcCompletion);
     
    22201915        else
    22211916        {
    2222 # if 0
    2223             lsilogicFreeGCSenseBuffer(pThis, pTaskState);
    2224 # else
    22251917            RTGCPHYS GCPhysAddrSenseBuffer;
    22261918
    2227             GCPhysAddrSenseBuffer = pTaskState->GuestRequest.SCSIIO.u32SenseBufferLowAddress;
     1919            GCPhysAddrSenseBuffer = pLsiReq->GuestRequest.SCSIIO.u32SenseBufferLowAddress;
    22281920            GCPhysAddrSenseBuffer |= ((uint64_t)pThis->u32SenseBufferHighAddr << 32);
    22291921
    22301922            /* Copy the sense buffer over. */
    2231             PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), GCPhysAddrSenseBuffer, pTaskState->abSenseBuffer,
    2232                                   RT_UNLIKELY(  pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength
    2233                                               < pTaskState->PDMScsiRequest.cbSenseBuffer)
    2234                                   ? pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength
    2235                                   : pTaskState->PDMScsiRequest.cbSenseBuffer);
    2236 # endif
    2237             if (pTaskState->PDMScsiRequest.cbScatterGather)
    2238                 lsilogicR3ScatterGatherListDestroy(pThis, pTaskState);
     1923            PDMDevHlpPCIPhysWrite(pThis->CTX_SUFF(pDevIns), GCPhysAddrSenseBuffer, pLsiReq->abSenseBuffer,
     1924                                  RT_UNLIKELY(  pLsiReq->GuestRequest.SCSIIO.u8SenseBufferLength
     1925                                              < pLsiReq->PDMScsiRequest.cbSenseBuffer)
     1926                                  ? pLsiReq->GuestRequest.SCSIIO.u8SenseBufferLength
     1927                                  : pLsiReq->PDMScsiRequest.cbSenseBuffer);
     1928
     1929            if (pLsiReq->PDMScsiRequest.cbScatterGather)
     1930                lsilogicIoBufFree(pThis->CTX_SUFF(pDevIns), pLsiReq, true /* fCopyToGuest */);
    22391931
    22401932
    22411933            if (RT_LIKELY(rcCompletion == SCSI_STATUS_OK))
    2242                 lsilogicR3FinishContextReply(pThis, pTaskState->GuestRequest.SCSIIO.u32MessageContext);
     1934                lsilogicR3FinishContextReply(pThis, pLsiReq->GuestRequest.SCSIIO.u32MessageContext);
    22431935            else
    22441936            {
    22451937                /* The SCSI target encountered an error during processing post a reply. */
    2246                 memset(&pTaskState->IOCReply, 0, sizeof(MptReplyUnion));
    2247                 pTaskState->IOCReply.SCSIIOError.u8TargetID          = pTaskState->GuestRequest.SCSIIO.u8TargetID;
    2248                 pTaskState->IOCReply.SCSIIOError.u8Bus               = pTaskState->GuestRequest.SCSIIO.u8Bus;
    2249                 pTaskState->IOCReply.SCSIIOError.u8MessageLength     = 8;
    2250                 pTaskState->IOCReply.SCSIIOError.u8Function          = pTaskState->GuestRequest.SCSIIO.u8Function;
    2251                 pTaskState->IOCReply.SCSIIOError.u8CDBLength         = pTaskState->GuestRequest.SCSIIO.u8CDBLength;
    2252                 pTaskState->IOCReply.SCSIIOError.u8SenseBufferLength = pTaskState->GuestRequest.SCSIIO.u8SenseBufferLength;
    2253                 pTaskState->IOCReply.SCSIIOError.u8MessageFlags      = pTaskState->GuestRequest.SCSIIO.u8MessageFlags;
    2254                 pTaskState->IOCReply.SCSIIOError.u32MessageContext   = pTaskState->GuestRequest.SCSIIO.u32MessageContext;
    2255                 pTaskState->IOCReply.SCSIIOError.u8SCSIStatus        = rcCompletion;
    2256                 pTaskState->IOCReply.SCSIIOError.u8SCSIState         = MPT_SCSI_IO_ERROR_SCSI_STATE_AUTOSENSE_VALID;
    2257                 pTaskState->IOCReply.SCSIIOError.u16IOCStatus        = 0;
    2258                 pTaskState->IOCReply.SCSIIOError.u32IOCLogInfo       = 0;
    2259                 pTaskState->IOCReply.SCSIIOError.u32TransferCount    = 0;
    2260                 pTaskState->IOCReply.SCSIIOError.u32SenseCount       = sizeof(pTaskState->abSenseBuffer);
    2261                 pTaskState->IOCReply.SCSIIOError.u32ResponseInfo     = 0;
    2262 
    2263                 lsilogicFinishAddressReply(pThis, &pTaskState->IOCReply, true);
     1938                memset(&pLsiReq->IOCReply, 0, sizeof(MptReplyUnion));
     1939                pLsiReq->IOCReply.SCSIIOError.u8TargetID          = pLsiReq->GuestRequest.SCSIIO.u8TargetID;
     1940                pLsiReq->IOCReply.SCSIIOError.u8Bus               = pLsiReq->GuestRequest.SCSIIO.u8Bus;
     1941                pLsiReq->IOCReply.SCSIIOError.u8MessageLength     = 8;
     1942                pLsiReq->IOCReply.SCSIIOError.u8Function          = pLsiReq->GuestRequest.SCSIIO.u8Function;
     1943                pLsiReq->IOCReply.SCSIIOError.u8CDBLength         = pLsiReq->GuestRequest.SCSIIO.u8CDBLength;
     1944                pLsiReq->IOCReply.SCSIIOError.u8SenseBufferLength = pLsiReq->GuestRequest.SCSIIO.u8SenseBufferLength;
     1945                pLsiReq->IOCReply.SCSIIOError.u8MessageFlags      = pLsiReq->GuestRequest.SCSIIO.u8MessageFlags;
     1946                pLsiReq->IOCReply.SCSIIOError.u32MessageContext   = pLsiReq->GuestRequest.SCSIIO.u32MessageContext;
     1947                pLsiReq->IOCReply.SCSIIOError.u8SCSIStatus        = rcCompletion;
     1948                pLsiReq->IOCReply.SCSIIOError.u8SCSIState         = MPT_SCSI_IO_ERROR_SCSI_STATE_AUTOSENSE_VALID;
     1949                pLsiReq->IOCReply.SCSIIOError.u16IOCStatus        = 0;
     1950                pLsiReq->IOCReply.SCSIIOError.u32IOCLogInfo       = 0;
     1951                pLsiReq->IOCReply.SCSIIOError.u32TransferCount    = 0;
     1952                pLsiReq->IOCReply.SCSIIOError.u32SenseCount       = sizeof(pLsiReq->abSenseBuffer);
     1953                pLsiReq->IOCReply.SCSIIOError.u32ResponseInfo     = 0;
     1954
     1955                lsilogicFinishAddressReply(pThis, &pLsiReq->IOCReply, true);
    22641956            }
    22651957        }
    22661958
    2267         RTMemCacheFree(pThis->hTaskCache, pTaskState);
     1959        RTMemCacheFree(pThis->hTaskCache, pLsiReq);
    22681960    }
    22691961
     
    36433335                                                                      (u32RequestMessageFrameDesc & ~0x07));
    36443336
    3645         PLSILOGICTASKSTATE pTaskState;
     3337        PLSILOGICREQ pLsiReq;
    36463338
    36473339        /* Get new task state. */
    3648         rc = RTMemCacheAllocEx(pThis->hTaskCache, (void **)&pTaskState);
     3340        rc = RTMemCacheAllocEx(pThis->hTaskCache, (void **)&pLsiReq);
    36493341        AssertRC(rc);
    36503342
    3651         pTaskState->GCPhysMessageFrameAddr = GCPhysMessageFrameAddr;
     3343        pLsiReq->GCPhysMessageFrameAddr = GCPhysMessageFrameAddr;
    36523344
    36533345        /* Read the message header from the guest first. */
    3654         PDMDevHlpPhysRead(pDevIns, GCPhysMessageFrameAddr, &pTaskState->GuestRequest, sizeof(MptMessageHdr));
     3346        PDMDevHlpPhysRead(pDevIns, GCPhysMessageFrameAddr, &pLsiReq->GuestRequest, sizeof(MptMessageHdr));
    36553347
    36563348        /* Determine the size of the request. */
    36573349        uint32_t cbRequest = 0;
    36583350
    3659         switch (pTaskState->GuestRequest.Header.u8Function)
     3351        switch (pLsiReq->GuestRequest.Header.u8Function)
    36603352        {
    36613353            case MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST:
     
    36943386                break;
    36953387            default:
    3696                 AssertMsgFailed(("Unknown function issued %u\n", pTaskState->GuestRequest.Header.u8Function));
     3388                AssertMsgFailed(("Unknown function issued %u\n", pLsiReq->GuestRequest.Header.u8Function));
    36973389                lsilogicSetIOCFaultCode(pThis, LSILOGIC_IOCSTATUS_INVALID_FUNCTION);
    36983390        }
     
    37013393        {
    37023394            /* Read the complete message frame from guest memory now. */
    3703             PDMDevHlpPhysRead(pDevIns, GCPhysMessageFrameAddr, &pTaskState->GuestRequest, cbRequest);
     3395            PDMDevHlpPhysRead(pDevIns, GCPhysMessageFrameAddr, &pLsiReq->GuestRequest, cbRequest);
    37043396
    37053397            /* Handle SCSI I/O requests now. */
    3706             if (pTaskState->GuestRequest.Header.u8Function == MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST)
     3398            if (pLsiReq->GuestRequest.Header.u8Function == MPT_MESSAGE_HDR_FUNCTION_SCSI_IO_REQUEST)
    37073399            {
    3708                rc = lsilogicR3ProcessSCSIIORequest(pThis, pTaskState);
     3400               rc = lsilogicR3ProcessSCSIIORequest(pThis, pLsiReq);
    37093401               AssertRC(rc);
    37103402            }
     
    37123404            {
    37133405                MptReplyUnion Reply;
    3714                 rc = lsilogicR3ProcessMessageRequest(pThis, &pTaskState->GuestRequest.Header, &Reply);
     3406                rc = lsilogicR3ProcessMessageRequest(pThis, &pLsiReq->GuestRequest.Header, &Reply);
    37153407                AssertRC(rc);
    3716                 RTMemCacheFree(pThis->hTaskCache, pTaskState);
     3408                RTMemCacheFree(pThis->hTaskCache, pLsiReq);
    37173409            }
    37183410
     
    37803472{
    37813473    int rc;
    3782     PLSILOGICTASKSTATE pTaskState;
     3474    PLSILOGICREQ pLsiReq;
    37833475    uint32_t           uTargetDevice;
    37843476
    3785     rc = RTMemCacheAllocEx(pThis->hTaskCache, (void **)&pTaskState);
     3477    rc = RTMemCacheAllocEx(pThis->hTaskCache, (void **)&pLsiReq);
    37863478    AssertMsgRCReturn(rc, ("Getting task from cache failed rc=%Rrc\n", rc), rc);
    37873479
    3788     pTaskState->fBIOS = true;
    3789 
    3790     rc = vboxscsiSetupRequest(&pThis->VBoxSCSI, &pTaskState->PDMScsiRequest, &uTargetDevice);
     3480    pLsiReq->fBIOS = true;
     3481
     3482    rc = vboxscsiSetupRequest(&pThis->VBoxSCSI, &pLsiReq->PDMScsiRequest, &uTargetDevice);
    37913483    AssertMsgRCReturn(rc, ("Setting up SCSI request failed rc=%Rrc\n", rc), rc);
    37923484
    3793     pTaskState->PDMScsiRequest.pvUser = pTaskState;
     3485    pLsiReq->PDMScsiRequest.pvUser = pLsiReq;
    37943486
    37953487    if (uTargetDevice < pThis->cDeviceStates)
    37963488    {
    3797         pTaskState->pTargetDevice = &pThis->paDeviceStates[uTargetDevice];
    3798 
    3799         if (pTaskState->pTargetDevice->pDrvBase)
    3800         {
    3801             ASMAtomicIncU32(&pTaskState->pTargetDevice->cOutstandingRequests);
    3802 
    3803             rc = pTaskState->pTargetDevice->pDrvSCSIConnector->pfnSCSIRequestSend(pTaskState->pTargetDevice->pDrvSCSIConnector,
    3804                                                                                   &pTaskState->PDMScsiRequest);
     3489        pLsiReq->pTargetDevice = &pThis->paDeviceStates[uTargetDevice];
     3490
     3491        if (pLsiReq->pTargetDevice->pDrvBase)
     3492        {
     3493            ASMAtomicIncU32(&pLsiReq->pTargetDevice->cOutstandingRequests);
     3494
     3495            rc = pLsiReq->pTargetDevice->pDrvSCSIConnector->pfnSCSIRequestSend(pLsiReq->pTargetDevice->pDrvSCSIConnector,
     3496                                                                                  &pLsiReq->PDMScsiRequest);
    38053497            AssertMsgRCReturn(rc, ("Sending request to SCSI layer failed rc=%Rrc\n", rc), rc);
    38063498            return VINF_SUCCESS;
     
    38093501
    38103502    /* Device is not present. */
    3811     AssertMsg(pTaskState->PDMScsiRequest.pbCDB[0] == SCSI_INQUIRY,
     3503    AssertMsg(pLsiReq->PDMScsiRequest.pbCDB[0] == SCSI_INQUIRY,
    38123504                ("Device is not present but command is not inquiry\n"));
    38133505
     
    38203512    memcpy(pThis->VBoxSCSI.pbBuf, &ScsiInquiryData, 5);
    38213513
    3822     rc = vboxscsiRequestFinished(&pThis->VBoxSCSI, &pTaskState->PDMScsiRequest, SCSI_STATUS_OK);
     3514    rc = vboxscsiRequestFinished(&pThis->VBoxSCSI, &pLsiReq->PDMScsiRequest, SCSI_STATUS_OK);
    38233515    AssertMsgRCReturn(rc, ("Finishing BIOS SCSI request failed rc=%Rrc\n", rc), rc);
    38243516
    3825     RTMemCacheFree(pThis->hTaskCache, pTaskState);
     3517    RTMemCacheFree(pThis->hTaskCache, pLsiReq);
    38263518    return rc;
    38273519}
     
    48244516             * lsilogicRegisterWrite.
    48254517             */
    4826             PLSILOGICTASKSTATE pTaskState = pThis->pTasksRedoHead;
     4518            PLSILOGICREQ pLsiReq = pThis->pTasksRedoHead;
    48274519
    48284520            pThis->pTasksRedoHead = NULL;
    48294521
    4830             while (pTaskState)
     4522            while (pLsiReq)
    48314523            {
    4832                 PLSILOGICTASKSTATE pFree;
    4833 
    4834                 if (!pTaskState->fBIOS)
     4524                PLSILOGICREQ pFree;
     4525
     4526                if (!pLsiReq->fBIOS)
    48354527                {
    48364528                    /* Write only the lower 32bit part of the address. */
    48374529                    ASMAtomicWriteU32(&pThis->CTX_SUFF(pRequestQueueBase)[pThis->uRequestQueueNextEntryFreeWrite],
    4838                                       pTaskState->GCPhysMessageFrameAddr & UINT32_C(0xffffffff));
     4530                                      pLsiReq->GCPhysMessageFrameAddr & UINT32_C(0xffffffff));
    48394531
    48404532                    pThis->uRequestQueueNextEntryFreeWrite++;
     
    48454537                else
    48464538                {
    4847                     AssertMsg(!pTaskState->pRedoNext, ("Only one BIOS task can be active!\n"));
    4848                     vboxscsiSetRequestRedo(&pThis->VBoxSCSI, &pTaskState->PDMScsiRequest);
     4539                    AssertMsg(!pLsiReq->pRedoNext, ("Only one BIOS task can be active!\n"));
     4540                    vboxscsiSetRequestRedo(&pThis->VBoxSCSI, &pLsiReq->PDMScsiRequest);
    48494541                }
    48504542
    4851                 pFree = pTaskState;
    4852                 pTaskState = pTaskState->pRedoNext;
     4543                pFree = pLsiReq;
     4544                pLsiReq = pLsiReq->pRedoNext;
    48534545
    48544546                RTMemCacheFree(pThis->hTaskCache, pFree);
     
    52664958     * Allocate task cache.
    52674959     */
    5268     rc = RTMemCacheCreate(&pThis->hTaskCache, sizeof(LSILOGICTASKSTATE), 0, UINT32_MAX,
    5269                           lsilogicR3TaskStateCtor, lsilogicR3TaskStateDtor, NULL, 0);
     4960    rc = RTMemCacheCreate(&pThis->hTaskCache, sizeof(LSILOGICREQ), 0, UINT32_MAX,
     4961                          NULL, NULL, NULL, 0);
    52704962    if (RT_FAILURE(rc))
    52714963        return PDMDEV_SET_ERROR(pDevIns, rc, N_("Cannot create task cache"));
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