1 /* $NetBSD: usbdi.c,v 1.100 2002/05/19 06:24:33 augustss 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.100 2002/05/19 06:24:33 augustss 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 speed=%d self_powered=%d " 133 "power=%d langid=%d\n", 134 dev->address, dev->config, dev->depth, dev->speed, 135 dev->self_powered, dev->power, dev->langid); 136 } 137 138 void 139 usbd_dump_endpoint(struct usbd_endpoint *endp) 140 { 141 printf("usbd_dump_endpoint: endp=%p\n", endp); 142 if (endp == NULL) 143 return; 144 printf(" edesc=%p refcnt=%d\n", endp->edesc, endp->refcnt); 145 if (endp->edesc) 146 printf(" bEndpointAddress=0x%02x\n", 147 endp->edesc->bEndpointAddress); 148 } 149 150 void 151 usbd_dump_queue(usbd_pipe_handle pipe) 152 { 153 usbd_xfer_handle xfer; 154 155 printf("usbd_dump_queue: pipe=%p\n", pipe); 156 for (xfer = SIMPLEQ_FIRST(&pipe->queue); 157 xfer; 158 xfer = SIMPLEQ_NEXT(xfer, next)) { 159 printf(" xfer=%p\n", xfer); 160 } 161 } 162 163 void 164 usbd_dump_pipe(usbd_pipe_handle pipe) 165 { 166 printf("usbd_dump_pipe: pipe=%p\n", pipe); 167 if (pipe == NULL) 168 return; 169 usbd_dump_iface(pipe->iface); 170 usbd_dump_device(pipe->device); 171 usbd_dump_endpoint(pipe->endpoint); 172 printf(" (usbd_dump_pipe:)\n refcnt=%d running=%d aborting=%d\n", 173 pipe->refcnt, pipe->running, pipe->aborting); 174 printf(" intrxfer=%p, repeat=%d, interval=%d\n", 175 pipe->intrxfer, pipe->repeat, pipe->interval); 176 } 177 #endif 178 179 usbd_status 180 usbd_open_pipe(usbd_interface_handle iface, u_int8_t address, 181 u_int8_t flags, usbd_pipe_handle *pipe) 182 { 183 return (usbd_open_pipe_ival(iface, address, flags, pipe, 184 USBD_DEFAULT_INTERVAL)); 185 } 186 187 usbd_status 188 usbd_open_pipe_ival(usbd_interface_handle iface, u_int8_t address, 189 u_int8_t flags, usbd_pipe_handle *pipe, int ival) 190 { 191 usbd_pipe_handle p; 192 struct usbd_endpoint *ep; 193 usbd_status err; 194 int i; 195 196 DPRINTFN(3,("usbd_open_pipe: iface=%p address=0x%x flags=0x%x\n", 197 iface, address, flags)); 198 199 for (i = 0; i < iface->idesc->bNumEndpoints; i++) { 200 ep = &iface->endpoints[i]; 201 if (ep->edesc == NULL) 202 return (USBD_IOERROR); 203 if (ep->edesc->bEndpointAddress == address) 204 goto found; 205 } 206 return (USBD_BAD_ADDRESS); 207 found: 208 if ((flags & USBD_EXCLUSIVE_USE) && ep->refcnt != 0) 209 return (USBD_IN_USE); 210 err = usbd_setup_pipe(iface->device, iface, ep, ival, &p); 211 if (err) 212 return (err); 213 LIST_INSERT_HEAD(&iface->pipes, p, next); 214 *pipe = p; 215 return (USBD_NORMAL_COMPLETION); 216 } 217 218 usbd_status 219 usbd_open_pipe_intr(usbd_interface_handle iface, u_int8_t address, 220 u_int8_t flags, usbd_pipe_handle *pipe, 221 usbd_private_handle priv, void *buffer, u_int32_t len, 222 usbd_callback cb, int ival) 223 { 224 usbd_status err; 225 usbd_xfer_handle xfer; 226 usbd_pipe_handle ipipe; 227 228 DPRINTFN(3,("usbd_open_pipe_intr: address=0x%x flags=0x%x len=%d\n", 229 address, flags, len)); 230 231 err = usbd_open_pipe_ival(iface, address, USBD_EXCLUSIVE_USE, 232 &ipipe, ival); 233 if (err) 234 return (err); 235 xfer = usbd_alloc_xfer(iface->device); 236 if (xfer == NULL) { 237 err = USBD_NOMEM; 238 goto bad1; 239 } 240 usbd_setup_xfer(xfer, ipipe, priv, buffer, len, flags, 241 USBD_NO_TIMEOUT, cb); 242 ipipe->intrxfer = xfer; 243 ipipe->repeat = 1; 244 err = usbd_transfer(xfer); 245 *pipe = ipipe; 246 if (err != USBD_IN_PROGRESS) 247 goto bad2; 248 return (USBD_NORMAL_COMPLETION); 249 250 bad2: 251 ipipe->intrxfer = NULL; 252 ipipe->repeat = 0; 253 usbd_free_xfer(xfer); 254 bad1: 255 usbd_close_pipe(ipipe); 256 return (err); 257 } 258 259 usbd_status 260 usbd_close_pipe(usbd_pipe_handle pipe) 261 { 262 #ifdef DIAGNOSTIC 263 if (pipe == NULL) { 264 printf("usbd_close_pipe: pipe==NULL\n"); 265 return (USBD_NORMAL_COMPLETION); 266 } 267 #endif 268 269 if (--pipe->refcnt != 0) 270 return (USBD_NORMAL_COMPLETION); 271 if (SIMPLEQ_FIRST(&pipe->queue) != 0) 272 return (USBD_PENDING_REQUESTS); 273 LIST_REMOVE(pipe, next); 274 pipe->endpoint->refcnt--; 275 pipe->methods->close(pipe); 276 if (pipe->intrxfer != NULL) 277 usbd_free_xfer(pipe->intrxfer); 278 free(pipe, M_USB); 279 return (USBD_NORMAL_COMPLETION); 280 } 281 282 usbd_status 283 usbd_transfer(usbd_xfer_handle xfer) 284 { 285 usbd_pipe_handle pipe = xfer->pipe; 286 usb_dma_t *dmap = &xfer->dmabuf; 287 usbd_status err; 288 u_int size; 289 int s; 290 291 DPRINTFN(5,("usbd_transfer: xfer=%p, flags=%d, pipe=%p, running=%d\n", 292 xfer, xfer->flags, pipe, pipe->running)); 293 #ifdef USB_DEBUG 294 if (usbdebug > 5) 295 usbd_dump_queue(pipe); 296 #endif 297 xfer->done = 0; 298 299 if (pipe->aborting) 300 return (USBD_CANCELLED); 301 302 size = xfer->length; 303 /* If there is no buffer, allocate one. */ 304 if (!(xfer->rqflags & URQ_DEV_DMABUF) && size != 0) { 305 struct usbd_bus *bus = pipe->device->bus; 306 307 #ifdef DIAGNOSTIC 308 if (xfer->rqflags & URQ_AUTO_DMABUF) 309 printf("usbd_transfer: has old buffer!\n"); 310 #endif 311 err = bus->methods->allocm(bus, dmap, size); 312 if (err) 313 return (err); 314 xfer->rqflags |= URQ_AUTO_DMABUF; 315 } 316 317 /* Copy data if going out. */ 318 if (!(xfer->flags & USBD_NO_COPY) && size != 0 && 319 !usbd_xfer_isread(xfer)) 320 memcpy(KERNADDR(dmap, 0), xfer->buffer, size); 321 322 err = pipe->methods->transfer(xfer); 323 324 if (err != USBD_IN_PROGRESS && err) { 325 /* The transfer has not been queued, so free buffer. */ 326 if (xfer->rqflags & URQ_AUTO_DMABUF) { 327 struct usbd_bus *bus = pipe->device->bus; 328 329 bus->methods->freem(bus, &xfer->dmabuf); 330 xfer->rqflags &= ~URQ_AUTO_DMABUF; 331 } 332 } 333 334 if (!(xfer->flags & USBD_SYNCHRONOUS)) 335 return (err); 336 337 /* Sync transfer, wait for completion. */ 338 if (err != USBD_IN_PROGRESS) 339 return (err); 340 s = splusb(); 341 if (!xfer->done) { 342 if (pipe->device->bus->use_polling) 343 panic("usbd_transfer: not done\n"); 344 tsleep(xfer, PRIBIO, "usbsyn", 0); 345 } 346 splx(s); 347 return (xfer->status); 348 } 349 350 /* Like usbd_transfer(), but waits for completion. */ 351 usbd_status 352 usbd_sync_transfer(usbd_xfer_handle xfer) 353 { 354 xfer->flags |= USBD_SYNCHRONOUS; 355 return (usbd_transfer(xfer)); 356 } 357 358 void * 359 usbd_alloc_buffer(usbd_xfer_handle xfer, u_int32_t size) 360 { 361 struct usbd_bus *bus = xfer->device->bus; 362 usbd_status err; 363 364 #ifdef DIAGNOSTIC 365 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) 366 printf("usbd_alloc_buffer: xfer already has a buffer\n"); 367 #endif 368 err = bus->methods->allocm(bus, &xfer->dmabuf, size); 369 if (err) 370 return (NULL); 371 xfer->rqflags |= URQ_DEV_DMABUF; 372 return (KERNADDR(&xfer->dmabuf, 0)); 373 } 374 375 void 376 usbd_free_buffer(usbd_xfer_handle xfer) 377 { 378 #ifdef DIAGNOSTIC 379 if (!(xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF))) { 380 printf("usbd_free_buffer: no buffer\n"); 381 return; 382 } 383 #endif 384 xfer->rqflags &= ~(URQ_DEV_DMABUF | URQ_AUTO_DMABUF); 385 xfer->device->bus->methods->freem(xfer->device->bus, &xfer->dmabuf); 386 } 387 388 void * 389 usbd_get_buffer(usbd_xfer_handle xfer) 390 { 391 if (!(xfer->rqflags & URQ_DEV_DMABUF)) 392 return (0); 393 return (KERNADDR(&xfer->dmabuf, 0)); 394 } 395 396 usbd_xfer_handle 397 usbd_alloc_xfer(usbd_device_handle dev) 398 { 399 usbd_xfer_handle xfer; 400 401 xfer = dev->bus->methods->allocx(dev->bus); 402 if (xfer == NULL) 403 return (NULL); 404 xfer->device = dev; 405 usb_callout_init(xfer->timeout_handle); 406 DPRINTFN(5,("usbd_alloc_xfer() = %p\n", xfer)); 407 return (xfer); 408 } 409 410 usbd_status 411 usbd_free_xfer(usbd_xfer_handle xfer) 412 { 413 DPRINTFN(5,("usbd_free_xfer: %p\n", xfer)); 414 if (xfer->rqflags & (URQ_DEV_DMABUF | URQ_AUTO_DMABUF)) 415 usbd_free_buffer(xfer); 416 #if defined(__NetBSD__) && defined(DIAGNOSTIC) 417 if (callout_pending(&xfer->timeout_handle)) { 418 callout_stop(&xfer->timeout_handle); 419 printf("usbd_free_xfer: timout_handle pending"); 420 } 421 #endif 422 xfer->device->bus->methods->freex(xfer->device->bus, xfer); 423 return (USBD_NORMAL_COMPLETION); 424 } 425 426 void 427 usbd_setup_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, 428 usbd_private_handle priv, void *buffer, u_int32_t length, 429 u_int16_t flags, u_int32_t timeout, 430 usbd_callback callback) 431 { 432 xfer->pipe = pipe; 433 xfer->priv = priv; 434 xfer->buffer = buffer; 435 xfer->length = length; 436 xfer->actlen = 0; 437 xfer->flags = flags; 438 xfer->timeout = timeout; 439 xfer->status = USBD_NOT_STARTED; 440 xfer->callback = callback; 441 xfer->rqflags &= ~URQ_REQUEST; 442 xfer->nframes = 0; 443 } 444 445 void 446 usbd_setup_default_xfer(usbd_xfer_handle xfer, usbd_device_handle dev, 447 usbd_private_handle priv, u_int32_t timeout, 448 usb_device_request_t *req, void *buffer, 449 u_int32_t length, u_int16_t flags, 450 usbd_callback callback) 451 { 452 xfer->pipe = dev->default_pipe; 453 xfer->priv = priv; 454 xfer->buffer = buffer; 455 xfer->length = length; 456 xfer->actlen = 0; 457 xfer->flags = flags; 458 xfer->timeout = timeout; 459 xfer->status = USBD_NOT_STARTED; 460 xfer->callback = callback; 461 xfer->request = *req; 462 xfer->rqflags |= URQ_REQUEST; 463 xfer->nframes = 0; 464 } 465 466 void 467 usbd_setup_isoc_xfer(usbd_xfer_handle xfer, usbd_pipe_handle pipe, 468 usbd_private_handle priv, u_int16_t *frlengths, 469 u_int32_t nframes, u_int16_t flags, usbd_callback callback) 470 { 471 xfer->pipe = pipe; 472 xfer->priv = priv; 473 xfer->buffer = 0; 474 xfer->length = 0; 475 xfer->actlen = 0; 476 xfer->flags = flags; 477 xfer->timeout = USBD_NO_TIMEOUT; 478 xfer->status = USBD_NOT_STARTED; 479 xfer->callback = callback; 480 xfer->rqflags &= ~URQ_REQUEST; 481 xfer->frlengths = frlengths; 482 xfer->nframes = nframes; 483 } 484 485 void 486 usbd_get_xfer_status(usbd_xfer_handle xfer, usbd_private_handle *priv, 487 void **buffer, u_int32_t *count, usbd_status *status) 488 { 489 if (priv != NULL) 490 *priv = xfer->priv; 491 if (buffer != NULL) 492 *buffer = xfer->buffer; 493 if (count != NULL) 494 *count = xfer->actlen; 495 if (status != NULL) 496 *status = xfer->status; 497 } 498 499 usb_config_descriptor_t * 500 usbd_get_config_descriptor(usbd_device_handle dev) 501 { 502 #ifdef DIAGNOSTIC 503 if (dev == NULL) { 504 printf("usbd_get_config_descriptor: dev == NULL\n"); 505 return (NULL); 506 } 507 #endif 508 return (dev->cdesc); 509 } 510 511 usb_interface_descriptor_t * 512 usbd_get_interface_descriptor(usbd_interface_handle iface) 513 { 514 #ifdef DIAGNOSTIC 515 if (iface == NULL) { 516 printf("usbd_get_interface_descriptor: dev == NULL\n"); 517 return (NULL); 518 } 519 #endif 520 return (iface->idesc); 521 } 522 523 usb_device_descriptor_t * 524 usbd_get_device_descriptor(usbd_device_handle dev) 525 { 526 return (&dev->ddesc); 527 } 528 529 usb_endpoint_descriptor_t * 530 usbd_interface2endpoint_descriptor(usbd_interface_handle iface, u_int8_t index) 531 { 532 if (index >= iface->idesc->bNumEndpoints) 533 return (0); 534 return (iface->endpoints[index].edesc); 535 } 536 537 usbd_status 538 usbd_abort_pipe(usbd_pipe_handle pipe) 539 { 540 usbd_status err; 541 int s; 542 543 #ifdef DIAGNOSTIC 544 if (pipe == NULL) { 545 printf("usbd_close_pipe: pipe==NULL\n"); 546 return (USBD_NORMAL_COMPLETION); 547 } 548 #endif 549 s = splusb(); 550 err = usbd_ar_pipe(pipe); 551 splx(s); 552 return (err); 553 } 554 555 usbd_status 556 usbd_clear_endpoint_stall(usbd_pipe_handle pipe) 557 { 558 usbd_device_handle dev = pipe->device; 559 usb_device_request_t req; 560 usbd_status err; 561 562 DPRINTFN(8, ("usbd_clear_endpoint_stall\n")); 563 564 /* 565 * Clearing en endpoint stall resets the endpoint toggle, so 566 * do the same to the HC toggle. 567 */ 568 pipe->methods->cleartoggle(pipe); 569 570 req.bmRequestType = UT_WRITE_ENDPOINT; 571 req.bRequest = UR_CLEAR_FEATURE; 572 USETW(req.wValue, UF_ENDPOINT_HALT); 573 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress); 574 USETW(req.wLength, 0); 575 err = usbd_do_request(dev, &req, 0); 576 #if 0 577 XXX should we do this? 578 if (!err) { 579 pipe->state = USBD_PIPE_ACTIVE; 580 /* XXX activate pipe */ 581 } 582 #endif 583 return (err); 584 } 585 586 usbd_status 587 usbd_clear_endpoint_stall_async(usbd_pipe_handle pipe) 588 { 589 usbd_device_handle dev = pipe->device; 590 usb_device_request_t req; 591 usbd_status err; 592 593 pipe->methods->cleartoggle(pipe); 594 595 req.bmRequestType = UT_WRITE_ENDPOINT; 596 req.bRequest = UR_CLEAR_FEATURE; 597 USETW(req.wValue, UF_ENDPOINT_HALT); 598 USETW(req.wIndex, pipe->endpoint->edesc->bEndpointAddress); 599 USETW(req.wLength, 0); 600 err = usbd_do_request_async(dev, &req, 0); 601 return (err); 602 } 603 604 void 605 usbd_clear_endpoint_toggle(usbd_pipe_handle pipe) 606 { 607 pipe->methods->cleartoggle(pipe); 608 } 609 610 usbd_status 611 usbd_endpoint_count(usbd_interface_handle iface, u_int8_t *count) 612 { 613 #ifdef DIAGNOSTIC 614 if (iface == NULL || iface->idesc == NULL) { 615 printf("usbd_endpoint_count: NULL pointer\n"); 616 return (USBD_INVAL); 617 } 618 #endif 619 *count = iface->idesc->bNumEndpoints; 620 return (USBD_NORMAL_COMPLETION); 621 } 622 623 usbd_status 624 usbd_interface_count(usbd_device_handle dev, u_int8_t *count) 625 { 626 if (dev->cdesc == NULL) 627 return (USBD_NOT_CONFIGURED); 628 *count = dev->cdesc->bNumInterface; 629 return (USBD_NORMAL_COMPLETION); 630 } 631 632 void 633 usbd_interface2device_handle(usbd_interface_handle iface, 634 usbd_device_handle *dev) 635 { 636 *dev = iface->device; 637 } 638 639 usbd_status 640 usbd_device2interface_handle(usbd_device_handle dev, 641 u_int8_t ifaceno, usbd_interface_handle *iface) 642 { 643 if (dev->cdesc == NULL) 644 return (USBD_NOT_CONFIGURED); 645 if (ifaceno >= dev->cdesc->bNumInterface) 646 return (USBD_INVAL); 647 *iface = &dev->ifaces[ifaceno]; 648 return (USBD_NORMAL_COMPLETION); 649 } 650 651 usbd_device_handle 652 usbd_pipe2device_handle(usbd_pipe_handle pipe) 653 { 654 return (pipe->device); 655 } 656 657 /* XXXX use altno */ 658 usbd_status 659 usbd_set_interface(usbd_interface_handle iface, int altidx) 660 { 661 usb_device_request_t req; 662 usbd_status err; 663 void *endpoints; 664 665 if (LIST_FIRST(&iface->pipes) != 0) 666 return (USBD_IN_USE); 667 668 endpoints = iface->endpoints; 669 err = usbd_fill_iface_data(iface->device, iface->index, altidx); 670 if (err) 671 return (err); 672 673 /* new setting works, we can free old endpoints */ 674 if (endpoints != NULL) 675 free(endpoints, M_USB); 676 677 #ifdef DIAGNOSTIC 678 if (iface->idesc == NULL) { 679 printf("usbd_set_interface: NULL pointer\n"); 680 return (USBD_INVAL); 681 } 682 #endif 683 684 req.bmRequestType = UT_WRITE_INTERFACE; 685 req.bRequest = UR_SET_INTERFACE; 686 USETW(req.wValue, iface->idesc->bAlternateSetting); 687 USETW(req.wIndex, iface->idesc->bInterfaceNumber); 688 USETW(req.wLength, 0); 689 return (usbd_do_request(iface->device, &req, 0)); 690 } 691 692 int 693 usbd_get_no_alts(usb_config_descriptor_t *cdesc, int ifaceno) 694 { 695 char *p = (char *)cdesc; 696 char *end = p + UGETW(cdesc->wTotalLength); 697 usb_interface_descriptor_t *d; 698 int n; 699 700 for (n = 0; p < end; p += d->bLength) { 701 d = (usb_interface_descriptor_t *)p; 702 if (p + d->bLength <= end && 703 d->bDescriptorType == UDESC_INTERFACE && 704 d->bInterfaceNumber == ifaceno) 705 n++; 706 } 707 return (n); 708 } 709 710 int 711 usbd_get_interface_altindex(usbd_interface_handle iface) 712 { 713 return (iface->altindex); 714 } 715 716 usbd_status 717 usbd_get_interface(usbd_interface_handle iface, u_int8_t *aiface) 718 { 719 usb_device_request_t req; 720 721 req.bmRequestType = UT_READ_INTERFACE; 722 req.bRequest = UR_GET_INTERFACE; 723 USETW(req.wValue, 0); 724 USETW(req.wIndex, iface->idesc->bInterfaceNumber); 725 USETW(req.wLength, 1); 726 return (usbd_do_request(iface->device, &req, aiface)); 727 } 728 729 /*** Internal routines ***/ 730 731 /* Dequeue all pipe operations, called at splusb(). */ 732 Static usbd_status 733 usbd_ar_pipe(usbd_pipe_handle pipe) 734 { 735 usbd_xfer_handle xfer; 736 737 SPLUSBCHECK; 738 739 DPRINTFN(2,("usbd_ar_pipe: pipe=%p\n", pipe)); 740 #ifdef USB_DEBUG 741 if (usbdebug > 5) 742 usbd_dump_queue(pipe); 743 #endif 744 pipe->repeat = 0; 745 pipe->aborting = 1; 746 while ((xfer = SIMPLEQ_FIRST(&pipe->queue)) != NULL) { 747 DPRINTFN(2,("usbd_ar_pipe: pipe=%p xfer=%p (methods=%p)\n", 748 pipe, xfer, pipe->methods)); 749 /* Make the HC abort it (and invoke the callback). */ 750 pipe->methods->abort(xfer); 751 /* XXX only for non-0 usbd_clear_endpoint_stall(pipe); */ 752 } 753 pipe->aborting = 0; 754 return (USBD_NORMAL_COMPLETION); 755 } 756 757 /* Called at splusb() */ 758 void 759 usb_transfer_complete(usbd_xfer_handle xfer) 760 { 761 usbd_pipe_handle pipe = xfer->pipe; 762 usb_dma_t *dmap = &xfer->dmabuf; 763 int repeat = pipe->repeat; 764 int polling; 765 766 SPLUSBCHECK; 767 768 DPRINTFN(5, ("usb_transfer_complete: pipe=%p xfer=%p status=%d " 769 "actlen=%d\n", pipe, xfer, xfer->status, xfer->actlen)); 770 #ifdef DIAGNOSTIC 771 if (xfer->busy_free != XFER_ONQU) { 772 printf("usb_transfer_complete: xfer=%p not busy 0x%08x\n", 773 xfer, xfer->busy_free); 774 return; 775 } 776 #endif 777 778 #ifdef DIAGNOSTIC 779 if (pipe == NULL) { 780 printf("usbd_transfer_cb: pipe==0, xfer=%p\n", xfer); 781 return; 782 } 783 #endif 784 polling = pipe->device->bus->use_polling; 785 /* XXXX */ 786 if (polling) 787 pipe->running = 0; 788 789 if (!(xfer->flags & USBD_NO_COPY) && xfer->actlen != 0 && 790 usbd_xfer_isread(xfer)) { 791 #ifdef DIAGNOSTIC 792 if (xfer->actlen > xfer->length) { 793 printf("usb_transfer_complete: actlen > len %d > %d\n", 794 xfer->actlen, xfer->length); 795 xfer->actlen = xfer->length; 796 } 797 #endif 798 memcpy(xfer->buffer, KERNADDR(dmap, 0), xfer->actlen); 799 } 800 801 /* if we allocated the buffer in usbd_transfer() we free it here. */ 802 if (xfer->rqflags & URQ_AUTO_DMABUF) { 803 if (!repeat) { 804 struct usbd_bus *bus = pipe->device->bus; 805 bus->methods->freem(bus, dmap); 806 xfer->rqflags &= ~URQ_AUTO_DMABUF; 807 } 808 } 809 810 if (!repeat) { 811 /* Remove request from queue. */ 812 #ifdef DIAGNOSTIC 813 if (xfer != SIMPLEQ_FIRST(&pipe->queue)) 814 printf("usb_transfer_complete: bad dequeue %p != %p\n", 815 xfer, SIMPLEQ_FIRST(&pipe->queue)); 816 xfer->busy_free = XFER_BUSY; 817 #endif 818 SIMPLEQ_REMOVE_HEAD(&pipe->queue, xfer, next); 819 } 820 DPRINTFN(5,("usb_transfer_complete: repeat=%d new head=%p\n", 821 repeat, SIMPLEQ_FIRST(&pipe->queue))); 822 823 /* Count completed transfers. */ 824 ++pipe->device->bus->stats.uds_requests 825 [pipe->endpoint->edesc->bmAttributes & UE_XFERTYPE]; 826 827 xfer->done = 1; 828 if (!xfer->status && xfer->actlen < xfer->length && 829 !(xfer->flags & USBD_SHORT_XFER_OK)) { 830 DPRINTFN(-1,("usbd_transfer_cb: short transfer %d<%d\n", 831 xfer->actlen, xfer->length)); 832 xfer->status = USBD_SHORT_XFER; 833 } 834 835 if (xfer->callback) 836 xfer->callback(xfer, xfer->priv, xfer->status); 837 838 #ifdef DIAGNOSTIC 839 if (pipe->methods->done != NULL) 840 pipe->methods->done(xfer); 841 else 842 printf("usb_transfer_complete: pipe->methods->done == NULL\n"); 843 #else 844 pipe->methods->done(xfer); 845 #endif 846 847 if ((xfer->flags & USBD_SYNCHRONOUS) && !polling) 848 wakeup(xfer); 849 850 if (!repeat) { 851 /* XXX should we stop the queue on all errors? */ 852 if ((xfer->status == USBD_CANCELLED || 853 xfer->status == USBD_TIMEOUT) && 854 pipe->iface != NULL) /* not control pipe */ 855 pipe->running = 0; 856 else 857 usbd_start_next(pipe); 858 } 859 } 860 861 usbd_status 862 usb_insert_transfer(usbd_xfer_handle xfer) 863 { 864 usbd_pipe_handle pipe = xfer->pipe; 865 usbd_status err; 866 int s; 867 868 DPRINTFN(5,("usb_insert_transfer: pipe=%p running=%d timeout=%d\n", 869 pipe, pipe->running, xfer->timeout)); 870 #ifdef DIAGNOSTIC 871 if (xfer->busy_free != XFER_BUSY) { 872 printf("usb_insert_transfer: xfer=%p not busy 0x%08x\n", 873 xfer, xfer->busy_free); 874 return (USBD_INVAL); 875 } 876 xfer->busy_free = XFER_ONQU; 877 #endif 878 s = splusb(); 879 SIMPLEQ_INSERT_TAIL(&pipe->queue, xfer, next); 880 if (pipe->running) 881 err = USBD_IN_PROGRESS; 882 else { 883 pipe->running = 1; 884 err = USBD_NORMAL_COMPLETION; 885 } 886 splx(s); 887 return (err); 888 } 889 890 /* Called at splusb() */ 891 void 892 usbd_start_next(usbd_pipe_handle pipe) 893 { 894 usbd_xfer_handle xfer; 895 usbd_status err; 896 897 SPLUSBCHECK; 898 899 #ifdef DIAGNOSTIC 900 if (pipe == NULL) { 901 printf("usbd_start_next: pipe == NULL\n"); 902 return; 903 } 904 if (pipe->methods == NULL || pipe->methods->start == NULL) { 905 printf("usbd_start_next: pipe=%p no start method\n", pipe); 906 return; 907 } 908 #endif 909 910 /* Get next request in queue. */ 911 xfer = SIMPLEQ_FIRST(&pipe->queue); 912 DPRINTFN(5, ("usbd_start_next: pipe=%p, xfer=%p\n", pipe, xfer)); 913 if (xfer == NULL) { 914 pipe->running = 0; 915 } else { 916 err = pipe->methods->start(xfer); 917 if (err != USBD_IN_PROGRESS) { 918 printf("usbd_start_next: error=%d\n", err); 919 pipe->running = 0; 920 /* XXX do what? */ 921 } 922 } 923 } 924 925 usbd_status 926 usbd_do_request(usbd_device_handle dev, usb_device_request_t *req, void *data) 927 { 928 return (usbd_do_request_flags(dev, req, data, 0, 0, 929 USBD_DEFAULT_TIMEOUT)); 930 } 931 932 usbd_status 933 usbd_do_request_flags(usbd_device_handle dev, usb_device_request_t *req, 934 void *data, u_int16_t flags, int *actlen, u_int32_t timo) 935 { 936 return (usbd_do_request_flags_pipe(dev, dev->default_pipe, req, 937 data, flags, actlen, timo)); 938 } 939 940 usbd_status 941 usbd_do_request_flags_pipe(usbd_device_handle dev, usbd_pipe_handle pipe, 942 usb_device_request_t *req, void *data, u_int16_t flags, int *actlen, 943 u_int32_t timeout) 944 { 945 usbd_xfer_handle xfer; 946 usbd_status err; 947 948 #ifdef DIAGNOSTIC 949 #if defined(__i386__) && defined(__FreeBSD__) 950 KASSERT(intr_nesting_level == 0, 951 ("usbd_do_request: in interrupt context")); 952 #endif 953 if (dev->bus->intr_context) { 954 printf("usbd_do_request: not in process context\n"); 955 return (USBD_INVAL); 956 } 957 #endif 958 959 xfer = usbd_alloc_xfer(dev); 960 if (xfer == NULL) 961 return (USBD_NOMEM); 962 usbd_setup_default_xfer(xfer, dev, 0, timeout, req, 963 data, UGETW(req->wLength), flags, 0); 964 xfer->pipe = pipe; 965 err = usbd_sync_transfer(xfer); 966 #if defined(USB_DEBUG) || defined(DIAGNOSTIC) 967 if (xfer->actlen > xfer->length) 968 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x" 969 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n", 970 dev->address, xfer->request.bmRequestType, 971 xfer->request.bRequest, UGETW(xfer->request.wValue), 972 UGETW(xfer->request.wIndex), 973 UGETW(xfer->request.wLength), 974 xfer->length, xfer->actlen)); 975 #endif 976 if (actlen != NULL) 977 *actlen = xfer->actlen; 978 if (err == USBD_STALLED) { 979 /* 980 * The control endpoint has stalled. Control endpoints 981 * should not halt, but some may do so anyway so clear 982 * any halt condition. 983 */ 984 usb_device_request_t treq; 985 usb_status_t status; 986 u_int16_t s; 987 usbd_status nerr; 988 989 treq.bmRequestType = UT_READ_ENDPOINT; 990 treq.bRequest = UR_GET_STATUS; 991 USETW(treq.wValue, 0); 992 USETW(treq.wIndex, 0); 993 USETW(treq.wLength, sizeof(usb_status_t)); 994 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, 995 &treq, &status,sizeof(usb_status_t), 996 0, 0); 997 nerr = usbd_sync_transfer(xfer); 998 if (nerr) 999 goto bad; 1000 s = UGETW(status.wStatus); 1001 DPRINTF(("usbd_do_request: status = 0x%04x\n", s)); 1002 if (!(s & UES_HALT)) 1003 goto bad; 1004 treq.bmRequestType = UT_WRITE_ENDPOINT; 1005 treq.bRequest = UR_CLEAR_FEATURE; 1006 USETW(treq.wValue, UF_ENDPOINT_HALT); 1007 USETW(treq.wIndex, 0); 1008 USETW(treq.wLength, 0); 1009 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, 1010 &treq, &status, 0, 0, 0); 1011 nerr = usbd_sync_transfer(xfer); 1012 if (nerr) 1013 goto bad; 1014 } 1015 1016 bad: 1017 usbd_free_xfer(xfer); 1018 return (err); 1019 } 1020 1021 void 1022 usbd_do_request_async_cb(usbd_xfer_handle xfer, usbd_private_handle priv, 1023 usbd_status status) 1024 { 1025 #if defined(USB_DEBUG) || defined(DIAGNOSTIC) 1026 if (xfer->actlen > xfer->length) 1027 DPRINTF(("usbd_do_request: overrun addr=%d type=0x%02x req=0x" 1028 "%02x val=%d index=%d rlen=%d length=%d actlen=%d\n", 1029 xfer->pipe->device->address, 1030 xfer->request.bmRequestType, 1031 xfer->request.bRequest, UGETW(xfer->request.wValue), 1032 UGETW(xfer->request.wIndex), 1033 UGETW(xfer->request.wLength), 1034 xfer->length, xfer->actlen)); 1035 #endif 1036 usbd_free_xfer(xfer); 1037 } 1038 1039 /* 1040 * Execute a request without waiting for completion. 1041 * Can be used from interrupt context. 1042 */ 1043 usbd_status 1044 usbd_do_request_async(usbd_device_handle dev, usb_device_request_t *req, 1045 void *data) 1046 { 1047 usbd_xfer_handle xfer; 1048 usbd_status err; 1049 1050 xfer = usbd_alloc_xfer(dev); 1051 if (xfer == NULL) 1052 return (USBD_NOMEM); 1053 usbd_setup_default_xfer(xfer, dev, 0, USBD_DEFAULT_TIMEOUT, req, 1054 data, UGETW(req->wLength), 0, usbd_do_request_async_cb); 1055 err = usbd_transfer(xfer); 1056 if (err != USBD_IN_PROGRESS) { 1057 usbd_free_xfer(xfer); 1058 return (err); 1059 } 1060 return (USBD_NORMAL_COMPLETION); 1061 } 1062 1063 const struct usbd_quirks * 1064 usbd_get_quirks(usbd_device_handle dev) 1065 { 1066 #ifdef DIAGNOSTIC 1067 if (dev == NULL) { 1068 printf("usbd_get_quirks: dev == NULL\n"); 1069 return 0; 1070 } 1071 #endif 1072 return (dev->quirks); 1073 } 1074 1075 /* XXX do periodic free() of free list */ 1076 1077 /* 1078 * Called from keyboard driver when in polling mode. 1079 */ 1080 void 1081 usbd_dopoll(usbd_interface_handle iface) 1082 { 1083 iface->device->bus->methods->do_poll(iface->device->bus); 1084 } 1085 1086 void 1087 usbd_set_polling(usbd_device_handle dev, int on) 1088 { 1089 if (on) 1090 dev->bus->use_polling++; 1091 else 1092 dev->bus->use_polling--; 1093 /* When polling we need to make sure there is nothing pending to do. */ 1094 if (dev->bus->use_polling) 1095 dev->bus->methods->soft_intr(dev->bus); 1096 } 1097 1098 1099 usb_endpoint_descriptor_t * 1100 usbd_get_endpoint_descriptor(usbd_interface_handle iface, u_int8_t address) 1101 { 1102 struct usbd_endpoint *ep; 1103 int i; 1104 1105 for (i = 0; i < iface->idesc->bNumEndpoints; i++) { 1106 ep = &iface->endpoints[i]; 1107 if (ep->edesc->bEndpointAddress == address) 1108 return (iface->endpoints[i].edesc); 1109 } 1110 return (0); 1111 } 1112 1113 /* 1114 * usbd_ratecheck() can limit the number of error messages that occurs. 1115 * When a device is unplugged it may take up to 0.25s for the hub driver 1116 * to notice it. If the driver continuosly tries to do I/O operations 1117 * this can generate a large number of messages. 1118 */ 1119 int 1120 usbd_ratecheck(struct timeval *last) 1121 { 1122 static struct timeval errinterval = { 0, 250000 }; /* 0.25 s*/ 1123 1124 return (ratecheck(last, &errinterval)); 1125 } 1126 1127 /* 1128 * Search for a vendor/product pair in an array. The item size is 1129 * given as an argument. 1130 */ 1131 const struct usb_devno * 1132 usb_match_device(const struct usb_devno *tbl, u_int nentries, u_int sz, 1133 u_int16_t vendor, u_int16_t product) 1134 { 1135 while (nentries-- > 0) { 1136 u_int16_t tproduct = tbl->ud_product; 1137 if (tbl->ud_vendor == vendor && 1138 (tproduct == product || tproduct == USB_PRODUCT_ANY)) 1139 return (tbl); 1140 tbl = (const struct usb_devno *)((const char *)tbl + sz); 1141 } 1142 return (NULL); 1143 } 1144 1145 #if defined(__FreeBSD__) 1146 int 1147 usbd_driver_load(module_t mod, int what, void *arg) 1148 { 1149 /* XXX should implement something like a function that removes all generic devices */ 1150 1151 return (0); 1152 } 1153 1154 #endif 1155