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) {
285 int handle_transfer_completion(struct libusb_dev_handle *devh,
286 struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status)
288 struct usb_urb *urb = &urbh->urb;
290 if (status == FP_URB_SILENT_COMPLETION)
293 if (urb->type == USB_URB_TYPE_CONTROL) {
294 libusb_ctrl_cb_fn callback = urbh->callback;
296 printf("ctrl completed status %d\n", status);
297 for (i = 0; i < urbh->transferred + sizeof(struct libusb_ctrl_setup); i++)
298 printf("%02x ", ((unsigned char *) urb->buffer)[i]);
301 callback(devh, urbh, status, urb->buffer,
302 urb->buffer + sizeof(struct libusb_ctrl_setup), urbh->transferred,
304 } else if (urb->type == USB_URB_TYPE_BULK ||
305 urb->type == USB_URB_TYPE_INTERRUPT) {
306 libusb_bulk_cb_fn callback = urbh->callback;
308 callback(devh, urbh, status, urbh->endpoint, urbh->transfer_len,
309 urbh->buffer, urbh->transferred, urbh->user_data);
314 static int handle_transfer_cancellation(struct libusb_dev_handle *devh,
315 struct libusb_urb_handle *urbh)
317 /* if the URB is being cancelled synchronously, raise cancellation
318 * completion event by unsetting flag, and ensure that user callback does
321 if (urbh->flags & LIBUSB_URBH_SYNC_CANCELLED) {
322 urbh->flags &= ~LIBUSB_URBH_SYNC_CANCELLED;
323 usbi_dbg("detected sync. cancel");
324 return handle_transfer_completion(devh, urbh, FP_URB_SILENT_COMPLETION);
327 /* if the URB was cancelled due to timeout, report timeout to the user */
328 if (urbh->flags & LIBUSB_URBH_TIMED_OUT) {
329 usbi_dbg("detected timeout cancellation");
330 return handle_transfer_completion(devh, urbh, FP_URB_TIMEOUT);
333 /* otherwise its a normal async cancel */
334 return handle_transfer_completion(devh, urbh, FP_URB_CANCELLED);
337 static int reap_for_devh(struct libusb_dev_handle *devh)
341 struct libusb_urb_handle *urbh;
344 r = ioctl(devh->fd, IOCTL_USB_REAPURBNDELAY, &urb);
345 if (r == -1 && errno == EAGAIN)
348 usbi_err("reap failed error %d errno=%d", r, errno);
352 urbh = container_of(urb, struct libusb_urb_handle, urb);
354 usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status,
356 list_del(&urbh->list);
358 if (urb->status == -2)
359 return handle_transfer_cancellation(devh, urbh);
360 /* FIXME: research what other status codes may exist */
361 if (urb->status != 0)
362 usbi_warn("unrecognised urb status %d", urb->status);
364 /* determine how much data was asked for */
365 trf_requested = MIN(urbh->transfer_len - urbh->transferred,
366 MAX_URB_BUFFER_LENGTH);
368 urbh->transferred += urb->actual_length;
370 /* if we were provided less data than requested, then our transfer is
372 if (urb->actual_length < trf_requested) {
373 usbi_dbg("less data than requested (%d/%d) --> all done",
374 urb->actual_length, trf_requested);
375 return handle_transfer_completion(devh, urbh, FP_URB_COMPLETED);
378 /* if we've transferred all data, we're done */
379 if (urbh->transferred == urbh->transfer_len) {
380 usbi_dbg("transfer complete --> all done");
381 return handle_transfer_completion(devh, urbh, FP_URB_COMPLETED);
384 /* otherwise, we have more data to transfer */
385 usbi_dbg("more data to transfer...");
386 memset(urb, 0, sizeof(*urb));
387 return submit_urb(devh, urbh);
390 static void handle_timeout(struct libusb_urb_handle *urbh)
392 /* handling timeouts is tricky, as we may race with the kernel: we may
393 * detect a timeout racing with the condition that the urb has actually
394 * completed. we asynchronously cancel the URB and report timeout
395 * to the user when the URB cancellation completes (or not at all if the
396 * URB actually gets delivered as per this race) */
400 urbh->flags |= LIBUSB_URBH_TIMED_OUT;
401 r = libusb_urb_handle_cancel(urbh->devh, urbh);
403 usbi_warn("async cancel failed %d errno=%d", r, errno);
406 static int handle_timeouts(void)
408 struct timespec systime_ts;
409 struct timeval systime;
410 struct libusb_urb_handle *urbh;
413 if (list_empty(&flying_urbs))
416 /* get current time */
417 r = clock_gettime(CLOCK_MONOTONIC, &systime_ts);
421 TIMESPEC_TO_TIMEVAL(&systime, &systime_ts);
423 /* iterate through flying urbs list, finding all urbs that have expired
425 list_for_each_entry(urbh, &flying_urbs, list) {
426 struct timeval *cur_tv = &urbh->timeout;
428 /* if we've reached urbs of infinite timeout, we're all done */
429 if (!timerisset(cur_tv))
432 /* ignore timeouts we've already handled */
433 if (urbh->flags & LIBUSB_URBH_TIMED_OUT)
436 /* if urb has non-expired timeout, nothing more to do */
437 if ((cur_tv->tv_sec > systime.tv_sec) ||
438 (cur_tv->tv_sec == systime.tv_sec &&
439 cur_tv->tv_usec > systime.tv_usec))
442 /* otherwise, we've got an expired timeout to handle */
443 handle_timeout(urbh);
449 static int poll_io(struct timeval *tv)
451 struct libusb_dev_handle *devh;
455 struct timeval select_timeout;
456 struct timeval timeout;
458 r = libusb_get_next_timeout(&timeout);
460 /* timeout already expired? */
461 if (!timerisset(&timeout))
462 return handle_timeouts();
464 /* choose the smallest of next URB timeout or user specified timeout */
465 if (timercmp(&timeout, tv, <))
466 select_timeout = timeout;
468 select_timeout = *tv;
470 select_timeout = *tv;
474 list_for_each_entry(devh, &open_devs, list) {
476 FD_SET(fd, &writefds);
481 usbi_dbg("select() with timeout in %d.%06ds", select_timeout.tv_sec,
482 select_timeout.tv_usec);
483 r = select(maxfd + 1, NULL, &writefds, NULL, &select_timeout);
484 usbi_dbg("select() returned %d with %d.%06ds remaining", r, select_timeout.tv_sec,
485 select_timeout.tv_usec);
487 *tv = select_timeout;
488 return handle_timeouts();
489 } else if (r == -1 && errno == EINTR) {
492 usbi_err("select failed %d err=%d\n", r, errno);
496 list_for_each_entry(devh, &open_devs, list) {
497 if (!FD_ISSET(devh->fd, &writefds))
499 r = reap_for_devh(devh);
500 if (r == -1 && errno == EAGAIN)
506 /* FIXME check return value? */
507 return handle_timeouts();
510 API_EXPORTED int libusb_poll_timeout(struct timeval *tv)
515 API_EXPORTED int libusb_poll(void)
523 API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
525 struct libusb_urb_handle *urbh;
526 struct timespec cur_ts;
527 struct timeval cur_tv;
528 struct timeval *next_timeout;
532 if (list_empty(&flying_urbs)) {
533 usbi_dbg("no URBs, no timeout!");
537 /* find next urb which hasn't already been processed as timed out */
538 list_for_each_entry(urbh, &flying_urbs, list) {
539 if (!(urbh->flags & LIBUSB_URBH_TIMED_OUT)) {
546 usbi_dbg("all URBs have already been processed for timeouts");
550 next_timeout = &urbh->timeout;
552 /* no timeout for next urb */
553 if (!timerisset(next_timeout)) {
554 usbi_dbg("no URBs with timeouts, no timeout!");
558 r = clock_gettime(CLOCK_MONOTONIC, &cur_ts);
560 usbi_err("failed to read monotonic clock, errno=%d", errno);
563 TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
565 if (timercmp(&cur_tv, next_timeout, >=)) {
566 usbi_dbg("first timeout already expired");
569 timersub(next_timeout, &cur_tv, tv);
570 usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec);
576 struct sync_ctrl_handle {
577 enum libusb_urb_cb_status status;
582 static void ctrl_transfer_cb(struct libusb_dev_handle *devh,
583 struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status,
584 struct libusb_ctrl_setup *setup, unsigned char *data, int actual_length,
587 struct sync_ctrl_handle *ctrlh = (struct sync_ctrl_handle *) user_data;
588 usbi_dbg("actual_length=%d", actual_length);
590 if (status == FP_URB_COMPLETED) {
591 /* copy results into user-defined buffer */
592 if (setup->bRequestType & LIBUSB_ENDPOINT_IN)
593 memcpy(ctrlh->data, data, actual_length);
596 ctrlh->status = status;
597 ctrlh->actual_length = actual_length;
598 /* caller frees urbh */
601 API_EXPORTED int libusb_control_transfer(struct libusb_dev_handle *devh,
602 struct libusb_control_transfer *transfer, unsigned int timeout)
604 struct libusb_urb_handle *urbh;
605 struct sync_ctrl_handle ctrlh;
607 memset(&ctrlh, 0, sizeof(ctrlh));
608 ctrlh.data = transfer->data;
610 urbh = libusb_async_control_transfer(devh, transfer, ctrl_transfer_cb,
615 while (!ctrlh.status) {
616 int r = libusb_poll();
618 libusb_urb_handle_cancel_sync(devh, urbh);
619 libusb_urb_handle_free(urbh);
624 libusb_urb_handle_free(urbh);
625 switch (ctrlh.status) {
626 case FP_URB_COMPLETED:
627 return ctrlh.actual_length;
631 usbi_warn("unrecognised status code %d", ctrlh.status);
636 struct sync_bulk_handle {
637 enum libusb_urb_cb_status status;
641 static void bulk_transfer_cb(struct libusb_dev_handle *devh,
642 struct libusb_urb_handle *urbh, enum libusb_urb_cb_status status,
643 unsigned char endpoint, int rqlength, unsigned char *data,
644 int actual_length, void *user_data)
646 struct sync_bulk_handle *bulkh = (struct sync_bulk_handle *) user_data;
648 bulkh->status = status;
649 bulkh->actual_length = actual_length;
650 /* caller frees urbh */
653 static int do_sync_bulk_transfer(struct libusb_dev_handle *devh,
654 struct libusb_bulk_transfer *transfer, int *transferred,
655 unsigned int timeout, unsigned char urbtype)
657 struct libusb_urb_handle *urbh;
658 struct sync_bulk_handle bulkh;
660 memset(&bulkh, 0, sizeof(bulkh));
662 urbh = submit_bulk_transfer(devh, transfer, bulk_transfer_cb, &bulkh,
667 while (!bulkh.status) {
668 int r = libusb_poll();
670 libusb_urb_handle_cancel_sync(devh, urbh);
671 libusb_urb_handle_free(urbh);
676 *transferred = bulkh.actual_length;
677 libusb_urb_handle_free(urbh);
679 switch (bulkh.status) {
680 case FP_URB_COMPLETED:
685 usbi_warn("unrecognised status code %d", bulkh.status);
690 API_EXPORTED int libusb_interrupt_transfer(struct libusb_dev_handle *devh,
691 struct libusb_bulk_transfer *transfer, int *transferred,
692 unsigned int timeout)
694 return do_sync_bulk_transfer(devh, transfer, transferred, timeout,
695 USB_URB_TYPE_INTERRUPT);
698 API_EXPORTED int libusb_bulk_transfer(struct libusb_dev_handle *devh,
699 struct libusb_bulk_transfer *transfer, int *transferred,
700 unsigned int timeout)
702 return do_sync_bulk_transfer(devh, transfer, transferred, timeout,
706 API_EXPORTED void libusb_urb_handle_free(struct libusb_urb_handle *urbh)
711 if (!(urbh->flags & LIBUSB_URBH_DATA_BELONGS_TO_USER))
712 free(urbh->urb.buffer);
716 API_EXPORTED void libusb_set_pollfd_notifiers(libusb_pollfd_added_cb added_cb,
717 libusb_pollfd_removed_cb removed_cb)
719 fd_added_cb = added_cb;
720 fd_removed_cb = removed_cb;
723 void usbi_add_pollfd(int fd, short events)
725 usbi_dbg("add fd %d events %d", fd, events);
727 fd_added_cb(fd, events);
730 void usbi_remove_pollfd(int fd)
732 usbi_dbg("remove fd %d", fd);