[lantiq] add ltq-hcd
[openwrt.git] / package / platform / lantiq / ltq-hcd / src / ifxhcd.c
1 /*****************************************************************************
2  **   FILE NAME       : ifxhcd.c
3  **   PROJECT         : IFX USB sub-system V3
4  **   MODULES         : IFX USB sub-system Host and Device driver
5  **   SRC VERSION     : 3.2
6  **   DATE            : 1/Jan/2011
7  **   AUTHOR          : Chen, Howard
8  **   DESCRIPTION     : This file contains the structures, constants, and
9  **                     interfaces for the Host Contoller Driver (HCD).
10  **
11  **                     The Host Controller Driver (HCD) is responsible for
12  **                     translating requests from the USB Driver into the
13  **                     appropriate actions on the IFXUSB controller.
14  **                     It isolates the USBD from the specifics of the
15  **                     controller by providing an API to the USBD.
16  **   FUNCTIONS       :
17  **   COMPILER        : gcc
18  **   REFERENCE       : Synopsys DWC-OTG Driver 2.7
19  **   COPYRIGHT       :  Copyright (c) 2010
20  **                      LANTIQ DEUTSCHLAND GMBH,
21  **                      Am Campeon 3, 85579 Neubiberg, Germany
22  **
23  **    This program is free software; you can redistribute it and/or modify
24  **    it under the terms of the GNU General Public License as published by
25  **    the Free Software Foundation; either version 2 of the License, or
26  **    (at your option) any later version.
27  **
28  **  Version Control Section  **
29  **   $Author$
30  **   $Date$
31  **   $Revisions$
32  **   $Log$       Revision history
33  *****************************************************************************/
34
35 /*
36  * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
37  * For this code the following notice is applicable:
38  *
39  * ==========================================================================
40  *
41  * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
42  * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
43  * otherwise expressly agreed to in writing between Synopsys and you.
44  *
45  * The Software IS NOT an item of Licensed Software or Licensed Product under
46  * any End User Software License Agreement or Agreement for Licensed Product
47  * with Synopsys or any supplement thereto. You are permitted to use and
48  * redistribute this Software in source and binary forms, with or without
49  * modification, provided that redistributions of source code must retain this
50  * notice. You may not view, use, disclose, copy or distribute this file or
51  * any information contained herein except pursuant to this license grant from
52  * Synopsys. If you do not agree with this notice, including the disclaimer
53  * below, then you are not authorized to use the Software.
54  *
55  * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
56  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
58  * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
59  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
60  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
61  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
62  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
65  * DAMAGE.
66  * ========================================================================== */
67
68 /*!
69   \file ifxhcd.c
70   \ingroup IFXUSB_DRIVER_V3
71   \brief This file contains the implementation of the HCD. In Linux,
72    the HCD implements the hc_driver API.
73 */
74
75 #include <linux/version.h>
76 #include "ifxusb_version.h"
77
78 #include <linux/kernel.h>
79 #include <linux/module.h>
80 #include <linux/moduleparam.h>
81 #include <linux/init.h>
82
83 #include <linux/device.h>
84
85 #include <linux/errno.h>
86 #include <linux/list.h>
87 #include <linux/interrupt.h>
88 #include <linux/string.h>
89
90 #include <linux/dma-mapping.h>
91
92
93 #include "ifxusb_plat.h"
94 #include "ifxusb_regs.h"
95 #include "ifxusb_cif.h"
96 #include "ifxhcd.h"
97
98 #include <asm/irq.h>
99
100 #ifdef __DEBUG__
101         static void dump_urb_info(struct urb *_urb, char* _fn_name);
102 #if 0
103         static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd,
104                                       ifxhcd_epqh_t *_epqh);
105 #endif
106 #endif
107
108 static void ifxhcd_complete_urb_sub(ifxhcd_urbd_t *_urbd)
109 {
110         ifxhcd_hcd_t *ifxhcd;
111         struct urb *urb=NULL;
112
113         if (!list_empty(&_urbd->ql))
114         {
115                 list_del_init(&_urbd->ql);
116                 _urbd->epqh->urbd_count--;
117         }
118         else
119                 IFX_ERROR("%s: urb(%p) not connect to any epqh\n",
120                           __func__,_urbd);
121
122         ifxhcd=_urbd->epqh->ifxhcd;
123         urb   =_urbd->urb;
124         if(!urb)
125                 IFX_ERROR("%s: invalid urb\n",__func__);
126         else if(urb->hcpriv)
127         {
128                 if(urb->hcpriv != _urbd)
129                         IFX_ERROR("%s: invalid"
130                                   " urb(%p)->hcpriv(%p) != _urbd(%p)\n",
131                                   __func__,
132                                   urb,
133                                   urb->hcpriv,
134                                   _urbd);
135                 #if   defined(__UNALIGNED_BUF_ADJ__)
136                         if(_urbd->is_in &&
137 //                         _urbd->using_aligned_buf &&
138                            _urbd->aligned_buf)
139                                 memcpy(_urbd->xfer_buff,
140                                        _urbd->aligned_buf,
141                                        _urbd->xfer_len);
142                         if(_urbd->aligned_buf)
143                                 ifxusb_free_buf_h(_urbd->aligned_buf);
144                 #endif
145                 urb->hcpriv = NULL;
146                 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
147                         urb->status=_urbd->status;
148                         usb_hcd_giveback_urb(ifxhcd_to_syshcd(ifxhcd), urb);
149                 #else
150                         usb_hcd_giveback_urb(ifxhcd_to_syshcd(ifxhcd), urb,
151                                              _urbd->status);
152                 #endif
153         }
154         kfree(_urbd);
155 }
156
157 #ifdef __STRICT_ORDER__
158         static void ifxhcd_complete_urb_func(unsigned long data)
159         {
160                 unsigned long             flags;
161                 ifxhcd_urbd_t *urbd;
162                 ifxhcd_epqh_t *epqh;
163                 struct list_head *item;
164
165                 int count=10;
166
167                 epqh=((ifxhcd_epqh_t *)data);
168
169                 while (!list_empty(&epqh->release_list) && count)
170                 {
171                         item = epqh->release_list.next;
172                         urbd = list_entry(item, ifxhcd_urbd_t, ql);
173                         if (!urbd)
174                                 IFX_ERROR("%s: invalid urbd\n",__func__);
175                         else if (!urbd->epqh)
176                                 IFX_ERROR("%s: invalid epqd\n",__func__);
177                         else
178                         {
179                                 ifxhcd_epqh_t *epqh2;
180                                 epqh2=urbd->epqh;
181                                 local_irq_save(flags);
182                                 LOCK_URBD_LIST(epqh2);
183                                 ifxhcd_complete_urb_sub(urbd);
184                                 UNLOCK_URBD_LIST(epqh2);
185                                 local_irq_restore (flags);
186                         }
187                         count--;
188                 }
189                 if(!list_empty(&epqh->release_list))
190                         tasklet_schedule(&epqh->complete_urb_sub);
191         }
192
193         /*!
194          \brief Sets the final status of an URB and returns it to the device
195           driver. Any required cleanup of the URB is performed.
196          */
197         void ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd,
198                                  ifxhcd_urbd_t *_urbd,
199                                  int _status)
200         {
201                 unsigned long             flags;
202
203                 if(!_urbd)
204                 {
205                         IFX_ERROR("%s: invalid urbd\n",__func__);
206                         return;
207                 }
208                 if (!_urbd->epqh)
209                 {
210                         IFX_ERROR("%s: invalid epqh\n",__func__);
211                         return;
212                 }
213
214                 local_irq_save(flags);
215                 LOCK_URBD_LIST(_urbd->epqh);
216                 #ifdef __DEBUG__
217                         if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
218                         {
219                                 IFX_PRINT("%s: ehqh %p _urbd %p, urb %p,"
220                                           " device %d, ep %d %s/%s, status=%d\n",
221                                           __func__,_urbd->epqh,
222                                           _urbd,_urbd->urb,
223                                           (_urbd->urb)?usb_pipedevice(_urbd->urb->pipe):-1,
224                                           (_urbd->urb)?usb_pipeendpoint(_urbd->urb->pipe):-1,
225                                           (_urbd->urb)?(usb_pipein(_urbd->urb->pipe) ? "IN" : "OUT"):"--",
226                                           (_urbd->is_in) ? "IN" : "OUT",
227                                            _status);
228                                 if ((_urbd->urb)&& _urbd->epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
229                                 {
230                                         int i;
231                                         for (i = 0; i < _urbd->urb->number_of_packets; i++)
232                                                 IFX_PRINT("  ISO Desc %d status: %d\n", i, _urbd->urb->iso_frame_desc[i].status);
233                                 }
234                         }
235                 #endif
236                 _urbd->status = _status;
237
238                 if(_urbd->phase!=URBD_FINISHING)
239                 {
240                         if(_urbd->phase!=URBD_DEQUEUEING && _urbd->phase!=URBD_COMPLETING)
241                                 printk(KERN_INFO "Warning: %s() Strange URBD PHASE %d\n",__func__,_urbd->phase);
242                         if(_urbd->urb)
243                         {
244                                 if(   _urbd->status == 0
245                                    && _urbd->phase==URBD_COMPLETING
246                                    && in_irq())
247                                 {
248                                         list_move_tail(&_urbd->ql,&_urbd->epqh->release_list);
249                                         if(!_urbd->epqh->complete_urb_sub.func)
250                                         {
251                                                 _urbd->epqh->complete_urb_sub.next = NULL;
252                                                 _urbd->epqh->complete_urb_sub.state = 0;
253                                                 atomic_set( &_urbd->epqh->complete_urb_sub.count, 0);
254                                                 _urbd->epqh->complete_urb_sub.func = ifxhcd_complete_urb_func;
255                                                 _urbd->epqh->complete_urb_sub.data = (unsigned long)_urbd->epqh;
256                                         }
257                                         tasklet_schedule(&_urbd->epqh->complete_urb_sub);
258                                 }
259                                 else
260                                 {
261                                         _urbd->phase=URBD_FINISHING;
262                                         ifxhcd_complete_urb_sub(_urbd);
263                                 }
264                                 UNLOCK_URBD_LIST(_urbd->epqh);
265                         }
266                         else
267                         {
268                                 UNLOCK_URBD_LIST(_urbd->epqh);
269                                 kfree(_urbd);
270                         }
271                 }
272                 else
273                 {
274                         printk(KERN_INFO "Warning: %s() Double Completing \n",__func__);
275                         UNLOCK_URBD_LIST(_urbd->epqh);
276                 }
277                 
278                 local_irq_restore (flags);
279         }
280 #else
281         static void ifxhcd_complete_urb_func(unsigned long data)
282         {
283                 unsigned long             flags;
284                 ifxhcd_urbd_t *urbd;
285
286                 urbd=((ifxhcd_urbd_t *)data);
287
288         //      local_irq_save(flags);
289                 if (!urbd)
290                         IFX_ERROR("%s: invalid urbd\n",__func__);
291                 else if (!urbd->epqh)
292                         IFX_ERROR("%s: invalid epqd\n",__func__);
293                 else
294                 {
295                         local_irq_save(flags);
296                         LOCK_URBD_LIST(urbd->epqh);
297                         ifxhcd_complete_urb_sub(urbd);
298                         UNLOCK_URBD_LIST(urbd->epqh);
299                         local_irq_restore (flags);
300                 }
301         //      local_irq_restore (flags);
302         }
303
304
305         /*!
306          \brief Sets the final status of an URB and returns it to the device driver. Any
307           required cleanup of the URB is performed.
308          */
309         void ifxhcd_complete_urb(ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd,  int _status)
310         {
311                 unsigned long             flags;
312
313                 if(!_urbd)
314                 {
315                         IFX_ERROR("%s: invalid urbd\n",__func__);
316                         return;
317                 }
318                 if (!_urbd->epqh)
319                 {
320                         IFX_ERROR("%s: invalid epqh\n",__func__);
321                         return;
322                 }
323
324                 local_irq_save(flags);
325                 LOCK_URBD_LIST(_urbd->epqh);
326                 #ifdef __DEBUG__
327                         if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
328                         {
329                                 IFX_PRINT("%s: ehqh %p _urbd %p, urb %p, device %d, ep %d %s/%s, status=%d\n",
330                                           __func__,_urbd->epqh, _urbd,_urbd->urb,
331                                           (_urbd->urb)?usb_pipedevice(_urbd->urb->pipe):-1,
332                                           (_urbd->urb)?usb_pipeendpoint(_urbd->urb->pipe):-1,
333                                           (_urbd->urb)?(usb_pipein(_urbd->urb->pipe) ? "IN" : "OUT"):"--",
334                                           (_urbd->is_in) ? "IN" : "OUT",
335                                            _status);
336                                 if ((_urbd->urb)&& _urbd->epqh->ep_type == IFXUSB_EP_TYPE_ISOC)
337                                 {
338                                         int i;
339                                         for (i = 0; i < _urbd->urb->number_of_packets; i++)
340                                                 IFX_PRINT("  ISO Desc %d status: %d\n", i, _urbd->urb->iso_frame_desc[i].status);
341                                 }
342                         }
343                 #endif
344                 _urbd->status = _status;
345
346                 if(_urbd->phase!=URBD_FINISHING)
347                 {
348                         if(_urbd->phase!=URBD_DEQUEUEING && _urbd->phase!=URBD_COMPLETING)
349                                 printk(KERN_INFO "Warning: %s() Strange URBD PHASE %d\n",__func__,_urbd->phase);
350                         if(_urbd->urb)
351                         {
352                                 if(   _urbd->status == 0
353                                    && _urbd->phase==URBD_COMPLETING
354                                    && in_irq())
355                                 {
356                                         if(_urbd->complete_urb_sub.func)
357                                                 printk(KERN_INFO "Warning: %s() URBD Tasklet is on already\n",__func__);
358                                         _urbd->phase=URBD_FINISHING;
359                                         _urbd->complete_urb_sub.next = NULL;
360                                         _urbd->complete_urb_sub.state = 0;
361                                         atomic_set( &_urbd->complete_urb_sub.count, 0);
362                                         _urbd->complete_urb_sub.func = ifxhcd_complete_urb_func;
363                                         _urbd->complete_urb_sub.data = (unsigned long)_urbd;
364                                         tasklet_schedule(&_urbd->complete_urb_sub);
365                                 }
366                                 else
367                                 {
368                                         _urbd->phase=URBD_FINISHING;
369                                         ifxhcd_complete_urb_sub(_urbd);
370                                 }
371                         }
372                         else
373                                 kfree(_urbd);
374                 }
375                 else
376                         printk(KERN_INFO "Warning: %s() Double Completing \n",__func__);
377                 UNLOCK_URBD_LIST(_urbd->epqh);
378                 local_irq_restore (flags);
379         }
380 #endif
381
382 /*!
383  \brief Processes all the URBs in a single EPQHs. Completes them with
384         status and frees the URBD.
385  */
386 static
387 void kill_all_urbs_in_epqh(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh, int _status)
388 {
389         struct list_head *item;
390         struct list_head *next;
391         ifxhcd_urbd_t    *urbd;
392
393         if(!_epqh)
394                 return;
395
396         IFX_DEBUGPL(DBG_HCDV, "%s %p\n",__func__,_epqh);
397         LOCK_URBD_LIST(_epqh);
398         list_for_each(item, &_epqh->urbd_list)
399         {
400                 urbd = list_entry(item, ifxhcd_urbd_t, ql);
401                 if(   urbd->phase==URBD_IDLE
402                    || urbd->phase==URBD_ACTIVE
403 //                 || urbd->phase==URBD_STARTING
404                   )
405                         urbd->phase=URBD_DEQUEUEING;
406         }
407         list_for_each_safe(item, next, &_epqh->urbd_list)
408         {
409                 urbd = list_entry(item, ifxhcd_urbd_t, ql);
410                 if(urbd->phase==URBD_DEQUEUEING)
411                 {
412                         urbd->urb->status = _status;
413                         urbd->phase = URBD_FINISHING;
414                         ifxhcd_complete_urb_sub(urbd);
415                 }
416                 else if(   urbd->phase==URBD_STARTED
417                         || urbd->phase==URBD_STARTING
418 //                      || urbd->phase==URBD_ACTIVE
419                        )
420                 {
421                         if(ifxhcd_hc_halt(&_ifxhcd->core_if, _epqh->hc, HC_XFER_URB_DEQUEUE))
422                         {
423                                 urbd->urb->status = _status;
424                                 urbd->phase=URBD_FINISHING;
425                                 ifxhcd_complete_urb_sub(urbd);
426                         }
427                 }
428                 else
429                         IFX_ERROR("%s: invalid urb phase:%d \n",__func__,urbd->phase);
430         }
431         UNLOCK_URBD_LIST(_epqh);
432         IFX_DEBUGPL(DBG_HCDV, "%s %p finish\n",__func__,_epqh);
433 }
434
435
436 /*!
437  \brief Free all EPS in one Processes all the URBs in a single list of EPQHs. Completes them with
438         -ETIMEDOUT and frees the URBD.
439  */
440 static
441 void epqh_list_free_1(ifxhcd_hcd_t *_ifxhcd, struct list_head *_epqh_list)
442 {
443         ifxhcd_epqh_t    *epqh;
444         struct list_head *item;
445         if (!_ifxhcd)
446                 return;
447         if (!_epqh_list)
448                 return;
449
450         IFX_DEBUGPL(DBG_HCDV, "%s %p\n",__func__,_epqh_list);
451
452         item = _epqh_list->next;
453         while(item != _epqh_list && item != item->next)
454         {
455                 epqh = list_entry(item, ifxhcd_epqh_t, ql);
456                 epqh->phase=EPQH_DISABLING;
457                 item = item->next;
458                 kill_all_urbs_in_epqh(_ifxhcd, epqh, -ETIMEDOUT);
459                 #ifdef __STRICT_ORDER__
460                 if(list_empty(&epqh->urbd_list) && list_empty(&epqh->release_list))
461                 #else
462                 if(list_empty(&epqh->urbd_list))
463                 #endif
464                         ifxhcd_epqh_free(epqh);
465         }
466         IFX_DEBUGPL(DBG_HCDV, "%s %p finish\n",__func__,_epqh_list);
467         /* Ensure there are no URBDs or URBs left. */
468 }
469
470 static
471 void epqh_list_free_2(ifxhcd_hcd_t *_ifxhcd, struct list_head *_epqh_list)
472 {
473         ifxhcd_epqh_t    *epqh;
474         struct list_head *item;
475         struct list_head *next;
476         if (!_ifxhcd)
477                 return;
478         if (!_epqh_list)
479                 return;
480
481         IFX_DEBUGPL(DBG_HCDV, "%s %p\n",__func__,_epqh_list);
482         list_for_each_safe(item, next, _epqh_list)
483         {
484                 epqh = list_entry(item, ifxhcd_epqh_t, ql);
485                 if(item == item->next)
486                 {
487                         ifxhcd_epqh_free(epqh);
488                 }
489                 else
490                 {
491                         uint32_t count=0x80000;
492                         #ifdef __STRICT_ORDER__
493                         for(;(!list_empty(&epqh->urbd_list) || !list_empty(&epqh->release_list))&& count> 0; count--) udelay(1);
494                         #else
495                         for(;!list_empty(&epqh->urbd_list) && count> 0; count--) udelay(1);
496                         #endif
497                         if(!count)
498                                 IFX_ERROR("%s: unable to clear urbd in epqh \n",__func__);
499                         ifxhcd_epqh_free(epqh);
500                 }
501         }
502         IFX_DEBUGPL(DBG_HCDV, "%s %p finish\n",__func__,_epqh_list);
503         /* Ensure there are no URBDs or URBs left. */
504 }
505
506 static
507 void epqh_list_free_all_sub(unsigned long data)
508 {
509         ifxhcd_hcd_t *ifxhcd;
510
511         ifxhcd=(ifxhcd_hcd_t *)data;
512         epqh_list_free_1(ifxhcd, &ifxhcd->epqh_list_np  );
513         epqh_list_free_1(ifxhcd, &ifxhcd->epqh_list_intr);
514         #ifdef __EN_ISOC__
515                 epqh_list_free_1(ifxhcd, &ifxhcd->epqh_list_isoc);
516         #endif
517
518         epqh_list_free_2(ifxhcd, &ifxhcd->epqh_list_np  );
519         epqh_list_free_2(ifxhcd, &ifxhcd->epqh_list_intr);
520         #ifdef __EN_ISOC__
521                 epqh_list_free_2(ifxhcd, &ifxhcd->epqh_list_isoc);
522         #endif
523 }
524
525 static
526 void epqh_list_free_all(ifxhcd_hcd_t *_ifxhcd)
527 {
528         _ifxhcd->tasklet_free_epqh_list.next = NULL;
529         _ifxhcd->tasklet_free_epqh_list.state = 0;
530         atomic_set( &_ifxhcd->tasklet_free_epqh_list.count, 0);
531         _ifxhcd->tasklet_free_epqh_list.func=epqh_list_free_all_sub;
532         _ifxhcd->tasklet_free_epqh_list.data = (unsigned long)_ifxhcd;
533         tasklet_schedule(&_ifxhcd->tasklet_free_epqh_list);
534 }
535
536
537 /*!
538    \brief This function is called to handle the disconnection of host port.
539  */
540 int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd)
541 {
542         IFX_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _ifxhcd);
543
544         _ifxhcd->disconnecting=1;
545         /* Set status flags for the hub driver. */
546         _ifxhcd->flags.b.port_connect_status_change = 1;
547         _ifxhcd->flags.b.port_connect_status = 0;
548
549         /*
550          * Shutdown any transfers in process by clearing the Tx FIFO Empty
551          * interrupt mask and status bits and disabling subsequent host
552          * channel interrupts.
553          */
554          {
555                 gint_data_t intr = { .d32 = 0 };
556                 intr.b.nptxfempty = 1;
557                 intr.b.ptxfempty  = 1;
558                 intr.b.hcintr     = 1;
559                 ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintmsk, intr.d32, 0);
560                 ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gintsts, intr.d32, 0);
561         }
562
563         /* Respond with an error status to all URBs in the schedule. */
564         epqh_list_free_all(_ifxhcd);
565
566         /* Clean up any host channels that were in use. */
567         {
568                 int               num_channels;
569                 ifxhcd_hc_t      *channel;
570                 ifxusb_hc_regs_t *hc_regs;
571                 hcchar_data_t     hcchar;
572                 int                   i;
573
574                 num_channels = _ifxhcd->core_if.params.host_channels;
575
576                 for (i = 0; i < num_channels; i++)
577                 {
578                         channel = &_ifxhcd->ifxhc[i];
579                         hc_regs = _ifxhcd->core_if.hc_regs[i];
580                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
581                         if (hcchar.b.chen)
582                                 printk(KERN_INFO "Warning: %s() HC still enabled\n",__func__);
583                         ifxhcd_hc_cleanup(&_ifxhcd->core_if, channel);
584                 }
585         }
586         IFX_DEBUGPL(DBG_HCDV, "%s(%p) finish\n", __func__, _ifxhcd);
587         return 1;
588 }
589
590
591 /*!
592    \brief Frees secondary storage associated with the ifxhcd_hcd structure contained
593           in the struct usb_hcd field.
594  */
595 static void ifxhcd_freeextra(struct usb_hcd *_syshcd)
596 {
597         ifxhcd_hcd_t    *ifxhcd = syshcd_to_ifxhcd(_syshcd);
598
599         IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD FREE\n");
600
601         /* Free memory for EPQH/URBD lists */
602         epqh_list_free_all(ifxhcd);
603
604         /* Free memory for the host channels. */
605         ifxusb_free_buf_h(ifxhcd->status_buf);
606         return;
607 }
608
609 /*!
610    \brief Initializes the HCD. This function allocates memory for and initializes the
611   static parts of the usb_hcd and ifxhcd_hcd structures. It also registers the
612   USB bus with the core and calls the hc_driver->start() function. It returns
613   a negative error on failure.
614  */
615 int ifxhcd_init(ifxhcd_hcd_t *_ifxhcd)
616 {
617         int retval = 0;
618         struct usb_hcd *syshcd = NULL;
619
620         IFX_DEBUGPL(DBG_HCD, "IFX USB HCD INIT\n");
621
622         INIT_EPQH_LIST_ALL(_ifxhcd);
623         INIT_EPQH_LIST(_ifxhcd);
624
625         init_timer(&_ifxhcd->autoprobe_timer);
626         init_timer(&_ifxhcd->host_probe_timer);
627         _ifxhcd->probe_sec = 5;
628         _ifxhcd->autoprobe_sec = 30;
629
630         _ifxhcd->hc_driver.description      = _ifxhcd->core_if.core_name;
631         _ifxhcd->hc_driver.product_desc     = "IFX USB Controller";
632         //_ifxhcd->hc_driver.hcd_priv_size    = sizeof(ifxhcd_hcd_t);
633         _ifxhcd->hc_driver.hcd_priv_size    = sizeof(unsigned long);
634         _ifxhcd->hc_driver.irq              = ifxhcd_irq;
635         _ifxhcd->hc_driver.flags            = HCD_MEMORY | HCD_USB2;
636         _ifxhcd->hc_driver.start            = ifxhcd_start;
637         _ifxhcd->hc_driver.stop             = ifxhcd_stop;
638         //_ifxhcd->hc_driver.reset          =
639         //_ifxhcd->hc_driver.suspend        =
640         //_ifxhcd->hc_driver.resume         =
641         _ifxhcd->hc_driver.urb_enqueue      = ifxhcd_urb_enqueue;
642         _ifxhcd->hc_driver.urb_dequeue      = ifxhcd_urb_dequeue;
643         _ifxhcd->hc_driver.endpoint_disable = ifxhcd_endpoint_disable;
644         _ifxhcd->hc_driver.get_frame_number = ifxhcd_get_frame_number;
645         _ifxhcd->hc_driver.hub_status_data  = ifxhcd_hub_status_data;
646         _ifxhcd->hc_driver.hub_control      = ifxhcd_hub_control;
647         //_ifxhcd->hc_driver.hub_suspend    =
648         //_ifxhcd->hc_driver.hub_resume     =
649         _ifxhcd->pkt_remaining_reload_hs=PKT_REMAINING_RELOAD_HS;
650         _ifxhcd->pkt_remaining_reload_fs=PKT_REMAINING_RELOAD_FS;
651         _ifxhcd->pkt_remaining_reload_ls=PKT_REMAINING_RELOAD_LS;
652         _ifxhcd->pkt_count_limit_bo         =8;
653         _ifxhcd->pkt_count_limit_bi         =8;
654
655         /* Allocate memory for and initialize the base HCD and  */
656         //syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->dev->bus_id);
657         syshcd = usb_create_hcd(&_ifxhcd->hc_driver, _ifxhcd->dev, _ifxhcd->core_if.core_name);
658
659         if (syshcd == NULL)
660         {
661                 retval = -ENOMEM;
662                 goto error1;
663         }
664
665         syshcd->rsrc_start = (unsigned long)_ifxhcd->core_if.core_global_regs;
666         syshcd->regs       = (void *)_ifxhcd->core_if.core_global_regs;
667         syshcd->self.otg_port = 0;
668
669         //*((unsigned long *)(&(syshcd->hcd_priv)))=(unsigned long)_ifxhcd;
670         //*((unsigned long *)(&(syshcd->hcd_priv[0])))=(unsigned long)_ifxhcd;
671         syshcd->hcd_priv[0]=(unsigned long)_ifxhcd;
672         _ifxhcd->syshcd=syshcd;
673         INIT_LIST_HEAD(&_ifxhcd->epqh_list_all   );
674         INIT_LIST_HEAD(&_ifxhcd->epqh_list_np    );
675         INIT_LIST_HEAD(&_ifxhcd->epqh_list_intr  );
676         #ifdef __EN_ISOC__
677                 INIT_LIST_HEAD(&_ifxhcd->epqh_list_isoc);
678         #endif
679
680         /*
681          * Create a host channel descriptor for each host channel implemented
682          * in the controller. Initialize the channel descriptor array.
683          */
684         {
685                 int          num_channels = _ifxhcd->core_if.params.host_channels;
686                 int i;
687                 for (i = 0; i < num_channels; i++)
688                 {
689                         _ifxhcd->ifxhc[i].hc_num = i;
690                         IFX_DEBUGPL(DBG_HCDV, "HCD Added channel #%d\n", i);
691                 }
692         }
693
694         /* Set device flags indicating whether the HCD supports DMA. */
695         if(_ifxhcd->dev->dma_mask)
696                 *(_ifxhcd->dev->dma_mask) = ~0;
697         _ifxhcd->dev->coherent_dma_mask = ~0;
698
699         /*
700          * Finish generic HCD initialization and start the HCD. This function
701          * allocates the DMA buffer pool, registers the USB bus, requests the
702          * IRQ line, and calls ifxusb_hcd_start method.
703          */
704         retval = usb_add_hcd(syshcd, _ifxhcd->core_if.irq, 0
705                                                            |IRQF_DISABLED
706                                                            |IRQF_SHARED
707                                                            );
708         if (retval < 0)
709                 goto error2;
710
711         /*
712          * Allocate space for storing data on status transactions. Normally no
713          * data is sent, but this space acts as a bit bucket. This must be
714          * done after usb_add_hcd since that function allocates the DMA buffer
715          * pool.
716          */
717         _ifxhcd->status_buf = ifxusb_alloc_buf_h(IFXHCD_STATUS_BUF_SIZE, 1);
718
719         if (_ifxhcd->status_buf)
720         {
721                 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->core_if.core_name, syshcd->self.busnum);
722                 return 0;
723         }
724         IFX_ERROR("%s: status_buf allocation failed\n", __func__);
725
726         /* Error conditions */
727         usb_remove_hcd(syshcd);
728 error2:
729         ifxhcd_freeextra(syshcd);
730         usb_put_hcd(syshcd);
731 error1:
732         return retval;
733 }
734
735 /*!
736    \brief Removes the HCD.
737   Frees memory and resources associated with the HCD and deregisters the bus.
738  */
739 void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd)
740 {
741         struct usb_hcd *syshcd = ifxhcd_to_syshcd(_ifxhcd);
742
743         IFX_DEBUGPL(DBG_HCD, "IFX USB HCD REMOVE\n");
744
745         /* Turn off all interrupts */
746         ifxusb_wreg (&_ifxhcd->core_if.core_global_regs->gintmsk, 0);
747         ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gahbcfg, 1, 0);
748
749         usb_remove_hcd(syshcd);
750         ifxhcd_freeextra(syshcd);
751         usb_put_hcd(syshcd);
752
753         return;
754 }
755
756
757 /* =========================================================================
758  *  Linux HC Driver Functions
759  * ========================================================================= */
760
761 /*!
762    \brief Initializes the IFXUSB controller and its root hub and prepares it for host
763  mode operation. Activates the root port. Returns 0 on success and a negative
764  error code on failure.
765  Called by USB stack.
766  */
767 int ifxhcd_start(struct usb_hcd *_syshcd)
768 {
769         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
770         ifxusb_core_if_t *core_if = &ifxhcd->core_if;
771         struct usb_bus *bus;
772
773         IFX_DEBUGPL(DBG_HCD, "IFX USB HCD START\n");
774
775         bus = hcd_to_bus(_syshcd);
776
777         /* Initialize the bus state.  */
778         _syshcd->state = HC_STATE_RUNNING;
779
780         /* Initialize and connect root hub if one is not already attached */
781         if (bus->root_hub)
782         {
783                 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Has Root Hub\n");
784                 /* Inform the HUB driver to resume. */
785                 usb_hcd_resume_root_hub(_syshcd);
786         }
787
788         ifxhcd->flags.d32 = 0;
789
790         /* Put all channels in the free channel list and clean up channel states.*/
791         {
792                 int num_channels = ifxhcd->core_if.params.host_channels;
793                 int i;
794                 for (i = 0; i < num_channels; i++)
795                 {
796                         ifxhcd_hc_t      *channel;
797                         channel = &ifxhcd->ifxhc[i];
798                         ifxhcd_hc_cleanup(&ifxhcd->core_if, channel);
799                 }
800         }
801         /* Initialize the USB core for host mode operation. */
802
803         ifxusb_host_enable_interrupts(core_if);
804         ifxusb_enable_global_interrupts_h(core_if);
805         ifxusb_phy_power_on_h (core_if);
806
807         ifxusb_vbus_init(core_if);
808
809         /* Turn on the vbus power. */
810         {
811                 hprt0_data_t hprt0;
812                 hprt0.d32 = ifxusb_read_hprt0(core_if);
813
814                 IFX_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
815                 if (hprt0.b.prtpwr == 0 )
816                 {
817                         hprt0.b.prtpwr = 1;
818                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
819                         ifxusb_vbus_on(core_if);
820                 }
821         }
822         return 0;
823 }
824
825 /*!
826    \brief Halts the IFXUSB  host mode operations in a clean manner. USB transfers are
827  stopped.
828  */
829         #if defined(__IS_AR10__)
830 void            ifxusb_oc_int_free(int port);
831         #else
832 void            ifxusb_oc_int_free(void);
833         #endif
834  
835 void ifxhcd_stop(struct usb_hcd *_syshcd)
836 {
837         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
838         hprt0_data_t  hprt0 = { .d32=0 };
839
840         IFX_DEBUGPL(DBG_HCD, "IFX USB HCD STOP\n");
841
842         /* Turn off all interrupts. */
843         ifxusb_disable_global_interrupts_h(&ifxhcd->core_if );
844         ifxusb_host_disable_interrupts(&ifxhcd->core_if );
845
846         /*
847          * The root hub should be disconnected before this function is called.
848          * The disconnect will clear the URBD lists (via ..._hcd_urb_dequeue)
849          * and the EPQH lists (via ..._hcd_endpoint_disable).
850          */
851
852         /* Turn off the vbus power */
853         IFX_PRINT("PortPower off\n");
854
855         ifxusb_vbus_off(&ifxhcd->core_if );
856         
857         
858         #if defined(__IS_AR10__)
859                 ifxusb_oc_int_free(ifxhcd->core_if.core_no);
860         #else
861                 ifxusb_oc_int_free();
862         #endif
863         
864
865         ifxusb_vbus_free(&ifxhcd->core_if );
866         hprt0.b.prtpwr = 0;
867         ifxusb_wreg(ifxhcd->core_if.hprt0, hprt0.d32);
868         return;
869 }
870
871 /*!
872    \brief Returns the current frame number
873  */
874 int ifxhcd_get_frame_number(struct usb_hcd *_syshcd)
875 {
876         ifxhcd_hcd_t    *ifxhcd = syshcd_to_ifxhcd(_syshcd);
877         hfnum_data_t hfnum;
878
879         hfnum.d32 = ifxusb_rreg(&ifxhcd->core_if.host_global_regs->hfnum);
880
881         return hfnum.b.frnum;
882 }
883
884 /*!
885    \brief Starts processing a USB transfer request specified by a USB Request Block
886   (URB). mem_flags indicates the type of memory allocation to use while
887   processing this URB.
888  */
889 int ifxhcd_urb_enqueue( struct usb_hcd           *_syshcd,
890 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
891                         struct usb_host_endpoint *_sysep,
892 #endif
893                         struct urb               *_urb,
894                         gfp_t                     _mem_flags)
895 {
896         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
897         ifxhcd_epqh_t *epqh = NULL;
898
899         #ifdef __DEBUG__
900                 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
901                         dump_urb_info(_urb, "ifxusb_hcd_urb_enqueue");
902         #endif //__DEBUG__
903
904         if (!ifxhcd->flags.b.port_connect_status)  /* No longer connected. */
905                 return -ENODEV;
906
907         #if !defined(__EN_ISOC__)
908                 if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
909                 {
910                         IFX_ERROR("ISOC transfer not supported!!!\n");
911                         return -ENODEV;
912                 }
913         #endif
914
915         if(_urb->hcpriv)
916         {
917                 IFX_WARN("%s() Previous urb->hcpriv exist %p\n",__func__,_urb->hcpriv);
918         #if 1
919                 return -ENOSPC;
920         #endif
921         }
922
923         epqh=ifxhcd_urbd_create (ifxhcd,_urb);
924         if (!epqh)
925         {
926                 IFX_ERROR("IFXUSB HCD URB Enqueue failed creating URBD\n");
927                 return -ENOSPC;
928         }
929         if(epqh->phase==EPQH_DISABLING )
930         {
931                 IFX_ERROR("Enqueue to a DISABLING EP!!!\n");
932                 return -ENODEV;
933         }
934
935         #ifdef __DYN_SOF_INTR__
936                 ifxhcd->dyn_sof_count = DYN_SOF_COUNT_DEF;
937         #endif
938         //enable_sof(ifxhcd);
939         {
940                 gint_data_t gintsts;
941                 gintsts.d32=0;
942                 gintsts.b.sofintr = 1;
943                 ifxusb_mreg(&ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32);
944         }
945
946         if(epqh->phase==EPQH_IDLE || epqh->phase==EPQH_STDBY )
947         {
948                 epqh->phase=EPQH_READY;
949                 #ifdef __EPQD_DESTROY_TIMEOUT__
950                         del_timer(&epqh->destroy_timer);
951                 #endif
952         }
953         select_eps(ifxhcd);
954         return 0;
955 }
956
957 /*!
958    \brief Aborts/cancels a USB transfer request. Always returns 0 to indicate
959   success.
960  */
961 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
962 int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb)
963 #else
964 int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb, int status)
965 #endif
966 {
967         ifxhcd_hcd_t  *ifxhcd;
968         struct usb_host_endpoint *sysep;
969         ifxhcd_urbd_t *urbd;
970         ifxhcd_epqh_t *epqh;
971
972         IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD URB Dequeue\n");
973         #if !defined(__EN_ISOC__)
974                 if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
975                         return 0;
976         #endif
977
978         ifxhcd = syshcd_to_ifxhcd(_syshcd);
979
980         urbd = (ifxhcd_urbd_t *) _urb->hcpriv;
981         if(!urbd)
982         {
983                 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
984                         _urb->status=-ETIMEDOUT;
985                         usb_hcd_giveback_urb(_syshcd, _urb);
986                 #else
987 //                      usb_hcd_giveback_urb(_syshcd, _urb,-ETIMEDOUT);
988                         usb_hcd_giveback_urb(_syshcd, _urb,status);
989                 #endif
990                 return 0;
991         }
992
993         sysep = ifxhcd_urb_to_endpoint(_urb);
994         if(sysep)
995         {
996                 LOCK_EPQH_LIST_ALL(ifxhcd);
997                 epqh = sysep_to_epqh(ifxhcd,sysep);
998                 UNLOCK_EPQH_LIST_ALL(ifxhcd);
999                 if(epqh!=urbd->epqh)
1000                         IFX_ERROR("%s inconsistant epqh %p %p\n",__func__,epqh,urbd->epqh);
1001         }
1002         else
1003                 epqh = (ifxhcd_epqh_t *) urbd->epqh;
1004         if(!ifxhcd->flags.b.port_connect_status || !epqh)
1005         {
1006                 urbd->phase=URBD_DEQUEUEING;
1007                 ifxhcd_complete_urb(ifxhcd, urbd, -ENODEV);
1008         }
1009         else
1010         {
1011                 LOCK_URBD_LIST(epqh);
1012                 if(   urbd->phase==URBD_IDLE
1013                    || urbd->phase==URBD_ACTIVE
1014 //                 || urbd->phase==URBD_STARTING
1015                    )
1016                 {
1017                         urbd->phase=URBD_DEQUEUEING;
1018                         #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
1019                                 ifxhcd_complete_urb(ifxhcd, urbd, -ETIMEDOUT);
1020                         #else
1021                                 ifxhcd_complete_urb(ifxhcd, urbd, status);
1022                         #endif
1023                 }
1024                 else if(   urbd->phase==URBD_STARTED
1025                         || urbd->phase==URBD_STARTING
1026 //                      || urbd->phase==URBD_ACTIVE
1027                        )
1028                 {
1029                         if(ifxhcd_hc_halt(&ifxhcd->core_if, epqh->hc, HC_XFER_URB_DEQUEUE))
1030                         {
1031                                 urbd->phase=URBD_DEQUEUEING;
1032                                 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
1033                                         ifxhcd_complete_urb(ifxhcd, urbd, -ETIMEDOUT);
1034                                 #else
1035                                         ifxhcd_complete_urb(ifxhcd, urbd, status);
1036                                 #endif
1037                                 ifxhcd_epqh_idle(epqh);
1038                         }
1039                 }
1040                 UNLOCK_URBD_LIST(epqh);
1041         }
1042         return 0;
1043 }
1044
1045
1046 /*!
1047    \brief Frees resources in the IFXUSB controller related to a given endpoint. Also
1048   clears state in the HCD related to the endpoint. Any URBs for the endpoint
1049   must already be dequeued.
1050  */
1051 void ifxhcd_endpoint_disable( struct usb_hcd *_syshcd,
1052                               struct usb_host_endpoint *_sysep)
1053 {
1054         ifxhcd_hcd_t  *ifxhcd;
1055         ifxhcd_epqh_t *epqh;
1056
1057         IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD EP DISABLE: _bEndpointAddress=0x%02x, "
1058             "endpoint=%d\n", _sysep->desc.bEndpointAddress,
1059                     ifxhcd_ep_addr_to_endpoint(_sysep->desc.bEndpointAddress));
1060
1061         ifxhcd = syshcd_to_ifxhcd(_syshcd);
1062
1063         LOCK_EPQH_LIST_ALL(ifxhcd);
1064         epqh = sysep_to_epqh(ifxhcd,_sysep);
1065         UNLOCK_EPQH_LIST_ALL(ifxhcd);
1066
1067         if (!epqh)
1068         {
1069                 return;
1070         }
1071         else
1072         {
1073                 if (epqh->sysep!=_sysep)
1074                 {
1075                         IFX_ERROR("%s inconsistant sysep %p %p %p\n",__func__,epqh,epqh->sysep,_sysep);
1076                         return;
1077                 }
1078
1079                 epqh->phase=EPQH_DISABLING;
1080                 kill_all_urbs_in_epqh(ifxhcd, epqh, -ETIMEDOUT);
1081                 {
1082                         uint32_t count=0x80000;
1083                         for(;!list_empty(&epqh->urbd_list) && count> 0; count--) udelay(1);
1084                         if(!count)
1085                                 IFX_ERROR("%s: unable to clear urbd in epqh \n",__func__);
1086                 }
1087                 ifxhcd_epqh_free(epqh);
1088         }
1089         IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD EP DISABLE: done\n");
1090 }
1091
1092
1093 /*!
1094   \brief Handles host mode interrupts for the IFXUSB controller. Returns IRQ_NONE if
1095  there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
1096  interrupt.
1097
1098  This function is called by the USB core when an interrupt occurs
1099  */
1100 irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd)
1101 {
1102         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
1103         int32_t retval=0;
1104
1105         //mask_and_ack_ifx_irq (ifxhcd->core_if.irq);
1106         retval = ifxhcd_handle_intr(ifxhcd);
1107         return IRQ_RETVAL(retval);
1108 }
1109
1110
1111
1112 /*!
1113  \brief Creates Status Change bitmap for the root hub and root port. The bitmap is
1114   returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
1115   is the status change indicator for the single root port. Returns 1 if either
1116   change indicator is 1, otherwise returns 0.
1117  */
1118 int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf)
1119 {
1120         ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
1121
1122         _buf[0] = 0;
1123         _buf[0] |= (ifxhcd->flags.b.port_connect_status_change ||
1124                     ifxhcd->flags.b.port_reset_change ||
1125                     ifxhcd->flags.b.port_enable_change ||
1126                     ifxhcd->flags.b.port_suspend_change ||
1127                     ifxhcd->flags.b.port_over_current_change) << 1;
1128
1129         #ifdef __DEBUG__
1130                 if (_buf[0])
1131                 {
1132                         IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD HUB STATUS DATA:"
1133                                     " Root port status changed\n");
1134                         IFX_DEBUGPL(DBG_HCDV, "  port_connect_status_change: %d\n",
1135                                     ifxhcd->flags.b.port_connect_status_change);
1136                         IFX_DEBUGPL(DBG_HCDV, "  port_reset_change: %d\n",
1137                                     ifxhcd->flags.b.port_reset_change);
1138                         IFX_DEBUGPL(DBG_HCDV, "  port_enable_change: %d\n",
1139                                     ifxhcd->flags.b.port_enable_change);
1140                         IFX_DEBUGPL(DBG_HCDV, "  port_suspend_change: %d\n",
1141                                     ifxhcd->flags.b.port_suspend_change);
1142                         IFX_DEBUGPL(DBG_HCDV, "  port_over_current_change: %d\n",
1143                                     ifxhcd->flags.b.port_over_current_change);
1144                         {
1145                                 hprt0_data_t hprt0;
1146                                 hprt0.d32 = ifxusb_rreg(ifxhcd->core_if.hprt0);
1147                                 IFX_DEBUGPL(DBG_HCDV, "  port reg :%08X\n",hprt0.d32);
1148                                 IFX_DEBUGPL(DBG_HCDV, "  port reg :connect: %d/%d\n",hprt0.b.prtconnsts,hprt0.b.prtconndet);
1149                                 IFX_DEBUGPL(DBG_HCDV, "  port reg :enable: %d/%d\n",hprt0.b.prtena,hprt0.b.prtenchng);
1150                                 IFX_DEBUGPL(DBG_HCDV, "  port reg :OC: %d/%d\n",hprt0.b.prtovrcurract,hprt0.b.prtovrcurrchng);
1151                                 IFX_DEBUGPL(DBG_HCDV, "  port reg :rsume/suspend/reset: %d/%d/%d\n",hprt0.b.prtres,hprt0.b.prtsusp,hprt0.b.prtrst);
1152                                 IFX_DEBUGPL(DBG_HCDV, "  port reg :port power: %d/\n",hprt0.b.prtpwr);
1153                                 IFX_DEBUGPL(DBG_HCDV, "  port reg :speed: %d/\n",hprt0.b.prtspd);
1154                         }
1155                 }
1156         #endif //__DEBUG__
1157         return (_buf[0] != 0);
1158 }
1159
1160 #ifdef __WITH_HS_ELECT_TST__
1161         extern void do_setup(ifxusb_core_if_t *_core_if) ;
1162         extern void do_in_ack(ifxusb_core_if_t *_core_if);
1163 #endif //__WITH_HS_ELECT_TST__
1164
1165 /*!
1166  \brief Handles hub class-specific requests.
1167  */
1168 int ifxhcd_hub_control( struct usb_hcd *_syshcd,
1169                         u16             _typeReq,
1170                         u16             _wValue,
1171                         u16             _wIndex,
1172                         char           *_buf,
1173                         u16             _wLength)
1174 {
1175         int retval = 0;
1176         ifxhcd_hcd_t              *ifxhcd  = syshcd_to_ifxhcd (_syshcd);
1177         ifxusb_core_if_t          *core_if = &ifxhcd->core_if;
1178         struct usb_hub_descriptor *desc;
1179         hprt0_data_t               hprt0 = {.d32 = 0};
1180
1181         uint32_t port_status;
1182
1183         switch (_typeReq)
1184         {
1185                 case ClearHubFeature:
1186                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1187                                  "ClearHubFeature 0x%x\n", _wValue);
1188                         switch (_wValue)
1189                         {
1190                                 case C_HUB_LOCAL_POWER:
1191                                 case C_HUB_OVER_CURRENT:
1192                                         /* Nothing required here */
1193                                         break;
1194                                 default:
1195                                         retval = -EINVAL;
1196                                         IFX_ERROR ("IFXUSB HCD - "
1197                                                    "ClearHubFeature request %xh unknown\n", _wValue);
1198                         }
1199                         break;
1200                 case ClearPortFeature:
1201                         if (!_wIndex || _wIndex > 1)
1202                                 goto error;
1203
1204                         switch (_wValue)
1205                         {
1206                                 case USB_PORT_FEAT_ENABLE:
1207                                         IFX_DEBUGPL (DBG_ANY, "IFXUSB HCD HUB CONTROL - "
1208                                                      "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
1209                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1210                                         hprt0.b.prtena = 1;
1211                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1212                                         break;
1213                                 case USB_PORT_FEAT_SUSPEND:
1214                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1215                                                      "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
1216                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1217                                         hprt0.b.prtres = 1;
1218                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1219                                         /* Clear Resume bit */
1220                                         mdelay (100);
1221                                         hprt0.b.prtres = 0;
1222                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1223                                         break;
1224                                 case USB_PORT_FEAT_POWER:
1225                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1226                                                      "ClearPortFeature USB_PORT_FEAT_POWER\n");
1227                                         #ifdef __IS_DUAL__
1228                                                 ifxusb_vbus_off(core_if);
1229                                         #else
1230                                                 ifxusb_vbus_off(core_if);
1231                                         #endif
1232                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1233                                         hprt0.b.prtpwr = 0;
1234                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1235                                         break;
1236                                 case USB_PORT_FEAT_INDICATOR:
1237                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1238                                                      "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
1239                                         /* Port inidicator not supported */
1240                                         break;
1241                                 case USB_PORT_FEAT_C_CONNECTION:
1242                                         /* Clears drivers internal connect status change
1243                                          * flag */
1244                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1245                                                      "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
1246                                         ifxhcd->flags.b.port_connect_status_change = 0;
1247                                         break;
1248                                 case USB_PORT_FEAT_C_RESET:
1249                                         /* Clears the driver's internal Port Reset Change
1250                                          * flag */
1251                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1252                                                      "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
1253                                         ifxhcd->flags.b.port_reset_change = 0;
1254                                         break;
1255                                 case USB_PORT_FEAT_C_ENABLE:
1256                                         /* Clears the driver's internal Port
1257                                          * Enable/Disable Change flag */
1258                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1259                                                      "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
1260                                         ifxhcd->flags.b.port_enable_change = 0;
1261                                         break;
1262                                 case USB_PORT_FEAT_C_SUSPEND:
1263                                         /* Clears the driver's internal Port Suspend
1264                                          * Change flag, which is set when resume signaling on
1265                                          * the host port is complete */
1266                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1267                                                      "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
1268                                         ifxhcd->flags.b.port_suspend_change = 0;
1269                                         break;
1270                                 case USB_PORT_FEAT_C_OVER_CURRENT:
1271                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1272                                                      "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
1273                                         ifxhcd->flags.b.port_over_current_change = 0;
1274                                         break;
1275                                 default:
1276                                         retval = -EINVAL;
1277                                         IFX_ERROR ("IFXUSB HCD - "
1278                                                  "ClearPortFeature request %xh "
1279                                                  "unknown or unsupported\n", _wValue);
1280                         }
1281                         break;
1282                 case GetHubDescriptor:
1283                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1284                                  "GetHubDescriptor\n");
1285                         desc = (struct usb_hub_descriptor *)_buf;
1286                         desc->bDescLength = 9;
1287                         desc->bDescriptorType = 0x29;
1288                         desc->bNbrPorts = 1;
1289                         desc->wHubCharacteristics = 0x08;
1290                         desc->bPwrOn2PwrGood = 1;
1291                         desc->bHubContrCurrent = 0;
1292
1293                         desc->u.hs.DeviceRemovable[0] = 0;
1294                         desc->u.hs.DeviceRemovable[1] = 1;
1295                         /*desc->bitmap[0] = 0;
1296                         desc->bitmap[1] = 0xff;*/
1297                         break;
1298                 case GetHubStatus:
1299                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1300                                  "GetHubStatus\n");
1301                         memset (_buf, 0, 4);
1302                         break;
1303                 case GetPortStatus:
1304                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1305                                  "GetPortStatus\n");
1306                         if (!_wIndex || _wIndex > 1)
1307                                 goto error;
1308                         port_status = 0;
1309                         if (ifxhcd->flags.b.port_connect_status_change)
1310                                 port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
1311                         if (ifxhcd->flags.b.port_enable_change)
1312                                 port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
1313                         if (ifxhcd->flags.b.port_suspend_change)
1314                                 port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
1315                         if (ifxhcd->flags.b.port_reset_change)
1316                                 port_status |= (1 << USB_PORT_FEAT_C_RESET);
1317                         if (ifxhcd->flags.b.port_over_current_change)
1318                         {
1319                                 IFX_ERROR("Device Not Supported\n");
1320                                 port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
1321                         }
1322                         if (!ifxhcd->flags.b.port_connect_status)
1323                         {
1324                                 /*
1325                                  * The port is disconnected, which means the core is
1326                                  * either in device mode or it soon will be. Just
1327                                  * return 0's for the remainder of the port status
1328                                  * since the port register can't be read if the core
1329                                  * is in device mode.
1330                                  */
1331                                 *((u32 *) _buf) = cpu_to_le32(port_status);
1332                                 break;
1333                         }
1334
1335                         hprt0.d32 = ifxusb_rreg(core_if->hprt0);
1336                         IFX_DEBUGPL(DBG_HCDV, "  HPRT0: 0x%08x\n", hprt0.d32);
1337                         if (hprt0.b.prtconnsts)
1338                                 port_status |= (1 << USB_PORT_FEAT_CONNECTION);
1339                         if (hprt0.b.prtena)
1340                         {
1341                                 ifxhcd->disconnecting=0;
1342                                 port_status |= (1 << USB_PORT_FEAT_ENABLE);
1343                         }
1344                         if (hprt0.b.prtsusp)
1345                                 port_status |= (1 << USB_PORT_FEAT_SUSPEND);
1346                         if (hprt0.b.prtovrcurract)
1347                                 port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
1348                         if (hprt0.b.prtrst)
1349                                 port_status |= (1 << USB_PORT_FEAT_RESET);
1350                         if (hprt0.b.prtpwr)
1351                                 port_status |= (1 << USB_PORT_FEAT_POWER);
1352 /*                      if      (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
1353                                 port_status |= (1 << USB_PORT_FEAT_HIGHSPEED);
1354                         else*/ if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
1355                                 port_status |= (1 << USB_PORT_FEAT_LOWSPEED);
1356                         if (hprt0.b.prttstctl)
1357                                 port_status |= (1 << USB_PORT_FEAT_TEST);
1358                         /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
1359                         *((u32 *) _buf) = cpu_to_le32(port_status);
1360                         break;
1361                 case SetHubFeature:
1362                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1363                                  "SetHubFeature\n");
1364                         /* No HUB features supported */
1365                         break;
1366                 case SetPortFeature:
1367                         if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
1368                                 goto error;
1369                         /*
1370                          * The port is disconnected, which means the core is
1371                          * either in device mode or it soon will be. Just
1372                          * return without doing anything since the port
1373                          * register can't be written if the core is in device
1374                          * mode.
1375                          */
1376                         if (!ifxhcd->flags.b.port_connect_status)
1377                                 break;
1378                         switch (_wValue)
1379                         {
1380                                 case USB_PORT_FEAT_SUSPEND:
1381                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1382                                                      "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
1383                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1384                                         hprt0.b.prtsusp = 1;
1385                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1386                                         //IFX_PRINT( "SUSPEND: HPRT0=%0x\n", hprt0.d32);
1387                                         /* Suspend the Phy Clock */
1388                                         {
1389                                                 pcgcctl_data_t pcgcctl = {.d32=0};
1390                                                 pcgcctl.b.stoppclk = 1;
1391                                                 ifxusb_wreg(core_if->pcgcctl, pcgcctl.d32);
1392                                         }
1393                                         break;
1394                                 case USB_PORT_FEAT_POWER:
1395                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1396                                              "SetPortFeature - USB_PORT_FEAT_POWER\n");
1397                                         ifxusb_vbus_on (core_if);
1398                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1399                                         hprt0.b.prtpwr = 1;
1400                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1401                                         break;
1402                                 case USB_PORT_FEAT_RESET:
1403                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1404                                                      "SetPortFeature - USB_PORT_FEAT_RESET\n");
1405                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1406                                         hprt0.b.prtrst = 1;
1407                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1408                                         /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
1409                                         MDELAY (60);
1410                                         hprt0.b.prtrst = 0;
1411                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1412                                         break;
1413                         #ifdef __WITH_HS_ELECT_TST__
1414                                 case USB_PORT_FEAT_TEST:
1415                                         {
1416                                                 uint32_t t;
1417                                                 gint_data_t gintmsk;
1418                                                 t = (_wIndex >> 8); /* MSB wIndex USB */
1419                                                 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1420                                                              "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
1421                                                 warn("USB_PORT_FEAT_TEST %d\n", t);
1422                                                 if (t < 6)
1423                                                 {
1424                                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1425                                                         hprt0.b.prttstctl = t;
1426                                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1427                                                 }
1428                                                 else if (t == 6)  /* HS_HOST_PORT_SUSPEND_RESUME */
1429                                                 {
1430                                                         /* Save current interrupt mask */
1431                                                         gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1432
1433                                                         /* Disable all interrupts while we muck with
1434                                                          * the hardware directly
1435                                                          */
1436                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1437
1438                                                         /* 15 second delay per the test spec */
1439                                                         mdelay(15000);
1440
1441                                                         /* Drive suspend on the root port */
1442                                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1443                                                         hprt0.b.prtsusp = 1;
1444                                                         hprt0.b.prtres = 0;
1445                                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1446
1447                                                         /* 15 second delay per the test spec */
1448                                                         mdelay(15000);
1449
1450                                                         /* Drive resume on the root port */
1451                                                         hprt0.d32 = ifxusb_read_hprt0 (core_if);
1452                                                         hprt0.b.prtsusp = 0;
1453                                                         hprt0.b.prtres = 1;
1454                                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1455                                                         mdelay(100);
1456
1457                                                         /* Clear the resume bit */
1458                                                         hprt0.b.prtres = 0;
1459                                                         ifxusb_wreg(core_if->hprt0, hprt0.d32);
1460
1461                                                         /* Restore interrupts */
1462                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1463                                                 }
1464                                                 else if (t == 7)  /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
1465                                                 {
1466                                                         /* Save current interrupt mask */
1467                                                         gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1468
1469                                                         /* Disable all interrupts while we muck with
1470                                                          * the hardware directly
1471                                                          */
1472                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1473
1474                                                         /* 15 second delay per the test spec */
1475                                                         mdelay(15000);
1476
1477                                                         /* Send the Setup packet */
1478                                                         do_setup(core_if);
1479
1480                                                         /* 15 second delay so nothing else happens for awhile */
1481                                                         mdelay(15000);
1482
1483                                                         /* Restore interrupts */
1484                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1485                                                 }
1486
1487                                                 else if (t == 8)  /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
1488                                                 {
1489                                                         /* Save current interrupt mask */
1490                                                         gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1491
1492                                                         /* Disable all interrupts while we muck with
1493                                                          * the hardware directly
1494                                                          */
1495                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1496
1497                                                         /* Send the Setup packet */
1498                                                         do_setup(core_if);
1499
1500                                                         /* 15 second delay so nothing else happens for awhile */
1501                                                         mdelay(15000);
1502
1503                                                         /* Send the In and Ack packets */
1504                                                         do_in_ack(core_if);
1505
1506                                                         /* 15 second delay so nothing else happens for awhile */
1507                                                         mdelay(15000);
1508
1509                                                         /* Restore interrupts */
1510                                                         ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1511                                                 }
1512                                         }
1513                                         break;
1514                         #endif //__WITH_HS_ELECT_TST__
1515                                 case USB_PORT_FEAT_INDICATOR:
1516                                         IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1517                                                      "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
1518                                         /* Not supported */
1519                                         break;
1520                                 default:
1521                                         retval = -EINVAL;
1522                                         IFX_ERROR ("IFXUSB HCD - "
1523                                                    "SetPortFeature request %xh "
1524                                                    "unknown or unsupported\n", _wValue);
1525                         }
1526                         break;
1527                 default:
1528                 error:
1529                         retval = -EINVAL;
1530                         IFX_WARN ("IFXUSB HCD - "
1531                                   "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
1532                                   _typeReq, _wIndex, _wValue);
1533         }
1534         return retval;
1535 }
1536
1537
1538
1539
1540 /*!
1541    \brief This function trigger a data transfer for a host channel and
1542   starts the transfer.
1543
1544   For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
1545   register along with a packet count of 1 and the channel is enabled. This
1546   causes a single PING transaction to occur. Other fields in HCTSIZ are
1547   simply set to 0 since no data transfer occurs in this case.
1548
1549   For a PING transfer in DMA mode, the HCTSIZ register is initialized with
1550   all the information required to perform the subsequent data transfer. In
1551   addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
1552   controller performs the entire PING protocol, then starts the data
1553   transfer.
1554   \param _core_if        Pointer of core_if structure
1555   \param _ifxhc Information needed to initialize the host channel. The xfer_len
1556   value may be reduced to accommodate the max widths of the XferSize and
1557   PktCnt fields in the HCTSIZn register. The multi_count value may be changed
1558   to reflect the final xfer_len value.
1559  */
1560 void ifxhcd_hc_start(ifxhcd_hcd_t *_ifxhcd, ifxhcd_hc_t *_ifxhc)
1561 {
1562         ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
1563         uint32_t max_hc_xfer_size = core_if->params.max_transfer_size;
1564         uint16_t max_hc_pkt_count = core_if->params.max_packet_count;
1565         ifxusb_hc_regs_t *hc_regs = core_if->hc_regs[_ifxhc->hc_num];
1566         hfnum_data_t hfnum;
1567
1568         hprt0_data_t hprt0;
1569
1570         if(_ifxhc->epqh->urbd->phase==URBD_DEQUEUEING)
1571                 return;
1572
1573         hprt0.d32 = ifxusb_read_hprt0(core_if);
1574
1575         if(_ifxhcd->pkt_remaining==0)
1576                 return;
1577
1578 #if 0
1579         if(_ifxhc->phase!=HC_WAITING)
1580                 printk(KERN_INFO "%s() line %d: _ifxhc->phase!=HC_WAITING :%d\n",__func__,__LINE__,_ifxhc->phase);
1581         if(_ifxhc->epqh->urbd->phase==URBD_IDLE      ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_IDLE\n",__func__,__LINE__);
1582 //      if(_ifxhc->epqh->urbd->phase==URBD_ACTIVE    ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_ACTIVE\n",__func__,__LINE__);
1583         if(_ifxhc->epqh->urbd->phase==URBD_STARTING  ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_STARTING\n",__func__,__LINE__);
1584         if(_ifxhc->epqh->urbd->phase==URBD_STARTED   ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_STARTED\n",__func__,__LINE__);
1585         if(_ifxhc->epqh->urbd->phase==URBD_COMPLETING) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_COMPLETING\n",__func__,__LINE__);
1586         if(_ifxhc->epqh->urbd->phase==URBD_DEQUEUEING) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_DEQUEUEING\n",__func__,__LINE__);
1587         if(_ifxhc->epqh->urbd->phase==URBD_FINISHING ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_FINISHING\n",__func__,__LINE__);
1588 #endif
1589
1590         if      (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
1591         {
1592                 if (_ifxhc->split)
1593                 {
1594                         if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
1595                                 max_hc_pkt_count = _ifxhcd->pkt_remaining;
1596                 }
1597                 else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
1598                 {
1599                         if( _ifxhc->is_in && _ifxhcd->pkt_count_limit_bi && max_hc_pkt_count > _ifxhcd->pkt_count_limit_bi)
1600                                 max_hc_pkt_count = _ifxhcd->pkt_count_limit_bi;
1601                         if(!_ifxhc->is_in && _ifxhcd->pkt_count_limit_bo && max_hc_pkt_count > _ifxhcd->pkt_count_limit_bo)
1602                                 max_hc_pkt_count = _ifxhcd->pkt_count_limit_bo;
1603                         if(max_hc_pkt_count*8 > _ifxhcd->pkt_remaining)
1604                                 max_hc_pkt_count = _ifxhcd->pkt_remaining/8;
1605                 }
1606                 else
1607                 {
1608                         if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
1609                                 max_hc_pkt_count = _ifxhcd->pkt_remaining;
1610                 }
1611         }
1612         else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
1613         {
1614                 if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
1615                         max_hc_pkt_count = _ifxhcd->pkt_remaining;
1616         }
1617         else
1618         {
1619                 if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
1620                         max_hc_pkt_count = _ifxhcd->pkt_remaining;
1621         }
1622
1623         if(max_hc_pkt_count==0)
1624                 return;
1625
1626         if(max_hc_pkt_count * _ifxhc->mps <  max_hc_xfer_size)
1627                 max_hc_xfer_size = max_hc_pkt_count * _ifxhc->mps;
1628
1629         _ifxhc->epqh->urbd->phase=URBD_STARTING;
1630
1631         if(_ifxhc->is_in || _ifxhc->speed != IFXUSB_EP_SPEED_HIGH || _ifxhc->xfer_len==0)
1632                 _ifxhc->epqh->do_ping=0;
1633         if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1634                 _ifxhc->epqh->do_ping=0;
1635         if(_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL && _ifxhc->control_phase != IFXHCD_CONTROL_DATA  )
1636                 _ifxhc->epqh->do_ping=0;
1637
1638         if (_ifxhc->split > 0)
1639         {
1640                 _ifxhc->start_pkt_count = 1;
1641                 if(!_ifxhc->is_in && _ifxhc->split>1) // OUT CSPLIT
1642                         _ifxhc->xfer_len = 0;
1643                 if (_ifxhc->xfer_len > _ifxhc->mps)
1644                         _ifxhc->xfer_len = _ifxhc->mps;
1645                 if (_ifxhc->xfer_len > 188)
1646                         _ifxhc->xfer_len = 188;
1647         }
1648         else if(_ifxhc->is_in)
1649         {
1650                 _ifxhc->short_rw = 0;
1651                 if (_ifxhc->xfer_len > 0)
1652                 {
1653                         if (_ifxhc->xfer_len > max_hc_xfer_size)
1654                                 _ifxhc->xfer_len = max_hc_xfer_size - _ifxhc->mps + 1;
1655                         _ifxhc->start_pkt_count = (_ifxhc->xfer_len + _ifxhc->mps - 1) / _ifxhc->mps;
1656                         if (_ifxhc->start_pkt_count > max_hc_pkt_count)
1657                                 _ifxhc->start_pkt_count = max_hc_pkt_count;
1658                 }
1659                 else /* Need 1 packet for transfer length of 0. */
1660                         _ifxhc->start_pkt_count = 1;
1661                 _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
1662         }
1663         else //non-split out
1664         {
1665                 if (_ifxhc->xfer_len == 0)
1666                 {
1667                         if(_ifxhc->short_rw==0)
1668                                 printk(KERN_INFO "Info: %s() line %d: ZLP write without short_rw set! xfer_count:%d/%d \n",__func__,__LINE__,
1669                                         _ifxhc->xfer_count,
1670                                         _ifxhc->epqh->urbd->xfer_len);
1671                         _ifxhc->start_pkt_count = 1;
1672                 }
1673                 else
1674                 {
1675                         if (_ifxhc->xfer_len > max_hc_xfer_size)
1676                         {
1677                                 _ifxhc->start_pkt_count = (max_hc_xfer_size / _ifxhc->mps);
1678                                 _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
1679                         }
1680                         else
1681                         {
1682                                 _ifxhc->start_pkt_count = (_ifxhc->xfer_len+_ifxhc->mps-1)  / _ifxhc->mps;
1683 //                              if(_ifxhc->start_pkt_count * _ifxhc->mps == _ifxhc->xfer_len )
1684 //                                      _ifxhc->start_pkt_count += _ifxhc->short_rw;
1685                         }
1686                 }
1687         }
1688
1689         if      (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
1690         {
1691                 if (_ifxhc->split)
1692                 {
1693                         if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
1694                                 _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
1695                         else
1696                                 _ifxhcd->pkt_remaining  = 0;
1697                 }
1698                 else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
1699                 {
1700                         if( _ifxhcd->pkt_remaining*8 > _ifxhc->start_pkt_count)
1701                                 _ifxhcd->pkt_remaining -= (_ifxhc->start_pkt_count*8);
1702                         else
1703                                 _ifxhcd->pkt_remaining  = 0;
1704                 }
1705                 else
1706                 {
1707                         if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
1708                                 _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
1709                         else
1710                                 _ifxhcd->pkt_remaining  = 0;
1711                 }
1712         }
1713         else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
1714         {
1715                 if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
1716                         _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
1717                 else
1718                         _ifxhcd->pkt_remaining  = 0;
1719         }
1720         else
1721         {
1722                 if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
1723                         _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
1724                 else
1725                         _ifxhcd->pkt_remaining  = 0;
1726         }
1727
1728         #ifdef __EN_ISOC__
1729                 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1730                 {
1731                         /* Set up the initial PID for the transfer. */
1732                         #if 1
1733                                 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
1734                         #else
1735                                 if (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1736                                 {
1737                                         if (_ifxhc->is_in)
1738                                         {
1739                                                 if      (_ifxhc->multi_count == 1)
1740                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
1741                                                 else if (_ifxhc->multi_count == 2)
1742                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
1743                                                 else
1744                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA2;
1745                                         }
1746                                         else
1747                                         {
1748                                                 if (_ifxhc->multi_count == 1)
1749                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
1750                                                 else
1751                                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_MDATA;
1752                                         }
1753                                 }
1754                                 else
1755                                         _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
1756                         #endif
1757                 }
1758         #endif
1759
1760         IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _ifxhc->hc_num);
1761         {
1762                 hctsiz_data_t hctsiz= { .d32=0 };
1763
1764                 hctsiz.b.dopng = _ifxhc->epqh->do_ping;
1765                 _ifxhc->epqh->do_ping=0;
1766
1767                 if(_ifxhc->is_in || _ifxhc->speed != IFXUSB_EP_SPEED_HIGH || _ifxhc->xfer_len==0)
1768                         hctsiz.b.dopng = 0;
1769                 if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1770                         hctsiz.b.dopng = 0;
1771                 if(_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL && _ifxhc->control_phase != IFXHCD_CONTROL_DATA  )
1772                         hctsiz.b.dopng = 0;
1773
1774                 hctsiz.b.xfersize = _ifxhc->xfer_len;
1775                 hctsiz.b.pktcnt   = _ifxhc->start_pkt_count;
1776                 hctsiz.b.pid      = _ifxhc->data_pid_start;
1777                 ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
1778
1779                 IFX_DEBUGPL(DBG_HCDV, "  Xfer Size: %d\n", hctsiz.b.xfersize);
1780                 IFX_DEBUGPL(DBG_HCDV, "  Num Pkts: %d\n" , hctsiz.b.pktcnt);
1781                 IFX_DEBUGPL(DBG_HCDV, "  Start PID: %d\n", hctsiz.b.pid);
1782         }
1783         IFX_DEBUGPL(DBG_HCDV, "  DMA: 0x%08x\n", (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
1784         ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
1785
1786         /* Start the split */
1787         if (_ifxhc->split>0)
1788         {
1789                 hcsplt_data_t hcsplt;
1790                 hcsplt.d32 = ifxusb_rreg (&hc_regs->hcsplt);
1791                 hcsplt.b.spltena = 1;
1792                 if (_ifxhc->split>1)
1793                         hcsplt.b.compsplt = 1;
1794                 else
1795                         hcsplt.b.compsplt = 0;
1796
1797                 #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
1798                         if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1799                                 hcsplt.b.xactpos = _ifxhc->isoc_xact_pos;
1800                         else
1801                 #endif
1802                 hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL;// if not ISO
1803                 ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
1804                 IFX_DEBUGPL(DBG_HCDV, "  SPLIT: XACT_POS:0x%08x\n", hcsplt.d32);
1805         }
1806
1807         {
1808                 hcchar_data_t hcchar;
1809                 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
1810 //              hcchar.b.multicnt = _ifxhc->multi_count;
1811                 hcchar.b.multicnt = 1;
1812
1813                 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1814                 {
1815                         hfnum.d32 = ifxusb_rreg(&core_if->host_global_regs->hfnum);
1816                         /* 1 if _next_ frame is odd, 0 if it's even */
1817                         hcchar.b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
1818                 }
1819
1820                 #ifdef __DEBUG__
1821                         _ifxhc->start_hcchar_val = hcchar.d32;
1822                         if (hcchar.b.chdis)
1823                                 IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
1824                                          __func__, _ifxhc->hc_num, hcchar.d32);
1825                 #endif
1826
1827                 /* Set host channel enable after all other setup is complete. */
1828                 hcchar.b.chen  = 1;
1829                 hcchar.b.chdis = 0;
1830                 hcchar.b.epdir =  _ifxhc->is_in;
1831                 _ifxhc->hcchar=hcchar.d32;
1832         }
1833
1834         IFX_DEBUGPL(DBG_HCDV, "  HCCHART: 0x%08x\n", _ifxhc->hcchar);
1835
1836         _ifxhc->phase=HC_STARTING;
1837 }
1838
1839 /*!
1840    \brief Attempts to halt a host channel. This function should only be called
1841   to abort a transfer in DMA mode. Under normal circumstances in DMA mode, the
1842   controller halts the channel when the transfer is complete or a condition
1843   occurs that requires application intervention.
1844
1845   In DMA mode, always sets the Channel Enable and Channel Disable bits of the
1846   HCCHARn register. The controller ensures there is space in the request
1847   queue before submitting the halt request.
1848
1849   Some time may elapse before the core flushes any posted requests for this
1850   host channel and halts. The Channel Halted interrupt handler completes the
1851   deactivation of the host channel.
1852  */
1853 int ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
1854                     ifxhcd_hc_t *_ifxhc,
1855                     ifxhcd_halt_status_e _halt_status)
1856 {
1857         hcchar_data_t   hcchar;
1858         ifxusb_hc_regs_t           *hc_regs;
1859         hc_regs          = _core_if->hc_regs[_ifxhc->hc_num];
1860
1861         WARN_ON(_halt_status == HC_XFER_NO_HALT_STATUS);
1862
1863         {
1864                 hprt0_data_t hprt0;
1865                 hprt0.d32 = ifxusb_rreg(_core_if->hprt0);
1866                 if(hprt0.b.prtena == 0)
1867                         return -1;
1868         }
1869
1870         if (_halt_status == HC_XFER_URB_DEQUEUE ||
1871             _halt_status == HC_XFER_AHB_ERR)
1872         {
1873                 /*
1874                  * Disable all channel interrupts except Ch Halted. The URBD
1875                  * and EPQH state associated with this transfer has been cleared
1876                  * (in the case of URB_DEQUEUE), so the channel needs to be
1877                  * shut down carefully to prevent crashes.
1878                  */
1879                 hcint_data_t hcintmsk;
1880                 hcintmsk.d32 = 0;
1881                 hcintmsk.b.chhltd = 1;
1882                 ifxusb_wreg(&hc_regs->hcintmsk, hcintmsk.d32);
1883
1884                 /*
1885                  * Make sure no other interrupts besides halt are currently
1886                  * pending. Handling another interrupt could cause a crash due
1887                  * to the URBD and EPQH state.
1888                  */
1889                 ifxusb_wreg(&hc_regs->hcint, ~hcintmsk.d32);
1890
1891                 /*
1892                  * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
1893                  * even if the channel was already halted for some other
1894                  * reason.
1895                  */
1896                 _ifxhc->halt_status = _halt_status;
1897         }
1898
1899         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
1900         if (hcchar.b.chen == 0)
1901         {
1902                 /*
1903                  * The channel is either already halted or it hasn't
1904                  * started yet. In DMA mode, the transfer may halt if
1905                  * it finishes normally or a condition occurs that
1906                  * requires driver intervention. Don't want to halt
1907                  * the channel again. In either Slave or DMA mode,
1908                  * it's possible that the transfer has been assigned
1909                  * to a channel, but not started yet when an URB is
1910                  * dequeued. Don't want to halt a channel that hasn't
1911                  * started yet.
1912                  */
1913                 _ifxhc->phase=HC_IDLE;
1914                 return -1;
1915         }
1916
1917         if (_ifxhc->phase==HC_STOPPING)
1918         {
1919                 /*
1920                  * A halt has already been issued for this channel. This might
1921                  * happen when a transfer is aborted by a higher level in
1922                  * the stack.
1923                  */
1924                 #ifdef __DEBUG__
1925                         IFX_PRINT("*** %s: Channel %d, double halt a channel***\n",
1926                                   __func__, _ifxhc->hc_num);
1927                 #endif
1928                 return 0;
1929         }
1930         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
1931         hcchar.b.chen = 1;
1932         hcchar.b.chdis = 1;
1933
1934         ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
1935
1936         _ifxhc->halt_status = _halt_status;
1937         _ifxhc->phase=HC_STOPPING;
1938
1939         IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n" , __func__, _ifxhc->hc_num);
1940         IFX_DEBUGPL(DBG_HCDV, "  hcchar: 0x%08x\n"   , hcchar.d32);
1941         IFX_DEBUGPL(DBG_HCDV, "  halt_status: %d\n"  , _ifxhc->halt_status);
1942
1943         return 0;
1944 }
1945
1946 /*!
1947    \brief Clears a host channel.
1948  */
1949 void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc)
1950 {
1951         ifxusb_hc_regs_t *hc_regs;
1952
1953         _ifxhc->phase=HC_IDLE;
1954         _ifxhc->epqh=0;
1955
1956         /*
1957          * Clear channel interrupt enables and any unhandled channel interrupt
1958          * conditions.
1959          */
1960         hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
1961         ifxusb_wreg(&hc_regs->hcintmsk, 0);
1962         ifxusb_wreg(&hc_regs->hcint, 0xFFFFFFFF);
1963
1964         #ifdef __DEBUG__
1965                 {
1966                         hcchar_data_t hcchar;
1967                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
1968                         if (hcchar.b.chdis)
1969                                 IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", __func__, _ifxhc->hc_num, hcchar.d32);
1970                 }
1971         #endif
1972 }
1973
1974
1975
1976
1977
1978 #ifdef __DEBUG__
1979         static void dump_urb_info(struct urb *_urb, char* _fn_name)
1980         {
1981                 IFX_PRINT("%s, urb %p\n"          , _fn_name, _urb);
1982                 IFX_PRINT("  Device address: %d\n", usb_pipedevice(_urb->pipe));
1983                 IFX_PRINT("  Endpoint: %d, %s\n"  , usb_pipeendpoint(_urb->pipe),
1984                                                     (usb_pipein(_urb->pipe) ? "IN" : "OUT"));
1985                 IFX_PRINT("  Endpoint type: %s\n",
1986                     ({  char *pipetype;
1987                         switch (usb_pipetype(_urb->pipe)) {
1988                                 case PIPE_CONTROL:     pipetype = "CONTROL"; break;
1989                                 case PIPE_BULK:        pipetype = "BULK"; break;
1990                                 case PIPE_INTERRUPT:   pipetype = "INTERRUPT"; break;
1991                                 case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
1992                                 default:               pipetype = "UNKNOWN"; break;
1993                         };
1994                         pipetype;
1995                     }));
1996                 IFX_PRINT("  Speed: %s\n",
1997                     ({  char *speed;
1998                         switch (_urb->dev->speed) {
1999                                 case USB_SPEED_HIGH: speed = "HIGH"; break;
2000                                 case USB_SPEED_FULL: speed = "FULL"; break;
2001                                 case USB_SPEED_LOW:  speed = "LOW"; break;
2002                                 default:             speed = "UNKNOWN"; break;
2003                         };
2004                         speed;
2005                     }));
2006                 IFX_PRINT("  Max packet size: %d\n",
2007                           usb_maxpacket(_urb->dev, _urb->pipe, usb_pipeout(_urb->pipe)));
2008                 IFX_PRINT("  Data buffer length: %d\n", _urb->transfer_buffer_length);
2009                 IFX_PRINT("  Transfer buffer: %p, Transfer DMA: %p\n",
2010                           _urb->transfer_buffer, (void *)_urb->transfer_dma);
2011                 IFX_PRINT("  Setup buffer: %p, Setup DMA: %p\n",
2012                           _urb->setup_packet, (void *)_urb->setup_dma);
2013                 IFX_PRINT("  Interval: %d\n", _urb->interval);
2014                 if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
2015                 {
2016                         int i;
2017                         for (i = 0; i < _urb->number_of_packets;  i++)
2018                         {
2019                                 IFX_PRINT("  ISO Desc %d:\n", i);
2020                                 IFX_PRINT("    offset: %d, length %d\n",
2021                                     _urb->iso_frame_desc[i].offset,
2022                                     _urb->iso_frame_desc[i].length);
2023                         }
2024                 }
2025         }
2026
2027 #if 0
2028         static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
2029         {
2030                 if (_epqh->hc != NULL)
2031                 {
2032                         ifxhcd_hc_t      *hc = _epqh->hc;
2033                         struct list_head *item;
2034                         ifxhcd_epqh_t      *epqh_item;
2035
2036                         ifxusb_hc_regs_t *hc_regs;
2037
2038                         hcchar_data_t  hcchar;
2039                         hcsplt_data_t  hcsplt;
2040                         hctsiz_data_t  hctsiz;
2041                         uint32_t       hcdma;
2042
2043                         hc_regs = _ifxhcd->core_if.hc_regs[hc->hc_num];
2044                         hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2045                         hcsplt.d32 = ifxusb_rreg(&hc_regs->hcsplt);
2046                         hctsiz.d32 = ifxusb_rreg(&hc_regs->hctsiz);
2047                         hcdma      = ifxusb_rreg(&hc_regs->hcdma);
2048
2049                         IFX_PRINT("  Assigned to channel %d:\n"       , hc->hc_num);
2050                         IFX_PRINT("    hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
2051                         IFX_PRINT("    hctsiz 0x%08x, hcdma 0x%08x\n" , hctsiz.d32, hcdma);
2052                         IFX_PRINT("    dev_addr: %d, ep_num: %d, is_in: %d\n",
2053                            hc->dev_addr, hc->ep_num, hc->is_in);
2054                         IFX_PRINT("    ep_type: %d\n"        , hc->ep_type);
2055                         IFX_PRINT("    max_packet_size: %d\n", hc->mps);
2056                         IFX_PRINT("    data_pid_start: %d\n" , hc->data_pid_start);
2057                         IFX_PRINT("    halt_status: %d\n"    , hc->halt_status);
2058                         IFX_PRINT("    xfer_buff: %p\n"      , hc->xfer_buff);
2059                         IFX_PRINT("    xfer_len: %d\n"       , hc->xfer_len);
2060                         IFX_PRINT("    epqh: %p\n"           , hc->epqh);
2061                         IFX_PRINT("  NP :\n");
2062                         list_for_each(item, &_ifxhcd->epqh_list_np)
2063                         {
2064                                 epqh_item = list_entry(item, ifxhcd_epqh_t, ql);
2065                                 IFX_PRINT("    %p\n", epqh_item);
2066                         }
2067                         IFX_PRINT("  INTR :\n");
2068                         list_for_each(item, &_ifxhcd->epqh_list_intr)
2069                         {
2070                                 epqh_item = list_entry(item, ifxhcd_epqh_t, ql);
2071                                 IFX_PRINT("    %p\n", epqh_item);
2072                         }
2073                         #ifdef __EN_ISOC__
2074                                 IFX_PRINT("  ISOC:\n");
2075                                 list_for_each(item, &_ifxhcd->epqh_list_isoc)
2076                                 {
2077                                         epqh_item = list_entry(item, ifxhcd_epqh_t, ql);
2078                                         IFX_PRINT("    %p\n", epqh_item);
2079                                 }
2080                         #endif
2081                 }
2082         }
2083 #endif
2084 #endif //__DEBUG__
2085
2086
2087 /*!
2088    \brief This function writes a packet into the Tx FIFO associated with the Host
2089   Channel. For a channel associated with a non-periodic EP, the non-periodic
2090   Tx FIFO is written. For a channel associated with a periodic EP, the
2091   periodic Tx FIFO is written. This function should only be called in Slave
2092   mode.
2093
2094   Upon return the xfer_buff and xfer_count fields in _hc are incremented by
2095   then number of bytes written to the Tx FIFO.
2096  */
2097
2098 #ifdef __ENABLE_DUMP__
2099         void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd)
2100         {
2101                 int num_channels;
2102                 int i;
2103                 num_channels = _ifxhcd->core_if.params.host_channels;
2104                 IFX_PRINT("\n");
2105                 IFX_PRINT("************************************************************\n");
2106                 IFX_PRINT("HCD State:\n");
2107                 IFX_PRINT("  Num channels: %d\n", num_channels);
2108                 for (i = 0; i < num_channels; i++) {
2109                         ifxhcd_hc_t *hc = &_ifxhcd->ifxhc[i];
2110                         IFX_PRINT("  Channel %d:\n", hc->hc_num);
2111                         IFX_PRINT("    dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
2112                                   hc->dev_addr, hc->ep_num, hc->is_in);
2113                         IFX_PRINT("    speed: %d\n"          , hc->speed);
2114                         IFX_PRINT("    ep_type: %d\n"        , hc->ep_type);
2115                         IFX_PRINT("    mps: %d\n", hc->mps);
2116                         IFX_PRINT("    data_pid_start: %d\n" , hc->data_pid_start);
2117                         IFX_PRINT("    xfer_buff: %p\n"      , hc->xfer_buff);
2118                         IFX_PRINT("    xfer_len: %d\n"       , hc->xfer_len);
2119                         IFX_PRINT("    xfer_count: %d\n"     , hc->xfer_count);
2120                         IFX_PRINT("    halt_status: %d\n"    , hc->halt_status);
2121                         IFX_PRINT("    split: %d\n"          , hc->split);
2122                         IFX_PRINT("    hub_addr: %d\n"       , hc->hub_addr);
2123                         IFX_PRINT("    port_addr: %d\n"      , hc->port_addr);
2124                         #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
2125                                 IFX_PRINT("    isoc_xact_pos: %d\n"       , hc->isoc_xact_pos);
2126                         #endif
2127
2128                         IFX_PRINT("    epqh: %p\n"           , hc->epqh);
2129                         IFX_PRINT("    short_rw: %d\n"       , hc->short_rw);
2130                         IFX_PRINT("    control_phase: %d\n"  , hc->control_phase);
2131                         if(hc->epqh)
2132                         {
2133                                 IFX_PRINT("    do_ping: %d\n"        , hc->epqh->do_ping);
2134                         }
2135                         IFX_PRINT("    start_pkt_count: %d\n"       , hc->start_pkt_count);
2136                 }
2137                 IFX_PRINT("************************************************************\n");
2138                 IFX_PRINT("\n");
2139         }
2140 #endif //__ENABLE_DUMP__
2141