third_party/virtualbox/src/VBox/Devices/Network/DevE1000.cpp
/**
 * Check if the device can receive data now.
 * This must be called before the pfnRecieve() method is called.
 *
 * @returns Number of bytes the device can receive.
 * @param   pInterface      Pointer to the interface structure containing the called function pointer.
 * @thread  EMT
 */
Check if the device can receive data now.
This must be called before the pfnRecieve() method is called.

@returns Number of bytes the device can receive.
@param   pInterface      Pointer to the interface structure containing the called function pointer.
@thread  EMT
Check if the device can receive data now . This must be called before the pfnRecieve () method is called . @returns Number of bytes the device can receive . @param pInterface Pointer to the interface structure containing the called function pointer . @thread EMT
static int e1kCanReceive(PE1KSTATE pThis)
{
#ifndef E1K_WITH_RXD_CACHE
    size_t cb;
    if (RT_UNLIKELY(e1kCsRxEnter(pThis, VERR_SEM_BUSY) != VINF_SUCCESS))
        return VERR_NET_NO_BUFFER_SPACE;
    if (RT_UNLIKELY(RDLEN == sizeof(E1KRXDESC)))
    {
        E1KRXDESC desc;
        PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), e1kDescAddr(RDBAH, RDBAL, RDH),
                          &desc, sizeof(desc));
        if (desc.status.fDD)
            cb = 0;
        else
            cb = pThis->u16RxBSize;
    }
    else if (RDH < RDT)
        cb = (RDT - RDH) * pThis->u16RxBSize;
    else if (RDH > RDT)
        cb = (RDLEN/sizeof(E1KRXDESC) - RDH + RDT) * pThis->u16RxBSize;
    else
    {
        cb = 0;
        E1kLogRel(("E1000: OUT of RX descriptors!\n"));
    }
    E1kLog2(("%s e1kCanReceive: at exit RDH=%d RDT=%d RDLEN=%d u16RxBSize=%d cb=%lu\n",
             pThis->szPrf, RDH, RDT, RDLEN, pThis->u16RxBSize, cb));
    e1kCsRxLeave(pThis);
    return cb > 0 ? VINF_SUCCESS : VERR_NET_NO_BUFFER_SPACE;
#else 
    int rc = VINF_SUCCESS;
    if (RT_UNLIKELY(e1kCsRxEnter(pThis, VERR_SEM_BUSY) != VINF_SUCCESS))
        return VERR_NET_NO_BUFFER_SPACE;
    if (RT_UNLIKELY(RDLEN == sizeof(E1KRXDESC)))
    {
        E1KRXDESC desc;
        PDMDevHlpPhysRead(pThis->CTX_SUFF(pDevIns), e1kDescAddr(RDBAH, RDBAL, RDH),
                          &desc, sizeof(desc));
        if (desc.status.fDD)
            rc = VERR_NET_NO_BUFFER_SPACE;
    }
    else if (e1kRxDIsCacheEmpty(pThis) && RDH == RDT)
    {
        rc = VERR_NET_NO_BUFFER_SPACE;
    }
    E1kLog2(("%s e1kCanReceive: at exit in_cache=%d RDH=%d RDT=%d RDLEN=%d"
             " u16RxBSize=%d rc=%Rrc\n", pThis->szPrf,
             e1kRxDInCache(pThis), RDH, RDT, RDLEN, pThis->u16RxBSize, rc));
    e1kCsRxLeave(pThis);
    return rc;
#endif 
}
static int e1kCanReceive ( PE1KSTATE pThis ) { #ifndef E1K_WITH_RXD_CACHE size_t cb ; if ( RT_UNLIKELY ( e1kCsRxEnter ( pThis , VERR_SEM_BUSY ) != VINF_SUCCESS ) ) return VERR_NET_NO_BUFFER_SPACE ; if ( RT_UNLIKELY ( RDLEN == sizeof ( E1KRXDESC ) ) ) { E1KRXDESC desc ; PDMDevHlpPhysRead ( pThis -> CTX_SUFF ( pDevIns ) , e1kDescAddr ( RDBAH , RDBAL , RDH ) , & desc , sizeof ( desc ) ) ; if ( desc . status . fDD ) cb = 0 ; else cb = pThis -> u16RxBSize ; } else if ( RDH < RDT ) cb = ( RDT - RDH ) * pThis -> u16RxBSize ; else if ( RDH > RDT ) cb = ( RDLEN / sizeof ( E1KRXDESC ) - RDH + RDT ) * pThis -> u16RxBSize ; else { cb = 0 ; E1kLogRel ( ( " \n " ) ) ; } E1kLog2 ( ( " \n " , pThis -> szPrf , RDH , RDT , RDLEN , pThis -> u16RxBSize , cb ) ) ; e1kCsRxLeave ( pThis ) ; return cb > 0 ? VINF_SUCCESS : VERR_NET_NO_BUFFER_SPACE ; #else int rc = VINF_SUCCESS ; if ( RT_UNLIKELY ( e1kCsRxEnter ( pThis , VERR_SEM_BUSY ) != VINF_SUCCESS ) ) return VERR_NET_NO_BUFFER_SPACE ; if ( RT_UNLIKELY ( RDLEN == sizeof ( E1KRXDESC ) ) ) { E1KRXDESC desc ; PDMDevHlpPhysRead ( pThis -> CTX_SUFF ( pDevIns ) , e1kDescAddr ( RDBAH , RDBAL , RDH ) , & desc , sizeof ( desc ) ) ; if ( desc . status . fDD ) rc = VERR_NET_NO_BUFFER_SPACE ; } else if ( e1kRxDIsCacheEmpty ( pThis ) && RDH == RDT ) { rc = VERR_NET_NO_BUFFER_SPACE ; } E1kLog2 ( ( " " " \n " , pThis -> szPrf , e1kRxDInCache ( pThis ) , RDH , RDT , RDLEN , pThis -> u16RxBSize , rc ) ) ; e1kCsRxLeave ( pThis ) ; return rc ; #endif }
Check if the device can receive data now.
Check if the device can receive data now .
/* E1K_WITH_RXD_CACHE */ /* Cache is empty, so is the RX ring. */ /* E1K_WITH_RXD_CACHE */