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