Rename libusb_dev_handle to libusb_device_handle
[platform/upstream/libusb.git] / libusb / io.c
1 /*
2  * I/O functions for libusb
3  * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
4  * Copyright (c) 2001 Johannes Erdfelt <johannes@erdfelt.com>
5  *
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.
10  *
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.
15  *
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
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <signal.h>
24 #include <stdint.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <sys/select.h>
28 #include <sys/time.h>
29 #include <time.h>
30 #include <unistd.h>
31
32 #include "libusbi.h"
33
34 #define TRANSFER_TO_PRIV(trf) (container_of((trf), struct usbi_transfer, pub))
35
36 /* this is a list of in-flight rb_handles, sorted by timeout expiration.
37  * URBs to timeout the soonest are placed at the beginning of the list, URBs
38  * that will time out later are placed after, and urbs with infinite timeout
39  * are always placed at the very end. */
40 static struct list_head flying_transfers;
41
42 /* user callbacks for pollfd changes */
43 static libusb_pollfd_added_cb fd_added_cb = NULL;
44 static libusb_pollfd_removed_cb fd_removed_cb = NULL;
45
46 void usbi_io_init()
47 {
48         list_init(&flying_transfers);
49         fd_added_cb = NULL;
50         fd_removed_cb = NULL;
51 }
52
53 static int calculate_timeout(struct usbi_transfer *transfer)
54 {
55         int r;
56         struct timespec current_time;
57         unsigned int timeout = transfer->pub.timeout;
58
59         if (!timeout)
60                 return 0;
61
62         r = clock_gettime(CLOCK_MONOTONIC, &current_time);
63         if (r < 0) {
64                 usbi_err("failed to read monotonic clock, errno=%d", errno);
65                 return r;
66         }
67
68         current_time.tv_sec += timeout / 1000;
69         current_time.tv_nsec += (timeout % 1000) * 1000000;
70
71         if (current_time.tv_nsec > 1000000000) {
72                 current_time.tv_nsec -= 1000000000;
73                 current_time.tv_sec++;
74         }
75
76         TIMESPEC_TO_TIMEVAL(&transfer->timeout, &current_time);
77         return 0;
78 }
79
80 static void add_to_flying_list(struct usbi_transfer *transfer)
81 {
82         struct usbi_transfer *cur;
83         struct timeval *timeout = &transfer->timeout;
84
85         /* if we have no other flying transfers, start the list with this one */
86         if (list_empty(&flying_transfers)) {
87                 list_add(&transfer->list, &flying_transfers);
88                 return;
89         }
90
91         /* if we have infinite timeout, append to end of list */
92         if (!timerisset(timeout)) {
93                 list_add_tail(&transfer->list, &flying_transfers);
94                 return;
95         }
96
97         /* otherwise, find appropriate place in list */
98         list_for_each_entry(cur, &flying_transfers, list) {
99                 /* find first timeout that occurs after the transfer in question */
100                 struct timeval *cur_tv = &cur->timeout;
101
102                 if (!timerisset(cur_tv) || (cur_tv->tv_sec > timeout->tv_sec) ||
103                                 (cur_tv->tv_sec == timeout->tv_sec &&
104                                         cur_tv->tv_usec > timeout->tv_usec)) {
105                         list_add_tail(&transfer->list, &cur->list);
106                         return;
107                 }
108         }
109
110         /* otherwise we need to be inserted at the end */
111         list_add_tail(&transfer->list, &flying_transfers);
112 }
113
114 static int submit_transfer(struct usbi_transfer *itransfer)
115 {
116         int r;
117         struct usb_urb *urb = &itransfer->urb;
118         struct libusb_transfer *transfer = &itransfer->pub;
119         int to_be_transferred = transfer->length - itransfer->transferred;
120
121         switch (transfer->endpoint_type) {
122         case LIBUSB_ENDPOINT_TYPE_CONTROL:
123                 urb->type = USB_URB_TYPE_CONTROL;
124                 break;
125         case LIBUSB_ENDPOINT_TYPE_BULK:
126                 urb->type = USB_URB_TYPE_BULK;
127                 break;
128         case LIBUSB_ENDPOINT_TYPE_INTERRUPT:
129                 urb->type = USB_URB_TYPE_INTERRUPT;
130                 break;
131         default:
132                 usbi_err("unknown endpoint type %d", transfer->endpoint_type);
133                 return -EINVAL;
134         }
135
136         urb->endpoint = transfer->endpoint;
137         urb->buffer = transfer->buffer + itransfer->transferred;
138         urb->buffer_length = MIN(to_be_transferred, MAX_URB_BUFFER_LENGTH);
139
140         /* FIXME: for requests that we have to split into multiple URBs, we should
141          * submit all the URBs instantly: submit, submit, submit, reap, reap, reap
142          * rather than: submit, reap, submit, reap, submit, reap
143          * this will improve performance and fix bugs concerning behaviour when
144          * the user submits two similar multiple-urb requests */
145         usbi_dbg("transferring %d from %d bytes", urb->buffer_length,
146                 to_be_transferred);
147
148         r = ioctl(transfer->dev_handle->fd, IOCTL_USB_SUBMITURB, urb);
149         if (r < 0) {
150                 usbi_err("submiturb failed error %d errno=%d", r, errno);
151                 return r;
152         }
153
154         add_to_flying_list(itransfer);
155         return 0;
156 }
157
158 API_EXPORTED size_t libusb_get_transfer_alloc_size(void)
159 {
160         return sizeof(struct usbi_transfer);
161 }
162
163 void __init_transfer(struct usbi_transfer *transfer)
164 {
165         memset(transfer, 0, sizeof(*transfer));
166 }
167
168 API_EXPORTED void libusb_init_transfer(struct libusb_transfer *transfer)
169 {
170         __init_transfer(TRANSFER_TO_PRIV(transfer));
171 }
172
173 API_EXPORTED struct libusb_transfer *libusb_alloc_transfer(void)
174 {
175         struct usbi_transfer *transfer = malloc(sizeof(*transfer));
176         if (!transfer)
177                 return NULL;
178
179         __init_transfer(transfer);
180         return &transfer->pub;
181 }
182
183 API_EXPORTED int libusb_submit_transfer(struct libusb_transfer *transfer)
184 {
185         struct usbi_transfer *itransfer = TRANSFER_TO_PRIV(transfer);
186         int r;
187
188         itransfer->transferred = 0;
189         r = calculate_timeout(itransfer);
190         if (r < 0)
191                 return r;
192
193         if (transfer->endpoint_type == LIBUSB_ENDPOINT_TYPE_CONTROL) {
194                 struct libusb_control_setup *setup =
195                         (struct libusb_control_setup *) transfer->buffer;
196         
197                 usbi_dbg("RQT=%02x RQ=%02x VAL=%04x IDX=%04x length=%d",
198                         setup->bRequestType, setup->bRequest, setup->wValue, setup->wIndex,
199                         setup->wLength);
200
201                 setup->wValue = cpu_to_le16(setup->wValue);
202                 setup->wIndex = cpu_to_le16(setup->wIndex);
203                 setup->wLength = cpu_to_le16(setup->wLength);
204         }
205
206         return submit_transfer(itransfer);
207 }
208
209 API_EXPORTED int libusb_cancel_transfer(struct libusb_device_handle *devh,
210         struct libusb_transfer *transfer)
211 {
212         struct usbi_transfer *itransfer = TRANSFER_TO_PRIV(transfer);
213         int r;
214
215         usbi_dbg("");
216         r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &itransfer->urb);
217         if (r < 0)
218                 usbi_err("cancel transfer failed error %d", r);
219         return r;
220 }
221
222 API_EXPORTED int libusb_cancel_transfer_sync(struct libusb_device_handle *devh,
223         struct libusb_transfer *transfer)
224 {
225         struct usbi_transfer *itransfer = TRANSFER_TO_PRIV(transfer);
226         int r;
227
228         usbi_dbg("");
229         r = ioctl(devh->fd, IOCTL_USB_DISCARDURB, &itransfer->urb);
230         if (r < 0) {
231                 usbi_err("cancel transfer failed error %d", r);
232                 return r;
233         }
234
235         itransfer->flags |= USBI_TRANSFER_SYNC_CANCELLED;
236         while (itransfer->flags & USBI_TRANSFER_SYNC_CANCELLED) {
237                 r = libusb_poll();
238                 if (r < 0)
239                         return r;
240         }
241
242         return 0;
243 }
244
245 static void handle_transfer_completion(struct usbi_transfer *itransfer,
246         enum libusb_transfer_status status)
247 {
248         struct libusb_transfer *transfer = &itransfer->pub;
249
250         if (status == LIBUSB_TRANSFER_SILENT_COMPLETION)
251                 return;
252
253         transfer->status = status;
254         transfer->actual_length = itransfer->transferred;
255         if (transfer->callback)
256                 transfer->callback(transfer);
257 }
258
259 static void handle_transfer_cancellation(struct libusb_device_handle *devh,
260         struct usbi_transfer *transfer)
261 {
262         /* if the URB is being cancelled synchronously, raise cancellation
263          * completion event by unsetting flag, and ensure that user callback does
264          * not get called.
265          */
266         if (transfer->flags & USBI_TRANSFER_SYNC_CANCELLED) {
267                 transfer->flags &= ~USBI_TRANSFER_SYNC_CANCELLED;
268                 usbi_dbg("detected sync. cancel");
269                 handle_transfer_completion(transfer, LIBUSB_TRANSFER_SILENT_COMPLETION);
270                 return;
271         }
272
273         /* if the URB was cancelled due to timeout, report timeout to the user */
274         if (transfer->flags & USBI_TRANSFER_TIMED_OUT) {
275                 usbi_dbg("detected timeout cancellation");
276                 handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT);
277                 return;
278         }
279
280         /* otherwise its a normal async cancel */
281         handle_transfer_completion(transfer, LIBUSB_TRANSFER_CANCELLED);
282 }
283
284 static int reap_for_devh(struct libusb_device_handle *devh)
285 {
286         int r;
287         struct usb_urb *urb;
288         struct usbi_transfer *itransfer;
289         struct libusb_transfer *transfer;
290         int trf_requested;
291         int length;
292
293         r = ioctl(devh->fd, IOCTL_USB_REAPURBNDELAY, &urb);
294         if (r == -1 && errno == EAGAIN)
295                 return r;
296         if (r < 0) {
297                 usbi_err("reap failed error %d errno=%d", r, errno);
298                 return r;
299         }
300
301         itransfer = container_of(urb, struct usbi_transfer, urb);
302         transfer = &itransfer->pub;
303
304         usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status,
305                 urb->actual_length);
306         list_del(&itransfer->list);
307
308         if (urb->status == -2) {
309                 handle_transfer_cancellation(devh, itransfer);
310                 return 0;
311         }
312
313         /* FIXME: research what other status codes may exist */
314         if (urb->status != 0)
315                 usbi_warn("unrecognised urb status %d", urb->status);
316
317         /* determine how much data was asked for */
318         length = transfer->length;
319         if (transfer->endpoint_type == LIBUSB_ENDPOINT_TYPE_CONTROL)
320                 length -= LIBUSB_CONTROL_SETUP_SIZE;
321         trf_requested = MIN(length - itransfer->transferred,
322                 MAX_URB_BUFFER_LENGTH);
323
324         itransfer->transferred += urb->actual_length;
325
326         /* if we were provided less data than requested, then our transfer is
327          * done */
328         if (urb->actual_length < trf_requested) {
329                 usbi_dbg("less data than requested (%d/%d) --> all done",
330                         urb->actual_length, trf_requested);
331                 handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
332                 return 0;
333         }
334
335         /* if we've transferred all data, we're done */
336         if (itransfer->transferred == length) {
337                 usbi_dbg("transfer complete --> all done");
338                 handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
339                 return 0;
340         }
341
342         /* otherwise, we have more data to transfer */
343         usbi_dbg("more data to transfer...");
344         memset(urb, 0, sizeof(*urb));
345         return submit_transfer(itransfer);
346 }
347
348 static void handle_timeout(struct usbi_transfer *itransfer)
349 {
350         /* handling timeouts is tricky, as we may race with the kernel: we may
351          * detect a timeout racing with the condition that the urb has actually
352          * completed. we asynchronously cancel the URB and report timeout
353          * to the user when the URB cancellation completes (or not at all if the
354          * URB actually gets delivered as per this race) */
355         struct libusb_transfer *transfer = &itransfer->pub;
356         int r;
357
358         itransfer->flags |= USBI_TRANSFER_TIMED_OUT;
359         r = libusb_cancel_transfer(transfer->dev_handle, transfer);
360         if (r < 0)
361                 usbi_warn("async cancel failed %d errno=%d", r, errno);
362 }
363
364 static int handle_timeouts(void)
365 {
366         struct timespec systime_ts;
367         struct timeval systime;
368         struct usbi_transfer *transfer;
369         int r;
370
371         if (list_empty(&flying_transfers))
372                 return 0;
373
374         /* get current time */
375         r = clock_gettime(CLOCK_MONOTONIC, &systime_ts);
376         if (r < 0)
377                 return r;
378
379         TIMESPEC_TO_TIMEVAL(&systime, &systime_ts);
380
381         /* iterate through flying transfers list, finding all transfers that
382          * have expired timeouts */
383         list_for_each_entry(transfer, &flying_transfers, list) {
384                 struct timeval *cur_tv = &transfer->timeout;
385
386                 /* if we've reached transfers of infinite timeout, we're all done */
387                 if (!timerisset(cur_tv))
388                         return 0;
389
390                 /* ignore timeouts we've already handled */
391                 if (transfer->flags & USBI_TRANSFER_TIMED_OUT)
392                         continue;
393
394                 /* if transfer has non-expired timeout, nothing more to do */
395                 if ((cur_tv->tv_sec > systime.tv_sec) ||
396                                 (cur_tv->tv_sec == systime.tv_sec &&
397                                         cur_tv->tv_usec > systime.tv_usec))
398                         return 0;
399         
400                 /* otherwise, we've got an expired timeout to handle */
401                 handle_timeout(transfer);
402         }
403
404         return 0;
405 }
406
407 static int poll_io(struct timeval *tv)
408 {
409         struct libusb_device_handle *devh;
410         int r;
411         int maxfd = 0;
412         fd_set writefds;
413         struct timeval select_timeout;
414         struct timeval timeout;
415
416         r = libusb_get_next_timeout(&timeout);
417         if (r) {
418                 /* timeout already expired? */
419                 if (!timerisset(&timeout))
420                         return handle_timeouts();
421
422                 /* choose the smallest of next URB timeout or user specified timeout */
423                 if (timercmp(&timeout, tv, <))
424                         select_timeout = timeout;
425                 else
426                         select_timeout = *tv;
427         } else {
428                 select_timeout = *tv;
429         }
430
431         FD_ZERO(&writefds);
432         list_for_each_entry(devh, &open_devs, list) {
433                 int fd = devh->fd;
434                 FD_SET(fd, &writefds);
435                 if (fd > maxfd)
436                         maxfd = fd;
437         }
438
439         usbi_dbg("select() with timeout in %d.%06ds", select_timeout.tv_sec,
440                 select_timeout.tv_usec);
441         r = select(maxfd + 1, NULL, &writefds, NULL, &select_timeout);
442         usbi_dbg("select() returned %d with %d.%06ds remaining", r, select_timeout.tv_sec,
443                 select_timeout.tv_usec);
444         if (r == 0) {
445                 *tv = select_timeout;
446                 return handle_timeouts();
447         } else if (r == -1 && errno == EINTR) {
448                 return 0;
449         } else if (r < 0) {
450                 usbi_err("select failed %d err=%d\n", r, errno);
451                 return r;
452         }
453
454         list_for_each_entry(devh, &open_devs, list) {
455                 if (!FD_ISSET(devh->fd, &writefds))
456                         continue;
457                 r = reap_for_devh(devh);
458                 if (r == -1 && errno == EAGAIN)
459                         continue;
460                 if (r < 0)
461                         return r;
462         }
463
464         /* FIXME check return value? */
465         return handle_timeouts();
466 }
467
468 API_EXPORTED int libusb_poll_timeout(struct timeval *tv)
469 {
470         return poll_io(tv);
471 }
472
473 API_EXPORTED int libusb_poll(void)
474 {
475         struct timeval tv;
476         tv.tv_sec = 2;
477         tv.tv_usec = 0;
478         return poll_io(&tv);
479 }
480
481 API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
482 {
483         struct usbi_transfer *transfer;
484         struct timespec cur_ts;
485         struct timeval cur_tv;
486         struct timeval *next_timeout;
487         int r;
488         int found = 0;
489
490         if (list_empty(&flying_transfers)) {
491                 usbi_dbg("no URBs, no timeout!");
492                 return 0;
493         }
494
495         /* find next transfer which hasn't already been processed as timed out */
496         list_for_each_entry(transfer, &flying_transfers, list) {
497                 if (!(transfer->flags & USBI_TRANSFER_TIMED_OUT)) {
498                         found = 1;
499                         break;
500                 }
501         }
502
503         if (!found) {
504                 usbi_dbg("all URBs have already been processed for timeouts");
505                 return 0;
506         }
507
508         next_timeout = &transfer->timeout;
509
510         /* no timeout for next transfer */
511         if (!timerisset(next_timeout)) {
512                 usbi_dbg("no URBs with timeouts, no timeout!");
513                 return 0;
514         }
515
516         r = clock_gettime(CLOCK_MONOTONIC, &cur_ts);
517         if (r < 0) {
518                 usbi_err("failed to read monotonic clock, errno=%d", errno);
519                 return r;
520         }
521         TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
522
523         if (timercmp(&cur_tv, next_timeout, >=)) {
524                 usbi_dbg("first timeout already expired");
525                 timerclear(tv);
526         } else {
527                 timersub(next_timeout, &cur_tv, tv);
528                 usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec);
529         }
530
531         return 1;
532 }
533
534 API_EXPORTED void libusb_free_transfer(struct libusb_transfer *transfer)
535 {
536         struct usbi_transfer *itransfer;
537         if (!transfer)
538                 return;
539
540         itransfer = TRANSFER_TO_PRIV(transfer);
541         free(itransfer);
542 }
543
544 API_EXPORTED void libusb_set_pollfd_notifiers(libusb_pollfd_added_cb added_cb,
545         libusb_pollfd_removed_cb removed_cb)
546 {
547         fd_added_cb = added_cb;
548         fd_removed_cb = removed_cb;
549 }
550
551 void usbi_add_pollfd(int fd, short events)
552 {
553         usbi_dbg("add fd %d events %d", fd, events);
554         if (fd_added_cb)
555                 fd_added_cb(fd, events);
556 }
557
558 void usbi_remove_pollfd(int fd)
559 {
560         usbi_dbg("remove fd %d", fd);
561         if (fd_removed_cb)
562                 fd_removed_cb(fd);
563 }
564