1/** 2 * \brief this file contains functions to setup the different xfers 3 */ 4 5/* 6 * Copyright (c) 2007-2013 ETH Zurich. 7 * All rights reserved. 8 * 9 * This file is distributed under the terms in the attached LICENSE file. 10 * If you do not find this file, copies can be found by writing to: 11 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 12 */ 13 14#include <stdlib.h> 15#include <stdio.h> 16#include <string.h> 17#include <barrelfish/barrelfish.h> 18 19#include <usb/usb.h> 20#include <usb/usb_descriptor.h> 21#include <usb/usb_error.h> 22 23#include <usb_device.h> 24#include <usb_controller.h> 25#include <usb_memory.h> 26#include <usb_xfer.h> 27 28/** 29 * \brief this function adds a usb xfer to a wait queue if it is not already 30 * in one. 31 * 32 * \param queue the queue the xfer should be added to 33 * \param xfer the transfer to add to the queue 34 * 35 * Note: a transfer is put on a queue, iff it cannot be handled directly, 36 * therefore a transfer can only be on one wait queue. 37 */ 38void usb_xfer_enqueue(struct usb_xfer_queue *queue, struct usb_xfer *xfer) 39{ 40 USB_DEBUG_TR_ENTER; 41 42 if (xfer->wait_queue == NULL) { 43 44 USB_DEBUG_XFER("add: [%x, q=%p, &f=%p, ln=%p, wn=%p, &wn=%p, pn=%p\n", 45 xfer->xfer_id, queue, &queue->head.first, 46 queue->head.last_next, xfer->wait_entry.next, 47 &xfer->wait_entry.next, xfer->wait_entry.prev_next); 48 49 assert(queue != NULL); 50 51 xfer->wait_queue = queue; 52 53 xfer->wait_entry.next = NULL; 54 xfer->wait_entry.prev_next = queue->head.last_next; 55 56 *(queue->head.last_next) = xfer; 57 queue->head.last_next = &(xfer->wait_entry.next); 58 59 } 60 61 USB_DEBUG_TR_RETURN; 62} 63 64/** 65 * \brief this function removes the usb xfer from the wait queue queue 66 * 67 * \param xfer the transfer to remove to the queue 68 * 69 */ 70void usb_xfer_dequeue(struct usb_xfer *xfer) 71{ 72 USB_DEBUG_TR_ENTER; 73 74 struct usb_xfer_queue *queue; 75 76 queue = xfer->wait_queue; 77 78 if (queue) { 79 80 USB_DEBUG_XFER("removing the transfer from the wait queue\n"); 81 82 if ((xfer->wait_entry.next) != NULL) 83 xfer->wait_entry.next->wait_entry.prev_next = xfer->wait_entry 84 .prev_next; 85 else { 86 queue->head.last_next = xfer->wait_entry.prev_next; 87 } 88 89 *xfer->wait_entry.prev_next = xfer->wait_entry.next; 90 91 xfer->wait_queue = NULL; 92 93 USB_DEBUG_XFER("rem: [%x, q=%p, &f=%p, ln=%p, wn=%p, &wn=%p, pn=%p\n", 94 xfer->xfer_id, queue, &queue->head.first, 95 queue->head.last_next, xfer->wait_entry.next, 96 &xfer->wait_entry.next, xfer->wait_entry.prev_next); 97 98 } 99 100 USB_DEBUG_TR_RETURN; 101} 102 103/** 104 * \brief this function handles complete transfers by removing them from 105 * the interrupt queue and inserting them into the done queue. 106 * 107 * \param xfer the completed usb transfer 108 * \param err error condition of the transfer 109 * 110 */ 111void usb_xfer_done(struct usb_xfer *xfer, usb_error_t err) 112{ 113 USB_DEBUG_TR_ENTER; 114 115 /* 116 * if the transfer started, this flag has to be set to 1. Therefore 117 * the transfer may be canceled. Just return then. 118 */ 119 if (!xfer->flags_internal.transferring && !xfer->flags_internal.done) { 120 USB_DEBUG_XFER("NOTICE: transfer was not transferring..\n"); 121 // clear the control active flag and return 122 xfer->flags_internal.ctrl_active = 0; 123 124 USB_DEBUG_TR_RETURN; 125 return; 126 } 127 128 if (!xfer->flags_internal.transferring && !xfer->flags_internal.started) { 129 /* the transfer is not transferring and not started nothing to do */ 130 return; 131 } 132 133 if ((!xfer->flags_internal.pipe_open) 134 && (!xfer->flags_internal.transfer_closed)) { 135 /* check if the pipe was opened and close it */ 136 xfer->endpoint->pipe_fn->close(xfer); 137 xfer->flags_internal.transfer_closed = 1; 138 139 } 140 141 // update error condition 142 xfer->error = err; 143 144 if (err != USB_ERR_OK) { 145 USB_DEBUG_XFER("Transfer done with error: %s\n", usb_get_error_string(err)); 146 } 147 148 /* 149 * the transfer was enqueued and is waiting on the interrupt queue 150 * so we have to dequeue it 151 */ 152 153 usb_xfer_dequeue(xfer); 154 155 /* 156 * check the number of actual frames this should not be bigger than 157 * the maximum number of frames 158 */ 159 if (xfer->actual_frames > xfer->num_frames) { 160 if (xfer->error == USB_ERR_OK) { 161 USER_PANIC("WARNING: actual frames bigger than num frames! PANIC!"); 162 } else { 163 xfer->actual_frames = xfer->num_frames; 164 } 165 } 166 167 /* calculate the actual size of the transferred data */uint32_t frame = 0; 168 xfer->actual_bytes = 0; 169 for (frame = 0; frame < xfer->actual_frames; frame++) { 170 xfer->actual_bytes += xfer->frame_lengths[frame]; 171 } 172 173 /* set frame length of the unused frames to be zero */ 174 while (frame < xfer->num_frames) { 175 xfer->frame_lengths[frame] = 0; 176 frame++; 177 } 178 179 if (xfer->actual_bytes > xfer->sum_bytes) { 180 if (xfer->error == USB_ERR_OK) { 181 USER_PANIC("WARNING: actual bytes biggar than sum bytes! PANIC!"); 182 } else { 183 xfer->actual_frames = xfer->num_frames; 184 } 185 } 186 187 /* clear the flags */ 188 xfer->flags_internal.ctrl_active = 0; 189 xfer->flags_internal.transferring = 0; 190 191 /* 192 * start the next transfer on this endpoint if there is any 193 */ 194 struct usb_endpoint *ep = xfer->endpoint; 195 struct usb_xfer_queue *q = &ep->transfers; 196 197 if (q->current == xfer || q->current == NULL) { 198 q->current = NULL; 199 if (!q->recurse_1) { 200 q->recurse_1 = 1; 201 /* get the first transfer of the queue */ 202 struct usb_xfer *next_xfer = q->head.first; 203 204 if (next_xfer) { 205 /* dequeue it */ 206 if (next_xfer->wait_entry.next != NULL) { 207 (*next_xfer->wait_entry.prev_next)->wait_entry.prev_next = 208 next_xfer->wait_entry.prev_next; 209 *next_xfer->wait_entry.prev_next = next_xfer->wait_entry 210 .next; 211 } else { 212 q->head.last_next = &(q->head.first); 213 q->head.first = NULL; 214 } 215 /* the transfer is not on a wait queue anymore */ 216 next_xfer->wait_queue = NULL; 217 q->current = next_xfer; 218 219 USB_DEBUG_XFER( 220 "rem2: [%x, q=%p, &f=%p, ln=%p, wn=%p, &wn=%p, pn=%p\n", 221 xfer->xfer_id, q, &q->head.first, q->head.last_next, 222 xfer->wait_entry.next, &xfer->wait_entry.next, 223 xfer->wait_entry.prev_next); 224 225 /* start the transfer */ 226 (q->command)(q); 227 228 } else { 229 /* reset the queue */ 230 (&q->head)->last_next = &q->head.first; 231 (&q->head)->first = NULL; 232 } 233 q->recurse_1 = 0; 234 } 235 if (!(ep->transfers.current || ep->transfers.head.first)) { 236 xfer->endpoint->is_sync = 0; 237 } 238 239 } 240 241 /* send the transfer done notification */ 242 if (xfer->xfer_done_cb && xfer->flags_internal.notify) { 243 xfer->flags_internal.notify = 0; 244 (xfer->xfer_done_cb)(xfer, err); 245 } 246 247 USB_DEBUG_TR_RETURN; 248 return; 249} 250 251/// struct for the packet sizes 252struct usb_std_packet_size { 253 struct { 254 uint16_t min; /* inclusive */ 255 uint16_t max; /* inclusive */ 256 } range; 257 258 uint16_t fixed[4]; 259}; 260 261/** 262 * \brief checks the standard packet sizes according to the transfer speed 263 * and the endpoint type 264 * 265 * \param ptr pointer to the memory location to store the size information 266 * \param type the type of the endpoint 267 * \param speed the endpoint speed 268 */ 269static void usb_xfer_get_packet_size(struct usb_std_packet_size *ptr, 270 uint8_t type, enum usb_speed speed) 271{ 272 /* interrupt type */ 273 static const uint16_t intr_range_max[USB_SPEED_MAX] = { 274 [USB_SPEED_LOW] = 8, 275 [USB_SPEED_FULL] = 64, 276 [USB_SPEED_HIGH] = 1024, 277 [USB_SPEED_VARIABLE] = 1024, 278 [USB_SPEED_SUPER] = 1024, 279 }; 280 281 /* isochronus type */ 282 static const uint16_t isoc_range_max[USB_SPEED_MAX] = { 283 [USB_SPEED_LOW] = 0, /* invalid */ 284 [USB_SPEED_FULL] = 1023, 285 [USB_SPEED_HIGH] = 1024, 286 [USB_SPEED_VARIABLE] = 3584, 287 [USB_SPEED_SUPER] = 1024, 288 }; 289 290 /* control type */ 291 static const uint16_t control_min[USB_SPEED_MAX] = { 292 [USB_SPEED_LOW] = 8, 293 [USB_SPEED_FULL] = 8, 294 [USB_SPEED_HIGH] = 64, 295 [USB_SPEED_VARIABLE] = 512, 296 [USB_SPEED_SUPER] = 512, 297 }; 298 299 /* bulk type */ 300 static const uint16_t bulk_min[USB_SPEED_MAX] = { 301 [USB_SPEED_LOW] = 8, 302 [USB_SPEED_FULL] = 8, 303 [USB_SPEED_HIGH] = 512, 304 [USB_SPEED_VARIABLE] = 512, 305 [USB_SPEED_SUPER] = 1024, 306 }; 307 308 uint16_t temp; 309 310 /* reset the fields */ 311 memset(ptr, 0, sizeof(*ptr)); 312 313 switch (type) { 314 case USB_ENDPOINT_TYPE_INTR: 315 ptr->range.max = intr_range_max[speed]; 316 break; 317 case USB_ENDPOINT_TYPE_ISOCHR: 318 ptr->range.max = isoc_range_max[speed]; 319 break; 320 default: 321 if (type == USB_ENDPOINT_TYPE_BULK) 322 temp = bulk_min[speed]; 323 else 324 temp = control_min[speed]; 325 326 ptr->fixed[0] = temp; 327 ptr->fixed[1] = temp; 328 ptr->fixed[2] = temp; 329 ptr->fixed[3] = temp; 330 331 if (speed == USB_SPEED_FULL) { 332 ptr->fixed[1] = 16; 333 ptr->fixed[2] = 32; 334 ptr->fixed[3] = 64; 335 } 336 break; 337 } 338} 339 340/** 341 * \brief this function is called from the xfer_setup function of the 342 * respective USB host controller driver. This function sets the 343 * correct values in the usb_xfer struct. 344 * 345 * \param param USB transfer setup parameters 346 * 347 */ 348void usb_xfer_setup_struct(struct usb_xfer_setup_params *param) 349{ 350 USB_DEBUG_TR_ENTER; 351 352 struct usb_xfer *xfer = param->curr_xfer; 353 354 /* do a parameter check */ 355 if ((param->hc_max_packet_size == 0) || (param->hc_max_packet_count == 0) 356 || (param->hc_max_frame_size == 0)) { 357 USB_DEBUG("WARNING: Invaid setup parameter\n"); 358 param->err = USB_ERR_INVAL; 359 360 xfer->max_hc_frame_size = 1; 361 xfer->max_frame_size = 1; 362 xfer->max_packet_size = 1; 363 xfer->max_data_length = 0; 364 xfer->num_frames = 0; 365 xfer->max_frame_count = 0; 366 USB_DEBUG_TR_RETURN; 367 return; 368 } 369 370 const struct usb_xfer_config *setup_config = param->xfer_setup; 371 struct usb_endpoint_descriptor *ep_desc = xfer->endpoint->descriptor; 372 373 assert(setup_config); 374 assert(ep_desc); 375 376 xfer->max_packet_size = xfer->endpoint->max_packet_size; 377 378 usb_speed_t ep_speed = param->speed; 379 uint8_t type = ep_desc->bmAttributes.xfer_type; 380 xfer->endpoint_number = ep_desc->bEndpointAddress.ep_number; 381 xfer->ed_direction = ep_desc->bEndpointAddress.direction; 382 383 xfer->max_packet_count = 1; 384 385 /* adjust maximum packet count and size */ 386 switch (ep_speed) { 387 case USB_SPEED_HIGH: 388 if (type == USB_ENDPOINT_TYPE_ISOCHR 389 || type == USB_ENDPOINT_TYPE_INTR) { 390 xfer->max_packet_count += (xfer->max_packet_size >> 11) & 3; 391 if (xfer->max_packet_count > 3) { 392 xfer->max_packet_count = 3; 393 } 394 } 395 xfer->max_packet_size &= 0x7FF; 396 break; 397 case USB_SPEED_SUPER: 398 assert(!"NYI: No super speed support right now."); 399 break; 400 default: 401 /* noop */ 402 break; 403 } 404 405 uint32_t num_frlengths; 406 uint32_t num_frbuffers; 407 408 /* setup some values of the xfer struct */ 409 xfer->flags = setup_config->flags; 410 xfer->num_frames = setup_config->frames; 411 xfer->timeout = setup_config->timeout; 412 xfer->interval = setup_config->interval; 413 param->bufsize = setup_config->bufsize; 414 415 xfer->flags_internal.usb_mode = param->device->flags.usb_mode; 416 417 418 struct usb_std_packet_size size; 419 usb_xfer_get_packet_size(&size, type, param->speed); 420 421 if (size.range.min || size.range.max) { 422 if (xfer->max_packet_size < size.range.min) { 423 xfer->max_packet_size = size.range.min; 424 } 425 if (xfer->max_packet_size > size.range.max) { 426 xfer->max_packet_size = size.range.max; 427 } 428 } else { 429 if (xfer->max_packet_size >= size.fixed[3]) { 430 xfer->max_packet_size = size.fixed[3]; 431 } else if (xfer->max_packet_size >= size.fixed[2]) { 432 xfer->max_packet_size = size.fixed[2]; 433 } else if (xfer->max_packet_size >= size.fixed[1]) { 434 xfer->max_packet_size = size.fixed[1]; 435 } else { 436 /* only one possibility left */ 437 xfer->max_packet_size = size.fixed[0]; 438 } 439 } 440 441 /* 442 * range checks and filter values according to the host controller 443 * values. Maximum packet size and count must not be bigger than supported 444 * by the host controller. 445 */ 446 447 if (xfer->max_packet_count > param->hc_max_packet_count) { 448 xfer->max_packet_count = param->hc_max_packet_count; 449 } 450 451 if ((xfer->max_packet_size > param->hc_max_packet_size) 452 || (xfer->max_packet_size == 0)) { 453 xfer->max_packet_size = param->hc_max_packet_size; 454 } 455 456 /* 457 * compute the maximum frame size as the maximum number of packets 458 * multiplied by the maximum packet size 459 */ 460 xfer->max_frame_size = xfer->max_packet_size * xfer->max_packet_count; 461 462 /* 463 * isochronus and interrupt transfer need to be checked very INTERVALL ms 464 * so we need to setup the interval for this to transfer types 465 */ 466 switch (type) { 467 case USB_TYPE_ISOC: 468 /* TODO: ISOCHRONUS IMPLEMENTATION */ 469 assert(!"NYI: isochronus support not yet implemented"); 470 break; 471 case USB_TYPE_INTR: 472 if (xfer->interval == 0) { 473 /* interval is not set, get it from the endpoint descriptor */ 474 xfer->interval = ep_desc->bInterval; 475 /* 476 * since the frames have different durations for FULL/LOW speed 477 * and high speed devices we have to do conversion 478 * from 125 us -> 1 ms 479 */ 480 if (param->speed != USB_SPEED_FULL 481 && param->speed != USB_SPEED_LOW) { 482 if (xfer->interval < 4) { 483 /* smallest interval 1 ms*/ 484 xfer->interval = 1; 485 } else if (xfer->interval > 16) { 486 /* maximum interval 32ms */ 487 xfer->interval = (0x1 << (16 - 4)); 488 } else { 489 /* normal interval */ 490 xfer->interval = (0x1 << (xfer->interval - 4)); 491 } 492 } 493 } 494 495 /* ensure that the interval is at least 1 */ 496 xfer->interval += (xfer->interval ? 0 : 1); 497 498 /* calculate the frame down shift value */ 499 xfer->frame_shift = 0; 500 uint32_t tmp = 1; 501 while ((tmp != 0) && (tmp < xfer->interval)) { 502 xfer->frame_shift++; 503 tmp *= 2; 504 } 505 506 if (param->speed != USB_SPEED_FULL 507 && param->speed != USB_SPEED_LOW) { 508 xfer->frame_shift += 3; 509 } 510 511 break; 512 default: 513 /* noop */ 514 break; 515 } 516 uint8_t max_length_zero = 0; 517 518 if ((xfer->max_frame_size == 0) || (xfer->max_packet_size == 0)) { 519 520 max_length_zero = 1; 521 522 /* check for minimum packet size */ 523 if ((param->bufsize <= 8) && (type != USB_TYPE_CTRL) 524 && (type != USB_TYPE_BULK)) { 525 xfer->max_packet_size = 8; 526 xfer->max_packet_count = 1; 527 param->bufsize = 0; 528 xfer->max_frame_size = xfer->max_packet_size 529 * xfer->max_packet_count; 530 } else { 531 /* error condition */ 532 USB_DEBUG("WARNING: Invalid zero max length.\n"); 533 param->err = USB_ERR_ZERO_MAXP; 534 xfer->max_hc_frame_size = 1; 535 xfer->max_frame_size = 1; 536 xfer->max_packet_size = 1; 537 xfer->max_data_length = 0; 538 xfer->num_frames = 0; 539 xfer->max_frame_count = 0; 540 USB_DEBUG_TR_RETURN; 541 return; 542 } 543 } 544 545 /* 546 * if the buffer size is not given, we set it to the default size 547 * such that the maximum frame fits into it. For isochronus we have 548 * to multiply this by the expected number of frames. 549 */ 550 if (param->bufsize == 0) { 551 param->bufsize = xfer->max_frame_size; 552 553 if (type == USB_ENDPOINT_TYPE_ISOCHR) { 554 param->bufsize *= xfer->num_frames; 555 } 556 } 557 558 if (xfer->flags.ext_buffer) { 559 param->bufsize += (xfer->max_frame_size - 1); 560 561 if (param->bufsize < xfer->max_frame_size) { 562 param->err = USB_ERR_INVAL; 563 USB_DEBUG("WARNING: Invalid buffer size.\n"); 564 xfer->max_hc_frame_size = 1; 565 xfer->max_frame_size = 1; 566 xfer->max_packet_size = 1; 567 xfer->max_data_length = 0; 568 xfer->num_frames = 0; 569 xfer->max_frame_count = 0; 570 USB_DEBUG_TR_RETURN; 571 return; 572 } 573 param->bufsize -= (param->bufsize % xfer->max_frame_size); 574 if (type == USB_ENDPOINT_TYPE_CONTROL) { 575 /* add the device request size for the setup message 576 * to the buffer length 577 */ 578 param->bufsize += 8; 579 } 580 } 581 582 xfer->max_data_length = param->bufsize; 583 584 /* calculate the number of required frames depending on the transfer type */ 585 switch (type) { 586 case USB_TYPE_ISOC: 587 num_frlengths = xfer->num_frames; 588 num_frbuffers = 1; 589 break; 590 591 case USB_TYPE_CTRL: 592 /* 593 * control transfers are special, since they may have a data stage 594 * or not, the number of frames depends on this. 595 * 596 * If the buffer size is 8 bytes, this is just the size of the 597 * device request and thus there is no data stage. 598 * 599 * Set the flag indicating that this is a control transfer 600 */ 601 602 xfer->flags_internal.ctrl_xfer = 1; 603 604 if (xfer->num_frames == 0) { 605 if (param->bufsize <= 8) { 606 /* no data stage of this control request */ 607 xfer->num_frames = 1; 608 } else { 609 /* there is a data stage of this control request */ 610 xfer->num_frames = 2; 611 } 612 } 613 614 615 num_frlengths = xfer->num_frames; 616 num_frbuffers = xfer->num_frames; 617 618 if (xfer->max_data_length < 8) { 619 /* too small length: wrap around or too small buffer size */ 620 param->err = USB_ERR_INVAL; 621 USB_DEBUG("WARNING: invalid max_data_length.\n"); 622 xfer->max_hc_frame_size = 1; 623 xfer->max_frame_size = 1; 624 xfer->max_packet_size = 1; 625 xfer->max_data_length = 0; 626 xfer->num_frames = 0; 627 xfer->max_frame_count = 0; 628 USB_DEBUG_TR_RETURN; 629 return; 630 } 631 632 /* subtract the request size */ 633 634 xfer->max_data_length -= 8; 635 break; 636 637 default: 638 /* the num frames is at least one */ 639 xfer->num_frames = (xfer->num_frames) ? (xfer->num_frames) : 1; 640 num_frlengths = xfer->num_frames; 641 num_frbuffers = xfer->num_frames; 642 break; 643 } 644 645 646 /* allocate the frame buffers and the frame length array */ 647 xfer->max_frame_count = xfer->num_frames; 648 649 xfer->frame_lengths = malloc(2 * xfer->num_frames * sizeof(uint32_t)); 650 xfer->frame_buffers = malloc( 651 xfer->num_frames * sizeof(struct usb_dma_page)); 652 653 for (uint32_t i = 0; i < xfer->num_frames; i++) { 654 xfer->frame_lengths[i] = xfer->max_data_length; 655 xfer->frame_buffers[i] = usb_mem_dma_alloc( 656 param->num_pages * USB_PAGE_SIZE, USB_PAGE_SIZE); 657 } 658 659 /* 660 * we expect to have no data stage, so set it to the correct value 661 */ 662 if (max_length_zero) { 663 xfer->max_data_length = 0; 664 } 665 666 /* round up maximum buf size */ 667 if (param->bufsize_max < param->bufsize) { 668 param->bufsize_max = param->bufsize; 669 } 670 671 xfer->max_hc_frame_size = (param->hc_max_frame_size 672 - (param->hc_max_frame_size % xfer->max_frame_size)); 673 674 if (xfer->max_hc_frame_size == 0) { 675 USB_DEBUG("WARNING: Invalid max_hc_frame_size.\n"); 676 param->err = USB_ERR_INVAL; 677 xfer->max_hc_frame_size = 1; 678 xfer->max_frame_size = 1; 679 xfer->max_packet_size = 1; 680 xfer->max_data_length = 0; 681 xfer->num_frames = 0; 682 xfer->max_frame_count = 0; 683 USB_DEBUG_TR_RETURN; 684 return; 685 } 686 687 USB_DEBUG_TR_RETURN; 688} 689 690