int libusb_submit_transfer(struct libusb_transfer* transfer) { transfer_wrapper* wrapper = GetWrapper(transfer); void*& context = wrapper->usb; if (NULL == context) { int ret (LIBUSB_ERROR_OTHER); switch(transfer->type) { case LIBUSB_TRANSFER_TYPE_CONTROL : fprintf(stderr, "ERROR: libusb_submit_transfer() with LIBUSB_TRANSFER_TYPE_CONTROL; use libusb_control_transfer() instead.\n"); return(LIBUSB_ERROR_INVALID_PARAM); case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS : ret = usb_isochronous_setup_async(translate(transfer->dev_handle), &context, transfer->endpoint, transfer->iso_packet_desc[0].length); break; case LIBUSB_TRANSFER_TYPE_BULK : ret = usb_bulk_setup_async(translate(transfer->dev_handle), &context, transfer->endpoint); break; case LIBUSB_TRANSFER_TYPE_INTERRUPT : ret = usb_interrupt_setup_async(translate(transfer->dev_handle), &context, transfer->endpoint); break; default : return(LIBUSB_ERROR_INVALID_PARAM); } if (ret < 0) { // TODO: better error handling... // what do the functions usb_***_setup_async() actually return on error? return(ret); } TMapIsocTransfers::iterator it = mIsocTransfers.find(transfer->endpoint); if (it == mIsocTransfers.end()) mIsocTransfers.insert(std::make_pair(transfer->endpoint, new TListTransfers())); } mIsocTransfers[transfer->endpoint]->Append(wrapper); transfer->status = LIBUSB_TRANSFER_COMPLETED; int ret = usb_submit_async(context, (char*)transfer->buffer, transfer->length); if (ret < 0) { // TODO: better error handling... // what does usb_submit_async() actually returns on error? // LIBUSB_ERROR_NO_DEVICE if the device has been disconnected // LIBUSB_ERROR_BUSY if the transfer has already been submitted. // another LIBUSB_ERROR code on other failure return(ret); } // 0 on success return(0); }
void sendFrame(void) { if(enabled) { #ifdef PINDMD2 usb_submit_async( asyncWriteContext, frame_buf, 2052 ); usb_reap_async( asyncWriteContext, 5000 ); #else DWORD bytes; sendFrameCount++; // send dmd frame buffer to pindmd board ftStatus = FT_Write(ftHandle, &frame_buf, (do16==1)?(DWORD)2052:(DWORD)1028, &bytes); sendFrameCount--; #endif } }
int TransferAsync(struct BENCHMARK_TRANSFER_PARAM* transferParam, struct BENCHMARK_TRANSFER_HANDLE** handleRef) { int ret; struct BENCHMARK_TRANSFER_HANDLE* handle; *handleRef = NULL; // Submit transfers until the maximum number of outstanding transfer(s) is reached. while (transferParam->OutstandingTransferCount < transferParam->Test->BufferCount) { // Get the next available benchmark transfer handle. *handleRef = handle = &transferParam->TransferHandles[transferParam->TransferHandleNextIndex]; // If a libusb-win32 transfer context hasn't been setup for this benchmark transfer // handle, do it now. // if (!handle->Context) { // Data buffer(s) are located at the end of the transfer param. handle->Data = transferParam->Buffer + (transferParam->TransferHandleNextIndex * transferParam->Test->BufferSize); handle->DataMaxLength = transferParam->Test->BufferSize; switch (ENDPOINT_TYPE(transferParam)) { case USB_ENDPOINT_TYPE_ISOCHRONOUS: ret = usb_isochronous_setup_async(transferParam->Test->DeviceHandle, &handle->Context, transferParam->Ep.bEndpointAddress, transferParam->IsoPacketSize ? transferParam->IsoPacketSize : transferParam->Ep.wMaxPacketSize); break; case USB_ENDPOINT_TYPE_BULK: ret = usb_bulk_setup_async(transferParam->Test->DeviceHandle, &handle->Context, transferParam->Ep.bEndpointAddress); break; case USB_ENDPOINT_TYPE_INTERRUPT: ret = usb_interrupt_setup_async(transferParam->Test->DeviceHandle, &handle->Context, transferParam->Ep.bEndpointAddress); break; default: ret = -1; break; } if (ret < 0) { CONERR("failed creating transfer context ret=%d\n",ret); goto Done; } } // Submit this transfer now. handle->ReturnCode = ret = usb_submit_async(handle->Context, handle->Data, handle->DataMaxLength); if (ret < 0) goto Done; // Mark this handle has InUse. handle->InUse = TRUE; // When transfers ir successfully submitted, OutstandingTransferCount goes up; when // they are completed it goes down. // transferParam->OutstandingTransferCount++; // Move TransferHandleNextIndex to the next available transfer. INC_ROLL(transferParam->TransferHandleNextIndex, transferParam->Test->BufferCount); } // If the number of outstanding transfers has reached the limit, wait for the // oldest outstanding transfer to complete. // if (transferParam->OutstandingTransferCount == transferParam->Test->BufferCount) { // TransferHandleWaitIndex is the index of the oldest outstanding transfer. *handleRef = handle = &transferParam->TransferHandles[transferParam->TransferHandleWaitIndex]; // Only wait, cancelling & freeing is handled by the caller. handle->ReturnCode = ret = usb_reap_async_nocancel(handle->Context, transferParam->Test->Timeout); if (ret < 0) goto Done; // Mark this handle has no longer InUse. handle->InUse = FALSE; // When transfers ir successfully submitted, OutstandingTransferCount goes up; when // they are completed it goes down. // transferParam->OutstandingTransferCount--; // Move TransferHandleWaitIndex to the oldest outstanding transfer. INC_ROLL(transferParam->TransferHandleWaitIndex, transferParam->Test->BufferCount); } Done: return ret; }