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