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;
43 list_init(&flying_urbs);
46 static int calculate_timeout(struct libusb_urb_handle *urbh,
50 struct timespec current_time;
55 r = clock_gettime(CLOCK_MONOTONIC, ¤t_time);
57 usbi_err("failed to read monotonic clock, errno=%d", errno);
61 current_time.tv_sec += timeout / 1000;
62 current_time.tv_nsec += (timeout % 1000) * 1000000;
64 if (current_time.tv_nsec > 1000000000) {
65 current_time.tv_nsec -= 1000000000;
66 current_time.tv_sec++;
69 TIMESPEC_TO_TIMEVAL(&urbh->timeout, ¤t_time);
73 static void add_to_flying_list(struct libusb_urb_handle *urbh)
75 struct libusb_urb_handle *cur;
76 struct timeval *timeout = &urbh->timeout;
78 /* if we have no other flying urbs, start the list with this one */
79 if (list_empty(&flying_urbs)) {
80 list_add(&urbh->list, &flying_urbs);
84 /* if we have infinite timeout, append to end of list */
85 if (!timerisset(timeout)) {
86 list_add_tail(&urbh->list, &flying_urbs);
90 /* otherwise, find appropriate place in list */
91 list_for_each_entry(cur, &flying_urbs, list) {
92 /* find first timeout that occurs after the urbh in question */
93 struct timeval *cur_tv = &cur->timeout;
95 if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) ||
96 (cur_tv->tv_sec == timeout->tv_sec &&
97 cur_tv->tv_usec > timeout->tv_usec)) {
98 list_add_tail(&urbh->list, &cur->list);
103 /* otherwise we need to be inserted at the end */
104 list_add_tail(&urbh->list, &flying_urbs);
107 static int submit_urb(struct libusb_dev_handle *devh,
108 struct libusb_urb_handle *urbh)
111 struct usb_urb *urb = &urbh->urb;
112 int to_be_transferred = urbh->transfer_len - urbh->transferred;
114 urb->type = urbh->urb_type;
115 urb->endpoint = urbh->endpoint;
116 urb->buffer = urbh->buffer + urbh->transferred;
117 urb->buffer_length = MIN(to_be_transferred, MAX_URB_BUFFER_LENGTH);
119 /* FIXME: for requests that we have to split into multiple URBs, we should
120 * submit all the URBs instantly: submit, submit, submit, reap, reap, reap
121 * rather than: submit, reap, submit, reap, submit, reap
122 * this will improve performance and fix bugs concerning behaviour when
123 * the user submits two similar multiple-urb requests */
124 usbi_dbg("transferring %d from %d bytes", urb->buffer_length,
127 r = ioctl(devh->fd, IOCTL_USB_SUBMITURB, &urbh->urb);
129 usbi_err("submiturb failed error %d errno=%d", r, errno);
133 add_to_flying_list(urbh);
137 API_EXPORTED struct libusb_urb_handle *libusb_async_control_transfer(
138 struct libusb_dev_handle *devh, struct libusb_control_transfer *transfer,
139 libusb_ctrl_cb_fn callback, void *user_data, unsigned int timeout)
141 struct libusb_urb_handle *urbh = malloc(sizeof(*urbh));
142 struct libusb_ctrl_setup *setup;
143 unsigned char *urbdata;
144 int urbdata_length = sizeof(struct libusb_ctrl_setup) + transfer->length;
149 memset(urbh, 0, sizeof(*urbh));
151 urbh->callback = callback;
152 urbh->user_data = user_data;
153 r = calculate_timeout(urbh, timeout);
159 urbdata = malloc(urbdata_length);
165 usbi_dbg("RQT=%02x RQ=%02x VAL=%04x IDX=%04x length=%d",
166 transfer->requesttype, transfer->request, transfer->value,
167 transfer->index, transfer->length);
169 setup = (struct libusb_ctrl_setup *) urbdata;
170 setup->bRequestType = transfer->requesttype;
171 setup->bRequest = transfer->request;
172 setup->wValue = cpu_to_le16(transfer->value);
173 setup->wIndex = cpu_to_le16(transfer->index);
174 setup->wLength = cpu_to_le16(transfer->length);
176 if ((transfer->requesttype & 0x80) == LIBUSB_ENDPOINT_OUT)
177 memcpy(urbdata + sizeof(struct libusb_ctrl_setup), transfer->data,
180 urbh->urb_type = USB_URB_TYPE_CONTROL;
181 urbh->buffer = urbdata;
182 urbh->transfer_len = urbdata_length;
184 r = submit_urb(devh, urbh);
194 static struct libusb_urb_handle *submit_bulk_transfer(
195 struct libusb_dev_handle *devh, struct libusb_bulk_transfer *transfer,
196 libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout,
197 unsigned char urbtype)
199 struct libusb_urb_handle *urbh = malloc(sizeof(*urbh));
202 usbi_dbg("length %d timeout %d", transfer->length, timeout);
206 memset(urbh, 0, sizeof(*urbh));
207 r = calculate_timeout(urbh, timeout);
213 urbh->callback = callback;
214 urbh->user_data = user_data;
215 urbh->flags |= LIBUSB_URBH_DATA_BELONGS_TO_USER;
216 urbh->endpoint = transfer->endpoint;
217 urbh->urb_type = urbtype;
218 urbh->buffer = transfer->data;
219 urbh->transfer_len = transfer->length;
221 r = submit_urb(devh, urbh);
230 API_EXPORTED struct libusb_urb_handle *libusb_async_bulk_transfer(
231 struct libusb_dev_handle *devh, struct libusb_bulk_transfer *transfer,
232 libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout)
234 return submit_bulk_transfer(devh, transfer, callback, user_data, timeout,
238 API_EXPORTED struct libusb_urb_handle *libusb_async_interrupt_transfer(
239 struct libusb_dev_handle *devh, struct libusb_bulk_transfer *transfer,
240 libusb_bulk_cb_fn callback, void *user_data, unsigned int timeout)
242 return submit_bulk_transfer(devh, transfer, callback, user_data, timeout,
243 USB_URB_TYPE_INTERRUPT);
246 API_EXPORTED int libusb_urb_handle_cancel(struct libusb_dev_handle *devh,
247 struct libusb_urb_handle *urbh)
251 r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &urbh->urb);
253 usbi_err("cancel urb failed error %d", r);
257 API_EXPORTED int libusb_urb_handle_cancel_sync(struct libusb_dev_handle *devh,
258 struct libusb_urb_handle *urbh)
262 r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &urbh->urb);
264 usbi_err("cancel urb failed error %d", r);
268 urbh->flags |= LIBUSB_URBH_SYNC_CANCELLED;
269 while (urbh->flags & LIBUSB_URBH_SYNC_CANCELLED) {
278 int handle_transfer_completion(struct libusb_dev_handle *devh,
279 struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status)
281 struct usb_urb *urb = &urbh->urb;
283 if (status == FP_URB_SILENT_COMPLETION)
286 if (urb->type == USB_URB_TYPE_CONTROL) {
287 libusb_ctrl_cb_fn callback = urbh->callback;
289 callback(devh, urbh, status, urb->buffer,
290 urb->buffer + sizeof(struct libusb_ctrl_setup), urbh->transferred,
292 } else if (urb->type == USB_URB_TYPE_BULK ||
293 urb->type == USB_URB_TYPE_INTERRUPT) {
294 libusb_bulk_cb_fn callback = urbh->callback;
296 callback(devh, urbh, status, urbh->endpoint, urbh->transfer_len,
297 urbh->buffer, urbh->transferred, urbh->user_data);
302 static int handle_transfer_cancellation(struct libusb_dev_handle *devh,
303 struct libusb_urb_handle *urbh)
305 /* if the URB is being cancelled synchronously, raise cancellation
306 * completion event by unsetting flag, and ensure that user callback does
309 if (urbh->flags & LIBUSB_URBH_SYNC_CANCELLED) {
310 urbh->flags &= ~LIBUSB_URBH_SYNC_CANCELLED;
311 usbi_dbg("detected sync. cancel");
312 return handle_transfer_completion(devh, urbh, FP_URB_SILENT_COMPLETION);
315 /* if the URB was cancelled due to timeout, report timeout to the user */
316 if (urbh->flags & LIBUSB_URBH_TIMED_OUT) {
317 usbi_dbg("detected timeout cancellation");
318 return handle_transfer_completion(devh, urbh, FP_URB_TIMEOUT);
321 /* otherwise its a normal async cancel */
322 return handle_transfer_completion(devh, urbh, FP_URB_CANCELLED);
325 static int reap_for_devh(struct libusb_dev_handle *devh)
329 struct libusb_urb_handle *urbh;
332 r = ioctl(devh->fd, IOCTL_USB_REAPURBNDELAY, &urb);
333 if (r == -1 && errno == EAGAIN)
336 usbi_err("reap failed error %d errno=%d", r, errno);
340 urbh = container_of(urb, struct libusb_urb_handle, urb);
342 usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status,
344 list_del(&urbh->list);
346 if (urb->status == -2)
347 return handle_transfer_cancellation(devh, urbh);
348 /* FIXME: research what other status codes may exist */
349 if (urb->status != 0)
350 usbi_warn("unrecognised urb status %d", urb->status);
352 /* determine how much data was asked for */
353 trf_requested = MIN(urbh->transfer_len - urbh->transferred,
354 MAX_URB_BUFFER_LENGTH);
356 urbh->transferred += urb->actual_length;
358 /* if we were provided less data than requested, then our transfer is
360 if (urb->actual_length < trf_requested) {
361 usbi_dbg("less data than requested (%d/%d) --> all done",
362 urb->actual_length, trf_requested);
363 return handle_transfer_completion(devh, urbh, FP_URB_COMPLETED);
366 /* if we've transferred all data, we're done */
367 if (urbh->transferred == urbh->transfer_len) {
368 usbi_dbg("transfer complete --> all done");
369 return handle_transfer_completion(devh, urbh, FP_URB_COMPLETED);
372 /* otherwise, we have more data to transfer */
373 usbi_dbg("more data to transfer...");
374 memset(urb, 0, sizeof(*urb));
375 return submit_urb(devh, urbh);
378 static void handle_timeout(struct libusb_urb_handle *urbh)
380 /* handling timeouts is tricky, as we may race with the kernel: we may
381 * detect a timeout racing with the condition that the urb has actually
382 * completed. we asynchronously cancel the URB and report timeout
383 * to the user when the URB cancellation completes (or not at all if the
384 * URB actually gets delivered as per this race) */
388 urbh->flags |= LIBUSB_URBH_TIMED_OUT;
389 r = libusb_urb_handle_cancel(urbh->devh, urbh);
391 usbi_warn("async cancel failed %d errno=%d", r, errno);
394 static int handle_timeouts(void)
396 struct timespec systime_ts;
397 struct timeval systime;
398 struct libusb_urb_handle *urbh;
401 if (list_empty(&flying_urbs))
404 /* get current time */
405 r = clock_gettime(CLOCK_MONOTONIC, &systime_ts);
409 TIMESPEC_TO_TIMEVAL(&systime, &systime_ts);
411 /* iterate through flying urbs list, finding all urbs that have expired
413 list_for_each_entry(urbh, &flying_urbs, list) {
414 struct timeval *cur_tv = &urbh->timeout;
416 /* if we've reached urbs of infinite timeout, we're all done */
417 if (!timerisset(cur_tv))
420 /* ignore timeouts we've already handled */
421 if (urbh->flags & LIBUSB_URBH_TIMED_OUT)
424 /* if urb has non-expired timeout, nothing more to do */
425 if ((cur_tv->tv_sec > systime.tv_sec) ||
426 (cur_tv->tv_sec == systime.tv_sec &&
427 cur_tv->tv_usec > systime.tv_usec))
430 /* otherwise, we've got an expired timeout to handle */
431 handle_timeout(urbh);
437 static int poll_io(struct timeval *tv)
439 struct libusb_dev_handle *devh;
443 struct timeval select_timeout;
444 struct timeval timeout;
446 r = libusb_get_next_timeout(&timeout);
448 /* timeout already expired? */
449 if (!timerisset(&timeout))
450 return handle_timeouts();
452 /* choose the smallest of next URB timeout or user specified timeout */
453 if (timercmp(&timeout, tv, <))
454 select_timeout = timeout;
456 select_timeout = *tv;
458 select_timeout = *tv;
462 list_for_each_entry(devh, &open_devs, list) {
464 FD_SET(fd, &writefds);
469 usbi_dbg("select() with timeout in %d.%06ds", select_timeout.tv_sec,
470 select_timeout.tv_usec);
471 r = select(maxfd + 1, NULL, &writefds, NULL, &select_timeout);
472 usbi_dbg("select() returned %d with %d.%06ds remaining", r, select_timeout.tv_sec,
473 select_timeout.tv_usec);
475 *tv = select_timeout;
476 return handle_timeouts();
477 } else if (r == -1 && errno == EINTR) {
480 usbi_err("select failed %d err=%d\n", r, errno);
484 list_for_each_entry(devh, &open_devs, list) {
485 if (!FD_ISSET(devh->fd, &writefds))
487 r = reap_for_devh(devh);
488 if (r == -1 && errno == EAGAIN)
494 /* FIXME check return value? */
495 return handle_timeouts();
498 API_EXPORTED int libusb_poll_timeout(struct timeval *tv)
503 API_EXPORTED int libusb_poll(void)
511 API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
513 struct libusb_urb_handle *urbh;
514 struct timespec cur_ts;
515 struct timeval cur_tv;
516 struct timeval *next_timeout;
520 if (list_empty(&flying_urbs)) {
521 usbi_dbg("no URBs, no timeout!");
525 /* find next urb which hasn't already been processed as timed out */
526 list_for_each_entry(urbh, &flying_urbs, list) {
527 if (!(urbh->flags & LIBUSB_URBH_TIMED_OUT)) {
534 usbi_dbg("all URBs have already been processed for timeouts");
538 next_timeout = &urbh->timeout;
540 /* no timeout for next urb */
541 if (!timerisset(next_timeout)) {
542 usbi_dbg("no URBs with timeouts, no timeout!");
546 r = clock_gettime(CLOCK_MONOTONIC, &cur_ts);
548 usbi_err("failed to read monotonic clock, errno=%d", errno);
551 TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
553 if (timercmp(&cur_tv, next_timeout, >=)) {
554 usbi_dbg("first timeout already expired");
557 timersub(next_timeout, &cur_tv, tv);
558 usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec);
564 struct sync_ctrl_handle {
565 enum libusb_urb_cb_status status;
570 static void ctrl_transfer_cb(struct libusb_dev_handle *devh,
571 struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status,
572 struct libusb_ctrl_setup *setup, unsigned char *data, int actual_length,
575 struct sync_ctrl_handle *ctrlh = (struct sync_ctrl_handle *) user_data;
576 usbi_dbg("actual_length=%d", actual_length);
578 if (status == FP_URB_COMPLETED) {
579 /* copy results into user-defined buffer */
580 if (setup->bRequestType & LIBUSB_ENDPOINT_IN)
581 memcpy(ctrlh->data, data, actual_length);
584 ctrlh->status = status;
585 ctrlh->actual_length = actual_length;
586 /* caller frees urbh */
589 API_EXPORTED int libusb_control_transfer(struct libusb_dev_handle *devh,
590 struct libusb_control_transfer *transfer, unsigned int timeout)
592 struct libusb_urb_handle *urbh;
593 struct sync_ctrl_handle ctrlh;
595 memset(&ctrlh, 0, sizeof(ctrlh));
596 ctrlh.data = transfer->data;
598 urbh = libusb_async_control_transfer(devh, transfer, ctrl_transfer_cb,
603 while (!ctrlh.status) {
604 int r = libusb_poll();
606 libusb_urb_handle_cancel_sync(devh, urbh);
607 libusb_urb_handle_free(urbh);
612 libusb_urb_handle_free(urbh);
613 switch (ctrlh.status) {
614 case FP_URB_COMPLETED:
615 return ctrlh.actual_length;
619 usbi_warn("unrecognised status code %d", ctrlh.status);
624 struct sync_bulk_handle {
625 enum libusb_urb_cb_status status;
629 static void bulk_transfer_cb(struct libusb_dev_handle *devh,
630 struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status,
631 unsigned char endpoint, int rqlength, unsigned char *data,
632 int actual_length, void *user_data)
634 struct sync_bulk_handle *bulkh = (struct sync_bulk_handle *) user_data;
636 bulkh->status = status;
637 bulkh->actual_length = actual_length;
638 /* caller frees urbh */
641 static int do_sync_bulk_transfer(struct libusb_dev_handle *devh,
642 struct libusb_bulk_transfer *transfer, int *transferred,
643 unsigned int timeout, unsigned char urbtype)
645 struct libusb_urb_handle *urbh;
646 struct sync_bulk_handle bulkh;
648 memset(&bulkh, 0, sizeof(bulkh));
650 urbh = submit_bulk_transfer(devh, transfer, bulk_transfer_cb, &bulkh,
655 while (!bulkh.status) {
656 int r = libusb_poll();
658 libusb_urb_handle_cancel_sync(devh, urbh);
659 libusb_urb_handle_free(urbh);
664 *transferred = bulkh.actual_length;
665 libusb_urb_handle_free(urbh);
667 switch (bulkh.status) {
668 case FP_URB_COMPLETED:
673 usbi_warn("unrecognised status code %d", bulkh.status);
678 API_EXPORTED int libusb_interrupt_transfer(struct libusb_dev_handle *devh,
679 struct libusb_bulk_transfer *transfer, int *transferred,
680 unsigned int timeout)
682 return do_sync_bulk_transfer(devh, transfer, transferred, timeout,
683 USB_URB_TYPE_INTERRUPT);
686 API_EXPORTED int libusb_bulk_transfer(struct libusb_dev_handle *devh,
687 struct libusb_bulk_transfer *transfer, int *transferred,
688 unsigned int timeout)
690 return do_sync_bulk_transfer(devh, transfer, transferred, timeout,
694 API_EXPORTED void libusb_urb_handle_free(struct libusb_urb_handle *urbh)
699 if (!(urbh->flags & LIBUSB_URBH_DATA_BELONGS_TO_USER))
700 free(urbh->urb.buffer);