2 * I/O functions for libusb
3 * Copyright (C) 2007 Daniel Drake <dsd@gentoo.org>
4 * Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
28 #include <sys/select.h>
35 /* this is a list of in-flight rb_handles, sorted by timeout expiration.
36 * URBs to timeout the soonest are placed at the beginning of the list, URBs
37 * that will time out later are placed after, and urbs with infinite timeout
38 * are always placed at the very end. */
39 static struct list_head flying_urbs;
41 /* user callbacks for pollfd changes */
42 static libusb_pollfd_added_cb fd_added_cb = NULL;
43 static libusb_pollfd_removed_cb fd_removed_cb = NULL;
47 list_init(&flying_urbs);
52 static int calculate_timeout(struct libusb_urb_handle *urbh,
56 struct timespec current_time;
61 r = clock_gettime(CLOCK_MONOTONIC, ¤t_time);
63 usbi_err("failed to read monotonic clock, errno=%d", errno);
67 current_time.tv_sec += timeout / 1000;
68 current_time.tv_nsec += (timeout % 1000) * 1000000;
70 if (current_time.tv_nsec > 1000000000) {
71 current_time.tv_nsec -= 1000000000;
72 current_time.tv_sec++;
75 TIMESPEC_TO_TIMEVAL(&urbh->timeout, ¤t_time);
79 static void add_to_flying_list(struct libusb_urb_handle *urbh)
81 struct libusb_urb_handle *cur;
82 struct timeval *timeout = &urbh->timeout;
84 /* if we have no other flying urbs, start the list with this one */
85 if (list_empty(&flying_urbs)) {
86 list_add(&urbh->list, &flying_urbs);
90 /* if we have infinite timeout, append to end of list */
91 if (!timerisset(timeout)) {
92 list_add_tail(&urbh->list, &flying_urbs);
96 /* otherwise, find appropriate place in list */
97 list_for_each_entry(cur, &flying_urbs, list) {
98 /* find first timeout that occurs after the urbh in question */
99 struct timeval *cur_tv = &cur->timeout;
101 if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) ||
102 (cur_tv->tv_sec == timeout->tv_sec &&
103 cur_tv->tv_usec > timeout->tv_usec)) {
104 list_add_tail(&urbh->list, &cur->list);
109 /* otherwise we need to be inserted at the end */
110 list_add_tail(&urbh->list, &flying_urbs);
113 static int submit_urb(struct libusb_dev_handle *devh,
114 struct libusb_urb_handle *urbh)
117 struct usb_urb *urb = &urbh->urb;
118 int to_be_transferred = urbh->transfer_len - urbh->transferred;
120 urb->type = urbh->urb_type;
121 urb->endpoint = urbh->endpoint;
122 urb->buffer = urbh->buffer + urbh->transferred;
123 urb->buffer_length = MIN(to_be_transferred, MAX_URB_BUFFER_LENGTH);
125 /* FIXME: for requests that we have to split into multiple URBs, we should
126 * submit all the URBs instantly: submit, submit, submit, reap, reap, reap
127 * rather than: submit, reap, submit, reap, submit, reap
128 * this will improve performance and fix bugs concerning behaviour when
129 * the user submits two similar multiple-urb requests */
130 usbi_dbg("transferring %d from %d bytes", urb->buffer_length,
133 r = ioctl(devh->fd, IOCTL_USB_SUBMITURB, &urbh->urb);
135 usbi_err("submiturb failed error %d errno=%d", r, errno);
139 add_to_flying_list(urbh);
143 API_EXPORTED struct libusb_urb_handle *libusb_async_control_transfer(
144 struct libusb_dev_handle *devh, struct libusb_control_transfer *transfer,
145 libusb_ctrl_cb_fn callback, void *user_data, unsigned int timeout)
147 struct libusb_urb_handle *urbh = malloc(sizeof(*urbh));
148 struct libusb_ctrl_setup *setup;
149 unsigned char *urbdata;
150 int urbdata_length = sizeof(struct libusb_ctrl_setup) + transfer->length;
155 memset(urbh, 0, sizeof(*urbh));
157 urbh->callback = callback;
158 urbh->user_data = user_data;
159 r = calculate_timeout(urbh, timeout);
165 urbdata = malloc(urbdata_length);
171 usbi_dbg("RQT=%02x RQ=%02x VAL=%04x IDX=%04x length=%d",
172 transfer->requesttype, transfer->request, transfer->value,
173 transfer->index, transfer->length);
175 setup = (struct libusb_ctrl_setup *) urbdata;
176 setup->bRequestType = transfer->requesttype;
177 setup->bRequest = transfer->request;
178 setup->wValue = cpu_to_le16(transfer->value);
179 setup->wIndex = cpu_to_le16(transfer->index);
180 setup->wLength = cpu_to_le16(transfer->length);
182 if ((transfer->requesttype & 0x80) == LIBUSB_ENDPOINT_OUT)
183 memcpy(urbdata + sizeof(struct libusb_ctrl_setup), transfer->data,
186 urbh->urb_type = USB_URB_TYPE_CONTROL;
187 urbh->buffer = urbdata;
188 urbh->transfer_len = urbdata_length;
190 r = submit_urb(devh, urbh);
200 static struct libusb_urb_handle *submit_bulk_transfer(
201 struct libusb_dev_handle *devh, struct libusb_bulk_transfer *transfer,
202 libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout,
203 unsigned char urbtype)
205 struct libusb_urb_handle *urbh = malloc(sizeof(*urbh));
208 usbi_dbg("length %d timeout %d", transfer->length, timeout);
212 memset(urbh, 0, sizeof(*urbh));
213 r = calculate_timeout(urbh, timeout);
219 urbh->callback = callback;
220 urbh->user_data = user_data;
221 urbh->flags |= LIBUSB_URBH_DATA_BELONGS_TO_USER;
222 urbh->endpoint = transfer->endpoint;
223 urbh->urb_type = urbtype;
224 urbh->buffer = transfer->data;
225 urbh->transfer_len = transfer->length;
227 r = submit_urb(devh, urbh);
236 API_EXPORTED struct libusb_urb_handle *libusb_async_bulk_transfer(
237 struct libusb_dev_handle *devh, struct libusb_bulk_transfer *transfer,
238 libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout)
240 return submit_bulk_transfer(devh, transfer, callback, user_data, timeout,
244 API_EXPORTED struct libusb_urb_handle *libusb_async_interrupt_transfer(
245 struct libusb_dev_handle *devh, struct libusb_bulk_transfer *transfer,
246 libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout)
248 return submit_bulk_transfer(devh, transfer, callback, user_data, timeout,
249 USB_URB_TYPE_INTERRUPT);
252 API_EXPORTED int libusb_urb_handle_cancel(struct libusb_dev_handle *devh,
253 struct libusb_urb_handle *urbh)
257 r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &urbh->urb);
259 usbi_err("cancel urb failed error %d", r);
263 API_EXPORTED int libusb_urb_handle_cancel_sync(struct libusb_dev_handle *devh,
264 struct libusb_urb_handle *urbh)
268 r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &urbh->urb);
270 usbi_err("cancel urb failed error %d", r);
274 urbh->flags |= LIBUSB_URBH_SYNC_CANCELLED;
275 while (urbh->flags & LIBUSB_URBH_SYNC_CANCELLED) {
284 int handle_transfer_completion(struct libusb_dev_handle *devh,
285 struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status)
287 struct usb_urb *urb = &urbh->urb;
289 if (status == FP_URB_SILENT_COMPLETION)
292 if (urb->type == USB_URB_TYPE_CONTROL) {
293 libusb_ctrl_cb_fn callback = urbh->callback;
295 callback(devh, urbh, status, urb->buffer,
296 urb->buffer + sizeof(struct libusb_ctrl_setup), urbh->transferred,
298 } else if (urb->type == USB_URB_TYPE_BULK ||
299 urb->type == USB_URB_TYPE_INTERRUPT) {
300 libusb_bulk_cb_fn callback = urbh->callback;
302 callback(devh, urbh, status, urbh->endpoint, urbh->transfer_len,
303 urbh->buffer, urbh->transferred, urbh->user_data);
308 static int handle_transfer_cancellation(struct libusb_dev_handle *devh,
309 struct libusb_urb_handle *urbh)
311 /* if the URB is being cancelled synchronously, raise cancellation
312 * completion event by unsetting flag, and ensure that user callback does
315 if (urbh->flags & LIBUSB_URBH_SYNC_CANCELLED) {
316 urbh->flags &= ~LIBUSB_URBH_SYNC_CANCELLED;
317 usbi_dbg("detected sync. cancel");
318 return handle_transfer_completion(devh, urbh, FP_URB_SILENT_COMPLETION);
321 /* if the URB was cancelled due to timeout, report timeout to the user */
322 if (urbh->flags & LIBUSB_URBH_TIMED_OUT) {
323 usbi_dbg("detected timeout cancellation");
324 return handle_transfer_completion(devh, urbh, FP_URB_TIMEOUT);
327 /* otherwise its a normal async cancel */
328 return handle_transfer_completion(devh, urbh, FP_URB_CANCELLED);
331 static int reap_for_devh(struct libusb_dev_handle *devh)
335 struct libusb_urb_handle *urbh;
338 r = ioctl(devh->fd, IOCTL_USB_REAPURBNDELAY, &urb);
339 if (r == -1 && errno == EAGAIN)
342 usbi_err("reap failed error %d errno=%d", r, errno);
346 urbh = container_of(urb, struct libusb_urb_handle, urb);
348 usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status,
350 list_del(&urbh->list);
352 if (urb->status == -2)
353 return handle_transfer_cancellation(devh, urbh);
354 /* FIXME: research what other status codes may exist */
355 if (urb->status != 0)
356 usbi_warn("unrecognised urb status %d", urb->status);
358 /* determine how much data was asked for */
359 trf_requested = MIN(urbh->transfer_len - urbh->transferred,
360 MAX_URB_BUFFER_LENGTH);
362 urbh->transferred += urb->actual_length;
364 /* if we were provided less data than requested, then our transfer is
366 if (urb->actual_length < trf_requested) {
367 usbi_dbg("less data than requested (%d/%d) --> all done",
368 urb->actual_length, trf_requested);
369 return handle_transfer_completion(devh, urbh, FP_URB_COMPLETED);
372 /* if we've transferred all data, we're done */
373 if (urbh->transferred == urbh->transfer_len) {
374 usbi_dbg("transfer complete --> all done");
375 return handle_transfer_completion(devh, urbh, FP_URB_COMPLETED);
378 /* otherwise, we have more data to transfer */
379 usbi_dbg("more data to transfer...");
380 memset(urb, 0, sizeof(*urb));
381 return submit_urb(devh, urbh);
384 static void handle_timeout(struct libusb_urb_handle *urbh)
386 /* handling timeouts is tricky, as we may race with the kernel: we may
387 * detect a timeout racing with the condition that the urb has actually
388 * completed. we asynchronously cancel the URB and report timeout
389 * to the user when the URB cancellation completes (or not at all if the
390 * URB actually gets delivered as per this race) */
394 urbh->flags |= LIBUSB_URBH_TIMED_OUT;
395 r = libusb_urb_handle_cancel(urbh->devh, urbh);
397 usbi_warn("async cancel failed %d errno=%d", r, errno);
400 static int handle_timeouts(void)
402 struct timespec systime_ts;
403 struct timeval systime;
404 struct libusb_urb_handle *urbh;
407 if (list_empty(&flying_urbs))
410 /* get current time */
411 r = clock_gettime(CLOCK_MONOTONIC, &systime_ts);
415 TIMESPEC_TO_TIMEVAL(&systime, &systime_ts);
417 /* iterate through flying urbs list, finding all urbs that have expired
419 list_for_each_entry(urbh, &flying_urbs, list) {
420 struct timeval *cur_tv = &urbh->timeout;
422 /* if we've reached urbs of infinite timeout, we're all done */
423 if (!timerisset(cur_tv))
426 /* ignore timeouts we've already handled */
427 if (urbh->flags & LIBUSB_URBH_TIMED_OUT)
430 /* if urb has non-expired timeout, nothing more to do */
431 if ((cur_tv->tv_sec > systime.tv_sec) ||
432 (cur_tv->tv_sec == systime.tv_sec &&
433 cur_tv->tv_usec > systime.tv_usec))
436 /* otherwise, we've got an expired timeout to handle */
437 handle_timeout(urbh);
443 static int poll_io(struct timeval *tv)
445 struct libusb_dev_handle *devh;
449 struct timeval select_timeout;
450 struct timeval timeout;
452 r = libusb_get_next_timeout(&timeout);
454 /* timeout already expired? */
455 if (!timerisset(&timeout))
456 return handle_timeouts();
458 /* choose the smallest of next URB timeout or user specified timeout */
459 if (timercmp(&timeout, tv, <))
460 select_timeout = timeout;
462 select_timeout = *tv;
464 select_timeout = *tv;
468 list_for_each_entry(devh, &open_devs, list) {
470 FD_SET(fd, &writefds);
475 usbi_dbg("select() with timeout in %d.%06ds", select_timeout.tv_sec,
476 select_timeout.tv_usec);
477 r = select(maxfd + 1, NULL, &writefds, NULL, &select_timeout);
478 usbi_dbg("select() returned %d with %d.%06ds remaining", r, select_timeout.tv_sec,
479 select_timeout.tv_usec);
481 *tv = select_timeout;
482 return handle_timeouts();
483 } else if (r == -1 && errno == EINTR) {
486 usbi_err("select failed %d err=%d\n", r, errno);
490 list_for_each_entry(devh, &open_devs, list) {
491 if (!FD_ISSET(devh->fd, &writefds))
493 r = reap_for_devh(devh);
494 if (r == -1 && errno == EAGAIN)
500 /* FIXME check return value? */
501 return handle_timeouts();
504 API_EXPORTED int libusb_poll_timeout(struct timeval *tv)
509 API_EXPORTED int libusb_poll(void)
517 API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
519 struct libusb_urb_handle *urbh;
520 struct timespec cur_ts;
521 struct timeval cur_tv;
522 struct timeval *next_timeout;
526 if (list_empty(&flying_urbs)) {
527 usbi_dbg("no URBs, no timeout!");
531 /* find next urb which hasn't already been processed as timed out */
532 list_for_each_entry(urbh, &flying_urbs, list) {
533 if (!(urbh->flags & LIBUSB_URBH_TIMED_OUT)) {
540 usbi_dbg("all URBs have already been processed for timeouts");
544 next_timeout = &urbh->timeout;
546 /* no timeout for next urb */
547 if (!timerisset(next_timeout)) {
548 usbi_dbg("no URBs with timeouts, no timeout!");
552 r = clock_gettime(CLOCK_MONOTONIC, &cur_ts);
554 usbi_err("failed to read monotonic clock, errno=%d", errno);
557 TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
559 if (timercmp(&cur_tv, next_timeout, >=)) {
560 usbi_dbg("first timeout already expired");
563 timersub(next_timeout, &cur_tv, tv);
564 usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec);
570 struct sync_ctrl_handle {
571 enum libusb_urb_cb_status status;
576 static void ctrl_transfer_cb(struct libusb_dev_handle *devh,
577 struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status,
578 struct libusb_ctrl_setup *setup, unsigned char *data, int actual_length,
581 struct sync_ctrl_handle *ctrlh = (struct sync_ctrl_handle *) user_data;
582 usbi_dbg("actual_length=%d", actual_length);
584 if (status == FP_URB_COMPLETED) {
585 /* copy results into user-defined buffer */
586 if (setup->bRequestType & LIBUSB_ENDPOINT_IN)
587 memcpy(ctrlh->data, data, actual_length);
590 ctrlh->status = status;
591 ctrlh->actual_length = actual_length;
592 /* caller frees urbh */
595 API_EXPORTED int libusb_control_transfer(struct libusb_dev_handle *devh,
596 struct libusb_control_transfer *transfer, unsigned int timeout)
598 struct libusb_urb_handle *urbh;
599 struct sync_ctrl_handle ctrlh;
601 memset(&ctrlh, 0, sizeof(ctrlh));
602 ctrlh.data = transfer->data;
604 urbh = libusb_async_control_transfer(devh, transfer, ctrl_transfer_cb,
609 while (!ctrlh.status) {
610 int r = libusb_poll();
612 libusb_urb_handle_cancel_sync(devh, urbh);
613 libusb_urb_handle_free(urbh);
618 libusb_urb_handle_free(urbh);
619 switch (ctrlh.status) {
620 case FP_URB_COMPLETED:
621 return ctrlh.actual_length;
625 usbi_warn("unrecognised status code %d", ctrlh.status);
630 struct sync_bulk_handle {
631 enum libusb_urb_cb_status status;
635 static void bulk_transfer_cb(struct libusb_dev_handle *devh,
636 struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status,
637 unsigned char endpoint, int rqlength, unsigned char *data,
638 int actual_length, void *user_data)
640 struct sync_bulk_handle *bulkh = (struct sync_bulk_handle *) user_data;
642 bulkh->status = status;
643 bulkh->actual_length = actual_length;
644 /* caller frees urbh */
647 static int do_sync_bulk_transfer(struct libusb_dev_handle *devh,
648 struct libusb_bulk_transfer *transfer, int *transferred,
649 unsigned int timeout, unsigned char urbtype)
651 struct libusb_urb_handle *urbh;
652 struct sync_bulk_handle bulkh;
654 memset(&bulkh, 0, sizeof(bulkh));
656 urbh = submit_bulk_transfer(devh, transfer, bulk_transfer_cb, &bulkh,
661 while (!bulkh.status) {
662 int r = libusb_poll();
664 libusb_urb_handle_cancel_sync(devh, urbh);
665 libusb_urb_handle_free(urbh);
670 *transferred = bulkh.actual_length;
671 libusb_urb_handle_free(urbh);
673 switch (bulkh.status) {
674 case FP_URB_COMPLETED:
679 usbi_warn("unrecognised status code %d", bulkh.status);
684 API_EXPORTED int libusb_interrupt_transfer(struct libusb_dev_handle *devh,
685 struct libusb_bulk_transfer *transfer, int *transferred,
686 unsigned int timeout)
688 return do_sync_bulk_transfer(devh, transfer, transferred, timeout,
689 USB_URB_TYPE_INTERRUPT);
692 API_EXPORTED int libusb_bulk_transfer(struct libusb_dev_handle *devh,
693 struct libusb_bulk_transfer *transfer, int *transferred,
694 unsigned int timeout)
696 return do_sync_bulk_transfer(devh, transfer, transferred, timeout,
700 API_EXPORTED void libusb_urb_handle_free(struct libusb_urb_handle *urbh)
705 if (!(urbh->flags & LIBUSB_URBH_DATA_BELONGS_TO_USER))
706 free(urbh->urb.buffer);
710 API_EXPORTED void libusb_set_pollfd_notifiers(libusb_pollfd_added_cb added_cb,
711 libusb_pollfd_removed_cb removed_cb)
713 fd_added_cb = added_cb;
714 fd_removed_cb = removed_cb;
717 void usbi_add_pollfd(int fd, short events)
719 usbi_dbg("add fd %d events %d", fd, events);
721 fd_added_cb(fd, events);
724 void usbi_remove_pollfd(int fd)
726 usbi_dbg("remove fd %d", fd);