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