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