(no commit message)
[firefly-linux-kernel-4.4.55.git] / drivers / usb / dwc_otg / dwc_otg_hcd_queue.c
1 /* ==========================================================================
2  * $File: //dwh/usb_iip/dev/software/otg_ipmate/linux/drivers/dwc_otg_hcd_queue.c $
3  * $Revision: #4 $
4  * $Date: 2005/09/15 $
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/irq.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. */
64 dwc_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] _qh The QH to free.
84  */
85 void dwc_otg_hcd_qh_free (dwc_otg_qh_t *_qh)
86 {
87         dwc_otg_qtd_t *qtd;
88         struct list_head *pos;
89         unsigned long flags;
90
91         /* Free each QTD in the QTD list */
92         local_irq_save (flags);
93         for (pos = _qh->qtd_list.next;
94              pos != &_qh->qtd_list;
95              pos = _qh->qtd_list.next)
96         {
97                 list_del (pos);
98                 qtd = dwc_list_to_qtd (pos);
99                 dwc_otg_hcd_qtd_free (qtd);
100         }
101         local_irq_restore (flags);
102
103         kfree (_qh);
104         return;
105 }
106
107 /** Initializes a QH structure.
108  *
109  * @param[in] _hcd The HCD state structure for the DWC OTG controller.
110  * @param[in] _qh The QH to init.
111  * @param[in] _urb Holds the information about the device/endpoint that we need
112  * to initialize the QH. */
113 #define SCHEDULE_SLOP 10
114 void dwc_otg_hcd_qh_init(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, struct urb *_urb)
115 {
116         memset (_qh, 0, sizeof (dwc_otg_qh_t));
117
118         /* Initialize QH */
119         switch (usb_pipetype(_urb->pipe)) {
120         case PIPE_CONTROL:
121                 _qh->ep_type = USB_ENDPOINT_XFER_CONTROL;
122                 break;
123         case PIPE_BULK:
124                 _qh->ep_type = USB_ENDPOINT_XFER_BULK;
125                 break;
126         case PIPE_ISOCHRONOUS:
127                 _qh->ep_type = USB_ENDPOINT_XFER_ISOC;
128                 break;
129         case PIPE_INTERRUPT: 
130                 _qh->ep_type = USB_ENDPOINT_XFER_INT;
131                 break;
132         }
133
134         _qh->ep_is_in = usb_pipein(_urb->pipe) ? 1 : 0;
135
136         _qh->data_toggle = DWC_OTG_HC_PID_DATA0;
137         _qh->maxp = usb_maxpacket(_urb->dev, _urb->pipe, !(usb_pipein(_urb->pipe)));
138         INIT_LIST_HEAD(&_qh->qtd_list);
139         INIT_LIST_HEAD(&_qh->qh_list_entry);
140         _qh->channel = NULL;
141
142         /* FS/LS Enpoint on HS Hub 
143          * NOT virtual root hub */
144 #if 1
145         _qh->do_split = 0;
146         if (((_urb->dev->speed == USB_SPEED_LOW) || 
147              (_urb->dev->speed == USB_SPEED_FULL)) &&
148             (_urb->dev->tt) && (_urb->dev->tt->hub->devnum != 1)) 
149         {
150                 DWC_DEBUGPL(DBG_HCD, "QH init: EP %d: TT found at hub addr %d, for port %d\n", 
151                            usb_pipeendpoint(_urb->pipe), _urb->dev->tt->hub->devnum, 
152                            _urb->dev->ttport);
153                 _qh->do_split = 1;
154         }
155 #endif
156
157         if (_qh->ep_type == USB_ENDPOINT_XFER_INT ||
158             _qh->ep_type == USB_ENDPOINT_XFER_ISOC) {
159                 /* Compute scheduling parameters once and save them. */
160                 hprt0_data_t hprt;
161
162                 /** @todo Account for split transfers in the bus time. */
163                 int bytecount = dwc_hb_mult(_qh->maxp) * dwc_max_packet(_qh->maxp);
164                 _qh->usecs = usb_calc_bus_time(_urb->dev->speed,
165                                                usb_pipein(_urb->pipe),
166                                                (_qh->ep_type == USB_ENDPOINT_XFER_ISOC),
167                                                bytecount);
168
169                 /* Start in a slightly future (micro)frame. */
170                 _qh->sched_frame = dwc_frame_num_inc(_hcd->frame_number,
171                                                      SCHEDULE_SLOP);
172                 _qh->interval = _urb->interval;
173 #if 0
174                 /* Increase interrupt polling rate for debugging. */
175                 if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
176                         _qh->interval = 8;
177                 }
178 #endif          
179                 hprt.d32 = dwc_read_reg32(_hcd->core_if->host_if->hprt0);
180                 if ((hprt.b.prtspd == DWC_HPRT0_PRTSPD_HIGH_SPEED) && 
181                     ((_urb->dev->speed == USB_SPEED_LOW) || 
182                      (_urb->dev->speed == USB_SPEED_FULL)))
183                 {
184                         _qh->interval *= 8;
185                         _qh->sched_frame |= 0x7;
186                         _qh->start_split_frame = _qh->sched_frame;
187                 }
188
189         }
190
191         DWC_DEBUGPL(DBG_HCD, "DWC OTG HCD QH Initialized\n");
192         DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH  - qh = %p\n", _qh);
193         DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH  - Device Address = %d\n",
194                     _urb->dev->devnum);
195         DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH  - Endpoint %d, %s\n",
196                     usb_pipeendpoint(_urb->pipe),
197                     usb_pipein(_urb->pipe) == USB_DIR_IN ? "IN" : "OUT");
198         DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH  - Speed = %s\n", 
199                     ({ char *speed; switch (_urb->dev->speed) {
200                     case USB_SPEED_LOW: speed = "low";  break;
201                     case USB_SPEED_FULL: speed = "full";        break;
202                     case USB_SPEED_HIGH: speed = "high";        break;
203                     default: speed = "?";       break;
204                     }; speed;}));
205         DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH  - Type = %s\n",
206                     ({ char *type; switch (_qh->ep_type) {
207                     case USB_ENDPOINT_XFER_ISOC: type = "isochronous";  break;
208                     case USB_ENDPOINT_XFER_INT: type = "interrupt";     break;
209                     case USB_ENDPOINT_XFER_CONTROL: type = "control";   break;
210                     case USB_ENDPOINT_XFER_BULK: type = "bulk"; break;
211                     default: type = "?";        break;
212                     }; type;}));
213 #ifdef DEBUG
214         if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
215                 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - usecs = %d\n",
216                             _qh->usecs);
217                 DWC_DEBUGPL(DBG_HCDV, "DWC OTG HCD QH - interval = %d\n",
218                             _qh->interval);
219         }
220 #endif  
221         
222         return;
223 }
224
225 /**
226  * Checks that a channel is available for a periodic transfer.
227  *
228  * @return 0 if successful, negative error code otherise.
229  */
230 static int periodic_channel_available(dwc_otg_hcd_t *_hcd)
231 {
232         /*
233          * Currently assuming that there is a dedicated host channnel for each
234          * periodic transaction plus at least one host channel for
235          * non-periodic transactions.
236          */
237         int status;
238         int num_channels;
239
240         num_channels = _hcd->core_if->core_params->host_channels;
241         if ((_hcd->periodic_channels + _hcd->non_periodic_channels < num_channels) &&
242             (_hcd->periodic_channels < num_channels - 1)) {
243                 status = 0;
244         }
245         else {
246                 DWC_NOTICE("%s: Total channels: %d, Periodic: %d, Non-periodic: %d\n",
247                            __func__, num_channels, _hcd->periodic_channels,
248                            _hcd->non_periodic_channels);
249                 status = -ENOSPC;
250         }
251
252         return status;
253 }
254
255 /**
256  * Checks that there is sufficient bandwidth for the specified QH in the
257  * periodic schedule. For simplicity, this calculation assumes that all the
258  * transfers in the periodic schedule may occur in the same (micro)frame.
259  *
260  * @param _hcd The HCD state structure for the DWC OTG controller.
261  * @param _qh QH containing periodic bandwidth required.
262  *
263  * @return 0 if successful, negative error code otherwise.
264  */
265 static int check_periodic_bandwidth(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
266 {
267         int             status;
268         uint16_t        max_claimed_usecs;
269
270         status = 0;
271
272         if (_hcd->core_if->core_params->speed == DWC_SPEED_PARAM_HIGH) {
273                 /*
274                  * High speed mode.
275                  * Max periodic usecs is 80% x 125 usec = 100 usec.
276                  */
277                 max_claimed_usecs = 100 - _qh->usecs;
278         } else {
279                 /*
280                  * Full speed mode.
281                  * Max periodic usecs is 90% x 1000 usec = 900 usec.
282                  */
283                 max_claimed_usecs = 900 - _qh->usecs;
284         }
285
286         if (_hcd->periodic_usecs > max_claimed_usecs) {
287                 DWC_NOTICE("%s: already claimed usecs %d, required usecs %d\n",
288                            __func__, _hcd->periodic_usecs, _qh->usecs);
289                 status = -ENOSPC;
290         }
291
292         return status;
293 }
294                         
295 /**
296  * Checks that the max transfer size allowed in a host channel is large enough
297  * to handle the maximum data transfer in a single (micro)frame for a periodic
298  * transfer.
299  *
300  * @param _hcd The HCD state structure for the DWC OTG controller.
301  * @param _qh QH for a periodic endpoint.
302  *
303  * @return 0 if successful, negative error code otherwise.
304  */
305 static int check_max_xfer_size(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
306 {
307         int             status;
308         uint32_t        max_xfer_size;
309         uint32_t        max_channel_xfer_size;
310
311         status = 0;
312
313         max_xfer_size = dwc_max_packet(_qh->maxp) * dwc_hb_mult(_qh->maxp);
314         max_channel_xfer_size = _hcd->core_if->core_params->max_transfer_size;
315
316         if (max_xfer_size > max_channel_xfer_size) {
317                 DWC_NOTICE("%s: Periodic xfer length %d > "
318                             "max xfer length for channel %d\n",
319                             __func__, max_xfer_size, max_channel_xfer_size);
320                 status = -ENOSPC;
321         }
322
323         return status;
324 }
325
326 /**
327  * Schedules an interrupt or isochronous transfer in the periodic schedule.
328  *
329  * @param _hcd The HCD state structure for the DWC OTG controller.
330  * @param _qh QH for the periodic transfer. The QH should already contain the
331  * scheduling information.
332  *
333  * @return 0 if successful, negative error code otherwise.
334  */
335 static int schedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
336 {
337         int status = 0;
338
339         status = periodic_channel_available(_hcd);
340         if (status) {
341                 DWC_NOTICE("%s: No host channel available for periodic "
342                            "transfer.\n", __func__);
343                 return status;
344         }
345
346         status = check_periodic_bandwidth(_hcd, _qh);
347         if (status) {
348                 DWC_NOTICE("%s: Insufficient periodic bandwidth for "
349                            "periodic transfer.\n", __func__);
350                 return status;
351         }
352
353         status = check_max_xfer_size(_hcd, _qh);
354         if (status) {
355                 DWC_NOTICE("%s: Channel max transfer size too small "
356                             "for periodic transfer.\n", __func__);
357                 return status;
358         }
359
360         /* Always start in the inactive schedule. */
361         list_add_tail(&_qh->qh_list_entry, &_hcd->periodic_sched_inactive);
362
363         /* Reserve the periodic channel. */
364         _hcd->periodic_channels++;
365
366         /* Update claimed usecs per (micro)frame. */
367         _hcd->periodic_usecs += _qh->usecs;
368
369         /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
370         hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_allocated += _qh->usecs / _qh->interval;
371         if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
372                 hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_int_reqs++;
373                 DWC_DEBUGPL(DBG_HCD, "Scheduled intr: qh %p, usecs %d, period %d\n",
374                             _qh, _qh->usecs, _qh->interval);
375         } else {
376                 hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_isoc_reqs++;
377                 DWC_DEBUGPL(DBG_HCD, "Scheduled isoc: qh %p, usecs %d, period %d\n",
378                             _qh, _qh->usecs, _qh->interval);
379         }
380                 
381         return status;
382 }
383
384 /**
385  * This function adds a QH to either the non periodic or periodic schedule if
386  * it is not already in the schedule. If the QH is already in the schedule, no
387  * action is taken.
388  *
389  * @return 0 if successful, negative error code otherwise.
390  */
391 int dwc_otg_hcd_qh_add (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
392 {
393         //unsigned long flags;
394         int status = 0;
395
396         //local_irq_save(flags);
397
398         if (!list_empty(&_qh->qh_list_entry)) {
399                 /* QH already in a schedule. */
400                 goto done;
401         }
402
403         /* Add the new QH to the appropriate schedule */
404         if (dwc_qh_is_non_per(_qh)) {
405                 /* Always start in the inactive schedule. */
406                 list_add_tail(&_qh->qh_list_entry, &_hcd->non_periodic_sched_inactive);
407         } else {
408                 status = schedule_periodic(_hcd, _qh);
409         }
410
411  done:
412         //local_irq_restore(flags);
413
414         return status;
415 }
416
417 /**
418  * Removes an interrupt or isochronous transfer from the periodic schedule.
419  *
420  * @param _hcd The HCD state structure for the DWC OTG controller.
421  * @param _qh QH for the periodic transfer.
422  */
423 static void deschedule_periodic(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
424 {
425         list_del_init(&_qh->qh_list_entry);
426
427         /* Release the periodic channel reservation. */
428         _hcd->periodic_channels--;
429
430         /* Update claimed usecs per (micro)frame. */
431         _hcd->periodic_usecs -= _qh->usecs;
432
433         /* Update average periodic bandwidth claimed and # periodic reqs for usbfs. */
434         hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_allocated -= _qh->usecs / _qh->interval;
435
436         if (_qh->ep_type == USB_ENDPOINT_XFER_INT) {
437                 hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_int_reqs--;
438                 DWC_DEBUGPL(DBG_HCD, "Descheduled intr: qh %p, usecs %d, period %d\n",
439                             _qh, _qh->usecs, _qh->interval);
440         } else {
441                 hcd_to_bus(dwc_otg_hcd_to_hcd(_hcd))->bandwidth_isoc_reqs--;
442                 DWC_DEBUGPL(DBG_HCD, "Descheduled isoc: qh %p, usecs %d, period %d\n",
443                             _qh, _qh->usecs, _qh->interval);
444         }
445 }
446
447 /** 
448  * Removes a QH from either the non-periodic or periodic schedule.  Memory is
449  * not freed.
450  *
451  * @param[in] _hcd The HCD state structure.
452  * @param[in] _qh QH to remove from schedule. */
453 void dwc_otg_hcd_qh_remove (dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh)
454 {
455         unsigned long flags;
456
457         local_irq_save(flags);
458
459         if (list_empty(&_qh->qh_list_entry)) {
460                 /* QH is not in a schedule. */
461                 goto done;
462         }
463
464         if (dwc_qh_is_non_per(_qh)) {
465                 if (_hcd->non_periodic_qh_ptr == &_qh->qh_list_entry) {
466                         _hcd->non_periodic_qh_ptr = _hcd->non_periodic_qh_ptr->next;
467                 }
468                 list_del_init(&_qh->qh_list_entry);
469         } else {
470                 deschedule_periodic(_hcd, _qh);
471         }
472
473  done:
474         local_irq_restore(flags);
475 }
476
477 /**
478  * Deactivates a QH. For non-periodic QHs, removes the QH from the active
479  * non-periodic schedule. The QH is added to the inactive non-periodic
480  * schedule if any QTDs are still attached to the QH.
481  *
482  * For periodic QHs, the QH is removed from the periodic queued schedule. If
483  * there are any QTDs still attached to the QH, the QH is added to either the
484  * periodic inactive schedule or the periodic ready schedule and its next
485  * scheduled frame is calculated. The QH is placed in the ready schedule if
486  * the scheduled frame has been reached already. Otherwise it's placed in the
487  * inactive schedule. If there are no QTDs attached to the QH, the QH is
488  * completely removed from the periodic schedule.
489  */
490 void dwc_otg_hcd_qh_deactivate(dwc_otg_hcd_t *_hcd, dwc_otg_qh_t *_qh, int sched_next_periodic_split)
491 {
492         unsigned long flags;
493         local_irq_save(flags);
494
495         if (dwc_qh_is_non_per(_qh)) {
496                 dwc_otg_hcd_qh_remove(_hcd, _qh);
497                 if (!list_empty(&_qh->qtd_list)) {
498                         /* Add back to inactive non-periodic schedule. */
499                         dwc_otg_hcd_qh_add(_hcd, _qh);
500                 }
501         } else {
502                 uint16_t frame_number = dwc_otg_hcd_get_frame_number(dwc_otg_hcd_to_hcd(_hcd));
503
504                 if (_qh->do_split) {
505                         /* Schedule the next continuing periodic split transfer */
506                         if (sched_next_periodic_split) {
507
508                                 _qh->sched_frame = frame_number;
509                                 if (dwc_frame_num_le(frame_number,
510                                                      dwc_frame_num_inc(_qh->start_split_frame, 1))) {
511                                         /*
512                                          * Allow one frame to elapse after start
513                                          * split microframe before scheduling
514                                          * complete split, but DONT if we are
515                                          * doing the next start split in the
516                                          * same frame for an ISOC out.
517                                          */
518                                         if ((_qh->ep_type != USB_ENDPOINT_XFER_ISOC) || (_qh->ep_is_in != 0)) {
519                                                 _qh->sched_frame = dwc_frame_num_inc(_qh->sched_frame, 1);
520                                         }
521                                 }
522                         } else {
523                                 _qh->sched_frame = dwc_frame_num_inc(_qh->start_split_frame,
524                                                                      _qh->interval);
525                                 if (dwc_frame_num_le(_qh->sched_frame, frame_number)) {
526                                         _qh->sched_frame = frame_number;
527                                 }
528                                 _qh->sched_frame |= 0x7;
529                                 _qh->start_split_frame = _qh->sched_frame;
530                         }
531                 } else {
532                         _qh->sched_frame = dwc_frame_num_inc(_qh->sched_frame, _qh->interval);
533                         if (dwc_frame_num_le(_qh->sched_frame, frame_number)) {
534                                 _qh->sched_frame = frame_number;
535                         }
536                 }
537
538                 if (list_empty(&_qh->qtd_list)) {
539                         dwc_otg_hcd_qh_remove(_hcd, _qh);
540                 } else {
541                         /*
542                          * Remove from periodic_sched_queued and move to
543                          * appropriate queue.
544                          */
545                         if (_qh->sched_frame == frame_number) {
546                                 list_move(&_qh->qh_list_entry,
547                                           &_hcd->periodic_sched_ready);
548                         } else {
549                                 list_move(&_qh->qh_list_entry,
550                                           &_hcd->periodic_sched_inactive);
551                         }
552                 }
553         }
554
555         local_irq_restore(flags);
556 }
557
558 /** 
559  * This function allocates and initializes a QTD. 
560  *
561  * @param[in] _urb The URB to create a QTD from.  Each URB-QTD pair will end up
562  * pointing to each other so each pair should have a unique correlation.
563  *
564  * @return Returns pointer to the newly allocated QTD, or NULL on error. */
565 dwc_otg_qtd_t *dwc_otg_hcd_qtd_create (struct urb *_urb)
566 {
567         dwc_otg_qtd_t *qtd;
568
569         qtd = dwc_otg_hcd_qtd_alloc ();
570         if (qtd == NULL) {
571                 return NULL;
572         }
573
574         dwc_otg_hcd_qtd_init (qtd, _urb);
575         return qtd;
576 }
577
578 /** 
579  * Initializes a QTD structure.
580  *
581  * @param[in] _qtd The QTD to initialize.
582  * @param[in] _urb The URB to use for initialization.  */
583 void dwc_otg_hcd_qtd_init (dwc_otg_qtd_t *_qtd, struct urb *_urb)
584 {
585         memset (_qtd, 0, sizeof (dwc_otg_qtd_t));
586         _qtd->urb = _urb;
587         if (usb_pipecontrol(_urb->pipe)) {
588                 /*
589                  * The only time the QTD data toggle is used is on the data
590                  * phase of control transfers. This phase always starts with
591                  * DATA1.
592                  */
593                 _qtd->data_toggle = DWC_OTG_HC_PID_DATA1;
594                 _qtd->control_phase = DWC_OTG_CONTROL_SETUP;
595         }
596
597         /* start split */
598         _qtd->complete_split = 0;
599         _qtd->isoc_split_pos = DWC_HCSPLIT_XACTPOS_ALL;
600         _qtd->isoc_split_offset = 0;
601
602         /* Store the qtd ptr in the urb to reference what QTD. */
603         _urb->hcpriv = _qtd;
604         return;
605 }
606
607 /**
608  * This function adds a QTD to the QTD-list of a QH.  It will find the correct
609  * QH to place the QTD into.  If it does not find a QH, then it will create a
610  * new QH. If the QH to which the QTD is added is not currently scheduled, it
611  * is placed into the proper schedule based on its EP type.
612  *
613  * @param[in] _qtd The QTD to add
614  * @param[in] _dwc_otg_hcd The DWC HCD structure
615  *
616  * @return 0 if successful, negative error code otherwise.
617  */
618 int dwc_otg_hcd_qtd_add (dwc_otg_qtd_t *_qtd,
619                          dwc_otg_hcd_t *_dwc_otg_hcd)
620 {
621         struct usb_host_endpoint *ep;
622         dwc_otg_qh_t *qh;
623         //unsigned long flags;
624         int retval = 0;
625
626         struct urb *urb = _qtd->urb;
627
628         //local_irq_save(flags);
629
630         /*
631          * Get the QH which holds the QTD-list to insert to. Create QH if it
632          * doesn't exist.
633          */ 
634         ep = dwc_urb_to_endpoint(urb);
635         qh = (dwc_otg_qh_t *) ep->hcpriv;
636         if (qh == NULL) {
637                 qh = dwc_otg_hcd_qh_create (_dwc_otg_hcd, urb);
638                 if (qh == NULL) {
639                         retval = -ENOMEM;
640                         goto done;
641                 }
642                 ep->hcpriv = qh;
643         }
644         
645         retval = dwc_otg_hcd_qh_add(_dwc_otg_hcd, qh);
646         if (retval == 0) {
647                 list_add_tail(&_qtd->qtd_list_entry, &qh->qtd_list);
648         }
649
650  done:
651         //local_irq_restore(flags);
652         return retval;
653 }
654
655 #endif /* DWC_DEVICE_ONLY */