jcs's openbsd hax
openbsd
1/* $OpenBSD: usbdi.c,v 1.112 2025/04/03 11:02:44 kirill Exp $ */
2/* $NetBSD: usbdi.c,v 1.103 2002/09/27 15:37:38 provos Exp $ */
3/* $FreeBSD: src/sys/dev/usb/usbdi.c,v 1.28 1999/11/17 22:33:49 n_hibma Exp $ */
4
5/*
6 * Copyright (c) 1998 The NetBSD Foundation, Inc.
7 * All rights reserved.
8 *
9 * This code is derived from software contributed to The NetBSD Foundation
10 * by Lennart Augustsson (lennart@augustsson.net) at
11 * Carlstedt Research & Technology.
12 *
13 * Redistribution and use in source and binary forms, with or without
14 * modification, are permitted provided that the following conditions
15 * are met:
16 * 1. Redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer.
18 * 2. Redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 */
34
35#include <sys/param.h>
36#include <sys/systm.h>
37#include <sys/device.h>
38#include <sys/malloc.h>
39
40#include <machine/bus.h>
41
42#include <dev/usb/usb.h>
43#include <dev/usb/usbdi.h>
44#include <dev/usb/usbdivar.h>
45#include <dev/usb/usb_mem.h>
46
47#ifdef USB_DEBUG
48#define DPRINTF(x) do { if (usbdebug) printf x; } while (0)
49#define DPRINTFN(n,x) do { if (usbdebug>(n)) printf x; } while (0)
50extern int usbdebug;
51#else
52#define DPRINTF(x)
53#define DPRINTFN(n,x)
54#endif
55
56void usbd_request_async_cb(struct usbd_xfer *, void *, usbd_status);
57void usbd_start_next(struct usbd_pipe *pipe);
58usbd_status usbd_open_pipe_ival(struct usbd_interface *, u_int8_t, u_int8_t,
59 struct usbd_pipe **, int);
60
61int
62usbd_is_dying(struct usbd_device *dev)
63{
64 return (dev->dying || dev->bus->dying);
65}
66
67void
68usbd_deactivate(struct usbd_device *dev)
69{
70 dev->dying = 1;
71}
72
73void
74usbd_ref_incr(struct usbd_device *dev)
75{
76 dev->ref_cnt++;
77}
78
79void
80usbd_ref_decr(struct usbd_device *dev)
81{
82 if (--dev->ref_cnt == 0)
83 wakeup(&dev->ref_cnt);
84}
85
86void
87usbd_ref_wait(struct usbd_device *dev)
88{
89 while (dev->ref_cnt > 0)
90 tsleep_nsec(&dev->ref_cnt, PWAIT, "usbref", SEC_TO_NSEC(60));
91}
92
93int
94usbd_get_devcnt(struct usbd_device *dev)
95{
96 return (dev->ndevs);
97}
98
99void
100usbd_claim_iface(struct usbd_device *dev, int ifaceno)
101{
102 dev->ifaces[ifaceno].claimed = 1;
103}
104
105int
106usbd_iface_claimed(struct usbd_device *dev, int ifaceno)
107{
108 return (dev->ifaces[ifaceno].claimed);
109}
110
111#ifdef USB_DEBUG
112void
113usbd_dump_iface(struct usbd_interface *iface)
114{
115 printf("%s: iface=%p\n", __func__, iface);
116 if (iface == NULL)
117 return;
118 printf(" device=%p idesc=%p index=%d altindex=%d priv=%p\n",
119 iface->device, iface->idesc, iface->index, iface->altindex,
120 iface->priv);
121}
122
123void
124usbd_dump_device(struct usbd_device *dev)
125{
126 printf("%s: dev=%p\n", __func__, dev);
127 if (dev == NULL)
128 return;
129 printf(" bus=%p default_pipe=%p\n", dev->bus, dev->default_pipe);
130 printf(" address=%d config=%d depth=%d speed=%d self_powered=%d "
131 "power=%d langid=%d\n", dev->address, dev->config, dev->depth,
132 dev->speed, dev->self_powered, dev->power, dev->langid);
133}
134
135void
136usbd_dump_endpoint(struct usbd_endpoint *endp)
137{
138 printf("%s: endp=%p\n", __func__, endp);
139 if (endp == NULL)
140 return;
141 printf(" edesc=%p refcnt=%d\n", endp->edesc, endp->refcnt);
142 if (endp->edesc)
143 printf(" bEndpointAddress=0x%02x\n",
144 endp->edesc->bEndpointAddress);
145}
146
147void
148usbd_dump_queue(struct usbd_pipe *pipe)
149{
150 struct usbd_xfer *xfer;
151
152 printf("%s: pipe=%p\n", __func__, pipe);
153 SIMPLEQ_FOREACH(xfer, &pipe->queue, next) {
154 printf(" xfer=%p\n", xfer);
155 }
156}
157
158void
159usbd_dump_pipe(struct usbd_pipe *pipe)
160{
161 printf("%s: pipe=%p\n", __func__, pipe);
162 if (pipe == NULL)
163 return;
164 usbd_dump_iface(pipe->iface);
165 usbd_dump_device(pipe->device);
166 usbd_dump_endpoint(pipe->endpoint);
167 printf(" (usbd_dump_pipe:)\n running=%d aborting=%d\n",
168 pipe->running, pipe->aborting);
169 printf(" intrxfer=%p, repeat=%d, interval=%d\n", pipe->intrxfer,
170 pipe->repeat, pipe->interval);
171}
172#endif
173
174usbd_status
175usbd_open_pipe(struct usbd_interface *iface, u_int8_t address, u_int8_t flags,
176 struct usbd_pipe **pipe)
177{
178 return (usbd_open_pipe_ival(iface, address, flags, pipe,
179 USBD_DEFAULT_INTERVAL));
180}
181
182usbd_status
183usbd_open_pipe_ival(struct usbd_interface *iface, u_int8_t address,
184 u_int8_t flags, struct usbd_pipe **pipe, int ival)
185{
186 struct usbd_pipe *p;
187 struct usbd_endpoint *ep;
188 usbd_status err;
189 int i;
190
191 DPRINTFN(3,("%s: iface=%p address=0x%x flags=0x%x\n", __func__,
192 iface, address, flags));
193
194 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
195 ep = &iface->endpoints[i];
196 if (ep->edesc == NULL)
197 return (USBD_IOERROR);
198 if (ep->edesc->bEndpointAddress == address)
199 goto found;
200 }
201 return (USBD_BAD_ADDRESS);
202 found:
203 if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0)
204 return (USBD_IN_USE);
205 err = usbd_setup_pipe(iface->device, iface, ep, ival, &p);
206 if (err)
207 return (err);
208 LIST_INSERT_HEAD(&iface->pipes, p, next);
209 *pipe = p;
210 return (USBD_NORMAL_COMPLETION);
211}
212
213usbd_status
214usbd_open_pipe_intr(struct usbd_interface *iface, u_int8_t address,
215 u_int8_t flags, struct usbd_pipe **pipe, void *priv,
216 void *buffer, u_int32_t len, usbd_callback cb, int ival)
217{
218 usbd_status err;
219 struct usbd_xfer *xfer;
220 struct usbd_pipe *ipipe;
221
222 DPRINTFN(3,("%s: address=0x%x flags=0x%x len=%d\n", __func__,
223 address, flags, len));
224
225 err = usbd_open_pipe_ival(iface, address, USBD_EXCLUSIVE_USE, &ipipe,
226 ival);
227 if (err)
228 return (err);
229 xfer = usbd_alloc_xfer(iface->device);
230 if (xfer == NULL) {
231 err = USBD_NOMEM;
232 goto bad1;
233 }
234 usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags,
235 USBD_NO_TIMEOUT, cb);
236 ipipe->intrxfer = xfer;
237 ipipe->repeat = 1;
238 err = usbd_transfer(xfer);
239 *pipe = ipipe;
240 if (err != USBD_IN_PROGRESS)
241 goto bad2;
242 return (USBD_NORMAL_COMPLETION);
243
244 bad2:
245 ipipe->intrxfer = NULL;
246 ipipe->repeat = 0;
247 usbd_free_xfer(xfer);
248 bad1:
249 usbd_close_pipe(ipipe);
250 return (err);
251}
252
253usbd_status
254usbd_close_pipe(struct usbd_pipe *pipe)
255{
256#ifdef DIAGNOSTIC
257 if (pipe == NULL) {
258 printf("usbd_close_pipe: pipe==NULL\n");
259 return (USBD_NORMAL_COMPLETION);
260 }
261#endif
262
263 if (!SIMPLEQ_EMPTY(&pipe->queue))
264 usbd_abort_pipe(pipe);
265
266 /* Default pipes are never linked */
267 if (pipe->iface != NULL)
268 LIST_REMOVE(pipe, next);
269 pipe->endpoint->refcnt--;
270 pipe->methods->close(pipe);
271 if (pipe->intrxfer != NULL)
272 usbd_free_xfer(pipe->intrxfer);
273 free(pipe, M_USB, pipe->pipe_size);
274 return (USBD_NORMAL_COMPLETION);
275}
276
277usbd_status
278usbd_transfer(struct usbd_xfer *xfer)
279{
280 struct usbd_pipe *pipe = xfer->pipe;
281 struct usbd_bus *bus = pipe->device->bus;
282 int polling = bus->use_polling;
283 usbd_status err;
284 int flags, s;
285
286 if (usbd_is_dying(pipe->device))
287 return (USBD_IOERROR);
288
289 DPRINTFN(5,("%s: xfer=%p, flags=%d, pipe=%p, running=%d\n", __func__,
290 xfer, xfer->flags, pipe, pipe->running));
291#ifdef USB_DEBUG
292 if (usbdebug > 5)
293 usbd_dump_queue(pipe);
294#endif
295 xfer->done = 0;
296 xfer->status = USBD_NOT_STARTED;
297
298 if (pipe->aborting)
299 return (USBD_CANCELLED);
300
301 /* If there is no buffer, allocate one. */
302 if ((xfer->rqflags & URQ_DEV_DMABUF) == 0) {
303#ifdef DIAGNOSTIC
304 if (xfer->rqflags & URQ_AUTO_DMABUF)
305 printf("usbd_transfer: has old buffer!\n");
306#endif
307 err = usb_allocmem(bus, xfer->length, 0, 0, &xfer->dmabuf);
308 if (err)
309 return (err);
310 xfer->rqflags |= URQ_AUTO_DMABUF;
311 }
312
313 if (!usbd_xfer_isread(xfer) && (xfer->flags & USBD_NO_COPY) == 0)
314 memcpy(KERNADDR(&xfer->dmabuf, 0), xfer->buffer,
315 xfer->length);
316
317 usb_tap(bus, xfer, USBTAP_DIR_OUT);
318
319 err = pipe->methods->transfer(xfer);
320
321 if (err != USBD_IN_PROGRESS && err != USBD_NORMAL_COMPLETION) {
322 /* The transfer has not been queued, so free buffer. */
323 if (xfer->rqflags & URQ_AUTO_DMABUF) {
324 usb_freemem(bus, &xfer->dmabuf);
325 xfer->rqflags &= ~URQ_AUTO_DMABUF;
326 }
327 }
328
329 if (!(xfer->flags & USBD_SYNCHRONOUS))
330 return (err);
331
332 /* Sync transfer, wait for completion. */
333 if (err != USBD_IN_PROGRESS)
334 return (err);
335
336 s = splusb();
337 if (polling) {
338 int timo;
339
340 for (timo = xfer->timeout; timo >= 0; timo--) {
341 usb_delay_ms(bus, 1);
342 if (bus->dying) {
343 xfer->status = USBD_IOERROR;
344 usb_transfer_complete(xfer);
345 break;
346 }
347
348 usbd_dopoll(pipe->device);
349 if (xfer->done)
350 break;
351 }
352
353 if (timo < 0) {
354 xfer->status = USBD_TIMEOUT;
355 usb_transfer_complete(xfer);
356 }
357 } else {
358 while (!xfer->done) {
359 flags = PRIBIO|(xfer->flags & USBD_CATCH ? PCATCH : 0);
360
361 err = tsleep_nsec(xfer, flags, "usbsyn", INFSLP);
362 if (err && !xfer->done) {
363 usbd_abort_pipe(pipe);
364 if (err == EINTR)
365 xfer->status = USBD_INTERRUPTED;
366 else
367 xfer->status = USBD_TIMEOUT;
368 }
369 }
370 }
371 splx(s);
372 return (xfer->status);
373}
374
375void *
376usbd_alloc_buffer(struct usbd_xfer *xfer, u_int32_t size)
377{
378 struct usbd_bus *bus = xfer->device->bus;
379 usbd_status err;
380
381#ifdef DIAGNOSTIC
382 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
383 printf("usbd_alloc_buffer: xfer already has a buffer\n");
384#endif
385 err = usb_allocmem(bus, size, 0, 0, &xfer->dmabuf);
386 if (err)
387 return (NULL);
388 xfer->rqflags |= URQ_DEV_DMABUF;
389 return (KERNADDR(&xfer->dmabuf, 0));
390}
391
392void
393usbd_free_buffer(struct usbd_xfer *xfer)
394{
395#ifdef DIAGNOSTIC
396 if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) {
397 printf("usbd_free_buffer: no buffer\n");
398 return;
399 }
400#endif
401 xfer->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF);
402 usb_freemem(xfer->device->bus, &xfer->dmabuf);
403}
404
405void *
406usbd_get_buffer(struct usbd_xfer *xfer)
407{
408 if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)))
409 return (NULL);
410 return (KERNADDR(&xfer->dmabuf, 0));
411}
412
413struct usbd_xfer *
414usbd_alloc_xfer(struct usbd_device *dev)
415{
416 struct usbd_xfer *xfer;
417
418 xfer = dev->bus->methods->allocx(dev->bus);
419 if (xfer == NULL)
420 return (NULL);
421#ifdef DIAGNOSTIC
422 xfer->busy_free = XFER_FREE;
423#endif
424 xfer->device = dev;
425 timeout_set(&xfer->timeout_handle, NULL, NULL);
426 DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer));
427 return (xfer);
428}
429
430void
431usbd_free_xfer(struct usbd_xfer *xfer)
432{
433 DPRINTFN(5,("%s: %p\n", __func__, xfer));
434 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))
435 usbd_free_buffer(xfer);
436#ifdef DIAGNOSTIC
437 if (xfer->busy_free != XFER_FREE) {
438 printf("%s: xfer=%p not free\n", __func__, xfer);
439 return;
440 }
441#endif
442 xfer->device->bus->methods->freex(xfer->device->bus, xfer);
443}
444
445void
446usbd_setup_xfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe,
447 void *priv, void *buffer, u_int32_t length, u_int16_t flags,
448 u_int32_t timeout, usbd_callback callback)
449{
450 xfer->pipe = pipe;
451 xfer->priv = priv;
452 xfer->buffer = buffer;
453 xfer->length = length;
454 xfer->actlen = 0;
455 xfer->flags = flags;
456 xfer->timeout = timeout;
457 xfer->status = USBD_NOT_STARTED;
458 xfer->callback = callback;
459 xfer->rqflags &= ~URQ_REQUEST;
460 xfer->nframes = 0;
461}
462
463void
464usbd_setup_default_xfer(struct usbd_xfer *xfer, struct usbd_device *dev,
465 void *priv, u_int32_t timeout, usb_device_request_t *req,
466 void *buffer, u_int32_t length, u_int16_t flags, usbd_callback callback)
467{
468 xfer->pipe = dev->default_pipe;
469 xfer->priv = priv;
470 xfer->buffer = buffer;
471 xfer->length = length;
472 xfer->actlen = 0;
473 xfer->flags = flags;
474 xfer->timeout = timeout;
475 xfer->status = USBD_NOT_STARTED;
476 xfer->callback = callback;
477 xfer->request = *req;
478 xfer->rqflags |= URQ_REQUEST;
479 xfer->nframes = 0;
480}
481
482void
483usbd_setup_isoc_xfer(struct usbd_xfer *xfer, struct usbd_pipe *pipe,
484 void *priv, u_int16_t *frlengths, u_int32_t nframes,
485 u_int16_t flags, usbd_callback callback)
486{
487 int i;
488
489 xfer->pipe = pipe;
490 xfer->priv = priv;
491 xfer->buffer = 0;
492 xfer->length = 0;
493 for (i = 0; i < nframes; i++)
494 xfer->length += frlengths[i];
495 xfer->actlen = 0;
496 xfer->flags = flags;
497 xfer->timeout = USBD_NO_TIMEOUT;
498 xfer->status = USBD_NOT_STARTED;
499 xfer->callback = callback;
500 xfer->rqflags &= ~URQ_REQUEST;
501 xfer->frlengths = frlengths;
502 xfer->nframes = nframes;
503}
504
505void
506usbd_get_xfer_status(struct usbd_xfer *xfer, void **priv,
507 void **buffer, u_int32_t *count, usbd_status *status)
508{
509 if (priv != NULL)
510 *priv = xfer->priv;
511 if (buffer != NULL)
512 *buffer = xfer->buffer;
513 if (count != NULL)
514 *count = xfer->actlen;
515 if (status != NULL)
516 *status = xfer->status;
517}
518
519usb_config_descriptor_t *
520usbd_get_config_descriptor(struct usbd_device *dev)
521{
522#ifdef DIAGNOSTIC
523 if (dev == NULL) {
524 printf("usbd_get_config_descriptor: dev == NULL\n");
525 return (NULL);
526 }
527#endif
528 return (dev->cdesc);
529}
530
531usb_interface_descriptor_t *
532usbd_get_interface_descriptor(struct usbd_interface *iface)
533{
534#ifdef DIAGNOSTIC
535 if (iface == NULL) {
536 printf("usbd_get_interface_descriptor: dev == NULL\n");
537 return (NULL);
538 }
539#endif
540 return (iface->idesc);
541}
542
543usb_device_descriptor_t *
544usbd_get_device_descriptor(struct usbd_device *dev)
545{
546 return (&dev->ddesc);
547}
548
549usb_endpoint_descriptor_t *
550usbd_interface2endpoint_descriptor(struct usbd_interface *iface, u_int8_t index)
551{
552 if (index >= iface->idesc->bNumEndpoints)
553 return (0);
554 return (iface->endpoints[index].edesc);
555}
556
557void
558usbd_abort_pipe(struct usbd_pipe *pipe)
559{
560 struct usbd_xfer *xfer;
561 int s;
562
563#ifdef DIAGNOSTIC
564 if (pipe == NULL) {
565 printf("usbd_abort_pipe: pipe==NULL\n");
566 return;
567 }
568#endif
569 s = splusb();
570 DPRINTFN(2,("%s: pipe=%p\n", __func__, pipe));
571#ifdef USB_DEBUG
572 if (usbdebug > 5)
573 usbd_dump_queue(pipe);
574#endif
575 pipe->repeat = 0;
576 pipe->aborting = 1;
577 while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) {
578 DPRINTFN(2,("%s: pipe=%p xfer=%p (methods=%p)\n", __func__,
579 pipe, xfer, pipe->methods));
580 /* Make the HC abort it (and invoke the callback). */
581 pipe->methods->abort(xfer);
582 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
583 }
584 pipe->aborting = 0;
585 splx(s);
586}
587
588usbd_status
589usbd_clear_endpoint_stall(struct usbd_pipe *pipe)
590{
591 struct usbd_device *dev = pipe->device;
592 usb_device_request_t req;
593 usbd_status err;
594
595 DPRINTFN(8, ("usbd_clear_endpoint_stall\n"));
596
597 /*
598 * Clearing en endpoint stall resets the endpoint toggle, so
599 * do the same to the HC toggle.
600 */
601 usbd_clear_endpoint_toggle(pipe);
602
603 req.bmRequestType = UT_WRITE_ENDPOINT;
604 req.bRequest = UR_CLEAR_FEATURE;
605 USETW(req.wValue, UF_ENDPOINT_HALT);
606 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
607 USETW(req.wLength, 0);
608 err = usbd_do_request(dev, &req, 0);
609
610 return (err);
611}
612
613usbd_status
614usbd_clear_endpoint_stall_async(struct usbd_pipe *pipe)
615{
616 struct usbd_device *dev = pipe->device;
617 struct usbd_xfer *xfer;
618 usb_device_request_t req;
619 usbd_status err;
620
621 usbd_clear_endpoint_toggle(pipe);
622
623 req.bmRequestType = UT_WRITE_ENDPOINT;
624 req.bRequest = UR_CLEAR_FEATURE;
625 USETW(req.wValue, UF_ENDPOINT_HALT);
626 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress);
627 USETW(req.wLength, 0);
628
629 xfer = usbd_alloc_xfer(dev);
630 if (xfer == NULL)
631 return (USBD_NOMEM);
632
633 err = usbd_request_async(xfer, &req, NULL, NULL);
634 return (err);
635}
636
637void
638usbd_clear_endpoint_toggle(struct usbd_pipe *pipe)
639{
640 if (pipe->methods->cleartoggle != NULL)
641 pipe->methods->cleartoggle(pipe);
642}
643
644usbd_status
645usbd_device2interface_handle(struct usbd_device *dev, u_int8_t ifaceno,
646 struct usbd_interface **iface)
647{
648 u_int8_t idx;
649
650 if (dev->cdesc == NULL)
651 return (USBD_NOT_CONFIGURED);
652 if (ifaceno < dev->cdesc->bNumInterfaces) {
653 *iface = &dev->ifaces[ifaceno];
654 return (USBD_NORMAL_COMPLETION);
655 }
656 /*
657 * The correct interface should be at dev->ifaces[ifaceno], but we've
658 * seen non-compliant devices in the wild which present non-contiguous
659 * interface numbers and this skews the indices. For this reason we
660 * linearly search the interface array.
661 */
662 for (idx = 0; idx < dev->cdesc->bNumInterfaces; idx++) {
663 if (dev->ifaces[idx].idesc->bInterfaceNumber == ifaceno) {
664 *iface = &dev->ifaces[idx];
665 return (USBD_NORMAL_COMPLETION);
666 }
667 }
668 return (USBD_INVAL);
669}
670
671/* XXXX use altno */
672usbd_status
673usbd_set_interface(struct usbd_interface *iface, int altno)
674{
675 usb_device_request_t req;
676 usbd_status err;
677 struct usbd_endpoint *endpoints;
678 int nendpt;
679
680 if (LIST_FIRST(&iface->pipes) != 0)
681 return (USBD_IN_USE);
682
683 endpoints = iface->endpoints;
684 nendpt = iface->nendpt;
685 err = usbd_fill_iface_data(iface->device, iface->index, altno);
686 if (err)
687 return (err);
688
689 /* new setting works, we can free old endpoints */
690 free(endpoints, M_USB, nendpt * sizeof(*endpoints));
691
692#ifdef DIAGNOSTIC
693 if (iface->idesc == NULL) {
694 printf("usbd_set_interface: NULL pointer\n");
695 return (USBD_INVAL);
696 }
697#endif
698
699 req.bmRequestType = UT_WRITE_INTERFACE;
700 req.bRequest = UR_SET_INTERFACE;
701 USETW(req.wValue, iface->idesc->bAlternateSetting);
702 USETW(req.wIndex, iface->idesc->bInterfaceNumber);
703 USETW(req.wLength, 0);
704 return (usbd_do_request(iface->device, &req, 0));
705}
706
707int
708usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno)
709{
710 char *p = (char *)cdesc;
711 char *end = p + UGETW(cdesc->wTotalLength);
712 usb_interface_descriptor_t *d;
713 int n;
714
715 for (n = 0; p < end; p += d->bLength) {
716 d = (usb_interface_descriptor_t *)p;
717 if (p + d->bLength <= end &&
718 d->bDescriptorType == UDESC_INTERFACE &&
719 d->bInterfaceNumber == ifaceno)
720 n++;
721 }
722 return (n);
723}
724
725int
726usbd_get_interface_altindex(struct usbd_interface *iface)
727{
728 return (iface->altindex);
729}
730
731/*** Internal routines ***/
732
733/* Called at splusb() */
734void
735usb_transfer_complete(struct usbd_xfer *xfer)
736{
737 struct usbd_pipe *pipe = xfer->pipe;
738 struct usbd_bus *bus = pipe->device->bus;
739 int polling = bus->use_polling;
740 int status, flags;
741
742#if 0
743 /* XXX ohci_intr1() calls usb_transfer_complete() for RHSC. */
744 splsoftassert(IPL_SOFTUSB);
745#endif
746
747 DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d "
748 "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen));
749#ifdef DIAGNOSTIC
750 if (xfer->busy_free != XFER_ONQU) {
751 printf("%s: xfer=%p not on queue\n", __func__, xfer);
752 return;
753 }
754#endif
755
756 /* XXXX */
757 if (polling)
758 pipe->running = 0;
759
760 if (xfer->actlen > xfer->length) {
761#ifdef DIAGNOSTIC
762 printf("%s: actlen > len %u > %u\n", __func__, xfer->actlen,
763 xfer->length);
764#endif
765 xfer->actlen = xfer->length;
766 }
767
768 if (usbd_xfer_isread(xfer) && xfer->actlen != 0 &&
769 (xfer->flags & USBD_NO_COPY) == 0)
770 memcpy(xfer->buffer, KERNADDR(&xfer->dmabuf, 0),
771 xfer->actlen);
772
773 /* if we allocated the buffer in usbd_transfer() we free it here. */
774 if (xfer->rqflags & URQ_AUTO_DMABUF) {
775 if (!pipe->repeat) {
776 usb_freemem(bus, &xfer->dmabuf);
777 xfer->rqflags &= ~URQ_AUTO_DMABUF;
778 }
779 }
780
781 if (!pipe->repeat) {
782 /* Remove request from queue. */
783 KASSERT(xfer == SIMPLEQ_FIRST(&pipe->queue));
784 SIMPLEQ_REMOVE_HEAD(&pipe->queue, next);
785#ifdef DIAGNOSTIC
786 xfer->busy_free = XFER_FREE;
787#endif
788 }
789 DPRINTFN(5,("%s: repeat=%d new head=%p\n", __func__,
790 pipe->repeat, SIMPLEQ_FIRST(&pipe->queue)));
791
792 /* Count completed transfers. */
793 ++bus->stats.uds_requests
794 [UE_GET_XFERTYPE(pipe->endpoint->edesc->bmAttributes)];
795
796 xfer->done = 1;
797 if (!xfer->status && xfer->actlen < xfer->length &&
798 !(xfer->flags & USBD_SHORT_XFER_OK)) {
799 DPRINTFN(-1,("%s: short transfer %d<%d\n", __func__,
800 xfer->actlen, xfer->length));
801 xfer->status = USBD_SHORT_XFER;
802 }
803
804 usb_tap(bus, xfer, USBTAP_DIR_IN);
805
806 /*
807 * We cannot dereference ``xfer'' after calling the callback as
808 * it might free it.
809 */
810 status = xfer->status;
811 flags = xfer->flags;
812
813 if (pipe->repeat) {
814 if (xfer->callback)
815 xfer->callback(xfer, xfer->priv, xfer->status);
816 pipe->methods->done(xfer);
817 } else {
818 pipe->methods->done(xfer);
819 if (xfer->callback)
820 xfer->callback(xfer, xfer->priv, xfer->status);
821 }
822
823 if ((flags & USBD_SYNCHRONOUS) && !polling)
824 wakeup(xfer);
825
826 if (!pipe->repeat) {
827 /* XXX should we stop the queue on all errors? */
828 if ((status == USBD_CANCELLED || status == USBD_IOERROR ||
829 status == USBD_TIMEOUT) &&
830 pipe->iface != NULL) /* not control pipe */
831 pipe->running = 0;
832 else
833 usbd_start_next(pipe);
834 }
835}
836
837usbd_status
838usb_insert_transfer(struct usbd_xfer *xfer)
839{
840 struct usbd_pipe *pipe = xfer->pipe;
841 usbd_status err;
842 int s;
843
844 DPRINTFN(5,("%s: pipe=%p running=%d timeout=%d\n", __func__,
845 pipe, pipe->running, xfer->timeout));
846#ifdef DIAGNOSTIC
847 if (xfer->busy_free != XFER_FREE) {
848 printf("%s: xfer=%p not free\n", __func__, xfer);
849 return (USBD_INVAL);
850 }
851 xfer->busy_free = XFER_ONQU;
852#endif
853 s = splusb();
854 SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next);
855 if (pipe->running)
856 err = USBD_IN_PROGRESS;
857 else {
858 pipe->running = 1;
859 err = USBD_NORMAL_COMPLETION;
860 }
861 splx(s);
862 return (err);
863}
864
865/* Called at splusb() */
866void
867usbd_start_next(struct usbd_pipe *pipe)
868{
869 struct usbd_xfer *xfer;
870 usbd_status err;
871
872 splsoftassert(IPL_SOFTUSB);
873
874#ifdef DIAGNOSTIC
875 if (pipe == NULL) {
876 printf("usbd_start_next: pipe == NULL\n");
877 return;
878 }
879 if (pipe->methods == NULL || pipe->methods->start == NULL) {
880 printf("%s: pipe=%p no start method\n", __func__, pipe);
881 return;
882 }
883#endif
884
885 /* Get next request in queue. */
886 xfer = SIMPLEQ_FIRST(&pipe->queue);
887 DPRINTFN(5, ("%s: pipe=%p, xfer=%p\n", __func__, pipe, xfer));
888 if (xfer == NULL) {
889 pipe->running = 0;
890 } else {
891 err = pipe->methods->start(xfer);
892 if (err != USBD_IN_PROGRESS) {
893 printf("%s: error=%d\n", __func__, err);
894 pipe->running = 0;
895 /* XXX do what? */
896 }
897 }
898}
899
900usbd_status
901usbd_do_request(struct usbd_device *dev, usb_device_request_t *req, void *data)
902{
903 return (usbd_do_request_flags(dev, req, data, 0, 0,
904 USBD_DEFAULT_TIMEOUT));
905}
906
907usbd_status
908usbd_do_request_flags(struct usbd_device *dev, usb_device_request_t *req,
909 void *data, uint16_t flags, int *actlen, uint32_t timeout)
910{
911 struct usbd_xfer *xfer;
912 usbd_status err;
913
914#ifdef DIAGNOSTIC
915 if (dev->bus->intr_context) {
916 printf("usbd_do_request: not in process context\n");
917 return (USBD_INVAL);
918 }
919#endif
920
921 /* If the bus is gone, don't go any further. */
922 if (usbd_is_dying(dev))
923 return (USBD_IOERROR);
924
925 xfer = usbd_alloc_xfer(dev);
926 if (xfer == NULL)
927 return (USBD_NOMEM);
928 usbd_setup_default_xfer(xfer, dev, 0, timeout, req, data,
929 UGETW(req->wLength), flags | USBD_SYNCHRONOUS, 0);
930 err = usbd_transfer(xfer);
931 if (actlen != NULL)
932 *actlen = xfer->actlen;
933 if (err == USBD_STALLED) {
934 /*
935 * The control endpoint has stalled. Control endpoints
936 * should not halt, but some may do so anyway so clear
937 * any halt condition.
938 */
939 usb_device_request_t treq;
940 usb_status_t status;
941 u_int16_t s;
942 usbd_status nerr;
943
944 treq.bmRequestType = UT_READ_ENDPOINT;
945 treq.bRequest = UR_GET_STATUS;
946 USETW(treq.wValue, 0);
947 USETW(treq.wIndex, 0);
948 USETW(treq.wLength, sizeof(usb_status_t));
949 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
950 &treq, &status, sizeof(usb_status_t), USBD_SYNCHRONOUS, 0);
951 nerr = usbd_transfer(xfer);
952 if (nerr)
953 goto bad;
954 s = UGETW(status.wStatus);
955 DPRINTF(("%s: status = 0x%04x\n", __func__, s));
956 if (!(s & UES_HALT))
957 goto bad;
958 treq.bmRequestType = UT_WRITE_ENDPOINT;
959 treq.bRequest = UR_CLEAR_FEATURE;
960 USETW(treq.wValue, UF_ENDPOINT_HALT);
961 USETW(treq.wIndex, 0);
962 USETW(treq.wLength, 0);
963 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
964 &treq, &status, 0, USBD_SYNCHRONOUS, 0);
965 nerr = usbd_transfer(xfer);
966 if (nerr)
967 goto bad;
968 }
969
970 bad:
971 usbd_free_xfer(xfer);
972 return (err);
973}
974
975void
976usbd_request_async_cb(struct usbd_xfer *xfer, void *priv, usbd_status status)
977{
978 usbd_free_xfer(xfer);
979}
980
981/*
982 * Execute a request without waiting for completion.
983 * Can be used from interrupt context.
984 */
985usbd_status
986usbd_request_async(struct usbd_xfer *xfer, usb_device_request_t *req,
987 void *priv, usbd_callback callback)
988{
989 usbd_status err;
990
991 if (callback == NULL)
992 callback = usbd_request_async_cb;
993
994 usbd_setup_default_xfer(xfer, xfer->device, priv,
995 USBD_DEFAULT_TIMEOUT, req, NULL, UGETW(req->wLength),
996 USBD_NO_COPY, callback);
997 err = usbd_transfer(xfer);
998 if (err != USBD_IN_PROGRESS) {
999 usbd_free_xfer(xfer);
1000 return (err);
1001 }
1002 return (USBD_NORMAL_COMPLETION);
1003}
1004
1005const struct usbd_quirks *
1006usbd_get_quirks(struct usbd_device *dev)
1007{
1008#ifdef DIAGNOSTIC
1009 if (dev == NULL) {
1010 printf("usbd_get_quirks: dev == NULL\n");
1011 return 0;
1012 }
1013#endif
1014 return (dev->quirks);
1015}
1016
1017/* XXX do periodic free() of free list */
1018
1019/*
1020 * Called from keyboard driver when in polling mode.
1021 */
1022void
1023usbd_dopoll(struct usbd_device *udev)
1024{
1025 udev->bus->methods->do_poll(udev->bus);
1026}
1027
1028void
1029usbd_set_polling(struct usbd_device *dev, int on)
1030{
1031 if (on)
1032 dev->bus->use_polling++;
1033 else
1034 dev->bus->use_polling--;
1035 /* When polling we need to make sure there is nothing pending to do. */
1036 if (dev->bus->use_polling)
1037 dev->bus->methods->soft_intr(dev->bus);
1038}
1039
1040usb_endpoint_descriptor_t *
1041usbd_get_endpoint_descriptor(struct usbd_interface *iface, u_int8_t address)
1042{
1043 struct usbd_endpoint *ep;
1044 int i;
1045
1046 for (i = 0; i < iface->idesc->bNumEndpoints; i++) {
1047 ep = &iface->endpoints[i];
1048 if (ep->edesc->bEndpointAddress == address)
1049 return (iface->endpoints[i].edesc);
1050 }
1051 return (0);
1052}
1053
1054/*
1055 * usbd_ratecheck() can limit the number of error messages that occurs.
1056 * When a device is unplugged it may take up to 0.25s for the hub driver
1057 * to notice it. If the driver continuously tries to do I/O operations
1058 * this can generate a large number of messages.
1059 */
1060int
1061usbd_ratecheck(struct timeval *last)
1062{
1063 static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/
1064
1065 return (ratecheck(last, &errinterval));
1066}
1067
1068/*
1069 * Search for a vendor/product pair in an array. The item size is
1070 * given as an argument.
1071 */
1072const struct usb_devno *
1073usbd_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
1074 u_int16_t vendor, u_int16_t product)
1075{
1076 while (nentries-- > 0) {
1077 u_int16_t tproduct = tbl->ud_product;
1078 if (tbl->ud_vendor == vendor &&
1079 (tproduct == product || tproduct == USB_PRODUCT_ANY))
1080 return (tbl);
1081 tbl = (const struct usb_devno *)((const char *)tbl + sz);
1082 }
1083 return (NULL);
1084}
1085
1086void
1087usbd_desc_iter_init(struct usbd_device *dev, struct usbd_desc_iter *iter)
1088{
1089 const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
1090
1091 iter->cur = (const uByte *)cd;
1092 iter->end = (const uByte *)cd + UGETW(cd->wTotalLength);
1093}
1094
1095const usb_descriptor_t *
1096usbd_desc_iter_next(struct usbd_desc_iter *iter)
1097{
1098 const usb_descriptor_t *desc;
1099
1100 if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) {
1101 if (iter->cur != iter->end)
1102 printf("usbd_desc_iter_next: bad descriptor\n");
1103 return NULL;
1104 }
1105 desc = (const usb_descriptor_t *)iter->cur;
1106 if (desc->bLength == 0) {
1107 printf("usbd_desc_iter_next: descriptor length = 0\n");
1108 return NULL;
1109 }
1110 iter->cur += desc->bLength;
1111 if (iter->cur > iter->end) {
1112 printf("usbd_desc_iter_next: descriptor length too large\n");
1113 return NULL;
1114 }
1115 return desc;
1116}
1117
1118int
1119usbd_str(usb_string_descriptor_t *p, int l, const char *s)
1120{
1121 int i;
1122
1123 if (l == 0)
1124 return (0);
1125 p->bLength = 2 * strlen(s) + 2;
1126 if (l == 1)
1127 return (1);
1128 p->bDescriptorType = UDESC_STRING;
1129 l -= 2;
1130 for (i = 0; s[i] && l > 1; i++, l -= 2)
1131 USETW2(p->bString[i], 0, s[i]);
1132 return (2 * i + 2);
1133}