third_party/virtualbox/src/VBox/Devices/Network/DevE1000.cpp
/**
 * Write handler for Receive Descriptor Tail register.
 *
 * @remarks Write into RDT forces switch to HC and signal to
 *          e1kR3NetworkDown_WaitReceiveAvail().
 *
 * @returns VBox status code.
 *
 * @param   pThis       The device state structure.
 * @param   offset      Register offset in memory-mapped frame.
 * @param   index       Register index in register array.
 * @param   value       The value to store.
 * @param   mask        Used to implement partial writes (8 and 16-bit).
 * @thread  EMT
 */
Write handler for Receive Descriptor Tail register.
@remarks Write into RDT forces switch to HC and signal to
e1kR3NetworkDown_WaitReceiveAvail().

@returns VBox status code.

@param   pThis       The device state structure.
@param   offset      Register offset in memory-mapped frame.
@param   index       Register index in register array.
@param   value       The value to store.
@param   mask        Used to implement partial writes (8 and 16-bit).
@thread  EMT
Write handler for Receive Descriptor Tail register . @remarks Write into RDT forces switch to HC and signal to e1kR3NetworkDown_WaitReceiveAvail () . @returns VBox status code . @param pThis The device state structure . @param offset Register offset in memory - mapped frame . @param index Register index in register array . @param value The value to store . @param mask Used to implement partial writes ( 8 and 16 - bit ) . @thread EMT
static int e1kRegWriteRDT(PE1KSTATE pThis, uint32_t offset, uint32_t index, uint32_t value)
{
#ifndef IN_RING3
#endif
    int rc = e1kCsRxEnter(pThis, VINF_IOM_R3_MMIO_WRITE);
    if (RT_LIKELY(rc == VINF_SUCCESS))
    {
        E1kLog(("%s e1kRegWriteRDT\n",  pThis->szPrf));
        if (value == RDH)
        {
            if (RDH == 0)
                value = (RDLEN / sizeof(E1KRXDESC)) - 1;
            else
                value = RDH - 1;
        }
        rc = e1kRegWriteDefault(pThis, offset, index, value);
#ifdef E1K_WITH_RXD_CACHE
        if (e1kRxDIsCacheEmpty(pThis) && (RCTL & RCTL_EN))
            e1kRxDPrefetch(pThis);
#endif 
        e1kCsRxLeave(pThis);
        if (RT_SUCCESS(rc))
        {
#ifdef IN_RING3
            e1kWakeupReceive(pThis->CTX_SUFF(pDevIns));
#else
            PPDMQUEUEITEMCORE pItem = PDMQueueAlloc(pThis->CTX_SUFF(pCanRxQueue));
            if (pItem)
                PDMQueueInsert(pThis->CTX_SUFF(pCanRxQueue), pItem);
#endif
        }
    }
    return rc;
}
static int e1kRegWriteRDT ( PE1KSTATE pThis , uint32_t offset , uint32_t index , uint32_t value ) { #ifndef IN_RING3 #endif int rc = e1kCsRxEnter ( pThis , VINF_IOM_R3_MMIO_WRITE ) ; if ( RT_LIKELY ( rc == VINF_SUCCESS ) ) { E1kLog ( ( " \n " , pThis -> szPrf ) ) ; if ( value == RDH ) { if ( RDH == 0 ) value = ( RDLEN / sizeof ( E1KRXDESC ) ) - 1 ; else value = RDH - 1 ; } rc = e1kRegWriteDefault ( pThis , offset , index , value ) ; #ifdef E1K_WITH_RXD_CACHE if ( e1kRxDIsCacheEmpty ( pThis ) && ( RCTL & RCTL_EN ) ) e1kRxDPrefetch ( pThis ) ; #endif e1kCsRxLeave ( pThis ) ; if ( RT_SUCCESS ( rc ) ) { #ifdef IN_RING3 e1kWakeupReceive ( pThis -> CTX_SUFF ( pDevIns ) ) ; #else PPDMQUEUEITEMCORE pItem = PDMQueueAlloc ( pThis -> CTX_SUFF ( pCanRxQueue ) ) ; if ( pItem ) PDMQueueInsert ( pThis -> CTX_SUFF ( pCanRxQueue ) , pItem ) ; #endif } } return rc ; }
Write handler for Receive Descriptor Tail register.
Write handler for Receive Descriptor Tail register .
/* XXX */ //    return VINF_IOM_R3_MMIO_WRITE; /*
         * Some drivers advance RDT too far, so that it equals RDH. This
         * somehow manages to work with real hardware but not with this
         * emulated device. We can work with these drivers if we just
         * write 1 less when we see a driver writing RDT equal to RDH,
         * see @bugref{7346}.
         */ /*
         * We need to fetch descriptors now as RDT may go whole circle
         * before we attempt to store a received packet. For example,
         * Intel's DOS drivers use 2 (!) RX descriptors with the total ring
         * size being only 8 descriptors! Note that we fetch descriptors
         * only when the cache is empty to reduce the number of memory reads
         * in case of frequent RDT writes. Don't fetch anything when the
         * receiver is disabled either as RDH, RDT, RDLEN can be in some
         * messed up state.
         * Note that despite the cache may seem empty, meaning that there are
         * no more available descriptors in it, it may still be used by RX
         * thread which has not yet written the last descriptor back but has
         * temporarily released the RX lock in order to write the packet body
         * to descriptor's buffer. At this point we still going to do prefetch
         * but it won't actually fetch anything if there are no unused slots in
         * our "empty" cache (nRxDFetched==E1K_RXD_CACHE_SIZE). We must not
         * reset the cache here even if it appears empty. It will be reset at
         * a later point in e1kRxDGet().
         */ /* E1K_WITH_RXD_CACHE */ /** @todo bird: Use SUPSem* for this so we can signal it in ring-0 as well
 *        without requiring any context switches.  We should also check the
 *        wait condition before bothering to queue the item as we're currently
 *        queuing thousands of items per second here in a normal transmit
 *        scenario.  Expect performance changes when fixing this! */ /* Signal that we have more receive descriptors available. */