third_party/virtualbox/src/VBox/Devices/USB/VUSBUrb.cpp
/**
 * Sets up the message.
 *
 * The message is associated with the pipe, in what's currently called
 * control pipe extra state data (pointed to by pPipe->pCtrl). If this
 * is a OUT message, we will no go on collecting data URB. If it's a
 * IN message, we'll send it and then queue any incoming data for the
 * URBs collecting it.
 *
 * @returns Success indicator.
 */
Sets up the message.
The message is associated with the pipe, in what's currently called
control pipe extra state data (pointed to by pPipe->pCtrl). If this
is a OUT message, we will no go on collecting data URB. If it's a
IN message, we'll send it and then queue any incoming data for the
URBs collecting it.

@returns Success indicator.
Sets up the message . The message is associated with the pipe in what ' s currently called control pipe extra state data ( pointed to by pPipe - > pCtrl ) . If this is a OUT message we will no go on collecting data URB . If it ' s a IN message we ' ll send it and then queue any incoming data for the URBs collecting it . @returns Success indicator .
static bool vusbMsgSetup(PVUSBPIPE pPipe, const void *pvBuf, uint32_t cbBuf)
{
    PVUSBCTRLEXTRA  pExtra = pPipe->pCtrl;
    const VUSBSETUP *pSetupIn = (PVUSBSETUP)pvBuf;
    if (cbBuf < sizeof(VUSBSETUP))
    {
        LogFlow(("vusbMsgSetup: pPipe=%p cbBuf=%u < %u (failure) !!!\n",
                 pPipe, cbBuf, sizeof(VUSBSETUP)));
        return false;
    }
    if (pExtra->Urb.enmState == VUSBURBSTATE_CANCELLED)
    {
        void *pvNew = RTMemDup(pExtra, RT_UOFFSETOF_DYN(VUSBCTRLEXTRA, Urb.abData[pExtra->cbMax]));
        if (!pvNew)
        {
            Log(("vusbMsgSetup: out of memory!!! cbReq=%zu\n", RT_UOFFSETOF_DYN(VUSBCTRLEXTRA, Urb.abData[pExtra->cbMax])));
            return false;
        }
        pExtra->Urb.pVUsb->pvFreeCtx = NULL;
        LogFlow(("vusbMsgSetup: Replacing canceled pExtra=%p with %p.\n", pExtra, pvNew));
        pPipe->pCtrl = pExtra = (PVUSBCTRLEXTRA)pvNew;
        pExtra->Urb.pVUsb = (PVUSBURBVUSB)&pExtra->Urb.abData[sizeof(pExtra->Urb.abData) + sizeof(VUSBSETUP)];
        pExtra->Urb.pVUsb->pUrb = &pExtra->Urb;
        pExtra->pMsg = (PVUSBSETUP)pExtra->Urb.abData;
        pExtra->Urb.enmState = VUSBURBSTATE_ALLOCATED;
        pExtra->Urb.fCompleting = false;
    }
    if (pExtra->cbMax < cbBuf + pSetupIn->wLength + sizeof(VUSBURBVUSBINT))
    {
#if 1
        LogRelMax(10, ("VUSB: Control URB too large (wLength=%u)!\n", pSetupIn->wLength));
        return false;
#else
        uint32_t cbReq = RT_ALIGN_32(cbBuf + pSetupIn->wLength + sizeof(VUSBURBVUSBINT), 1024);
        PVUSBCTRLEXTRA pNew = (PVUSBCTRLEXTRA)RTMemRealloc(pExtra, RT_UOFFSETOF_DYN(VUSBCTRLEXTRA, Urb.abData[cbReq]));
        if (!pNew)
        {
            Log(("vusbMsgSetup: out of memory!!! cbReq=%u %zu\n",
                 cbReq, RT_UOFFSETOF_DYN(VUSBCTRLEXTRA, Urb.abData[cbReq])));
            return false;
        }
        if (pExtra != pNew)
        {
            pNew->pMsg = (PVUSBSETUP)pNew->Urb.abData;
            pExtra = pNew;
            pPipe->pCtrl = pExtra;
        }
        PVUSBURBVUSB pOldVUsb = (PVUSBURBVUSB)&pExtra->Urb.abData[pExtra->cbMax - sizeof(VUSBURBVUSBINT)];
        pExtra->Urb.pVUsb = (PVUSBURBVUSB)&pExtra->Urb.abData[cbBuf + pSetupIn->wLength];
        memmove(pExtra->Urb.pVUsb, pOldVUsb, sizeof(VUSBURBVUSBINT));
        memset(pOldVUsb, 0, (uint8_t *)pExtra->Urb.pVUsb - (uint8_t *)pOldVUsb);
        pExtra->Urb.pVUsb->pUrb = &pExtra->Urb;
        pExtra->Urb.pVUsb->pvFreeCtx = &pExtra->Urb;
        pExtra->cbMax = cbReq;
#endif
    }
    Assert(pExtra->Urb.enmState == VUSBURBSTATE_ALLOCATED);
    PVUSBSETUP pSetup = pExtra->pMsg;
    pExtra->fSubmitted      = false;
    pExtra->Urb.enmState    = VUSBURBSTATE_IN_FLIGHT;
    pExtra->pbCur           = (uint8_t *)(pSetup + 1);
    pSetup->bmRequestType   = pSetupIn->bmRequestType;
    pSetup->bRequest        = pSetupIn->bRequest;
    pSetup->wValue          = RT_LE2H_U16(pSetupIn->wValue);
    pSetup->wIndex          = RT_LE2H_U16(pSetupIn->wIndex);
    pSetup->wLength         = RT_LE2H_U16(pSetupIn->wLength);
    LogFlow(("vusbMsgSetup(%p,,%d): bmRequestType=%#04x bRequest=%#04x wValue=%#06x wIndex=%#06x wLength=0x%.4x\n",
             pPipe, cbBuf, pSetup->bmRequestType, pSetup->bRequest, pSetup->wValue, pSetup->wIndex, pSetup->wLength));
    return true;
}
static bool vusbMsgSetup ( PVUSBPIPE pPipe , const void * pvBuf , uint32_t cbBuf ) { PVUSBCTRLEXTRA pExtra = pPipe -> pCtrl ; const VUSBSETUP * pSetupIn = ( PVUSBSETUP ) pvBuf ; if ( cbBuf < sizeof ( VUSBSETUP ) ) { LogFlow ( ( " \n " , pPipe , cbBuf , sizeof ( VUSBSETUP ) ) ) ; return false ; } if ( pExtra -> Urb . enmState == VUSBURBSTATE_CANCELLED ) { void * pvNew = RTMemDup ( pExtra , RT_UOFFSETOF_DYN ( VUSBCTRLEXTRA , Urb . abData [ pExtra -> cbMax ] ) ) ; if ( ! pvNew ) { Log ( ( " \n " , RT_UOFFSETOF_DYN ( VUSBCTRLEXTRA , Urb . abData [ pExtra -> cbMax ] ) ) ) ; return false ; } pExtra -> Urb . pVUsb -> pvFreeCtx = NULL ; LogFlow ( ( " \n " , pExtra , pvNew ) ) ; pPipe -> pCtrl = pExtra = ( PVUSBCTRLEXTRA ) pvNew ; pExtra -> Urb . pVUsb = ( PVUSBURBVUSB ) & pExtra -> Urb . abData [ sizeof ( pExtra -> Urb . abData ) + sizeof ( VUSBSETUP ) ] ; pExtra -> Urb . pVUsb -> pUrb = & pExtra -> Urb ; pExtra -> pMsg = ( PVUSBSETUP ) pExtra -> Urb . abData ; pExtra -> Urb . enmState = VUSBURBSTATE_ALLOCATED ; pExtra -> Urb . fCompleting = false ; } if ( pExtra -> cbMax < cbBuf + pSetupIn -> wLength + sizeof ( VUSBURBVUSBINT ) ) { #if 1 LogRelMax ( 10 , ( " \n " , pSetupIn -> wLength ) ) ; return false ; #else uint32_t cbReq = RT_ALIGN_32 ( cbBuf + pSetupIn -> wLength + sizeof ( VUSBURBVUSBINT ) , 1024 ) ; PVUSBCTRLEXTRA pNew = ( PVUSBCTRLEXTRA ) RTMemRealloc ( pExtra , RT_UOFFSETOF_DYN ( VUSBCTRLEXTRA , Urb . abData [ cbReq ] ) ) ; if ( ! pNew ) { Log ( ( " \n " , cbReq , RT_UOFFSETOF_DYN ( VUSBCTRLEXTRA , Urb . abData [ cbReq ] ) ) ) ; return false ; } if ( pExtra != pNew ) { pNew -> pMsg = ( PVUSBSETUP ) pNew -> Urb . abData ; pExtra = pNew ; pPipe -> pCtrl = pExtra ; } PVUSBURBVUSB pOldVUsb = ( PVUSBURBVUSB ) & pExtra -> Urb . abData [ pExtra -> cbMax - sizeof ( VUSBURBVUSBINT ) ] ; pExtra -> Urb . pVUsb = ( PVUSBURBVUSB ) & pExtra -> Urb . abData [ cbBuf + pSetupIn -> wLength ] ; memmove ( pExtra -> Urb . pVUsb , pOldVUsb , sizeof ( VUSBURBVUSBINT ) ) ; memset ( pOldVUsb , 0 , ( uint8_t * ) pExtra -> Urb . pVUsb - ( uint8_t * ) pOldVUsb ) ; pExtra -> Urb . pVUsb -> pUrb = & pExtra -> Urb ; pExtra -> Urb . pVUsb -> pvFreeCtx = & pExtra -> Urb ; pExtra -> cbMax = cbReq ; #endif } Assert ( pExtra -> Urb . enmState == VUSBURBSTATE_ALLOCATED ) ; PVUSBSETUP pSetup = pExtra -> pMsg ; pExtra -> fSubmitted = false ; pExtra -> Urb . enmState = VUSBURBSTATE_IN_FLIGHT ; pExtra -> pbCur = ( uint8_t * ) ( pSetup + 1 ) ; pSetup -> bmRequestType = pSetupIn -> bmRequestType ; pSetup -> bRequest = pSetupIn -> bRequest ; pSetup -> wValue = RT_LE2H_U16 ( pSetupIn -> wValue ) ; pSetup -> wIndex = RT_LE2H_U16 ( pSetupIn -> wIndex ) ; pSetup -> wLength = RT_LE2H_U16 ( pSetupIn -> wLength ) ; LogFlow ( ( " \n " , pPipe , cbBuf , pSetup -> bmRequestType , pSetup -> bRequest , pSetup -> wValue , pSetup -> wIndex , pSetup -> wLength ) ) ; return true ; }
Sets up the message.
Sets up the message .
/*
     * Validate length.
     */ /*
     * Check if we've got an cancelled message URB. Allocate a new one in that case.
     */ /*
     * Check that we've got sufficient space in the message URB.
     */ /*
     * Copy the setup data and prepare for data.
     */