1/* ========================================================================== 2 * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd_queue.c $ 3 * $Revision: 1.5 $ 4 * $Date: 2008-12-15 06:51:32 $ 5 * $Change: 537387 $ 6 * 7 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter, 8 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless 9 * otherwise expressly agreed to in writing between Synopsys and you. 10 * 11 * The Software IS NOT an item of Licensed Software or Licensed Product under 12 * any End User Software License Agreement or Agreement for Licensed Product 13 * with Synopsys or any supplement thereto. You are permitted to use and 14 * redistribute this Software in source and binary forms, with or without 15 * modification, provided that redistributions of source code must retain this 16 * notice. You may not view, use, disclose, copy or distribute this file or 17 * any information contained herein except pursuant to this license grant from 18 * Synopsys. If you do not agree with this notice, including the disclaimer 19 * below, then you are not authorized to use the Software. 20 * 21 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS 22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT, 25 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 31 * DAMAGE. 32 * ========================================================================== */ 33#ifndef DWC_DEVICE_ONLY 34 35/** 36 * @file 37 * 38 * This file contains the functions to manage Queue Heads and Queue 39 * Transfer Descriptors. 40 */ 41#include <linux/kernel.h> 42#include <linux/module.h> 43#include <linux/moduleparam.h> 44#include <linux/init.h> 45#include <linux/device.h> 46#include <linux/errno.h> 47#include <linux/list.h> 48#include <linux/interrupt.h> 49#include <linux/string.h> 50#include <linux/dma-mapping.h> 51 52#include "dwc_otg_driver.h" 53#include "dwc_otg_hcd.h" 54#include "dwc_otg_regs.h" 55 56/** 57 * This function allocates and initializes a QH. 58 * 59 * @param hcd The HCD state structure for the DWC OTG controller. 60 * @param[in] urb Holds the information about the device/endpoint that we need 61 * to initialize the QH. 62 * 63 * @return Returns pointer to the newly allocated QH, or NULL on error. */ 64dwc_otg_qh_t *dwc_otg_hcd_qh_create (dwc_otg_hcd_t *hcd, struct urb *urb) 65{ 66 dwc_otg_qh_t *qh; 67 68 /* Allocate memory */ 69 /** @todo add memflags argument */ 70 qh = dwc_otg_hcd_qh_alloc (); 71 if (qh == NULL) { 72 return NULL; 73 } 74 75 dwc_otg_hcd_qh_init (hcd, qh, urb); 76 return qh; 77} 78 79/** Free each QTD in the QH's QTD-list then free the QH. QH should already be 80 * removed from a list. QTD list should already be empty if called from URB 81 * Dequeue. 82 * 83 * @param[in] hcd HCD instance. 84 * @param[in] qh The QH to free. 85 */ 86void dwc_otg_hcd_qh_free (dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) 87{ 88 dwc_otg_qtd_t *qtd; 89 struct list_head *pos; 90 unsigned long flags; 91 92 /* Free each QTD in the QTD list */ 93 SPIN_LOCK_IRQSAVE(&hcd->lock, flags) 94 for (pos = qh->qtd_list.next; 95 pos != &qh->qtd_list; 96 pos = qh->qtd_list.next) 97 { 98 list_del (pos); 99 qtd = dwc_list_to_qtd (pos); 100 dwc_otg_hcd_qtd_free (qtd); 101 } 102 SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags) 103 104 if (qh->dw_align_buf) { 105 dma_free_coherent((dwc_otg_hcd_to_hcd(hcd))->self.controller, 106 hcd->core_if->core_params->max_transfer_size, 107 qh->dw_align_buf, 108 qh->dw_align_buf_dma); 109 } 110 111 kfree (qh); 112 return; 113} 114 115/** Initializes a QH structure. 116 * 117 * @param[in] hcd The HCD state structure for the DWC OTG controller. 118 * @param[in] qh The QH to init. 119 * @param[in] urb Holds the information about the device/endpoint that we need 120 * to initialize the QH. */ 121#define SCHEDULE_SLOP 10 122void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, struct urb *urb) 123{ 124 char *speed, *type; 125 memset (qh, 0, sizeof (dwc_otg_qh_t)); 126 127 /* Initialize QH */ 128 switch (usb_pipetype(urb->pipe)) { 129 case PIPE_CONTROL: 130 qh->ep_type = USB_ENDPOINT_XFER_CONTROL; 131 break; 132 case PIPE_BULK: 133 qh->ep_type = USB_ENDPOINT_XFER_BULK; 134 break; 135 case PIPE_ISOCHRONOUS: 136 qh->ep_type = USB_ENDPOINT_XFER_ISOC; 137 break; 138 case PIPE_INTERRUPT: 139 qh->ep_type = USB_ENDPOINT_XFER_INT; 140 break; 141 } 142 143 qh->ep_is_in = usb_pipein(urb->pipe) ? 1 : 0; 144 145 qh->data_toggle = DWC_OTG_HC_PID_DATA0; 146 qh->maxp = usb_maxpacket(urb->dev, urb->pipe, !(usb_pipein(urb->pipe))); 147 INIT_LIST_HEAD(&qh->qtd_list); 148 INIT_LIST_HEAD(&qh->qh_list_entry); 149 qh->channel = NULL; 150 151 /* FS/LS Enpoint on HS Hub 152 * NOT virtual root hub */ 153 qh->do_split = 0; 154 if (((urb->dev->speed == USB_SPEED_LOW) || 155 (urb->dev->speed == USB_SPEED_FULL)) && 156 (urb->dev->tt) && (urb->dev->tt->hub) && (urb->dev->tt->hub->devnum != 1)) 157 { 158 DWC_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n", 159 usb_pipeendpoint(urb->pipe), urb->dev->tt->hub->devnum, 160 urb->dev->ttport); 161 qh->do_split = 1; 162 } 163 164 if (qh->ep_type == USB_ENDPOINT_XFER_INT || 165 qh->ep_type == USB_ENDPOINT_XFER_ISOC) { 166 /* Compute scheduling parameters once and save them. */ 167 hprt0_data_t hprt; 168 169 /** @todo Account for split transfers in the bus time. */ 170 int bytecount = dwc_hb_mult(qh->maxp) * dwc_max_packet(qh->maxp); 171 172 /* FIXME: work-around patch by Steven */ 173 qh->usecs = NS_TO_US(usb_calc_bus_time(urb->dev->speed, 174 usb_pipein(urb->pipe), 175 (qh->ep_type == USB_ENDPOINT_XFER_ISOC), 176 bytecount)); 177 178 /* Start in a slightly future (micro)frame. */ 179 qh->sched_frame = dwc_frame_num_inc(hcd->frame_number, 180 SCHEDULE_SLOP); 181 qh->interval = urb->interval; 182#if 0 183 /* Increase interrupt polling rate for debugging. */ 184 if (qh->ep_type == USB_ENDPOINT_XFER_INT) { 185 qh->interval = 8; 186 } 187#endif 188 hprt.d32 = dwc_read_reg32(hcd->core_if->host_if->hprt0); 189 if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) && 190 ((urb->dev->speed == USB_SPEED_LOW) || 191 (urb->dev->speed == USB_SPEED_FULL))) { 192 qh->interval *= 8; 193 qh->sched_frame |= 0x7; 194 qh->start_split_frame = qh->sched_frame; 195 } 196 197 } 198 199 DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n"); 200 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - qh = %p\n", qh); 201 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Device Address = %d\n", 202 urb->dev->devnum); 203 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Endpoint %d, %s\n", 204 usb_pipeendpoint(urb->pipe), 205 usb_pipein(urb->pipe) == USB_DIR_IN ? "IN" : "OUT"); 206 207 switch(urb->dev->speed) { 208 case USB_SPEED_LOW: 209 speed = "low"; 210 break; 211 case USB_SPEED_FULL: 212 speed = "full"; 213 break; 214 case USB_SPEED_HIGH: 215 speed = "high"; 216 break; 217 default: 218 speed = "?"; 219 break; 220 } 221 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Speed = %s\n", speed); 222 223 switch (qh->ep_type) { 224 case USB_ENDPOINT_XFER_ISOC: 225 type = "isochronous"; 226 break; 227 case USB_ENDPOINT_XFER_INT: 228 type = "interrupt"; 229 break; 230 case USB_ENDPOINT_XFER_CONTROL: 231 type = "control"; 232 break; 233 case USB_ENDPOINT_XFER_BULK: 234 type = "bulk"; 235 break; 236 default: 237 type = "?"; 238 break; 239 } 240 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - Type = %s\n",type); 241 242#ifdef DEBUG 243 if (qh->ep_type == USB_ENDPOINT_XFER_INT) { 244 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n", 245 qh->usecs); 246 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n", 247 qh->interval); 248 } 249#endif 250 qh->dw_align_buf = NULL; 251 return; 252} 253 254/** 255 * Checks that a channel is available for a periodic transfer. 256 * 257 * @return 0 if successful, negative error code otherise. 258 */ 259static int periodic_channel_available(dwc_otg_hcd_t *hcd) 260{ 261 /* 262 * Currently assuming that there is a dedicated host channnel for each 263 * periodic transaction plus at least one host channel for 264 * non-periodic transactions. 265 */ 266 int status; 267 int num_channels; 268 269 num_channels = hcd->core_if->core_params->host_channels; 270 if ((hcd->periodic_channels + hcd->non_periodic_channels < num_channels) && 271 (hcd->periodic_channels < num_channels - 1)) { 272 status = 0; 273 } 274 else { 275 DWC_NOTICE("%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n", 276 __func__, num_channels, hcd->periodic_channels, 277 hcd->non_periodic_channels); 278 status = -ENOSPC; 279 } 280 281 return status; 282} 283 284/** 285 * Checks that there is sufficient bandwidth for the specified QH in the 286 * periodic schedule. For simplicity, this calculation assumes that all the 287 * transfers in the periodic schedule may occur in the same (micro)frame. 288 * 289 * @param hcd The HCD state structure for the DWC OTG controller. 290 * @param qh QH containing periodic bandwidth required. 291 * 292 * @return 0 if successful, negative error code otherwise. 293 */ 294static int check_periodic_bandwidth(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) 295{ 296 int status; 297 uint16_t max_claimed_usecs; 298 299 status = 0; 300 301 if (hcd->core_if->core_params->speed == DWC_SPEED_PARAM_HIGH) { 302 /* 303 * High speed mode. 304 * Max periodic usecs is 80% x 125 usec = 100 usec. 305 */ 306 max_claimed_usecs = 100 - qh->usecs; 307 } else { 308 /* 309 * Full speed mode. 310 * Max periodic usecs is 90% x 1000 usec = 900 usec. 311 */ 312 max_claimed_usecs = 900 - qh->usecs; 313 } 314 315 if (hcd->periodic_usecs > max_claimed_usecs) { 316 DWC_NOTICE("%s: already claimed usecs %d, required usecs %d\n", 317 __func__, hcd->periodic_usecs, qh->usecs); 318 status = -ENOSPC; 319 } 320 321 return status; 322} 323 324/** 325 * Checks that the max transfer size allowed in a host channel is large enough 326 * to handle the maximum data transfer in a single (micro)frame for a periodic 327 * transfer. 328 * 329 * @param hcd The HCD state structure for the DWC OTG controller. 330 * @param qh QH for a periodic endpoint. 331 * 332 * @return 0 if successful, negative error code otherwise. 333 */ 334static int check_max_xfer_size(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) 335{ 336 int status; 337 uint32_t max_xfer_size; 338 uint32_t max_channel_xfer_size; 339 340 status = 0; 341 342 max_xfer_size = dwc_max_packet(qh->maxp) * dwc_hb_mult(qh->maxp); 343 max_channel_xfer_size = hcd->core_if->core_params->max_transfer_size; 344 345 if (max_xfer_size > max_channel_xfer_size) { 346 DWC_NOTICE("%s: Periodic xfer length %d > " 347 "max xfer length for channel %d\n", 348 __func__, max_xfer_size, max_channel_xfer_size); 349 status = -ENOSPC; 350 } 351 352 return status; 353} 354 355/** 356 * Schedules an interrupt or isochronous transfer in the periodic schedule. 357 * 358 * @param hcd The HCD state structure for the DWC OTG controller. 359 * @param qh QH for the periodic transfer. The QH should already contain the 360 * scheduling information. 361 * 362 * @return 0 if successful, negative error code otherwise. 363 */ 364static int schedule_periodic(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) 365{ 366 int status = 0; 367 368 status = periodic_channel_available(hcd); 369 if (status) { 370 DWC_NOTICE("%s: No host channel available for periodic " 371 "transfer.\n", __func__); 372 return status; 373 } 374 375 status = check_periodic_bandwidth(hcd, qh); 376 if (status) { 377 DWC_NOTICE("%s: Insufficient periodic bandwidth for " 378 "periodic transfer.\n", __func__); 379 return status; 380 } 381 382 status = check_max_xfer_size(hcd, qh); 383 if (status) { 384 DWC_NOTICE("%s: Channel max transfer size too small " 385 "for periodic transfer.\n", __func__); 386 return status; 387 } 388 389 /* Always start in the inactive schedule. */ 390 list_add_tail(&qh->qh_list_entry, &hcd->periodic_sched_inactive); 391 392 /* Reserve the periodic channel. */ 393 hcd->periodic_channels++; 394 395 /* Update claimed usecs per (micro)frame. */ 396 hcd->periodic_usecs += qh->usecs; 397 398 /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */ 399 hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated += qh->usecs / qh->interval; 400 if (qh->ep_type == USB_ENDPOINT_XFER_INT) { 401 hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs++; 402 DWC_DEBUGPL(DBG_HCD, "Scheduled intr: qh %p, usecs %d, period %d\n", 403 qh, qh->usecs, qh->interval); 404 } else { 405 hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs++; 406 DWC_DEBUGPL(DBG_HCD, "Scheduled isoc: qh %p, usecs %d, period %d\n", 407 qh, qh->usecs, qh->interval); 408 } 409 410 return status; 411} 412 413/** 414 * This function adds a QH to either the non periodic or periodic schedule if 415 * it is not already in the schedule. If the QH is already in the schedule, no 416 * action is taken. 417 * 418 * @return 0 if successful, negative error code otherwise. 419 */ 420int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) 421{ 422 unsigned long flags; 423 int status = 0; 424 425 SPIN_LOCK_IRQSAVE(&hcd->lock, flags) 426 427 if (!list_empty(&qh->qh_list_entry)) { 428 /* QH already in a schedule. */ 429 goto done; 430 } 431 432 /* Add the new QH to the appropriate schedule */ 433 if (dwc_qh_is_non_per(qh)) { 434 /* Always start in the inactive schedule. */ 435 list_add_tail(&qh->qh_list_entry, &hcd->non_periodic_sched_inactive); 436 } else { 437 status = schedule_periodic(hcd, qh); 438 } 439 440 done: 441 SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags) 442 443 return status; 444} 445 446/** 447 * Removes an interrupt or isochronous transfer from the periodic schedule. 448 * 449 * @param hcd The HCD state structure for the DWC OTG controller. 450 * @param qh QH for the periodic transfer. 451 */ 452static void deschedule_periodic(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) 453{ 454 list_del_init(&qh->qh_list_entry); 455 456 /* Release the periodic channel reservation. */ 457 hcd->periodic_channels--; 458 459 /* Update claimed usecs per (micro)frame. */ 460 hcd->periodic_usecs -= qh->usecs; 461 462 /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */ 463 hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_allocated -= qh->usecs / qh->interval; 464 465 if (qh->ep_type == USB_ENDPOINT_XFER_INT) { 466 hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_int_reqs--; 467 DWC_DEBUGPL(DBG_HCD, "Descheduled intr: qh %p, usecs %d, period %d\n", 468 qh, qh->usecs, qh->interval); 469 } else { 470 hcd_to_bus(dwc_otg_hcd_to_hcd(hcd))->bandwidth_isoc_reqs--; 471 DWC_DEBUGPL(DBG_HCD, "Descheduled isoc: qh %p, usecs %d, period %d\n", 472 qh, qh->usecs, qh->interval); 473 } 474} 475 476/** 477 * Removes a QH from either the non-periodic or periodic schedule. Memory is 478 * not freed. 479 * 480 * @param[in] hcd The HCD state structure. 481 * @param[in] qh QH to remove from schedule. */ 482void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh) 483{ 484 unsigned long flags; 485 486 SPIN_LOCK_IRQSAVE(&hcd->lock, flags); 487 488 if (list_empty(&qh->qh_list_entry)) { 489 /* QH is not in a schedule. */ 490 goto done; 491 } 492 493 if (dwc_qh_is_non_per(qh)) { 494 if (hcd->non_periodic_qh_ptr == &qh->qh_list_entry) { 495 hcd->non_periodic_qh_ptr = hcd->non_periodic_qh_ptr->next; 496 } 497 list_del_init(&qh->qh_list_entry); 498 } else { 499 deschedule_periodic(hcd, qh); 500 } 501 502 done: 503 SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags) 504} 505 506/** 507 * Deactivates a QH. For non-periodic QHs, removes the QH from the active 508 * non-periodic schedule. The QH is added to the inactive non-periodic 509 * schedule if any QTDs are still attached to the QH. 510 * 511 * For periodic QHs, the QH is removed from the periodic queued schedule. If 512 * there are any QTDs still attached to the QH, the QH is added to either the 513 * periodic inactive schedule or the periodic ready schedule and its next 514 * scheduled frame is calculated. The QH is placed in the ready schedule if 515 * the scheduled frame has been reached already. Otherwise it's placed in the 516 * inactive schedule. If there are no QTDs attached to the QH, the QH is 517 * completely removed from the periodic schedule. 518 */ 519void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *hcd, dwc_otg_qh_t *qh, int sched_next_periodic_split) 520{ 521 unsigned long flags; 522 SPIN_LOCK_IRQSAVE(&hcd->lock, flags); 523 524 if (dwc_qh_is_non_per(qh)) { 525 dwc_otg_hcd_qh_remove(hcd, qh); 526 if (!list_empty(&qh->qtd_list)) { 527 /* Add back to inactive non-periodic schedule. */ 528 dwc_otg_hcd_qh_add(hcd, qh); 529 } 530 } else { 531 uint16_t frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(hcd)); 532 533 if (qh->do_split) { 534 /* Schedule the next continuing periodic split transfer */ 535 if (sched_next_periodic_split) { 536 537 qh->sched_frame = frame_number; 538 if (dwc_frame_num_le(frame_number, 539 dwc_frame_num_inc(qh->start_split_frame, 1))) { 540 /* 541 * Allow one frame to elapse after start 542 * split microframe before scheduling 543 * complete split, but DONT if we are 544 * doing the next start split in the 545 * same frame for an ISOC out. 546 */ 547 if ((qh->ep_type != USB_ENDPOINT_XFER_ISOC) || (qh->ep_is_in != 0)) { 548 qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, 1); 549 } 550 } 551 } else { 552 qh->sched_frame = dwc_frame_num_inc(qh->start_split_frame, 553 qh->interval); 554 if (dwc_frame_num_le(qh->sched_frame, frame_number)) { 555 qh->sched_frame = frame_number; 556 } 557 qh->sched_frame |= 0x7; 558 qh->start_split_frame = qh->sched_frame; 559 } 560 } else { 561 qh->sched_frame = dwc_frame_num_inc(qh->sched_frame, qh->interval); 562 if (dwc_frame_num_le(qh->sched_frame, frame_number)) { 563 qh->sched_frame = frame_number; 564 } 565 } 566 567 if (list_empty(&qh->qtd_list)) { 568 dwc_otg_hcd_qh_remove(hcd, qh); 569 } else { 570 /* 571 * Remove from periodic_sched_queued and move to 572 * appropriate queue. 573 */ 574 if (qh->sched_frame == frame_number) { 575 list_move(&qh->qh_list_entry, 576 &hcd->periodic_sched_ready); 577 } else { 578 list_move(&qh->qh_list_entry, 579 &hcd->periodic_sched_inactive); 580 } 581 } 582 } 583 584 SPIN_UNLOCK_IRQRESTORE(&hcd->lock, flags); 585} 586 587/** 588 * This function allocates and initializes a QTD. 589 * 590 * @param[in] urb The URB to create a QTD from. Each URB-QTD pair will end up 591 * pointing to each other so each pair should have a unique correlation. 592 * 593 * @return Returns pointer to the newly allocated QTD, or NULL on error. */ 594dwc_otg_qtd_t *dwc_otg_hcd_qtd_create (struct urb *urb) 595{ 596 dwc_otg_qtd_t *qtd; 597 598 qtd = dwc_otg_hcd_qtd_alloc (); 599 if (qtd == NULL) { 600 return NULL; 601 } 602 603 dwc_otg_hcd_qtd_init (qtd, urb); 604 return qtd; 605} 606 607/** 608 * Initializes a QTD structure. 609 * 610 * @param[in] qtd The QTD to initialize. 611 * @param[in] urb The URB to use for initialization. */ 612void dwc_otg_hcd_qtd_init (dwc_otg_qtd_t *qtd, struct urb *urb) 613{ 614 memset (qtd, 0, sizeof (dwc_otg_qtd_t)); 615 qtd->urb = urb; 616 if (usb_pipecontrol(urb->pipe)) { 617 /* 618 * The only time the QTD data toggle is used is on the data 619 * phase of control transfers. This phase always starts with 620 * DATA1. 621 */ 622 qtd->data_toggle = DWC_OTG_HC_PID_DATA1; 623 qtd->control_phase = DWC_OTG_CONTROL_SETUP; 624 } 625 626 /* start split */ 627 qtd->complete_split = 0; 628 qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL; 629 qtd->isoc_split_offset = 0; 630 631 /* Store the qtd ptr in the urb to reference what QTD. */ 632 urb->hcpriv = qtd; 633 return; 634} 635 636/** 637 * This function adds a QTD to the QTD-list of a QH. It will find the correct 638 * QH to place the QTD into. If it does not find a QH, then it will create a 639 * new QH. If the QH to which the QTD is added is not currently scheduled, it 640 * is placed into the proper schedule based on its EP type. 641 * 642 * @param[in] qtd The QTD to add 643 * @param[in] dwc_otg_hcd The DWC HCD structure 644 * 645 * @return 0 if successful, negative error code otherwise. 646 */ 647int dwc_otg_hcd_qtd_add (dwc_otg_qtd_t *qtd, 648 dwc_otg_hcd_t *dwc_otg_hcd) 649{ 650 struct usb_host_endpoint *ep; 651 dwc_otg_qh_t *qh; 652 unsigned long flags; 653 int retval = 0; 654 655 struct urb *urb = qtd->urb; 656 657 SPIN_LOCK_IRQSAVE(&dwc_otg_hcd->lock, flags); 658 659 /* 660 * Get the QH which holds the QTD-list to insert to. Create QH if it 661 * doesn't exist. 662 */ 663 ep = dwc_urb_to_endpoint(urb); 664 qh = (dwc_otg_qh_t *)ep->hcpriv; 665 if (qh == NULL) { 666 qh = dwc_otg_hcd_qh_create (dwc_otg_hcd, urb); 667 if (qh == NULL) { 668 goto done; 669 } 670 ep->hcpriv = qh; 671 } 672 673 retval = dwc_otg_hcd_qh_add(dwc_otg_hcd, qh); 674 if (retval == 0) { 675 list_add_tail(&qtd->qtd_list_entry, &qh->qtd_list); 676 } 677 678 done: 679 SPIN_UNLOCK_IRQRESTORE(&dwc_otg_hcd->lock, flags); 680 681 return retval; 682} 683 684#endif /* DWC_DEVICE_ONLY */ 685