third_party/virtualbox/src/VBox/Devices/USB/VUSBUrb.cpp
/**
 * Build the message URB from the given control URB and accompanying message
 * pipe state which we grab from the device for the URB.
 *
 * @param   pUrb        The URB to submit.
 * @param   pSetup      The setup packet for the message transfer.
 * @param   pExtra      Pointer to the additional state requred for a control transfer.
 * @param   pPipe       The message pipe state.
 */
Build the message URB from the given control URB and accompanying message
pipe state which we grab from the device for the URB.

@param   pUrb        The URB to submit.
@param   pSetup      The setup packet for the message transfer.
@param   pExtra      Pointer to the additional state requred for a control transfer.
@param   pPipe       The message pipe state.
Build the message URB from the given control URB and accompanying message pipe state which we grab from the device for the URB . @param pUrb The URB to submit . @param pSetup The setup packet for the message transfer . @param pExtra Pointer to the additional state requred for a control transfer . @param pPipe The message pipe state .
static void vusbMsgDoTransfer(PVUSBURB pUrb, PVUSBSETUP pSetup, PVUSBCTRLEXTRA pExtra, PVUSBPIPE pPipe)
{
    RT_NOREF(pPipe);
    Assert(!pExtra->fSubmitted);
    pExtra->fSubmitted = true;
    bool fSafeRequest = vusbUrbIsRequestSafe(pSetup, pUrb);
    if (!fSafeRequest)
    {
        vusbMsgSubmitSynchronously(pUrb, fSafeRequest);
        return;
    }
    LogFlow(("%s: vusbMsgDoTransfer: ep=%d pMsgUrb=%p pPipe=%p stage=%s\n",
             pUrb->pszDesc, pUrb->EndPt, &pExtra->Urb, pPipe, g_apszCtlStates[pExtra->enmStage]));
    Assert(pExtra->Urb.enmType == VUSBXFERTYPE_MSG);
    Assert(pExtra->Urb.EndPt == pUrb->EndPt);
    pExtra->Urb.enmDir  = (pSetup->bmRequestType & VUSB_DIR_TO_HOST) ? VUSBDIRECTION_IN : VUSBDIRECTION_OUT;
    pExtra->Urb.cbData  = pSetup->wLength + sizeof(*pSetup);
    pExtra->Urb.pVUsb->pCtrlUrb = pUrb;
    int rc = vusbUrbQueueAsyncRh(&pExtra->Urb);
    if (RT_FAILURE(rc))
    {
        LogFlow(("%s: vusbMsgDoTransfer: failed submitting urb! failing it with %s (rc=%Rrc)!!!\n",
                 pUrb->pszDesc, rc == VERR_VUSB_DEVICE_NOT_ATTACHED ? "DNR" : "CRC", rc));
        pExtra->Urb.enmStatus = rc == VERR_VUSB_DEVICE_NOT_ATTACHED ? VUSBSTATUS_DNR : VUSBSTATUS_CRC;
        pExtra->Urb.enmState = VUSBURBSTATE_REAPED;
        vusbMsgCompletion(&pExtra->Urb);
    }
}
static void vusbMsgDoTransfer ( PVUSBURB pUrb , PVUSBSETUP pSetup , PVUSBCTRLEXTRA pExtra , PVUSBPIPE pPipe ) { RT_NOREF ( pPipe ) ; Assert ( ! pExtra -> fSubmitted ) ; pExtra -> fSubmitted = true ; bool fSafeRequest = vusbUrbIsRequestSafe ( pSetup , pUrb ) ; if ( ! fSafeRequest ) { vusbMsgSubmitSynchronously ( pUrb , fSafeRequest ) ; return ; } LogFlow ( ( " \n " , pUrb -> pszDesc , pUrb -> EndPt , & pExtra -> Urb , pPipe , g_apszCtlStates [ pExtra -> enmStage ] ) ) ; Assert ( pExtra -> Urb . enmType == VUSBXFERTYPE_MSG ) ; Assert ( pExtra -> Urb . EndPt == pUrb -> EndPt ) ; pExtra -> Urb . enmDir = ( pSetup -> bmRequestType & VUSB_DIR_TO_HOST ) ? VUSBDIRECTION_IN : VUSBDIRECTION_OUT ; pExtra -> Urb . cbData = pSetup -> wLength + sizeof ( * pSetup ) ; pExtra -> Urb . pVUsb -> pCtrlUrb = pUrb ; int rc = vusbUrbQueueAsyncRh ( & pExtra -> Urb ) ; if ( RT_FAILURE ( rc ) ) { LogFlow ( ( " \n " , pUrb -> pszDesc , rc == VERR_VUSB_DEVICE_NOT_ATTACHED ? " " : " " , rc ) ) ; pExtra -> Urb . enmStatus = rc == VERR_VUSB_DEVICE_NOT_ATTACHED ? VUSBSTATUS_DNR : VUSBSTATUS_CRC ; pExtra -> Urb . enmState = VUSBURBSTATE_REAPED ; vusbMsgCompletion ( & pExtra -> Urb ) ; } }
Build the message URB from the given control URB and accompanying message
 pipe state which we grab from the device for the URB.
Build the message URB from the given control URB and accompanying message pipe state which we grab from the device for the URB .
/*
     * Mark this transfer as sent (cleared at setup time).
     */ /*
     * Do we have to do this synchronously?
     */ /*
     * Do it asynchronously.
     */ /*
         * If we fail submitting it, will not retry but fail immediately.
         *
         * This keeps things simple. The host OS will have retried if
         * it's a proxied device, and if it's a virtual one it really means
         * it if it's failing a control message.
         */