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