1 /* $NetBSD: usb_subr.c,v 1.28 1999/01/10 19:13:16 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 SIMPLEQ_INIT(&p->queue); 683 r = dev->bus->open_pipe(p); 684 if (r != USBD_NORMAL_COMPLETION) { 685 DPRINTFN(-1,("usbd_setup_pipe: endpoint=0x%x failed, error=%d" 686 "(%s)\n", 687 ep->edesc->bEndpointAddress, r, usbd_error_strs[r])); 688 free(p, M_USB); 689 return (r); 690 } 691 *pipe = p; 692 return (USBD_NORMAL_COMPLETION); 693 } 694 695 /* Abort the device control pipe. */ 696 void 697 usbd_kill_pipe(pipe) 698 usbd_pipe_handle pipe; 699 { 700 pipe->methods->close(pipe); 701 pipe->endpoint->refcnt--; 702 free(pipe, M_USB); 703 } 704 705 int 706 usbd_getnewaddr(bus) 707 usbd_bus_handle bus; 708 { 709 int addr; 710 711 for (addr = 1; addr < USB_MAX_DEVICES; addr++) 712 if (bus->devices[addr] == 0) 713 return (addr); 714 return (-1); 715 } 716 717 718 usbd_status 719 usbd_probe_and_attach(parent, dev, port, addr) 720 bdevice *parent; 721 usbd_device_handle dev; 722 int port; 723 int addr; 724 { 725 struct usb_attach_arg uaa; 726 usb_device_descriptor_t *dd = &dev->ddesc; 727 int r, found, i, confi, nifaces; 728 usbd_interface_handle ifaces[256]; /* 256 is the absolute max */ 729 730 #if defined(__FreeBSD__) 731 /* 732 * XXX uaa is a static var. Not a problem as it _should_ be used only 733 * during probe and attach. Should be changed however. 734 */ 735 bdevice bdev; 736 bdev = device_add_child(*parent, NULL, -1, &uaa); 737 if (!bdev) { 738 printf("%s: Device creation failed\n", USBDEVNAME(dev->bus->bdev)); 739 return (USBD_INVAL); 740 } 741 #endif 742 743 uaa.device = dev; 744 uaa.iface = 0; 745 uaa.ifaces = 0; 746 uaa.nifaces = 0; 747 uaa.usegeneric = 0; 748 uaa.port = port; 749 uaa.configno = UHUB_UNK_CONFIGURATION; 750 uaa.ifaceno = UHUB_UNK_INTERFACE; 751 752 /* First try with device specific drivers. */ 753 if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch)) 754 return (USBD_NORMAL_COMPLETION); 755 756 DPRINTF(("usbd_probe_and_attach: no device specific driver found\n")); 757 758 /* Next try with interface drivers. */ 759 for (confi = 0; confi < dd->bNumConfigurations; confi++) { 760 DPRINTFN(1,("usbd_probe_and_attach: trying config idx=%d\n", 761 confi)); 762 r = usbd_set_config_index(dev, confi, 1); 763 if (r != USBD_NORMAL_COMPLETION) { 764 #ifdef USB_DEBUG 765 DPRINTF(("%s: port %d, set config at addr %d failed, " 766 "error=%d(%s)\n", USBDEVNAME(*parent), port, 767 addr, r, usbd_error_strs[r])); 768 #else 769 printf("%s: port %d, set config at addr %d failed\n", 770 USBDEVNAME(*parent), port, addr); 771 #endif 772 #if defined(__FreeBSD__) 773 device_delete_child(*parent, bdev); 774 #endif 775 return (r); 776 } 777 nifaces = dev->cdesc->bNumInterface; 778 uaa.configno = dev->cdesc->bConfigurationValue; 779 for (i = 0; i < nifaces; i++) 780 ifaces[i] = &dev->ifaces[i]; 781 uaa.ifaces = ifaces; 782 uaa.nifaces = nifaces; 783 for (found = i = 0; i < nifaces; i++) { 784 if (!ifaces[i]) 785 continue; /* interface already claimed */ 786 uaa.iface = ifaces[i]; 787 uaa.ifaceno = ifaces[i]->idesc->bInterfaceNumber; 788 if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, 789 usbd_submatch)) { 790 found++; 791 ifaces[i] = 0; /* consumed */ 792 } 793 } 794 if (found != 0) 795 return (USBD_NORMAL_COMPLETION); 796 } 797 /* No interfaces were attached in any of the configurations. */ 798 if (dd->bNumConfigurations > 1)/* don't change if only 1 config */ 799 usbd_set_config_index(dev, 0, 0); 800 801 DPRINTF(("usbd_probe_and_attach: no interface drivers found\n")); 802 803 /* Finally try the generic driver. */ 804 uaa.iface = 0; 805 uaa.usegeneric = 1; 806 uaa.configno = UHUB_UNK_CONFIGURATION; 807 uaa.ifaceno = UHUB_UNK_INTERFACE; 808 if (USB_DO_ATTACH(dev, bdev, parent, &uaa, usbd_print, usbd_submatch)) 809 return (USBD_NORMAL_COMPLETION); 810 811 /* 812 * The generic attach failed, but leave the device as it is. 813 * We just did not find any drivers, that's all. The device is 814 * fully operational and not harming anyone. 815 */ 816 DPRINTF(("usbd_probe_and_attach: generic attach failed\n")); 817 #if defined(__FreeBSD__) 818 /* 819 * XXX should we delete the child again? Left for now to avoid dangling 820 * references. 821 device_delete_child(*parent, bdev); 822 */ 823 #endif 824 return (USBD_NORMAL_COMPLETION); 825 } 826 827 828 829 /* 830 * Called when a new device has been put in the powered state, 831 * but not yet in the addressed state. 832 * Get initial descriptor, set the address, get full descriptor, 833 * and attach a driver. 834 */ 835 usbd_status 836 usbd_new_device(parent, bus, depth, lowspeed, port, up) 837 bdevice *parent; 838 usbd_bus_handle bus; 839 int depth; 840 int lowspeed; 841 int port; 842 struct usbd_port *up; 843 { 844 usbd_device_handle dev; 845 usb_device_descriptor_t *dd; 846 usbd_status r; 847 int addr; 848 int i; 849 850 DPRINTF(("usbd_new_device bus=%p depth=%d lowspeed=%d\n", 851 bus, depth, lowspeed)); 852 addr = usbd_getnewaddr(bus); 853 if (addr < 0) { 854 printf("%s: No free USB addresses, new device ignored.\n", 855 USBDEVNAME(bus->bdev)); 856 return (USBD_NO_ADDR); 857 } 858 859 dev = malloc(sizeof *dev, M_USB, M_NOWAIT); 860 if (dev == 0) 861 return (USBD_NOMEM); 862 memset(dev, 0, sizeof(*dev)); 863 864 dev->bus = bus; 865 866 /* Set up default endpoint handle. */ 867 dev->def_ep.edesc = &dev->def_ep_desc; 868 dev->def_ep.state = USBD_ENDPOINT_ACTIVE; 869 870 /* Set up default endpoint descriptor. */ 871 dev->def_ep_desc.bLength = USB_ENDPOINT_DESCRIPTOR_SIZE; 872 dev->def_ep_desc.bDescriptorType = UDESC_ENDPOINT; 873 dev->def_ep_desc.bEndpointAddress = USB_CONTROL_ENDPOINT; 874 dev->def_ep_desc.bmAttributes = UE_CONTROL; 875 USETW(dev->def_ep_desc.wMaxPacketSize, USB_MAX_IPACKET); 876 dev->def_ep_desc.bInterval = 0; 877 878 dev->state = USBD_DEVICE_DEFAULT; 879 dev->quirks = &usbd_no_quirk; 880 dev->address = USB_START_ADDR; 881 dev->ddesc.bMaxPacketSize = 0; 882 dev->lowspeed = lowspeed != 0; 883 dev->depth = depth; 884 dev->powersrc = up; 885 dev->langid = USBD_NOLANG; 886 887 /* Establish the the default pipe. */ 888 r = usbd_setup_pipe(dev, 0, &dev->def_ep, &dev->default_pipe); 889 if (r != USBD_NORMAL_COMPLETION) { 890 usbd_remove_device(dev, up); 891 return (r); 892 } 893 894 up->device = dev; 895 dd = &dev->ddesc; 896 /* Try a few times in case the device is slow (i.e. outside specs.) */ 897 for (i = 0; i < 5; i++) { 898 /* Get the first 8 bytes of the device descriptor. */ 899 r = usbd_get_desc(dev, UDESC_DEVICE, 0, USB_MAX_IPACKET, dd); 900 if (r == USBD_NORMAL_COMPLETION) 901 break; 902 usbd_delay_ms(dev, 200); 903 } 904 if (r != USBD_NORMAL_COMPLETION) { 905 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting first desc " 906 "failed\n", 907 addr)); 908 usbd_remove_device(dev, up); 909 return (r); 910 } 911 912 if (dd->bDescriptorType != UDESC_DEVICE) { 913 /* Illegal device descriptor */ 914 DPRINTFN(-1,("usbd_new_device: illegal descriptor %d\n", 915 dd->bDescriptorType)); 916 usbd_remove_device(dev, up); 917 return (USBD_INVAL); 918 } 919 920 DPRINTF(("usbd_new_device: adding unit addr=%d, rev=%02x, class=%d, " 921 "subclass=%d, protocol=%d, maxpacket=%d, ls=%d\n", 922 addr,UGETW(dd->bcdUSB), dd->bDeviceClass, dd->bDeviceSubClass, 923 dd->bDeviceProtocol, dd->bMaxPacketSize, dev->lowspeed)); 924 925 USETW(dev->def_ep_desc.wMaxPacketSize, dd->bMaxPacketSize); 926 927 /* Get the full device descriptor. */ 928 r = usbd_get_device_desc(dev, dd); 929 if (r != USBD_NORMAL_COMPLETION) { 930 DPRINTFN(-1, ("usbd_new_device: addr=%d, getting full desc " 931 "failed\n", addr)); 932 usbd_remove_device(dev, up); 933 return (r); 934 } 935 936 /* Figure out what's wrong with this device. */ 937 dev->quirks = usbd_find_quirk(dd); 938 939 /* Set the address */ 940 r = usbd_set_address(dev, addr); 941 if (r != USBD_NORMAL_COMPLETION) { 942 DPRINTFN(-1,("usb_new_device: set address %d failed\n",addr)); 943 r = USBD_SET_ADDR_FAILED; 944 usbd_remove_device(dev, up); 945 return (r); 946 } 947 /* Allow device time to set new address */ 948 usbd_delay_ms(dev, USB_SET_ADDRESS_SETTLE); 949 950 dev->address = addr; /* New device address now */ 951 dev->state = USBD_DEVICE_ADDRESSED; 952 bus->devices[addr] = dev; 953 954 /* Assume 100mA bus powered for now. Changed when configured. */ 955 dev->power = USB_MIN_POWER; 956 dev->self_powered = 0; 957 958 DPRINTF(("usbd_new_device: new dev (addr %d), dev=%p, parent=%p\n", 959 addr, dev, parent)); 960 961 r = usbd_probe_and_attach(parent, dev, port, addr); 962 if (r != USBD_NORMAL_COMPLETION) { 963 usbd_remove_device(dev, up); 964 return (r); 965 } 966 967 return (USBD_NORMAL_COMPLETION); 968 } 969 970 void 971 usbd_remove_device(dev, up) 972 usbd_device_handle dev; 973 struct usbd_port *up; 974 { 975 DPRINTF(("usbd_remove_device: %p\n", dev)); 976 977 if (dev->default_pipe) 978 usbd_kill_pipe(dev->default_pipe); 979 up->device = 0; 980 dev->bus->devices[dev->address] = 0; 981 982 free(dev, M_USB); 983 } 984 985 #if defined(__NetBSD__) 986 int 987 usbd_print(aux, pnp) 988 void *aux; 989 const char *pnp; 990 { 991 struct usb_attach_arg *uaa = aux; 992 char devinfo[1024]; 993 994 DPRINTFN(15, ("usbd_print dev=%p\n", uaa->device)); 995 if (pnp) { 996 if (!uaa->usegeneric) 997 return (QUIET); 998 usbd_devinfo(uaa->device, 1, devinfo); 999 printf("%s, %s", devinfo, pnp); 1000 } 1001 if (uaa->port != 0) 1002 printf(" port %d", uaa->port); 1003 if (uaa->configno != UHUB_UNK_CONFIGURATION) 1004 printf(" configuration %d", uaa->configno); 1005 if (uaa->ifaceno != UHUB_UNK_INTERFACE) 1006 printf(" interface %d", uaa->ifaceno); 1007 return (UNCONF); 1008 } 1009 1010 int 1011 usbd_submatch(parent, cf, aux) 1012 struct device *parent; 1013 struct cfdata *cf; 1014 void *aux; 1015 { 1016 struct usb_attach_arg *uaa = aux; 1017 1018 if ((uaa->port != 0 && 1019 cf->uhubcf_port != UHUB_UNK_PORT && 1020 cf->uhubcf_port != uaa->port) || 1021 (uaa->configno != UHUB_UNK_CONFIGURATION && 1022 cf->uhubcf_configuration != UHUB_UNK_CONFIGURATION && 1023 cf->uhubcf_configuration != uaa->configno) || 1024 (uaa->ifaceno != UHUB_UNK_INTERFACE && 1025 cf->uhubcf_interface != UHUB_UNK_INTERFACE && 1026 cf->uhubcf_interface != uaa->ifaceno)) 1027 return 0; 1028 return ((*cf->cf_attach->ca_match)(parent, cf, aux)); 1029 } 1030 1031 #elif defined(__FreeBSD__) 1032 static void 1033 usbd_bus_print_child(device_t bus, device_t dev) 1034 { 1035 /* FIXME print the device address and the configuration used 1036 */ 1037 } 1038 #endif 1039 1040 usbd_status 1041 usb_insert_transfer(reqh) 1042 usbd_request_handle reqh; 1043 { 1044 usbd_pipe_handle pipe = reqh->pipe; 1045 usbd_interface_handle iface = pipe->iface; 1046 1047 if (pipe->state == USBD_PIPE_IDLE || 1048 (iface && iface->state == USBD_INTERFACE_IDLE)) 1049 return (USBD_IS_IDLE); 1050 SIMPLEQ_INSERT_TAIL(&pipe->queue, reqh, next); 1051 if (pipe->state != USBD_PIPE_ACTIVE || 1052 (iface && iface->state != USBD_INTERFACE_ACTIVE)) 1053 return (USBD_NOT_STARTED); 1054 if (pipe->running) 1055 return (USBD_IN_PROGRESS); 1056 pipe->running = 1; 1057 return (USBD_NORMAL_COMPLETION); 1058 } 1059 1060 void 1061 usb_start_next(pipe) 1062 usbd_pipe_handle pipe; 1063 { 1064 usbd_request_handle reqh; 1065 usbd_status r; 1066 1067 #ifdef DIAGNOSTIC 1068 if (SIMPLEQ_FIRST(&pipe->queue) == 0) { 1069 printf("usb_start_next: empty\n"); 1070 return; 1071 } 1072 #endif 1073 1074 /* First remove remove old */ 1075 SIMPLEQ_REMOVE_HEAD(&pipe->queue, SIMPLEQ_FIRST(&pipe->queue), next); 1076 if (pipe->state != USBD_PIPE_ACTIVE) { 1077 pipe->running = 0; 1078 return; 1079 } 1080 reqh = SIMPLEQ_FIRST(&pipe->queue); 1081 DPRINTFN(5, ("usb_start_next: start reqh=%p\n", reqh)); 1082 if (!reqh) 1083 pipe->running = 0; 1084 else { 1085 r = pipe->methods->start(reqh); 1086 if (r != USBD_IN_PROGRESS) { 1087 printf("usb_start_next: error=%d\n", r); 1088 pipe->running = 0; 1089 /* XXX do what? */ 1090 } 1091 } 1092 } 1093 1094 void 1095 usbd_fill_deviceinfo(dev, di) 1096 usbd_device_handle dev; 1097 struct usb_device_info *di; 1098 { 1099 struct usbd_port *p; 1100 int i, r, s; 1101 1102 di->config = dev->config; 1103 usbd_devinfo_vp(dev, di->vendor, di->product); 1104 usbd_printBCD(di->revision, UGETW(dev->ddesc.bcdDevice)); 1105 di->vendorNo = UGETW(dev->ddesc.idVendor); 1106 di->productNo = UGETW(dev->ddesc.idProduct); 1107 di->class = dev->ddesc.bDeviceClass; 1108 di->power = dev->self_powered ? 0 : dev->power; 1109 di->lowspeed = dev->lowspeed; 1110 di->addr = dev->address; 1111 if (dev->hub) { 1112 for (i = 0; 1113 i < sizeof(di->ports) / sizeof(di->ports[0]) && 1114 i < dev->hub->hubdesc.bNbrPorts; 1115 i++) { 1116 p = &dev->hub->ports[i]; 1117 if (p->device) 1118 r = p->device->address; 1119 else { 1120 s = UGETW(p->status.wPortStatus); 1121 if (s & UPS_PORT_ENABLED) 1122 r = USB_PORT_ENABLED; 1123 else if (s & UPS_SUSPEND) 1124 r = USB_PORT_SUSPENDED; 1125 else if (s & UPS_PORT_POWER) 1126 r = USB_PORT_POWERED; 1127 else 1128 r = USB_PORT_DISABLED; 1129 } 1130 di->ports[i] = r; 1131 } 1132 di->nports = dev->hub->hubdesc.bNbrPorts; 1133 } else 1134 di->nports = 0; 1135 } 1136