summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TODO1
-rw-r--r--libusb/core.c15
-rw-r--r--libusb/io.c47
-rw-r--r--libusb/libusb.h9
-rw-r--r--libusb/os/linux_usbfs.c59
5 files changed, 72 insertions, 59 deletions
diff --git a/TODO b/TODO
index da22bca..89db498 100644
--- a/TODO
+++ b/TODO
@@ -1,6 +1,5 @@
for 1.0
=======
-error codes
fixme review
review functionality missing over 0.1
endianness of control setup, issues when resubmitting transfers
diff --git a/libusb/core.c b/libusb/core.c
index 6348c93..d33eef7 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -282,7 +282,8 @@ struct libusb_device *usbi_get_device_by_session_id(unsigned long session_id)
*
* \param list output location for a list of devices. Must be later freed with
* libusb_free_device_list().
- * \returns the number of devices in the outputted list, or negative on error
+ * \returns the number of devices in the outputted list, or LIBUSB_ERROR_NOMEM
+ * on memory allocation failure.
*/
API_EXPORTED int libusb_get_device_list(struct libusb_device ***list)
{
@@ -294,7 +295,7 @@ API_EXPORTED int libusb_get_device_list(struct libusb_device ***list)
usbi_dbg("");
if (!discdevs)
- return -ENOMEM;
+ return LIBUSB_ERROR_NOMEM;
r = usbi_backend->get_device_list(&discdevs);
if (r < 0)
@@ -304,7 +305,7 @@ API_EXPORTED int libusb_get_device_list(struct libusb_device ***list)
len = discdevs->len;
ret = malloc(sizeof(void *) * (len + 1));
if (!ret) {
- r = -ENOMEM;
+ r = LIBUSB_ERROR_NOMEM;
goto out;
}
@@ -519,7 +520,7 @@ API_EXPORTED struct libusb_device *libusb_get_device(
* you wish to use before you can perform I/O on any of the endpoints.
* \param iface the <tt>bInterfaceNumber</tt> of the interface you wish to claim
* \param dev a device handle
- * \returns 0 on success, non-zero on error
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
*/
API_EXPORTED int libusb_claim_interface(struct libusb_device_handle *dev,
int iface)
@@ -534,7 +535,7 @@ API_EXPORTED int libusb_claim_interface(struct libusb_device_handle *dev,
* \param dev a device handle
* \param iface the <tt>bInterfaceNumber</tt> of the previously-claimed
* interface
- * \returns 0 on success, non-zero on error
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
*/
API_EXPORTED int libusb_release_interface(struct libusb_device_handle *dev,
int iface)
@@ -554,7 +555,7 @@ API_EXPORTED int libusb_set_interface_altsetting(
/** \ingroup lib
* Initialize libusb. This function must be called before calling any other
* libusb function.
- * \returns 0 on success, non-zero on error
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
*/
API_EXPORTED int libusb_init(void)
{
@@ -562,7 +563,7 @@ API_EXPORTED int libusb_init(void)
if (usbi_backend->init) {
int r = usbi_backend->init();
- if (r < 0)
+ if (r)
return r;
}
diff --git a/libusb/io.c b/libusb/io.c
index b3b2c98..453ecce 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -627,21 +627,6 @@ out:
pthread_mutex_unlock(&flying_transfers_lock);
}
-static int submit_transfer(struct usbi_transfer *itransfer)
-{
- int r;
-
- add_to_flying_list(itransfer);
- r = usbi_backend->submit_transfer(itransfer);
- if (r < 0) {
- pthread_mutex_lock(&flying_transfers_lock);
- list_del(&itransfer->list);
- pthread_mutex_unlock(&flying_transfers_lock);
- }
-
- return r;
-}
-
/** \ingroup asyncio
* Allocate a libusb transfer with a specified number of isochronous packet
* descriptors. The returned transfer is pre-initialized for you. When the new
@@ -717,8 +702,7 @@ API_EXPORTED void libusb_free_transfer(struct libusb_transfer *transfer)
* submitted but has not yet completed.
*
* \param transfer the transfer to submit
- * \returns 0 on success
- * \returns negative on error
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
*/
API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer)
{
@@ -729,7 +713,7 @@ API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer)
itransfer->transferred = 0;
r = calculate_timeout(itransfer);
if (r < 0)
- return r;
+ return LIBUSB_ERROR_OTHER;
if (transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL) {
struct libusb_control_setup *setup =
@@ -743,8 +727,16 @@ API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer)
setup->wIndex = cpu_to_le16(setup->wIndex);
setup->wLength = cpu_to_le16(setup->wLength);
}
+
+ add_to_flying_list(itransfer);
+ r = usbi_backend->submit_transfer(itransfer);
+ if (r) {
+ pthread_mutex_lock(&flying_transfers_lock);
+ list_del(&itransfer->list);
+ pthread_mutex_unlock(&flying_transfers_lock);
+ }
- return submit_transfer(itransfer);
+ return r;
}
/** \ingroup asyncio
@@ -942,7 +934,7 @@ static int handle_events(struct timeval *tv)
return 0;
} else if (r < 0) {
usbi_err("select failed %d err=%d\n", r, errno);
- return r;
+ return LIBUSB_ERROR_IO;
}
r = usbi_backend->handle_events(_readfds, _writefds);
@@ -968,8 +960,7 @@ static int handle_events(struct timeval *tv)
*
* \param tv the maximum time to block waiting for events, or zero for
* non-blocking mode
- * \returns 0 on success
- * \returns non-zero on error
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
*/
API_EXPORTED int libusb_handle_events_timeout(struct timeval *tv)
{
@@ -983,8 +974,7 @@ API_EXPORTED int libusb_handle_events_timeout(struct timeval *tv)
* function is blocking or non-blocking, or the maximum timeout, use
* libusb_handle_events_timeout() instead.
*
- * \returns 0 on success
- * \returns non-zero on error
+ * \returns 0 on success, or a LIBUSB_ERROR code on failure
*/
API_EXPORTED int libusb_handle_events(void)
{
@@ -1008,14 +998,15 @@ API_EXPORTED int libusb_handle_events(void)
* When the timeout has expired, call into libusb_handle_events_timeout()
* (perhaps in non-blocking mode) so that libusb can handle the timeout.
*
- * This function may return 0 (success) and an all-zero timeval. If this is
+ * This function may return 1 (success) and an all-zero timeval. If this is
* the case, it indicates that libusb has a timeout that has already expired
* so you should call libusb_handle_events_timeout() or similar immediately.
+ * A return code of 0 indicates that there are no pending timeouts.
*
* \param tv output location for a relative time against the current
* clock in which libusb must be called into in order to process timeout events
- * \returns 0 on success
- * \returns non-zero on error
+ * \returns 0 if there are no pending timeouts, 1 if a timeout was returned,
+ * or LIBUSB_ERROR_OTHER on failure
*/
API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
{
@@ -1058,7 +1049,7 @@ API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
r = clock_gettime(CLOCK_MONOTONIC, &cur_ts);
if (r < 0) {
usbi_err("failed to read monotonic clock, errno=%d", errno);
- return r;
+ return LIBUSB_ERROR_OTHER;
}
TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
diff --git a/libusb/libusb.h b/libusb/libusb.h
index 08d256d..66708b3 100644
--- a/libusb/libusb.h
+++ b/libusb/libusb.h
@@ -491,6 +491,15 @@ typedef struct libusb_device libusb_device;
struct libusb_device_handle;
typedef struct libusb_device_handle libusb_device_handle;
+enum libusb_error {
+ LIBUSB_SUCCESS = 0,
+ LIBUSB_ERROR_IO = -1,
+ LIBUSB_ERROR_INVALID_PARAM = -2,
+ LIBUSB_ERROR_ACCESS = -3,
+ LIBUSB_ERROR_NOMEM = -4,
+ LIBUSB_ERROR_OTHER = -5,
+};
+
/** \ingroup asyncio
* Transfer status codes */
enum libusb_transfer_status {
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index 6379da9..bbe48cb 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -128,7 +128,7 @@ static int op_init(void)
usbfs_path = find_usbfs_path();
if (!usbfs_path) {
usbi_err("could not find usbfs");
- return -ENODEV;
+ return LIBUSB_ERROR_OTHER;
}
return 0;
}
@@ -411,18 +411,23 @@ static int op_claim_interface(struct libusb_device_handle *handle, int iface)
{
int fd = __device_handle_priv(handle)->fd;
int r = ioctl(fd, IOCTL_USBFS_CLAIMINTF, &iface);
- if (r < 0)
+ if (r) {
usbi_err("claim interface failed, error %d", r);
- return r;
+ /* FIXME interpret error codes better */
+ return LIBUSB_ERROR_OTHER;
+ }
+ return 0;
}
static int op_release_interface(struct libusb_device_handle *handle, int iface)
{
int fd = __device_handle_priv(handle)->fd;
int r = ioctl(fd, IOCTL_USBFS_RELEASEINTF, &iface);
- if (r < 0)
+ if (r) {
usbi_err("release interface failed, error %d", r);
- return r;
+ return LIBUSB_ERROR_OTHER;
+ }
+ return 0;
}
static int op_set_interface(struct libusb_device_handle *handle, int iface,
@@ -435,9 +440,12 @@ static int op_set_interface(struct libusb_device_handle *handle, int iface,
setintf.interface = iface;
setintf.altsetting = altsetting;
r = ioctl(fd, IOCTL_USBFS_SETINTF, &setintf);
- if (r < 0)
+ if (r) {
usbi_err("setintf failed error %d", r);
- return r;
+ return LIBUSB_ERROR_OTHER;
+ }
+
+ return 0;
}
static void op_destroy_device(struct libusb_device *dev)
@@ -483,7 +491,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer,
alloc_size = num_urbs * sizeof(struct usbfs_urb);
urbs = malloc(alloc_size);
if (!urbs)
- return -ENOMEM;
+ return LIBUSB_ERROR_NOMEM;
memset(urbs, 0, alloc_size);
tpriv->urbs = urbs;
tpriv->num_urbs = num_urbs;
@@ -512,7 +520,7 @@ static int submit_bulk_transfer(struct usbi_transfer *itransfer,
if (i == 0) {
usbi_dbg("first URB failed, easy peasy");
free(urbs);
- return r;
+ return LIBUSB_ERROR_IO;
}
/* if it's not the first URB that failed, the situation is a bit
@@ -588,7 +596,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
alloc_size = num_urbs * sizeof(*urbs);
urbs = malloc(alloc_size);
if (!urbs)
- return -ENOMEM;
+ return LIBUSB_ERROR_NOMEM;
memset(urbs, 0, alloc_size);
tpriv->iso_urbs = urbs;
@@ -627,7 +635,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
urb = malloc(alloc_size);
if (!urb) {
free_iso_urbs(tpriv);
- return -ENOMEM;
+ return LIBUSB_ERROR_NOMEM;
}
memset(urb, 0, alloc_size);
urbs[i] = urb;
@@ -660,7 +668,7 @@ static int submit_iso_transfer(struct usbi_transfer *itransfer)
if (i == 0) {
usbi_dbg("first URB failed, easy peasy");
free_iso_urbs(tpriv);
- return r;
+ return LIBUSB_ERROR_IO;
}
/* if it's not the first URB that failed, the situation is a bit
@@ -708,11 +716,11 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
int r;
if (transfer->length - LIBUSB_CONTROL_SETUP_SIZE > MAX_CTRL_BUFFER_LENGTH)
- return -EINVAL;
+ return LIBUSB_ERROR_INVALID_PARAM;
urb = malloc(sizeof(struct usbfs_urb));
if (!urb)
- return -ENOMEM;
+ return LIBUSB_ERROR_NOMEM;
memset(urb, 0, sizeof(struct usbfs_urb));
tpriv->urbs = urb;
tpriv->reap_action = NORMAL;
@@ -727,8 +735,9 @@ static int submit_control_transfer(struct usbi_transfer *itransfer)
if (r < 0) {
usbi_err("submiturb failed error %d errno=%d", r, errno);
free(urb);
+ return LIBUSB_ERROR_IO;
}
- return r;
+ return 0;
}
static int op_submit_transfer(struct usbi_transfer *itransfer)
@@ -747,7 +756,7 @@ static int op_submit_transfer(struct usbi_transfer *itransfer)
return submit_iso_transfer(itransfer);
default:
usbi_err("unknown endpoint type %d", transfer->type);
- return -EINVAL;
+ return LIBUSB_ERROR_INVALID_PARAM;
}
}
@@ -765,11 +774,12 @@ static int cancel_control_transfer(struct usbi_transfer *itransfer)
if (r == -EINVAL) {
usbi_dbg("URB not found --> assuming ready to be reaped");
return 0;
- } else if (r != 0) {
+ } else if (r) {
usbi_err("unrecognised DISCARD code %d", r);
+ return LIBUSB_ERROR_OTHER;
}
- return r;
+ return 0;
}
static void cancel_bulk_transfer(struct usbi_transfer *itransfer)
@@ -831,7 +841,7 @@ static int op_cancel_transfer(struct usbi_transfer *itransfer)
return 0;
default:
usbi_err("unknown endpoint type %d", transfer->type);
- return -EINVAL;
+ return LIBUSB_ERROR_INVALID_PARAM;
}
}
@@ -1042,24 +1052,27 @@ static int reap_for_handle(struct libusb_device_handle *handle)
static int op_handle_events(fd_set *readfds, fd_set *writefds)
{
struct libusb_device_handle *handle;
- int r = 0;
+ int ret = 0;
pthread_mutex_lock(&usbi_open_devs_lock);
list_for_each_entry(handle, &usbi_open_devs, list) {
struct linux_device_handle_priv *hpriv = __device_handle_priv(handle);
+ int r;
+
if (!FD_ISSET(hpriv->fd, writefds))
continue;
r = reap_for_handle(handle);
if (r == -1 && errno == EAGAIN)
continue;
- if (r < 0)
+ if (r < 0) {
+ ret = LIBUSB_ERROR_IO;
goto out;
+ }
}
- r = 0;
out:
pthread_mutex_unlock(&usbi_open_devs_lock);
- return r;
+ return ret;
}
const struct usbi_os_backend linux_usbfs_backend = {