diff --git a/lib/libusb/libusb10_io.c b/lib/libusb/libusb10_io.c --- a/lib/libusb/libusb10_io.c +++ b/lib/libusb/libusb10_io.c @@ -502,7 +502,9 @@ return (LIBUSB_ERROR_PIPE); else if (err == LIBUSB20_ERROR_TIMEOUT) return (LIBUSB_ERROR_TIMEOUT); - else if (err) + else if (err == LIBUSB_ERROR_INTERRUPTED) + return (LIBUSB_ERROR_IO); + else if (err < 0) return (LIBUSB_ERROR_NO_DEVICE); return (actlen); diff --git a/lib/libusb/libusb20_ugen20.c b/lib/libusb/libusb20_ugen20.c --- a/lib/libusb/libusb20_ugen20.c +++ b/lib/libusb/libusb20_ugen20.c @@ -98,6 +98,41 @@ LIBUSB20_DEVICE(LIBUSB20_DECLARE, ugen20) }; +static int +errno_to_libusb_error(int uerr) +{ + switch (uerr) { + case 0: + return (LIBUSB20_SUCCESS); + case EIO: + return (LIBUSB20_ERROR_IO); + case EINVAL: + return (LIBUSB20_ERROR_INVALID_PARAM); + case EACCES: + return (LIBUSB20_ERROR_ACCESS); + case ENXIO: + return (LIBUSB20_ERROR_NO_DEVICE); + case EFAULT: + return (LIBUSB20_ERROR_NOT_FOUND); + case EBUSY: + return (LIBUSB20_ERROR_BUSY); + case ETIMEDOUT: + return (LIBUSB20_ERROR_TIMEOUT); + case EMSGSIZE: + return (LIBUSB20_ERROR_OVERFLOW); + case EPIPE: + return (LIBUSB20_ERROR_PIPE); + case EAGAIN: + return (LIBUSB20_ERROR_INTERRUPTED); + case ENOMEM: + return (LIBUSB20_ERROR_NO_MEM); + case ENOTSUP: + return (LIBUSB20_ERROR_NOT_SUPPORTED); + default: + return (LIBUSB20_ERROR_OTHER); + } +} + static const char * ugen20_get_backend_name(void) { @@ -749,6 +784,7 @@ void *data, uint16_t *pactlen, uint32_t timeout, uint8_t flags) { struct usb_ctl_request req; + int err; memset(&req, 0, sizeof(req)); @@ -760,8 +796,8 @@ sizeof(req.ucr_request), setup)) { /* ignore */ } - if (ioctl(pdev->file_ctrl, IOUSB(USB_DO_REQUEST), &req)) { - return (LIBUSB20_ERROR_OTHER); + if ((err = ioctl(pdev->file_ctrl, IOUSB(USB_DO_REQUEST), &req))) { + return (errno_to_libusb_error(err)); } if (pactlen) { /* get actual length */ @@ -1027,7 +1063,7 @@ pq->bcdDeviceHigh = q.bcdDeviceHigh; strlcpy(pq->quirkname, q.quirkname, sizeof(pq->quirkname)); } - return (error); + return (errno_to_libusb_error(error)); } static int diff --git a/sys/dev/usb/usb_generic.c b/sys/dev/usb/usb_generic.c --- a/sys/dev/usb/usb_generic.c +++ b/sys/dev/usb/usb_generic.c @@ -143,6 +143,37 @@ 0, "Debug level"); #endif +static const int usb_error_to_errno[USB_ERR_MAX] = { + [USB_ERR_NORMAL_COMPLETION] = 0, + [USB_ERR_PENDING_REQUESTS] = EALREADY, + [USB_ERR_NOT_STARTED] = EINVAL, + [USB_ERR_NOMEM] = ENOMEM, + [USB_ERR_CANCELLED] = ECANCELED, + [USB_ERR_BAD_ADDRESS] = EFAULT, + [USB_ERR_BAD_BUFSIZE] = ENOBUFS, + [USB_ERR_BAD_FLAG] = EINVAL, + [USB_ERR_NO_CALLBACK] = EINVAL, + [USB_ERR_IN_USE] = EADDRINUSE, + [USB_ERR_NO_ADDR] = EFAULT, + [USB_ERR_NO_PIPE] = EPIPE, + [USB_ERR_ZERO_NFRAMES] = EINVAL, + [USB_ERR_ZERO_MAXP] = EINVAL, + [USB_ERR_SET_ADDR_FAILED] = EADDRNOTAVAIL, + [USB_ERR_NO_POWER] = ENXIO, + [USB_ERR_TOO_DEEP] = EINVAL, + [USB_ERR_IOERROR] = EIO, + [USB_ERR_NOT_CONFIGURED] = ENXIO, + [USB_ERR_TIMEOUT] = ETIMEDOUT, + [USB_ERR_SHORT_XFER] = ERANGE, + [USB_ERR_STALLED] = EAGAIN, + [USB_ERR_INTERRUPTED] = EAGAIN, + [USB_ERR_DMA_LOAD_FAILED] = EIO, + [USB_ERR_BAD_CONTEXT] = EBADMSG, + [USB_ERR_NO_ROOT_HUB] = EINVAL, + [USB_ERR_NO_INTR_THREAD] = EIO, + [USB_ERR_NOT_LOCKED] = EINVAL, +}; + /* prototypes */ static int @@ -861,10 +892,7 @@ ur->ucr_actlen = actlen; - if (error) { - error = EIO; - } - return (error); + return (usb_error_to_errno[error]); } #ifdef COMPAT_FREEBSD32