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