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