summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Drake <dsd@gentoo.org>2008-03-09 01:01:57 +0000
committerDaniel Drake <dsd@gentoo.org>2008-03-09 01:06:08 +0000
commit1ac0a7d88f282b6f293c456fac8edb143cbaca3d (patch)
treee75ff5bcaf431f71fa6189c5c0ddaa185470ea39
parent66348c90ea4570bf999ac301089e006d0cce1926 (diff)
downloadlibusb-1ac0a7d88f282b6f293c456fac8edb143cbaca3d.tar.gz
Move synchronous I/O implementation to its own file
-rw-r--r--libusb/Makefile.am2
-rw-r--r--libusb/io.c150
-rw-r--r--libusb/sync.c169
3 files changed, 171 insertions, 150 deletions
diff --git a/libusb/Makefile.am b/libusb/Makefile.am
index ff69290..462bd2f 100644
--- a/libusb/Makefile.am
+++ b/libusb/Makefile.am
@@ -1,7 +1,7 @@
lib_LTLIBRARIES = libusb-1.0.la
libusb_1_0_la_CFLAGS = -fvisibility=hidden $(AM_CFLAGS)
-libusb_1_0_la_SOURCES = libusbi.h usbfs.h core.c descriptor.c io.c
+libusb_1_0_la_SOURCES = libusbi.h usbfs.h core.c descriptor.c io.c sync.c
libusb_1_0_la_LIBADD = -lrt
hdrdir = $(includedir)/libusb-1.0
diff --git a/libusb/io.c b/libusb/io.c
index accecab..522a010 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -19,12 +19,11 @@
*/
#include <config.h>
-
#include <errno.h>
#include <signal.h>
#include <stdint.h>
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
#include <sys/select.h>
#include <sys/time.h>
#include <time.h>
@@ -532,153 +531,6 @@ API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
return 1;
}
-static void ctrl_transfer_cb(struct libusb_transfer *transfer)
-{
- int *completed = transfer->user_data;
- *completed = 1;
- usbi_dbg("actual_length=%d", transfer->actual_length);
- /* caller interprets result and frees transfer */
-}
-
-API_EXPORTED int libusb_control_transfer(libusb_dev_handle *dev_handle,
- uint8_t bRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
- unsigned char *data, uint16_t wLength, unsigned int timeout)
-{
- struct libusb_transfer *transfer = libusb_alloc_transfer();
- unsigned char *buffer;
- int length = wLength + LIBUSB_CONTROL_SETUP_SIZE;
- int completed = 0;
- int r;
-
- if (!transfer)
- return -ENOMEM;
-
- buffer = malloc(length);
- if (!buffer) {
- libusb_free_transfer(transfer);
- return -ENOMEM;
- }
-
- libusb_fill_control_setup(buffer, bRequestType, bRequest, wValue, wIndex,
- wLength);
- if ((bRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
- memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength);
-
- libusb_fill_control_transfer(transfer, dev_handle, buffer, length,
- ctrl_transfer_cb, &completed, timeout);
- r = libusb_submit_transfer(transfer);
- if (r < 0) {
- libusb_free_transfer(transfer);
- return r;
- }
-
- while (!completed) {
- r = libusb_poll();
- if (r < 0) {
- libusb_cancel_transfer_sync(dev_handle, transfer);
- libusb_free_transfer(transfer);
- return r;
- }
- }
-
- if ((bRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
- memcpy(data, libusb_control_transfer_get_data(transfer),
- transfer->actual_length);
-
- switch (transfer->status) {
- case LIBUSB_TRANSFER_COMPLETED:
- r = transfer->actual_length;
- break;
- case LIBUSB_TRANSFER_TIMED_OUT:
- r = -ETIMEDOUT;
- break;
- default:
- usbi_warn("unrecognised status code %d", transfer->status);
- r = -1;
- }
-
- libusb_free_transfer(transfer);
- return r;
-}
-
-struct sync_bulk_handle {
- enum libusb_transfer_status status;
- int actual_length;
-};
-
-static void bulk_transfer_cb(struct libusb_transfer *transfer)
-{
- int *completed = transfer->user_data;
- *completed = 1;
- usbi_dbg("actual_length=%d", transfer->actual_length);
- /* caller interprets results and frees transfer */
-}
-
-static int do_sync_bulk_transfer(struct libusb_dev_handle *dev_handle,
- unsigned char endpoint, unsigned char *buffer, int length,
- int *transferred, unsigned int timeout, unsigned char endpoint_type)
-{
- struct libusb_transfer *transfer = libusb_alloc_transfer();
- int completed = 0;
- int r;
-
- if (!transfer)
- return -ENOMEM;
-
- libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
- bulk_transfer_cb, &completed, timeout);
- transfer->endpoint_type = endpoint_type;
-
- r = libusb_submit_transfer(transfer);
- if (r < 0) {
- libusb_free_transfer(transfer);
- return r;
- }
-
- while (!completed) {
- r = libusb_poll();
- if (r < 0) {
- libusb_cancel_transfer_sync(dev_handle, transfer);
- libusb_free_transfer(transfer);
- return r;
- }
- }
-
- *transferred = transfer->actual_length;
- switch (transfer->status) {
- case LIBUSB_TRANSFER_COMPLETED:
- r = 0;
- break;
- case LIBUSB_TRANSFER_TIMED_OUT:
- r = -ETIMEDOUT;
- break;
- default:
- usbi_warn("unrecognised status code %d", transfer->status);
- r = -1;
- }
-
- libusb_free_transfer(transfer);
- return r;
-}
-
-/* FIXME: should transferred be the return value? */
-API_EXPORTED int libusb_bulk_transfer(struct libusb_dev_handle *dev_handle,
- unsigned char endpoint, unsigned char *data, int length, int *transferred,
- unsigned int timeout)
-{
- return do_sync_bulk_transfer(dev_handle, endpoint, data, length,
- transferred, timeout, LIBUSB_ENDPOINT_TYPE_BULK);
-}
-
-/* FIXME: do we need an interval param here? usbfs doesn't expose it? */
-API_EXPORTED int libusb_interrupt_transfer(struct libusb_dev_handle *dev_handle,
- unsigned char endpoint, unsigned char *data, int length, int *transferred,
- unsigned int timeout)
-{
- return do_sync_bulk_transfer(dev_handle, endpoint, data, length,
- transferred, timeout, LIBUSB_ENDPOINT_TYPE_INTERRUPT);
-}
-
API_EXPORTED void libusb_free_transfer(struct libusb_transfer *transfer)
{
struct usbi_transfer *itransfer;
diff --git a/libusb/sync.c b/libusb/sync.c
new file mode 100644
index 0000000..2bcfc5b
--- /dev/null
+++ b/libusb/sync.c
@@ -0,0 +1,169 @@
+/*
+ * Synchronous I/O functions for libusb
+ * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <config.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "libusbi.h"
+
+static void ctrl_transfer_cb(struct libusb_transfer *transfer)
+{
+ int *completed = transfer->user_data;
+ *completed = 1;
+ usbi_dbg("actual_length=%d", transfer->actual_length);
+ /* caller interprets result and frees transfer */
+}
+
+API_EXPORTED int libusb_control_transfer(libusb_dev_handle *dev_handle,
+ uint8_t bRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
+ unsigned char *data, uint16_t wLength, unsigned int timeout)
+{
+ struct libusb_transfer *transfer = libusb_alloc_transfer();
+ unsigned char *buffer;
+ int length = wLength + LIBUSB_CONTROL_SETUP_SIZE;
+ int completed = 0;
+ int r;
+
+ if (!transfer)
+ return -ENOMEM;
+
+ buffer = malloc(length);
+ if (!buffer) {
+ libusb_free_transfer(transfer);
+ return -ENOMEM;
+ }
+
+ libusb_fill_control_setup(buffer, bRequestType, bRequest, wValue, wIndex,
+ wLength);
+ if ((bRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
+ memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength);
+
+ libusb_fill_control_transfer(transfer, dev_handle, buffer, length,
+ ctrl_transfer_cb, &completed, timeout);
+ r = libusb_submit_transfer(transfer);
+ if (r < 0) {
+ libusb_free_transfer(transfer);
+ return r;
+ }
+
+ while (!completed) {
+ r = libusb_poll();
+ if (r < 0) {
+ libusb_cancel_transfer_sync(dev_handle, transfer);
+ libusb_free_transfer(transfer);
+ return r;
+ }
+ }
+
+ if ((bRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
+ memcpy(data, libusb_control_transfer_get_data(transfer),
+ transfer->actual_length);
+
+ switch (transfer->status) {
+ case LIBUSB_TRANSFER_COMPLETED:
+ r = transfer->actual_length;
+ break;
+ case LIBUSB_TRANSFER_TIMED_OUT:
+ r = -ETIMEDOUT;
+ break;
+ default:
+ usbi_warn("unrecognised status code %d", transfer->status);
+ r = -1;
+ }
+
+ libusb_free_transfer(transfer);
+ return r;
+}
+
+static void bulk_transfer_cb(struct libusb_transfer *transfer)
+{
+ int *completed = transfer->user_data;
+ *completed = 1;
+ usbi_dbg("actual_length=%d", transfer->actual_length);
+ /* caller interprets results and frees transfer */
+}
+
+static int do_sync_bulk_transfer(struct libusb_dev_handle *dev_handle,
+ unsigned char endpoint, unsigned char *buffer, int length,
+ int *transferred, unsigned int timeout, unsigned char endpoint_type)
+{
+ struct libusb_transfer *transfer = libusb_alloc_transfer();
+ int completed = 0;
+ int r;
+
+ if (!transfer)
+ return -ENOMEM;
+
+ libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length,
+ bulk_transfer_cb, &completed, timeout);
+ transfer->endpoint_type = endpoint_type;
+
+ r = libusb_submit_transfer(transfer);
+ if (r < 0) {
+ libusb_free_transfer(transfer);
+ return r;
+ }
+
+ while (!completed) {
+ r = libusb_poll();
+ if (r < 0) {
+ libusb_cancel_transfer_sync(dev_handle, transfer);
+ libusb_free_transfer(transfer);
+ return r;
+ }
+ }
+
+ *transferred = transfer->actual_length;
+ switch (transfer->status) {
+ case LIBUSB_TRANSFER_COMPLETED:
+ r = 0;
+ break;
+ case LIBUSB_TRANSFER_TIMED_OUT:
+ r = -ETIMEDOUT;
+ break;
+ default:
+ usbi_warn("unrecognised status code %d", transfer->status);
+ r = -1;
+ }
+
+ libusb_free_transfer(transfer);
+ return r;
+}
+
+/* FIXME: should transferred be the return value? */
+API_EXPORTED int libusb_bulk_transfer(struct libusb_dev_handle *dev_handle,
+ unsigned char endpoint, unsigned char *data, int length, int *transferred,
+ unsigned int timeout)
+{
+ return do_sync_bulk_transfer(dev_handle, endpoint, data, length,
+ transferred, timeout, LIBUSB_ENDPOINT_TYPE_BULK);
+}
+
+/* FIXME: do we need an interval param here? usbfs doesn't expose it? */
+API_EXPORTED int libusb_interrupt_transfer(struct libusb_dev_handle *dev_handle,
+ unsigned char endpoint, unsigned char *data, int length, int *transferred,
+ unsigned int timeout)
+{
+ return do_sync_bulk_transfer(dev_handle, endpoint, data, length,
+ transferred, timeout, LIBUSB_ENDPOINT_TYPE_INTERRUPT);
+}
+