1 /* $FreeBSD$ */ 2 /*- 3 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 4 * 5 * Copyright (c) 2007 Hans Petter Selasky. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* 30 * This file contains sub-routines to build up USB descriptors from 31 * USB templates. 32 */ 33 34 #ifdef USB_GLOBAL_INCLUDE_FILE 35 #include USB_GLOBAL_INCLUDE_FILE 36 #else 37 #include <sys/stdint.h> 38 #include <sys/stddef.h> 39 #include <sys/param.h> 40 #include <sys/queue.h> 41 #include <sys/types.h> 42 #include <sys/systm.h> 43 #include <sys/kernel.h> 44 #include <sys/bus.h> 45 #include <sys/module.h> 46 #include <sys/lock.h> 47 #include <sys/mutex.h> 48 #include <sys/condvar.h> 49 #include <sys/sysctl.h> 50 #include <sys/sx.h> 51 #include <sys/unistd.h> 52 #include <sys/callout.h> 53 #include <sys/malloc.h> 54 #include <sys/priv.h> 55 56 #include <dev/usb/usb.h> 57 #include <dev/usb/usb_ioctl.h> 58 #include <dev/usb/usbdi.h> 59 #include <dev/usb/usbdi_util.h> 60 #include "usbdevs.h" 61 62 #include <dev/usb/usb_cdc.h> 63 #include <dev/usb/usb_core.h> 64 #include <dev/usb/usb_dynamic.h> 65 #include <dev/usb/usb_busdma.h> 66 #include <dev/usb/usb_process.h> 67 #include <dev/usb/usb_device.h> 68 #include <dev/usb/usb_util.h> 69 70 #define USB_DEBUG_VAR usb_debug 71 #include <dev/usb/usb_debug.h> 72 73 #include <dev/usb/usb_controller.h> 74 #include <dev/usb/usb_bus.h> 75 #include <dev/usb/usb_request.h> 76 #include <dev/usb/template/usb_template.h> 77 #endif /* USB_GLOBAL_INCLUDE_FILE */ 78 79 SYSCTL_NODE(_hw_usb, OID_AUTO, templates, CTLFLAG_RW, 0, 80 "USB device side templates"); 81 82 MODULE_DEPEND(usb_template, usb, 1, 1, 1); 83 MODULE_VERSION(usb_template, 1); 84 85 /* function prototypes */ 86 87 static void usb_make_raw_desc(struct usb_temp_setup *, const uint8_t *); 88 static void usb_make_endpoint_desc(struct usb_temp_setup *, 89 const struct usb_temp_endpoint_desc *); 90 static void usb_make_interface_desc(struct usb_temp_setup *, 91 const struct usb_temp_interface_desc *); 92 static void usb_make_config_desc(struct usb_temp_setup *, 93 const struct usb_temp_config_desc *); 94 static void usb_make_device_desc(struct usb_temp_setup *, 95 const struct usb_temp_device_desc *); 96 static uint8_t usb_hw_ep_match(const struct usb_hw_ep_profile *, uint8_t, 97 uint8_t); 98 static uint8_t usb_hw_ep_find_match(struct usb_hw_ep_scratch *, 99 struct usb_hw_ep_scratch_sub *, uint8_t); 100 static uint8_t usb_hw_ep_get_needs(struct usb_hw_ep_scratch *, uint8_t, 101 uint8_t); 102 static usb_error_t usb_hw_ep_resolve(struct usb_device *, 103 struct usb_descriptor *); 104 static const struct usb_temp_device_desc *usb_temp_get_tdd(struct usb_device *); 105 static void *usb_temp_get_device_desc(struct usb_device *); 106 static void *usb_temp_get_qualifier_desc(struct usb_device *); 107 static void *usb_temp_get_config_desc(struct usb_device *, uint16_t *, 108 uint8_t); 109 static const void *usb_temp_get_string_desc(struct usb_device *, uint16_t, 110 uint8_t); 111 static const void *usb_temp_get_vendor_desc(struct usb_device *, 112 const struct usb_device_request *, uint16_t *plen); 113 static const void *usb_temp_get_hub_desc(struct usb_device *); 114 static usb_error_t usb_temp_get_desc(struct usb_device *, 115 struct usb_device_request *, const void **, uint16_t *); 116 static usb_error_t usb_temp_setup_by_index(struct usb_device *, 117 uint16_t index); 118 static void usb_temp_init(void *); 119 120 /*------------------------------------------------------------------------* 121 * usb_decode_str_desc 122 * 123 * Helper function to decode string descriptors into a C string. 124 *------------------------------------------------------------------------*/ 125 void 126 usb_decode_str_desc(struct usb_string_descriptor *sd, char *buf, size_t buflen) 127 { 128 size_t i; 129 130 if (sd->bLength < 2) { 131 buf[0] = '\0'; 132 return; 133 } 134 135 for (i = 0; i < buflen - 1 && i < (sd->bLength / 2) - 1; i++) 136 buf[i] = UGETW(sd->bString[i]); 137 138 buf[i] = '\0'; 139 } 140 141 /*------------------------------------------------------------------------* 142 * usb_temp_sysctl 143 * 144 * Callback for SYSCTL_PROC(9), to set and retrieve template string 145 * descriptors. 146 *------------------------------------------------------------------------*/ 147 int 148 usb_temp_sysctl(SYSCTL_HANDLER_ARGS) 149 { 150 char buf[128]; 151 struct usb_string_descriptor *sd = arg1; 152 size_t len, sdlen = arg2; 153 int error; 154 155 usb_decode_str_desc(sd, buf, sizeof(buf)); 156 157 error = sysctl_handle_string(oidp, buf, sizeof(buf), req); 158 if (error != 0 || req->newptr == NULL) 159 return (error); 160 161 len = usb_make_str_desc(sd, sdlen, buf); 162 if (len == 0) 163 return (EINVAL); 164 165 return (0); 166 } 167 168 169 /*------------------------------------------------------------------------* 170 * usb_make_raw_desc 171 * 172 * This function will insert a raw USB descriptor into the generated 173 * USB configuration. 174 *------------------------------------------------------------------------*/ 175 static void 176 usb_make_raw_desc(struct usb_temp_setup *temp, 177 const uint8_t *raw) 178 { 179 void *dst; 180 uint8_t len; 181 182 /* 183 * The first byte of any USB descriptor gives the length. 184 */ 185 if (raw) { 186 len = raw[0]; 187 if (temp->buf) { 188 dst = USB_ADD_BYTES(temp->buf, temp->size); 189 memcpy(dst, raw, len); 190 191 /* check if we have got a CDC union descriptor */ 192 193 if ((raw[0] == sizeof(struct usb_cdc_union_descriptor)) && 194 (raw[1] == UDESC_CS_INTERFACE) && 195 (raw[2] == UDESCSUB_CDC_UNION)) { 196 struct usb_cdc_union_descriptor *ud = (void *)dst; 197 198 /* update the interface numbers */ 199 200 ud->bMasterInterface += 201 temp->bInterfaceNumber; 202 ud->bSlaveInterface[0] += 203 temp->bInterfaceNumber; 204 } 205 206 /* check if we have got an interface association descriptor */ 207 208 if ((raw[0] == sizeof(struct usb_interface_assoc_descriptor)) && 209 (raw[1] == UDESC_IFACE_ASSOC)) { 210 struct usb_interface_assoc_descriptor *iad = (void *)dst; 211 212 /* update the interface number */ 213 214 iad->bFirstInterface += 215 temp->bInterfaceNumber; 216 } 217 218 /* check if we have got a call management descriptor */ 219 220 if ((raw[0] == sizeof(struct usb_cdc_cm_descriptor)) && 221 (raw[1] == UDESC_CS_INTERFACE) && 222 (raw[2] == UDESCSUB_CDC_CM)) { 223 struct usb_cdc_cm_descriptor *ccd = (void *)dst; 224 225 /* update the interface number */ 226 227 ccd->bDataInterface += 228 temp->bInterfaceNumber; 229 } 230 } 231 temp->size += len; 232 } 233 } 234 235 /*------------------------------------------------------------------------* 236 * usb_make_endpoint_desc 237 * 238 * This function will generate an USB endpoint descriptor from the 239 * given USB template endpoint descriptor, which will be inserted into 240 * the USB configuration. 241 *------------------------------------------------------------------------*/ 242 static void 243 usb_make_endpoint_desc(struct usb_temp_setup *temp, 244 const struct usb_temp_endpoint_desc *ted) 245 { 246 struct usb_endpoint_descriptor *ed; 247 const void **rd; 248 uint16_t old_size; 249 uint16_t mps; 250 uint8_t ea; /* Endpoint Address */ 251 uint8_t et; /* Endpiont Type */ 252 253 /* Reserve memory */ 254 old_size = temp->size; 255 256 ea = (ted->bEndpointAddress & (UE_ADDR | UE_DIR_IN | UE_DIR_OUT)); 257 et = (ted->bmAttributes & UE_XFERTYPE); 258 259 if (et == UE_ISOCHRONOUS) { 260 /* account for extra byte fields */ 261 temp->size += sizeof(*ed) + 2; 262 } else { 263 temp->size += sizeof(*ed); 264 } 265 266 /* Scan all Raw Descriptors first */ 267 rd = ted->ppRawDesc; 268 if (rd) { 269 while (*rd) { 270 usb_make_raw_desc(temp, *rd); 271 rd++; 272 } 273 } 274 if (ted->pPacketSize == NULL) { 275 /* not initialized */ 276 temp->err = USB_ERR_INVAL; 277 return; 278 } 279 mps = ted->pPacketSize->mps[temp->usb_speed]; 280 if (mps == 0) { 281 /* not initialized */ 282 temp->err = USB_ERR_INVAL; 283 return; 284 } else if (mps == UE_ZERO_MPS) { 285 /* escape for Zero Max Packet Size */ 286 mps = 0; 287 } 288 289 /* 290 * Fill out the real USB endpoint descriptor 291 * in case there is a buffer present: 292 */ 293 if (temp->buf) { 294 ed = USB_ADD_BYTES(temp->buf, old_size); 295 if (et == UE_ISOCHRONOUS) 296 ed->bLength = sizeof(*ed) + 2; 297 else 298 ed->bLength = sizeof(*ed); 299 ed->bDescriptorType = UDESC_ENDPOINT; 300 ed->bEndpointAddress = ea; 301 ed->bmAttributes = ted->bmAttributes; 302 USETW(ed->wMaxPacketSize, mps); 303 304 /* setup bInterval parameter */ 305 306 if (ted->pIntervals && 307 ted->pIntervals->bInterval[temp->usb_speed]) { 308 ed->bInterval = 309 ted->pIntervals->bInterval[temp->usb_speed]; 310 } else { 311 switch (et) { 312 case UE_BULK: 313 case UE_CONTROL: 314 ed->bInterval = 0; /* not used */ 315 break; 316 case UE_INTERRUPT: 317 switch (temp->usb_speed) { 318 case USB_SPEED_LOW: 319 case USB_SPEED_FULL: 320 ed->bInterval = 1; /* 1 ms */ 321 break; 322 default: 323 ed->bInterval = 4; /* 1 ms */ 324 break; 325 } 326 break; 327 default: /* UE_ISOCHRONOUS */ 328 switch (temp->usb_speed) { 329 case USB_SPEED_LOW: 330 case USB_SPEED_FULL: 331 ed->bInterval = 1; /* 1 ms */ 332 break; 333 default: 334 ed->bInterval = 1; /* 125 us */ 335 break; 336 } 337 break; 338 } 339 } 340 } 341 temp->bNumEndpoints++; 342 } 343 344 /*------------------------------------------------------------------------* 345 * usb_make_interface_desc 346 * 347 * This function will generate an USB interface descriptor from the 348 * given USB template interface descriptor, which will be inserted 349 * into the USB configuration. 350 *------------------------------------------------------------------------*/ 351 static void 352 usb_make_interface_desc(struct usb_temp_setup *temp, 353 const struct usb_temp_interface_desc *tid) 354 { 355 struct usb_interface_descriptor *id; 356 const struct usb_temp_endpoint_desc **ted; 357 const void **rd; 358 uint16_t old_size; 359 360 /* Reserve memory */ 361 362 old_size = temp->size; 363 temp->size += sizeof(*id); 364 365 /* Update interface and alternate interface numbers */ 366 367 if (tid->isAltInterface == 0) { 368 temp->bAlternateSetting = 0; 369 temp->bInterfaceNumber++; 370 } else { 371 temp->bAlternateSetting++; 372 } 373 374 /* Scan all Raw Descriptors first */ 375 376 rd = tid->ppRawDesc; 377 378 if (rd) { 379 while (*rd) { 380 usb_make_raw_desc(temp, *rd); 381 rd++; 382 } 383 } 384 /* Reset some counters */ 385 386 temp->bNumEndpoints = 0; 387 388 /* Scan all Endpoint Descriptors second */ 389 390 ted = tid->ppEndpoints; 391 if (ted) { 392 while (*ted) { 393 usb_make_endpoint_desc(temp, *ted); 394 ted++; 395 } 396 } 397 /* 398 * Fill out the real USB interface descriptor 399 * in case there is a buffer present: 400 */ 401 if (temp->buf) { 402 id = USB_ADD_BYTES(temp->buf, old_size); 403 id->bLength = sizeof(*id); 404 id->bDescriptorType = UDESC_INTERFACE; 405 id->bInterfaceNumber = temp->bInterfaceNumber; 406 id->bAlternateSetting = temp->bAlternateSetting; 407 id->bNumEndpoints = temp->bNumEndpoints; 408 id->bInterfaceClass = tid->bInterfaceClass; 409 id->bInterfaceSubClass = tid->bInterfaceSubClass; 410 id->bInterfaceProtocol = tid->bInterfaceProtocol; 411 id->iInterface = tid->iInterface; 412 } 413 } 414 415 /*------------------------------------------------------------------------* 416 * usb_make_config_desc 417 * 418 * This function will generate an USB config descriptor from the given 419 * USB template config descriptor, which will be inserted into the USB 420 * configuration. 421 *------------------------------------------------------------------------*/ 422 static void 423 usb_make_config_desc(struct usb_temp_setup *temp, 424 const struct usb_temp_config_desc *tcd) 425 { 426 struct usb_config_descriptor *cd; 427 const struct usb_temp_interface_desc **tid; 428 uint16_t old_size; 429 430 /* Reserve memory */ 431 432 old_size = temp->size; 433 temp->size += sizeof(*cd); 434 435 /* Reset some counters */ 436 437 temp->bInterfaceNumber = 0xFF; 438 temp->bAlternateSetting = 0; 439 440 /* Scan all the USB interfaces */ 441 442 tid = tcd->ppIfaceDesc; 443 if (tid) { 444 while (*tid) { 445 usb_make_interface_desc(temp, *tid); 446 tid++; 447 } 448 } 449 /* 450 * Fill out the real USB config descriptor 451 * in case there is a buffer present: 452 */ 453 if (temp->buf) { 454 cd = USB_ADD_BYTES(temp->buf, old_size); 455 456 /* compute total size */ 457 old_size = temp->size - old_size; 458 459 cd->bLength = sizeof(*cd); 460 cd->bDescriptorType = UDESC_CONFIG; 461 USETW(cd->wTotalLength, old_size); 462 cd->bNumInterface = temp->bInterfaceNumber + 1; 463 cd->bConfigurationValue = temp->bConfigurationValue; 464 cd->iConfiguration = tcd->iConfiguration; 465 cd->bmAttributes = tcd->bmAttributes; 466 cd->bMaxPower = tcd->bMaxPower; 467 cd->bmAttributes |= (UC_REMOTE_WAKEUP | UC_BUS_POWERED); 468 469 if (temp->self_powered) { 470 cd->bmAttributes |= UC_SELF_POWERED; 471 } else { 472 cd->bmAttributes &= ~UC_SELF_POWERED; 473 } 474 } 475 } 476 477 /*------------------------------------------------------------------------* 478 * usb_make_device_desc 479 * 480 * This function will generate an USB device descriptor from the 481 * given USB template device descriptor. 482 *------------------------------------------------------------------------*/ 483 static void 484 usb_make_device_desc(struct usb_temp_setup *temp, 485 const struct usb_temp_device_desc *tdd) 486 { 487 struct usb_temp_data *utd; 488 const struct usb_temp_config_desc **tcd; 489 uint16_t old_size; 490 491 /* Reserve memory */ 492 493 old_size = temp->size; 494 temp->size += sizeof(*utd); 495 496 /* Scan all the USB configs */ 497 498 temp->bConfigurationValue = 1; 499 tcd = tdd->ppConfigDesc; 500 if (tcd) { 501 while (*tcd) { 502 usb_make_config_desc(temp, *tcd); 503 temp->bConfigurationValue++; 504 tcd++; 505 } 506 } 507 /* 508 * Fill out the real USB device descriptor 509 * in case there is a buffer present: 510 */ 511 512 if (temp->buf) { 513 utd = USB_ADD_BYTES(temp->buf, old_size); 514 515 /* Store a pointer to our template device descriptor */ 516 utd->tdd = tdd; 517 518 /* Fill out USB device descriptor */ 519 utd->udd.bLength = sizeof(utd->udd); 520 utd->udd.bDescriptorType = UDESC_DEVICE; 521 utd->udd.bDeviceClass = tdd->bDeviceClass; 522 utd->udd.bDeviceSubClass = tdd->bDeviceSubClass; 523 utd->udd.bDeviceProtocol = tdd->bDeviceProtocol; 524 USETW(utd->udd.idVendor, tdd->idVendor); 525 USETW(utd->udd.idProduct, tdd->idProduct); 526 USETW(utd->udd.bcdDevice, tdd->bcdDevice); 527 utd->udd.iManufacturer = tdd->iManufacturer; 528 utd->udd.iProduct = tdd->iProduct; 529 utd->udd.iSerialNumber = tdd->iSerialNumber; 530 utd->udd.bNumConfigurations = temp->bConfigurationValue - 1; 531 532 /* 533 * Fill out the USB device qualifier. Pretend that we 534 * don't support any other speeds by setting 535 * "bNumConfigurations" equal to zero. That saves us 536 * generating an extra set of configuration 537 * descriptors. 538 */ 539 utd->udq.bLength = sizeof(utd->udq); 540 utd->udq.bDescriptorType = UDESC_DEVICE_QUALIFIER; 541 utd->udq.bDeviceClass = tdd->bDeviceClass; 542 utd->udq.bDeviceSubClass = tdd->bDeviceSubClass; 543 utd->udq.bDeviceProtocol = tdd->bDeviceProtocol; 544 utd->udq.bNumConfigurations = 0; 545 USETW(utd->udq.bcdUSB, 0x0200); 546 utd->udq.bMaxPacketSize0 = 0; 547 548 switch (temp->usb_speed) { 549 case USB_SPEED_LOW: 550 USETW(utd->udd.bcdUSB, 0x0110); 551 utd->udd.bMaxPacketSize = 8; 552 break; 553 case USB_SPEED_FULL: 554 USETW(utd->udd.bcdUSB, 0x0110); 555 utd->udd.bMaxPacketSize = 32; 556 break; 557 case USB_SPEED_HIGH: 558 USETW(utd->udd.bcdUSB, 0x0200); 559 utd->udd.bMaxPacketSize = 64; 560 break; 561 case USB_SPEED_VARIABLE: 562 USETW(utd->udd.bcdUSB, 0x0250); 563 utd->udd.bMaxPacketSize = 255; /* 512 bytes */ 564 break; 565 case USB_SPEED_SUPER: 566 USETW(utd->udd.bcdUSB, 0x0300); 567 utd->udd.bMaxPacketSize = 9; /* 2**9 = 512 bytes */ 568 break; 569 default: 570 temp->err = USB_ERR_INVAL; 571 break; 572 } 573 } 574 } 575 576 /*------------------------------------------------------------------------* 577 * usb_hw_ep_match 578 * 579 * Return values: 580 * 0: The endpoint profile does not match the criteria 581 * Else: The endpoint profile matches the criteria 582 *------------------------------------------------------------------------*/ 583 static uint8_t 584 usb_hw_ep_match(const struct usb_hw_ep_profile *pf, 585 uint8_t ep_type, uint8_t ep_dir_in) 586 { 587 if (ep_type == UE_CONTROL) { 588 /* special */ 589 return (pf->support_control); 590 } 591 if ((pf->support_in && ep_dir_in) || 592 (pf->support_out && !ep_dir_in)) { 593 if ((pf->support_interrupt && (ep_type == UE_INTERRUPT)) || 594 (pf->support_isochronous && (ep_type == UE_ISOCHRONOUS)) || 595 (pf->support_bulk && (ep_type == UE_BULK))) { 596 return (1); 597 } 598 } 599 return (0); 600 } 601 602 /*------------------------------------------------------------------------* 603 * usb_hw_ep_find_match 604 * 605 * This function is used to find the best matching endpoint profile 606 * for and endpoint belonging to an USB descriptor. 607 * 608 * Return values: 609 * 0: Success. Got a match. 610 * Else: Failure. No match. 611 *------------------------------------------------------------------------*/ 612 static uint8_t 613 usb_hw_ep_find_match(struct usb_hw_ep_scratch *ues, 614 struct usb_hw_ep_scratch_sub *ep, uint8_t is_simplex) 615 { 616 const struct usb_hw_ep_profile *pf; 617 uint16_t distance; 618 uint16_t temp; 619 uint16_t max_frame_size; 620 uint8_t n; 621 uint8_t best_n; 622 uint8_t dir_in; 623 uint8_t dir_out; 624 625 distance = 0xFFFF; 626 best_n = 0; 627 628 if ((!ep->needs_in) && (!ep->needs_out)) { 629 return (0); /* we are done */ 630 } 631 if (ep->needs_ep_type == UE_CONTROL) { 632 dir_in = 1; 633 dir_out = 1; 634 } else { 635 if (ep->needs_in) { 636 dir_in = 1; 637 dir_out = 0; 638 } else { 639 dir_in = 0; 640 dir_out = 1; 641 } 642 } 643 644 for (n = 1; n != (USB_EP_MAX / 2); n++) { 645 646 /* get HW endpoint profile */ 647 (ues->methods->get_hw_ep_profile) (ues->udev, &pf, n); 648 if (pf == NULL) { 649 /* end of profiles */ 650 break; 651 } 652 /* check if IN-endpoint is reserved */ 653 if (dir_in || pf->is_simplex) { 654 if (ues->bmInAlloc[n / 8] & (1 << (n % 8))) { 655 /* mismatch */ 656 continue; 657 } 658 } 659 /* check if OUT-endpoint is reserved */ 660 if (dir_out || pf->is_simplex) { 661 if (ues->bmOutAlloc[n / 8] & (1 << (n % 8))) { 662 /* mismatch */ 663 continue; 664 } 665 } 666 /* check simplex */ 667 if (pf->is_simplex == is_simplex) { 668 /* mismatch */ 669 continue; 670 } 671 /* check if HW endpoint matches */ 672 if (!usb_hw_ep_match(pf, ep->needs_ep_type, dir_in)) { 673 /* mismatch */ 674 continue; 675 } 676 /* get maximum frame size */ 677 if (dir_in) 678 max_frame_size = pf->max_in_frame_size; 679 else 680 max_frame_size = pf->max_out_frame_size; 681 682 /* check if we have a matching profile */ 683 if (max_frame_size >= ep->max_frame_size) { 684 temp = (max_frame_size - ep->max_frame_size); 685 if (distance > temp) { 686 distance = temp; 687 best_n = n; 688 ep->pf = pf; 689 } 690 } 691 } 692 693 /* see if we got a match */ 694 if (best_n != 0) { 695 /* get the correct profile */ 696 pf = ep->pf; 697 698 /* reserve IN-endpoint */ 699 if (dir_in) { 700 ues->bmInAlloc[best_n / 8] |= 701 (1 << (best_n % 8)); 702 ep->hw_endpoint_in = best_n | UE_DIR_IN; 703 ep->needs_in = 0; 704 } 705 /* reserve OUT-endpoint */ 706 if (dir_out) { 707 ues->bmOutAlloc[best_n / 8] |= 708 (1 << (best_n % 8)); 709 ep->hw_endpoint_out = best_n | UE_DIR_OUT; 710 ep->needs_out = 0; 711 } 712 return (0); /* got a match */ 713 } 714 return (1); /* failure */ 715 } 716 717 /*------------------------------------------------------------------------* 718 * usb_hw_ep_get_needs 719 * 720 * This function will figure out the type and number of endpoints 721 * which are needed for an USB configuration. 722 * 723 * Return values: 724 * 0: Success. 725 * Else: Failure. 726 *------------------------------------------------------------------------*/ 727 static uint8_t 728 usb_hw_ep_get_needs(struct usb_hw_ep_scratch *ues, 729 uint8_t ep_type, uint8_t is_complete) 730 { 731 const struct usb_hw_ep_profile *pf; 732 struct usb_hw_ep_scratch_sub *ep_iface; 733 struct usb_hw_ep_scratch_sub *ep_curr; 734 struct usb_hw_ep_scratch_sub *ep_max; 735 struct usb_hw_ep_scratch_sub *ep_end; 736 struct usb_descriptor *desc; 737 struct usb_interface_descriptor *id; 738 struct usb_endpoint_descriptor *ed; 739 enum usb_dev_speed speed; 740 uint16_t wMaxPacketSize; 741 uint16_t temp; 742 uint8_t ep_no; 743 744 ep_iface = ues->ep_max; 745 ep_curr = ues->ep_max; 746 ep_end = ues->ep + USB_EP_MAX; 747 ep_max = ues->ep_max; 748 desc = NULL; 749 speed = usbd_get_speed(ues->udev); 750 751 repeat: 752 753 while ((desc = usb_desc_foreach(ues->cd, desc))) { 754 755 if ((desc->bDescriptorType == UDESC_INTERFACE) && 756 (desc->bLength >= sizeof(*id))) { 757 758 id = (void *)desc; 759 760 if (id->bAlternateSetting == 0) { 761 /* going forward */ 762 ep_iface = ep_max; 763 } else { 764 /* reset */ 765 ep_curr = ep_iface; 766 } 767 } 768 if ((desc->bDescriptorType == UDESC_ENDPOINT) && 769 (desc->bLength >= sizeof(*ed))) { 770 771 ed = (void *)desc; 772 773 goto handle_endpoint_desc; 774 } 775 } 776 ues->ep_max = ep_max; 777 return (0); 778 779 handle_endpoint_desc: 780 temp = (ed->bmAttributes & UE_XFERTYPE); 781 782 if (temp == ep_type) { 783 784 if (ep_curr == ep_end) { 785 /* too many endpoints */ 786 return (1); /* failure */ 787 } 788 wMaxPacketSize = UGETW(ed->wMaxPacketSize); 789 if ((wMaxPacketSize & 0xF800) && 790 (speed == USB_SPEED_HIGH)) { 791 /* handle packet multiplier */ 792 temp = (wMaxPacketSize >> 11) & 3; 793 wMaxPacketSize &= 0x7FF; 794 if (temp == 1) { 795 wMaxPacketSize *= 2; 796 } else { 797 wMaxPacketSize *= 3; 798 } 799 } 800 /* 801 * Check if we have a fixed endpoint number, else the 802 * endpoint number is allocated dynamically: 803 */ 804 ep_no = (ed->bEndpointAddress & UE_ADDR); 805 if (ep_no != 0) { 806 807 /* get HW endpoint profile */ 808 (ues->methods->get_hw_ep_profile) 809 (ues->udev, &pf, ep_no); 810 if (pf == NULL) { 811 /* HW profile does not exist - failure */ 812 DPRINTFN(0, "Endpoint profile %u " 813 "does not exist\n", ep_no); 814 return (1); 815 } 816 /* reserve fixed endpoint number */ 817 if (ep_type == UE_CONTROL) { 818 ues->bmInAlloc[ep_no / 8] |= 819 (1 << (ep_no % 8)); 820 ues->bmOutAlloc[ep_no / 8] |= 821 (1 << (ep_no % 8)); 822 if ((pf->max_in_frame_size < wMaxPacketSize) || 823 (pf->max_out_frame_size < wMaxPacketSize)) { 824 DPRINTFN(0, "Endpoint profile %u " 825 "has too small buffer\n", ep_no); 826 return (1); 827 } 828 } else if (ed->bEndpointAddress & UE_DIR_IN) { 829 ues->bmInAlloc[ep_no / 8] |= 830 (1 << (ep_no % 8)); 831 if (pf->max_in_frame_size < wMaxPacketSize) { 832 DPRINTFN(0, "Endpoint profile %u " 833 "has too small buffer\n", ep_no); 834 return (1); 835 } 836 } else { 837 ues->bmOutAlloc[ep_no / 8] |= 838 (1 << (ep_no % 8)); 839 if (pf->max_out_frame_size < wMaxPacketSize) { 840 DPRINTFN(0, "Endpoint profile %u " 841 "has too small buffer\n", ep_no); 842 return (1); 843 } 844 } 845 } else if (is_complete) { 846 847 /* check if we have enough buffer space */ 848 if (wMaxPacketSize > 849 ep_curr->max_frame_size) { 850 return (1); /* failure */ 851 } 852 if (ed->bEndpointAddress & UE_DIR_IN) { 853 ed->bEndpointAddress = 854 ep_curr->hw_endpoint_in; 855 } else { 856 ed->bEndpointAddress = 857 ep_curr->hw_endpoint_out; 858 } 859 860 } else { 861 862 /* compute the maximum frame size */ 863 if (ep_curr->max_frame_size < wMaxPacketSize) { 864 ep_curr->max_frame_size = wMaxPacketSize; 865 } 866 if (temp == UE_CONTROL) { 867 ep_curr->needs_in = 1; 868 ep_curr->needs_out = 1; 869 } else { 870 if (ed->bEndpointAddress & UE_DIR_IN) { 871 ep_curr->needs_in = 1; 872 } else { 873 ep_curr->needs_out = 1; 874 } 875 } 876 ep_curr->needs_ep_type = ep_type; 877 } 878 879 ep_curr++; 880 if (ep_max < ep_curr) { 881 ep_max = ep_curr; 882 } 883 } 884 goto repeat; 885 } 886 887 /*------------------------------------------------------------------------* 888 * usb_hw_ep_resolve 889 * 890 * This function will try to resolve endpoint requirements by the 891 * given endpoint profiles that the USB hardware reports. 892 * 893 * Return values: 894 * 0: Success 895 * Else: Failure 896 *------------------------------------------------------------------------*/ 897 static usb_error_t 898 usb_hw_ep_resolve(struct usb_device *udev, 899 struct usb_descriptor *desc) 900 { 901 struct usb_hw_ep_scratch *ues; 902 struct usb_hw_ep_scratch_sub *ep; 903 const struct usb_hw_ep_profile *pf; 904 const struct usb_bus_methods *methods; 905 struct usb_device_descriptor *dd; 906 uint16_t mps; 907 908 if (desc == NULL) 909 return (USB_ERR_INVAL); 910 911 /* get bus methods */ 912 methods = udev->bus->methods; 913 914 if (methods->get_hw_ep_profile == NULL) 915 return (USB_ERR_INVAL); 916 917 if (desc->bDescriptorType == UDESC_DEVICE) { 918 919 if (desc->bLength < sizeof(*dd)) 920 return (USB_ERR_INVAL); 921 922 dd = (void *)desc; 923 924 /* get HW control endpoint 0 profile */ 925 (methods->get_hw_ep_profile) (udev, &pf, 0); 926 if (pf == NULL) { 927 return (USB_ERR_INVAL); 928 } 929 if (!usb_hw_ep_match(pf, UE_CONTROL, 0)) { 930 DPRINTFN(0, "Endpoint 0 does not " 931 "support control\n"); 932 return (USB_ERR_INVAL); 933 } 934 mps = dd->bMaxPacketSize; 935 936 if (udev->speed == USB_SPEED_FULL) { 937 /* 938 * We can optionally choose another packet size ! 939 */ 940 while (1) { 941 /* check if "mps" is ok */ 942 if (pf->max_in_frame_size >= mps) { 943 break; 944 } 945 /* reduce maximum packet size */ 946 mps /= 2; 947 948 /* check if "mps" is too small */ 949 if (mps < 8) { 950 return (USB_ERR_INVAL); 951 } 952 } 953 954 dd->bMaxPacketSize = mps; 955 956 } else { 957 /* We only have one choice */ 958 if (mps == 255) { 959 mps = 512; 960 } 961 /* Check if we support the specified wMaxPacketSize */ 962 if (pf->max_in_frame_size < mps) { 963 return (USB_ERR_INVAL); 964 } 965 } 966 return (0); /* success */ 967 } 968 if (desc->bDescriptorType != UDESC_CONFIG) 969 return (USB_ERR_INVAL); 970 if (desc->bLength < sizeof(*(ues->cd))) 971 return (USB_ERR_INVAL); 972 973 ues = udev->scratch.hw_ep_scratch; 974 975 memset(ues, 0, sizeof(*ues)); 976 977 ues->ep_max = ues->ep; 978 ues->cd = (void *)desc; 979 ues->methods = methods; 980 ues->udev = udev; 981 982 /* Get all the endpoints we need */ 983 984 if (usb_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 0) || 985 usb_hw_ep_get_needs(ues, UE_INTERRUPT, 0) || 986 usb_hw_ep_get_needs(ues, UE_CONTROL, 0) || 987 usb_hw_ep_get_needs(ues, UE_BULK, 0)) { 988 DPRINTFN(0, "Could not get needs\n"); 989 return (USB_ERR_INVAL); 990 } 991 for (ep = ues->ep; ep != ues->ep_max; ep++) { 992 993 while (ep->needs_in || ep->needs_out) { 994 995 /* 996 * First try to use a simplex endpoint. 997 * Then try to use a duplex endpoint. 998 */ 999 if (usb_hw_ep_find_match(ues, ep, 1) && 1000 usb_hw_ep_find_match(ues, ep, 0)) { 1001 DPRINTFN(0, "Could not find match\n"); 1002 return (USB_ERR_INVAL); 1003 } 1004 } 1005 } 1006 1007 ues->ep_max = ues->ep; 1008 1009 /* Update all endpoint addresses */ 1010 1011 if (usb_hw_ep_get_needs(ues, UE_ISOCHRONOUS, 1) || 1012 usb_hw_ep_get_needs(ues, UE_INTERRUPT, 1) || 1013 usb_hw_ep_get_needs(ues, UE_CONTROL, 1) || 1014 usb_hw_ep_get_needs(ues, UE_BULK, 1)) { 1015 DPRINTFN(0, "Could not update endpoint address\n"); 1016 return (USB_ERR_INVAL); 1017 } 1018 return (0); /* success */ 1019 } 1020 1021 /*------------------------------------------------------------------------* 1022 * usb_temp_get_tdd 1023 * 1024 * Returns: 1025 * NULL: No USB template device descriptor found. 1026 * Else: Pointer to the USB template device descriptor. 1027 *------------------------------------------------------------------------*/ 1028 static const struct usb_temp_device_desc * 1029 usb_temp_get_tdd(struct usb_device *udev) 1030 { 1031 if (udev->usb_template_ptr == NULL) { 1032 return (NULL); 1033 } 1034 return (udev->usb_template_ptr->tdd); 1035 } 1036 1037 /*------------------------------------------------------------------------* 1038 * usb_temp_get_device_desc 1039 * 1040 * Returns: 1041 * NULL: No USB device descriptor found. 1042 * Else: Pointer to USB device descriptor. 1043 *------------------------------------------------------------------------*/ 1044 static void * 1045 usb_temp_get_device_desc(struct usb_device *udev) 1046 { 1047 struct usb_device_descriptor *dd; 1048 1049 if (udev->usb_template_ptr == NULL) { 1050 return (NULL); 1051 } 1052 dd = &udev->usb_template_ptr->udd; 1053 if (dd->bDescriptorType != UDESC_DEVICE) { 1054 /* sanity check failed */ 1055 return (NULL); 1056 } 1057 return (dd); 1058 } 1059 1060 /*------------------------------------------------------------------------* 1061 * usb_temp_get_qualifier_desc 1062 * 1063 * Returns: 1064 * NULL: No USB device_qualifier descriptor found. 1065 * Else: Pointer to USB device_qualifier descriptor. 1066 *------------------------------------------------------------------------*/ 1067 static void * 1068 usb_temp_get_qualifier_desc(struct usb_device *udev) 1069 { 1070 struct usb_device_qualifier *dq; 1071 1072 if (udev->usb_template_ptr == NULL) { 1073 return (NULL); 1074 } 1075 dq = &udev->usb_template_ptr->udq; 1076 if (dq->bDescriptorType != UDESC_DEVICE_QUALIFIER) { 1077 /* sanity check failed */ 1078 return (NULL); 1079 } 1080 return (dq); 1081 } 1082 1083 /*------------------------------------------------------------------------* 1084 * usb_temp_get_config_desc 1085 * 1086 * Returns: 1087 * NULL: No USB config descriptor found. 1088 * Else: Pointer to USB config descriptor having index "index". 1089 *------------------------------------------------------------------------*/ 1090 static void * 1091 usb_temp_get_config_desc(struct usb_device *udev, 1092 uint16_t *pLength, uint8_t index) 1093 { 1094 struct usb_device_descriptor *dd; 1095 struct usb_config_descriptor *cd; 1096 uint16_t temp; 1097 1098 if (udev->usb_template_ptr == NULL) { 1099 return (NULL); 1100 } 1101 dd = &udev->usb_template_ptr->udd; 1102 cd = (void *)(udev->usb_template_ptr + 1); 1103 1104 if (index >= dd->bNumConfigurations) { 1105 /* out of range */ 1106 return (NULL); 1107 } 1108 while (index--) { 1109 if (cd->bDescriptorType != UDESC_CONFIG) { 1110 /* sanity check failed */ 1111 return (NULL); 1112 } 1113 temp = UGETW(cd->wTotalLength); 1114 cd = USB_ADD_BYTES(cd, temp); 1115 } 1116 1117 if (pLength) { 1118 *pLength = UGETW(cd->wTotalLength); 1119 } 1120 return (cd); 1121 } 1122 1123 /*------------------------------------------------------------------------* 1124 * usb_temp_get_vendor_desc 1125 * 1126 * Returns: 1127 * NULL: No vendor descriptor found. 1128 * Else: Pointer to a vendor descriptor. 1129 *------------------------------------------------------------------------*/ 1130 static const void * 1131 usb_temp_get_vendor_desc(struct usb_device *udev, 1132 const struct usb_device_request *req, uint16_t *plen) 1133 { 1134 const struct usb_temp_device_desc *tdd; 1135 1136 tdd = usb_temp_get_tdd(udev); 1137 if (tdd == NULL) { 1138 return (NULL); 1139 } 1140 if (tdd->getVendorDesc == NULL) { 1141 return (NULL); 1142 } 1143 return ((tdd->getVendorDesc) (req, plen)); 1144 } 1145 1146 /*------------------------------------------------------------------------* 1147 * usb_temp_get_string_desc 1148 * 1149 * Returns: 1150 * NULL: No string descriptor found. 1151 * Else: Pointer to a string descriptor. 1152 *------------------------------------------------------------------------*/ 1153 static const void * 1154 usb_temp_get_string_desc(struct usb_device *udev, 1155 uint16_t lang_id, uint8_t string_index) 1156 { 1157 const struct usb_temp_device_desc *tdd; 1158 1159 tdd = usb_temp_get_tdd(udev); 1160 if (tdd == NULL) { 1161 return (NULL); 1162 } 1163 if (tdd->getStringDesc == NULL) { 1164 return (NULL); 1165 } 1166 return ((tdd->getStringDesc) (lang_id, string_index)); 1167 } 1168 1169 /*------------------------------------------------------------------------* 1170 * usb_temp_get_hub_desc 1171 * 1172 * Returns: 1173 * NULL: No USB HUB descriptor found. 1174 * Else: Pointer to a USB HUB descriptor. 1175 *------------------------------------------------------------------------*/ 1176 static const void * 1177 usb_temp_get_hub_desc(struct usb_device *udev) 1178 { 1179 return (NULL); /* needs to be implemented */ 1180 } 1181 1182 /*------------------------------------------------------------------------* 1183 * usb_temp_get_desc 1184 * 1185 * This function is a demultiplexer for local USB device side control 1186 * endpoint requests. 1187 *------------------------------------------------------------------------*/ 1188 static usb_error_t 1189 usb_temp_get_desc(struct usb_device *udev, struct usb_device_request *req, 1190 const void **pPtr, uint16_t *pLength) 1191 { 1192 const uint8_t *buf; 1193 uint16_t len; 1194 1195 buf = NULL; 1196 len = 0; 1197 1198 switch (req->bmRequestType) { 1199 case UT_READ_DEVICE: 1200 switch (req->bRequest) { 1201 case UR_GET_DESCRIPTOR: 1202 goto tr_handle_get_descriptor; 1203 default: 1204 goto tr_stalled; 1205 } 1206 case UT_READ_CLASS_DEVICE: 1207 switch (req->bRequest) { 1208 case UR_GET_DESCRIPTOR: 1209 goto tr_handle_get_class_descriptor; 1210 default: 1211 goto tr_stalled; 1212 } 1213 default: 1214 goto tr_stalled; 1215 } 1216 1217 tr_handle_get_descriptor: 1218 switch (req->wValue[1]) { 1219 case UDESC_DEVICE: 1220 if (req->wValue[0]) { 1221 goto tr_stalled; 1222 } 1223 buf = usb_temp_get_device_desc(udev); 1224 goto tr_valid; 1225 case UDESC_DEVICE_QUALIFIER: 1226 if (udev->speed != USB_SPEED_HIGH) { 1227 goto tr_stalled; 1228 } 1229 if (req->wValue[0]) { 1230 goto tr_stalled; 1231 } 1232 buf = usb_temp_get_qualifier_desc(udev); 1233 goto tr_valid; 1234 case UDESC_OTHER_SPEED_CONFIGURATION: 1235 if (udev->speed != USB_SPEED_HIGH) { 1236 goto tr_stalled; 1237 } 1238 case UDESC_CONFIG: 1239 buf = usb_temp_get_config_desc(udev, 1240 &len, req->wValue[0]); 1241 goto tr_valid; 1242 case UDESC_STRING: 1243 buf = usb_temp_get_string_desc(udev, 1244 UGETW(req->wIndex), req->wValue[0]); 1245 goto tr_valid; 1246 default: 1247 goto tr_stalled; 1248 } 1249 1250 tr_handle_get_class_descriptor: 1251 if (req->wValue[0]) { 1252 goto tr_stalled; 1253 } 1254 buf = usb_temp_get_hub_desc(udev); 1255 goto tr_valid; 1256 1257 tr_valid: 1258 if (buf == NULL) 1259 goto tr_stalled; 1260 if (len == 0) 1261 len = buf[0]; 1262 *pPtr = buf; 1263 *pLength = len; 1264 return (0); /* success */ 1265 1266 tr_stalled: 1267 /* try to get a vendor specific descriptor */ 1268 len = 0; 1269 buf = usb_temp_get_vendor_desc(udev, req, &len); 1270 if (buf != NULL) 1271 goto tr_valid; 1272 *pPtr = NULL; 1273 *pLength = 0; 1274 return (0); /* we ignore failures */ 1275 } 1276 1277 /*------------------------------------------------------------------------* 1278 * usb_temp_setup 1279 * 1280 * This function generates USB descriptors according to the given USB 1281 * template device descriptor. It will also try to figure out the best 1282 * matching endpoint addresses using the hardware endpoint profiles. 1283 * 1284 * Returns: 1285 * 0: Success 1286 * Else: Failure 1287 *------------------------------------------------------------------------*/ 1288 usb_error_t 1289 usb_temp_setup(struct usb_device *udev, 1290 const struct usb_temp_device_desc *tdd) 1291 { 1292 struct usb_temp_setup *uts; 1293 void *buf; 1294 usb_error_t error; 1295 uint8_t n; 1296 uint8_t do_unlock; 1297 1298 /* be NULL safe */ 1299 if (tdd == NULL) 1300 return (0); 1301 1302 /* Protect scratch area */ 1303 do_unlock = usbd_ctrl_lock(udev); 1304 1305 uts = udev->scratch.temp_setup; 1306 1307 memset(uts, 0, sizeof(*uts)); 1308 1309 uts->usb_speed = udev->speed; 1310 uts->self_powered = udev->flags.self_powered; 1311 1312 /* first pass */ 1313 1314 usb_make_device_desc(uts, tdd); 1315 1316 if (uts->err) { 1317 /* some error happened */ 1318 goto done; 1319 } 1320 /* sanity check */ 1321 if (uts->size == 0) { 1322 uts->err = USB_ERR_INVAL; 1323 goto done; 1324 } 1325 /* allocate zeroed memory */ 1326 uts->buf = usbd_alloc_config_desc(udev, uts->size); 1327 /* 1328 * Allow malloc() to return NULL regardless of M_WAITOK flag. 1329 * This helps when porting the software to non-FreeBSD 1330 * systems. 1331 */ 1332 if (uts->buf == NULL) { 1333 /* could not allocate memory */ 1334 uts->err = USB_ERR_NOMEM; 1335 goto done; 1336 } 1337 /* second pass */ 1338 1339 uts->size = 0; 1340 1341 usb_make_device_desc(uts, tdd); 1342 1343 /* 1344 * Store a pointer to our descriptors: 1345 */ 1346 udev->usb_template_ptr = uts->buf; 1347 1348 if (uts->err) { 1349 /* some error happened during second pass */ 1350 goto done; 1351 } 1352 /* 1353 * Resolve all endpoint addresses ! 1354 */ 1355 buf = usb_temp_get_device_desc(udev); 1356 uts->err = usb_hw_ep_resolve(udev, buf); 1357 if (uts->err) { 1358 DPRINTFN(0, "Could not resolve endpoints for " 1359 "Device Descriptor, error = %s\n", 1360 usbd_errstr(uts->err)); 1361 goto done; 1362 } 1363 for (n = 0;; n++) { 1364 1365 buf = usb_temp_get_config_desc(udev, NULL, n); 1366 if (buf == NULL) { 1367 break; 1368 } 1369 uts->err = usb_hw_ep_resolve(udev, buf); 1370 if (uts->err) { 1371 DPRINTFN(0, "Could not resolve endpoints for " 1372 "Config Descriptor %u, error = %s\n", n, 1373 usbd_errstr(uts->err)); 1374 goto done; 1375 } 1376 } 1377 done: 1378 error = uts->err; 1379 if (error) 1380 usb_temp_unsetup(udev); 1381 if (do_unlock) 1382 usbd_ctrl_unlock(udev); 1383 return (error); 1384 } 1385 1386 /*------------------------------------------------------------------------* 1387 * usb_temp_unsetup 1388 * 1389 * This function frees any memory associated with the currently 1390 * setup template, if any. 1391 *------------------------------------------------------------------------*/ 1392 void 1393 usb_temp_unsetup(struct usb_device *udev) 1394 { 1395 usbd_free_config_desc(udev, udev->usb_template_ptr); 1396 udev->usb_template_ptr = NULL; 1397 } 1398 1399 static usb_error_t 1400 usb_temp_setup_by_index(struct usb_device *udev, uint16_t index) 1401 { 1402 usb_error_t err; 1403 1404 switch (index) { 1405 case USB_TEMP_MSC: 1406 err = usb_temp_setup(udev, &usb_template_msc); 1407 break; 1408 case USB_TEMP_CDCE: 1409 err = usb_temp_setup(udev, &usb_template_cdce); 1410 break; 1411 case USB_TEMP_MTP: 1412 err = usb_temp_setup(udev, &usb_template_mtp); 1413 break; 1414 case USB_TEMP_MODEM: 1415 err = usb_temp_setup(udev, &usb_template_modem); 1416 break; 1417 case USB_TEMP_AUDIO: 1418 err = usb_temp_setup(udev, &usb_template_audio); 1419 break; 1420 case USB_TEMP_KBD: 1421 err = usb_temp_setup(udev, &usb_template_kbd); 1422 break; 1423 case USB_TEMP_MOUSE: 1424 err = usb_temp_setup(udev, &usb_template_mouse); 1425 break; 1426 case USB_TEMP_PHONE: 1427 err = usb_temp_setup(udev, &usb_template_phone); 1428 break; 1429 case USB_TEMP_SERIALNET: 1430 err = usb_temp_setup(udev, &usb_template_serialnet); 1431 break; 1432 case USB_TEMP_MIDI: 1433 err = usb_temp_setup(udev, &usb_template_midi); 1434 break; 1435 case USB_TEMP_MULTI: 1436 err = usb_temp_setup(udev, &usb_template_multi); 1437 break; 1438 default: 1439 return (USB_ERR_INVAL); 1440 } 1441 1442 return (err); 1443 } 1444 1445 static void 1446 usb_temp_init(void *arg) 1447 { 1448 /* register our functions */ 1449 usb_temp_get_desc_p = &usb_temp_get_desc; 1450 usb_temp_setup_by_index_p = &usb_temp_setup_by_index; 1451 usb_temp_unsetup_p = &usb_temp_unsetup; 1452 } 1453 1454 SYSINIT(usb_temp_init, SI_SUB_LOCK, SI_ORDER_FIRST, usb_temp_init, NULL); 1455 SYSUNINIT(usb_temp_unload, SI_SUB_LOCK, SI_ORDER_ANY, usb_temp_unload, NULL); 1456