Deleted Added
full compact
libusb10.h (194676) libusb10.h (195560)
1/* $FreeBSD: head/lib/libusb/libusb10.h 194676 2009-06-23 01:04:58Z thompsa $ */
1/* $FreeBSD: head/lib/libusb/libusb10.h 195560 2009-07-10 14:15:53Z thompsa $ */
2/*-
3 * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 16 unchanged lines hidden (view full) ---

26
27#ifndef __LIBUSB10_H__
28#define __LIBUSB10_H__
29
30/*
31 * The two following macros were taken from the original LibUSB v1.0
32 * for sake of compatibility:
33 */
2/*-
3 * Copyright (c) 2009 Sylvestre Gallon. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.

--- 16 unchanged lines hidden (view full) ---

26
27#ifndef __LIBUSB10_H__
28#define __LIBUSB10_H__
29
30/*
31 * The two following macros were taken from the original LibUSB v1.0
32 * for sake of compatibility:
33 */
34#define USB_LIST_INIT(entry) \
35 (entry)->prev = (entry)->next = entry;
36#define USB_LIST_EMPTY(entry) \
37 ((entry)->next = (entry))
38
34
39#define LIST_ADD(entry, head) \
40 (entry)->next = (head)->next; \
41 (entry)->prev = (head); \
42 (head)->next->prev = (entry); \
43 (head)->next = (entry);
44#define LIST_ADD_TAIL(entry, head) \
45 (entry)->next = (head); \
46 (entry)->prev = (head)->prev; \
47 (head)->prev->next = (entry); \
48 (head)->prev = (entry);
49#define LIST_DEL(entry) \
50 (entry)->next->prev = (entry)->prev; \
51 (entry)->prev->next = (entry)->next;
52
53#define LIST_ENT(ptr, type, member) \
54 ((type *)((char *)(ptr) - (unsigned long) (&((type*)0L)->member)))
55#define LIST_FOREACH_ENTRY(pos, head, member) \
56 for (pos = LIST_ENT((head)->next, typeof(*pos), member) ; \
57 &pos->member != head ; \
58 pos = LIST_ENT(pos->member.next, typeof(*pos), member))
59#define LIST_FOREACH_ENTRY_SAFE(pos, n, head, member) \
60 for (pos = LIST_ENT((head)->next, typeof(*pos), member), \
61 n = LIST_ENT(pos->member.next, typeof(*pos), member); \
62 &pos->member != (head); \
63 pos = n, n = LIST_ENT(n->member.next, typeof(*n), member))
64
65/* fetch libusb20_transfer from libusb20_device */
66#define GET_XFER(xfer, endpoint, pdev)\
67 xfer = libusb20_tr_get_pointer(pdev, \
68 (2 *endpoint)|(endpoint/0x80)); \
69 if (xfer == NULL) \
70 return (LIBUSB_ERROR_OTHER);
71
72
73static int get_next_timeout(libusb_context *ctx, struct timeval *tv, struct timeval *out);
74static int handle_timeouts(struct libusb_context *ctx);
75static int handle_events(struct libusb_context *ctx, struct timeval *tv);
76extern struct libusb_context *usbi_default_context;
77extern pthread_mutex_t libusb20_lock;
78
79/* if ctx is NULL use default context*/
80
81#define GET_CONTEXT(ctx) \
82 if (ctx == NULL) ctx = usbi_default_context;
83
84#define MAX(a,b) (((a)>(b))?(a):(b))
85#define USB_TIMED_OUT (1<<0)
35static int get_next_timeout(libusb_context *ctx, struct timeval *tv, struct timeval *out);
36static int handle_timeouts(struct libusb_context *ctx);
37static int handle_events(struct libusb_context *ctx, struct timeval *tv);
38extern struct libusb_context *usbi_default_context;
39extern pthread_mutex_t libusb20_lock;
40
41/* if ctx is NULL use default context*/
42
43#define GET_CONTEXT(ctx) \
44 if (ctx == NULL) ctx = usbi_default_context;
45
46#define MAX(a,b) (((a)>(b))?(a):(b))
47#define USB_TIMED_OUT (1<<0)
48#define UNEXPORTED __attribute__((__visibility__("hidden")))
86
49
87static inline void
88dprintf(libusb_context *ctx, int debug, char *str)
89{
90 if (ctx->debug != debug)
91 return ;
92
93 switch (ctx->debug) {
94 case LIBUSB_DEBUG_NO:
95 break ;
96 case LIBUSB_DEBUG_FUNCTION:
97 printf("LIBUSB FUNCTION : %s\n", str);
98 break ;
99 case LIBUSB_DEBUG_TRANSFER:
100 printf("LIBUSB TRANSFER : %s\n", str);
101 break ;
102 default:
103 printf("LIBUSB UNKNOW DEBUG\n");
104 break ;
105 }
106 return ;
50#define DPRINTF(ctx, dbg, format, args...) \
51if (ctx->debug == dbg) { \
52 printf("LIBUSB_%s : ", (ctx->debug == LIBUSB_DEBUG_FUNCTION) ? "FUNCTION" : "TRANSFER"); \
53 switch(ctx->debug) { \
54 case LIBUSB_DEBUG_FUNCTION: \
55 printf(format, ## args);\
56 break ; \
57 case LIBUSB_DEBUG_TRANSFER: \
58 printf(format, ## args);\
59 break ; \
60 } \
61 printf("\n"); \
107}
108
62}
63
109struct usb_pollfd {
110 struct libusb_pollfd pollfd;
111 struct list_head list;
112};
64UNEXPORTED int usb_add_pollfd(libusb_context *ctx, int fd, short events);
65UNEXPORTED void usb_remove_pollfd(libusb_context *ctx, int fd);
66UNEXPORTED void usb_handle_transfer_completion(struct usb_transfer *uxfer,
67 enum libusb_transfer_status status);
68UNEXPORTED void usb_handle_disconnect(struct libusb_device_handle *devh);
113
69
114struct usb_transfer {
115 int num_iso_packets;
116 struct list_head list;
117 struct timeval timeout;
118 int transferred;
119 uint8_t flags;
120};
121
122static inline int
123usb_add_pollfd(libusb_context *ctx, int fd, short events)
124{
125 struct usb_pollfd *pollfd;
126
127 if (ctx == NULL)
128 return (LIBUSB_ERROR_INVALID_PARAM);
129
130 pollfd = malloc(sizeof(*pollfd));
131 if (pollfd == NULL)
132 return (LIBUSB_ERROR_NO_MEM);
133
134 pollfd->pollfd.fd = fd;
135 pollfd->pollfd.events = events;
136
137 pthread_mutex_lock(&ctx->pollfds_lock);
138 LIST_ADD_TAIL(&pollfd->list, &ctx->pollfds);
139 pthread_mutex_unlock(&ctx->pollfds_lock);
140
141 if (ctx->fd_added_cb)
142 ctx->fd_added_cb(fd, events, ctx->fd_cb_user_data);
143 return (0);
144}
145
146static inline void
147usb_remove_pollfd(libusb_context *ctx, int fd)
148{
149 struct usb_pollfd *pollfd;
150 int found;
151
152 found = 0;
153 pthread_mutex_lock(&ctx->pollfds_lock);
154
155 LIST_FOREACH_ENTRY(pollfd, &ctx->pollfds, list) {
156 if (pollfd->pollfd.fd == fd) {
157 found = 1;
158 break ;
159 }
160 }
161
162 if (found == 0) {
163 pthread_mutex_unlock(&ctx->pollfds_lock);
164 return ;
165 }
166
167 LIST_DEL(&pollfd->list);
168 pthread_mutex_unlock(&ctx->pollfds_lock);
169 free(pollfd);
170
171 if (ctx->fd_removed_cb)
172 ctx->fd_removed_cb(fd, ctx->fd_cb_user_data);
173}
174
175static inline void
176usb_handle_transfer_completion(struct usb_transfer *uxfer,
177 enum libusb_transfer_status status)
178{
179 libusb_transfer *xfer;
180 libusb_context *ctx;
181 int len;
182
183 xfer = (struct libusb_transfer *) ((uint8_t *)uxfer +
184 sizeof(struct usb_transfer));
185 ctx = xfer->dev_handle->dev->ctx;
186
187 pthread_mutex_lock(&ctx->flying_transfers_lock);
188 LIST_DEL(&uxfer->list);
189 pthread_mutex_unlock(&ctx->flying_transfers_lock);
190
191 if (status == LIBUSB_TRANSFER_COMPLETED && xfer->flags &
192 LIBUSB_TRANSFER_SHORT_NOT_OK) {
193 len = xfer->length;
194 if (xfer->type == LIBUSB_TRANSFER_TYPE_CONTROL)
195 len -= sizeof(libusb_control_setup);
196 if (len != uxfer->transferred) {
197 status = LIBUSB_TRANSFER_ERROR;
198 }
199 }
200
201 xfer->status = status;
202 xfer->actual_length = uxfer->transferred;
203
204 if (xfer->callback)
205 xfer->callback(xfer);
206 if (xfer->flags & LIBUSB_TRANSFER_FREE_TRANSFER)
207 libusb_free_transfer(xfer);
208
209 pthread_mutex_lock(&ctx->event_waiters_lock);
210 pthread_cond_broadcast(&ctx->event_waiters_cond);
211 pthread_mutex_unlock(&ctx->event_waiters_lock);
212}
213
214static inline void
215usb_handle_disconnect(struct libusb_device_handle *devh)
216{
217 struct libusb_context *ctx;
218 struct libusb_transfer *xfer;
219 struct usb_transfer *cur;
220 struct usb_transfer *to_cancel;
221
222 ctx = devh->dev->ctx;
223
224 while (1) {
225 pthread_mutex_lock(&ctx->flying_transfers_lock);
226 to_cancel = NULL;
227 LIST_FOREACH_ENTRY(cur, &ctx->flying_transfers, list) {
228 xfer = (struct libusb_transfer *) ((uint8_t *)cur +
229 sizeof(struct usb_transfer));
230 if (xfer->dev_handle == devh) {
231 to_cancel = cur;
232 break ;
233 }
234 }
235 pthread_mutex_unlock(&ctx->flying_transfers_lock);
236
237 if (to_cancel == NULL)
238 break ;
239
240 usb_handle_transfer_completion(to_cancel, LIBUSB_TRANSFER_NO_DEVICE);
241 }
242 return ;
243}
244
245#endif /*__LIBUSB10_H__*/
70#endif /*__LIBUSB10_H__*/