libusb10.c (195560) | libusb10.c (195957) |
---|---|
1/* $FreeBSD: head/lib/libusb/libusb10.c 195560 2009-07-10 14:15:53Z thompsa $ */ | 1/* $FreeBSD: head/lib/libusb/libusb10.c 195957 2009-07-30 00:11:41Z alfred $ */ |
2/*- 3 * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. | 2/*- 3 * Copyright (c) 2009 Sylvestre Gallon. All rights reserved. |
4 * Copyright (c) 2009 Hans Petter Selasky. 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. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the --- 7 unchanged lines hidden (view full) --- 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 | 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the --- 7 unchanged lines hidden (view full) --- 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 */ 27 |
27#include <sys/queue.h> | |
28#include <stdlib.h> 29#include <unistd.h> 30#include <stdio.h> 31#include <poll.h> 32#include <pthread.h> 33#include <time.h> 34#include <errno.h> | 28#include <stdlib.h> 29#include <unistd.h> 30#include <stdio.h> 31#include <poll.h> 32#include <pthread.h> 33#include <time.h> 34#include <errno.h> |
35#include <sys/ioctl.h> 36#include <sys/filio.h> 37#include <sys/queue.h> |
|
35 36#include "libusb20.h" 37#include "libusb20_desc.h" 38#include "libusb20_int.h" 39#include "libusb.h" 40#include "libusb10.h" 41 42static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER; 43struct libusb_context *usbi_default_context = NULL; | 38 39#include "libusb20.h" 40#include "libusb20_desc.h" 41#include "libusb20_int.h" 42#include "libusb.h" 43#include "libusb10.h" 44 45static pthread_mutex_t default_context_lock = PTHREAD_MUTEX_INITIALIZER; 46struct libusb_context *usbi_default_context = NULL; |
44pthread_mutex_t libusb20_lock = PTHREAD_MUTEX_INITIALIZER; | |
45 | 47 |
48/* Prototypes */ 49 50static struct libusb20_transfer *libusb10_get_transfer(struct libusb20_device *, uint8_t, uint8_t); 51static int libusb10_get_maxframe(struct libusb20_device *, libusb_transfer *); 52static int libusb10_get_buffsize(struct libusb20_device *, libusb_transfer *); 53static int libusb10_convert_error(uint8_t status); 54static void libusb10_complete_transfer(struct libusb20_transfer *, struct libusb_super_transfer *, int); 55static void libusb10_isoc_proxy(struct libusb20_transfer *); 56static void libusb10_bulk_intr_proxy(struct libusb20_transfer *); 57static void libusb10_ctrl_proxy(struct libusb20_transfer *); 58static void libusb10_submit_transfer_sub(struct libusb20_device *, uint8_t); 59 |
|
46/* Library initialisation / deinitialisation */ 47 48void | 60/* Library initialisation / deinitialisation */ 61 62void |
49libusb_set_debug(libusb_context * ctx, int level) | 63libusb_set_debug(libusb_context *ctx, int level) |
50{ | 64{ |
51 GET_CONTEXT(ctx); | 65 ctx = GET_CONTEXT(ctx); |
52 if (ctx) 53 ctx->debug = level; 54} 55 56int | 66 if (ctx) 67 ctx->debug = level; 68} 69 70int |
57libusb_init(libusb_context ** context) | 71libusb_init(libusb_context **context) |
58{ 59 struct libusb_context *ctx; | 72{ 73 struct libusb_context *ctx; |
60 char * debug; | 74 char *debug; |
61 int ret; 62 63 ctx = malloc(sizeof(*ctx)); 64 if (!ctx) 65 return (LIBUSB_ERROR_INVALID_PARAM); 66 67 memset(ctx, 0, sizeof(*ctx)); 68 69 debug = getenv("LIBUSB_DEBUG"); 70 if (debug != NULL) { 71 ctx->debug = atoi(debug); 72 if (ctx->debug != 0) 73 ctx->debug_fixed = 1; 74 } | 75 int ret; 76 77 ctx = malloc(sizeof(*ctx)); 78 if (!ctx) 79 return (LIBUSB_ERROR_INVALID_PARAM); 80 81 memset(ctx, 0, sizeof(*ctx)); 82 83 debug = getenv("LIBUSB_DEBUG"); 84 if (debug != NULL) { 85 ctx->debug = atoi(debug); 86 if (ctx->debug != 0) 87 ctx->debug_fixed = 1; 88 } |
89 TAILQ_INIT(&ctx->pollfds); 90 TAILQ_INIT(&ctx->tr_done); |
|
75 | 91 |
76 pthread_mutex_init(&ctx->usb_devs_lock, NULL); 77 pthread_mutex_init(&ctx->open_devs_lock, NULL); 78 TAILQ_INIT(&ctx->usb_devs); 79 TAILQ_INIT(&ctx->open_devs); | 92 pthread_mutex_init(&ctx->ctx_lock, NULL); 93 pthread_cond_init(&ctx->ctx_cond, NULL); |
80 | 94 |
81 pthread_mutex_init(&ctx->flying_transfers_lock, NULL); 82 pthread_mutex_init(&ctx->pollfds_lock, NULL); 83 pthread_mutex_init(&ctx->pollfd_modify_lock, NULL); 84 pthread_mutex_init(&ctx->events_lock, NULL); 85 pthread_mutex_init(&ctx->event_waiters_lock, NULL); 86 pthread_cond_init(&ctx->event_waiters_cond, NULL); | 95 ctx->ctx_handler = NO_THREAD; |
87 | 96 |
88 TAILQ_INIT(&ctx->flying_transfers); 89 TAILQ_INIT(&ctx->pollfds); 90 | |
91 ret = pipe(ctx->ctrl_pipe); 92 if (ret < 0) { | 97 ret = pipe(ctx->ctrl_pipe); 98 if (ret < 0) { |
93 usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]); 94 close(ctx->ctrl_pipe[0]); 95 close(ctx->ctrl_pipe[1]); | 99 pthread_mutex_destroy(&ctx->ctx_lock); 100 pthread_cond_destroy(&ctx->ctx_cond); |
96 free(ctx); 97 return (LIBUSB_ERROR_OTHER); 98 } | 101 free(ctx); 102 return (LIBUSB_ERROR_OTHER); 103 } |
104 /* set non-blocking mode on the control pipe to avoid deadlock */ 105 ret = 1; 106 ioctl(ctx->ctrl_pipe[0], FIONBIO, &ret); 107 ret = 1; 108 ioctl(ctx->ctrl_pipe[1], FIONBIO, &ret); |
|
99 | 109 |
100 ret = usb_add_pollfd(ctx, ctx->ctrl_pipe[0], POLLIN); 101 if (ret < 0) { 102 usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]); 103 close(ctx->ctrl_pipe[0]); 104 close(ctx->ctrl_pipe[1]); 105 free(ctx); 106 return ret; 107 } | 110 libusb10_add_pollfd(ctx, &ctx->ctx_poll, NULL, ctx->ctrl_pipe[0], POLLIN); |
108 109 pthread_mutex_lock(&default_context_lock); 110 if (usbi_default_context == NULL) { 111 usbi_default_context = ctx; 112 } 113 pthread_mutex_unlock(&default_context_lock); 114 115 if (context) 116 *context = ctx; 117 | 111 112 pthread_mutex_lock(&default_context_lock); 113 if (usbi_default_context == NULL) { 114 usbi_default_context = ctx; 115 } 116 pthread_mutex_unlock(&default_context_lock); 117 118 if (context) 119 *context = ctx; 120 |
121 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_init complete"); 122 |
|
118 return (0); 119} 120 121void | 123 return (0); 124} 125 126void |
122libusb_exit(libusb_context * ctx) | 127libusb_exit(libusb_context *ctx) |
123{ | 128{ |
124 GET_CONTEXT(ctx); | 129 ctx = GET_CONTEXT(ctx); |
125 | 130 |
126 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit enter"); 127 usb_remove_pollfd(ctx, ctx->ctrl_pipe[0]); | 131 if (ctx == NULL) 132 return; 133 134 /* XXX cleanup devices */ 135 136 libusb10_remove_pollfd(ctx, &ctx->ctx_poll); |
128 close(ctx->ctrl_pipe[0]); 129 close(ctx->ctrl_pipe[1]); | 137 close(ctx->ctrl_pipe[0]); 138 close(ctx->ctrl_pipe[1]); |
139 pthread_mutex_destroy(&ctx->ctx_lock); 140 pthread_cond_destroy(&ctx->ctx_cond); |
|
130 131 pthread_mutex_lock(&default_context_lock); 132 if (ctx == usbi_default_context) { 133 usbi_default_context = NULL; 134 } 135 pthread_mutex_unlock(&default_context_lock); 136 137 free(ctx); | 141 142 pthread_mutex_lock(&default_context_lock); 143 if (ctx == usbi_default_context) { 144 usbi_default_context = NULL; 145 } 146 pthread_mutex_unlock(&default_context_lock); 147 148 free(ctx); |
138 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_exit leave"); | |
139} 140 141/* Device handling and initialisation. */ 142 143ssize_t | 149} 150 151/* Device handling and initialisation. */ 152 153ssize_t |
144libusb_get_device_list(libusb_context * ctx, libusb_device *** list) | 154libusb_get_device_list(libusb_context *ctx, libusb_device ***list) |
145{ | 155{ |
156 struct libusb20_backend *usb_backend; |
|
146 struct libusb20_device *pdev; | 157 struct libusb20_device *pdev; |
147 struct LIBUSB20_DEVICE_DESC_DECODED *ddesc; | |
148 struct libusb_device *dev; | 158 struct libusb_device *dev; |
149 struct libusb20_backend *usb_backend; | |
150 int i; 151 | 159 int i; 160 |
152 GET_CONTEXT(ctx); 153 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list enter"); | 161 ctx = GET_CONTEXT(ctx); |
154 | 162 |
163 if (ctx == NULL) 164 return (LIBUSB_ERROR_INVALID_PARAM); 165 166 if (list == NULL) 167 return (LIBUSB_ERROR_INVALID_PARAM); 168 |
|
155 usb_backend = libusb20_be_alloc_default(); 156 if (usb_backend == NULL) | 169 usb_backend = libusb20_be_alloc_default(); 170 if (usb_backend == NULL) |
157 return (-1); | 171 return (LIBUSB_ERROR_NO_MEM); |
158 | 172 |
173 /* figure out how many USB devices are present */ |
|
159 pdev = NULL; 160 i = 0; 161 while ((pdev = libusb20_be_device_foreach(usb_backend, pdev))) 162 i++; 163 | 174 pdev = NULL; 175 i = 0; 176 while ((pdev = libusb20_be_device_foreach(usb_backend, pdev))) 177 i++; 178 |
164 if (list == NULL) { 165 libusb20_be_free(usb_backend); 166 return (LIBUSB_ERROR_INVALID_PARAM); 167 } | 179 /* allocate device pointer list */ |
168 *list = malloc((i + 1) * sizeof(void *)); 169 if (*list == NULL) { 170 libusb20_be_free(usb_backend); 171 return (LIBUSB_ERROR_NO_MEM); 172 } | 180 *list = malloc((i + 1) * sizeof(void *)); 181 if (*list == NULL) { 182 libusb20_be_free(usb_backend); 183 return (LIBUSB_ERROR_NO_MEM); 184 } |
185 /* create libusb v1.0 compliant devices */ |
|
173 i = 0; 174 while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) { 175 /* get device into libUSB v1.0 list */ 176 libusb20_be_dequeue_device(usb_backend, pdev); 177 | 186 i = 0; 187 while ((pdev = libusb20_be_device_foreach(usb_backend, NULL))) { 188 /* get device into libUSB v1.0 list */ 189 libusb20_be_dequeue_device(usb_backend, pdev); 190 |
178 ddesc = libusb20_dev_get_device_desc(pdev); | |
179 dev = malloc(sizeof(*dev)); 180 if (dev == NULL) { 181 while (i != 0) { 182 libusb_unref_device((*list)[i - 1]); 183 i--; 184 } 185 free(*list); | 191 dev = malloc(sizeof(*dev)); 192 if (dev == NULL) { 193 while (i != 0) { 194 libusb_unref_device((*list)[i - 1]); 195 i--; 196 } 197 free(*list); |
198 *list = NULL; |
|
186 libusb20_be_free(usb_backend); 187 return (LIBUSB_ERROR_NO_MEM); 188 } 189 memset(dev, 0, sizeof(*dev)); 190 | 199 libusb20_be_free(usb_backend); 200 return (LIBUSB_ERROR_NO_MEM); 201 } 202 memset(dev, 0, sizeof(*dev)); 203 |
191 pthread_mutex_init(&dev->lock, NULL); | 204 /* init transfer queues */ 205 TAILQ_INIT(&dev->tr_head); 206 207 /* set context we belong to */ |
192 dev->ctx = ctx; | 208 dev->ctx = ctx; |
193 dev->bus_number = pdev->bus_number; 194 dev->device_address = pdev->device_address; 195 dev->num_configurations = ddesc->bNumConfigurations; | |
196 197 /* link together the two structures */ 198 dev->os_priv = pdev; | 209 210 /* link together the two structures */ 211 dev->os_priv = pdev; |
212 pdev->privLuData = dev; |
|
199 | 213 |
200 pthread_mutex_lock(&ctx->usb_devs_lock); 201 TAILQ_INSERT_HEAD(&ctx->usb_devs, dev, list); 202 pthread_mutex_unlock(&ctx->usb_devs_lock); 203 | |
204 (*list)[i] = libusb_ref_device(dev); 205 i++; 206 } 207 (*list)[i] = NULL; 208 209 libusb20_be_free(usb_backend); | 214 (*list)[i] = libusb_ref_device(dev); 215 i++; 216 } 217 (*list)[i] = NULL; 218 219 libusb20_be_free(usb_backend); |
210 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_list leave"); | |
211 return (i); 212} 213 | 220 return (i); 221} 222 |
214/* 215 * In this function we cant free all the device contained into list because 216 * open_with_pid_vid use some node of list after the free_device_list. 217 */ | |
218void 219libusb_free_device_list(libusb_device **list, int unref_devices) 220{ 221 int i; | 223void 224libusb_free_device_list(libusb_device **list, int unref_devices) 225{ 226 int i; |
222 libusb_context *ctx; | |
223 | 227 |
224 ctx = NULL; 225 GET_CONTEXT(ctx); 226 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list enter"); 227 | |
228 if (list == NULL) | 228 if (list == NULL) |
229 return ; | 229 return; /* be NULL safe */ |
230 231 if (unref_devices) { 232 for (i = 0; list[i] != NULL; i++) 233 libusb_unref_device(list[i]); 234 } 235 free(list); | 230 231 if (unref_devices) { 232 for (i = 0; list[i] != NULL; i++) 233 libusb_unref_device(list[i]); 234 } 235 free(list); |
236 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_device_list leave"); | |
237} 238 239uint8_t | 236} 237 238uint8_t |
240libusb_get_bus_number(libusb_device * dev) | 239libusb_get_bus_number(libusb_device *dev) |
241{ | 240{ |
242 libusb_context *ctx; 243 244 ctx = NULL; 245 GET_CONTEXT(ctx); 246 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number enter"); 247 | |
248 if (dev == NULL) | 241 if (dev == NULL) |
249 return (LIBUSB_ERROR_NO_DEVICE); 250 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_bus_number leave"); 251 return (dev->bus_number); | 242 return (0); /* should not happen */ 243 return (libusb20_dev_get_bus_number(dev->os_priv)); |
252} 253 254uint8_t | 244} 245 246uint8_t |
255libusb_get_device_address(libusb_device * dev) | 247libusb_get_device_address(libusb_device *dev) |
256{ | 248{ |
257 libusb_context *ctx; 258 259 ctx = NULL; 260 GET_CONTEXT(ctx); 261 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address enter"); 262 | |
263 if (dev == NULL) | 249 if (dev == NULL) |
264 return (LIBUSB_ERROR_NO_DEVICE); 265 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device_address leave"); 266 return (dev->device_address); | 250 return (0); /* should not happen */ 251 return (libusb20_dev_get_address(dev->os_priv)); |
267} 268 269int | 252} 253 254int |
270libusb_get_max_packet_size(libusb_device *dev, unsigned char endpoint) | 255libusb_get_max_packet_size(libusb_device *dev, uint8_t endpoint) |
271{ 272 struct libusb_config_descriptor *pdconf; 273 struct libusb_interface *pinf; 274 struct libusb_interface_descriptor *pdinf; 275 struct libusb_endpoint_descriptor *pdend; | 256{ 257 struct libusb_config_descriptor *pdconf; 258 struct libusb_interface *pinf; 259 struct libusb_interface_descriptor *pdinf; 260 struct libusb_endpoint_descriptor *pdend; |
276 libusb_context *ctx; 277 int i, j, k, ret; | 261 int i; 262 int j; 263 int k; 264 int ret; |
278 | 265 |
279 ctx = NULL; 280 GET_CONTEXT(ctx); 281 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size enter"); 282 | |
283 if (dev == NULL) 284 return (LIBUSB_ERROR_NO_DEVICE); 285 | 266 if (dev == NULL) 267 return (LIBUSB_ERROR_NO_DEVICE); 268 |
286 if (libusb_get_active_config_descriptor(dev, &pdconf) < 0) 287 return (LIBUSB_ERROR_OTHER); 288 | 269 ret = libusb_get_active_config_descriptor(dev, &pdconf); 270 if (ret < 0) 271 return (ret); 272 |
289 ret = LIBUSB_ERROR_NOT_FOUND; | 273 ret = LIBUSB_ERROR_NOT_FOUND; |
290 for (i = 0 ; i < pdconf->bNumInterfaces ; i++) { | 274 for (i = 0; i < pdconf->bNumInterfaces; i++) { |
291 pinf = &pdconf->interface[i]; | 275 pinf = &pdconf->interface[i]; |
292 for (j = 0 ; j < pinf->num_altsetting ; j++) { | 276 for (j = 0; j < pinf->num_altsetting; j++) { |
293 pdinf = &pinf->altsetting[j]; | 277 pdinf = &pinf->altsetting[j]; |
294 for (k = 0 ; k < pdinf->bNumEndpoints ; k++) { | 278 for (k = 0; k < pdinf->bNumEndpoints; k++) { |
295 pdend = &pdinf->endpoint[k]; 296 if (pdend->bEndpointAddress == endpoint) { 297 ret = pdend->wMaxPacketSize; 298 goto out; 299 } 300 } 301 } 302 } 303 304out: 305 libusb_free_config_descriptor(pdconf); | 279 pdend = &pdinf->endpoint[k]; 280 if (pdend->bEndpointAddress == endpoint) { 281 ret = pdend->wMaxPacketSize; 282 goto out; 283 } 284 } 285 } 286 } 287 288out: 289 libusb_free_config_descriptor(pdconf); |
306 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_max_packet_size leave"); | |
307 return (ret); 308} 309 310libusb_device * | 290 return (ret); 291} 292 293libusb_device * |
311libusb_ref_device(libusb_device * dev) | 294libusb_ref_device(libusb_device *dev) |
312{ | 295{ |
313 libusb_context *ctx; 314 315 ctx = NULL; 316 GET_CONTEXT(ctx); 317 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device enter"); 318 | |
319 if (dev == NULL) | 296 if (dev == NULL) |
320 return (NULL); | 297 return (NULL); /* be NULL safe */ |
321 | 298 |
322 pthread_mutex_lock(&dev->lock); | 299 CTX_LOCK(dev->ctx); |
323 dev->refcnt++; | 300 dev->refcnt++; |
324 pthread_mutex_unlock(&dev->lock); | 301 CTX_UNLOCK(dev->ctx); |
325 | 302 |
326 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_ref_device leave"); | |
327 return (dev); 328} 329 330void | 303 return (dev); 304} 305 306void |
331libusb_unref_device(libusb_device * dev) | 307libusb_unref_device(libusb_device *dev) |
332{ | 308{ |
333 libusb_context *ctx; 334 335 ctx = NULL; 336 GET_CONTEXT(ctx); 337 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device enter"); 338 | |
339 if (dev == NULL) | 309 if (dev == NULL) |
340 return; | 310 return; /* be NULL safe */ |
341 | 311 |
342 pthread_mutex_lock(&dev->lock); | 312 CTX_LOCK(dev->ctx); |
343 dev->refcnt--; | 313 dev->refcnt--; |
344 pthread_mutex_unlock(&dev->lock); | 314 CTX_UNLOCK(dev->ctx); |
345 346 if (dev->refcnt == 0) { | 315 316 if (dev->refcnt == 0) { |
347 pthread_mutex_lock(&dev->ctx->usb_devs_lock); 348 TAILQ_REMOVE(&ctx->usb_devs, dev, list); 349 pthread_mutex_unlock(&dev->ctx->usb_devs_lock); 350 | |
351 libusb20_dev_free(dev->os_priv); 352 free(dev); 353 } | 317 libusb20_dev_free(dev->os_priv); 318 free(dev); 319 } |
354 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_unref_device leave"); | |
355} 356 357int | 320} 321 322int |
358libusb_open(libusb_device * dev, libusb_device_handle **devh) | 323libusb_open(libusb_device *dev, libusb_device_handle **devh) |
359{ 360 libusb_context *ctx = dev->ctx; 361 struct libusb20_device *pdev = dev->os_priv; | 324{ 325 libusb_context *ctx = dev->ctx; 326 struct libusb20_device *pdev = dev->os_priv; |
362 libusb_device_handle *hdl; 363 unsigned char dummy; | 327 uint8_t dummy; |
364 int err; 365 | 328 int err; 329 |
366 GET_CONTEXT(ctx); 367 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open enter"); 368 369 dummy = 1; | |
370 if (devh == NULL) 371 return (LIBUSB_ERROR_INVALID_PARAM); 372 | 330 if (devh == NULL) 331 return (LIBUSB_ERROR_INVALID_PARAM); 332 |
373 hdl = malloc(sizeof(*hdl)); 374 if (hdl == NULL) 375 return (LIBUSB_ERROR_NO_MEM); | 333 /* set default device handle value */ 334 *devh = NULL; |
376 | 335 |
336 dev = libusb_ref_device(dev); 337 if (dev == NULL) 338 return (LIBUSB_ERROR_INVALID_PARAM); 339 |
|
377 err = libusb20_dev_open(pdev, 16 * 4 /* number of endpoints */ ); 378 if (err) { | 340 err = libusb20_dev_open(pdev, 16 * 4 /* number of endpoints */ ); 341 if (err) { |
379 free(hdl); | 342 libusb_unref_device(dev); |
380 return (LIBUSB_ERROR_NO_MEM); 381 } | 343 return (LIBUSB_ERROR_NO_MEM); 344 } |
382 memset(hdl, 0, sizeof(*hdl)); 383 pthread_mutex_init(&hdl->lock, NULL); 384 385 TAILQ_INIT(&hdl->ep_list); 386 hdl->dev = libusb_ref_device(dev); 387 hdl->claimed_interfaces = 0; 388 hdl->os_priv = dev->os_priv; 389 err = usb_add_pollfd(ctx, libusb20_dev_get_fd(pdev), POLLIN | | 345 libusb10_add_pollfd(ctx, &dev->dev_poll, pdev, libusb20_dev_get_fd(pdev), POLLIN | |
390 POLLOUT | POLLRDNORM | POLLWRNORM); | 346 POLLOUT | POLLRDNORM | POLLWRNORM); |
391 if (err < 0) { 392 libusb_unref_device(dev); 393 free(hdl); 394 return (err); 395 } | |
396 | 347 |
397 pthread_mutex_lock(&ctx->open_devs_lock); 398 TAILQ_INSERT_HEAD(&ctx->open_devs, hdl, list); 399 pthread_mutex_unlock(&ctx->open_devs_lock); 400 401 *devh = hdl; 402 403 pthread_mutex_lock(&ctx->pollfd_modify_lock); 404 ctx->pollfd_modify++; 405 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 406 | 348 /* make sure our event loop detects the new device */ 349 dummy = 0; |
407 err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); | 350 err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); |
408 if (err <= 0) { 409 pthread_mutex_lock(&ctx->pollfd_modify_lock); 410 ctx->pollfd_modify--; 411 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 412 return 0; | 351 if (err < sizeof(dummy)) { 352 /* ignore error, if any */ 353 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open write failed!"); |
413 } | 354 } |
355 *devh = pdev; |
|
414 | 356 |
415 libusb_lock_events(ctx); 416 read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy)); 417 pthread_mutex_lock(&ctx->pollfd_modify_lock); 418 ctx->pollfd_modify--; 419 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 420 libusb_unlock_events(ctx); 421 422 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open leave"); | |
423 return (0); 424} 425 426libusb_device_handle * | 357 return (0); 358} 359 360libusb_device_handle * |
427libusb_open_device_with_vid_pid(libusb_context * ctx, uint16_t vendor_id, | 361libusb_open_device_with_vid_pid(libusb_context *ctx, uint16_t vendor_id, |
428 uint16_t product_id) 429{ 430 struct libusb_device **devs; | 362 uint16_t product_id) 363{ 364 struct libusb_device **devs; |
431 struct libusb_device_handle *devh; | |
432 struct libusb20_device *pdev; 433 struct LIBUSB20_DEVICE_DESC_DECODED *pdesc; | 365 struct libusb20_device *pdev; 366 struct LIBUSB20_DEVICE_DESC_DECODED *pdesc; |
434 int i, j; | 367 int i; 368 int j; |
435 | 369 |
436 GET_CONTEXT(ctx); | 370 ctx = GET_CONTEXT(ctx); 371 if (ctx == NULL) 372 return (NULL); /* be NULL safe */ 373 |
437 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter"); 438 | 374 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid enter"); 375 |
439 devh = NULL; 440 | |
441 if ((i = libusb_get_device_list(ctx, &devs)) < 0) 442 return (NULL); 443 | 376 if ((i = libusb_get_device_list(ctx, &devs)) < 0) 377 return (NULL); 378 |
379 pdev = NULL; 380 |
|
444 for (j = 0; j < i; j++) { | 381 for (j = 0; j < i; j++) { |
445 pdev = (struct libusb20_device *)devs[j]->os_priv; | 382 pdev = devs[j]->os_priv; |
446 pdesc = libusb20_dev_get_device_desc(pdev); | 383 pdesc = libusb20_dev_get_device_desc(pdev); |
384 /* 385 * NOTE: The USB library will automatically swap the 386 * fields in the device descriptor to be of host 387 * endian type! 388 */ |
|
447 if (pdesc->idVendor == vendor_id && 448 pdesc->idProduct == product_id) { | 389 if (pdesc->idVendor == vendor_id && 390 pdesc->idProduct == product_id) { |
449 if (libusb_open(devs[j], &devh) < 0) 450 devh = NULL; 451 break ; | 391 if (libusb_open(devs[j], &pdev) < 0) 392 pdev = NULL; 393 break; |
452 } 453 } 454 455 libusb_free_device_list(devs, 1); 456 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave"); | 394 } 395 } 396 397 libusb_free_device_list(devs, 1); 398 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_open_device_width_vid_pid leave"); |
457 return (devh); | 399 return (pdev); |
458} 459 460void | 400} 401 402void |
461libusb_close(libusb_device_handle * devh) | 403libusb_close(struct libusb20_device *pdev) |
462{ 463 libusb_context *ctx; | 404{ 405 libusb_context *ctx; |
464 struct libusb20_device *pdev; 465 struct usb_ep_tr *eptr; 466 unsigned char dummy = 1; | 406 struct libusb_device *dev; 407 uint8_t dummy; |
467 int err; 468 | 408 int err; 409 |
469 if (devh == NULL) 470 return ; | 410 if (pdev == NULL) 411 return; /* be NULL safe */ |
471 | 412 |
472 ctx = devh->dev->ctx; 473 pdev = devh->os_priv; | 413 dev = libusb_get_device(pdev); 414 ctx = dev->ctx; |
474 | 415 |
475 GET_CONTEXT(ctx); 476 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close enter"); | 416 libusb10_remove_pollfd(ctx, &dev->dev_poll); |
477 | 417 |
478 pthread_mutex_lock(&ctx->pollfd_modify_lock); 479 ctx->pollfd_modify++; 480 pthread_mutex_unlock(&ctx->pollfd_modify_lock); | 418 libusb20_dev_close(pdev); 419 libusb_unref_device(dev); |
481 | 420 |
421 /* make sure our event loop detects the closed device */ 422 dummy = 0; |
|
482 err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); | 423 err = write(ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); |
483 484 if (err <= 0) { 485 pthread_mutex_lock(&ctx->open_devs_lock); 486 TAILQ_REMOVE(&ctx->open_devs, devh, list); 487 pthread_mutex_unlock(&ctx->open_devs_lock); 488 489 usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev)); 490 libusb20_dev_close(pdev); 491 libusb_unref_device(devh->dev); 492 TAILQ_FOREACH(eptr, &devh->ep_list, list) { 493 TAILQ_REMOVE(&devh->ep_list, eptr, list); 494 libusb20_tr_close(((struct libusb20_transfer **) 495 eptr->os_priv)[0]); 496 if (eptr->flags) 497 libusb20_tr_close(((struct libusb20_transfer **) 498 eptr->os_priv)[1]); 499 free((struct libusb20_transfer **)eptr->os_priv); 500 } 501 free(devh); 502 503 pthread_mutex_lock(&ctx->pollfd_modify_lock); 504 ctx->pollfd_modify--; 505 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 506 return ; | 424 if (err < sizeof(dummy)) { 425 /* ignore error, if any */ 426 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close write failed!"); |
507 } | 427 } |
508 libusb_lock_events(ctx); 509 510 read(ctx->ctrl_pipe[0], &dummy, sizeof(dummy)); 511 pthread_mutex_lock(&ctx->open_devs_lock); 512 TAILQ_REMOVE(&ctx->open_devs, devh, list); 513 pthread_mutex_unlock(&ctx->open_devs_lock); 514 515 usb_remove_pollfd(ctx, libusb20_dev_get_fd(pdev)); 516 libusb20_dev_close(pdev); 517 libusb_unref_device(devh->dev); 518 TAILQ_FOREACH(eptr, &devh->ep_list, list) { 519 TAILQ_REMOVE(&devh->ep_list, eptr, list); 520 libusb20_tr_close(((struct libusb20_transfer **) 521 eptr->os_priv)[0]); 522 if (eptr->flags) 523 libusb20_tr_close(((struct libusb20_transfer **) 524 eptr->os_priv)[1]); 525 free((struct libusb20_transfer **)eptr->os_priv); 526 } 527 free(devh); 528 529 pthread_mutex_lock(&ctx->pollfd_modify_lock); 530 ctx->pollfd_modify--; 531 pthread_mutex_unlock(&ctx->pollfd_modify_lock); 532 533 libusb_unlock_events(ctx); 534 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_close leave"); | |
535} 536 537libusb_device * | 428} 429 430libusb_device * |
538libusb_get_device(libusb_device_handle * devh) | 431libusb_get_device(struct libusb20_device *pdev) |
539{ | 432{ |
540 libusb_context *ctx; 541 542 ctx = NULL; 543 GET_CONTEXT(ctx); 544 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device enter"); 545 546 if (devh == NULL) | 433 if (pdev == NULL) |
547 return (NULL); | 434 return (NULL); |
548 549 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_device leave"); 550 return (devh->dev); | 435 return ((libusb_device *)pdev->privLuData); |
551} 552 553int | 436} 437 438int |
554libusb_get_configuration(libusb_device_handle * devh, int *config) | 439libusb_get_configuration(struct libusb20_device *pdev, int *config) |
555{ | 440{ |
556 libusb_context *ctx; | 441 struct libusb20_config *pconf; |
557 | 442 |
558 ctx = NULL; 559 GET_CONTEXT(ctx); 560 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration enter"); 561 562 if (devh == NULL || config == NULL) | 443 if (pdev == NULL || config == NULL) |
563 return (LIBUSB_ERROR_INVALID_PARAM); 564 | 444 return (LIBUSB_ERROR_INVALID_PARAM); 445 |
565 *config = libusb20_dev_get_config_index((struct libusb20_device *) 566 devh->dev->os_priv); | 446 pconf = libusb20_dev_alloc_config(pdev, libusb20_dev_get_config_index(pdev)); 447 if (pconf == NULL) 448 return (LIBUSB_ERROR_NO_MEM); |
567 | 449 |
568 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_get_configuration leave"); | 450 *config = pconf->desc.bConfigurationValue; 451 452 free(pconf); 453 |
569 return (0); 570} 571 572int | 454 return (0); 455} 456 457int |
573libusb_set_configuration(libusb_device_handle * devh, int configuration) | 458libusb_set_configuration(struct libusb20_device *pdev, int configuration) |
574{ | 459{ |
575 struct libusb20_device *pdev; 576 libusb_context *ctx; | 460 struct libusb20_config *pconf; 461 struct libusb_device *dev; 462 int err; 463 uint8_t i; |
577 | 464 |
578 ctx = NULL; 579 GET_CONTEXT(ctx); 580 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration enter"); | 465 dev = libusb_get_device(pdev); |
581 | 466 |
582 if (devh == NULL) | 467 if (dev == NULL) |
583 return (LIBUSB_ERROR_INVALID_PARAM); 584 | 468 return (LIBUSB_ERROR_INVALID_PARAM); 469 |
585 pdev = (struct libusb20_device *)devh->dev->os_priv; | 470 if (configuration < 1) { 471 /* unconfigure */ 472 i = 255; 473 } else { 474 for (i = 0; i != 255; i++) { 475 uint8_t found; |
586 | 476 |
587 libusb20_dev_set_config_index(pdev, configuration); 588 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_configuration leave"); 589 return (0); | 477 pconf = libusb20_dev_alloc_config(pdev, i); 478 if (pconf == NULL) 479 return (LIBUSB_ERROR_INVALID_PARAM); 480 found = (pconf->desc.bConfigurationValue 481 == configuration); 482 free(pconf); 483 484 if (found) 485 goto set_config; 486 } 487 return (LIBUSB_ERROR_INVALID_PARAM); 488 } 489 490set_config: 491 492 libusb10_cancel_all_transfer(dev); 493 494 libusb10_remove_pollfd(dev->ctx, &dev->dev_poll); 495 496 err = libusb20_dev_set_config_index(pdev, i); 497 498 libusb10_add_pollfd(dev->ctx, &dev->dev_poll, pdev, libusb20_dev_get_fd(pdev), POLLIN | 499 POLLOUT | POLLRDNORM | POLLWRNORM); 500 501 return (err ? LIBUSB_ERROR_INVALID_PARAM : 0); |
590} 591 592int | 502} 503 504int |
593libusb_claim_interface(libusb_device_handle * dev, int interface_number) | 505libusb_claim_interface(struct libusb20_device *pdev, int interface_number) |
594{ | 506{ |
595 libusb_context *ctx; 596 int ret = 0; | 507 libusb_device *dev; 508 int err = 0; |
597 | 509 |
598 ctx = NULL; 599 GET_CONTEXT(ctx); 600 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface enter"); 601 | 510 dev = libusb_get_device(pdev); |
602 if (dev == NULL) 603 return (LIBUSB_ERROR_INVALID_PARAM); 604 | 511 if (dev == NULL) 512 return (LIBUSB_ERROR_INVALID_PARAM); 513 |
605 if (interface_number >= sizeof(dev->claimed_interfaces) * 8) | 514 if (interface_number < 0 || interface_number > 31) |
606 return (LIBUSB_ERROR_INVALID_PARAM); 607 | 515 return (LIBUSB_ERROR_INVALID_PARAM); 516 |
608 pthread_mutex_lock(&(dev->lock)); | 517 CTX_LOCK(dev->ctx); |
609 if (dev->claimed_interfaces & (1 << interface_number)) | 518 if (dev->claimed_interfaces & (1 << interface_number)) |
610 ret = LIBUSB_ERROR_BUSY; | 519 err = LIBUSB_ERROR_BUSY; |
611 | 520 |
612 if (!ret) | 521 if (!err) |
613 dev->claimed_interfaces |= (1 << interface_number); | 522 dev->claimed_interfaces |= (1 << interface_number); |
614 pthread_mutex_unlock(&(dev->lock)); 615 616 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_claim_interface leave"); 617 return (ret); | 523 CTX_UNLOCK(dev->ctx); 524 return (err); |
618} 619 620int | 525} 526 527int |
621libusb_release_interface(libusb_device_handle * dev, int interface_number) | 528libusb_release_interface(struct libusb20_device *pdev, int interface_number) |
622{ | 529{ |
623 libusb_context *ctx; 624 int ret; | 530 libusb_device *dev; 531 int err = 0; |
625 | 532 |
626 ctx = NULL; 627 GET_CONTEXT(ctx); 628 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface enter"); 629 630 ret = 0; | 533 dev = libusb_get_device(pdev); |
631 if (dev == NULL) 632 return (LIBUSB_ERROR_INVALID_PARAM); 633 | 534 if (dev == NULL) 535 return (LIBUSB_ERROR_INVALID_PARAM); 536 |
634 if (interface_number >= sizeof(dev->claimed_interfaces) * 8) | 537 if (interface_number < 0 || interface_number > 31) |
635 return (LIBUSB_ERROR_INVALID_PARAM); 636 | 538 return (LIBUSB_ERROR_INVALID_PARAM); 539 |
637 pthread_mutex_lock(&(dev->lock)); | 540 CTX_LOCK(dev->ctx); |
638 if (!(dev->claimed_interfaces & (1 << interface_number))) | 541 if (!(dev->claimed_interfaces & (1 << interface_number))) |
639 ret = LIBUSB_ERROR_NOT_FOUND; | 542 err = LIBUSB_ERROR_NOT_FOUND; |
640 | 543 |
641 if (!ret) | 544 if (!err) |
642 dev->claimed_interfaces &= ~(1 << interface_number); | 545 dev->claimed_interfaces &= ~(1 << interface_number); |
643 pthread_mutex_unlock(&(dev->lock)); 644 645 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_release_interface leave"); 646 return (ret); | 546 CTX_UNLOCK(dev->ctx); 547 return (err); |
647} 648 649int | 548} 549 550int |
650libusb_set_interface_alt_setting(libusb_device_handle * dev, | 551libusb_set_interface_alt_setting(struct libusb20_device *pdev, |
651 int interface_number, int alternate_setting) 652{ | 552 int interface_number, int alternate_setting) 553{ |
653 libusb_context *ctx; | 554 libusb_device *dev; 555 int err = 0; |
654 | 556 |
655 ctx = NULL; 656 GET_CONTEXT(ctx); 657 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting enter"); 658 | 557 dev = libusb_get_device(pdev); |
659 if (dev == NULL) 660 return (LIBUSB_ERROR_INVALID_PARAM); 661 | 558 if (dev == NULL) 559 return (LIBUSB_ERROR_INVALID_PARAM); 560 |
662 if (interface_number >= sizeof(dev->claimed_interfaces) *8) | 561 if (interface_number < 0 || interface_number > 31) |
663 return (LIBUSB_ERROR_INVALID_PARAM); 664 | 562 return (LIBUSB_ERROR_INVALID_PARAM); 563 |
665 pthread_mutex_lock(&dev->lock); 666 if (!(dev->claimed_interfaces & (1 << interface_number))) { 667 pthread_mutex_unlock(&dev->lock); 668 return (LIBUSB_ERROR_NOT_FOUND); 669 } 670 pthread_mutex_unlock(&dev->lock); | 564 CTX_LOCK(dev->ctx); 565 if (!(dev->claimed_interfaces & (1 << interface_number))) 566 err = LIBUSB_ERROR_NOT_FOUND; 567 CTX_UNLOCK(dev->ctx); |
671 | 568 |
672 if (libusb20_dev_set_alt_index(dev->os_priv, interface_number, 673 alternate_setting) != 0) 674 return (LIBUSB_ERROR_OTHER); 675 676 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_set_interface_alt_setting leave"); 677 return (0); | 569 if (err) 570 return (err); 571 572 libusb10_cancel_all_transfer(dev); 573 574 libusb10_remove_pollfd(dev->ctx, &dev->dev_poll); 575 576 err = libusb20_dev_set_alt_index(pdev, 577 interface_number, alternate_setting); 578 579 libusb10_add_pollfd(dev->ctx, &dev->dev_poll, 580 pdev, libusb20_dev_get_fd(pdev), 581 POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM); 582 583 return (err ? LIBUSB_ERROR_OTHER : 0); |
678} 679 | 584} 585 |
586static struct libusb20_transfer * 587libusb10_get_transfer(struct libusb20_device *pdev, 588 uint8_t endpoint, uint8_t index) 589{ 590 index &= 1; /* double buffering */ 591 592 index |= (endpoint & LIBUSB20_ENDPOINT_ADDRESS_MASK) * 4; 593 594 if (endpoint & LIBUSB20_ENDPOINT_DIR_MASK) { 595 /* this is an IN endpoint */ 596 index |= 2; 597 } 598 return (libusb20_tr_get_pointer(pdev, index)); 599} 600 |
|
680int | 601int |
681libusb_clear_halt(libusb_device_handle * devh, unsigned char endpoint) | 602libusb_clear_halt(struct libusb20_device *pdev, uint8_t endpoint) |
682{ 683 struct libusb20_transfer *xfer; | 603{ 604 struct libusb20_transfer *xfer; |
684 struct libusb20_device *pdev; 685 libusb_context *ctx; 686 int ret; | 605 struct libusb_device *dev; 606 int err; |
687 | 607 |
688 ctx = NULL; 689 GET_CONTEXT(ctx); 690 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt enter"); 691 692 pdev = devh->os_priv; 693 xfer = libusb20_tr_get_pointer(pdev, 694 ((endpoint / 0x40) | (endpoint * 4)) % (16 * 4)); | 608 xfer = libusb10_get_transfer(pdev, endpoint, 0); |
695 if (xfer == NULL) | 609 if (xfer == NULL) |
696 return (LIBUSB_ERROR_NO_MEM); | 610 return (LIBUSB_ERROR_INVALID_PARAM); |
697 | 611 |
698 pthread_mutex_lock(&libusb20_lock); 699 ret = libusb20_tr_open(xfer, 0, 0, endpoint); 700 if (ret != 0 && ret != LIBUSB20_ERROR_BUSY) { 701 pthread_mutex_unlock(&libusb20_lock); | 612 dev = libusb_get_device(pdev); 613 614 CTX_LOCK(dev->ctx); 615 err = libusb20_tr_open(xfer, 0, 0, endpoint); 616 CTX_UNLOCK(dev->ctx); 617 618 if (err != 0 && err != LIBUSB20_ERROR_BUSY) |
702 return (LIBUSB_ERROR_OTHER); | 619 return (LIBUSB_ERROR_OTHER); |
703 } | |
704 705 libusb20_tr_clear_stall_sync(xfer); | 620 621 libusb20_tr_clear_stall_sync(xfer); |
706 if (ret == 0) /* check if we have open the device */ 707 libusb20_tr_close(xfer); 708 pthread_mutex_unlock(&libusb20_lock); | |
709 | 622 |
710 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_clear_halt leave"); 711 return (0); | 623 /* check if we opened the transfer */ 624 if (err == 0) { 625 CTX_LOCK(dev->ctx); 626 libusb20_tr_close(xfer); 627 CTX_UNLOCK(dev->ctx); 628 } 629 return (0); /* success */ |
712} 713 714int | 630} 631 632int |
715libusb_reset_device(libusb_device_handle * dev) | 633libusb_reset_device(struct libusb20_device *pdev) |
716{ | 634{ |
717 libusb_context *ctx; | 635 libusb_device *dev; 636 int err; |
718 | 637 |
719 ctx = NULL; 720 GET_CONTEXT(ctx); 721 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device enter"); 722 | 638 dev = libusb_get_device(pdev); |
723 if (dev == NULL) 724 return (LIBUSB20_ERROR_INVALID_PARAM); 725 | 639 if (dev == NULL) 640 return (LIBUSB20_ERROR_INVALID_PARAM); 641 |
726 libusb20_dev_reset(dev->os_priv); 727 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_reset_device leave"); 728 return (0); | 642 libusb10_cancel_all_transfer(dev); 643 644 libusb10_remove_pollfd(dev->ctx, &dev->dev_poll); 645 646 err = libusb20_dev_reset(pdev); 647 648 libusb10_add_pollfd(dev->ctx, &dev->dev_poll, 649 pdev, libusb20_dev_get_fd(pdev), 650 POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM); 651 652 return (err ? LIBUSB_ERROR_OTHER : 0); |
729} 730 731int | 653} 654 655int |
732libusb_kernel_driver_active(libusb_device_handle * devh, int interface) | 656libusb_kernel_driver_active(struct libusb20_device *pdev, int interface) |
733{ | 657{ |
734 libusb_context *ctx; 735 736 ctx = NULL; 737 GET_CONTEXT(ctx); 738 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active enter"); 739 740 if (devh == NULL) | 658 if (pdev == NULL) |
741 return (LIBUSB_ERROR_INVALID_PARAM); 742 | 659 return (LIBUSB_ERROR_INVALID_PARAM); 660 |
743 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_kernel_driver_active leave"); 744 return (libusb20_dev_kernel_driver_active(devh->os_priv, interface)); | 661 return (libusb20_dev_kernel_driver_active( 662 pdev, interface)); |
745} 746 747int | 663} 664 665int |
748libusb_detach_kernel_driver(libusb_device_handle * devh, int interface) | 666libusb_detach_kernel_driver(struct libusb20_device *pdev, int interface) |
749{ | 667{ |
750 struct libusb20_device *pdev; 751 libusb_context *ctx; | 668 int err; |
752 | 669 |
753 ctx = NULL; 754 GET_CONTEXT(ctx); 755 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver enter"); 756 757 if (devh == NULL) | 670 if (pdev == NULL) |
758 return (LIBUSB_ERROR_INVALID_PARAM); 759 | 671 return (LIBUSB_ERROR_INVALID_PARAM); 672 |
760 pdev = (struct libusb20_device *)devh->dev->os_priv; 761 if (libusb20_dev_detach_kernel_driver(pdev, interface) == LIBUSB20_ERROR_OTHER) 762 return (LIBUSB_ERROR_OTHER); | 673 err = libusb20_dev_detach_kernel_driver( 674 pdev, interface); |
763 | 675 |
764 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_detach_kernel_driver leave"); 765 return (0); | 676 return (err ? LIBUSB20_ERROR_OTHER : 0); |
766} 767 | 677} 678 |
768/* 769 * stub function. 770 * libusb20 doesn't support this feature. 771 */ | |
772int | 679int |
773libusb_attach_kernel_driver(libusb_device_handle * devh, int interface) | 680libusb_attach_kernel_driver(struct libusb20_device *pdev, int interface) |
774{ | 681{ |
775 libusb_context *ctx; 776 777 ctx = NULL; 778 GET_CONTEXT(ctx); 779 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver enter"); 780 781 if (devh == NULL) | 682 if (pdev == NULL) |
782 return (LIBUSB_ERROR_INVALID_PARAM); | 683 return (LIBUSB_ERROR_INVALID_PARAM); |
783 784 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_attach_kernel_driver leave"); | 684 /* stub - currently not supported by libusb20 */ |
785 return (0); 786} 787 788/* Asynchronous device I/O */ 789 790struct libusb_transfer * 791libusb_alloc_transfer(int iso_packets) 792{ | 685 return (0); 686} 687 688/* Asynchronous device I/O */ 689 690struct libusb_transfer * 691libusb_alloc_transfer(int iso_packets) 692{ |
793 struct libusb_transfer *xfer; 794 struct usb_transfer *bxfer; 795 libusb_context *ctx; | 693 struct libusb_transfer *uxfer; 694 struct libusb_super_transfer *sxfer; |
796 int len; 797 | 695 int len; 696 |
798 ctx = NULL; 799 GET_CONTEXT(ctx); 800 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer enter"); 801 | |
802 len = sizeof(struct libusb_transfer) + | 697 len = sizeof(struct libusb_transfer) + |
803 sizeof(struct usb_transfer) + | 698 sizeof(struct libusb_super_transfer) + |
804 (iso_packets * sizeof(libusb_iso_packet_descriptor)); 805 | 699 (iso_packets * sizeof(libusb_iso_packet_descriptor)); 700 |
806 bxfer = malloc(len); 807 if (bxfer == NULL) | 701 sxfer = malloc(len); 702 if (sxfer == NULL) |
808 return (NULL); 809 | 703 return (NULL); 704 |
810 memset(bxfer, 0, len); 811 bxfer->num_iso_packets = iso_packets; | 705 memset(sxfer, 0, len); |
812 | 706 |
813 xfer = (struct libusb_transfer *) ((uint8_t *)bxfer + 814 sizeof(struct usb_transfer)); | 707 uxfer = (struct libusb_transfer *)( 708 ((uint8_t *)sxfer) + sizeof(*sxfer)); |
815 | 709 |
816 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_alloc_transfer leave"); 817 return (xfer); | 710 /* set default value */ 711 uxfer->num_iso_packets = iso_packets; 712 713 return (uxfer); |
818} 819 820void | 714} 715 716void |
821libusb_free_transfer(struct libusb_transfer *xfer) | 717libusb_free_transfer(struct libusb_transfer *uxfer) |
822{ | 718{ |
823 struct usb_transfer *bxfer; 824 libusb_context *ctx; | 719 struct libusb_super_transfer *sxfer; |
825 | 720 |
826 ctx = NULL; 827 GET_CONTEXT(ctx); 828 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer enter"); | 721 if (uxfer == NULL) 722 return; /* be NULL safe */ |
829 | 723 |
830 if (xfer == NULL) 831 return ; | 724 sxfer = (struct libusb_super_transfer *)( 725 (uint8_t *)uxfer - sizeof(*sxfer)); |
832 | 726 |
833 bxfer = (struct usb_transfer *) ((uint8_t *)xfer - 834 sizeof(struct usb_transfer)); 835 836 free(bxfer); 837 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_free_transfer leave"); 838 return; | 727 free(sxfer); |
839} 840 841static int | 728} 729 730static int |
842libusb_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer) | 731libusb10_get_maxframe(struct libusb20_device *pdev, libusb_transfer *xfer) |
843{ 844 int ret; 845 int usb_speed; 846 847 usb_speed = libusb20_dev_get_speed(pdev); 848 849 switch (xfer->type) { 850 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 851 switch (usb_speed) { 852 case LIBUSB20_SPEED_LOW: 853 case LIBUSB20_SPEED_FULL: 854 ret = 60 * 1; | 732{ 733 int ret; 734 int usb_speed; 735 736 usb_speed = libusb20_dev_get_speed(pdev); 737 738 switch (xfer->type) { 739 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 740 switch (usb_speed) { 741 case LIBUSB20_SPEED_LOW: 742 case LIBUSB20_SPEED_FULL: 743 ret = 60 * 1; |
855 break ; 856 default : | 744 break; 745 default: |
857 ret = 60 * 8; | 746 ret = 60 * 8; |
858 break ; | 747 break; |
859 } | 748 } |
860 break ; | 749 break; |
861 case LIBUSB_TRANSFER_TYPE_CONTROL: 862 ret = 2; | 750 case LIBUSB_TRANSFER_TYPE_CONTROL: 751 ret = 2; |
863 break ; | 752 break; |
864 default: 865 ret = 1; | 753 default: 754 ret = 1; |
866 break ; | 755 break; |
867 } | 756 } |
868 869 return ret; | 757 return (ret); |
870} 871 872static int | 758} 759 760static int |
873libusb_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer) | 761libusb10_get_buffsize(struct libusb20_device *pdev, libusb_transfer *xfer) |
874{ 875 int ret; 876 int usb_speed; 877 878 usb_speed = libusb20_dev_get_speed(pdev); 879 880 switch (xfer->type) { 881 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: | 762{ 763 int ret; 764 int usb_speed; 765 766 usb_speed = libusb20_dev_get_speed(pdev); 767 768 switch (xfer->type) { 769 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: |
882 ret = 0; 883 break ; | 770 ret = 0; /* kernel will auto-select */ 771 break; |
884 case LIBUSB_TRANSFER_TYPE_CONTROL: | 772 case LIBUSB_TRANSFER_TYPE_CONTROL: |
773 ret = 1024; 774 break; 775 default: |
|
885 switch (usb_speed) { | 776 switch (usb_speed) { |
886 case LIBUSB20_SPEED_LOW: 887 ret = 8; 888 break ; 889 case LIBUSB20_SPEED_FULL: 890 ret = 64; 891 break ; 892 default: 893 ret = 64; 894 break ; | 777 case LIBUSB20_SPEED_LOW: 778 ret = 256; 779 break; 780 case LIBUSB20_SPEED_FULL: 781 ret = 4096; 782 break; 783 default: 784 ret = 16384; 785 break; |
895 } | 786 } |
896 ret += 8; 897 break ; 898 default : 899 switch (usb_speed) { 900 case LIBUSB20_SPEED_LOW: 901 ret = 256; 902 break ; 903 case LIBUSB20_SPEED_FULL: 904 ret = 4096; 905 break ; 906 default: 907 ret = 16384; 908 break ; 909 } 910 break ; | 787 break; |
911 } | 788 } |
912 913 return ret; | 789 return (ret); |
914} 915 | 790} 791 |
792static int 793libusb10_convert_error(uint8_t status) 794{ 795 ; /* indent fix */ 796 797 switch (status) { 798 case LIBUSB20_TRANSFER_START: 799 case LIBUSB20_TRANSFER_COMPLETED: 800 return (LIBUSB_TRANSFER_COMPLETED); 801 case LIBUSB20_TRANSFER_OVERFLOW: 802 return (LIBUSB_TRANSFER_OVERFLOW); 803 case LIBUSB20_TRANSFER_NO_DEVICE: 804 return (LIBUSB_TRANSFER_NO_DEVICE); 805 case LIBUSB20_TRANSFER_STALL: 806 return (LIBUSB_TRANSFER_STALL); 807 case LIBUSB20_TRANSFER_CANCELLED: 808 return (LIBUSB_TRANSFER_CANCELLED); 809 case LIBUSB20_TRANSFER_TIMED_OUT: 810 return (LIBUSB_TRANSFER_TIMED_OUT); 811 default: 812 return (LIBUSB_TRANSFER_ERROR); 813 } 814} 815 816/* This function must be called locked */ 817 |
|
916static void | 818static void |
917libusb10_proxy(struct libusb20_transfer *xfer) | 819libusb10_complete_transfer(struct libusb20_transfer *pxfer, 820 struct libusb_super_transfer *sxfer, int status) |
918{ | 821{ |
919 struct usb_transfer *usb_backend; 920 struct libusb20_device *pdev; 921 libusb_transfer *usb_xfer; 922 libusb_context *ctx; 923 uint32_t pos; 924 uint32_t max; 925 uint32_t size; | 822 struct libusb_transfer *uxfer; 823 struct libusb_device *dev; 824 825 uxfer = (struct libusb_transfer *)( 826 ((uint8_t *)sxfer) + sizeof(*sxfer)); 827 828 if (pxfer != NULL) 829 libusb20_tr_set_priv_sc1(pxfer, NULL); 830 831 uxfer->status = status; 832 833 dev = libusb_get_device(uxfer->dev_handle); 834 835 TAILQ_INSERT_TAIL(&dev->ctx->tr_done, sxfer, entry); 836} 837 838/* This function must be called locked */ 839 840static void 841libusb10_isoc_proxy(struct libusb20_transfer *pxfer) 842{ 843 struct libusb_super_transfer *sxfer; 844 struct libusb_transfer *uxfer; 845 uint32_t actlen; 846 uint16_t iso_packets; 847 uint16_t i; |
926 uint8_t status; | 848 uint8_t status; |
927 uint32_t iso_packets; 928 int i; | 849 uint8_t flags; |
929 | 850 |
930 status = libusb20_tr_get_status(xfer); 931 usb_xfer = libusb20_tr_get_priv_sc0(xfer); 932 usb_backend = (struct usb_transfer *) ((uint8_t *)usb_xfer - 933 sizeof(struct usb_transfer)); 934 pdev = usb_xfer->dev_handle->dev->os_priv; 935 ctx = usb_xfer->dev_handle->dev->ctx; 936 GET_CONTEXT(ctx); | 851 status = libusb20_tr_get_status(pxfer); 852 sxfer = libusb20_tr_get_priv_sc1(pxfer); 853 actlen = libusb20_tr_get_actual_length(pxfer); 854 iso_packets = libusb20_tr_get_max_frames(pxfer); |
937 | 855 |
856 if (sxfer == NULL) 857 return; /* cancelled - nothing to do */ 858 859 uxfer = (struct libusb_transfer *)( 860 ((uint8_t *)sxfer) + sizeof(*sxfer)); 861 862 if (iso_packets > uxfer->num_iso_packets) 863 iso_packets = uxfer->num_iso_packets; 864 865 if (iso_packets == 0) 866 return; /* nothing to do */ 867 868 /* make sure that the number of ISOCHRONOUS packets is valid */ 869 uxfer->num_iso_packets = iso_packets; 870 871 flags = uxfer->flags; 872 |
|
938 switch (status) { 939 case LIBUSB20_TRANSFER_COMPLETED: | 873 switch (status) { 874 case LIBUSB20_TRANSFER_COMPLETED: |
940 usb_backend->transferred += libusb20_tr_get_actual_length(xfer); 941 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER %i bytes", 942 usb_backend->transferred); 943 if (usb_backend->transferred != usb_xfer->length) 944 goto tr_start; | |
945 | 875 |
946 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 TRANSFER COMPLETE"); 947 usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_COMPLETED); | 876 /* update actual length */ 877 uxfer->actual_length = actlen; 878 for (i = 0; i != iso_packets; i++) { 879 uxfer->iso_packet_desc[i].actual_length = 880 libusb20_tr_get_length(pxfer, i); 881 } 882 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 883 break; |
948 | 884 |
949 break ; | |
950 case LIBUSB20_TRANSFER_START: | 885 case LIBUSB20_TRANSFER_START: |
951tr_start: 952 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 START"); 953 max = libusb_get_buffsize(pdev, usb_xfer); 954 pos = usb_backend->transferred; 955 size = (usb_xfer->length - pos); 956 size = (size > max) ? max : size; 957 usb_xfer->actual_length = 0; 958 switch (usb_xfer->type) { 959 case LIBUSB_TRANSFER_TYPE_CONTROL: 960 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE CTR"); 961 libusb20_tr_setup_control(xfer, usb_xfer->buffer, 962 (void *)(((uint8_t *) &usb_xfer->buffer[pos]) + 963 sizeof(libusb_control_setup)), 964 usb_xfer->timeout); 965 break ; 966 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 967 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE ISO"); 968 iso_packets = libusb20_tr_get_max_frames(xfer); 969 if (usb_xfer->num_iso_packets > iso_packets) 970 usb_xfer->num_iso_packets = iso_packets; 971 for (i = 0 ; i < usb_xfer->num_iso_packets ; i++) { 972 libusb20_tr_setup_isoc(xfer, 973 &usb_xfer->buffer[pos], size, i); 974 } 975 libusb20_tr_set_total_frames(xfer, i); 976 break ; 977 case LIBUSB_TRANSFER_TYPE_BULK: 978 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE BULK"); 979 libusb20_tr_setup_bulk(xfer, &usb_xfer->buffer[pos], 980 size, usb_xfer->timeout); 981 break ; 982 case LIBUSB_TRANSFER_TYPE_INTERRUPT: 983 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TYPE INTR"); 984 libusb20_tr_setup_intr(xfer, &usb_xfer->buffer[pos], 985 size, usb_xfer->timeout); 986 break ; | 886 887 /* setup length(s) */ 888 actlen = 0; 889 for (i = 0; i != iso_packets; i++) { 890 libusb20_tr_setup_isoc(pxfer, 891 &uxfer->buffer[actlen], 892 uxfer->iso_packet_desc[i].length, i); 893 actlen += uxfer->iso_packet_desc[i].length; |
987 } | 894 } |
988 libusb20_tr_submit(xfer); 989 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20 SUBMITED"); 990 break ; | 895 896 /* no remainder */ 897 sxfer->rem_len = 0; 898 899 libusb20_tr_set_total_frames(pxfer, iso_packets); 900 libusb20_tr_submit(pxfer); 901 902 /* fork another USB transfer, if any */ 903 libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint); 904 break; 905 |
991 default: | 906 default: |
992 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "TRANSFER DEFAULT 0x%x\n", 993 status); 994 usb_backend->transferred = 0; 995 usb_handle_transfer_completion(usb_backend, LIBUSB_TRANSFER_CANCELLED); 996 break ; | 907 libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status)); 908 break; |
997 } | 909 } |
910} |
|
998 | 911 |
912/* This function must be called locked */ 913 914static void 915libusb10_bulk_intr_proxy(struct libusb20_transfer *pxfer) 916{ 917 struct libusb_super_transfer *sxfer; 918 struct libusb_transfer *uxfer; 919 uint32_t max_bulk; 920 uint32_t actlen; 921 uint8_t status; 922 uint8_t flags; 923 924 status = libusb20_tr_get_status(pxfer); 925 sxfer = libusb20_tr_get_priv_sc1(pxfer); 926 max_bulk = libusb20_tr_get_max_total_length(pxfer); 927 actlen = libusb20_tr_get_actual_length(pxfer); 928 929 if (sxfer == NULL) 930 return; /* cancelled - nothing to do */ 931 932 uxfer = (struct libusb_transfer *)( 933 ((uint8_t *)sxfer) + sizeof(*sxfer)); 934 935 flags = uxfer->flags; 936 |
|
999 switch (status) { 1000 case LIBUSB20_TRANSFER_COMPLETED: | 937 switch (status) { 938 case LIBUSB20_TRANSFER_COMPLETED: |
1001 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS COMPLETED"); 1002 usb_xfer->status = LIBUSB_TRANSFER_COMPLETED; 1003 break ; 1004 case LIBUSB20_TRANSFER_OVERFLOW: 1005 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR OVERFLOW"); 1006 usb_xfer->status = LIBUSB_TRANSFER_OVERFLOW; 1007 break ; 1008 case LIBUSB20_TRANSFER_NO_DEVICE: 1009 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR NO DEVICE"); 1010 usb_xfer->status = LIBUSB_TRANSFER_NO_DEVICE; 1011 break ; 1012 case LIBUSB20_TRANSFER_STALL: 1013 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR STALL"); 1014 usb_xfer->status = LIBUSB_TRANSFER_STALL; 1015 break ; 1016 case LIBUSB20_TRANSFER_CANCELLED: 1017 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR CANCELLED"); 1018 usb_xfer->status = LIBUSB_TRANSFER_CANCELLED; 1019 break ; 1020 case LIBUSB20_TRANSFER_TIMED_OUT: 1021 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "STATUS TR TIMEOUT"); 1022 usb_xfer->status = LIBUSB_TRANSFER_TIMED_OUT; 1023 break ; 1024 case LIBUSB20_TRANSFER_ERROR: 1025 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "ERROR"); 1026 usb_xfer->status = LIBUSB_TRANSFER_ERROR; 1027 break ; | 939 940 uxfer->actual_length += actlen; 941 942 /* check for short packet */ 943 if (sxfer->last_len != actlen) { 944 if (flags & LIBUSB_TRANSFER_SHORT_NOT_OK) { 945 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_ERROR); 946 } else { 947 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 948 } 949 break; 950 } 951 /* check for end of data */ 952 if (sxfer->rem_len == 0) { 953 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 954 break; 955 } 956 /* FALLTHROUGH */ 957 958 case LIBUSB20_TRANSFER_START: 959 if (max_bulk > sxfer->rem_len) { 960 max_bulk = sxfer->rem_len; 961 } 962 /* setup new BULK or INTERRUPT transaction */ 963 libusb20_tr_setup_bulk(pxfer, 964 sxfer->curr_data, max_bulk, uxfer->timeout); 965 966 /* update counters */ 967 sxfer->last_len = max_bulk; 968 sxfer->curr_data += max_bulk; 969 sxfer->rem_len -= max_bulk; 970 971 libusb20_tr_submit(pxfer); 972 973 /* check if we can fork another USB transfer */ 974 if (sxfer->rem_len == 0) 975 libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint); 976 break; 977 978 default: 979 libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status)); 980 break; |
1028 } 1029} 1030 | 981 } 982} 983 |
1031int 1032libusb_submit_transfer(struct libusb_transfer *xfer) | 984/* This function must be called locked */ 985 986static void 987libusb10_ctrl_proxy(struct libusb20_transfer *pxfer) |
1033{ | 988{ |
1034 struct libusb20_transfer **usb20_xfer; 1035 struct usb_transfer *usb_backend; 1036 struct usb_transfer *usb_node; 1037 struct libusb20_device *pdev; 1038 struct usb_ep_tr *eptr; 1039 struct timespec cur_ts; 1040 struct timeval *cur_tv; 1041 libusb_device_handle *devh; 1042 libusb_context *ctx; 1043 int maxframe; 1044 int buffsize; 1045 int ep_idx; 1046 int ret; | 989 struct libusb_super_transfer *sxfer; 990 struct libusb_transfer *uxfer; 991 uint32_t max_bulk; 992 uint32_t actlen; 993 uint8_t status; 994 uint8_t flags; |
1047 | 995 |
1048 if (xfer == NULL) 1049 return (LIBUSB_ERROR_NO_MEM); | 996 status = libusb20_tr_get_status(pxfer); 997 sxfer = libusb20_tr_get_priv_sc1(pxfer); 998 max_bulk = libusb20_tr_get_max_total_length(pxfer); 999 actlen = libusb20_tr_get_actual_length(pxfer); |
1050 | 1000 |
1051 usb20_xfer = malloc(2 * sizeof(struct libusb20_transfer *)); 1052 if (usb20_xfer == NULL) 1053 return (LIBUSB_ERROR_NO_MEM); | 1001 if (sxfer == NULL) 1002 return; /* cancelled - nothing to do */ |
1054 | 1003 |
1055 ctx = xfer->dev_handle->dev->ctx; 1056 pdev = xfer->dev_handle->os_priv; 1057 devh = xfer->dev_handle; | 1004 uxfer = (struct libusb_transfer *)( 1005 ((uint8_t *)sxfer) + sizeof(*sxfer)); |
1058 | 1006 |
1059 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter"); | 1007 flags = uxfer->flags; |
1060 | 1008 |
1061 usb_backend = (struct usb_transfer *) ((uint8_t *)xfer - 1062 sizeof(struct usb_transfer)); 1063 usb_backend->transferred = 0; 1064 usb_backend->flags = 0; | 1009 switch (status) { 1010 case LIBUSB20_TRANSFER_COMPLETED: |
1065 | 1011 |
1066 if (xfer->timeout != 0) { 1067 clock_gettime(CLOCK_MONOTONIC, &cur_ts); 1068 cur_ts.tv_sec += xfer->timeout / 1000; 1069 cur_ts.tv_nsec += (xfer->timeout % 1000) * 1000000; 1070 1071 if (cur_ts.tv_nsec > 1000000000) { 1072 cur_ts.tv_nsec -= 1000000000; 1073 cur_ts.tv_sec++; | 1012 uxfer->actual_length += actlen; 1013 1014 /* subtract length of SETUP packet, if any */ 1015 actlen -= libusb20_tr_get_length(pxfer, 0); 1016 1017 /* check for short packet */ 1018 if (sxfer->last_len != actlen) { 1019 if (flags & LIBUSB_TRANSFER_SHORT_NOT_OK) { 1020 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_ERROR); 1021 } else { 1022 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 1023 } 1024 break; |
1074 } | 1025 } |
1075 1076 TIMESPEC_TO_TIMEVAL(&usb_backend->timeout, &cur_ts); 1077 } | 1026 /* check for end of data */ 1027 if (sxfer->rem_len == 0) { 1028 libusb10_complete_transfer(pxfer, sxfer, LIBUSB_TRANSFER_COMPLETED); 1029 break; 1030 } 1031 /* FALLTHROUGH */ |
1078 | 1032 |
1079 /*Add to flying list*/ 1080 pthread_mutex_lock(&ctx->flying_transfers_lock); 1081 if (TAILQ_EMPTY(&ctx->flying_transfers)) { 1082 TAILQ_INSERT_HEAD(&ctx->flying_transfers, usb_backend, list); 1083 goto out; | 1033 case LIBUSB20_TRANSFER_START: 1034 if (max_bulk > sxfer->rem_len) { 1035 max_bulk = sxfer->rem_len; 1036 } 1037 /* setup new CONTROL transaction */ 1038 if (status == LIBUSB20_TRANSFER_COMPLETED) { 1039 /* next fragment - don't send SETUP packet */ 1040 libusb20_tr_set_length(pxfer, 0, 0); 1041 } else { 1042 /* first fragment - send SETUP packet */ 1043 libusb20_tr_set_length(pxfer, 8, 0); 1044 libusb20_tr_set_buffer(pxfer, uxfer->buffer, 0); 1045 } 1046 1047 if (max_bulk != 0) { 1048 libusb20_tr_set_length(pxfer, max_bulk, 1); 1049 libusb20_tr_set_buffer(pxfer, sxfer->curr_data, 1); 1050 libusb20_tr_set_total_frames(pxfer, 2); 1051 } else { 1052 libusb20_tr_set_total_frames(pxfer, 1); 1053 } 1054 1055 /* update counters */ 1056 sxfer->last_len = max_bulk; 1057 sxfer->curr_data += max_bulk; 1058 sxfer->rem_len -= max_bulk; 1059 1060 libusb20_tr_submit(pxfer); 1061 1062 /* check if we can fork another USB transfer */ 1063 if (sxfer->rem_len == 0) 1064 libusb10_submit_transfer_sub(libusb20_tr_get_priv_sc0(pxfer), uxfer->endpoint); 1065 break; 1066 1067 default: 1068 libusb10_complete_transfer(pxfer, sxfer, libusb10_convert_error(status)); 1069 break; |
1084 } | 1070 } |
1085 if (timerisset(&usb_backend->timeout) == 0) { 1086 TAILQ_INSERT_HEAD(&ctx->flying_transfers, usb_backend, list); 1087 goto out; | 1071} 1072 1073/* The following function must be called locked */ 1074 1075static void 1076libusb10_submit_transfer_sub(struct libusb20_device *pdev, uint8_t endpoint) 1077{ 1078 struct libusb20_transfer *pxfer0; 1079 struct libusb20_transfer *pxfer1; 1080 struct libusb_super_transfer *sxfer; 1081 struct libusb_transfer *uxfer; 1082 struct libusb_device *dev; 1083 int err; 1084 int buffsize; 1085 int maxframe; 1086 int temp; 1087 uint8_t dummy; 1088 1089 dev = libusb_get_device(pdev); 1090 1091 pxfer0 = libusb10_get_transfer(pdev, endpoint, 0); 1092 pxfer1 = libusb10_get_transfer(pdev, endpoint, 1); 1093 1094 if (pxfer0 == NULL || pxfer1 == NULL) 1095 return; /* shouldn't happen */ 1096 1097 temp = 0; 1098 if (libusb20_tr_pending(pxfer0)) 1099 temp |= 1; 1100 if (libusb20_tr_pending(pxfer1)) 1101 temp |= 2; 1102 1103 switch (temp) { 1104 case 3: 1105 /* wait till one of the transfers complete */ 1106 return; 1107 case 2: 1108 sxfer = libusb20_tr_get_priv_sc1(pxfer1); 1109 if (sxfer->rem_len) 1110 return; /* cannot queue another one */ 1111 /* swap transfers */ 1112 pxfer1 = pxfer0; 1113 break; 1114 case 1: 1115 sxfer = libusb20_tr_get_priv_sc1(pxfer0); 1116 if (sxfer->rem_len) 1117 return; /* cannot queue another one */ 1118 /* swap transfers */ 1119 pxfer0 = pxfer1; 1120 break; 1121 default: 1122 break; |
1088 } | 1123 } |
1089 TAILQ_FOREACH(usb_node, &ctx->flying_transfers, list) { 1090 cur_tv = &usb_node->timeout; 1091 if (timerisset(cur_tv) == 0 || 1092 (cur_tv->tv_sec > usb_backend->timeout.tv_sec) || 1093 (cur_tv->tv_sec == usb_backend->timeout.tv_sec && 1094 cur_tv->tv_usec > usb_backend->timeout.tv_usec)) { 1095 TAILQ_INSERT_TAIL(&ctx->flying_transfers, usb_backend, list); 1096 goto out; | 1124 1125 /* find next transfer on same endpoint */ 1126 TAILQ_FOREACH(sxfer, &dev->tr_head, entry) { 1127 1128 uxfer = (struct libusb_transfer *)( 1129 ((uint8_t *)sxfer) + sizeof(*sxfer)); 1130 1131 if (uxfer->endpoint == endpoint) { 1132 TAILQ_REMOVE(&dev->tr_head, sxfer, entry); 1133 sxfer->entry.tqe_prev = NULL; 1134 goto found; |
1097 } | 1135 } |
1098 } 1099 TAILQ_INSERT_TAIL(&ctx->flying_transfers, usb_backend, list); | 1136 } 1137 return; /* success */ |
1100 | 1138 |
1101out: 1102 pthread_mutex_unlock(&ctx->flying_transfers_lock); | 1139found: |
1103 | 1140 |
1104 ep_idx = (xfer->endpoint / 0x40) | (xfer->endpoint * 4) % (16 * 4); 1105 usb20_xfer[0] = libusb20_tr_get_pointer(pdev, ep_idx); 1106 usb20_xfer[1] = libusb20_tr_get_pointer(pdev, ep_idx + 1); 1107 1108 if (usb20_xfer[0] == NULL) 1109 return (LIBUSB_ERROR_OTHER); | 1141 libusb20_tr_set_priv_sc0(pxfer0, pdev); 1142 libusb20_tr_set_priv_sc1(pxfer0, sxfer); |
1110 | 1143 |
1111 xfer->os_priv = usb20_xfer; | 1144 /* reset super transfer state */ 1145 sxfer->rem_len = uxfer->length; 1146 sxfer->curr_data = uxfer->buffer; 1147 uxfer->actual_length = 0; |
1112 | 1148 |
1113 pthread_mutex_lock(&libusb20_lock); | 1149 switch (uxfer->type) { 1150 case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS: 1151 libusb20_tr_set_callback(pxfer0, libusb10_isoc_proxy); 1152 break; 1153 case LIBUSB_TRANSFER_TYPE_BULK: 1154 case LIBUSB_TRANSFER_TYPE_INTERRUPT: 1155 libusb20_tr_set_callback(pxfer0, libusb10_bulk_intr_proxy); 1156 break; 1157 case LIBUSB_TRANSFER_TYPE_CONTROL: 1158 libusb20_tr_set_callback(pxfer0, libusb10_ctrl_proxy); 1159 if (sxfer->rem_len < 8) 1160 goto failure; |
1114 | 1161 |
1115 buffsize = libusb_get_buffsize(pdev, xfer); 1116 maxframe = libusb_get_maxframe(pdev, xfer); 1117 1118 ret = 0; 1119 TAILQ_FOREACH(eptr, &devh->ep_list, list) { 1120 if (xfer->endpoint == eptr->addr) 1121 ret++; | 1162 /* remove SETUP packet from data */ 1163 sxfer->rem_len -= 8; 1164 sxfer->curr_data += 8; 1165 break; 1166 default: 1167 goto failure; |
1122 } | 1168 } |
1123 if (ret == 0) { 1124 eptr = malloc(sizeof(struct usb_ep_tr)); 1125 eptr->addr = xfer->endpoint; 1126 eptr->idx = ep_idx; 1127 eptr->os_priv = usb20_xfer; 1128 eptr->flags = (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)?1:0; 1129 TAILQ_INSERT_HEAD(&devh->ep_list, eptr, list); 1130 ret = libusb20_tr_open(usb20_xfer[0], buffsize, 1131 maxframe, xfer->endpoint); 1132 if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) 1133 ret |= libusb20_tr_open(usb20_xfer[1], buffsize, 1134 maxframe, xfer->endpoint); 1135 1136 if (ret != 0) { 1137 pthread_mutex_unlock(&libusb20_lock); 1138 pthread_mutex_lock(&ctx->flying_transfers_lock); 1139 TAILQ_REMOVE(&ctx->flying_transfers, usb_backend, list); 1140 pthread_mutex_unlock(&ctx->flying_transfers_lock); 1141 return (LIBUSB_ERROR_OTHER); 1142 } | 1169 1170 buffsize = libusb10_get_buffsize(pdev, uxfer); 1171 maxframe = libusb10_get_maxframe(pdev, uxfer); 1172 1173 /* make sure the transfer is opened */ 1174 err = libusb20_tr_open(pxfer0, buffsize, maxframe, endpoint); 1175 if (err && (err != LIBUSB20_ERROR_BUSY)) { 1176 goto failure; |
1143 } | 1177 } |
1178 libusb20_tr_start(pxfer0); 1179 return; |
|
1144 | 1180 |
1145 libusb20_tr_set_priv_sc0(usb20_xfer[0], xfer); 1146 libusb20_tr_set_callback(usb20_xfer[0], libusb10_proxy); 1147 if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) { 1148 libusb20_tr_set_priv_sc0(usb20_xfer[1], xfer); 1149 libusb20_tr_set_callback(usb20_xfer[1], libusb10_proxy); 1150 } | 1181failure: 1182 libusb10_complete_transfer(pxfer0, sxfer, LIBUSB_TRANSFER_ERROR); |
1151 | 1183 |
1152 DPRINTF(ctx, LIBUSB_DEBUG_TRANSFER, "LIBUSB20_TR_START"); 1153 libusb20_tr_start(usb20_xfer[0]); 1154 if (xfer->type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS) 1155 libusb20_tr_start(usb20_xfer[1]); | 1184 /* make sure our event loop spins the done handler */ 1185 dummy = 0; 1186 write(dev->ctx->ctrl_pipe[1], &dummy, sizeof(dummy)); 1187} |
1156 | 1188 |
1157 pthread_mutex_unlock(&libusb20_lock); | 1189/* The following function must be called unlocked */ |
1158 | 1190 |
1159 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave"); 1160 return (0); | 1191int 1192libusb_submit_transfer(struct libusb_transfer *uxfer) 1193{ 1194 struct libusb20_transfer *pxfer0; 1195 struct libusb20_transfer *pxfer1; 1196 struct libusb_super_transfer *sxfer; 1197 struct libusb_device *dev; 1198 unsigned int endpoint; 1199 int err; 1200 1201 if (uxfer == NULL) 1202 return (LIBUSB_ERROR_INVALID_PARAM); 1203 1204 if (uxfer->dev_handle == NULL) 1205 return (LIBUSB_ERROR_INVALID_PARAM); 1206 1207 endpoint = uxfer->endpoint; 1208 1209 if (endpoint > 255) 1210 return (LIBUSB_ERROR_INVALID_PARAM); 1211 1212 dev = libusb_get_device(uxfer->dev_handle); 1213 1214 DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer enter"); 1215 1216 sxfer = (struct libusb_super_transfer *)( 1217 (uint8_t *)uxfer - sizeof(*sxfer)); 1218 1219 CTX_LOCK(dev->ctx); 1220 1221 pxfer0 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 0); 1222 pxfer1 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 1); 1223 1224 if (pxfer0 == NULL || pxfer1 == NULL) { 1225 err = LIBUSB_ERROR_OTHER; 1226 } else if ((sxfer->entry.tqe_prev != NULL) || 1227 (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) || 1228 (libusb20_tr_get_priv_sc1(pxfer1) == sxfer)) { 1229 err = LIBUSB_ERROR_BUSY; 1230 } else { 1231 TAILQ_INSERT_TAIL(&dev->tr_head, sxfer, entry); 1232 1233 libusb10_submit_transfer_sub( 1234 uxfer->dev_handle, endpoint); 1235 1236 err = 0; /* success */ 1237 } 1238 1239 CTX_UNLOCK(dev->ctx); 1240 1241 DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_submit_transfer leave %d", err); 1242 1243 return (err); |
1161} 1162 | 1244} 1245 |
1246/* Asynchronous transfer cancel */ 1247 |
|
1163int | 1248int |
1164libusb_cancel_transfer(struct libusb_transfer *xfer) | 1249libusb_cancel_transfer(struct libusb_transfer *uxfer) |
1165{ | 1250{ |
1166 libusb_context *ctx; | 1251 struct libusb20_transfer *pxfer0; 1252 struct libusb20_transfer *pxfer1; 1253 struct libusb_super_transfer *sxfer; 1254 struct libusb_device *dev; 1255 unsigned int endpoint; |
1167 | 1256 |
1168 ctx = NULL; 1169 GET_CONTEXT(ctx); 1170 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter"); | 1257 if (uxfer == NULL) 1258 return (LIBUSB_ERROR_INVALID_PARAM); |
1171 | 1259 |
1172 if (xfer == NULL) 1173 return (LIBUSB_ERROR_NO_MEM); | 1260 if (uxfer->dev_handle == NULL) 1261 return (LIBUSB_ERROR_INVALID_PARAM); |
1174 | 1262 |
1175 pthread_mutex_lock(&libusb20_lock); 1176 libusb20_tr_stop(xfer->os_priv); 1177 pthread_mutex_unlock(&libusb20_lock); | 1263 endpoint = uxfer->endpoint; |
1178 | 1264 |
1179 DPRINTF(ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave"); | 1265 if (endpoint > 255) 1266 return (LIBUSB_ERROR_INVALID_PARAM); 1267 1268 dev = libusb_get_device(uxfer->dev_handle); 1269 1270 DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer enter"); 1271 1272 sxfer = (struct libusb_super_transfer *)( 1273 (uint8_t *)uxfer - sizeof(*sxfer)); 1274 1275 CTX_LOCK(dev->ctx); 1276 1277 pxfer0 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 0); 1278 pxfer1 = libusb10_get_transfer(uxfer->dev_handle, endpoint, 1); 1279 1280 if (sxfer->entry.tqe_prev != NULL) { 1281 /* we are lucky - transfer is on a queue */ 1282 TAILQ_REMOVE(&dev->tr_head, sxfer, entry); 1283 sxfer->entry.tqe_prev = NULL; 1284 libusb10_complete_transfer(NULL, sxfer, LIBUSB_TRANSFER_CANCELLED); 1285 } else if (pxfer0 == NULL || pxfer1 == NULL) { 1286 /* not started */ 1287 } else if (libusb20_tr_get_priv_sc1(pxfer0) == sxfer) { 1288 libusb10_complete_transfer(pxfer0, sxfer, LIBUSB_TRANSFER_CANCELLED); 1289 libusb20_tr_stop(pxfer0); 1290 /* make sure the queue doesn't stall */ 1291 libusb10_submit_transfer_sub( 1292 uxfer->dev_handle, endpoint); 1293 } else if (libusb20_tr_get_priv_sc1(pxfer1) == sxfer) { 1294 libusb10_complete_transfer(pxfer1, sxfer, LIBUSB_TRANSFER_CANCELLED); 1295 libusb20_tr_stop(pxfer1); 1296 /* make sure the queue doesn't stall */ 1297 libusb10_submit_transfer_sub( 1298 uxfer->dev_handle, endpoint); 1299 } else { 1300 /* not started */ 1301 } 1302 1303 CTX_UNLOCK(dev->ctx); 1304 1305 DPRINTF(dev->ctx, LIBUSB_DEBUG_FUNCTION, "libusb_cancel_transfer leave"); 1306 |
1180 return (0); 1181} 1182 | 1307 return (0); 1308} 1309 |
1310UNEXPORTED void 1311libusb10_cancel_all_transfer(libusb_device *dev) 1312{ 1313 /* TODO */ 1314} |
|