usbdi.c revision 1.119.12.6 1 /* $NetBSD: usbdi.c,v 1.119.12.6 2008/05/21 05:04:03 itohy Exp $ */
2 /* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.99 2006/11/27 18:39:02 marius Exp $ */
3
4 /*-
5 * Copyright (c) 1998 The NetBSD Foundation, Inc.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Lennart Augustsson (lennart (at) augustsson.net) at
10 * Carlstedt Research & Technology.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the NetBSD
23 * Foundation, Inc. and its contributors.
24 * 4. Neither the name of The NetBSD Foundation nor the names of its
25 * contributors may be used to endorse or promote products derived
26 * from this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
29 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
31 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
32 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.119.12.6 2008/05/21 05:04:03 itohy Exp $");
43 /* __FBSDID("$FreeBSD: src/sys/dev/usb/usbdi.c,v 1.99 2006/11/27 18:39:02 marius Exp $"); */
44
45 #ifdef __NetBSD__
46 #include "opt_compat_netbsd.h"
47 #endif
48
49 #include <sys/param.h>
50 #include <sys/systm.h>
51 #if defined(__NetBSD__) || defined(__OpenBSD__)
52 #include <sys/kernel.h>
53 #include <sys/device.h>
54 #elif defined(__FreeBSD__)
55 #include <sys/module.h>
56 #include <sys/bus.h>
57 #include "usb_if.h"
58 #if defined(DIAGNOSTIC) && defined(__i386__)
59 #include <machine/cpu.h>
60 #endif
61 #endif
62 #include <sys/malloc.h>
63 #include <sys/mbuf.h>
64 #include <sys/proc.h>
65
66 #include <machine/bus.h>
67
68 #include <dev/usb/usb.h>
69 #include <dev/usb/usbdi.h>
70 #include <dev/usb/usbdi_util.h>
71 #include <dev/usb/usbdivar.h>
72 /* #include <dev/usb/usb_mem.h> */
73 #include <dev/usb/usb_quirks.h>
74
75 #if defined(__FreeBSD__)
76 #include "usb_if.h"
77 #define delay(d) DELAY(d)
78 #endif
79
80 /* UTF-8 encoding stuff */
81 #include <fs/unicode.h>
82
83 #ifdef USB_DEBUG
84 #define DPRINTF(x) if (usbdebug) logprintf x
85 #define DPRINTFN(n,x) if (usbdebug>(n)) logprintf x
86 extern int usbdebug;
87 #else
88 #define DPRINTF(x)
89 #define DPRINTFN(n,x)
90 #endif
91
92 Static usbd_xfer_handle usbd_alloc_xfer_flag(usbd_device_handle,
93 usbd_pipe_handle pipe, enum usbd_waitflg);
94 Static void usbd_free_buffer_flag(usbd_xfer_handle, enum usbd_waitflg);
95 Static usbd_status usbd_free_xfer_flag(usbd_xfer_handle, enum usbd_waitflg);
96 Static usbd_status usbd_ar_pipe(usbd_pipe_handle pipe);
97 Static void usbd_callback_task(void *);
98 Static void usbd_do_request_async_cb
99 (usbd_xfer_handle, usbd_private_handle, usbd_status);
100 Static void usbd_do_request_async_task(void *);
101 Static void usbd_start_next(usbd_pipe_handle pipe);
102 Static usbd_status usbd_open_pipe_ival
103 (usbd_interface_handle, u_int8_t, u_int8_t, usbd_pipe_handle *, int);
104
105 int
106 usbd_xfer_isread(usbd_xfer_handle xfer)
107 {
108 if (xfer->rqflags & URQ_REQUEST)
109 return (xfer->request.bmRequestType & UT_READ);
110 else
111 return (xfer->pipe->endpoint->edesc->bEndpointAddress &
112 UE_DIR_IN);
113 }
114
115 #ifdef USB_DEBUG
116 void
117 usbd_dump_iface(struct usbd_interface *iface)
118 {
119 printf("usbd_dump_iface: iface=%p\n", iface);
120 if (iface == NULL)
121 return;
122 printf(" device=%p idesc=%p index=%d altindex=%d priv=%p\n",
123 iface->device, iface->idesc, iface->index, iface->altindex,
124 iface->priv);
125 }
126
127 void
128 usbd_dump_device(struct usbd_device *dev)
129 {
130 printf("usbd_dump_device: dev=%p\n", dev);
131 if (dev == NULL)
132 return;
133 printf(" bus=%p default_pipe=%p\n", dev->bus, dev->default_pipe);
134 printf(" address=%d config=%d depth=%d speed=%d self_powered=%d "
135 "power=%d langid=%d\n",
136 dev->address, dev->config, dev->depth, dev->speed,
137 dev->self_powered, dev->power, dev->langid);
138 }
139
140 void
141 usbd_dump_endpoint(struct usbd_endpoint *endp)
142 {
143 printf("usbd_dump_endpoint: endp=%p\n", endp);
144 if (endp == NULL)
145 return;
146 printf(" edesc=%p refcnt=%d\n", endp->edesc, endp->refcnt);
147 if (endp->edesc)
148 printf(" bEndpointAddress=0x%02x\n",
149 endp->edesc->bEndpointAddress);
150 }
151
152 void
153 usbd_dump_queue(usbd_pipe_handle pipe)
154 {
155 usbd_xfer_handle xfer;
156
157 printf("usbd_dump_queue: pipe=%p\n", pipe);
158 SIMPLEQ_FOREACH(xfer, &pipe->queue, next) {
159 printf(" xfer=%p\n", xfer);
160 }
161 }
162
163 void
164 usbd_dump_pipe(usbd_pipe_handle pipe)
165 {
166 printf("usbd_dump_pipe: pipe=%p\n", pipe);
167 if (pipe == NULL)
168 return;
169 usbd_dump_iface(pipe->iface);
170 usbd_dump_device(pipe->device);
171 usbd_dump_endpoint(pipe->endpoint);
172 printf(" (usbd_dump_pipe:)\n refcnt=%d running=%d aborting=%d\n",
173 pipe->refcnt, pipe->running, pipe->aborting);
174 printf(" intrxfer=%p, repeat=%d, interval=%d\n",
175 pipe->intrxfer, pipe->repeat, pipe->interval);
176 }
177 #endif
178
179 usbd_status
180 usbd_open_pipe(usbd_interface_handle iface, u_int8_t address,
181 u_int8_t flags, usbd_pipe_handle *pipe)
182 {
183 return (usbd_open_pipe_ival(iface, address, flags, pipe,
184 USBD_DEFAULT_INTERVAL));
185 }
186
187 usbd_status
188 usbd_open_pipe_ival(usbd_interface_handle iface, u_int8_t address,
189 u_int8_t flags, usbd_pipe_handle *pipe, int ival)
190 {
191 usbd_pipe_handle p;
192 struct usbd_endpoint *ep;
193 usbd_status err;
194 int i;
195
196 DPRINTFN(3,("usbd_open_pipe: iface=%p address=0x%x flags=0x%x\n",
197 iface, address, flags));
198
199 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
200 ep = &iface->endpoints[i];
201 if (ep->edesc == NULL)
202 return (USBD_IOERROR);
203 if (ep->edesc->bEndpointAddress == address)
204 goto found;
205 }
206 return (USBD_BAD_ADDRESS);
207 found:
208 if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0)
209 return (USBD_IN_USE);
210 err = usbd_setup_pipe(iface->device, iface, ep, ival, &p);
211 if (err)
212 return (err);
213 LIST_INSERT_HEAD(&iface->pipes, p, next);
214 *pipe = p;
215 return (USBD_NORMAL_COMPLETION);
216 }
217
218 usbd_status
219 usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address,
220 u_int8_t flags, usbd_pipe_handle *pipe,
221 usbd_private_handle priv, void *buffer, u_int32_t len,
222 usbd_callback cb, int ival)
223 {
224 usbd_status err;
225 usbd_xfer_handle xfer;
226 usbd_pipe_handle ipipe;
227
228 DPRINTFN(3,("usbd_open_pipe_intr: address=0x%x flags=0x%x len=%d\n",
229 address, flags, len));
230
231 err = usbd_open_pipe_ival(iface, address, USBD_EXCLUSIVE_USE,
232 &ipipe, ival);
233 if (err)
234 return (err);
235 xfer = usbd_alloc_xfer(iface->device, ipipe);
236 if (xfer == NULL) {
237 err = USBD_NOMEM;
238 goto bad1;
239 }
240 usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags,
241 USBD_NO_TIMEOUT, cb);
242 ipipe->intrxfer = xfer;
243 ipipe->repeat = 1;
244 err = usbd_transfer(xfer);
245 *pipe = ipipe;
246 if (err != USBD_IN_PROGRESS && err)
247 goto bad2;
248 return (USBD_NORMAL_COMPLETION);
249
250 bad2:
251 ipipe->intrxfer = NULL;
252 ipipe->repeat = 0;
253 usbd_free_xfer(xfer);
254 bad1:
255 usbd_close_pipe(ipipe);
256 return (err);
257 }
258
259 usbd_status
260 usbd_close_pipe(usbd_pipe_handle pipe)
261 {
262 #ifdef DIAGNOSTIC
263 if (pipe == NULL) {
264 printf("usbd_close_pipe: pipe==NULL\n");
265 return (USBD_NORMAL_COMPLETION);
266 }
267 #endif
268
269 if (--pipe->refcnt != 0)
270 return (USBD_NORMAL_COMPLETION);
271 if (! SIMPLEQ_EMPTY(&pipe->queue))
272 return (USBD_PENDING_REQUESTS);
273 LIST_REMOVE(pipe, next);
274 pipe->endpoint->refcnt--;
275 pipe->methods->close(pipe);
276 if (pipe->intrxfer != NULL)
277 usbd_free_xfer(pipe->intrxfer);
278 free(pipe, M_USB);
279 return (USBD_NORMAL_COMPLETION);
280 }
281
282 usbd_status
283 usbd_transfer(usbd_xfer_handle xfer)
284 {
285 usbd_pipe_handle pipe = xfer->pipe;
286 usbd_status err;
287 u_int size, flags;
288 int s;
289
290 DPRINTFN(5,("usbd_transfer: xfer=%p, flags=%x, pipe=%p, running=%d\n",
291 xfer, xfer->flags, pipe, pipe->running));
292 #ifdef USB_DEBUG
293 if (usbdebug > 5)
294 usbd_dump_queue(pipe);
295 #endif
296 xfer->done = 0;
297
298 if (pipe->aborting)
299 return (USBD_CANCELLED);
300
301 size = xfer->length;
302 flags = xfer->flags;
303 /* If there is no buffer, allocate one. */
304 if (!(xfer->rqflags & URQ_MASK_DRV_REQUESTED_BUF) && size != 0) {
305 struct usbd_bus *bus = pipe->device->bus;
306
307 #ifdef DIAGNOSTIC
308 if (xfer->rqflags & URQ_AUTO_BUF)
309 printf("usbd_transfer: has old buffer!\n");
310 if (xfer->device->bus->intr_context)
311 panic("usbd_transfer: allocm not in process context");
312 #endif
313 err = bus->methods->allocm(bus, xfer,
314 (flags & USBD_NO_COPY) ? xfer->buffer : NULL,
315 size);
316 if (err)
317 return (err);
318 xfer->rqflags |= URQ_AUTO_BUF;
319 }
320 #ifdef DIAGNOSTIC
321 if ((xfer->rqflags & URQ_MASK_DRV_REQUESTED_BUF) != 0 &&
322 size > xfer->bufsize) {
323 panic("usbd_transfer: buffer size overrun size=%u bufsize=%lu rqflags=%x",
324 size, (unsigned long)xfer->bufsize, xfer->rqflags);
325 }
326 #endif
327
328 #ifdef DIAGNOSTIC
329 if ((flags & USBD_NO_COPY) == 0 && size != 0) {
330 if (xfer->rqflags & URQ_DEV_MAP_BUFFER)
331 printf("usbd_transfer: USBD_NO_COPY recommended with mapped buffer");
332 if (xfer->rqflags & URQ_DEV_MAP_MBUF)
333 panic("usbd_transfer: USBD_NO_COPY required with mapped mbuf");
334 }
335 #endif
336 /* Copy data if going out. */
337 if (!(flags & USBD_NO_COPY) && size != 0 &&
338 !usbd_xfer_isread(xfer) && xfer->buffer != xfer->hcbuffer) {
339 DPRINTFN(5, ("usbd_transfer: copy %p (alloc) <- %p (buffer), %u bytes\n",
340 xfer->hcbuffer, xfer->buffer, (unsigned)size));
341 memcpy(xfer->hcbuffer, xfer->buffer, size);
342 }
343
344 err = pipe->methods->transfer(xfer);
345 /*
346 * Note xfer may not be valid after non-error completion
347 * of the transfer method unless synchronous.
348 */
349
350 if (err != USBD_IN_PROGRESS && err) {
351 /* The transfer has not been queued, so free buffer. */
352 if (xfer->rqflags & URQ_AUTO_BUF) {
353 struct usbd_bus *bus = pipe->device->bus;
354
355 #ifdef DIAGNOSTIC
356 if (bus->intr_context)
357 panic("usbd_transfer: freem not in process context");
358 #endif
359 bus->methods->freem(bus, xfer, U_WAITOK);
360 xfer->rqflags &= ~URQ_AUTO_BUF;
361 }
362 }
363
364 if (!(flags & USBD_SYNCHRONOUS))
365 return (xfer->done ? 0 : USBD_IN_PROGRESS);
366
367 /* Sync transfer, wait for completion. */
368 s = splusb();
369 while (!xfer->done) {
370 if (pipe->device->bus->use_polling)
371 panic("usbd_transfer: not done");
372 tsleep(xfer, PRIBIO, "usbsyn", 0);
373 }
374 splx(s);
375 return (xfer->status);
376 }
377
378 /* Like usbd_transfer(), but waits for completion. */
379 usbd_status
380 usbd_sync_transfer(usbd_xfer_handle xfer)
381 {
382 xfer->flags |= USBD_SYNCHRONOUS;
383 return (usbd_transfer(xfer));
384 }
385
386 void *
387 usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size)
388 {
389 struct usbd_bus *bus = xfer->device->bus;
390 usbd_status err;
391
392 USB_KASSERT2((xfer->rqflags & URQ_MASK_BUF) == 0,
393 ("usbd_alloc_buffer: xfer already has a buffer"));
394
395 #ifdef DIAGNOSTIC
396 if (xfer->device->bus->intr_context)
397 panic("usbd_alloc_buffer: allocm not in process context");
398 #endif
399 err = bus->methods->allocm(bus, xfer, NULL, size);
400 if (err)
401 return (NULL);
402 xfer->bufsize = size;
403 xfer->rqflags |= URQ_DEV_BUF;
404 return xfer->hcbuffer;
405 }
406
407 Static void
408 usbd_free_buffer_flag(usbd_xfer_handle xfer, enum usbd_waitflg waitflg)
409 {
410 struct usbd_bus *bus;
411
412 USB_KASSERT2((xfer->rqflags & URQ_MASK_BUF) == URQ_DEV_BUF,
413 ("usbd_free_buffer_flag: no/auto buffer"));
414
415 xfer->rqflags &= ~(URQ_DEV_BUF | URQ_AUTO_BUF);
416 xfer->bufsize = 0;
417 bus = xfer->device->bus;
418 #ifdef DIAGNOSTIC
419 if (waitflg == U_WAITOK && bus->intr_context)
420 panic("usbd_free_buffer: freem not in process context");
421 #endif
422 bus->methods->freem(bus, xfer, waitflg);
423
424 xfer->hcbuffer = NULL;
425 }
426
427 void
428 usbd_free_buffer(usbd_xfer_handle xfer)
429 {
430 usbd_free_buffer_flag(xfer, U_WAITOK);
431 }
432
433 void *
434 usbd_get_buffer(usbd_xfer_handle xfer)
435 {
436 if (!(xfer->rqflags & URQ_DEV_BUF))
437 return (NULL);
438 return (xfer->hcbuffer);
439 }
440
441 /*
442 * map buffer handlings
443 */
444
445 /* Allocate mapping resources to prepare buffer mapping. */
446 usbd_status
447 usbd_map_alloc(usbd_xfer_handle xfer)
448 {
449 struct usbd_bus *bus = xfer->device->bus;
450 usbd_status err;
451
452 #ifdef DIAGNOSTIC
453 if (bus->intr_context)
454 panic("usbd_map_alloc: map_alloc not in process context");
455 #endif
456 USB_KASSERT2((xfer->rqflags & URQ_DEV_MAP_PREPARED) == 0,
457 ("usbd_map_alloc: map already allocated"));
458
459 err = bus->methods->map_alloc(xfer);
460 if (err != USBD_NORMAL_COMPLETION)
461 return (err);
462
463 xfer->rqflags |= URQ_DEV_MAP_PREPARED;
464
465 return (USBD_NORMAL_COMPLETION);
466 }
467
468 /* Free mapping resources. */
469 void
470 usbd_map_free(usbd_xfer_handle xfer)
471 {
472 struct usbd_bus *bus = xfer->device->bus;
473
474 #ifdef DIAGNOSTIC
475 if (bus->intr_context)
476 panic("usbd_map_free: map_free not in process context");
477 #endif
478 USB_KASSERT2((xfer->rqflags & URQ_DEV_MAP_PREPARED),
479 ("usbd_map_free: map not allocated"));
480
481 bus->methods->map_free(xfer);
482
483 xfer->rqflags &= ~URQ_DEV_MAP_PREPARED;
484 }
485
486 /* Map plain buffer. */
487 void
488 usbd_map_buffer(usbd_xfer_handle xfer, void *buf, u_int32_t size)
489 {
490 struct usbd_bus *bus = xfer->device->bus;
491
492 #ifdef DIAGNOSTIC
493 if ((xfer->rqflags & URQ_MASK_BUF))
494 panic("usbd_map_buffer: already has buffer (rqflags=%x)",
495 xfer->rqflags);
496 if ((xfer->rqflags & URQ_DEV_MAP_PREPARED) == 0 && bus->intr_context)
497 panic("usbd_map_buffer: mapm (without map_alloc) not in process context");
498 #endif
499
500 bus->methods->mapm(xfer, buf, size);
501
502 xfer->bufsize = size;
503 xfer->rqflags |= URQ_DEV_MAP_BUFFER;
504 }
505
506 /* Map mbuf(9) chain. */
507 usbd_status
508 usbd_map_buffer_mbuf(usbd_xfer_handle xfer, struct mbuf *chain)
509 {
510 struct usbd_bus *bus = xfer->device->bus;
511 usbd_status err;
512
513 #ifdef DIAGNOSTIC
514 if ((xfer->rqflags & URQ_MASK_BUF))
515 panic("usbd_map_buffer_mbuf: already has buffer (rqflags=%x)",
516 xfer->rqflags);
517 if ((xfer->rqflags & URQ_DEV_MAP_PREPARED) == 0 && bus->intr_context)
518 panic("usbd_map_buffer_mbuf: mapm_mbuf (without map_alloc) not in process context");
519 #endif
520
521 err = bus->methods->mapm_mbuf(xfer, chain);
522 if (err != USBD_NORMAL_COMPLETION)
523 return (err);
524
525 xfer->bufsize = chain->m_pkthdr.len;
526 xfer->mbuf_chain = chain;
527 xfer->rqflags |= URQ_DEV_MAP_MBUF;
528
529 return (err);
530 }
531
532 /* Unmap plain buffer or mbuf(9) chain. */
533 void
534 usbd_unmap_buffer(usbd_xfer_handle xfer)
535 {
536 struct usbd_bus *bus = xfer->device->bus;
537
538 USB_KASSERT2((xfer->rqflags & (URQ_DEV_MAP_BUFFER | URQ_DEV_MAP_MBUF)),
539 ("usbd_unmap_buffer: no map"));
540 #ifdef DIAGNOSTIC
541 if ((xfer->rqflags & URQ_DEV_MAP_PREPARED) == 0 && bus->intr_context)
542 panic("usbd_unmap_buffer: unmapm (without map_alloc) not in process context");
543 #endif
544
545 bus->methods->unmapm(xfer);
546
547 xfer->rqflags &= ~(URQ_DEV_MAP_BUFFER | URQ_DEV_MAP_MBUF);
548 xfer->bufsize = 0;
549 xfer->mbuf_chain = NULL;
550 }
551
552 Static usbd_xfer_handle
553 usbd_alloc_xfer_flag(usbd_device_handle dev, usbd_pipe_handle pipe,
554 enum usbd_waitflg waitflg)
555 {
556 usbd_xfer_handle xfer;
557
558 #ifdef DIAGNOSTIC
559 if (waitflg == U_WAITOK && dev->bus->intr_context)
560 panic("usbd_alloc_xfer: allocx not in process context");
561 if (pipe == NULL)
562 panic("usbd_alloc_xfer: pipe == NULL");
563 #endif
564 xfer = dev->bus->methods->allocx(dev->bus, pipe, waitflg);
565 if (xfer == NULL)
566 return (NULL);
567 xfer->pipe = pipe;
568 xfer->device = dev;
569 usb_callout_init(xfer->timeout_handle);
570 DPRINTFN(5,("usbd_alloc_xfer_flag() = %p\n", xfer));
571 return (xfer);
572 }
573
574 usbd_xfer_handle
575 usbd_alloc_xfer(usbd_device_handle dev, usbd_pipe_handle pipe)
576 {
577 return (usbd_alloc_xfer_flag(dev, pipe, U_WAITOK));
578 }
579
580 usbd_xfer_handle
581 usbd_alloc_default_xfer(usbd_device_handle dev)
582 {
583 return (usbd_alloc_xfer_flag(dev, dev->default_pipe, U_WAITOK));
584 }
585
586 Static usbd_status
587 usbd_free_xfer_flag(usbd_xfer_handle xfer, enum usbd_waitflg waitflg)
588 {
589 DPRINTFN(5,("usbd_free_xfer_flag: %p %d\n", xfer, waitflg));
590 usb_rem_task(xfer->device, &xfer->task);
591 if (xfer->rqflags & (URQ_DEV_BUF | URQ_AUTO_BUF))
592 usbd_free_buffer_flag(xfer, waitflg);
593 if (xfer->rqflags & (URQ_DEV_MAP_BUFFER | URQ_DEV_MAP_MBUF))
594 usbd_unmap_buffer(xfer);
595 if (waitflg == U_WAITOK && (xfer->rqflags & URQ_DEV_MAP_PREPARED))
596 usbd_map_free(xfer);
597 #if defined(__NetBSD__) && defined(DIAGNOSTIC)
598 if (callout_pending(&xfer->timeout_handle)) {
599 callout_stop(&xfer->timeout_handle);
600 printf("usbd_free_xfer_flag: timout_handle pending");
601 }
602 #endif
603 xfer->device->bus->methods->freex(xfer->device->bus, xfer);
604 return (USBD_NORMAL_COMPLETION);
605 }
606
607 usbd_status
608 usbd_free_xfer(usbd_xfer_handle xfer)
609 {
610
611 return (usbd_free_xfer_flag(xfer, U_WAITOK));
612 }
613
614 void
615 usbd_setup_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
616 usbd_private_handle priv, void *buffer, u_int32_t length,
617 u_int16_t flags, u_int32_t timeout,
618 usbd_callback callback)
619 {
620 USB_KASSERT(xfer->pipe == pipe); /* XXX pipe arg should go */
621 xfer->priv = priv;
622 xfer->buffer = buffer;
623 xfer->length = length;
624 xfer->actlen = 0;
625 xfer->flags = flags;
626 xfer->timeout = timeout;
627 xfer->status = USBD_NOT_STARTED;
628 xfer->callback = callback;
629 xfer->rqflags &= ~URQ_REQUEST;
630 xfer->nframes = 0;
631 }
632
633 void
634 usbd_setup_default_xfer(usbd_xfer_handle xfer, usbd_device_handle dev,
635 usbd_private_handle priv, u_int32_t timeout,
636 usb_device_request_t *req, void *buffer,
637 u_int32_t length, u_int16_t flags,
638 usbd_callback callback)
639 {
640 USB_KASSERT(xfer->pipe == dev->default_pipe); /* XXX */
641 xfer->priv = priv;
642 xfer->buffer = buffer;
643 xfer->length = length;
644 xfer->actlen = 0;
645 xfer->flags = flags;
646 xfer->timeout = timeout;
647 xfer->status = USBD_NOT_STARTED;
648 xfer->callback = callback;
649 xfer->request = *req;
650 xfer->rqflags |= URQ_REQUEST;
651 xfer->nframes = 0;
652 }
653
654 void
655 usbd_setup_isoc_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
656 usbd_private_handle priv, u_int16_t *frlengths,
657 u_int32_t nframes, u_int16_t flags, usbd_callback callback)
658 {
659 int i;
660
661 USB_KASSERT(xfer->pipe == pipe); /* XXX pipe arg should go */
662 xfer->priv = priv;
663 xfer->buffer = 0;
664 xfer->length = 0;
665 for (i = 0; i < nframes; i++)
666 xfer->length += frlengths[i];
667 xfer->actlen = 0;
668 xfer->flags = flags;
669 xfer->timeout = USBD_NO_TIMEOUT;
670 xfer->status = USBD_NOT_STARTED;
671 xfer->callback = callback;
672 xfer->rqflags &= ~URQ_REQUEST;
673 xfer->frlengths = frlengths;
674 xfer->nframes = nframes;
675 }
676
677 void
678 usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv,
679 void **buffer, u_int32_t *count, usbd_status *status)
680 {
681 if (priv != NULL)
682 *priv = xfer->priv;
683 if (buffer != NULL)
684 *buffer = xfer->buffer;
685 if (count != NULL)
686 *count = xfer->actlen;
687 if (status != NULL)
688 *status = xfer->status;
689 }
690
691 usb_config_descriptor_t *
692 usbd_get_config_descriptor(usbd_device_handle dev)
693 {
694 #ifdef DIAGNOSTIC
695 if (dev == NULL) {
696 printf("usbd_get_config_descriptor: dev == NULL\n");
697 return (NULL);
698 }
699 #endif
700 return (dev->cdesc);
701 }
702
703 int
704 usbd_get_speed(usbd_device_handle dev)
705 {
706 return (dev->speed);
707 }
708
709 usb_interface_descriptor_t *
710 usbd_get_interface_descriptor(usbd_interface_handle iface)
711 {
712 #ifdef DIAGNOSTIC
713 if (iface == NULL) {
714 printf("usbd_get_interface_descriptor: dev == NULL\n");
715 return (NULL);
716 }
717 #endif
718 return (iface->idesc);
719 }
720
721 usb_device_descriptor_t *
722 usbd_get_device_descriptor(usbd_device_handle dev)
723 {
724 return (&dev->ddesc);
725 }
726
727 usb_endpoint_descriptor_t *
728 usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index)
729 {
730 if (index >= iface->idesc->bNumEndpoints)
731 return (0);
732 return (iface->endpoints[index].edesc);
733 }
734
735 usbd_status
736 usbd_abort_pipe(usbd_pipe_handle pipe)
737 {
738 usbd_status err;
739 int s;
740
741 #ifdef DIAGNOSTIC
742 if (pipe == NULL) {
743 printf("usbd_abort_pipe: pipe==NULL\n");
744 return (USBD_NORMAL_COMPLETION);
745 }
746 #endif
747 s = splusb();
748 err = usbd_ar_pipe(pipe);
749 splx(s);
750 return (err);
751 }
752
753 usbd_status
754 usbd_abort_default_pipe(usbd_device_handle dev)
755 {
756 return (usbd_abort_pipe(dev->default_pipe));
757 }
758
759 usbd_status
760 usbd_clear_endpoint_stall(usbd_pipe_handle pipe)
761 {
762 usbd_device_handle dev = pipe->device;
763 usb_device_request_t req;
764 usbd_status err;
765
766 DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
767
768 /*
769 * Clearing en endpoint stall resets the endpoint toggle, so
770 * do the same to the HC toggle.
771 */
772 pipe->methods->cleartoggle(pipe);
773
774 req.bmRequestType = UT_WRITE_ENDPOINT;
775 req.bRequest = UR_CLEAR_FEATURE;
776 USETW(req.wValue, UF_ENDPOINT_HALT);
777 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
778 USETW(req.wLength, 0);
779 err = usbd_do_request(dev, &req, 0);
780 #if 0
781 XXX should we do this?
782 if (!err) {
783 pipe->state = USBD_PIPE_ACTIVE;
784 /* XXX activate pipe */
785 }
786 #endif
787 return (err);
788 }
789
790 usbd_status
791 usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe)
792 {
793 usbd_device_handle dev = pipe->device;
794 usb_device_request_t req;
795 usbd_status err;
796
797 pipe->methods->cleartoggle(pipe);
798
799 req.bmRequestType = UT_WRITE_ENDPOINT;
800 req.bRequest = UR_CLEAR_FEATURE;
801 USETW(req.wValue, UF_ENDPOINT_HALT);
802 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
803 USETW(req.wLength, 0);
804 err = usbd_do_request_async(dev, &req, 0);
805 return (err);
806 }
807
808 void
809 usbd_clear_endpoint_toggle(usbd_pipe_handle pipe)
810 {
811 pipe->methods->cleartoggle(pipe);
812 }
813
814 usbd_status
815 usbd_endpoint_count(usbd_interface_handle iface, u_int8_t *count)
816 {
817 #ifdef DIAGNOSTIC
818 if (iface == NULL || iface->idesc == NULL) {
819 printf("usbd_endpoint_count: NULL pointer\n");
820 return (USBD_INVAL);
821 }
822 #endif
823 *count = iface->idesc->bNumEndpoints;
824 return (USBD_NORMAL_COMPLETION);
825 }
826
827 usbd_status
828 usbd_interface_count(usbd_device_handle dev, u_int8_t *count)
829 {
830 if (dev->cdesc == NULL)
831 return (USBD_NOT_CONFIGURED);
832 *count = dev->cdesc->bNumInterface;
833 return (USBD_NORMAL_COMPLETION);
834 }
835
836 void
837 usbd_interface2device_handle(usbd_interface_handle iface,
838 usbd_device_handle *dev)
839 {
840 *dev = iface->device;
841 }
842
843 usbd_status
844 usbd_device2interface_handle(usbd_device_handle dev,
845 u_int8_t ifaceno, usbd_interface_handle *iface)
846 {
847 if (dev->cdesc == NULL)
848 return (USBD_NOT_CONFIGURED);
849 if (ifaceno >= dev->cdesc->bNumInterface)
850 return (USBD_INVAL);
851 *iface = &dev->ifaces[ifaceno];
852 return (USBD_NORMAL_COMPLETION);
853 }
854
855 usbd_device_handle
856 usbd_pipe2device_handle(usbd_pipe_handle pipe)
857 {
858 return (pipe->device);
859 }
860
861 /* XXXX use altno */
862 usbd_status
863 usbd_set_interface(usbd_interface_handle iface, int altidx)
864 {
865 usb_device_request_t req;
866 usbd_status err;
867 void *endpoints;
868
869 if (LIST_FIRST(&iface->pipes) != 0)
870 return (USBD_IN_USE);
871
872 endpoints = iface->endpoints;
873 err = usbd_fill_iface_data(iface->device, iface->index, altidx);
874 if (err)
875 return (err);
876
877 /* new setting works, we can free old endpoints */
878 if (endpoints != NULL)
879 free(endpoints, M_USB);
880
881 #ifdef DIAGNOSTIC
882 if (iface->idesc == NULL) {
883 printf("usbd_set_interface: NULL pointer\n");
884 return (USBD_INVAL);
885 }
886 #endif
887
888 req.bmRequestType = UT_WRITE_INTERFACE;
889 req.bRequest = UR_SET_INTERFACE;
890 USETW(req.wValue, iface->idesc->bAlternateSetting);
891 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
892 USETW(req.wLength, 0);
893 return (usbd_do_request(iface->device, &req, 0));
894 }
895
896 int
897 usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno)
898 {
899 char *p = (char *)cdesc;
900 char *end = p + UGETW(cdesc->wTotalLength);
901 usb_interface_descriptor_t *d;
902 int n;
903
904 for (n = 0; p < end; p += d->bLength) {
905 d = (usb_interface_descriptor_t *)p;
906 if (p + d->bLength <= end &&
907 d->bDescriptorType == UDESC_INTERFACE &&
908 d->bInterfaceNumber == ifaceno)
909 n++;
910 }
911 return (n);
912 }
913
914 int
915 usbd_get_interface_altindex(usbd_interface_handle iface)
916 {
917 return (iface->altindex);
918 }
919
920 usbd_status
921 usbd_get_interface(usbd_interface_handle iface, u_int8_t *aiface)
922 {
923 usb_device_request_t req;
924
925 req.bmRequestType = UT_READ_INTERFACE;
926 req.bRequest = UR_GET_INTERFACE;
927 USETW(req.wValue, 0);
928 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
929 USETW(req.wLength, 1);
930 return (usbd_do_request(iface->device, &req, aiface));
931 }
932
933 /*** Internal routines ***/
934
935 /* Dequeue all pipe operations, called at splusb(). */
936 Static usbd_status
937 usbd_ar_pipe(usbd_pipe_handle pipe)
938 {
939 usbd_xfer_handle xfer;
940
941 SPLUSBCHECK;
942
943 DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe));
944 #ifdef USB_DEBUG
945 if (usbdebug > 5)
946 usbd_dump_queue(pipe);
947 #endif
948 pipe->repeat = 0;
949 pipe->aborting = 1;
950 while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
951 DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n",
952 pipe, xfer, pipe->methods));
953 /* Make the HC abort it (and invoke the callback). */
954 pipe->methods->abort(xfer);
955 USB_KASSERT2(SIMPLEQ_FIRST(&pipe->queue) != xfer,
956 ("usbd_ar_pipe"));
957 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
958 }
959 pipe->aborting = 0;
960 return (USBD_NORMAL_COMPLETION);
961 }
962
963 /* Called at splusb() */
964 void
965 usb_transfer_complete(usbd_xfer_handle xfer)
966 {
967 usbd_pipe_handle pipe = xfer->pipe;
968 int sync = xfer->flags & USBD_SYNCHRONOUS;
969 int erred = xfer->status == USBD_CANCELLED ||
970 xfer->status == USBD_TIMEOUT;
971 int repeat, polling;
972
973 SPLUSBCHECK;
974
975 DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
976 "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
977 #ifdef DIAGNOSTIC
978 if (xfer->busy_free != XFER_ONQU) {
979 printf("usb_transfer_complete: xfer=%p not busy 0x%08x\n",
980 xfer, xfer->busy_free);
981 }
982 #endif
983
984 #ifdef DIAGNOSTIC
985 if (pipe == NULL) {
986 printf("usb_transfer_complete: pipe==0, xfer=%p\n", xfer);
987 return;
988 }
989 #endif
990 repeat = pipe->repeat;
991 polling = pipe->device->bus->use_polling;
992 /* XXXX */
993 if (polling)
994 pipe->running = 0;
995
996 if (!(xfer->flags & USBD_NO_COPY) && xfer->actlen != 0 &&
997 usbd_xfer_isread(xfer)) {
998 #ifdef DIAGNOSTIC
999 if (xfer->actlen > xfer->length) {
1000 printf("usb_transfer_complete: actlen > len %d > %d\n",
1001 xfer->actlen, xfer->length);
1002 xfer->actlen = xfer->length;
1003 }
1004 #endif
1005 /* Copy data if it is not already in the correct buffer. */
1006 if (!(xfer->flags & USBD_NO_COPY) && xfer->hcbuffer != NULL) {
1007 DPRINTFN(5, ("usb_transfer_complete: copy %p (buffer) <- %p (alloc), %u bytes\n",
1008 xfer->buffer, xfer->hcbuffer, (unsigned)xfer->actlen));
1009 #ifdef DIAGNOSTIC
1010 if ((xfer->rqflags & (URQ_AUTO_BUF | URQ_DEV_BUF)) == 0)
1011 panic("usb_transfer_complete: USBD_NO_COPY required with mapped buffer");
1012 #endif
1013 memcpy(xfer->buffer, xfer->hcbuffer, xfer->actlen);
1014 }
1015 }
1016
1017 /*
1018 * if we allocated or mapped the buffer in usbd_transfer()
1019 * we unmap it here.
1020 */
1021 if (xfer->rqflags & URQ_AUTO_BUF) {
1022 if (!repeat) {
1023 struct usbd_bus *bus = pipe->device->bus;
1024 bus->methods->freem(bus, xfer, U_NOWAIT);
1025 xfer->rqflags &= ~URQ_AUTO_BUF;
1026 }
1027 }
1028
1029 if (!repeat) {
1030 /* Remove request from queue. */
1031 #ifdef DIAGNOSTIC
1032 xfer->busy_free = XFER_BUSY;
1033 #endif
1034 USB_KASSERT2(SIMPLEQ_FIRST(&pipe->queue) == xfer,
1035 ("usb_transfer_complete: bad dequeue"));
1036 SIMPLEQ_REMOVE_HEAD(&pipe->queue, next);
1037 }
1038 DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n",
1039 repeat, SIMPLEQ_FIRST(&pipe->queue)));
1040
1041 /* Count completed transfers. */
1042 ++pipe->device->bus->stats.uds_requests
1043 [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE];
1044
1045 xfer->done = 1;
1046 if (!xfer->status && xfer->actlen < xfer->length &&
1047 !(xfer->flags & USBD_SHORT_XFER_OK)) {
1048 DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n",
1049 xfer->actlen, xfer->length));
1050 xfer->status = USBD_SHORT_XFER;
1051 }
1052
1053 /*
1054 * For repeat operations, call the callback first, as the xfer
1055 * will not go away and the "done" method may modify it. Otherwise
1056 * reverse the order in case the callback wants to free or reuse
1057 * the xfer.
1058 */
1059 if (repeat) {
1060 if (xfer->callback)
1061 xfer->callback(xfer, xfer->priv, xfer->status);
1062 pipe->methods->done(xfer);
1063 } else {
1064 pipe->methods->done(xfer);
1065 if (xfer->callback) {
1066 if (xfer->flags & USBD_CALLBACK_AS_TASK) {
1067 /*
1068 * Callback as a task (in thread context).
1069 */
1070 usb_init_task(&xfer->task, usbd_callback_task,
1071 xfer);
1072 usb_add_task(xfer->device, &xfer->task,
1073 USB_TASKQ_DRIVER);
1074 } else
1075 xfer->callback(xfer, xfer->priv, xfer->status);
1076 }
1077 }
1078
1079 if (sync && !polling)
1080 wakeup(xfer);
1081
1082 if (!repeat) {
1083 /* XXX should we stop the queue on all errors? */
1084 if (erred && pipe->iface != NULL) /* not control pipe */
1085 pipe->running = 0;
1086 else
1087 usbd_start_next(pipe);
1088 }
1089 }
1090
1091 Static void
1092 usbd_callback_task(void *arg)
1093 {
1094 usbd_xfer_handle xfer = arg;
1095
1096 xfer->callback(xfer, xfer->priv, xfer->status);
1097 }
1098
1099 usbd_status
1100 usb_insert_transfer(usbd_xfer_handle xfer)
1101 {
1102 usbd_pipe_handle pipe = xfer->pipe;
1103 usbd_status err;
1104 int s;
1105
1106 DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n",
1107 pipe, pipe->running, xfer->timeout));
1108 #ifdef DIAGNOSTIC
1109 if (xfer->busy_free != XFER_BUSY) {
1110 printf("usb_insert_transfer: xfer=%p not busy 0x%08x\n",
1111 xfer, xfer->busy_free);
1112 return (USBD_INVAL);
1113 }
1114 xfer->busy_free = XFER_ONQU;
1115 #endif
1116 s = splusb();
1117 USB_KASSERT2(SIMPLEQ_FIRST(&pipe->queue) != xfer,
1118 ("usb_insert_transfer"));
1119 SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
1120 if (pipe->running)
1121 err = USBD_IN_PROGRESS;
1122 else {
1123 pipe->running = 1;
1124 err = USBD_NORMAL_COMPLETION;
1125 }
1126 splx(s);
1127 return (err);
1128 }
1129
1130 /* Called at splusb() */
1131 void
1132 usbd_start_next(usbd_pipe_handle pipe)
1133 {
1134 usbd_xfer_handle xfer;
1135 usbd_status err;
1136
1137 SPLUSBCHECK;
1138
1139 #ifdef DIAGNOSTIC
1140 if (pipe == NULL) {
1141 printf("usbd_start_next: pipe == NULL\n");
1142 return;
1143 }
1144 if (pipe->methods == NULL || pipe->methods->start == NULL) {
1145 printf("usbd_start_next: pipe=%p no start method\n", pipe);
1146 return;
1147 }
1148 #endif
1149
1150 /* Get next request in queue. */
1151 xfer = SIMPLEQ_FIRST(&pipe->queue);
1152 DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer));
1153 if (xfer == NULL) {
1154 pipe->running = 0;
1155 } else {
1156 err = pipe->methods->start(xfer);
1157 if (err != USBD_IN_PROGRESS) {
1158 printf("usbd_start_next: error=%d\n", err);
1159 pipe->running = 0;
1160 /* XXX do what? */
1161 }
1162 }
1163 }
1164
1165 usbd_status
1166 usbd_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data)
1167 {
1168 return (usbd_do_request_flags(dev, req, data, 0, 0,
1169 USBD_DEFAULT_TIMEOUT));
1170 }
1171
1172 usbd_status
1173 usbd_do_request_flags(usbd_device_handle dev, usb_device_request_t *req,
1174 void *data, u_int16_t flags, int *actlen, u_int32_t timo)
1175 {
1176 return (usbd_do_request_flags_pipe(dev, dev->default_pipe, req,
1177 data, flags, actlen, timo));
1178 }
1179
1180 usbd_status
1181 usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe,
1182 usb_device_request_t *req, void *data, u_int16_t flags, int *actlen,
1183 u_int32_t timeout)
1184 {
1185 usbd_xfer_handle xfer;
1186 usbd_status err;
1187
1188 #ifdef DIAGNOSTIC
1189 #if defined(__i386__) && defined(__FreeBSD__)
1190 KASSERT(curthread->td_intr_nesting_level == 0,
1191 ("usbd_do_request: in interrupt context"));
1192 #endif
1193 if (dev->bus->intr_context) {
1194 panic("usbd_do_request: not in process context");
1195 }
1196 #endif
1197
1198 xfer = usbd_alloc_xfer(dev, pipe);
1199 if (xfer == NULL)
1200 return (USBD_NOMEM);
1201 xfer->pipe = dev->default_pipe; /* XXX */
1202 /* XXX */
1203 usbd_setup_default_xfer(xfer, dev, 0, timeout, req,
1204 data, UGETW(req->wLength), flags, 0);
1205 /* XXX */
1206 xfer->pipe = pipe;
1207 err = usbd_sync_transfer(xfer);
1208 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1209 if (xfer->actlen > xfer->length) {
1210 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
1211 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
1212 dev->address, xfer->request.bmRequestType,
1213 xfer->request.bRequest, UGETW(xfer->request.wValue),
1214 UGETW(xfer->request.wIndex),
1215 UGETW(xfer->request.wLength),
1216 xfer->length, xfer->actlen));
1217 }
1218 #endif
1219 if (actlen != NULL)
1220 *actlen = xfer->actlen;
1221 if (err == USBD_STALLED) {
1222 /*
1223 * The control endpoint has stalled. Control endpoints
1224 * should not halt, but some may do so anyway so clear
1225 * any halt condition.
1226 */
1227 usb_device_request_t treq;
1228 usb_status_t status;
1229 u_int16_t s;
1230 usbd_status nerr;
1231
1232 treq.bmRequestType = UT_READ_ENDPOINT;
1233 treq.bRequest = UR_GET_STATUS;
1234 USETW(treq.wValue, 0);
1235 USETW(treq.wIndex, 0);
1236 USETW(treq.wLength, sizeof(usb_status_t));
1237 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
1238 &treq, &status,sizeof(usb_status_t),
1239 0, 0);
1240 nerr = usbd_sync_transfer(xfer);
1241 if (nerr)
1242 goto bad;
1243 s = UGETW(status.wStatus);
1244 DPRINTF(("usbd_do_request: status = 0x%04x\n", s));
1245 if (!(s & UES_HALT))
1246 goto bad;
1247 treq.bmRequestType = UT_WRITE_ENDPOINT;
1248 treq.bRequest = UR_CLEAR_FEATURE;
1249 USETW(treq.wValue, UF_ENDPOINT_HALT);
1250 USETW(treq.wIndex, 0);
1251 USETW(treq.wLength, 0);
1252 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
1253 &treq, &status, 0, 0, 0);
1254 nerr = usbd_sync_transfer(xfer);
1255 if (nerr)
1256 goto bad;
1257 }
1258
1259 bad:
1260 usbd_free_xfer(xfer);
1261 return (err);
1262 }
1263
1264 void
1265 usbd_do_request_async_cb(usbd_xfer_handle xfer,
1266 usbd_private_handle priv, usbd_status status)
1267 {
1268 #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1269 if (xfer->actlen > xfer->length) {
1270 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x"
1271 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n",
1272 xfer->pipe->device->address,
1273 xfer->request.bmRequestType,
1274 xfer->request.bRequest, UGETW(xfer->request.wValue),
1275 UGETW(xfer->request.wIndex),
1276 UGETW(xfer->request.wLength),
1277 xfer->length, xfer->actlen));
1278 }
1279 #endif
1280 usbd_free_xfer_flag(xfer, U_NOWAIT);
1281 }
1282
1283 /*
1284 * Execute a request without waiting for completion.
1285 * Can be used from interrupt context.
1286 */
1287 usbd_status
1288 usbd_do_request_async(usbd_device_handle dev, usb_device_request_t *req,
1289 void *data)
1290 {
1291 usbd_xfer_handle xfer;
1292
1293 xfer = usbd_alloc_xfer_flag(dev, dev->default_pipe, U_NOWAIT);
1294 if (xfer == NULL)
1295 return (USBD_NOMEM);
1296 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req,
1297 data, UGETW(req->wLength), 0, usbd_do_request_async_cb);
1298
1299 /*
1300 * Request will be processed later as a task (in thread context).
1301 */
1302 usb_init_task(&xfer->task, usbd_do_request_async_task, xfer);
1303 usb_add_task(dev, &xfer->task, USB_TASKQ_HC);
1304
1305 return (USBD_IN_PROGRESS);
1306 }
1307
1308 Static void
1309 usbd_do_request_async_task(void *arg)
1310 {
1311 usbd_xfer_handle xfer = arg;
1312 usbd_status err;
1313
1314 /* XXX impossible to notify caller the error */
1315 err = usbd_transfer(xfer);
1316 if (err != USBD_IN_PROGRESS && err) {
1317 usbd_free_xfer(xfer);
1318 }
1319 }
1320
1321 const struct usbd_quirks *
1322 usbd_get_quirks(usbd_device_handle dev)
1323 {
1324 #ifdef DIAGNOSTIC
1325 if (dev == NULL) {
1326 printf("usbd_get_quirks: dev == NULL\n");
1327 return 0;
1328 }
1329 #endif
1330 return (dev->quirks);
1331 }
1332
1333 /* XXX do periodic free() of free list */
1334
1335 /*
1336 * Called from keyboard driver when in polling mode.
1337 */
1338 void
1339 usbd_dopoll(usbd_interface_handle iface)
1340 {
1341 iface->device->bus->methods->do_poll(iface->device->bus);
1342 }
1343
1344 void
1345 usbd_set_polling(usbd_device_handle dev, int on)
1346 {
1347 if (on)
1348 dev->bus->use_polling++;
1349 else
1350 dev->bus->use_polling--;
1351 /* When polling we need to make sure there is nothing pending to do. */
1352 if (dev->bus->use_polling)
1353 dev->bus->methods->soft_intr(dev->bus);
1354 }
1355
1356
1357 usb_endpoint_descriptor_t *
1358 usbd_get_endpoint_descriptor(usbd_interface_handle iface, u_int8_t address)
1359 {
1360 struct usbd_endpoint *ep;
1361 int i;
1362
1363 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
1364 ep = &iface->endpoints[i];
1365 if (ep->edesc->bEndpointAddress == address)
1366 return (iface->endpoints[i].edesc);
1367 }
1368 return (0);
1369 }
1370
1371 /*
1372 * usbd_ratecheck() can limit the number of error messages that occurs.
1373 * When a device is unplugged it may take up to 0.25s for the hub driver
1374 * to notice it. If the driver continuosly tries to do I/O operations
1375 * this can generate a large number of messages.
1376 */
1377 int
1378 usbd_ratecheck(struct timeval *last)
1379 {
1380 #if defined(__NetBSD__)
1381 static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/
1382
1383 return (ratecheck(last, &errinterval));
1384 #elif defined(__FreeBSD__)
1385 if (last->tv_sec == time_second)
1386 return (0);
1387 last->tv_sec = time_second;
1388 return (1);
1389 #endif
1390 }
1391
1392 /*
1393 * Search for a vendor/product pair in an array. The item size is
1394 * given as an argument.
1395 */
1396 const struct usb_devno *
1397 usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
1398 u_int16_t vendor, u_int16_t product)
1399 {
1400 while (nentries-- > 0) {
1401 u_int16_t tproduct = tbl->ud_product;
1402 if (tbl->ud_vendor == vendor &&
1403 (tproduct == product || tproduct == USB_PRODUCT_ANY))
1404 return (tbl);
1405 tbl = (const struct usb_devno *)((const char *)tbl + sz);
1406 }
1407 return (NULL);
1408 }
1409
1410
1411 void
1412 usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter)
1413 {
1414 const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
1415
1416 iter->cur = (const uByte *)cd;
1417 iter->end = (const uByte *)cd + UGETW(cd->wTotalLength);
1418 }
1419
1420 const usb_descriptor_t *
1421 usb_desc_iter_next(usbd_desc_iter_t *iter)
1422 {
1423 const usb_descriptor_t *desc;
1424
1425 if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) {
1426 if (iter->cur != iter->end)
1427 printf("usb_desc_iter_next: bad descriptor\n");
1428 return NULL;
1429 }
1430 desc = (const usb_descriptor_t *)iter->cur;
1431 if (desc->bLength == 0) {
1432 printf("usb_desc_iter_next: descriptor length = 0\n");
1433 return NULL;
1434 }
1435 iter->cur += desc->bLength;
1436 if (iter->cur > iter->end) {
1437 printf("usb_desc_iter_next: descriptor length too large\n");
1438 return NULL;
1439 }
1440 return desc;
1441 }
1442
1443 usbd_status
1444 usbd_get_string(usbd_device_handle dev, int si, char *buf)
1445 {
1446 return usbd_get_string0(dev, si, buf, 1);
1447 }
1448
1449 usbd_status
1450 usbd_get_string0(usbd_device_handle dev, int si, char *buf, int unicode)
1451 {
1452 int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE;
1453 usb_string_descriptor_t us;
1454 char *s;
1455 int i, n;
1456 u_int16_t c;
1457 usbd_status err;
1458 int size;
1459
1460 buf[0] = '\0';
1461 if (si == 0)
1462 return (USBD_INVAL);
1463 if (dev->quirks->uq_flags & UQ_NO_STRINGS)
1464 return (USBD_STALLED);
1465 if (dev->langid == USBD_NOLANG) {
1466 /* Set up default language */
1467 err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
1468 &size);
1469 if (err || size < 4) {
1470 DPRINTFN(-1,("usbd_get_string: getting lang failed, using 0\n"));
1471 dev->langid = 0; /* Well, just pick something then */
1472 } else {
1473 /* Pick the first language as the default. */
1474 dev->langid = UGETW(us.bString[0]);
1475 }
1476 }
1477 err = usbd_get_string_desc(dev, si, dev->langid, &us, &size);
1478 if (err)
1479 return (err);
1480 s = buf;
1481 n = size / 2 - 1;
1482 if (unicode) {
1483 for (i = 0; i < n; i++) {
1484 c = UGETW(us.bString[i]);
1485 if (swap)
1486 c = (c >> 8) | (c << 8);
1487 s += wput_utf8(s, 3, c);
1488 }
1489 *s++ = 0;
1490 }
1491 #if defined(__NetBSD__) && defined(COMPAT_30)
1492 else {
1493 for (i = 0; i < n; i++) {
1494 c = UGETW(us.bString[i]);
1495 if (swap)
1496 c = (c >> 8) | (c << 8);
1497 *s++ = (c < 0x80) ? c : '?';
1498 }
1499 *s++ = 0;
1500 }
1501 #endif
1502 return (USBD_NORMAL_COMPLETION);
1503 }
1504
1505 #if defined(__FreeBSD__)
1506 int
1507 usbd_driver_load(module_t mod, int what, void *arg)
1508 {
1509 /* XXX should implement something like a function that removes all generic devices */
1510
1511 return (0);
1512 }
1513
1514 #endif
1515