static int haiku_handle_transfer_completion(struct usbi_transfer * itransfer) { USBTransfer* transfer=*((USBTransfer**)usbi_transfer_get_os_priv(itransfer)); usbi_mutex_lock(&itransfer->lock); if(transfer->IsCancelled()) { delete transfer; *((USBTransfer**)usbi_transfer_get_os_priv(itransfer))=NULL; usbi_mutex_unlock(&itransfer->lock); if (itransfer->transferred < 0) itransfer->transferred = 0; return usbi_handle_transfer_cancellation(itransfer); } libusb_transfer_status status = LIBUSB_TRANSFER_COMPLETED; if(itransfer->transferred < 0) { usbi_err(ITRANSFER_CTX(itransfer), "error in transfer"); status = LIBUSB_TRANSFER_ERROR; itransfer->transferred=0; } delete transfer; *((USBTransfer**)usbi_transfer_get_os_priv(itransfer))=NULL; usbi_mutex_unlock(&itransfer->lock); return usbi_handle_transfer_completion(itransfer, status); }
void windows_handle_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); switch (transfer->type) { case LIBUSB_TRANSFER_TYPE_CONTROL: case LIBUSB_TRANSFER_TYPE_BULK: case LIBUSB_TRANSFER_TYPE_INTERRUPT: case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: windows_transfer_callback(itransfer, io_result, io_size); break; case LIBUSB_TRANSFER_TYPE_BULK_STREAM: usbi_warn(ITRANSFER_CTX(itransfer), "bulk stream transfers are not yet supported on this platform"); break; default: usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); } }
static void wince_handle_callback (struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); switch (transfer->type) { case LIBUSB_TRANSFER_TYPE_CONTROL: case LIBUSB_TRANSFER_TYPE_BULK: case LIBUSB_TRANSFER_TYPE_INTERRUPT: case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: wince_transfer_callback (itransfer, io_result, io_size); break; default: usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); } }
static int usbdk_cancel_transfer(struct usbi_transfer *itransfer) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); switch (transfer->type) { case LIBUSB_TRANSFER_TYPE_CONTROL: // Control transfers cancelled by IoCancelXXX() API // No special treatment needed return LIBUSB_SUCCESS; case LIBUSB_TRANSFER_TYPE_BULK: case LIBUSB_TRANSFER_TYPE_INTERRUPT: case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: return usbdk_abort_transfers(itransfer); default: usbi_err(ITRANSFER_CTX(itransfer), "unknown endpoint type %d", transfer->type); return LIBUSB_ERROR_INVALID_PARAM; } }
static void windows_transfer_callback(const struct windows_backend *backend, struct usbi_transfer *itransfer, DWORD io_result, DWORD io_size) { int status, istatus; usbi_dbg("handling I/O completion with errcode %u, size %u", (unsigned int)io_result, (unsigned int)io_size); switch (io_result) { case NO_ERROR: status = backend->copy_transfer_data(itransfer, (uint32_t)io_size); break; case ERROR_GEN_FAILURE: usbi_dbg("detected endpoint stall"); status = LIBUSB_TRANSFER_STALL; break; case ERROR_SEM_TIMEOUT: usbi_dbg("detected semaphore timeout"); status = LIBUSB_TRANSFER_TIMED_OUT; break; case ERROR_OPERATION_ABORTED: istatus = backend->copy_transfer_data(itransfer, (uint32_t)io_size); if (istatus != LIBUSB_TRANSFER_COMPLETED) usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus); usbi_dbg("detected operation aborted"); status = LIBUSB_TRANSFER_CANCELLED; break; case ERROR_FILE_NOT_FOUND: usbi_dbg("detected device removed"); status = LIBUSB_TRANSFER_NO_DEVICE; break; default: usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", (unsigned int)io_result, windows_error_str(io_result)); status = LIBUSB_TRANSFER_ERROR; break; } backend->clear_transfer_priv(itransfer); // Cancel polling if (status == LIBUSB_TRANSFER_CANCELLED) usbi_handle_transfer_cancellation(itransfer); else usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status); }
static void windows_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size) { int status, istatus; usbi_dbg("handling I/O completion with errcode %u, size %u", io_result, io_size); switch (io_result) { case NO_ERROR: status = windows_copy_transfer_data(itransfer, io_size); break; case ERROR_GEN_FAILURE: usbi_dbg("detected endpoint stall"); status = LIBUSB_TRANSFER_STALL; break; case ERROR_SEM_TIMEOUT: usbi_dbg("detected semaphore timeout"); status = LIBUSB_TRANSFER_TIMED_OUT; break; case ERROR_OPERATION_ABORTED: istatus = windows_copy_transfer_data(itransfer, io_size); if (istatus != LIBUSB_TRANSFER_COMPLETED) usbi_dbg("Failed to copy partial data in aborted operation: %d", istatus); if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) { usbi_dbg("detected timeout"); status = LIBUSB_TRANSFER_TIMED_OUT; } else { usbi_dbg("detected operation aborted"); status = LIBUSB_TRANSFER_CANCELLED; } break; default: usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error %u: %s", io_result, windows_error_str(io_result)); status = LIBUSB_TRANSFER_ERROR; break; } windows_clear_transfer_priv(itransfer); // Cancel polling usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status); }
static void wince_transfer_callback(struct usbi_transfer *itransfer, uint32_t io_result, uint32_t io_size) { struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer); struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev); int status; usbi_dbg("handling I/O completion with errcode %d", io_result); if (io_result == ERROR_NOT_SUPPORTED && transfer->type != LIBUSB_TRANSFER_TYPE_CONTROL) { /* For functional stalls, the WinCE USB layer (and therefore the USB Kernel Wrapper * Driver) will report USB_ERROR_STALL/ERROR_NOT_SUPPORTED in situations where the * endpoint isn't actually stalled. * * One example of this is that some devices will occasionally fail to reply to an IN * token. The WinCE USB layer carries on with the transaction until it is completed * (or cancelled) but then completes it with USB_ERROR_STALL. * * This code therefore needs to confirm that there really is a stall error, by both * checking the pipe status and requesting the endpoint status from the device. */ BOOL halted = FALSE; usbi_dbg("checking I/O completion with errcode ERROR_NOT_SUPPORTED is really a stall"); if (UkwIsPipeHalted(priv->dev, transfer->endpoint, &halted)) { /* Pipe status retrieved, so now request endpoint status by sending a GET_STATUS * control request to the device. This is done synchronously, which is a bit * naughty, but this is a special corner case. */ WORD wStatus = 0; DWORD written = 0; UKW_CONTROL_HEADER ctrlHeader; ctrlHeader.bmRequestType = LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_ENDPOINT_IN | LIBUSB_RECIPIENT_ENDPOINT; ctrlHeader.bRequest = LIBUSB_REQUEST_GET_STATUS; ctrlHeader.wValue = 0; ctrlHeader.wIndex = transfer->endpoint; ctrlHeader.wLength = sizeof(wStatus); if (UkwIssueControlTransfer(priv->dev, UKW_TF_IN_TRANSFER | UKW_TF_SEND_TO_ENDPOINT, &ctrlHeader, &wStatus, sizeof(wStatus), &written, NULL)) { if (written == sizeof(wStatus) && (wStatus & STATUS_HALT_FLAG) == 0) { if (!halted || UkwClearHaltHost(priv->dev, transfer->endpoint)) { usbi_dbg("Endpoint doesn't appear to be stalled, overriding error with success"); io_result = ERROR_SUCCESS; } else { usbi_dbg("Endpoint doesn't appear to be stalled, but the host is halted, changing error"); io_result = ERROR_IO_DEVICE; } } } } } switch(io_result) { case ERROR_SUCCESS: itransfer->transferred += io_size; status = LIBUSB_TRANSFER_COMPLETED; break; case ERROR_CANCELLED: usbi_dbg("detected transfer cancel"); status = LIBUSB_TRANSFER_CANCELLED; break; case ERROR_NOT_SUPPORTED: case ERROR_GEN_FAILURE: usbi_dbg("detected endpoint stall"); status = LIBUSB_TRANSFER_STALL; break; case ERROR_SEM_TIMEOUT: usbi_dbg("detected semaphore timeout"); status = LIBUSB_TRANSFER_TIMED_OUT; break; case ERROR_OPERATION_ABORTED: if (itransfer->flags & USBI_TRANSFER_TIMED_OUT) { usbi_dbg("detected timeout"); status = LIBUSB_TRANSFER_TIMED_OUT; } else { usbi_dbg("detected operation aborted"); status = LIBUSB_TRANSFER_CANCELLED; } break; default: usbi_err(ITRANSFER_CTX(itransfer), "detected I/O error: %s", windows_error_str(io_result)); status = LIBUSB_TRANSFER_ERROR; break; } wince_clear_transfer_priv(itransfer); if (status == LIBUSB_TRANSFER_CANCELLED) { usbi_handle_transfer_cancellation(itransfer); } else { usbi_handle_transfer_completion(itransfer, (enum libusb_transfer_status)status); } }
static void windows_clear_transfer_priv(struct usbi_transfer *itransfer) { struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer)); priv->backend->clear_transfer_priv(itransfer); }
static int windows_cancel_transfer(struct usbi_transfer *itransfer) { struct windows_context_priv *priv = _context_priv(ITRANSFER_CTX(itransfer)); return priv->backend->cancel_transfer(itransfer); }