Add transfer flags
[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_transfer *transfer)
210 {
211         struct usbi_transfer *itransfer = TRANSFER_TO_PRIV(transfer);
212         int r;
213
214         usbi_dbg("");
215         r = ioctl(transfer->dev_handle->fd, IOCTL_USB_DISCARDURB, &itransfer->urb);
216         if (r < 0)
217                 usbi_err("cancel transfer failed error %d", r);
218         return r;
219 }
220
221 API_EXPORTED int libusb_cancel_transfer_sync(struct libusb_transfer *transfer)
222 {
223         struct usbi_transfer *itransfer = TRANSFER_TO_PRIV(transfer);
224         int r;
225
226         usbi_dbg("");
227         r = ioctl(transfer->dev_handle->fd, IOCTL_USB_DISCARDURB, &itransfer->urb);
228         if (r < 0) {
229                 usbi_err("cancel transfer failed error %d", r);
230                 return r;
231         }
232
233         itransfer->flags |= USBI_TRANSFER_SYNC_CANCELLED;
234         while (itransfer->flags & USBI_TRANSFER_SYNC_CANCELLED) {
235                 r = libusb_poll();
236                 if (r < 0)
237                         return r;
238         }
239
240         return 0;
241 }
242
243 static void handle_transfer_completion(struct usbi_transfer *itransfer,
244         enum libusb_transfer_status status)
245 {
246         struct libusb_transfer *transfer = &itransfer->pub;
247
248         if (status == LIBUSB_TRANSFER_SILENT_COMPLETION)
249                 return;
250
251         if (status == LIBUSB_TRANSFER_COMPLETED
252                         && transfer->flags & LIBUSB_TRANSFER_SHORT_NOT_OK) {
253                 int rqlen = transfer->length;
254                 if (transfer->endpoint_type == LIBUSB_ENDPOINT_TYPE_CONTROL)
255                         rqlen -= LIBUSB_CONTROL_SETUP_SIZE;
256                 if (rqlen != itransfer->transferred) {
257                         usbi_dbg("interpreting short transfer as error");
258                         status = LIBUSB_TRANSFER_ERROR;
259                 }
260         }
261
262         transfer->status = status;
263         transfer->actual_length = itransfer->transferred;
264         if (transfer->callback)
265                 transfer->callback(transfer);
266         if (transfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER)
267                 libusb_free_transfer(transfer);
268 }
269
270 static void handle_transfer_cancellation(struct usbi_transfer *transfer)
271 {
272         /* if the URB is being cancelled synchronously, raise cancellation
273          * completion event by unsetting flag, and ensure that user callback does
274          * not get called.
275          */
276         if (transfer->flags & USBI_TRANSFER_SYNC_CANCELLED) {
277                 transfer->flags &= ~USBI_TRANSFER_SYNC_CANCELLED;
278                 usbi_dbg("detected sync. cancel");
279                 handle_transfer_completion(transfer, LIBUSB_TRANSFER_SILENT_COMPLETION);
280                 return;
281         }
282
283         /* if the URB was cancelled due to timeout, report timeout to the user */
284         if (transfer->flags & USBI_TRANSFER_TIMED_OUT) {
285                 usbi_dbg("detected timeout cancellation");
286                 handle_transfer_completion(transfer, LIBUSB_TRANSFER_TIMED_OUT);
287                 return;
288         }
289
290         /* otherwise its a normal async cancel */
291         handle_transfer_completion(transfer, LIBUSB_TRANSFER_CANCELLED);
292 }
293
294 static int reap_for_devh(struct libusb_device_handle *devh)
295 {
296         int r;
297         struct usb_urb *urb;
298         struct usbi_transfer *itransfer;
299         struct libusb_transfer *transfer;
300         int trf_requested;
301         int length;
302
303         r = ioctl(devh->fd, IOCTL_USB_REAPURBNDELAY, &urb);
304         if (r == -1 && errno == EAGAIN)
305                 return r;
306         if (r < 0) {
307                 usbi_err("reap failed error %d errno=%d", r, errno);
308                 return r;
309         }
310
311         itransfer = container_of(urb, struct usbi_transfer, urb);
312         transfer = &itransfer->pub;
313
314         usbi_dbg("urb type=%d status=%d transferred=%d", urb->type, urb->status,
315                 urb->actual_length);
316         list_del(&itransfer->list);
317
318         if (urb->status == -2) {
319                 handle_transfer_cancellation(itransfer);
320                 return 0;
321         }
322
323         /* FIXME: research what other status codes may exist */
324         if (urb->status != 0)
325                 usbi_warn("unrecognised urb status %d", urb->status);
326
327         /* determine how much data was asked for */
328         length = transfer->length;
329         if (transfer->endpoint_type == LIBUSB_ENDPOINT_TYPE_CONTROL)
330                 length -= LIBUSB_CONTROL_SETUP_SIZE;
331         trf_requested = MIN(length - itransfer->transferred,
332                 MAX_URB_BUFFER_LENGTH);
333
334         itransfer->transferred += urb->actual_length;
335
336         /* if we were provided less data than requested, then our transfer is
337          * done */
338         if (urb->actual_length < trf_requested) {
339                 usbi_dbg("less data than requested (%d/%d) --> all done",
340                         urb->actual_length, trf_requested);
341                 handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
342                 return 0;
343         }
344
345         /* if we've transferred all data, we're done */
346         if (itransfer->transferred == length) {
347                 usbi_dbg("transfer complete --> all done");
348                 handle_transfer_completion(itransfer, LIBUSB_TRANSFER_COMPLETED);
349                 return 0;
350         }
351
352         /* otherwise, we have more data to transfer */
353         usbi_dbg("more data to transfer...");
354         memset(urb, 0, sizeof(*urb));
355         return submit_transfer(itransfer);
356 }
357
358 static void handle_timeout(struct usbi_transfer *itransfer)
359 {
360         /* handling timeouts is tricky, as we may race with the kernel: we may
361          * detect a timeout racing with the condition that the urb has actually
362          * completed. we asynchronously cancel the URB and report timeout
363          * to the user when the URB cancellation completes (or not at all if the
364          * URB actually gets delivered as per this race) */
365         struct libusb_transfer *transfer = &itransfer->pub;
366         int r;
367
368         itransfer->flags |= USBI_TRANSFER_TIMED_OUT;
369         r = libusb_cancel_transfer(transfer);
370         if (r < 0)
371                 usbi_warn("async cancel failed %d errno=%d", r, errno);
372 }
373
374 static int handle_timeouts(void)
375 {
376         struct timespec systime_ts;
377         struct timeval systime;
378         struct usbi_transfer *transfer;
379         int r;
380
381         if (list_empty(&flying_transfers))
382                 return 0;
383
384         /* get current time */
385         r = clock_gettime(CLOCK_MONOTONIC, &systime_ts);
386         if (r < 0)
387                 return r;
388
389         TIMESPEC_TO_TIMEVAL(&systime, &systime_ts);
390
391         /* iterate through flying transfers list, finding all transfers that
392          * have expired timeouts */
393         list_for_each_entry(transfer, &flying_transfers, list) {
394                 struct timeval *cur_tv = &transfer->timeout;
395
396                 /* if we've reached transfers of infinite timeout, we're all done */
397                 if (!timerisset(cur_tv))
398                         return 0;
399
400                 /* ignore timeouts we've already handled */
401                 if (transfer->flags & USBI_TRANSFER_TIMED_OUT)
402                         continue;
403
404                 /* if transfer has non-expired timeout, nothing more to do */
405                 if ((cur_tv->tv_sec > systime.tv_sec) ||
406                                 (cur_tv->tv_sec == systime.tv_sec &&
407                                         cur_tv->tv_usec > systime.tv_usec))
408                         return 0;
409         
410                 /* otherwise, we've got an expired timeout to handle */
411                 handle_timeout(transfer);
412         }
413
414         return 0;
415 }
416
417 static int poll_io(struct timeval *tv)
418 {
419         struct libusb_device_handle *devh;
420         int r;
421         int maxfd = 0;
422         fd_set writefds;
423         struct timeval select_timeout;
424         struct timeval timeout;
425
426         r = libusb_get_next_timeout(&timeout);
427         if (r) {
428                 /* timeout already expired? */
429                 if (!timerisset(&timeout))
430                         return handle_timeouts();
431
432                 /* choose the smallest of next URB timeout or user specified timeout */
433                 if (timercmp(&timeout, tv, <))
434                         select_timeout = timeout;
435                 else
436                         select_timeout = *tv;
437         } else {
438                 select_timeout = *tv;
439         }
440
441         FD_ZERO(&writefds);
442         list_for_each_entry(devh, &open_devs, list) {
443                 int fd = devh->fd;
444                 FD_SET(fd, &writefds);
445                 if (fd > maxfd)
446                         maxfd = fd;
447         }
448
449         usbi_dbg("select() with timeout in %d.%06ds", select_timeout.tv_sec,
450                 select_timeout.tv_usec);
451         r = select(maxfd + 1, NULL, &writefds, NULL, &select_timeout);
452         usbi_dbg("select() returned %d with %d.%06ds remaining", r, select_timeout.tv_sec,
453                 select_timeout.tv_usec);
454         if (r == 0) {
455                 *tv = select_timeout;
456                 return handle_timeouts();
457         } else if (r == -1 && errno == EINTR) {
458                 return 0;
459         } else if (r < 0) {
460                 usbi_err("select failed %d err=%d\n", r, errno);
461                 return r;
462         }
463
464         list_for_each_entry(devh, &open_devs, list) {
465                 if (!FD_ISSET(devh->fd, &writefds))
466                         continue;
467                 r = reap_for_devh(devh);
468                 if (r == -1 && errno == EAGAIN)
469                         continue;
470                 if (r < 0)
471                         return r;
472         }
473
474         /* FIXME check return value? */
475         return handle_timeouts();
476 }
477
478 API_EXPORTED int libusb_poll_timeout(struct timeval *tv)
479 {
480         return poll_io(tv);
481 }
482
483 API_EXPORTED int libusb_poll(void)
484 {
485         struct timeval tv;
486         tv.tv_sec = 2;
487         tv.tv_usec = 0;
488         return poll_io(&tv);
489 }
490
491 API_EXPORTED int libusb_get_next_timeout(struct timeval *tv)
492 {
493         struct usbi_transfer *transfer;
494         struct timespec cur_ts;
495         struct timeval cur_tv;
496         struct timeval *next_timeout;
497         int r;
498         int found = 0;
499
500         if (list_empty(&flying_transfers)) {
501                 usbi_dbg("no URBs, no timeout!");
502                 return 0;
503         }
504
505         /* find next transfer which hasn't already been processed as timed out */
506         list_for_each_entry(transfer, &flying_transfers, list) {
507                 if (!(transfer->flags & USBI_TRANSFER_TIMED_OUT)) {
508                         found = 1;
509                         break;
510                 }
511         }
512
513         if (!found) {
514                 usbi_dbg("all URBs have already been processed for timeouts");
515                 return 0;
516         }
517
518         next_timeout = &transfer->timeout;
519
520         /* no timeout for next transfer */
521         if (!timerisset(next_timeout)) {
522                 usbi_dbg("no URBs with timeouts, no timeout!");
523                 return 0;
524         }
525
526         r = clock_gettime(CLOCK_MONOTONIC, &cur_ts);
527         if (r < 0) {
528                 usbi_err("failed to read monotonic clock, errno=%d", errno);
529                 return r;
530         }
531         TIMESPEC_TO_TIMEVAL(&cur_tv, &cur_ts);
532
533         if (timercmp(&cur_tv, next_timeout, >=)) {
534                 usbi_dbg("first timeout already expired");
535                 timerclear(tv);
536         } else {
537                 timersub(next_timeout, &cur_tv, tv);
538                 usbi_dbg("next timeout in %d.%06ds", tv->tv_sec, tv->tv_usec);
539         }
540
541         return 1;
542 }
543
544 API_EXPORTED void libusb_free_transfer(struct libusb_transfer *transfer)
545 {
546         struct usbi_transfer *itransfer;
547         if (!transfer)
548                 return;
549
550         if (transfer->flags & LIBUSB_TRANSFER_FREE_BUFFER)
551                 free(transfer->buffer);
552
553         itransfer = TRANSFER_TO_PRIV(transfer);
554         free(itransfer);
555 }
556
557 API_EXPORTED void libusb_set_pollfd_notifiers(libusb_pollfd_added_cb added_cb,
558         libusb_pollfd_removed_cb removed_cb)
559 {
560         fd_added_cb = added_cb;
561         fd_removed_cb = removed_cb;
562 }
563
564 void usbi_add_pollfd(int fd, short events)
565 {
566         usbi_dbg("add fd %d events %d", fd, events);
567         if (fd_added_cb)
568                 fd_added_cb(fd, events);
569 }
570
571 void usbi_remove_pollfd(int fd)
572 {
573         usbi_dbg("remove fd %d", fd);
574         if (fd_removed_cb)
575                 fd_removed_cb(fd);
576 }
577