Annotation of src/sys/dev/usb/usbdi.c, Revision 1.162.2.19
1.162.2.19! skrll 1: /* $NetBSD: usbdi.c,v 1.162.2.18 2015/03/06 14:08:39 skrll Exp $ */
1.1 augustss 2:
3: /*
1.137 mrg 4: * Copyright (c) 1998, 2012 The NetBSD Foundation, Inc.
1.1 augustss 5: * All rights reserved.
6: *
1.11 augustss 7: * This code is derived from software contributed to The NetBSD Foundation
1.72 augustss 8: * by Lennart Augustsson (lennart@augustsson.net) at
1.137 mrg 9: * Carlstedt Research & Technology and Matthew R. Green (mrg@eterna.com.au).
1.1 augustss 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: *
20: * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21: * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22: * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24: * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25: * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26: * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27: * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28: * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29: * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30: * POSSIBILITY OF SUCH DAMAGE.
31: */
1.84 lukem 32:
33: #include <sys/cdefs.h>
1.162.2.19! skrll 34: __KERNEL_RCSID(0, "$NetBSD: usbdi.c,v 1.162.2.18 2015/03/06 14:08:39 skrll Exp $");
1.115 pavel 35:
1.141 christos 36: #ifdef _KERNEL_OPT
1.162 skrll 37: #include "opt_usb.h"
1.115 pavel 38: #include "opt_compat_netbsd.h"
1.141 christos 39: #endif
1.1 augustss 40:
1.162.2.5 skrll 41: #include "usb_dma.h"
42:
1.1 augustss 43: #include <sys/param.h>
44: #include <sys/systm.h>
45: #include <sys/kernel.h>
1.15 augustss 46: #include <sys/device.h>
1.162.2.5 skrll 47: #include <sys/kmem.h>
1.1 augustss 48: #include <sys/proc.h>
1.121 ad 49: #include <sys/bus.h>
1.136 mrg 50: #include <sys/cpu.h>
1.36 augustss 51:
1.1 augustss 52: #include <dev/usb/usb.h>
53: #include <dev/usb/usbdi.h>
54: #include <dev/usb/usbdi_util.h>
55: #include <dev/usb/usbdivar.h>
1.36 augustss 56: #include <dev/usb/usb_mem.h>
1.105 augustss 57: #include <dev/usb/usb_quirks.h>
1.162 skrll 58: #include <dev/usb/usbhist.h>
1.1 augustss 59:
1.119 drochner 60: /* UTF-8 encoding stuff */
61: #include <fs/unicode.h>
62:
1.1 augustss 63: extern int usbdebug;
64:
1.159 skrll 65: Static usbd_status usbd_ar_pipe(usbd_pipe_handle);
66: Static void usbd_start_next(usbd_pipe_handle);
1.69 augustss 67: Static usbd_status usbd_open_pipe_ival
1.162.2.1 skrll 68: (usbd_interface_handle, uint8_t, uint8_t, usbd_pipe_handle *, int);
1.1 augustss 69:
1.110 perry 70: static inline int
1.74 augustss 71: usbd_xfer_isread(usbd_xfer_handle xfer)
1.37 augustss 72: {
1.162.2.6 skrll 73: if (xfer->ux_rqflags & URQ_REQUEST)
1.162.2.9 skrll 74: return xfer->ux_request.bmRequestType & UT_READ;
1.37 augustss 75: else
1.162.2.6 skrll 76: return (xfer->ux_pipe->up_endpoint->ue_edesc->bEndpointAddress &
1.37 augustss 77: UE_DIR_IN);
78: }
79:
1.162 skrll 80: #if defined(USB_DEBUG)
1.82 augustss 81: void
82: usbd_dump_iface(struct usbd_interface *iface)
83: {
1.162 skrll 84: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
85:
1.162.2.10 skrll 86: USBHIST_LOG(usbdebug, "iface %p", iface, 0, 0, 0);
1.82 augustss 87: if (iface == NULL)
88: return;
1.162 skrll 89: USBHIST_LOG(usbdebug, " device = %p idesc = %p index = %d",
1.162.2.6 skrll 90: iface->ui_dev, iface->ui_idesc, iface->ui_index, 0);
1.162 skrll 91: USBHIST_LOG(usbdebug, " altindex=%d priv=%p",
1.162.2.6 skrll 92: iface->ui_altindex, iface->ui_priv, 0, 0);
1.82 augustss 93: }
94:
95: void
96: usbd_dump_device(struct usbd_device *dev)
97: {
1.162 skrll 98: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
99:
100: USBHIST_LOG(usbdebug, "dev = %p", dev, 0, 0, 0);
1.82 augustss 101: if (dev == NULL)
102: return;
1.162 skrll 103: USBHIST_LOG(usbdebug, " bus = %p default_pipe = %p",
1.162.2.6 skrll 104: dev->ud_bus, dev->ud_pipe0, 0, 0);
1.162 skrll 105: USBHIST_LOG(usbdebug, " address = %d config = %d depth = %d ",
1.162.2.6 skrll 106: dev->ud_addr, dev->ud_config, dev->ud_depth, 0);
1.162 skrll 107: USBHIST_LOG(usbdebug, " speed = %d self_powered = %d "
108: "power = %d langid = %d",
1.162.2.6 skrll 109: dev->ud_speed, dev->ud_selfpowered, dev->ud_power, dev->ud_langid);
1.82 augustss 110: }
111:
112: void
113: usbd_dump_endpoint(struct usbd_endpoint *endp)
114: {
1.162 skrll 115: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
116:
117: USBHIST_LOG(usbdebug, "endp = %p", endp, 0, 0, 0);
1.82 augustss 118: if (endp == NULL)
119: return;
1.162 skrll 120: USBHIST_LOG(usbdebug, " edesc = %p refcnt = %d",
1.162.2.6 skrll 121: endp->ue_edesc, endp->ue_refcnt, 0, 0);
122: if (endp->ue_edesc)
1.162 skrll 123: USBHIST_LOG(usbdebug, " bEndpointAddress=0x%02x",
1.162.2.6 skrll 124: endp->ue_edesc->bEndpointAddress, 0, 0, 0);
1.82 augustss 125: }
126:
1.28 augustss 127: void
1.74 augustss 128: usbd_dump_queue(usbd_pipe_handle pipe)
1.28 augustss 129: {
1.48 augustss 130: usbd_xfer_handle xfer;
1.28 augustss 131:
1.162 skrll 132: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
133:
134: USBHIST_LOG(usbdebug, "pipe = %p", pipe, 0, 0, 0);
1.162.2.6 skrll 135: SIMPLEQ_FOREACH(xfer, &pipe->up_queue, ux_next) {
1.162 skrll 136: USBHIST_LOG(usbdebug, " xfer = %p", xfer, 0, 0, 0);
1.28 augustss 137: }
1.82 augustss 138: }
139:
140: void
141: usbd_dump_pipe(usbd_pipe_handle pipe)
142: {
1.162 skrll 143: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
144:
145: USBHIST_LOG(usbdebug, "pipe = %p", pipe, 0, 0, 0);
1.82 augustss 146: if (pipe == NULL)
147: return;
1.162.2.6 skrll 148: usbd_dump_iface(pipe->up_iface);
149: usbd_dump_device(pipe->up_dev);
150: usbd_dump_endpoint(pipe->up_endpoint);
1.162 skrll 151: USBHIST_LOG(usbdebug, "(usbd_dump_pipe)", 0, 0, 0, 0);
152: USBHIST_LOG(usbdebug, " refcnt = %d running = %d aborting = %d",
1.162.2.6 skrll 153: pipe->up_refcnt, pipe->up_running, pipe->up_aborting, 0);
1.162 skrll 154: USBHIST_LOG(usbdebug, " intrxfer = %p, repeat = %d, interval = %d",
1.162.2.6 skrll 155: pipe->up_intrxfer, pipe->up_repeat, pipe->up_interval, 0);
1.28 augustss 156: }
157: #endif
158:
1.102 augustss 159: usbd_status
1.162.2.1 skrll 160: usbd_open_pipe(usbd_interface_handle iface, uint8_t address,
161: uint8_t flags, usbd_pipe_handle *pipe)
1.102 augustss 162: {
163: return (usbd_open_pipe_ival(iface, address, flags, pipe,
1.60 augustss 164: USBD_DEFAULT_INTERVAL));
165: }
166:
1.102 augustss 167: usbd_status
1.162.2.1 skrll 168: usbd_open_pipe_ival(usbd_interface_handle iface, uint8_t address,
169: uint8_t flags, usbd_pipe_handle *pipe, int ival)
1.102 augustss 170: {
1.1 augustss 171: usbd_pipe_handle p;
172: struct usbd_endpoint *ep;
1.48 augustss 173: usbd_status err;
1.12 augustss 174: int i;
1.1 augustss 175:
1.162 skrll 176: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
177:
178: USBHIST_LOG(usbdebug, "iface = %p address = 0x%x flags = 0x%x",
179: iface, address, flags, 0);
1.53 augustss 180:
1.162.2.6 skrll 181: for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) {
182: ep = &iface->ui_endpoints[i];
183: if (ep->ue_edesc == NULL)
1.162.2.9 skrll 184: return USBD_IOERROR;
1.162.2.6 skrll 185: if (ep->ue_edesc->bEndpointAddress == address)
1.1 augustss 186: goto found;
187: }
1.162.2.9 skrll 188: return USBD_BAD_ADDRESS;
1.1 augustss 189: found:
1.162.2.6 skrll 190: if ((flags & USBD_EXCLUSIVE_USE) && ep->ue_refcnt != 0)
1.162.2.9 skrll 191: return USBD_IN_USE;
1.162.2.6 skrll 192: err = usbd_setup_pipe_flags(iface->ui_dev, iface, ep, ival, &p, flags);
1.48 augustss 193: if (err)
1.162.2.9 skrll 194: return err;
1.162.2.6 skrll 195: LIST_INSERT_HEAD(&iface->ui_pipes, p, up_next);
1.1 augustss 196: *pipe = p;
1.162.2.9 skrll 197: return USBD_NORMAL_COMPLETION;
1.1 augustss 198: }
199:
1.102 augustss 200: usbd_status
1.162.2.1 skrll 201: usbd_open_pipe_intr(usbd_interface_handle iface, uint8_t address,
202: uint8_t flags, usbd_pipe_handle *pipe,
203: usbd_private_handle priv, void *buffer, uint32_t len,
1.74 augustss 204: usbd_callback cb, int ival)
1.1 augustss 205: {
1.48 augustss 206: usbd_status err;
207: usbd_xfer_handle xfer;
1.1 augustss 208: usbd_pipe_handle ipipe;
209:
1.162 skrll 210: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
211:
212: USBHIST_LOG(usbdebug, "address = 0x%x flags = 0x%x len = %d",
213: address, flags, len, 0);
1.53 augustss 214:
1.150 jmcneill 215: err = usbd_open_pipe_ival(iface, address,
216: USBD_EXCLUSIVE_USE | (flags & USBD_MPSAFE),
1.60 augustss 217: &ipipe, ival);
1.48 augustss 218: if (err)
1.162.2.9 skrll 219: return err;
1.162.2.6 skrll 220: xfer = usbd_alloc_xfer(iface->ui_dev);
1.48 augustss 221: if (xfer == NULL) {
222: err = USBD_NOMEM;
1.1 augustss 223: goto bad1;
1.36 augustss 224: }
1.162.2.11 skrll 225: void *buf = usbd_alloc_buffer(xfer, len);
226: if (buf == NULL) {
1.162.2.17 skrll 227: err = USBD_NOMEM;
1.162.2.11 skrll 228: goto bad2;
229: }
230:
1.60 augustss 231: usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags,
232: USBD_NO_TIMEOUT, cb);
1.162.2.6 skrll 233: ipipe->up_intrxfer = xfer;
234: ipipe->up_repeat = 1;
1.48 augustss 235: err = usbd_transfer(xfer);
1.1 augustss 236: *pipe = ipipe;
1.48 augustss 237: if (err != USBD_IN_PROGRESS)
1.162.2.11 skrll 238: goto bad3;
1.162.2.9 skrll 239: return USBD_NORMAL_COMPLETION;
1.1 augustss 240:
1.162.2.11 skrll 241: bad3:
1.162.2.6 skrll 242: ipipe->up_intrxfer = NULL;
243: ipipe->up_repeat = 0;
1.162.2.11 skrll 244: bad2:
1.50 augustss 245: usbd_free_xfer(xfer);
1.36 augustss 246: bad1:
1.1 augustss 247: usbd_close_pipe(ipipe);
1.162.2.9 skrll 248: return err;
1.9 augustss 249: }
250:
1.1 augustss 251: usbd_status
1.74 augustss 252: usbd_close_pipe(usbd_pipe_handle pipe)
1.1 augustss 253: {
1.138 mrg 254:
1.162 skrll 255: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
256:
1.26 augustss 257: #ifdef DIAGNOSTIC
1.48 augustss 258: if (pipe == NULL) {
1.162 skrll 259: USBHIST_LOG(usbdebug, "pipe == NULL", 0, 0, 0, 0);
1.162.2.9 skrll 260: return USBD_NORMAL_COMPLETION;
1.26 augustss 261: }
262: #endif
263:
1.138 mrg 264: usbd_lock_pipe(pipe);
1.162.2.6 skrll 265: if (--pipe->up_refcnt != 0) {
1.138 mrg 266: usbd_unlock_pipe(pipe);
1.162.2.9 skrll 267: return USBD_NORMAL_COMPLETION;
1.138 mrg 268: }
1.162.2.6 skrll 269: if (! SIMPLEQ_EMPTY(&pipe->up_queue)) {
1.138 mrg 270: usbd_unlock_pipe(pipe);
1.162.2.9 skrll 271: return USBD_PENDING_REQUESTS;
1.138 mrg 272: }
1.162.2.6 skrll 273: LIST_REMOVE(pipe, up_next);
274: pipe->up_endpoint->ue_refcnt--;
275: pipe->up_methods->upm_close(pipe);
1.138 mrg 276: usbd_unlock_pipe(pipe);
1.162.2.13 skrll 277: if (pipe->up_intrxfer != NULL)
1.162.2.6 skrll 278: usbd_free_xfer(pipe->up_intrxfer);
1.162.2.7 skrll 279: kmem_free(pipe, pipe->up_dev->ud_bus->ub_pipesize);
1.162.2.9 skrll 280: return USBD_NORMAL_COMPLETION;
1.1 augustss 281: }
282:
1.31 augustss 283: usbd_status
1.74 augustss 284: usbd_transfer(usbd_xfer_handle xfer)
1.1 augustss 285: {
1.162.2.6 skrll 286: usbd_pipe_handle pipe = xfer->ux_pipe;
1.48 augustss 287: usbd_status err;
1.120 kiyohara 288: unsigned int size, flags;
1.16 augustss 289:
1.162 skrll 290: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
291:
292: USBHIST_LOG(usbdebug,
293: "xfer = %p, flags = %#x, pipe = %p, running = %d",
1.162.2.6 skrll 294: xfer, xfer->ux_flags, pipe, pipe->up_running);
1.134 jmcneill 295:
1.28 augustss 296: #ifdef USB_DEBUG
297: if (usbdebug > 5)
298: usbd_dump_queue(pipe);
299: #endif
1.162.2.6 skrll 300: xfer->ux_done = 0;
1.31 augustss 301:
1.162.2.6 skrll 302: if (pipe->up_aborting) {
1.162 skrll 303: USBHIST_LOG(usbdebug, "<- done xfer %p, aborting", xfer, 0, 0,
304: 0);
1.162.2.9 skrll 305: return USBD_CANCELLED;
1.162 skrll 306: }
1.71 augustss 307:
1.162.2.11 skrll 308: KASSERT(xfer->ux_length == 0 || xfer->ux_buf != NULL);
1.162.2.5 skrll 309:
1.162.2.6 skrll 310: size = xfer->ux_length;
311: flags = xfer->ux_flags;
1.162.2.5 skrll 312:
1.162.2.11 skrll 313: struct usbd_bus *bus = pipe->up_dev->ud_bus;
1.37 augustss 314:
1.162.2.6 skrll 315: if (bus->ub_usedma) {
1.162.2.5 skrll 316: /*
317: * Copy data if not using the xfer buffer. isoc transfers
318: * always use DMA buffer, i.e. buffer == NULL
319: */
1.162.2.6 skrll 320: if (xfer->ux_buffer == NULL) {
321: xfer->ux_buffer = xfer->ux_buf;
322: } else if (xfer->ux_buffer != xfer->ux_buf) {
323: memcpy(xfer->ux_buf, xfer->ux_buffer, size);
1.162.2.5 skrll 324: }
325: } else {
1.162.2.6 skrll 326: xfer->ux_buffer = xfer->ux_buf;
1.162.2.5 skrll 327: }
1.37 augustss 328:
1.120 kiyohara 329: /* xfer is not valid after the transfer method unless synchronous */
1.162.2.6 skrll 330: err = pipe->up_methods->upm_transfer(xfer);
1.162 skrll 331: USBHIST_LOG(usbdebug, "<- done transfer %p, err = %d", xfer, err, 0, 0);
1.37 augustss 332:
1.162 skrll 333: if (!(flags & USBD_SYNCHRONOUS)) {
334: USBHIST_LOG(usbdebug, "<- done xfer %p, not sync", xfer, 0, 0,
335: 0);
1.162.2.9 skrll 336: return err;
1.162 skrll 337: }
1.31 augustss 338:
339: /* Sync transfer, wait for completion. */
1.162 skrll 340: if (err != USBD_IN_PROGRESS) {
1.162.2.14 skrll 341: USBHIST_LOG(usbdebug, "<- done xfer %p, err %d (complete/error)", xfer,
1.162.2.15 skrll 342: err, 0, 0);
1.162.2.9 skrll 343: return err;
1.162 skrll 344: }
1.138 mrg 345: usbd_lock_pipe(pipe);
1.162.2.6 skrll 346: while (!xfer->ux_done) {
347: if (pipe->up_dev->ud_bus->ub_usepolling)
1.103 provos 348: panic("usbd_transfer: not done");
1.162 skrll 349: USBHIST_LOG(usbdebug, "<- sleeping on xfer %p", xfer, 0, 0, 0);
1.138 mrg 350:
1.144 christos 351: err = 0;
1.138 mrg 352: if ((flags & USBD_SYNCHRONOUS_SIG) != 0) {
1.162.2.6 skrll 353: err = cv_wait_sig(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock);
1.138 mrg 354: } else {
1.162.2.6 skrll 355: cv_wait(&xfer->ux_cv, pipe->up_dev->ud_bus->ub_lock);
1.138 mrg 356: }
1.154 aymeric 357: if (err) {
1.162.2.6 skrll 358: if (!xfer->ux_done)
359: pipe->up_methods->upm_abort(xfer);
1.144 christos 360: break;
1.154 aymeric 361: }
1.31 augustss 362: }
1.138 mrg 363: usbd_unlock_pipe(pipe);
1.162.2.9 skrll 364: return xfer->ux_status;
1.31 augustss 365: }
366:
367: /* Like usbd_transfer(), but waits for completion. */
368: usbd_status
1.74 augustss 369: usbd_sync_transfer(usbd_xfer_handle xfer)
1.31 augustss 370: {
1.162.2.6 skrll 371: xfer->ux_flags |= USBD_SYNCHRONOUS;
1.162.2.9 skrll 372: return usbd_transfer(xfer);
1.16 augustss 373: }
374:
1.138 mrg 375: /* Like usbd_transfer(), but waits for completion and listens for signals. */
376: usbd_status
377: usbd_sync_transfer_sig(usbd_xfer_handle xfer)
378: {
1.162.2.6 skrll 379: xfer->ux_flags |= USBD_SYNCHRONOUS | USBD_SYNCHRONOUS_SIG;
1.162.2.9 skrll 380: return usbd_transfer(xfer);
1.138 mrg 381: }
382:
1.36 augustss 383: void *
1.162.2.1 skrll 384: usbd_alloc_buffer(usbd_xfer_handle xfer, uint32_t size)
1.36 augustss 385: {
1.162.2.5 skrll 386:
1.162.2.6 skrll 387: KASSERT(xfer->ux_buf == NULL);
1.162.2.5 skrll 388: KASSERT(size != 0);
389:
1.162.2.6 skrll 390: xfer->ux_bufsize = 0;
1.162.2.5 skrll 391: #if NUSB_DMA > 0
1.162.2.6 skrll 392: struct usbd_bus *bus = xfer->ux_dev->ud_bus;
1.37 augustss 393:
1.162.2.6 skrll 394: if (bus->ub_usedma) {
395: usb_dma_t *dmap = &xfer->ux_dmabuf;
1.162.2.5 skrll 396:
1.162.2.6 skrll 397: int err = usb_allocmem_flags(bus, size, 0, dmap, bus->ub_dmaflags);
1.162.2.5 skrll 398: if (err) {
399: return NULL;
400: }
1.162.2.6 skrll 401: xfer->ux_buf = KERNADDR(&xfer->ux_dmabuf, 0);
402: xfer->ux_bufsize = size;
1.162.2.5 skrll 403:
1.162.2.6 skrll 404: return xfer->ux_buf;
1.162.2.5 skrll 405: }
1.92 augustss 406: #endif
1.162.2.6 skrll 407: KASSERT(xfer->ux_dev->ud_bus->ub_usedma == false);
408: xfer->ux_buf = kmem_alloc(size, KM_SLEEP);
1.162.2.5 skrll 409:
1.162.2.6 skrll 410: if (xfer->ux_buf != NULL) {
411: xfer->ux_bufsize = size;
1.162.2.5 skrll 412: }
413:
1.162.2.6 skrll 414: return xfer->ux_buf;
1.36 augustss 415: }
416:
417: void
1.74 augustss 418: usbd_free_buffer(usbd_xfer_handle xfer)
1.36 augustss 419: {
1.162.2.6 skrll 420: KASSERT(xfer->ux_buf != NULL);
421: KASSERT(xfer->ux_bufsize != 0);
1.162.2.5 skrll 422:
1.162.2.6 skrll 423: void *buf = xfer->ux_buf;
424: uint32_t size = xfer->ux_bufsize;
1.162.2.5 skrll 425:
1.162.2.6 skrll 426: xfer->ux_buf = NULL;
427: xfer->ux_bufsize = 0;
1.162.2.5 skrll 428:
429: #if NUSB_DMA > 0
1.162.2.6 skrll 430: struct usbd_bus *bus = xfer->ux_dev->ud_bus;
1.162.2.5 skrll 431:
1.162.2.6 skrll 432: if (bus->ub_usedma) {
433: usb_dma_t *dmap = &xfer->ux_dmabuf;
1.162.2.5 skrll 434:
435: usb_freemem(bus, dmap);
1.37 augustss 436: return;
437: }
438: #endif
1.162.2.6 skrll 439: KASSERT(xfer->ux_dev->ud_bus->ub_usedma == false);
1.162.2.5 skrll 440:
441: kmem_free(buf, size);
1.36 augustss 442: }
443:
1.38 augustss 444: void *
1.74 augustss 445: usbd_get_buffer(usbd_xfer_handle xfer)
1.38 augustss 446: {
1.162.2.5 skrll 447:
1.162.2.6 skrll 448: return xfer->ux_buf;
1.38 augustss 449: }
450:
1.102 augustss 451: usbd_xfer_handle
1.74 augustss 452: usbd_alloc_xfer(usbd_device_handle dev)
1.1 augustss 453: {
1.48 augustss 454: usbd_xfer_handle xfer;
1.1 augustss 455:
1.162 skrll 456: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
457:
1.162.2.3 skrll 458: ASSERT_SLEEPABLE();
459:
1.162.2.6 skrll 460: xfer = dev->ud_bus->ub_methods->ubm_allocx(dev->ud_bus);
1.48 augustss 461: if (xfer == NULL)
1.162.2.9 skrll 462: return NULL;
1.162.2.6 skrll 463: xfer->ux_dev = dev;
464: callout_init(&xfer->ux_callout, CALLOUT_MPSAFE);
465: cv_init(&xfer->ux_cv, "usbxfer");
466: cv_init(&xfer->ux_hccv, "usbhcxfer");
1.162 skrll 467:
468: USBHIST_LOG(usbdebug, "returns %p", xfer, 0, 0, 0);
469:
1.162.2.9 skrll 470: return xfer;
1.1 augustss 471: }
472:
1.102 augustss 473: usbd_status
1.74 augustss 474: usbd_free_xfer(usbd_xfer_handle xfer)
1.1 augustss 475: {
1.162 skrll 476: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
477:
478: USBHIST_LOG(usbdebug, "%p", xfer, 0, 0, 0);
1.162.2.6 skrll 479: if (xfer->ux_buf) {
1.48 augustss 480: usbd_free_buffer(xfer);
1.162.2.5 skrll 481: }
1.123 drochner 482: #if defined(DIAGNOSTIC)
1.162.2.6 skrll 483: if (callout_pending(&xfer->ux_callout)) {
484: callout_stop(&xfer->ux_callout);
1.140 skrll 485: printf("usbd_free_xfer: timeout_handle pending\n");
1.68 augustss 486: }
1.66 thorpej 487: #endif
1.162.2.6 skrll 488: cv_destroy(&xfer->ux_cv);
489: cv_destroy(&xfer->ux_hccv);
490: xfer->ux_dev->ud_bus->ub_methods->ubm_freex(xfer->ux_dev->ud_bus, xfer);
1.162.2.9 skrll 491: return USBD_NORMAL_COMPLETION;
1.1 augustss 492: }
493:
1.36 augustss 494: void
1.74 augustss 495: usbd_setup_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
1.162.2.1 skrll 496: usbd_private_handle priv, void *buffer, uint32_t length,
497: uint16_t flags, uint32_t timeout,
1.74 augustss 498: usbd_callback callback)
1.1 augustss 499: {
1.162.2.6 skrll 500: xfer->ux_pipe = pipe;
501: xfer->ux_priv = priv;
502: xfer->ux_buffer = buffer;
503: xfer->ux_length = length;
504: xfer->ux_actlen = 0;
505: xfer->ux_flags = flags;
506: xfer->ux_timeout = timeout;
507: xfer->ux_status = USBD_NOT_STARTED;
508: xfer->ux_callback = callback;
509: xfer->ux_rqflags &= ~URQ_REQUEST;
510: xfer->ux_nframes = 0;
1.1 augustss 511: }
512:
1.36 augustss 513: void
1.74 augustss 514: usbd_setup_default_xfer(usbd_xfer_handle xfer, usbd_device_handle dev,
1.162.2.1 skrll 515: usbd_private_handle priv, uint32_t timeout,
1.74 augustss 516: usb_device_request_t *req, void *buffer,
1.162.2.1 skrll 517: uint32_t length, uint16_t flags,
1.74 augustss 518: usbd_callback callback)
1.1 augustss 519: {
1.162.2.6 skrll 520: xfer->ux_pipe = dev->ud_pipe0;
521: xfer->ux_priv = priv;
522: xfer->ux_buffer = buffer;
523: xfer->ux_length = length;
524: xfer->ux_actlen = 0;
525: xfer->ux_flags = flags;
526: xfer->ux_timeout = timeout;
527: xfer->ux_status = USBD_NOT_STARTED;
528: xfer->ux_callback = callback;
529: xfer->ux_request = *req;
530: xfer->ux_rqflags |= URQ_REQUEST;
531: xfer->ux_nframes = 0;
1.36 augustss 532: }
533:
534: void
1.74 augustss 535: usbd_setup_isoc_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe,
1.162.2.1 skrll 536: usbd_private_handle priv, uint16_t *frlengths,
537: uint32_t nframes, uint16_t flags, usbd_callback callback)
1.36 augustss 538: {
1.162.2.6 skrll 539: xfer->ux_pipe = pipe;
540: xfer->ux_priv = priv;
541: xfer->ux_buffer = 0;
542: xfer->ux_length = 0;
543: xfer->ux_actlen = 0;
544: xfer->ux_flags = flags;
545: xfer->ux_timeout = USBD_NO_TIMEOUT;
546: xfer->ux_status = USBD_NOT_STARTED;
547: xfer->ux_callback = callback;
548: xfer->ux_rqflags &= ~URQ_REQUEST;
549: xfer->ux_frlengths = frlengths;
550: xfer->ux_nframes = nframes;
1.1 augustss 551: }
552:
1.31 augustss 553: void
1.74 augustss 554: usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv,
1.162.2.1 skrll 555: void **buffer, uint32_t *count, usbd_status *status)
1.1 augustss 556: {
1.48 augustss 557: if (priv != NULL)
1.162.2.6 skrll 558: *priv = xfer->ux_priv;
1.48 augustss 559: if (buffer != NULL)
1.162.2.6 skrll 560: *buffer = xfer->ux_buffer;
1.48 augustss 561: if (count != NULL)
1.162.2.6 skrll 562: *count = xfer->ux_actlen;
1.48 augustss 563: if (status != NULL)
1.162.2.6 skrll 564: *status = xfer->ux_status;
1.1 augustss 565: }
566:
567: usb_config_descriptor_t *
1.74 augustss 568: usbd_get_config_descriptor(usbd_device_handle dev)
1.1 augustss 569: {
1.53 augustss 570: #ifdef DIAGNOSTIC
571: if (dev == NULL) {
572: printf("usbd_get_config_descriptor: dev == NULL\n");
1.162.2.9 skrll 573: return NULL;
1.53 augustss 574: }
575: #endif
1.162.2.9 skrll 576: return dev->ud_cdesc;
1.1 augustss 577: }
578:
579: usb_interface_descriptor_t *
1.74 augustss 580: usbd_get_interface_descriptor(usbd_interface_handle iface)
1.1 augustss 581: {
1.53 augustss 582: #ifdef DIAGNOSTIC
583: if (iface == NULL) {
584: printf("usbd_get_interface_descriptor: dev == NULL\n");
1.162.2.9 skrll 585: return NULL;
1.53 augustss 586: }
587: #endif
1.162.2.9 skrll 588: return iface->ui_idesc;
1.1 augustss 589: }
590:
591: usb_device_descriptor_t *
1.74 augustss 592: usbd_get_device_descriptor(usbd_device_handle dev)
1.1 augustss 593: {
1.162.2.9 skrll 594: return &dev->ud_ddesc;
1.1 augustss 595: }
596:
597: usb_endpoint_descriptor_t *
1.162.2.1 skrll 598: usbd_interface2endpoint_descriptor(usbd_interface_handle iface, uint8_t index)
1.1 augustss 599: {
1.162.2.6 skrll 600: if (index >= iface->ui_idesc->bNumEndpoints)
1.162.2.9 skrll 601: return NULL;
602: return iface->ui_endpoints[index].ue_edesc;
1.1 augustss 603: }
604:
1.125 jmorse 605: /* Some drivers may wish to abort requests on the default pipe, *
606: * but there is no mechanism for getting a handle on it. */
607: usbd_status
608: usbd_abort_default_pipe(struct usbd_device *device)
609: {
610:
1.162.2.6 skrll 611: return usbd_abort_pipe(device->ud_pipe0);
1.125 jmorse 612: }
613:
1.102 augustss 614: usbd_status
1.74 augustss 615: usbd_abort_pipe(usbd_pipe_handle pipe)
1.1 augustss 616: {
1.48 augustss 617: usbd_status err;
1.1 augustss 618:
1.26 augustss 619: #ifdef DIAGNOSTIC
1.48 augustss 620: if (pipe == NULL) {
1.126 uebayasi 621: printf("usbd_abort_pipe: pipe==NULL\n");
1.162.2.9 skrll 622: return USBD_NORMAL_COMPLETION;
1.26 augustss 623: }
624: #endif
1.138 mrg 625: usbd_lock_pipe(pipe);
1.48 augustss 626: err = usbd_ar_pipe(pipe);
1.138 mrg 627: usbd_unlock_pipe(pipe);
1.162.2.9 skrll 628: return err;
1.1 augustss 629: }
1.102 augustss 630:
631: usbd_status
1.74 augustss 632: usbd_clear_endpoint_stall(usbd_pipe_handle pipe)
1.1 augustss 633: {
1.162.2.6 skrll 634: usbd_device_handle dev = pipe->up_dev;
1.1 augustss 635: usb_device_request_t req;
1.48 augustss 636: usbd_status err;
1.1 augustss 637:
1.162 skrll 638: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1.33 augustss 639:
1.102 augustss 640: /*
1.87 augustss 641: * Clearing en endpoint stall resets the endpoint toggle, so
1.33 augustss 642: * do the same to the HC toggle.
643: */
1.162.2.6 skrll 644: pipe->up_methods->upm_cleartoggle(pipe);
1.33 augustss 645:
1.1 augustss 646: req.bmRequestType = UT_WRITE_ENDPOINT;
647: req.bRequest = UR_CLEAR_FEATURE;
1.15 augustss 648: USETW(req.wValue, UF_ENDPOINT_HALT);
1.162.2.6 skrll 649: USETW(req.wIndex, pipe->up_endpoint->ue_edesc->bEndpointAddress);
1.1 augustss 650: USETW(req.wLength, 0);
1.48 augustss 651: err = usbd_do_request(dev, &req, 0);
1.1 augustss 652: #if 0
653: XXX should we do this?
1.51 augustss 654: if (!err) {
1.1 augustss 655: pipe->state = USBD_PIPE_ACTIVE;
656: /* XXX activate pipe */
657: }
658: #endif
1.162.2.9 skrll 659: return err;
1.1 augustss 660: }
661:
1.139 mrg 662: void
1.156 skrll 663: usbd_clear_endpoint_stall_task(void *arg)
1.7 augustss 664: {
1.139 mrg 665: usbd_pipe_handle pipe = arg;
1.162.2.6 skrll 666: usbd_device_handle dev = pipe->up_dev;
1.7 augustss 667: usb_device_request_t req;
668:
1.162.2.6 skrll 669: pipe->up_methods->upm_cleartoggle(pipe);
1.33 augustss 670:
1.7 augustss 671: req.bmRequestType = UT_WRITE_ENDPOINT;
672: req.bRequest = UR_CLEAR_FEATURE;
1.15 augustss 673: USETW(req.wValue, UF_ENDPOINT_HALT);
1.162.2.6 skrll 674: USETW(req.wIndex, pipe->up_endpoint->ue_edesc->bEndpointAddress);
1.7 augustss 675: USETW(req.wLength, 0);
1.156 skrll 676: (void)usbd_do_request(dev, &req, 0);
1.139 mrg 677: }
678:
679: void
680: usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe)
681: {
682:
1.162.2.6 skrll 683: usb_add_task(pipe->up_dev, &pipe->up_async_task, USB_TASKQ_DRIVER);
1.7 augustss 684: }
685:
1.61 augustss 686: void
1.74 augustss 687: usbd_clear_endpoint_toggle(usbd_pipe_handle pipe)
1.61 augustss 688: {
1.162.2.6 skrll 689: pipe->up_methods->upm_cleartoggle(pipe);
1.61 augustss 690: }
691:
1.102 augustss 692: usbd_status
1.162.2.1 skrll 693: usbd_endpoint_count(usbd_interface_handle iface, uint8_t *count)
1.1 augustss 694: {
1.73 augustss 695: #ifdef DIAGNOSTIC
1.162.2.6 skrll 696: if (iface == NULL || iface->ui_idesc == NULL) {
1.73 augustss 697: printf("usbd_endpoint_count: NULL pointer\n");
1.162.2.9 skrll 698: return USBD_INVAL;
1.73 augustss 699: }
700: #endif
1.162.2.6 skrll 701: *count = iface->ui_idesc->bNumEndpoints;
1.162.2.9 skrll 702: return USBD_NORMAL_COMPLETION;
1.1 augustss 703: }
704:
1.102 augustss 705: usbd_status
1.162.2.1 skrll 706: usbd_interface_count(usbd_device_handle dev, uint8_t *count)
1.1 augustss 707: {
1.162.2.6 skrll 708: if (dev->ud_cdesc == NULL)
1.162.2.9 skrll 709: return USBD_NOT_CONFIGURED;
1.162.2.6 skrll 710: *count = dev->ud_cdesc->bNumInterface;
1.162.2.9 skrll 711: return USBD_NORMAL_COMPLETION;
1.1 augustss 712: }
713:
1.85 augustss 714: void
1.74 augustss 715: usbd_interface2device_handle(usbd_interface_handle iface,
716: usbd_device_handle *dev)
1.1 augustss 717: {
1.162.2.6 skrll 718: *dev = iface->ui_dev;
1.1 augustss 719: }
720:
1.102 augustss 721: usbd_status
1.74 augustss 722: usbd_device2interface_handle(usbd_device_handle dev,
1.162.2.1 skrll 723: uint8_t ifaceno, usbd_interface_handle *iface)
1.1 augustss 724: {
1.162.2.6 skrll 725: if (dev->ud_cdesc == NULL)
1.162.2.9 skrll 726: return USBD_NOT_CONFIGURED;
1.162.2.6 skrll 727: if (ifaceno >= dev->ud_cdesc->bNumInterface)
1.162.2.9 skrll 728: return USBD_INVAL;
1.162.2.6 skrll 729: *iface = &dev->ud_ifaces[ifaceno];
1.162.2.9 skrll 730: return USBD_NORMAL_COMPLETION;
1.1 augustss 731: }
732:
1.36 augustss 733: usbd_device_handle
1.74 augustss 734: usbd_pipe2device_handle(usbd_pipe_handle pipe)
1.36 augustss 735: {
1.162.2.9 skrll 736: return pipe->up_dev;
1.36 augustss 737: }
738:
1.13 augustss 739: /* XXXX use altno */
1.3 augustss 740: usbd_status
1.74 augustss 741: usbd_set_interface(usbd_interface_handle iface, int altidx)
1.3 augustss 742: {
743: usb_device_request_t req;
1.48 augustss 744: usbd_status err;
1.73 augustss 745: void *endpoints;
1.13 augustss 746:
1.162.2.6 skrll 747: if (LIST_FIRST(&iface->ui_pipes) != 0)
1.162.2.9 skrll 748: return USBD_IN_USE;
1.13 augustss 749:
1.162.2.6 skrll 750: endpoints = iface->ui_endpoints;
1.162.2.19! skrll 751: int nendpt = iface->ui_idesc->bNumEndpoints;
1.162.2.6 skrll 752: err = usbd_fill_iface_data(iface->ui_dev, iface->ui_index, altidx);
1.48 augustss 753: if (err)
1.162.2.9 skrll 754: return err;
1.73 augustss 755:
1.76 augustss 756: /* new setting works, we can free old endpoints */
1.162.2.7 skrll 757: if (endpoints != NULL) {
758: kmem_free(endpoints, nendpt * sizeof(struct usbd_endpoint));
759: }
1.73 augustss 760:
761: #ifdef DIAGNOSTIC
1.162.2.6 skrll 762: if (iface->ui_idesc == NULL) {
1.73 augustss 763: printf("usbd_set_interface: NULL pointer\n");
1.162.2.9 skrll 764: return USBD_INVAL;
1.73 augustss 765: }
766: #endif
1.3 augustss 767:
768: req.bmRequestType = UT_WRITE_INTERFACE;
769: req.bRequest = UR_SET_INTERFACE;
1.162.2.6 skrll 770: USETW(req.wValue, iface->ui_idesc->bAlternateSetting);
771: USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber);
1.3 augustss 772: USETW(req.wLength, 0);
1.162.2.9 skrll 773: return usbd_do_request(iface->ui_dev, &req, 0);
1.12 augustss 774: }
775:
776: int
1.74 augustss 777: usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno)
1.12 augustss 778: {
1.13 augustss 779: char *p = (char *)cdesc;
780: char *end = p + UGETW(cdesc->wTotalLength);
1.12 augustss 781: usb_interface_descriptor_t *d;
782: int n;
783:
784: for (n = 0; p < end; p += d->bLength) {
785: d = (usb_interface_descriptor_t *)p;
1.102 augustss 786: if (p + d->bLength <= end &&
1.12 augustss 787: d->bDescriptorType == UDESC_INTERFACE &&
1.13 augustss 788: d->bInterfaceNumber == ifaceno)
1.12 augustss 789: n++;
790: }
1.162.2.9 skrll 791: return n;
1.13 augustss 792: }
793:
794: int
1.74 augustss 795: usbd_get_interface_altindex(usbd_interface_handle iface)
1.13 augustss 796: {
1.162.2.9 skrll 797: return iface->ui_altindex;
1.12 augustss 798: }
799:
800: usbd_status
1.162.2.1 skrll 801: usbd_get_interface(usbd_interface_handle iface, uint8_t *aiface)
1.12 augustss 802: {
803: usb_device_request_t req;
804:
805: req.bmRequestType = UT_READ_INTERFACE;
806: req.bRequest = UR_GET_INTERFACE;
807: USETW(req.wValue, 0);
1.162.2.6 skrll 808: USETW(req.wIndex, iface->ui_idesc->bInterfaceNumber);
1.12 augustss 809: USETW(req.wLength, 1);
1.162.2.9 skrll 810: return usbd_do_request(iface->ui_dev, &req, aiface);
1.3 augustss 811: }
1.1 augustss 812:
813: /*** Internal routines ***/
814:
815: /* Dequeue all pipe operations, called at splusb(). */
1.69 augustss 816: Static usbd_status
1.74 augustss 817: usbd_ar_pipe(usbd_pipe_handle pipe)
1.1 augustss 818: {
1.48 augustss 819: usbd_xfer_handle xfer;
1.1 augustss 820:
1.162 skrll 821: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
822:
1.162.2.6 skrll 823: KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1.138 mrg 824:
1.162 skrll 825: USBHIST_LOG(usbdebug, "pipe = %p", pipe, 0, 0, 0);
1.28 augustss 826: #ifdef USB_DEBUG
827: if (usbdebug > 5)
828: usbd_dump_queue(pipe);
829: #endif
1.162.2.6 skrll 830: pipe->up_repeat = 0;
831: pipe->up_aborting = 1;
832: while ((xfer = SIMPLEQ_FIRST(&pipe->up_queue)) != NULL) {
1.162 skrll 833: USBHIST_LOG(usbdebug, "pipe = %p xfer = %p (methods = %p)",
1.162.2.6 skrll 834: pipe, xfer, pipe->up_methods, 0);
1.28 augustss 835: /* Make the HC abort it (and invoke the callback). */
1.162.2.6 skrll 836: pipe->up_methods->upm_abort(xfer);
1.33 augustss 837: /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */
1.20 augustss 838: }
1.162.2.6 skrll 839: pipe->up_aborting = 0;
1.162.2.9 skrll 840: return USBD_NORMAL_COMPLETION;
1.1 augustss 841: }
842:
1.138 mrg 843: /* Called with USB lock held. */
1.31 augustss 844: void
1.74 augustss 845: usb_transfer_complete(usbd_xfer_handle xfer)
1.1 augustss 846: {
1.162.2.6 skrll 847: usbd_pipe_handle pipe = xfer->ux_pipe;
848: struct usbd_bus *bus = pipe->up_dev->ud_bus;
849: int sync = xfer->ux_flags & USBD_SYNCHRONOUS;
850: int erred = xfer->ux_status == USBD_CANCELLED ||
851: xfer->ux_status == USBD_TIMEOUT;
852: int polling = bus->ub_usepolling;
1.152 skrll 853: int repeat;
1.31 augustss 854:
1.162 skrll 855: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
856:
857: USBHIST_LOG(usbdebug, "pipe = %p xfer = %p status = %d actlen = %d",
1.162.2.6 skrll 858: pipe, xfer, xfer->ux_status, xfer->ux_actlen);
1.134 jmcneill 859:
1.162.2.6 skrll 860: KASSERT(polling || mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1.134 jmcneill 861:
1.93 augustss 862: #ifdef DIAGNOSTIC
1.162.2.6 skrll 863: if (xfer->ux_state != XFER_ONQU) {
1.147 skrll 864: printf("usb_transfer_complete: xfer=%p not queued 0x%08x\n",
1.162.2.6 skrll 865: xfer, xfer->ux_state);
1.93 augustss 866: }
867: #endif
1.5 augustss 868:
1.23 augustss 869: #ifdef DIAGNOSTIC
1.48 augustss 870: if (pipe == NULL) {
1.138 mrg 871: printf("usb_transfer_complete: pipe==0, xfer=%p\n", xfer);
1.31 augustss 872: return;
873: }
1.23 augustss 874: #endif
1.162.2.6 skrll 875: repeat = pipe->up_repeat;
1.31 augustss 876: /* XXXX */
877: if (polling)
1.162.2.6 skrll 878: pipe->up_running = 0;
1.31 augustss 879:
1.162.2.6 skrll 880: if (xfer->ux_buffer != xfer->ux_buf) {
1.162.2.5 skrll 881: /* can only be different for DMA busses */
1.162.2.6 skrll 882: KASSERT(bus->ub_usedma);
883: KDASSERTMSG(xfer->ux_actlen <= xfer->ux_length,
884: "actlen %d length %d",xfer->ux_actlen, xfer->ux_length);
1.162.2.5 skrll 885:
1.162.2.6 skrll 886: memcpy(xfer->ux_buffer, xfer->ux_buf, xfer->ux_actlen);
1.43 augustss 887: }
1.38 augustss 888:
1.37 augustss 889:
1.47 augustss 890: if (!repeat) {
891: /* Remove request from queue. */
1.153 jakllsch 892:
1.162.2.6 skrll 893: KASSERTMSG(!SIMPLEQ_EMPTY(&pipe->up_queue),
1.145 skrll 894: "pipe %p is empty, but xfer %p wants to complete", pipe,
895: xfer);
1.47 augustss 896: #ifdef DIAGNOSTIC
1.162.2.6 skrll 897: if (xfer != SIMPLEQ_FIRST(&pipe->up_queue))
1.145 skrll 898: printf("%s: bad dequeue %p != %p\n", __func__,
1.162.2.6 skrll 899: xfer, SIMPLEQ_FIRST(&pipe->up_queue));
900: xfer->ux_state = XFER_BUSY;
1.45 augustss 901: #endif
1.162.2.6 skrll 902: SIMPLEQ_REMOVE_HEAD(&pipe->up_queue, ux_next);
1.47 augustss 903: }
1.162 skrll 904: USBHIST_LOG(usbdebug, "xfer %p: repeat %d new head = %p",
1.162.2.6 skrll 905: xfer, repeat, SIMPLEQ_FIRST(&pipe->up_queue), 0);
1.31 augustss 906:
907: /* Count completed transfers. */
1.162.2.6 skrll 908: ++pipe->up_dev->ud_bus->ub_stats.uds_requests
909: [pipe->up_endpoint->ue_edesc->bmAttributes & UE_XFERTYPE];
1.1 augustss 910:
1.162.2.6 skrll 911: xfer->ux_done = 1;
912: if (!xfer->ux_status && xfer->ux_actlen < xfer->ux_length &&
913: !(xfer->ux_flags & USBD_SHORT_XFER_OK)) {
1.162 skrll 914: USBHIST_LOG(usbdebug, "short transfer %d < %d",
1.162.2.6 skrll 915: xfer->ux_actlen, xfer->ux_length, 0, 0);
916: xfer->ux_status = USBD_SHORT_XFER;
1.1 augustss 917: }
1.31 augustss 918:
1.124 jmcneill 919: if (repeat) {
1.162 skrll 920: USBHIST_LOG(usbdebug, "xfer %p doing callback %p status %x",
1.162.2.6 skrll 921: xfer, xfer->ux_callback, xfer->ux_status, 0);
922: if (xfer->ux_callback) {
1.158 skrll 923: if (!polling)
1.162.2.6 skrll 924: mutex_exit(pipe->up_dev->ud_bus->ub_lock);
1.148 jmcneill 925:
1.162.2.6 skrll 926: if (!(pipe->up_flags & USBD_MPSAFE))
1.148 jmcneill 927: KERNEL_LOCK(1, curlwp);
1.162.2.6 skrll 928: xfer->ux_callback(xfer, xfer->ux_priv, xfer->ux_status);
1.162 skrll 929: USBHIST_LOG(usbdebug, "xfer %p doing done %p", xfer,
1.162.2.6 skrll 930: pipe->up_methods->upm_done, 0, 0);
931: if (!(pipe->up_flags & USBD_MPSAFE))
1.148 jmcneill 932: KERNEL_UNLOCK_ONE(curlwp);
933:
1.158 skrll 934: if (!polling)
1.162.2.6 skrll 935: mutex_enter(pipe->up_dev->ud_bus->ub_lock);
1.138 mrg 936: }
1.162.2.6 skrll 937: pipe->up_methods->upm_done(xfer);
1.124 jmcneill 938: } else {
1.162 skrll 939: USBHIST_LOG(usbdebug, "xfer %p doing done %p", xfer,
1.162.2.6 skrll 940: pipe->up_methods->upm_done, 0, 0);
941: pipe->up_methods->upm_done(xfer);
1.162 skrll 942: USBHIST_LOG(usbdebug, "xfer %p doing callback %p status %x",
1.162.2.6 skrll 943: xfer, xfer->ux_callback, xfer->ux_status, 0);
944: if (xfer->ux_callback) {
1.158 skrll 945: if (!polling)
1.162.2.6 skrll 946: mutex_exit(pipe->up_dev->ud_bus->ub_lock);
1.148 jmcneill 947:
1.162.2.6 skrll 948: if (!(pipe->up_flags & USBD_MPSAFE))
1.148 jmcneill 949: KERNEL_LOCK(1, curlwp);
1.162.2.6 skrll 950: xfer->ux_callback(xfer, xfer->ux_priv, xfer->ux_status);
951: if (!(pipe->up_flags & USBD_MPSAFE))
1.148 jmcneill 952: KERNEL_UNLOCK_ONE(curlwp);
953:
1.158 skrll 954: if (!polling)
1.162.2.6 skrll 955: mutex_enter(pipe->up_dev->ud_bus->ub_lock);
1.138 mrg 956: }
1.124 jmcneill 957: }
1.31 augustss 958:
1.138 mrg 959: if (sync && !polling) {
1.162 skrll 960: USBHIST_LOG(usbdebug, "<- done xfer %p, wakeup", xfer, 0, 0, 0);
1.162.2.6 skrll 961: cv_broadcast(&xfer->ux_cv);
1.138 mrg 962: }
1.31 augustss 963:
1.47 augustss 964: if (!repeat) {
1.40 augustss 965: /* XXX should we stop the queue on all errors? */
1.162.2.6 skrll 966: if (erred && pipe->up_iface != NULL) /* not control pipe */
967: pipe->up_running = 0;
1.40 augustss 968: else
969: usbd_start_next(pipe);
970: }
1.1 augustss 971: }
972:
1.138 mrg 973: /* Called with USB lock held. */
1.31 augustss 974: usbd_status
1.74 augustss 975: usb_insert_transfer(usbd_xfer_handle xfer)
1.1 augustss 976: {
1.162.2.6 skrll 977: usbd_pipe_handle pipe = xfer->ux_pipe;
1.48 augustss 978: usbd_status err;
1.31 augustss 979:
1.162 skrll 980: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
981:
982: USBHIST_LOG(usbdebug, "pipe = %p running = %d timeout = %d",
1.162.2.6 skrll 983: pipe, pipe->up_running, xfer->ux_timeout, 0);
1.134 jmcneill 984:
1.162.2.6 skrll 985: KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1.134 jmcneill 986:
1.93 augustss 987: #ifdef DIAGNOSTIC
1.162.2.6 skrll 988: if (xfer->ux_state != XFER_BUSY) {
1.162 skrll 989: USBHIST_LOG(usbdebug, "<- done, xfer %p not busy", xfer, 0, 0,
990: 0);
1.93 augustss 991: printf("usb_insert_transfer: xfer=%p not busy 0x%08x\n",
1.162.2.6 skrll 992: xfer, xfer->ux_state);
1.162.2.9 skrll 993: return USBD_INVAL;
1.93 augustss 994: }
1.162.2.6 skrll 995: xfer->ux_state = XFER_ONQU;
1.93 augustss 996: #endif
1.162.2.6 skrll 997: SIMPLEQ_INSERT_TAIL(&pipe->up_queue, xfer, ux_next);
998: if (pipe->up_running)
1.48 augustss 999: err = USBD_IN_PROGRESS;
1.37 augustss 1000: else {
1.162.2.6 skrll 1001: pipe->up_running = 1;
1.48 augustss 1002: err = USBD_NORMAL_COMPLETION;
1.37 augustss 1003: }
1.162 skrll 1004: USBHIST_LOG(usbdebug, "<- done xfer %p, err %d", xfer, err, 0, 0);
1.162.2.9 skrll 1005: return err;
1.1 augustss 1006: }
1007:
1.138 mrg 1008: /* Called with USB lock held. */
1.31 augustss 1009: void
1.74 augustss 1010: usbd_start_next(usbd_pipe_handle pipe)
1.31 augustss 1011: {
1.48 augustss 1012: usbd_xfer_handle xfer;
1013: usbd_status err;
1.40 augustss 1014:
1.162 skrll 1015: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1016:
1.31 augustss 1017: #ifdef DIAGNOSTIC
1.48 augustss 1018: if (pipe == NULL) {
1.51 augustss 1019: printf("usbd_start_next: pipe == NULL\n");
1.31 augustss 1020: return;
1021: }
1.162.2.6 skrll 1022: if (pipe->up_methods == NULL || pipe->up_methods->upm_start == NULL) {
1.51 augustss 1023: printf("usbd_start_next: pipe=%p no start method\n", pipe);
1.31 augustss 1024: return;
1025: }
1026: #endif
1027:
1.162.2.6 skrll 1028: KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1.138 mrg 1029:
1.31 augustss 1030: /* Get next request in queue. */
1.162.2.6 skrll 1031: xfer = SIMPLEQ_FIRST(&pipe->up_queue);
1.162 skrll 1032: USBHIST_LOG(usbdebug, "pipe = %p, xfer = %p", pipe, xfer, 0, 0);
1.51 augustss 1033: if (xfer == NULL) {
1.162.2.6 skrll 1034: pipe->up_running = 0;
1.51 augustss 1035: } else {
1.162.2.6 skrll 1036: mutex_exit(pipe->up_dev->ud_bus->ub_lock);
1037: err = pipe->up_methods->upm_start(xfer);
1038: mutex_enter(pipe->up_dev->ud_bus->ub_lock);
1.158 skrll 1039:
1.48 augustss 1040: if (err != USBD_IN_PROGRESS) {
1.162 skrll 1041: USBHIST_LOG(usbdebug, "error = %d", err, 0, 0, 0);
1.162.2.6 skrll 1042: pipe->up_running = 0;
1.31 augustss 1043: /* XXX do what? */
1044: }
1.1 augustss 1045: }
1.138 mrg 1046:
1.162.2.6 skrll 1047: KASSERT(mutex_owned(pipe->up_dev->ud_bus->ub_lock));
1.1 augustss 1048: }
1049:
1050: usbd_status
1.74 augustss 1051: usbd_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data)
1.1 augustss 1052: {
1.99 thorpej 1053: return (usbd_do_request_flags(dev, req, data, 0, 0,
1.98 augustss 1054: USBD_DEFAULT_TIMEOUT));
1.17 augustss 1055: }
1056:
1057: usbd_status
1.74 augustss 1058: usbd_do_request_flags(usbd_device_handle dev, usb_device_request_t *req,
1.162.2.1 skrll 1059: void *data, uint16_t flags, int *actlen, uint32_t timo)
1.17 augustss 1060: {
1.162.2.6 skrll 1061: return (usbd_do_request_flags_pipe(dev, dev->ud_pipe0, req,
1.96 augustss 1062: data, flags, actlen, timo));
1.77 augustss 1063: }
1064:
1065: usbd_status
1066: usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe,
1.162.2.1 skrll 1067: usb_device_request_t *req, void *data, uint16_t flags, int *actlen,
1068: uint32_t timeout)
1.77 augustss 1069: {
1.48 augustss 1070: usbd_xfer_handle xfer;
1071: usbd_status err;
1.1 augustss 1072:
1.162 skrll 1073: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1074:
1.162.2.3 skrll 1075: ASSERT_SLEEPABLE();
1.7 augustss 1076:
1.50 augustss 1077: xfer = usbd_alloc_xfer(dev);
1.48 augustss 1078: if (xfer == NULL)
1.162.2.9 skrll 1079: return USBD_NOMEM;
1.162.2.11 skrll 1080:
1081: if (UGETW(req->wLength) != 0) {
1.162.2.13 skrll 1082: void *buf = usbd_alloc_buffer(xfer, UGETW(req->wLength));
1.162.2.11 skrll 1083: if (buf == NULL) {
1.162.2.18 skrll 1084: err = USBD_NOMEM;
1.162.2.11 skrll 1085: goto bad;
1086: }
1087: }
1088:
1.96 augustss 1089: usbd_setup_default_xfer(xfer, dev, 0, timeout, req,
1.77 augustss 1090: data, UGETW(req->wLength), flags, 0);
1.162.2.6 skrll 1091: xfer->ux_pipe = pipe;
1.48 augustss 1092: err = usbd_sync_transfer(xfer);
1.1 augustss 1093: #if defined(USB_DEBUG) || defined(DIAGNOSTIC)
1.162.2.6 skrll 1094: if (xfer->ux_actlen > xfer->ux_length) {
1.162 skrll 1095: USBHIST_LOG(usbdebug, "overrun addr = %d type = 0x%02x",
1.162.2.6 skrll 1096: dev->ud_addr, xfer->ux_request.bmRequestType, 0, 0);
1.162 skrll 1097: USBHIST_LOG(usbdebug, " req = 0x%02x val = %d index = %d",
1.162.2.6 skrll 1098: xfer->ux_request.bRequest, UGETW(xfer->ux_request.wValue),
1099: UGETW(xfer->ux_request.wIndex), 0);
1.162 skrll 1100: USBHIST_LOG(usbdebug, " rlen = %d length = %d actlen = %d",
1.162.2.6 skrll 1101: UGETW(xfer->ux_request.wLength),
1102: xfer->ux_length, xfer->ux_actlen, 0);
1.112 dogcow 1103: }
1.1 augustss 1104: #endif
1.48 augustss 1105: if (actlen != NULL)
1.162.2.6 skrll 1106: *actlen = xfer->ux_actlen;
1.48 augustss 1107: if (err == USBD_STALLED) {
1.102 augustss 1108: /*
1.15 augustss 1109: * The control endpoint has stalled. Control endpoints
1110: * should not halt, but some may do so anyway so clear
1111: * any halt condition.
1112: */
1113: usb_device_request_t treq;
1114: usb_status_t status;
1.162.2.1 skrll 1115: uint16_t s;
1.48 augustss 1116: usbd_status nerr;
1.15 augustss 1117:
1118: treq.bmRequestType = UT_READ_ENDPOINT;
1119: treq.bRequest = UR_GET_STATUS;
1120: USETW(treq.wValue, 0);
1121: USETW(treq.wIndex, 0);
1122: USETW(treq.wLength, sizeof(usb_status_t));
1.50 augustss 1123: usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
1.37 augustss 1124: &treq, &status,sizeof(usb_status_t),
1.36 augustss 1125: 0, 0);
1.48 augustss 1126: nerr = usbd_sync_transfer(xfer);
1127: if (nerr)
1.15 augustss 1128: goto bad;
1129: s = UGETW(status.wStatus);
1.162 skrll 1130: USBHIST_LOG(usbdebug, "status = 0x%04x", s, 0, 0, 0);
1.15 augustss 1131: if (!(s & UES_HALT))
1132: goto bad;
1133: treq.bmRequestType = UT_WRITE_ENDPOINT;
1134: treq.bRequest = UR_CLEAR_FEATURE;
1135: USETW(treq.wValue, UF_ENDPOINT_HALT);
1136: USETW(treq.wIndex, 0);
1137: USETW(treq.wLength, 0);
1.50 augustss 1138: usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT,
1.36 augustss 1139: &treq, &status, 0, 0, 0);
1.48 augustss 1140: nerr = usbd_sync_transfer(xfer);
1141: if (nerr)
1.15 augustss 1142: goto bad;
1143: }
1144:
1145: bad:
1.132 matt 1146: if (err) {
1.162.2.14 skrll 1147: USBHIST_LOG(usbdebug, "returning err = %d", err, 0, 0, 0);
1.132 matt 1148: }
1.50 augustss 1149: usbd_free_xfer(xfer);
1.162.2.9 skrll 1150: return err;
1.7 augustss 1151: }
1152:
1.78 augustss 1153: const struct usbd_quirks *
1.74 augustss 1154: usbd_get_quirks(usbd_device_handle dev)
1.1 augustss 1155: {
1.81 augustss 1156: #ifdef DIAGNOSTIC
1157: if (dev == NULL) {
1158: printf("usbd_get_quirks: dev == NULL\n");
1159: return 0;
1160: }
1161: #endif
1.162.2.9 skrll 1162: return dev->ud_quirks;
1.1 augustss 1163: }
1164:
1165: /* XXX do periodic free() of free list */
1166:
1.6 augustss 1167: /*
1168: * Called from keyboard driver when in polling mode.
1169: */
1170: void
1.74 augustss 1171: usbd_dopoll(usbd_interface_handle iface)
1.6 augustss 1172: {
1.162.2.6 skrll 1173: iface->ui_dev->ud_bus->ub_methods->ubm_dopoll(iface->ui_dev->ud_bus);
1.8 augustss 1174: }
1175:
1.138 mrg 1176: /*
1.162.2.6 skrll 1177: * XXX use this more??? ub_usepolling it touched manually all over
1.138 mrg 1178: */
1.8 augustss 1179: void
1.74 augustss 1180: usbd_set_polling(usbd_device_handle dev, int on)
1.8 augustss 1181: {
1.42 augustss 1182: if (on)
1.162.2.6 skrll 1183: dev->ud_bus->ub_usepolling++;
1.42 augustss 1184: else
1.162.2.6 skrll 1185: dev->ud_bus->ub_usepolling--;
1.133 jmcneill 1186:
1187: /* Kick the host controller when switching modes */
1.162.2.6 skrll 1188: mutex_enter(dev->ud_bus->ub_lock);
1189: dev->ud_bus->ub_methods->ubm_softint(dev->ud_bus);
1190: mutex_exit(dev->ud_bus->ub_lock);
1.6 augustss 1191: }
1.12 augustss 1192:
1193:
1194: usb_endpoint_descriptor_t *
1.162.2.1 skrll 1195: usbd_get_endpoint_descriptor(usbd_interface_handle iface, uint8_t address)
1.12 augustss 1196: {
1197: struct usbd_endpoint *ep;
1198: int i;
1199:
1.162.2.6 skrll 1200: for (i = 0; i < iface->ui_idesc->bNumEndpoints; i++) {
1201: ep = &iface->ui_endpoints[i];
1202: if (ep->ue_edesc->bEndpointAddress == address)
1.162.2.9 skrll 1203: return iface->ui_endpoints[i].ue_edesc;
1.12 augustss 1204: }
1.162.2.9 skrll 1205: return NULL;
1.63 augustss 1206: }
1207:
1208: /*
1209: * usbd_ratecheck() can limit the number of error messages that occurs.
1210: * When a device is unplugged it may take up to 0.25s for the hub driver
1211: * to notice it. If the driver continuosly tries to do I/O operations
1212: * this can generate a large number of messages.
1213: */
1214: int
1.74 augustss 1215: usbd_ratecheck(struct timeval *last)
1.63 augustss 1216: {
1.64 augustss 1217: static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/
1.63 augustss 1218:
1.162.2.9 skrll 1219: return ratecheck(last, &errinterval);
1.89 augustss 1220: }
1221:
1222: /*
1223: * Search for a vendor/product pair in an array. The item size is
1224: * given as an argument.
1225: */
1.90 augustss 1226: const struct usb_devno *
1227: usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz,
1.162.2.1 skrll 1228: uint16_t vendor, uint16_t product)
1.89 augustss 1229: {
1230: while (nentries-- > 0) {
1.162.2.1 skrll 1231: uint16_t tproduct = tbl->ud_product;
1.93 augustss 1232: if (tbl->ud_vendor == vendor &&
1233: (tproduct == product || tproduct == USB_PRODUCT_ANY))
1.162.2.9 skrll 1234: return tbl;
1.95 augustss 1235: tbl = (const struct usb_devno *)((const char *)tbl + sz);
1.89 augustss 1236: }
1.162.2.9 skrll 1237: return NULL;
1.12 augustss 1238: }
1239:
1.105 augustss 1240:
1241: void
1242: usb_desc_iter_init(usbd_device_handle dev, usbd_desc_iter_t *iter)
1243: {
1244: const usb_config_descriptor_t *cd = usbd_get_config_descriptor(dev);
1245:
1.162.2.2 skrll 1246: iter->cur = (const uByte *)cd;
1247: iter->end = (const uByte *)cd + UGETW(cd->wTotalLength);
1.105 augustss 1248: }
1249:
1250: const usb_descriptor_t *
1251: usb_desc_iter_next(usbd_desc_iter_t *iter)
1252: {
1253: const usb_descriptor_t *desc;
1254:
1255: if (iter->cur + sizeof(usb_descriptor_t) >= iter->end) {
1256: if (iter->cur != iter->end)
1257: printf("usb_desc_iter_next: bad descriptor\n");
1258: return NULL;
1259: }
1.108 christos 1260: desc = (const usb_descriptor_t *)iter->cur;
1.105 augustss 1261: if (desc->bLength == 0) {
1262: printf("usb_desc_iter_next: descriptor length = 0\n");
1263: return NULL;
1264: }
1265: iter->cur += desc->bLength;
1266: if (iter->cur > iter->end) {
1267: printf("usb_desc_iter_next: descriptor length too large\n");
1268: return NULL;
1269: }
1270: return desc;
1271: }
1272:
1273: usbd_status
1274: usbd_get_string(usbd_device_handle dev, int si, char *buf)
1275: {
1.115 pavel 1276: return usbd_get_string0(dev, si, buf, 1);
1277: }
1278:
1279: usbd_status
1280: usbd_get_string0(usbd_device_handle dev, int si, char *buf, int unicode)
1281: {
1.162.2.6 skrll 1282: int swap = dev->ud_quirks->uq_flags & UQ_SWAP_UNICODE;
1.105 augustss 1283: usb_string_descriptor_t us;
1284: char *s;
1.116 macallan 1285: int i, n;
1.162.2.1 skrll 1286: uint16_t c;
1.105 augustss 1287: usbd_status err;
1288: int size;
1289:
1.162 skrll 1290: USBHIST_FUNC(); USBHIST_CALLED(usbdebug);
1291:
1.105 augustss 1292: buf[0] = '\0';
1293: if (si == 0)
1.162.2.9 skrll 1294: return USBD_INVAL;
1.162.2.6 skrll 1295: if (dev->ud_quirks->uq_flags & UQ_NO_STRINGS)
1.162.2.9 skrll 1296: return USBD_STALLED;
1.162.2.6 skrll 1297: if (dev->ud_langid == USBD_NOLANG) {
1.105 augustss 1298: /* Set up default language */
1299: err = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us,
1300: &size);
1301: if (err || size < 4) {
1.162 skrll 1302: USBHIST_LOG(usbdebug, "getting lang failed, using 0",
1303: 0, 0, 0, 0);
1.162.2.6 skrll 1304: dev->ud_langid = 0; /* Well, just pick something then */
1.105 augustss 1305: } else {
1306: /* Pick the first language as the default. */
1.162.2.6 skrll 1307: dev->ud_langid = UGETW(us.bString[0]);
1.105 augustss 1308: }
1309: }
1.162.2.6 skrll 1310: err = usbd_get_string_desc(dev, si, dev->ud_langid, &us, &size);
1.105 augustss 1311: if (err)
1.162.2.9 skrll 1312: return err;
1.105 augustss 1313: s = buf;
1314: n = size / 2 - 1;
1.115 pavel 1315: if (unicode) {
1316: for (i = 0; i < n; i++) {
1317: c = UGETW(us.bString[i]);
1318: if (swap)
1319: c = (c >> 8) | (c << 8);
1.119 drochner 1320: s += wput_utf8(s, 3, c);
1.115 pavel 1321: }
1322: *s++ = 0;
1323: }
1324: #ifdef COMPAT_30
1325: else {
1.119 drochner 1326: for (i = 0; i < n; i++) {
1.115 pavel 1327: c = UGETW(us.bString[i]);
1328: if (swap)
1329: c = (c >> 8) | (c << 8);
1.119 drochner 1330: *s++ = (c < 0x80) ? c : '?';
1.107 augustss 1331: }
1.119 drochner 1332: *s++ = 0;
1.105 augustss 1333: }
1.115 pavel 1334: #endif
1.162.2.9 skrll 1335: return USBD_NORMAL_COMPLETION;
1.105 augustss 1336: }
CVSweb <webmaster@jp.NetBSD.org>