standardised error codes
authorDaniel Drake <dsd@gentoo.org>
Tue, 29 Apr 2008 14:26:46 +0000 (15:26 +0100)
committerDaniel Drake <dsd@gentoo.org>
Tue, 29 Apr 2008 14:26:46 +0000 (15:26 +0100)
TODO
libusb/core.c
libusb/io.c
libusb/libusb.h
libusb/os/linux_usbfs.c

diff --git a/TODO b/TODO
index da22bca..89db498 100644 (file)
--- 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
index 6348c93..d33eef7 100644 (file)
@@ -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;
        }
 
index b3b2c98..453ecce 100644 (file)
@@ -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);
 
index 08d256d..66708b3 100644 (file)
@@ -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 {
index 6379da9..bbe48cb 100644 (file)
@@ -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 = {