1 /* $NetBSD: usb_subr.c,v 1.29 1999/03/18 12:08:43 augustss Exp $ */ 2 3 /* 4 * Copyright (c) 1998 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Lennart Augustsson (augustss@carlstedt.se) at 9 * Carlstedt Research & Technology. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This product includes software developed by the NetBSD 22 * Foundation, Inc. and its contributors. 23 * 4. Neither the name of The NetBSD Foundation nor the names of its 24 * contributors may be used to endorse or promote products derived 25 * from this software without specific prior written permission. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 28 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 29 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 30 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 31 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 37 * POSSIBILITY OF SUCH DAMAGE. 38 */ 39 40 #include <sys/param.h> 41 #include <sys/systm.h> 42 #include <sys/kernel.h> 43 #include <sys/malloc.h> 44 #if defined(__NetBSD__) 45 #include <sys/device.h> 46 #elif defined(__FreeBSD__) 47 #include <sys/module.h> 48 #include <sys/bus.h> 49 #endif 50 #include <sys/proc.h> 51 #include <sys/select.h> 52 53 #include <dev/usb/usb.h> 54 55 #include <dev/usb/usbdi.h> 56 #include <dev/usb/usbdi_util.h> 57 #include <dev/usb/usbdivar.h> 58 #include <dev/usb/usbdevs.h> 59 #include <dev/usb/usb_quirks.h> 60 61 #if defined(__FreeBSD__) 62 #include <machine/clock.h> 63 #define delay(d) DELAY(d) 64 #endif 65 66 #ifdef USB_DEBUG 67 #define DPRINTF(x) if (usbdebug) printf x 68 #define DPRINTFN(n,x) if (usbdebug>(n)) printf x 69 extern int usbdebug; 70 #else 71 #define DPRINTF(x) 72 #define DPRINTFN(n,x) 73 #endif 74 75 static usbd_status usbd_set_config __P((usbd_device_handle, int)); 76 char *usbd_get_string __P((usbd_device_handle, int, char *)); 77 int usbd_getnewaddr __P((usbd_bus_handle bus)); 78 #if defined(__NetBSD__) 79 int usbd_print __P((void *aux, const char *pnp)); 80 int usbd_submatch __P((bdevice *, struct cfdata *cf, void *)); 81 #endif 82 void usbd_free_iface_data __P((usbd_device_handle dev, int ifcno)); 83 void usbd_kill_pipe __P((usbd_pipe_handle)); 84 usbd_status usbd_probe_and_attach 85 __P((bdevice *parent, usbd_device_handle dev, int port, int addr)); 86 87 88 #ifdef USBVERBOSE 89 typedef u_int16_t usb_vendor_id_t; 90 typedef u_int16_t usb_product_id_t; 91 92 /* 93 * Descriptions of of known vendors and devices ("products"). 94 */ 95 struct usb_knowndev { 96 usb_vendor_id_t vendor; 97 usb_product_id_t product; 98 int flags; 99 char *vendorname, *productname; 100 }; 101 #define USB_KNOWNDEV_NOPROD 0x01 /* match on vendor only */ 102 103 #include <dev/usb/usbdevs_data.h> 104 #endif /* USBVERBOSE */ 105 106 #ifdef USB_DEBUG 107 char *usbd_error_strs[] = { 108 "NORMAL_COMPLETION", 109 "IN_PROGRESS", 110 "PENDING_REQUESTS", 111 "NOT_STARTED", 112 "INVAL", 113 "IS_IDLE", 114 "NOMEM", 115 "CANCELLED", 116 "BAD_ADDRESS", 117 "IN_USE", 118 "INTERFACE_NOT_ACTIVE", 119 "NO_ADDR", 120 "SET_ADDR_FAILED", 121 "NO_POWER", 122 "TOO_DEEP", 123 "IOERROR", 124 "NOT_CONFIGURED", 125 "TIMEOUT", 126 "SHORT_XFER", 127 "STALLED", 128 "XXX", 129 }; 130 #endif 131 132 usbd_status 133 usbd_get_string_desc(dev, sindex, langid, sdesc) 134 usbd_device_handle dev; 135 int sindex; 136 int langid; 137 usb_string_descriptor_t *sdesc; 138 { 139 usb_device_request_t req; 140 usbd_status r; 141 142 req.bmRequestType = UT_READ_DEVICE; 143 req.bRequest = UR_GET_DESCRIPTOR; 144 USETW2(req.wValue, UDESC_STRING, sindex); 145 USETW(req.wIndex, langid); 146 USETW(req.wLength, 1); /* only size byte first */ 147 r = usbd_do_request(dev, &req, sdesc); 148 if (r != USBD_NORMAL_COMPLETION) 149 return (r); 150 USETW(req.wLength, sdesc->bLength); /* the whole string */ 151 return (usbd_do_request(dev, &req, sdesc)); 152 } 153 154 char * 155 usbd_get_string(dev, si, buf) 156 usbd_device_handle dev; 157 int si; 158 char *buf; 159 { 160 int swap = dev->quirks->uq_flags & UQ_SWAP_UNICODE; 161 usb_string_descriptor_t us; 162 char *s; 163 int i, n; 164 u_int16_t c; 165 usbd_status r; 166 167 if (si == 0) 168 return (0); 169 if (dev->quirks->uq_flags & UQ_NO_STRINGS) 170 return (0); 171 if (dev->langid == USBD_NOLANG) { 172 /* Set up default language */ 173 r = usbd_get_string_desc(dev, USB_LANGUAGE_TABLE, 0, &us); 174 if (r != USBD_NORMAL_COMPLETION || us.bLength < 4) { 175 dev->langid = 0; /* Well, just pick English then */ 176 } else { 177 /* Pick the first language as the default. */ 178 dev->langid = UGETW(us.bString[0]); 179 } 180 } 181 r = usbd_get_string_desc(dev, si, dev->langid, &us); 182 if (r != USBD_NORMAL_COMPLETION) 183 return (0); 184 s = buf; 185 n = us.bLength / 2 - 1; 186 for (i = 0; i < n; i++) { 187 c = UGETW(us.bString[i]); 188 /* Convert from Unicode, handle buggy strings. */ 189 if ((c & 0xff00) == 0) 190 *s++ = c; 191 else if ((c & 0x00ff) == 0 && swap) 192 *s++ = c >> 8; 193 else 194 *s++ = '?'; 195 } 196 *s++ = 0; 197 return buf; 198 } 199 200 void 201 usbd_devinfo_vp(dev, v, p) 202 usbd_device_handle dev; 203 char *v, *p; 204 { 205 usb_device_descriptor_t *udd = &dev->ddesc; 206 char *vendor = 0, *product = 0; 207 #ifdef USBVERBOSE 208 struct usb_knowndev *kdp; 209 #endif 210 211 vendor = usbd_get_string(dev, udd->iManufacturer, v); 212 product = usbd_get_string(dev, udd->iProduct, p); 213 #ifdef USBVERBOSE 214 if (!vendor) { 215 for(kdp = usb_knowndevs; 216 kdp->vendorname != NULL; 217 kdp++) { 218 if (kdp->vendor == UGETW(udd->idVendor) && 219 (kdp->product == UGETW(udd->idProduct) || 220 (kdp->flags & USB_KNOWNDEV_NOPROD) != 0)) 221 break; 222 } 223 if (kdp->vendorname == NULL) 224 vendor = product = NULL; 225 else { 226 vendor = kdp->vendorname; 227 product = (kdp->flags & USB_KNOWNDEV_NOPROD) == 0 ? 228 kdp->productname : NULL; 229 } 230 } 231 #endif 232 if (vendor) 233 strcpy(v, vendor); 234 else 235 sprintf(v, "vendor 0x%04x", UGETW(udd->idVendor)); 236 if (product) 237 strcpy(p, product); 238 else 239 sprintf(p, "product 0x%04x", UGETW(udd->idProduct)); 240 } 241 242 int 243 usbd_printBCD(cp, bcd) 244 char *cp; 245 int bcd; 246 { 247 return (sprintf(cp, "%x.%02x", bcd >> 8, bcd & 0xff)); 248 } 249 250 void 251 usbd_devinfo(dev, showclass, cp) 252 usbd_device_handle dev; 253 int showclass; 254 char *cp; 255 { 256 usb_device_descriptor_t *udd = &dev->ddesc; 257 char vendor[USB_MAX_STRING_LEN]; 258 char product[USB_MAX_STRING_LEN]; 259 int bcdDevice, bcdUSB; 260 261 usbd_devinfo_vp(dev, vendor, product); 262 cp += sprintf(cp, "%s %s", vendor, product); 263 if (showclass) 264 cp += sprintf(cp, ", class %d/%d", 265 udd->bDeviceClass, udd->bDeviceSubClass); 266 bcdUSB = UGETW(udd->bcdUSB); 267 bcdDevice = UGETW(udd->bcdDevice); 268 cp += sprintf(cp, ", rev "); 269 cp += usbd_printBCD(cp, bcdUSB); 270 *cp++ = '/'; 271 cp += usbd_printBCD(cp, bcdDevice); 272 cp += sprintf(cp, ", addr %d", dev->address); 273 *cp = 0; 274 } 275 276 /* Delay for a certain number of ms */ 277 void 278 usb_delay_ms(bus, ms) 279 usbd_bus_handle bus; 280 u_int ms; 281 { 282 /* Wait at least two clock ticks so we know the time has passed. */ 283 if (bus->use_polling) 284 delay((ms+1) * 1000); 285 else 286 tsleep(&ms, PRIBIO, "usbdly", (ms*hz+999)/1000 + 1); 287 } 288 289 /* Delay given a device handle. */ 290 void 291 usbd_delay_ms(dev, ms) 292 usbd_device_handle dev; 293 u_int ms; 294 { 295 usb_delay_ms(dev->bus, ms); 296 } 297 298 usbd_status 299 usbd_reset_port(dev, port, ps) 300 usbd_device_handle dev; 301 int port; 302 usb_port_status_t *ps; 303 { 304 usb_device_request_t req; 305 usbd_status r; 306 int n; 307 308 req.bmRequestType = UT_WRITE_CLASS_OTHER; 309 req.bRequest = UR_SET_FEATURE; 310 USETW(req.wValue, UHF_PORT_RESET); 311 USETW(req.wIndex, port); 312 USETW(req.wLength, 0); 313 r = usbd_do_request(dev, &req, 0); 314 DPRINTFN(1,("usbd_reset_port: port %d reset done, error=%d(%s)\n", 315 port, r, usbd_error_strs[r])); 316 if (r != USBD_NORMAL_COMPLETION) 317 return (r); 318 n = 10; 319 do { 320 /* Wait for device to recover from reset. */ 321 usbd_delay_ms(dev, USB_PORT_RESET_DELAY); 322 r = usbd_get_port_status(dev, port, ps); 323 if (r != USBD_NORMAL_COMPLETION) { 324 DPRINTF(("usbd_reset_port: get status failed %d\n",r)); 325 return (r); 326 } 327 } while ((UGETW(ps->wPortChange) & UPS_C_PORT_RESET) == 0 && --n > 0); 328 if (n == 0) { 329 printf("usbd_reset_port: timeout\n"); 330 return (USBD_IOERROR); 331 } 332 r = usbd_clear_port_feature(dev, port, UHF_C_PORT_RESET); 333 #ifdef USB_DEBUG 334 if (r != USBD_NORMAL_COMPLETION) 335 DPRINTF(("usbd_reset_port: clear port feature failed %d\n",r)); 336 #endif 337 338 /* Wait for the device to recover from reset. */ 339 usbd_delay_ms(dev, USB_PORT_RESET_RECOVERY); 340 return (r); 341 } 342 343 usb_interface_descriptor_t * 344 usbd_find_idesc(cd, ifaceidx, altidx) 345 usb_config_descriptor_t *cd; 346 int ifaceidx; 347 int altidx; 348 { 349 char *p = (char *)cd; 350 char *end = p + UGETW(cd->wTotalLength); 351 usb_interface_descriptor_t *d; 352 int curidx, lastidx, curaidx = 0; 353 354 for (curidx = lastidx = -1; p < end; ) { 355 d = (usb_interface_descriptor_t *)p; 356 DPRINTFN(4,("usbd_find_idesc: idx=%d(%d) altidx=%d(%d) len=%d " 357 "type=%d\n", 358 ifaceidx, curidx, altidx, curaidx, 359 d->bLength, d->bDescriptorType)); 360 if (d->bLength == 0) /* bad descriptor */ 361 break; 362 p += d->bLength; 363 if (p <= end && d->bDescriptorType == UDESC_INTERFACE) { 364 if (d->bInterfaceNumber != lastidx) { 365 lastidx = d->bInterfaceNumber; 366 curidx++; 367 curaidx = 0; 368 } else 369 curaidx++; 370 if (ifaceidx == curidx && altidx == curaidx) 371 return (d); 372 } 373 } 374 return (0); 375 } 376 377 usb_endpoint_descriptor_t * 378 usbd_find_edesc(cd, ifaceidx, altidx, endptidx) 379 usb_config_descriptor_t *cd; 380 int ifaceidx; 381 int altidx; 382 int endptidx; 383 { 384 char *p = (char *)cd; 385 char *end = p + UGETW(cd->wTotalLength); 386 usb_interface_descriptor_t *d; 387 usb_endpoint_descriptor_t *e; 388 int curidx; 389 390 d = usbd_find_idesc(cd, ifaceidx, altidx); 391 if (!d) 392 return (0); 393 if (endptidx >= d->bNumEndpoints) /* quick exit */ 394 return (0); 395 396 curidx = -1; 397 for (p = (char *)d + d->bLength; p < end; ) { 398 e = (usb_endpoint_descriptor_t *)p; 399 if (e->bLength == 0) /* bad descriptor */ 400 break; 401 p += e->bLength; 402 if (p <= end && e->bDescriptorType == UDESC_INTERFACE) 403 return (0); 404 if (p <= end && e->bDescriptorType == UDESC_ENDPOINT) { 405 curidx++; 406 if (curidx == endptidx) 407 return (e); 408 } 409 } 410 return (0); 411 } 412 413 usbd_status 414 usbd_fill_iface_data(dev, ifaceidx, altidx) 415 usbd_device_handle dev; 416 int ifaceidx; 417 int altidx; 418 { 419 usbd_interface_handle ifc = &dev->ifaces[ifaceidx]; 420 char *p, *end; 421 int endpt, nendpt; 422 423 DPRINTFN(4,("usbd_fill_iface_data: ifaceidx=%d altidx=%d\n", 424 ifaceidx, altidx)); 425 ifc->device = dev; 426 ifc->idesc = usbd_find_idesc(dev->cdesc, ifaceidx, altidx); 427 if (ifc->idesc == 0) 428 return (USBD_INVAL); 429 ifc->index = ifaceidx; 430 ifc->altindex = altidx; 431 nendpt = ifc->idesc->bNumEndpoints; 432 DPRINTFN(10,("usbd_fill_iface_data: found idesc n=%d\n", nendpt)); 433 if (nendpt != 0) { 434 ifc->endpoints = malloc(nendpt * sizeof(struct usbd_endpoint), 435 M_USB, M_NOWAIT); 436 if (ifc->endpoints == 0) 437 return (USBD_NOMEM); 438 } else 439 ifc->endpoints = 0; 440 ifc->priv = 0; 441 p = (char *)ifc->idesc + ifc->idesc->bLength; 442 end = (char *)dev->cdesc + UGETW(dev->cdesc->wTotalLength); 443 #define ed ((usb_endpoint_descriptor_t *)p) 444 for (endpt = 0; endpt < nendpt; endpt++) { 445 DPRINTFN(10,("usbd_fill_iface_data: endpt=%d\n", endpt)); 446 for (; p < end; p += ed->bLength) { 447 ed = (usb_endpoint_descriptor_t *)p; 448 DPRINTFN(10,("usbd_fill_iface_data: p=%p end=%p " 449 "len=%d type=%d\n", 450 p, end, ed->bLength, ed->bDescriptorType)); 451 if (p + ed->bLength <= end && ed->bLength != 0 && 452 ed->bDescriptorType == UDESC_ENDPOINT) 453 goto found; 454 if (ed->bDescriptorType == UDESC_INTERFACE || 455 ed->bLength == 0) 456 break; 457 } 458 /* passed end, or bad desc */ 459 goto bad; 460 found: 461 ifc->endpoints[endpt].edesc = ed; 462 ifc->endpoints[endpt].state = USBD_ENDPOINT_ACTIVE; 463 ifc->endpoints[endpt].refcnt = 0; 464 ifc->endpoints[endpt].toggle = 0; 465 p += ed->bLength; 466 } 467 #undef ed 468 LIST_INIT(&ifc->pipes); 469 ifc->state = USBD_INTERFACE_ACTIVE; 470 return (USBD_NORMAL_COMPLETION); 471 472 bad: 473 free(ifc->endpoints, M_USB); 474 return (USBD_INVAL); 475 } 476 477 void 478 usbd_free_iface_data(dev, ifcno) 479 usbd_device_handle dev; 480 int ifcno; 481 { 482 usbd_interface_handle ifc = &dev->ifaces[ifcno]; 483 if (ifc->endpoints) 484 free(ifc->endpoints, M_USB); 485 } 486 487 static usbd_status 488 usbd_set_config(dev, conf) 489 usbd_device_handle dev; 490 int conf; 491 { 492 usb_device_request_t req; 493 494 req.bmRequestType = UT_WRITE_DEVICE; 495 req.bRequest = UR_SET_CONFIG; 496 USETW(req.wValue, conf); 497 USETW(req.wIndex, 0); 498 USETW(req.wLength, 0); 499 return (usbd_do_request(dev, &req, 0)); 500 } 501 502 usbd_status 503 usbd_set_config_no(dev, no, msg) 504 usbd_device_handle dev; 505 int no; 506 int msg; 507 { 508 int index; 509 usb_config_descriptor_t cd; 510 usbd_status r; 511 512 DPRINTFN(5,("usbd_set_config_no: %d\n", no)); 513 /* Figure out what config index to use. */ 514 for (index = 0; index < dev->ddesc.bNumConfigurations; index++) { 515 r = usbd_get_config_desc(dev, index, &cd); 516 if (r != USBD_NORMAL_COMPLETION) 517 return (r); 518 if (cd.bConfigurationValue == no) 519 return (usbd_set_config_index(dev, index, msg)); 520 } 521 return (USBD_INVAL); 522 } 523 524 usbd_status 525 usbd_set_config_index(dev, index, msg) 526 usbd_device_handle dev; 527 int index; 528 int msg; 529 { 530 usb_status_t ds; 531 usb_hub_status_t hs; 532 usb_config_descriptor_t cd, *cdp; 533 usbd_status r; 534 int ifcidx, nifc, len, selfpowered, power; 535 536 DPRINTFN(5,("usbd_set_config_index: dev=%p index=%d\n", dev, index)); 537 538 /* XXX check that all interfaces are idle */ 539 if (dev->config != 0) { 540 DPRINTF(("usbd_set_config_index: free old config\n")); 541 /* Free all configuration data structures. */ 542 nifc = dev->cdesc->bNumInterface; 543 for (ifcidx = 0; ifcidx < nifc; ifcidx++) 544 usbd_free_iface_data(dev, ifcidx); 545 free(dev->ifaces, M_USB); 546 free(dev->cdesc, M_USB); 547 dev->ifaces = 0; 548 dev->cdesc = 0; 549 dev->config = 0; 550 dev->state = USBD_DEVICE_ADDRESSED; 551 } 552 553 /* Figure out what config number to use. */ 554 r = usbd_get_config_desc(dev, index, &cd); 555 if (r != USBD_NORMAL_COMPLETION) 556 return (r); 557 len = UGETW(cd.wTotalLength); 558 cdp = malloc(len, M_USB, M_NOWAIT); 559 if (cdp == 0) 560 return (USBD_NOMEM); 561 r = usbd_get_desc(dev, UDESC_CONFIG, index, len, cdp); 562 if (r != USBD_NORMAL_COMPLETION) 563 goto bad; 564 if (cdp->bDescriptorType != UDESC_CONFIG) { 565 DPRINTFN(-1,("usbd_set_config_index: bad desc %d\n", 566 cdp->bDescriptorType)); 567 r = USBD_INVAL; 568 goto bad; 569 } 570 selfpowered = 0; 571 if (cdp->bmAttributes & UC_SELF_POWERED) { 572 /* May be self powered. */ 573 if (cdp->bmAttributes & UC_BUS_POWERED) { 574 /* Must ask device. */ 575 if (dev->quirks->uq_flags & UQ_HUB_POWER) { 576 /* Buggy hub, use hub descriptor. */ 577 r = usbd_get_hub_status(dev, &hs); 578 if (r == USBD_NORMAL_COMPLETION && 579 !(UGETW(hs.wHubStatus) & UHS_LOCAL_POWER)) 580 selfpowered = 1; 581 } else { 582 r = usbd_get_device_status(dev, &ds); 583 if (r == USBD_NORMAL_COMPLETION && 584 (UGETW(ds.wStatus) & UDS_SELF_POWERED)) 585 selfpowered = 1; 586 } 587 DPRINTF(("usbd_set_config_index: status=0x%04x, " 588 "error=%d(%s)\n", 589 UGETW(ds.wStatus), r, usbd_error_strs[r])); 590 } else 591 selfpowered = 1; 592 } 593 DPRINTF(("usbd_set_config_index: (addr %d) attr=0x%02x, " 594 "selfpowered=%d, power=%d, powerquirk=%x\n", 595 dev->address, cdp->bmAttributes, 596 selfpowered, cdp->bMaxPower * 2, 597 dev->quirks->uq_flags & UQ_HUB_POWER)); 598 #ifdef USB_DEBUG 599 if (!dev->powersrc) { 600 printf("usbd_set_config_index: No power source?\n"); 601 return (USBD_IOERROR); 602 } 603 #endif 604 power = cdp->bMaxPower * 2; 605 if (power > dev->powersrc->power) { 606 /* XXX print nicer message. */ 607 if (msg) 608 printf("%s: device addr %d (config %d) exceeds power " 609 "budget, %d mA > %d mA\n", 610 USBDEVNAME(dev->bus->bdev), dev->address, 611 cdp->bConfigurationValue, 612 power, dev->powersrc->power); 613 r = USBD_NO_POWER; 614 goto bad; 615 } 616 dev->power = power; 617 dev->self_powered = selfpowered; 618 619 DPRINTF(("usbd_set_config_index: set config %d\n", 620 cdp->bConfigurationValue)); 621 r = usbd_set_config(dev, cdp->bConfigurationValue); 622 if (r != USBD_NORMAL_COMPLETION) { 623 DPRINTF(("usbd_set_config_index: setting config=%d failed, " 624 "error=%d(%s)\n", 625 cdp->bConfigurationValue, r, usbd_error_strs[r])); 626 goto bad; 627 } 628 DPRINTF(("usbd_set_config_index: setting new config %d\n", 629 cdp->bConfigurationValue)); 630 nifc = cdp->bNumInterface; 631 dev->ifaces = malloc(nifc * sizeof(struct usbd_interface), 632 M_USB, M_NOWAIT); 633 if (dev->ifaces == 0) { 634 r = USBD_NOMEM; 635 goto bad; 636 } 637 DPRINTFN(5,("usbd_set_config_index: dev=%p cdesc=%p\n", dev, cdp)); 638 dev->cdesc = cdp; 639 dev->config = cdp->bConfigurationValue; 640 dev->state = USBD_DEVICE_CONFIGURED; 641 for (ifcidx = 0; ifcidx < nifc; ifcidx++) { 642 r = usbd_fill_iface_data(dev, ifcidx, 0); 643 if (r != USBD_NORMAL_COMPLETION) { 644 while (--ifcidx >= 0) 645 usbd_free_iface_data(dev, ifcidx); 646 goto bad; 647 } 648 } 649 650 return (USBD_NORMAL_COMPLETION); 651 652 bad: 653 free(cdp, M_USB); 654 return (r); 655 } 656 657 /* XXX add function for alternate settings */ 658 659 usbd_status 660 usbd_setup_pipe(dev, iface, ep, pipe) 661 usbd_device_handle dev; 662 usbd_interface_handle iface; 663 struct usbd_endpoint *ep; 664 usbd_pipe_handle *pipe; 665 { 666 usbd_pipe_handle p; 667 usbd_status r; 668 669 DPRINTFN(1,("usbd_setup_pipe: dev=%p iface=%p ep=%p pipe=%p\n", 670 dev, iface, ep, pipe)); 671 p = malloc(dev->bus->pipe_size, M_USB, M_NOWAIT); 672 if (p == 0) 673 return (USBD_NOMEM); 674 p->device = dev; 675 p->iface = iface; 676 p->state = USBD_PIPE_ACTIVE; 677 p->endpoint = ep; 678 ep->refcnt++; 679 p->refcnt = 1; 680 p->intrreqh = 0; 681 p->running = 0; 682 p->disco = 0; 683 p->discoarg = 0; 684 SIMPLEQ_INIT(&p->queue); 685 r = dev->bus->open_pipe(p); 686 if (r != USBD_NORMAL_COMPLETION) { 687 DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error=%d" 688 "(%s)\n", 689 ep->edesc->bEndpointAddress, r, usbd_error_strs[r])); 690 free(p, M_USB); 691 return (r); 692 } 693 *pipe = p; 694 return (USBD_NORMAL_COMPLETION); 695 } 696 697 /* Abort the device control pipe. */ 698 void 699 usbd_kill_pipe(pipe) 700 usbd_pipe_handle pipe; 701 { 702 pipe->methods->close(pipe); 703 pipe->endpoint->refcnt--; 704 free(pipe, M_USB); 705 } 706 707 int 708 usbd_getnewaddr(bus) 709 usbd_bus_handle bus; 710 { 711 int addr; 712 713 for (addr = 1; addr < USB_MAX_DEVICES; addr++) 714 if (bus->devices[addr] == 0) 715 return (addr); 716 return (-1); 717 } 718 719 720 usbd_status 721 usbd_probe_and_attach(parent, dev, port, addr) 722 bdevice *parent; 723 usbd_device_handle dev; 724 int port; 725 int addr; 726 { 727 struct usb_attach_arg uaa; 728 usb_device_descriptor_t *dd = &dev->ddesc; 729 int r, found, i, confi, nifaces; 730 usbd_interface_handle ifaces[256]; /* 256 is the absolute max */ 731 732 #if defined(__FreeBSD__) 733 /* 734 * XXX uaa is a static var. Not a problem as it _should_ be used only 735 * during probe and attach. Should be changed however. 736 */ 737 bdevice bdev; 738 bdev = device_add_child(*parent, NULL, -1, &uaa); 739 if (!bdev) { 740 printf("%s: Device creation failed\n", USBDEVNAME(dev->bus->bdev)); 741 return (USBD_INVAL); 742 } 743 #endif 744 745 uaa.device = dev; 746 uaa.iface = 0; 747 uaa.ifaces = 0; 748 uaa.nifaces = 0; 749 uaa.usegeneric = 0; 750 uaa.port = port; 751 uaa.configno = UHUB_UNK_CONFIGURATION; 752 uaa.ifaceno = UHUB_UNK_INTERFACE; 753 754 /* First try with device specific drivers. */ 755 if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch)) 756 return (USBD_NORMAL_COMPLETION); 757 758 DPRINTF(("usbd_probe_and_attach: no device specific driver found\n")); 759 760 /* Next try with interface drivers. */ 761 for (confi = 0; confi < dd->bNumConfigurations; confi++) { 762 DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n", 763 confi)); 764 r = usbd_set_config_index(dev, confi, 1); 765 if (r != USBD_NORMAL_COMPLETION) { 766 #ifdef USB_DEBUG 767 DPRINTF(("%s: port %d, set config at addr %d failed, " 768 "error=%d(%s)\n", USBDEVNAME(*parent), port, 769 addr, r, usbd_error_strs[r])); 770 #else 771 printf("%s: port %d, set config at addr %d failed\n", 772 USBDEVNAME(*parent), port, addr); 773 #endif 774 #if defined(__FreeBSD__) 775 device_delete_child(*parent, bdev); 776 #endif 777 return (r); 778 } 779 nifaces = dev->cdesc->bNumInterface; 780 uaa.configno = dev->cdesc->bConfigurationValue; 781 for (i = 0; i < nifaces; i++) 782 ifaces[i] = &dev->ifaces[i]; 783 uaa.ifaces = ifaces; 784 uaa.nifaces = nifaces; 785 for (found = i = 0; i < nifaces; i++) { 786 if (!ifaces[i]) 787 continue; /* interface already claimed */ 788 uaa.iface = ifaces[i]; 789 uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; 790 if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, 791 usbd_submatch)) { 792 found++; 793 ifaces[i] = 0; /* consumed */ 794 } 795 } 796 if (found != 0) 797 return (USBD_NORMAL_COMPLETION); 798 } 799 /* No interfaces were attached in any of the configurations. */ 800 if (dd->bNumConfigurations > 1)/* don't change if only 1 config */ 801 usbd_set_config_index(dev, 0, 0); 802 803 DPRINTF(("usbd_probe_and_attach: no interface drivers found\n")); 804 805 /* Finally try the generic driver. */ 806 uaa.iface = 0; 807 uaa.usegeneric = 1; 808 uaa.configno = UHUB_UNK_CONFIGURATION; 809 uaa.ifaceno = UHUB_UNK_INTERFACE; 810 if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch)) 811 return (USBD_NORMAL_COMPLETION); 812 813 /* 814 * The generic attach failed, but leave the device as it is. 815 * We just did not find any drivers, that's all. The device is 816 * fully operational and not harming anyone. 817 */ 818 DPRINTF(("usbd_probe_and_attach: generic attach failed\n")); 819 #if defined(__FreeBSD__) 820 /* 821 * XXX should we delete the child again? Left for now to avoid dangling 822 * references. 823 device_delete_child(*parent, bdev); 824 */ 825 #endif 826 return (USBD_NORMAL_COMPLETION); 827 } 828 829 830 831 /* 832 * Called when a new device has been put in the powered state, 833 * but not yet in the addressed state. 834 * Get initial descriptor, set the address, get full descriptor, 835 * and attach a driver. 836 */ 837 usbd_status 838 usbd_new_device(parent, bus, depth, lowspeed, port, up) 839 bdevice *parent; 840 usbd_bus_handle bus; 841 int depth; 842 int lowspeed; 843 int port; 844 struct usbd_port *up; 845 { 846 usbd_device_handle dev; 847 usb_device_descriptor_t *dd; 848 usbd_status r; 849 int addr; 850 int i; 851 852 DPRINTF(("usbd_new_device bus=%p depth=%d lowspeed=%d\n", 853 bus, depth, lowspeed)); 854 addr = usbd_getnewaddr(bus); 855 if (addr < 0) { 856 printf("%s: No free USB addresses, new device ignored.\n", 857 USBDEVNAME(bus->bdev)); 858 return (USBD_NO_ADDR); 859 } 860 861 dev = malloc(sizeof *dev, M_USB, M_NOWAIT); 862 if (dev == 0) 863 return (USBD_NOMEM); 864 memset(dev, 0, sizeof(*dev)); 865 866 dev->bus = bus; 867 868 /* Set up default endpoint handle. */ 869 dev->def_ep.edesc = &dev->def_ep_desc; 870 dev->def_ep.state = USBD_ENDPOINT_ACTIVE; 871 872 /* Set up default endpoint descriptor. */ 873 dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; 874 dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT; 875 dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT; 876 dev->def_ep_desc.bmAttributes = UE_CONTROL; 877 USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET); 878 dev->def_ep_desc.bInterval = 0; 879 880 dev->state = USBD_DEVICE_DEFAULT; 881 dev->quirks = &usbd_no_quirk; 882 dev->address = USB_START_ADDR; 883 dev->ddesc.bMaxPacketSize = 0; 884 dev->lowspeed = lowspeed != 0; 885 dev->depth = depth; 886 dev->powersrc = up; 887 dev->langid = USBD_NOLANG; 888 889 /* Establish the the default pipe. */ 890 r = usbd_setup_pipe(dev, 0, &dev->def_ep, &dev->default_pipe); 891 if (r != USBD_NORMAL_COMPLETION) { 892 usbd_remove_device(dev, up); 893 return (r); 894 } 895 896 up->device = dev; 897 dd = &dev->ddesc; 898 /* Try a few times in case the device is slow (i.e. outside specs.) */ 899 for (i = 0; i < 5; i++) { 900 /* Get the first 8 bytes of the device descriptor. */ 901 r = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd); 902 if (r == USBD_NORMAL_COMPLETION) 903 break; 904 usbd_delay_ms(dev, 200); 905 } 906 if (r != USBD_NORMAL_COMPLETION) { 907 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc " 908 "failed\n", 909 addr)); 910 usbd_remove_device(dev, up); 911 return (r); 912 } 913 914 if (dd->bDescriptorType != UDESC_DEVICE) { 915 /* Illegal device descriptor */ 916 DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n", 917 dd->bDescriptorType)); 918 usbd_remove_device(dev, up); 919 return (USBD_INVAL); 920 } 921 922 DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, " 923 "subclass=%d, protocol=%d, maxpacket=%d, ls=%d\n", 924 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass, 925 dd->bDeviceProtocol, dd->bMaxPacketSize, dev->lowspeed)); 926 927 USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize); 928 929 /* Get the full device descriptor. */ 930 r = usbd_get_device_desc(dev, dd); 931 if (r != USBD_NORMAL_COMPLETION) { 932 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc " 933 "failed\n", addr)); 934 usbd_remove_device(dev, up); 935 return (r); 936 } 937 938 /* Figure out what's wrong with this device. */ 939 dev->quirks = usbd_find_quirk(dd); 940 941 /* Set the address */ 942 r = usbd_set_address(dev, addr); 943 if (r != USBD_NORMAL_COMPLETION) { 944 DPRINTFN(-1,("usb_new_device: set address %d failed\n",addr)); 945 r = USBD_SET_ADDR_FAILED; 946 usbd_remove_device(dev, up); 947 return (r); 948 } 949 /* Allow device time to set new address */ 950 usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE); 951 952 dev->address = addr; /* New device address now */ 953 dev->state = USBD_DEVICE_ADDRESSED; 954 bus->devices[addr] = dev; 955 956 /* Assume 100mA bus powered for now. Changed when configured. */ 957 dev->power = USB_MIN_POWER; 958 dev->self_powered = 0; 959 960 DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n", 961 addr, dev, parent)); 962 963 r = usbd_probe_and_attach(parent, dev, port, addr); 964 if (r != USBD_NORMAL_COMPLETION) { 965 usbd_remove_device(dev, up); 966 return (r); 967 } 968 969 return (USBD_NORMAL_COMPLETION); 970 } 971 972 void 973 usbd_remove_device(dev, up) 974 usbd_device_handle dev; 975 struct usbd_port *up; 976 { 977 DPRINTF(("usbd_remove_device: %p\n", dev)); 978 979 if (dev->default_pipe) 980 usbd_kill_pipe(dev->default_pipe); 981 up->device = 0; 982 dev->bus->devices[dev->address] = 0; 983 984 free(dev, M_USB); 985 } 986 987 #if defined(__NetBSD__) 988 int 989 usbd_print(aux, pnp) 990 void *aux; 991 const char *pnp; 992 { 993 struct usb_attach_arg *uaa = aux; 994 char devinfo[1024]; 995 996 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device)); 997 if (pnp) { 998 if (!uaa->usegeneric) 999 return (QUIET); 1000 usbd_devinfo(uaa->device, 1, devinfo); 1001 printf("%s, %s", devinfo, pnp); 1002 } 1003 if (uaa->port != 0) 1004 printf(" port %d", uaa->port); 1005 if (uaa->configno != UHUB_UNK_CONFIGURATION) 1006 printf(" configuration %d", uaa->configno); 1007 if (uaa->ifaceno != UHUB_UNK_INTERFACE) 1008 printf(" interface %d", uaa->ifaceno); 1009 return (UNCONF); 1010 } 1011 1012 int 1013 usbd_submatch(parent, cf, aux) 1014 struct device *parent; 1015 struct cfdata *cf; 1016 void *aux; 1017 { 1018 struct usb_attach_arg *uaa = aux; 1019 1020 if ((uaa->port != 0 && 1021 cf->uhubcf_port != UHUB_UNK_PORT && 1022 cf->uhubcf_port != uaa->port) || 1023 (uaa->configno != UHUB_UNK_CONFIGURATION && 1024 cf->uhubcf_configuration != UHUB_UNK_CONFIGURATION && 1025 cf->uhubcf_configuration != uaa->configno) || 1026 (uaa->ifaceno != UHUB_UNK_INTERFACE && 1027 cf->uhubcf_interface != UHUB_UNK_INTERFACE && 1028 cf->uhubcf_interface != uaa->ifaceno)) 1029 return 0; 1030 return ((*cf->cf_attach->ca_match)(parent, cf, aux)); 1031 } 1032 1033 #elif defined(__FreeBSD__) 1034 static void 1035 usbd_bus_print_child(device_t bus, device_t dev) 1036 { 1037 /* FIXME print the device address and the configuration used 1038 */ 1039 } 1040 #endif 1041 1042 usbd_status 1043 usb_insert_transfer(reqh) 1044 usbd_request_handle reqh; 1045 { 1046 usbd_pipe_handle pipe = reqh->pipe; 1047 usbd_interface_handle iface = pipe->iface; 1048 1049 if (pipe->state == USBD_PIPE_IDLE || 1050 (iface && iface->state == USBD_INTERFACE_IDLE)) 1051 return (USBD_IS_IDLE); 1052 SIMPLEQ_INSERT_TAIL(&pipe->queue, reqh, next); 1053 if (pipe->state != USBD_PIPE_ACTIVE || 1054 (iface && iface->state != USBD_INTERFACE_ACTIVE)) 1055 return (USBD_NOT_STARTED); 1056 if (pipe->running) 1057 return (USBD_IN_PROGRESS); 1058 pipe->running = 1; 1059 return (USBD_NORMAL_COMPLETION); 1060 } 1061 1062 void 1063 usb_start_next(pipe) 1064 usbd_pipe_handle pipe; 1065 { 1066 usbd_request_handle reqh; 1067 usbd_status r; 1068 1069 #ifdef DIAGNOSTIC 1070 if (SIMPLEQ_FIRST(&pipe->queue) == 0) { 1071 printf("usb_start_next: empty\n"); 1072 return; 1073 } 1074 #endif 1075 1076 /* First remove remove old */ 1077 SIMPLEQ_REMOVE_HEAD(&pipe->queue, SIMPLEQ_FIRST(&pipe->queue), next); 1078 if (pipe->state != USBD_PIPE_ACTIVE) { 1079 pipe->running = 0; 1080 return; 1081 } 1082 reqh = SIMPLEQ_FIRST(&pipe->queue); 1083 DPRINTFN(5, ("usb_start_next: start reqh=%p\n", reqh)); 1084 if (!reqh) 1085 pipe->running = 0; 1086 else { 1087 r = pipe->methods->start(reqh); 1088 if (r != USBD_IN_PROGRESS) { 1089 printf("usb_start_next: error=%d\n", r); 1090 pipe->running = 0; 1091 /* XXX do what? */ 1092 } 1093 } 1094 } 1095 1096 void 1097 usbd_fill_deviceinfo(dev, di) 1098 usbd_device_handle dev; 1099 struct usb_device_info *di; 1100 { 1101 struct usbd_port *p; 1102 int i, r, s; 1103 1104 di->config = dev->config; 1105 usbd_devinfo_vp(dev, di->vendor, di->product); 1106 usbd_printBCD(di->revision, UGETW(dev->ddesc.bcdDevice)); 1107 di->vendorNo = UGETW(dev->ddesc.idVendor); 1108 di->productNo = UGETW(dev->ddesc.idProduct); 1109 di->class = dev->ddesc.bDeviceClass; 1110 di->power = dev->self_powered ? 0 : dev->power; 1111 di->lowspeed = dev->lowspeed; 1112 di->addr = dev->address; 1113 if (dev->hub) { 1114 for (i = 0; 1115 i < sizeof(di->ports) / sizeof(di->ports[0]) && 1116 i < dev->hub->hubdesc.bNbrPorts; 1117 i++) { 1118 p = &dev->hub->ports[i]; 1119 if (p->device) 1120 r = p->device->address; 1121 else { 1122 s = UGETW(p->status.wPortStatus); 1123 if (s & UPS_PORT_ENABLED) 1124 r = USB_PORT_ENABLED; 1125 else if (s & UPS_SUSPEND) 1126 r = USB_PORT_SUSPENDED; 1127 else if (s & UPS_PORT_POWER) 1128 r = USB_PORT_POWERED; 1129 else 1130 r = USB_PORT_DISABLED; 1131 } 1132 di->ports[i] = r; 1133 } 1134 di->nports = dev->hub->hubdesc.bNbrPorts; 1135 } else 1136 di->nports = 0; 1137 } 1138