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