Root/package/platform/lantiq/ltq-hcd/src/ifxhcd_intr.c

1/*****************************************************************************
2 ** FILE NAME : ifxhcd_intr.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 implementation of the HCD Interrupt handlers.
9 ** FUNCTIONS :
10 ** COMPILER : gcc
11 ** REFERENCE : Synopsys DWC-OTG Driver 2.7
12 ** COPYRIGHT : Copyright (c) 2010
13 ** LANTIQ DEUTSCHLAND GMBH,
14 ** Am Campeon 3, 85579 Neubiberg, Germany
15 **
16 ** This program is free software; you can redistribute it and/or modify
17 ** it under the terms of the GNU General Public License as published by
18 ** the Free Software Foundation; either version 2 of the License, or
19 ** (at your option) any later version.
20 **
21 ** Version Control Section **
22 ** $Author$
23 ** $Date$
24 ** $Revisions$
25 ** $Log$ Revision history
26 *****************************************************************************/
27
28/*
29 * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
30 * For this code the following notice is applicable:
31 *
32 * ==========================================================================
33 *
34 * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
35 * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
36 * otherwise expressly agreed to in writing between Synopsys and you.
37 *
38 * The Software IS NOT an item of Licensed Software or Licensed Product under
39 * any End User Software License Agreement or Agreement for Licensed Product
40 * with Synopsys or any supplement thereto. You are permitted to use and
41 * redistribute this Software in source and binary forms, with or without
42 * modification, provided that redistributions of source code must retain this
43 * notice. You may not view, use, disclose, copy or distribute this file or
44 * any information contained herein except pursuant to this license grant from
45 * Synopsys. If you do not agree with this notice, including the disclaimer
46 * below, then you are not authorized to use the Software.
47 *
48 * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
49 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
52 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
53 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
54 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
55 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
58 * DAMAGE.
59 * ========================================================================== */
60
61/*!
62 \file ifxhcd_intr.c
63 \ingroup IFXUSB_DRIVER_V3
64 \brief This file contains the implementation of the HCD Interrupt handlers.
65*/
66
67
68#include <linux/version.h>
69#include "ifxusb_version.h"
70
71#include "ifxusb_plat.h"
72#include "ifxusb_regs.h"
73#include "ifxusb_cif.h"
74
75#include "ifxhcd.h"
76
77/* Macro used to clear one channel interrupt */
78#define clear_hc_int(_hc_regs_,_intr_) \
79    do { \
80        hcint_data_t hcint_clear = {.d32 = 0}; \
81        hcint_clear.b._intr_ = 1; \
82        ifxusb_wreg(&((_hc_regs_)->hcint), hcint_clear.d32); \
83    } while (0)
84
85/*
86 * Macro used to disable one channel interrupt. Channel interrupts are
87 * disabled when the channel is halted or released by the interrupt handler.
88 * There is no need to handle further interrupts of that type until the
89 * channel is re-assigned. In fact, subsequent handling may cause crashes
90 * because the channel structures are cleaned up when the channel is released.
91 */
92#define disable_hc_int(_hc_regs_,_intr_) \
93    do { \
94        hcint_data_t hcintmsk = {.d32 = 0}; \
95        hcintmsk.b._intr_ = 1; \
96        ifxusb_mreg(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \
97    } while (0)
98
99#define enable_hc_int(_hc_regs_,_intr_) \
100    do { \
101        hcint_data_t hcintmsk = {.d32 = 0}; \
102        hcintmsk.b._intr_ = 1; \
103        ifxusb_mreg(&((_hc_regs_)->hcintmsk),0, hcintmsk.d32); \
104    } while (0)
105
106/*
107 * Save the starting data toggle for the next transfer. The data toggle is
108 * saved in the QH for non-control transfers and it's saved in the QTD for
109 * control transfers.
110 */
111uint8_t read_data_toggle(ifxusb_hc_regs_t *_hc_regs)
112{
113    hctsiz_data_t hctsiz;
114    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
115    return(hctsiz.b.pid);
116}
117
118
119static void release_channel_dump(ifxhcd_hc_t *ifxhc,
120                               struct urb *urb,
121                               ifxhcd_epqh_t *epqh,
122                               ifxhcd_urbd_t *urbd,
123                               ifxhcd_halt_status_e halt_status)
124{
125    #ifdef __DEBUG__
126        printk(KERN_INFO);
127        switch (halt_status)
128        {
129            case HC_XFER_NO_HALT_STATUS:
130                printk("HC_XFER_NO_HALT_STATUS");break;
131            case HC_XFER_URB_COMPLETE:
132                printk("HC_XFER_URB_COMPLETE");break;
133            case HC_XFER_AHB_ERR:
134                printk("HC_XFER_AHB_ERR");break;
135            case HC_XFER_STALL:
136                printk("HC_XFER_STALL");break;
137            case HC_XFER_BABBLE_ERR:
138                printk("HC_XFER_BABBLE_ERR");break;
139            case HC_XFER_XACT_ERR:
140                printk("HC_XFER_XACT_ERR");break;
141            case HC_XFER_URB_DEQUEUE:
142                printk("HC_XFER_URB_DEQUEUE");break;
143            case HC_XFER_FRAME_OVERRUN:
144                printk("HC_XFER_FRAME_OVERRUN");break;
145            case HC_XFER_DATA_TOGGLE_ERR:
146                printk("HC_XFER_DATA_TOGGLE_ERR");break;
147        #ifdef __NAKSTOP__
148            case HC_XFER_NAK:
149                printk("HC_XFER_NAK");break;
150        #endif
151            case HC_XFER_COMPLETE:
152                printk("HC_XFER_COMPLETE");break;
153            default:
154                printk("KNOWN");break;
155        }
156        if(ifxhc)
157            printk("Ch %d %s%s S%d " , ifxhc->hc_num
158                ,(ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL)?"CTRL-":
159                   ((ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)?"BULK-":
160                     ((ifxhc->ep_type == IFXUSB_EP_TYPE_INTR)?"INTR-":
161                       ((ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)?"ISOC-":"????"
162                       )
163                     )
164                   )
165                ,(ifxhc->is_in)?"IN":"OUT"
166                ,(ifxhc->split)
167                );
168        else
169            printk(" [NULL HC] ");
170        printk("urb=%p epqh=%p urbd=%p\n",urb,epqh,urbd);
171
172        if(urb)
173        {
174            printk(KERN_INFO " Device address: %d\n", usb_pipedevice(urb->pipe));
175            printk(KERN_INFO " Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
176                    (usb_pipein(urb->pipe) ? "IN" : "OUT"));
177            printk(KERN_INFO " Endpoint type: %s\n",
178                    ({char *pipetype;
179                    switch (usb_pipetype(urb->pipe)) {
180                        case PIPE_CONTROL: pipetype = "CTRL"; break;
181                        case PIPE_BULK: pipetype = "BULK"; break;
182                        case PIPE_INTERRUPT: pipetype = "INTR"; break;
183                        case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break;
184                        default: pipetype = "????"; break;
185                    }; pipetype;}));
186            printk(KERN_INFO " Speed: %s\n",
187                    ({char *speed;
188                    switch (urb->dev->speed) {
189                        case USB_SPEED_HIGH: speed = "HS"; break;
190                        case USB_SPEED_FULL: speed = "FS"; break;
191                        case USB_SPEED_LOW: speed = "LS"; break;
192                        default: speed = "????"; break;
193                    }; speed;}));
194            printk(KERN_INFO " Max packet size: %d\n",
195                    usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
196            printk(KERN_INFO " Data buffer length: %d/%d\n",urb->actual_length, urb->transfer_buffer_length);
197            printk(KERN_INFO " Transfer buffer: %p, Transfer DMA: %p\n",
198                    urb->transfer_buffer, (void *)urb->transfer_dma);
199            printk(KERN_INFO " Setup buffer: %p, Setup DMA: %p\n",
200                    urb->setup_packet, (void *)urb->setup_dma);
201            printk(KERN_INFO " Interval: %d\n", urb->interval);
202        }
203        if(urbd)
204        {
205            switch (urbd->status)
206            {
207                case HC_XFER_NO_HALT_STATUS:
208                    printk(KERN_INFO " STATUS:HC_XFER_NO_HALT_STATUS\n");break;
209                case HC_XFER_URB_COMPLETE:
210                    printk(KERN_INFO " STATUS:HC_XFER_URB_COMPLETE\n");break;
211                case HC_XFER_AHB_ERR:
212                    printk(KERN_INFO " STATUS:HC_XFER_AHB_ERR\n");break;
213                case HC_XFER_STALL:
214                    printk(KERN_INFO " STATUS:HC_XFER_STALL\n");break;
215                case HC_XFER_BABBLE_ERR:
216                    printk(KERN_INFO " STATUS:HC_XFER_BABBLE_ERR\n");break;
217                case HC_XFER_XACT_ERR:
218                    printk(KERN_INFO " STATUS:HC_XFER_XACT_ERR\n");break;
219                case HC_XFER_URB_DEQUEUE:
220                    printk(KERN_INFO " STATUS:HC_XFER_URB_DEQUEUE\n");break;
221                case HC_XFER_FRAME_OVERRUN:
222                    printk(KERN_INFO " STATUS:HC_XFER_FRAME_OVERRUN\n");break;
223                case HC_XFER_DATA_TOGGLE_ERR:
224                    printk(KERN_INFO " STATUS:HC_XFER_DATA_TOGGLE_ERR\n");break;
225                case HC_XFER_COMPLETE:
226                    printk(KERN_INFO " STATUS:HC_XFER_COMPLETE\n");break;
227                default:
228                    printk(KERN_INFO " STATUS:UNKKNOWN %d\n",urbd->status);break;
229            }
230        }
231    #endif
232}
233
234/*!
235     \fn static void release_channel(ifxhcd_hcd_t *_ifxhcd,
236                            ifxhcd_hc_t *_ifxhc,
237                            ifxhcd_halt_status_e _halt_status)
238     \brief Release the halted channel.
239     \param _ifxhcd Pointer to the sate of HCD structure
240     \param _ifxhc Pointer to host channel descriptor
241     \param _halt_status Halt satus
242     \return None
243     \ingroup IFXUSB_HCD
244 */
245
246static void release_channel(ifxhcd_hcd_t *_ifxhcd,
247                            ifxhcd_hc_t *_ifxhc,
248                            ifxhcd_halt_status_e _halt_status)
249{
250    ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num];
251    struct urb *urb = NULL;
252    ifxhcd_epqh_t *epqh = NULL;
253    ifxhcd_urbd_t *urbd = NULL;
254
255    IFX_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
256            __func__, _ifxhc->hc_num, _halt_status);
257
258    epqh=_ifxhc->epqh;
259
260    if(!epqh)
261    {
262        if(_halt_status!=HC_XFER_NO_EPQH)
263            IFX_ERROR("%s epqh=null\n",__func__);
264    }
265    else
266    {
267        urbd=epqh->urbd;
268        if(!urbd)
269            IFX_ERROR("%s urbd=null\n",__func__);
270        else
271        {
272            urb=urbd->urb;
273            if(!urb)
274            {
275                if(_halt_status!=HC_XFER_NO_URB)
276                    IFX_ERROR("%s urb =null\n",__func__);
277            }
278            else
279            {
280                if (read_data_toggle(hc_regs) == IFXUSB_HCTSIZ_DATA0)
281                    usb_settoggle (urb->dev,usb_pipeendpoint (urb->pipe), (_ifxhc->is_in)?0:1,0);
282                else if (read_data_toggle(hc_regs) == IFXUSB_HCTSIZ_DATA1)
283                    usb_settoggle (urb->dev,usb_pipeendpoint (urb->pipe), (_ifxhc->is_in)?0:1,1);
284            }
285        }
286    }
287
288    switch (_halt_status)
289    {
290        case HC_XFER_NO_HALT_STATUS:
291            IFX_ERROR("%s: No halt_status, channel %d\n", __func__, _ifxhc->hc_num);
292// return;
293            break;
294        case HC_XFER_COMPLETE:
295            IFX_ERROR("%s: Inavalid halt_status HC_XFER_COMPLETE, channel %d\n", __func__, _ifxhc->hc_num);
296// return;
297            break;
298        case HC_XFER_NO_URB:
299            break;
300        case HC_XFER_NO_EPQH:
301            break;
302        case HC_XFER_URB_DEQUEUE:
303        case HC_XFER_AHB_ERR:
304        case HC_XFER_XACT_ERR:
305        case HC_XFER_FRAME_OVERRUN:
306            if(urbd && urb)
307            {
308                urbd->phase=URBD_DEQUEUEING;
309                ifxhcd_complete_urb(_ifxhcd, urbd, urbd->status);
310            }
311            else
312            {
313                IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
314                release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
315            }
316            break;
317        case HC_XFER_URB_COMPLETE:
318            if(urbd && urb)
319            {
320                urbd->phase=URBD_COMPLETING;
321                ifxhcd_complete_urb(_ifxhcd, urbd, urbd->status);
322            }
323            else
324            {
325                IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
326                release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
327            }
328            break;
329        case HC_XFER_STALL:
330            if(urbd)
331            {
332                urbd->phase=URBD_DEQUEUEING;
333                ifxhcd_complete_urb(_ifxhcd, urbd, -EPIPE);
334            }
335            else
336            {
337                IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
338                release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
339            }
340            if(epqh && urb && urb->dev && urb->pipe)
341                usb_settoggle(urb->dev, usb_pipeendpoint (urb->pipe), !usb_pipein(urb->pipe), IFXUSB_HC_PID_DATA0);
342            break;
343        case HC_XFER_BABBLE_ERR:
344        case HC_XFER_DATA_TOGGLE_ERR:
345            if(urbd)
346            {
347                urbd->phase=URBD_DEQUEUEING;
348                ifxhcd_complete_urb(_ifxhcd, urbd, -EOVERFLOW);
349            }
350            else
351            {
352                IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
353                release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
354            }
355            break;
356    #ifdef __NAKSTOP__
357        case HC_XFER_NAK:
358            if (_ifxhc->is_in)
359            {
360                if(urbd && urb)
361                {
362                    urbd->phase=URBD_COMPLETING;
363                    ifxhcd_complete_urb(_ifxhcd, urbd, 0);
364                }
365                else
366                {
367                    IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
368                    release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
369                }
370            }
371            else
372            {
373                IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
374                release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
375            }
376            break;
377    #endif
378    #if defined(__INTRNAKRETRY__) || defined(__INTRINCRETRY__)
379        case HC_XFER_INTR_NAK_RETRY:
380            epqh->phase=EPQH_READY;
381            urbd->phase=URBD_IDLE;
382            ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
383            select_eps(_ifxhcd);
384            return;
385            break;
386            
387    #endif
388    }
389    if(epqh)
390    {
391        ifxhcd_epqh_idle(epqh);
392    }
393    else if(_halt_status!=HC_XFER_NO_EPQH)
394    {
395        IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
396        release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
397    }
398    ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
399    select_eps(_ifxhcd);
400}
401
402/*
403 * Updates the state of the URB after a Transfer Complete interrupt on the
404 * host channel. Updates the actual_length field of the URB based on the
405 * number of bytes transferred via the host channel. Sets the URB status
406 * if the data transfer is finished.
407 *
408 * @return 1 if the data transfer specified by the URB is completely finished,
409 * 0 otherwise.
410 */
411static int update_urb_state_xfer_comp(ifxhcd_hc_t *_ifxhc,
412                                      ifxusb_hc_regs_t *_hc_regs,
413                                      struct urb *_urb,
414                                      ifxhcd_urbd_t *_urbd)
415{
416    int xfer_done = 0;
417
418    #ifdef __EN_ISOC__
419    if(_urbd->epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
420    {
421        struct usb_iso_packet_descriptor *frame_desc;
422        frame_desc = &_urb->iso_frame_desc[_urbd->isoc_frame_index];
423        if (_ifxhc->is_in)
424        {
425            hctsiz_data_t hctsiz;
426            hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
427            frame_desc->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
428            if ((hctsiz.b.xfersize != 0) || (frame_desc->actual_length >= _urbd->xfer_len))
429            {
430                xfer_done = 1;
431                frame_desc->status = 0;
432                #if 0
433                    if (frame_desc->actual_length < frame_desc->length && _urb->transfer_flags & URB_SHORT_NOT_OK)
434                        frame_desc->status = -EREMOTEIO;
435                #endif
436            }
437        }
438        else
439        {
440            if (_ifxhc->split)
441                frame_desc->actual_length += _ifxhc->ssplit_out_xfer_count;
442            else
443                frame_desc->actual_length += _ifxhc->xfer_len;
444            if (frame_desc->actual_length >= _urbd->xfer_len)
445            {
446                xfer_done = 1;
447                frame_desc->status = 0;
448            }
449        }
450    }
451    else
452    #endif
453    if (_ifxhc->is_in)
454    {
455        hctsiz_data_t hctsiz;
456        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
457        _urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
458#ifdef __INTRINCRETRY__
459        if(_urbd->epqh->ep_type==IFXUSB_EP_TYPE_INTR)
460        {
461            if(_ifxhc->xfer_len != hctsiz.b.xfersize)
462            {
463                xfer_done = 1;
464                _urbd->status = 0;
465            }
466        }
467        else
468#endif
469        if ((hctsiz.b.xfersize != 0) || (_urb->actual_length >= _urb->transfer_buffer_length))
470        {
471            xfer_done = 1;
472            _urbd->status = 0;
473            if(_urb->transfer_flags & URB_SHORT_NOT_OK)
474            {
475                if (_urb->actual_length < _urb->transfer_buffer_length)
476                    _urbd->status = -EREMOTEIO;
477            }
478        }
479    }
480    else if(_urb->transfer_buffer_length%_ifxhc->mps) // OUT without ZLP
481    {
482        if (_ifxhc->split)
483            _urb->actual_length += _ifxhc->ssplit_out_xfer_count;
484        else
485            _urb->actual_length += _ifxhc->xfer_len;
486        if (_urb->actual_length >= _urb->transfer_buffer_length)
487        {
488            xfer_done = 1;
489            _urbd->status = 0;
490        }
491    }
492    else if (_urb->actual_length >= _urb->transfer_buffer_length) //OUT with ZLP
493    {
494        xfer_done = 1;
495        _urbd->status = 0;
496    }
497    else //OUT without ZLP, unfinished
498    {
499        if (_ifxhc->split)
500            _urb->actual_length += _ifxhc->ssplit_out_xfer_count;
501        else
502            _urb->actual_length += _ifxhc->xfer_len;
503        if (!_ifxhc->short_rw && _urb->actual_length >= _urb->transfer_buffer_length)
504        {
505            xfer_done = 1;
506            _urbd->status = 0;
507        }
508    }
509
510    #ifdef __DEBUG__
511        {
512            hctsiz_data_t hctsiz;
513            hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
514            IFX_DEBUGPL(DBG_HCDV, "IFXUSB: %s: %s, channel %d\n",
515                    __func__, (_ifxhc->is_in ? "IN" : "OUT"), _ifxhc->hc_num);
516            IFX_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", _ifxhc->xfer_len);
517            IFX_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", hctsiz.b.xfersize);
518            #ifdef __EN_ISOC__
519            if(_urbd->epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
520            {
521                IFX_DEBUGPL(DBG_HCDV, " descritor # %d\n", _urbd->isoc_frame_index);
522                IFX_DEBUGPL(DBG_HCDV, " buffer_length %d\n",
523                    _urb->iso_frame_desc[_urbd->isoc_frame_index].length);
524                IFX_DEBUGPL(DBG_HCDV, " actual_length %d\n", _urb->iso_frame_desc[_urbd->isoc_frame_index].actual_length);
525            }
526            else
527            #endif
528            {
529                IFX_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
530                        _urb->transfer_buffer_length);
531                IFX_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", _urb->actual_length);
532            }
533        }
534    #endif
535    return xfer_done;
536}
537
538#ifdef __EN_ISOC__
539    static void next_isoc_sub(unsigned long data)
540    {
541        ifxhcd_urbd_t *urbd;
542        ifxhcd_hcd_t *ifxhcd;
543
544        urbd=((ifxhcd_urbd_t *)data);
545        ifxhcd=urbd->epqh->ifxhcd;
546
547        if (!urbd->epqh)
548            IFX_ERROR("%s: invalid epqd\n",__func__);
549        #if defined(__UNALIGNED_BUF_ADJ__)
550        else
551        {
552            if( urbd->aligned_checked &&
553// urbd->using_aligned_buf &&
554                urbd->xfer_buff &&
555                urbd->is_in)
556            {
557                uint8_t *buf;
558
559                buf=urbd->xfer_buff;
560                buf+=urbd->urb->iso_frame_desc[urbd->isoc_frame_index].offset;
561                memcpy(buf,urbd->aligned_buf,urbd->urb->iso_frame_desc[urbd->isoc_frame_index].length);
562            }
563// urbd->using_aligned_buf=0;
564// urbd->using_aligned_setup=0;
565        }
566        #endif
567
568        urbd->isoc_frame_index++;
569        if(urbd->isoc_frame_index>=urbd->urb->number_of_packets)
570            release_channel(ifxhcd,urbd->epqh->hc,HC_XFER_URB_COMPLETE);
571        else
572            init_hc(urbd->epqh);
573    }
574#endif
575
576/*!
577     \fn static void complete_channel(ifxhcd_hcd_t *_ifxhcd,
578                            ifxhcd_hc_t *_ifxhc,
579                            ifxhcd_urbd_t *_urbd)
580     \brief Complete the transaction on the channel.
581     \param _ifxhcd Pointer to the sate of HCD structure
582     \param _ifxhc Pointer to host channel descriptor
583     \param _urbd Pointer to URB descriptor
584     \return None
585     \ingroup IFXUSB_HCD
586 */
587static void complete_channel(ifxhcd_hcd_t *_ifxhcd,
588                            ifxhcd_hc_t *_ifxhc,
589                            ifxhcd_urbd_t *_urbd)
590{
591    ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num];
592    struct urb *urb = NULL;
593    ifxhcd_epqh_t *epqh = NULL;
594    int urb_xfer_done;
595
596    IFX_DEBUGPL(DBG_HCD, "--Complete Channel %d : \n", _ifxhc->hc_num);
597
598    if(!_urbd)
599    {
600        IFX_ERROR("ERROR %s():%d urbd=%p\n",__func__,__LINE__,_urbd);
601        return;
602    }
603
604    urb = _urbd->urb;
605    epqh = _urbd->epqh;
606
607    if(!epqh)
608    {
609        release_channel(_ifxhcd,_ifxhc,HC_XFER_NO_EPQH);
610        return;
611    }
612    if(!urb || (unsigned long)urb->hcpriv!=(unsigned long)_urbd)
613    {
614        release_channel(_ifxhcd,_ifxhc,HC_XFER_NO_URB);
615        return;
616    }
617
618    if (_ifxhc->split)
619        _ifxhc->split = 1;
620
621    switch (epqh->ep_type)
622    {
623        case IFXUSB_EP_TYPE_CTRL:
624            switch (_ifxhc->control_phase)
625            {
626                case IFXHCD_CONTROL_SETUP:
627                    if (_urbd->xfer_len > 0)
628                    {
629                        _ifxhc->control_phase = IFXHCD_CONTROL_DATA;
630                        IFX_DEBUGPL(DBG_HCDV, " Control setup transaction done Data Stage now\n");
631                        _ifxhc->is_in = _urbd->is_in;
632                        _ifxhc->xfer_len = _urbd->xfer_len;
633                        #if defined(__UNALIGNED_BUF_ADJ__)
634                            if(_urbd->aligned_buf)
635                                _ifxhc->xfer_buff = _urbd->aligned_buf;
636                            else
637                        #endif
638                                _ifxhc->xfer_buff = _urbd->xfer_buff;
639                        #ifdef __NAKSTOP__
640                        if(!_ifxhc->split)
641                        {
642                            #ifdef __INNAKSTOP_CTRL__
643                            if(_ifxhc->is_in)
644                                _ifxhc->stop_on=1;
645                            #endif
646                            #ifdef __PINGSTOP_CTRL__
647                            if(!_ifxhc->is_in)
648                                _ifxhc->stop_on=1;
649                            #endif
650                        }
651                        #endif
652                    }
653                    else
654                    {
655                        IFX_DEBUGPL(DBG_HCDV, " Control setup transaction done Status Stage now\n");
656                        _ifxhc->control_phase = IFXHCD_CONTROL_STATUS;
657                        _ifxhc->is_in = 1;
658                        _ifxhc->xfer_len = 0;
659                        _ifxhc->xfer_buff = _ifxhcd->status_buf;
660                        #ifdef __NAKSTOP__
661                            _ifxhc->stop_on=0;
662                        #endif
663                    }
664                    if(_ifxhc->is_in)
665                        _ifxhc->short_rw =0;
666                    else
667                        _ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
668                    _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
669                    _ifxhc->xfer_count = 0;
670                    _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
671                    _ifxhc->phase=HC_WAITING;
672                    ifxhcd_hc_start(_ifxhcd, _ifxhc);
673                    break;
674                case IFXHCD_CONTROL_DATA:
675                    urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
676                    if (urb_xfer_done)
677                    {
678                        _ifxhc->control_phase = IFXHCD_CONTROL_STATUS;
679                        IFX_DEBUGPL(DBG_HCDV, " Control data transaction done Status Stage now\n");
680                        _ifxhc->is_in = (_urbd->is_in)?0:1;
681                        _ifxhc->xfer_len = 0;
682                        _ifxhc->xfer_count = 0;
683                        _ifxhc->xfer_buff = _ifxhcd->status_buf;
684                        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
685                        _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
686                        if(_ifxhc->is_in)
687                            _ifxhc->short_rw =0;
688                        else
689                            _ifxhc->short_rw =1;
690                        #ifdef __NAKSTOP__
691                            _ifxhc->stop_on=0;
692                        #endif
693                    }
694                    else // continue
695                    {
696                        IFX_DEBUGPL(DBG_HCDV, " Control data transaction continue\n");
697                        _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length;
698                        _ifxhc->xfer_count = urb->actual_length;
699                        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
700                        _ifxhc->data_pid_start = read_data_toggle(hc_regs);
701                    }
702                    _ifxhc->phase=HC_WAITING;
703                    ifxhcd_hc_start(_ifxhcd, _ifxhc);
704                    break;
705                case IFXHCD_CONTROL_STATUS:
706                    IFX_DEBUGPL(DBG_HCDV, " Control status transaction done\n");
707                    if (_urbd->status == -EINPROGRESS)
708                        _urbd->status = 0;
709                    release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
710                    break;
711            }
712            break;
713        case IFXUSB_EP_TYPE_BULK:
714            IFX_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
715            urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
716            if (urb_xfer_done)
717                release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
718            else
719            {
720                _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length;
721                _ifxhc->xfer_count = urb->actual_length;
722                _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
723                _ifxhc->data_pid_start = read_data_toggle(hc_regs);
724                _ifxhc->phase=HC_WAITING;
725                ifxhcd_hc_start(_ifxhcd, _ifxhc);
726            }
727            break;
728        case IFXUSB_EP_TYPE_INTR:
729            urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
730            
731            #ifdef __INTRINCRETRY__
732            if(!urb_xfer_done)
733            release_channel(_ifxhcd,_ifxhc,HC_XFER_INTR_NAK_RETRY);
734            else
735            #endif
736            release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
737            break;
738        case IFXUSB_EP_TYPE_ISOC:
739            #ifdef __EN_ISOC__
740                urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
741                if (urb_xfer_done)
742                {
743                    #if defined(__UNALIGNED_BUF_ADJ__)
744                    if(in_irq())
745                    {
746                        if(!epqh->tasklet_next_isoc.func)
747                        {
748                            epqh->tasklet_next_isoc.next = NULL;
749                            epqh->tasklet_next_isoc.state = 0;
750                            atomic_set( &epqh->tasklet_next_isoc.count, 0);
751                            epqh->tasklet_next_isoc.func = next_isoc_sub;
752                            epqh->tasklet_next_isoc.data = (unsigned long)_urbd;
753                        }
754                        tasklet_schedule(&epqh->tasklet_next_isoc);
755                    }
756                    else
757                    #endif
758                    {
759                        next_isoc_sub((unsigned long)_urbd);
760                    }
761                }
762                else
763                {
764                    struct usb_iso_packet_descriptor *frame_desc;
765                    frame_desc = &urb->iso_frame_desc[_urbd->isoc_frame_index];
766                    _ifxhc->xfer_len = _urbd->xfer_len - frame_desc->actual_length;
767                    _ifxhc->xfer_count = frame_desc->actual_length;
768                    _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
769                    _ifxhc->data_pid_start = read_data_toggle(hc_regs);
770                    _ifxhc->phase=HC_WAITING;
771                    ifxhcd_hc_start(_ifxhcd, _ifxhc);
772                }
773            #endif
774            break;
775    }
776}
777
778
779
780////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
781////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
782////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
783static int32_t chhltd_ctrl_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
784                                        ifxhcd_hc_t *_ifxhc,
785                                        ifxusb_hc_regs_t *_hc_regs,
786                                        ifxhcd_urbd_t *_urbd)
787{
788    hcint_data_t hcint;
789    hcint_data_t hcintmsk;
790    hctsiz_data_t hctsiz;
791
792    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
793    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
794    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
795
796    disable_hc_int(_hc_regs,ack);
797    disable_hc_int(_hc_regs,nak);
798    disable_hc_int(_hc_regs,nyet);
799
800    #ifdef __INNAKSTOP_CTRL__
801    if (_ifxhc->halt_status == HC_XFER_NAK)
802    {
803        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
804        {
805            u32 actual_length;
806            actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
807
808            if(_urbd->xfer_len && actual_length >= _urbd->xfer_len)
809            {
810                _urbd->error_count =0;
811                complete_channel(_ifxhcd, _ifxhc, _urbd);
812            }
813            else
814            {
815                _ifxhc->xfer_count =
816                _urbd->urb->actual_length = actual_length;
817                _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
818                _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
819                _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
820                _ifxhc->phase=HC_WAITING;
821                ifxhcd_hc_start(_ifxhcd, _ifxhc);
822            }
823        }
824        else
825        {
826            printk(KERN_INFO "Warning: %s() %d Invalid CTRL Phase:%d\n",__func__,__LINE__,_ifxhc->control_phase);
827            release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
828        }
829        return 1;
830    }
831    #endif
832
833    if (hcint.b.xfercomp || hcint.d32 == 0x02)
834    {
835        _urbd->error_count =0;
836        complete_channel(_ifxhcd, _ifxhc, _urbd);
837        return 1;
838    }
839    else if (hcint.b.stall)
840    {
841        _urbd->error_count =0;
842        // ZLP shortcut
843        #if 0
844        if(hctsiz.b.pktcnt==0)
845            complete_channel(_ifxhcd, _ifxhc, _urbd);
846        else
847        #endif
848        #if 0
849        if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
850            complete_channel(_ifxhcd, _ifxhc, _urbd);
851        else
852        #endif
853        {
854            if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
855                _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
856// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
857            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
858        }
859        return 1;
860    }
861    else if (hcint.b.bblerr)
862    {
863        _urbd->error_count =0;
864
865        // ZLP shortcut
866        #if 0
867        if(hctsiz.b.pktcnt==0)
868            complete_channel(_ifxhcd, _ifxhc, _urbd);
869        else
870        #endif
871        #if 0
872        if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
873            complete_channel(_ifxhcd, _ifxhc, _urbd);
874        else
875        #endif
876        {
877            if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
878                _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
879// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
880            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
881        }
882        return 1;
883    }
884    else if (hcint.b.xacterr)
885    {
886        // ZLP shortcut
887        #if 1
888        if(hctsiz.b.pktcnt==0)
889        {
890            _urbd->error_count =0;
891            complete_channel(_ifxhcd, _ifxhc, _urbd);
892        }
893        else
894        #endif
895        #if 1
896        if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
897        {
898            _urbd->error_count =0;
899            complete_channel(_ifxhcd, _ifxhc, _urbd);
900        }
901        else
902        #endif
903        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
904        {
905            #if 1
906                _urbd->error_count =0;
907                complete_channel(_ifxhcd, _ifxhc, _urbd);
908            #else
909                u32 actual_length;
910                actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
911                if(actual_length >= _urbd->xfer_len)
912                {
913                    _urbd->error_count =0;
914                    complete_channel(_ifxhcd, _ifxhc, _urbd);
915                }
916                else
917                {
918                    _urbd->error_count++;
919                    _ifxhc->xfer_count =
920                    _urbd->urb->actual_length = actual_length;
921                    _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
922                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
923                    if (_urbd->error_count >= 3)
924                    {
925                        _urbd->error_count =0;
926                        release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
927                    }
928                    else
929                    {
930                        _ifxhc->erron=1;
931                        _ifxhc->phase=HC_WAITING;
932                        ifxhcd_hc_start(_ifxhcd, _ifxhc);
933                    }
934                }
935            #endif
936        }
937        else
938        {
939            _urbd->error_count =0;
940            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
941        }
942        return 1;
943    }
944    else if(hcint.b.datatglerr )
945    {
946        #if 0
947            #if 1
948                _urbd->error_count =0;
949                complete_channel(_ifxhcd, _ifxhc, _urbd);
950            #else
951                u32 actual_length;
952                actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
953                if(actual_length>=_urbd->xfer_len)
954                {
955                    _urbd->error_count =0;
956                    complete_channel(_ifxhcd, _ifxhc, _urbd);
957                }
958                else
959                {
960                    _urbd->urb->actual_length = actual_length;
961                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
962                    _urbd->error_count =0;
963                    release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
964                }
965            #endif
966        #else
967            if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
968                _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
969// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
970            release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
971        #endif
972        return 1;
973    }
974    else if(hcint.b.frmovrun )
975    {
976        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
977            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
978// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
979        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
980        return 1;
981    }
982    else
983    {
984        _urbd->error_count =0;
985        IFX_ERROR("ERROR %s():%d invalid chhlt condition %08X/%08X %d\n",__func__,__LINE__,hcint.d32,hcintmsk.d32,_ifxhc->halt_status);
986        release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
987        return 1;
988    }
989
990    return 0;
991}
992////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
993static int32_t chhltd_ctrl_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
994                                        ifxhcd_hc_t *_ifxhc,
995                                        ifxusb_hc_regs_t *_hc_regs,
996                                        ifxhcd_urbd_t *_urbd)
997{
998    hcint_data_t hcint;
999    hcint_data_t hcintmsk;
1000    hctsiz_data_t hctsiz;
1001
1002    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1003    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1004    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1005
1006    disable_hc_int(_hc_regs,ack);
1007    disable_hc_int(_hc_regs,nak);
1008    disable_hc_int(_hc_regs,nyet);
1009
1010    #ifdef __PINGSTOP_CTRL__
1011    if (_ifxhc->halt_status == HC_XFER_NAK)
1012    {
1013        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
1014        {
1015            u32 actual_length;
1016            actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1017
1018            if(_urbd->xfer_len && actual_length >= _urbd->xfer_len)
1019            {
1020                _urbd->error_count =0;
1021                complete_channel(_ifxhcd, _ifxhc, _urbd);
1022            }
1023            else
1024            {
1025                _ifxhc->xfer_count =
1026                _urbd->urb->actual_length = actual_length;
1027                _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
1028                _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1029                _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1030                _ifxhc->phase=HC_WAITING;
1031                ifxhcd_hc_start(_ifxhcd, _ifxhc);
1032            }
1033        }
1034        else
1035        {
1036            printk(KERN_INFO "Warning: %s() %d Invalid CTRL Phase:%d\n",__func__,__LINE__,_ifxhc->control_phase);
1037            release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
1038        }
1039        return 1;
1040    }
1041    #endif
1042
1043
1044    if (hcint.b.xfercomp || hcint.d32 == 0x02)
1045    {
1046        _urbd->error_count =0;
1047        if(_ifxhc->xfer_len==0 && !hcint.b.ack && hcint.b.nak)
1048        {
1049            // Walkaround: When sending ZLP and receive NAK but also issue CMPT intr
1050            // Solution: NoSplit: Resend at next SOF
1051            // Split : Resend at next SOF with SSPLIT
1052            if(hcint.b.nyet)
1053                _ifxhc->epqh->do_ping=1;
1054
1055            _ifxhc->xfer_len = 0;
1056            _ifxhc->xfer_count = 0;
1057            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1058            _ifxhc->phase=HC_WAITING;
1059            ifxhcd_hc_start(_ifxhcd, _ifxhc);
1060        }
1061        else
1062        {
1063            if(hcint.b.nyet)
1064                _ifxhc->epqh->do_ping=1;
1065            complete_channel(_ifxhcd, _ifxhc, _urbd);
1066        }
1067        return 1;
1068    }
1069    else if (hcint.b.stall)
1070    {
1071        _urbd->error_count =0;
1072
1073        // ZLP shortcut
1074        #if 1
1075        if(hctsiz.b.pktcnt==0)
1076            complete_channel(_ifxhcd, _ifxhc, _urbd);
1077        else
1078        #endif
1079        {
1080            if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
1081            {
1082                _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1083// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
1084            }
1085            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1086        }
1087        return 1;
1088    }
1089    else if (hcint.b.xacterr)
1090    {
1091        // ZLP shortcut
1092        #if 1
1093        if(hctsiz.b.pktcnt==0)
1094        {
1095            _urbd->error_count =0;
1096            complete_channel(_ifxhcd, _ifxhc, _urbd);
1097        }
1098        else
1099        #endif
1100        if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
1101        {
1102            _urbd->error_count =0;
1103            complete_channel(_ifxhcd, _ifxhc, _urbd);
1104        }
1105        else if(_ifxhc->control_phase == IFXHCD_CONTROL_SETUP)
1106        {
1107            _urbd->error_count =0;
1108            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1109        }
1110        else if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
1111        {
1112            #if 0
1113                _urbd->error_count =0;
1114                complete_channel(_ifxhcd, _ifxhc, _urbd);
1115            #else
1116                u32 actual_length;
1117                actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1118                if(actual_length>=_urbd->xfer_len)
1119                {
1120                    _urbd->error_count =0;
1121                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1122                }
1123                else
1124                {
1125                    _urbd->error_count++;
1126                    _ifxhc->xfer_count =
1127                    _urbd->urb->actual_length = actual_length;
1128                    _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
1129                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1130                    if (_urbd->error_count >= 3)
1131                    {
1132                        _urbd->error_count =0;
1133                        release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1134                    }
1135                    else
1136                    {
1137                        _ifxhc->erron=1;
1138                        _ifxhc->phase=HC_WAITING;
1139                        _ifxhc->epqh->do_ping=1;
1140                        ifxhcd_hc_start(_ifxhcd, _ifxhc);
1141                    }
1142                }
1143            #endif
1144        }
1145        else
1146        {
1147            _urbd->error_count =0;
1148            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1149        }
1150        return 1;
1151    }
1152    else if(hcint.b.bblerr )
1153    {
1154        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
1155        {
1156            _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1157// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
1158        }
1159        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1160        return 1;
1161    }
1162    else if(hcint.b.nak || hcint.b.nyet)
1163    {
1164        #ifdef __PINGSTOP_CTRL__
1165            _urbd->error_count =0;
1166            IFX_ERROR("ERROR %s():%d invalid chhlt condition\n",__func__,__LINE__);
1167            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1168        #else
1169            // ZLP shortcut
1170            #if 1
1171            if(hctsiz.b.pktcnt==0)
1172            {
1173                _urbd->error_count =0;
1174                complete_channel(_ifxhcd, _ifxhc, _urbd);
1175            }
1176            else
1177            #endif
1178            if(_ifxhc->control_phase == IFXHCD_CONTROL_STATUS)
1179            {
1180                _urbd->error_count =0;
1181                complete_channel(_ifxhcd, _ifxhc, _urbd);
1182            }
1183            else if(_ifxhc->control_phase == IFXHCD_CONTROL_SETUP)
1184            {
1185                _urbd->error_count =0;
1186                IFX_ERROR("ERROR %s():%d invalid chhlt condition\n",__func__,__LINE__);
1187                release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1188            }
1189            else if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
1190            {
1191                #if 0
1192                    _ifxhc->epqh->do_ping=1;
1193                    _urbd->error_count =0;
1194                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1195                #else
1196                    u32 actual_length;
1197                    _ifxhc->epqh->do_ping=1;
1198                    actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1199                    if(actual_length>=_urbd->xfer_len)
1200                    {
1201                        _urbd->error_count =0;
1202                        complete_channel(_ifxhcd, _ifxhc, _urbd);
1203                    }
1204                    else
1205                    {
1206                        _ifxhc->xfer_count =
1207                        _urbd->urb->actual_length = actual_length;
1208                        _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
1209                        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1210                        _ifxhc->erron=1;
1211                        _ifxhc->epqh->do_ping=1;
1212                        _ifxhc->phase=HC_WAITING;
1213                        ifxhcd_hc_start(_ifxhcd, _ifxhc);
1214                    }
1215                #endif
1216            }
1217        #endif
1218        return 1;
1219    }
1220    else if(hcint.b.datatglerr )
1221    {
1222        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
1223        {
1224            _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1225// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
1226        }
1227        _urbd->error_count =0;
1228        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1229        return 1;
1230    }
1231    else if(hcint.b.frmovrun )
1232    {
1233        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
1234        {
1235            _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1236// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
1237        }
1238        _urbd->error_count =0;
1239        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1240        return 1;
1241    }
1242    else
1243    {
1244        _urbd->error_count =0;
1245        IFX_ERROR("ERROR %s():%d invalid chhlt condition %08X/%08X %d\n",__func__,__LINE__,hcint.d32,hcintmsk.d32,_ifxhc->halt_status);
1246        release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1247        return 1;
1248    }
1249    return 0;
1250}
1251////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1252////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1253static int32_t chhltd_bulk_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1254                                        ifxhcd_hc_t *_ifxhc,
1255                                        ifxusb_hc_regs_t *_hc_regs,
1256                                        ifxhcd_urbd_t *_urbd)
1257{
1258    hcint_data_t hcint;
1259    hcint_data_t hcintmsk;
1260    hctsiz_data_t hctsiz;
1261
1262    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1263    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1264    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1265
1266    disable_hc_int(_hc_regs,ack);
1267    disable_hc_int(_hc_regs,nak);
1268    disable_hc_int(_hc_regs,nyet);
1269
1270    #ifdef __INNAKSTOP_BULK__
1271    if(_ifxhc->halt_status == HC_XFER_NAK)
1272    {
1273        u32 actual_length;
1274        actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
1275
1276        if(
1277           (_urbd->xfer_len && actual_length>=_urbd->xfer_len)
1278           || hctsiz.b.pktcnt==0
1279           || (hctsiz.b.xfersize % _ifxhc->mps)>0
1280          )
1281        {
1282            _urbd->error_count =0;
1283            complete_channel(_ifxhcd, _ifxhc, _urbd);
1284        }
1285        else
1286        {
1287            _urbd->urb->actual_length = actual_length;
1288            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1289            _ifxhc->xfer_count = _urbd->urb->actual_length;
1290            _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1291            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1292            _ifxhc->phase=HC_WAITING;
1293            ifxhcd_hc_start(_ifxhcd, _ifxhc);
1294        }
1295        return 1;
1296    }
1297    #endif
1298
1299    if (hcint.b.xfercomp || hcint.d32 == 0x02)
1300    {
1301        _urbd->error_count =0;
1302        complete_channel(_ifxhcd, _ifxhc, _urbd);
1303        return 1;
1304    }
1305    else if (hcint.b.stall)
1306    {
1307        _urbd->error_count =0;
1308        // ZLP shortcut
1309        #if 0
1310        if(hctsiz.b.pktcnt==0)
1311            complete_channel(_ifxhcd, _ifxhc, _urbd);
1312        else
1313        #endif
1314        {
1315            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1316            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1317        }
1318        return 1;
1319    }
1320    else if (hcint.b.bblerr)
1321    {
1322        _urbd->error_count =0;
1323
1324        // ZLP shortcut
1325        #if 0
1326        if(hctsiz.b.pktcnt==0)
1327            complete_channel(_ifxhcd, _ifxhc, _urbd);
1328        else
1329        #endif
1330        {
1331            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1332            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1333        }
1334        return 1;
1335    }
1336    else if (hcint.b.xacterr)
1337    {
1338        // ZLP shortcut
1339        #if 1
1340        if(hctsiz.b.pktcnt==0)
1341        {
1342            _urbd->error_count =0;
1343            complete_channel(_ifxhcd, _ifxhc, _urbd);
1344        }
1345        else
1346        #endif
1347        {
1348            #if 0
1349                _urbd->error_count =0;
1350                complete_channel(_ifxhcd, _ifxhc, _urbd);
1351            #else
1352                u32 actual_length;
1353                actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
1354                if(actual_length >= _urbd->xfer_len)
1355                {
1356                    _urbd->error_count =0;
1357                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1358                }
1359                else
1360                {
1361                    _urbd->error_count++;
1362                    _ifxhc->xfer_count =
1363                    _urbd->urb->actual_length = actual_length;
1364                    _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
1365                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1366                    if (_urbd->error_count >= 3)
1367                    {
1368                        _urbd->error_count =0;
1369                        release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1370                    }
1371                    else
1372                    {
1373                        _ifxhc->erron=1;
1374                        _ifxhc->phase=HC_WAITING;
1375                        ifxhcd_hc_start(_ifxhcd, _ifxhc);
1376                    }
1377                }
1378            #endif
1379        }
1380        return 1;
1381    }
1382    else if(hcint.b.datatglerr )
1383    {
1384        #if 0
1385            #if 1
1386                _urbd->error_count =0;
1387                complete_channel(_ifxhcd, _ifxhc, _urbd);
1388            #else
1389                u32 actual_length;
1390                actual_length = _urbd->urb->actual_length + (_ifxhc->xfer_len - hctsiz.b.xfersize);
1391                if(actual_length >= _urbd->xfer_len)
1392                {
1393                    _urbd->error_count =0;
1394                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1395                }
1396                else
1397                {
1398                    _urbd->urb->actual_length = actual_length;
1399                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1400                    _urbd->error_count =0;
1401                    release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1402                }
1403            #endif
1404        #else
1405            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1406// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
1407            release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1408        #endif
1409        return 1;
1410    }
1411    else if(hcint.b.frmovrun )
1412    {
1413// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
1414        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1415        return 1;
1416    }
1417    else
1418    {
1419        _urbd->error_count =0;
1420        IFX_ERROR("ERROR %s():%d invalid chhlt condition %08X/%08X %d sz:%d/%d/%d/%d\n",__func__,__LINE__,hcint.d32,hcintmsk.d32,_ifxhc->halt_status , hctsiz.b.xfersize, _ifxhc->xfer_len-_ifxhc->xfer_len,_ifxhc->xfer_len,_urbd->xfer_len);
1421        release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1422        return 1;
1423    }
1424    return 0;
1425}
1426////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1427static int32_t chhltd_bulk_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1428                                        ifxhcd_hc_t *_ifxhc,
1429                                        ifxusb_hc_regs_t *_hc_regs,
1430                                        ifxhcd_urbd_t *_urbd)
1431{
1432    hcint_data_t hcint;
1433    hcint_data_t hcintmsk;
1434    hctsiz_data_t hctsiz;
1435    int out_nak_enh = 0;
1436
1437    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1438        out_nak_enh = 1;
1439
1440    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1441    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1442    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1443    disable_hc_int(_hc_regs,ack);
1444    disable_hc_int(_hc_regs,nak);
1445    disable_hc_int(_hc_regs,nyet);
1446
1447    #ifdef __PINGSTOP_BULK__
1448    if (_ifxhc->halt_status == HC_XFER_NAK)
1449    {
1450        u32 actual_length;
1451        actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1452
1453        if(_urbd->xfer_len && actual_length >= _urbd->xfer_len)
1454        {
1455            _urbd->error_count =0;
1456            complete_channel(_ifxhcd, _ifxhc, _urbd);
1457        }
1458        else
1459        {
1460            _ifxhc->xfer_count =
1461            _urbd->urb->actual_length = actual_length;
1462            _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
1463            _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1464            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1465            _ifxhc->phase=HC_WAITING;
1466            ifxhcd_hc_start(_ifxhcd, _ifxhc);
1467        }
1468        return 1;
1469    }
1470    #endif
1471
1472    if (hcint.b.xfercomp || hcint.d32 == 0x02)
1473    {
1474        _urbd->error_count =0;
1475        if(_ifxhc->xfer_len==0 && !hcint.b.ack && hcint.b.nak)
1476        {
1477            // Walkaround: When sending ZLP and receive NAK but also issue CMPT intr
1478            // Solution: NoSplit: Resend at next SOF
1479            // Split : Resend at next SOF with SSPLIT
1480            if(hcint.b.nyet)
1481                _ifxhc->epqh->do_ping=1;
1482
1483            _ifxhc->xfer_len = 0;
1484            _ifxhc->xfer_count = 0;
1485            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1486            _ifxhc->phase=HC_WAITING;
1487            ifxhcd_hc_start(_ifxhcd, _ifxhc);
1488        }
1489        else
1490        {
1491            if(hcint.b.nyet)
1492                _ifxhc->epqh->do_ping=1;
1493            complete_channel(_ifxhcd, _ifxhc, _urbd);
1494        }
1495        return 1;
1496    }
1497    else if (hcint.b.stall)
1498    {
1499        _urbd->error_count =0;
1500
1501        // ZLP shortcut
1502        #if 1
1503        if(hctsiz.b.pktcnt==0)
1504            complete_channel(_ifxhcd, _ifxhc, _urbd);
1505        else
1506        #endif
1507        {
1508            _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1509            if(_urbd->urb->actual_length>_urbd->xfer_len) _urbd->urb->actual_length=_urbd->xfer_len;
1510            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1511        }
1512        return 1;
1513    }
1514    else if (hcint.b.xacterr)
1515    {
1516        // ZLP shortcut
1517        #if 1
1518        if(hctsiz.b.pktcnt==0)
1519        {
1520            _urbd->error_count =0;
1521            complete_channel(_ifxhcd, _ifxhc, _urbd);
1522        }
1523        else
1524        #endif
1525        {
1526            #if 0
1527                _urbd->error_count =0;
1528                complete_channel(_ifxhcd, _ifxhc, _urbd);
1529            #else
1530                u32 actual_length;
1531                actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1532                if(actual_length >= _urbd->xfer_len)
1533                {
1534                    _urbd->error_count =0;
1535                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1536                }
1537                else
1538                {
1539                    _urbd->error_count++;
1540                    _ifxhc->xfer_count =
1541                    _urbd->urb->actual_length = actual_length;
1542                    _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
1543                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1544                    if (_urbd->error_count >= 3)
1545                    {
1546                        _urbd->error_count =0;
1547                        release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1548                    }
1549                    else
1550                    {
1551                        _ifxhc->erron=1;
1552                        _ifxhc->phase=HC_WAITING;
1553                        _ifxhc->epqh->do_ping=1;
1554                        ifxhcd_hc_start(_ifxhcd, _ifxhc);
1555                    }
1556                }
1557            #endif
1558        }
1559        return 1;
1560    }
1561    else if(hcint.b.bblerr )
1562    {
1563        _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1564        if(_urbd->urb->actual_length>_urbd->xfer_len) _urbd->urb->actual_length=_urbd->xfer_len;
1565        IFX_ERROR("ERROR %s():%d invalid packet babble\n",__func__,__LINE__);
1566        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1567        return 1;
1568    }
1569    else if(hcint.b.nak || hcint.b.nyet)
1570    {
1571        #ifdef __PINGSTOP_BULK__
1572            _urbd->error_count =0;
1573            IFX_ERROR("ERROR %s():%d invalid chhlt condition\n",__func__,__LINE__);
1574            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1575        #else
1576            // ZLP shortcut
1577            #if 1
1578            if(hctsiz.b.pktcnt==0)
1579            {
1580                _urbd->error_count =0;
1581                complete_channel(_ifxhcd, _ifxhc, _urbd);
1582            }
1583            else
1584            #endif
1585            {
1586                #if 0
1587                    _ifxhc->epqh->do_ping=1;
1588                    _urbd->error_count =0;
1589                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1590                #else
1591                    u32 actual_length;
1592                    _ifxhc->epqh->do_ping=1;
1593                    actual_length = _urbd->urb->actual_length + ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1594                    if(actual_length>=_urbd->xfer_len)
1595                    {
1596                        _urbd->error_count =0;
1597                        complete_channel(_ifxhcd, _ifxhc, _urbd);
1598                    }
1599                    else
1600                    {
1601                        _ifxhc->xfer_count =
1602                        _urbd->urb->actual_length = actual_length;
1603                        _ifxhc->xfer_len = _urbd->xfer_len - actual_length;
1604                        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1605                        _ifxhc->erron=1;
1606                        _ifxhc->epqh->do_ping=1;
1607                        _ifxhc->phase=HC_WAITING;
1608                        ifxhcd_hc_start(_ifxhcd, _ifxhc);
1609                    }
1610                #endif
1611            }
1612        #endif
1613        return 1;
1614    }
1615    else if(hcint.b.datatglerr )
1616    {
1617        _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1618// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
1619        _urbd->error_count =0;
1620        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1621        return 1;
1622    }
1623    else if(hcint.b.frmovrun )
1624    {
1625        _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1626// if( _urbd->urb->actual_length > _ifxhc->xfer_len) _urbd->urb->actual_length = _urbd->xfer_len;
1627        _urbd->error_count =0;
1628        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1629        return 1;
1630    }
1631    else
1632    {
1633        _urbd->error_count =0;
1634        IFX_ERROR("ERROR %s():%d invalid chhlt condition %08X/%08X %d\n",__func__,__LINE__,hcint.d32,hcintmsk.d32,_ifxhc->halt_status);
1635        release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1636        return 1;
1637    }
1638    return 0;
1639}
1640////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1641////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1642static int32_t chhltd_intr_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1643                                    ifxhcd_hc_t *_ifxhc,
1644                                    ifxusb_hc_regs_t *_hc_regs,
1645                                    ifxhcd_urbd_t *_urbd)
1646{
1647    hcint_data_t hcint;
1648    hcint_data_t hcintmsk;
1649    hctsiz_data_t hctsiz;
1650
1651    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1652    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1653    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1654    disable_hc_int(_hc_regs,ack);
1655    disable_hc_int(_hc_regs,nak);
1656    disable_hc_int(_hc_regs,nyet);
1657
1658    if (hcint.b.xfercomp || hcint.d32 == 0x02)
1659    {
1660        _urbd->error_count =0;
1661        //restart INTR immediately
1662        complete_channel(_ifxhcd, _ifxhc, _urbd);
1663        return 1;
1664    }
1665    else if (hcint.b.stall)
1666    {
1667        _urbd->error_count =0;
1668
1669        // Don't care shortcut
1670        #if 0
1671        if(hctsiz.b.pktcnt==0)
1672            complete_channel(_ifxhcd, _ifxhc, _urbd);
1673        else
1674        #endif
1675        {
1676            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1677            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1678        }
1679        return 1;
1680    }
1681    else if (hcint.b.bblerr)
1682    {
1683        _urbd->error_count =0;
1684
1685        // Don't care shortcut
1686        #if 0
1687        if(hctsiz.b.pktcnt==0)
1688            complete_channel(_ifxhcd, _ifxhc, _urbd);
1689        else
1690        #endif
1691        {
1692            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1693            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1694        }
1695        return 1;
1696    }
1697    else if (hcint.b.datatglerr || hcint.b.frmovrun)
1698    {
1699        _urbd->error_count =0;
1700        //restart INTR immediately
1701        complete_channel(_ifxhcd, _ifxhc, _urbd);
1702        return 1;
1703    }
1704    else if (hcint.b.xacterr)
1705    {
1706        // ZLP shortcut
1707        #if 1
1708        if(hctsiz.b.pktcnt==0)
1709        {
1710            _urbd->error_count =0;
1711            complete_channel(_ifxhcd, _ifxhc, _urbd);
1712        }
1713        else
1714        #endif
1715        {
1716            _urbd->error_count++;
1717            if(_urbd->error_count>=3)
1718            {
1719                _urbd->error_count =0;
1720                release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1721            }
1722            else
1723            {
1724                _ifxhc->phase=HC_WAITING;
1725                ifxhcd_hc_start(_ifxhcd, _ifxhc);
1726            }
1727        }
1728        return 1;
1729    }
1730    else if(hcint.b.nyet )
1731    {
1732        return 1;
1733    }
1734    else if (hcint.b.nak)
1735    {
1736        
1737        #ifdef __INTRNAKRETRY__
1738        if(hctsiz.b.pktcnt)
1739        {
1740            release_channel(_ifxhcd, _ifxhc, HC_XFER_INTR_NAK_RETRY);
1741            return 1;
1742        }
1743        #endif
1744        _urbd->error_count =0;
1745        //restart INTR immediately
1746        complete_channel(_ifxhcd, _ifxhc, _urbd);
1747        return 1;
1748    }
1749    else
1750    {
1751        _urbd->error_count =0;
1752        //restart INTR immediately
1753        #if 0
1754        if(hctsiz.b.pktcnt>0)
1755        {
1756            // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
1757            _ifxhc->phase=HC_WAITING;
1758            ifxhcd_hc_start(_ifxhcd, _ifxhc);
1759        }
1760        else
1761        #endif
1762        {
1763            complete_channel(_ifxhcd, _ifxhc, _urbd);
1764        }
1765        return 1;
1766    }
1767
1768    return 0;
1769}
1770////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1771static int32_t chhltd_intr_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1772                                    ifxhcd_hc_t *_ifxhc,
1773                                    ifxusb_hc_regs_t *_hc_regs,
1774                                    ifxhcd_urbd_t *_urbd)
1775{
1776    hcint_data_t hcint;
1777    hcint_data_t hcintmsk;
1778    hctsiz_data_t hctsiz;
1779    int out_nak_enh = 0;
1780
1781    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1782        out_nak_enh = 1;
1783
1784    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1785    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1786    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1787
1788    if (hcint.b.xfercomp || hcint.d32 == 0x02)
1789    {
1790        disable_hc_int(_hc_regs,ack);
1791        disable_hc_int(_hc_regs,nak);
1792        disable_hc_int(_hc_regs,nyet);
1793        _urbd->error_count =0;
1794        //restart INTR immediately
1795        complete_channel(_ifxhcd, _ifxhc, _urbd);
1796        return 1;
1797    }
1798    else if (hcint.b.stall)
1799    {
1800        disable_hc_int(_hc_regs,ack);
1801        disable_hc_int(_hc_regs,nyet);
1802        disable_hc_int(_hc_regs,nak);
1803        _urbd->error_count =0;
1804
1805        // Don't care shortcut
1806        #if 0
1807        if(hctsiz.b.pktcnt==0)
1808            complete_channel(_ifxhcd, _ifxhc, _urbd);
1809        else
1810        #endif
1811        {
1812            if(_ifxhc->xfer_len!=0)// !_ifxhc->is_in
1813                _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1814            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1815        }
1816        return 1;
1817    }
1818    else if(hcint.b.nak || hcint.b.frmovrun )
1819    {
1820        disable_hc_int(_hc_regs,ack);
1821        disable_hc_int(_hc_regs,nyet);
1822        disable_hc_int(_hc_regs,nak);
1823        _urbd->error_count =0;
1824        //restart INTR immediately
1825        complete_channel(_ifxhcd, _ifxhc, _urbd);
1826        return 1;
1827    }
1828    else if(hcint.b.xacterr )
1829    {
1830        // ZLP shortcut
1831        #if 1
1832        if(hctsiz.b.pktcnt==0)
1833        {
1834            _urbd->error_count =0;
1835            complete_channel(_ifxhcd, _ifxhc, _urbd);
1836        }
1837        else
1838        #endif
1839        {
1840            _urbd->error_count++;
1841            if(_urbd->error_count>=3)
1842            {
1843                _urbd->error_count =0;
1844                release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1845            }
1846            else
1847            {
1848                _ifxhc->phase=HC_WAITING;
1849                ifxhcd_hc_start(_ifxhcd, _ifxhc);
1850            }
1851        }
1852        return 1;
1853    }
1854    else if(hcint.b.bblerr )
1855    {
1856        _urbd->error_count =0;
1857        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1858        return 1;
1859    }
1860    else if(hcint.b.datatglerr )
1861    {
1862        _urbd->error_count =0;
1863        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1864        return 1;
1865    }
1866    return 0;
1867}
1868////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1869////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1870static int32_t chhltd_isoc_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1871                                    ifxhcd_hc_t *_ifxhc,
1872                                    ifxusb_hc_regs_t *_hc_regs,
1873                                    ifxhcd_urbd_t *_urbd)
1874{
1875    #ifdef __EN_ISOC__
1876        hcint_data_t hcint;
1877        hcint_data_t hcintmsk;
1878        hctsiz_data_t hctsiz;
1879
1880        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1881        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1882        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1883
1884        if (hcint.b.xfercomp || hcint.b.frmovrun || hcint.d32 == 0x02)
1885        {
1886            _urbd->error_count=0;
1887            disable_hc_int(_hc_regs,ack);
1888            disable_hc_int(_hc_regs,nak);
1889            disable_hc_int(_hc_regs,nyet);
1890            if (hcint.b.xfercomp)
1891                complete_channel(_ifxhcd, _ifxhc, _urbd);
1892            else
1893                release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1894        }
1895        else if (hcint.b.xacterr || hcint.b.bblerr)
1896        {
1897            #ifndef VR9Skip
1898                if(hctsiz.b.pktcnt==0)
1899                {
1900                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1901                }
1902                else
1903                {
1904                    _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1905                    _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1906                    _ifxhc->xfer_count = _urbd->urb->actual_length;
1907                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1908                    _urbd->error_count++;
1909                    if(_urbd->error_count>=3)
1910                    {
1911                        _urbd->error_count=0;
1912                        if (hcint.b.bblerr)
1913                            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1914                        else if (hcint.b.xacterr)
1915                            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1916                    }
1917                    else
1918                    {
1919                        enable_hc_int(_hc_regs,ack);
1920                        enable_hc_int(_hc_regs,nak);
1921                        enable_hc_int(_hc_regs,nyet);
1922                        _ifxhc->phase=HC_WAITING;
1923                        ifxhcd_hc_start(_ifxhcd, _ifxhc);
1924                    }
1925                }
1926            #endif
1927        }
1928        else if(hcint.b.datatglerr )
1929        {
1930            return 1;
1931        }
1932        else if(hcint.b.stall )
1933        {
1934            return 1;
1935        }
1936    #endif
1937    return 0;
1938}
1939////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1940static int32_t chhltd_isoc_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1941                                    ifxhcd_hc_t *_ifxhc,
1942                                    ifxusb_hc_regs_t *_hc_regs,
1943                                    ifxhcd_urbd_t *_urbd)
1944{
1945    #ifdef __EN_ISOC__
1946        hcint_data_t hcint;
1947        hcint_data_t hcintmsk;
1948        hctsiz_data_t hctsiz;
1949        int out_nak_enh = 0;
1950
1951        if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1952            out_nak_enh = 1;
1953
1954        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1955        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1956        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1957
1958        if (hcint.b.xfercomp || hcint.d32 == 0x02)
1959        {
1960            _urbd->error_count=0;
1961            disable_hc_int(_hc_regs,ack);
1962            disable_hc_int(_hc_regs,nak);
1963            disable_hc_int(_hc_regs,nyet);
1964            complete_channel(_ifxhcd, _ifxhc, _urbd);
1965            return 1;
1966        }
1967        else if (hcint.b.frmovrun)
1968        {
1969            #ifndef VR9Skip
1970                _urbd->error_count=0;
1971                disable_hc_int(_hc_regs,ack);
1972                disable_hc_int(_hc_regs,nak);
1973                disable_hc_int(_hc_regs,nyet);
1974                release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1975            #endif
1976        }
1977        else if(hcint.b.datatglerr )
1978        {
1979            return 1;
1980        }
1981        else if(hcint.b.bblerr )
1982        {
1983            #ifndef VR9Skip
1984                if(hctsiz.b.pktcnt==0)
1985                {
1986                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1987                }
1988                else
1989                {
1990                    _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1991                    _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1992                    _ifxhc->xfer_count = _urbd->urb->actual_length;
1993                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1994                    _urbd->error_count++;
1995                    if(_urbd->error_count>=3)
1996                    {
1997                        _urbd->error_count=0;
1998                        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1999                    }
2000                    else
2001                    {
2002                        enable_hc_int(_hc_regs,ack);
2003                        enable_hc_int(_hc_regs,nak);
2004                        enable_hc_int(_hc_regs,nyet);
2005                        _ifxhc->phase=HC_WAITING;
2006                        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2007                    }
2008                }
2009            #endif
2010        }
2011        else if(hcint.b.xacterr )
2012        {
2013            if(hctsiz.b.pktcnt==0)
2014            {
2015                complete_channel(_ifxhcd, _ifxhc, _urbd);
2016                return 1;
2017            }
2018            _urbd->error_count++;
2019            if(_urbd->error_count>=3)
2020            {
2021                _urbd->error_count=0;
2022                release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2023            }
2024            else
2025            {
2026                _ifxhc->phase=HC_WAITING;
2027                ifxhcd_hc_start(_ifxhcd, _ifxhc);
2028            }
2029            return 1;
2030        }
2031        else if(hcint.b.stall )
2032        {
2033            return 1;
2034        }
2035    #endif
2036    return 0;
2037}
2038////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2039////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2040////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2041static int32_t chhltd_ctrl_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2042                                      ifxhcd_hc_t *_ifxhc,
2043                                      ifxusb_hc_regs_t *_hc_regs,
2044                                      ifxhcd_urbd_t *_urbd)
2045{
2046    hcint_data_t hcint;
2047    hcint_data_t hcintmsk;
2048    hctsiz_data_t hctsiz;
2049
2050    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2051    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2052    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2053
2054    disable_hc_int(_hc_regs,ack);
2055    disable_hc_int(_hc_regs,nak);
2056    disable_hc_int(_hc_regs,nyet);
2057
2058    if (hcint.b.ack)
2059    {
2060        _urbd->error_count=0;
2061        _ifxhc->split=2;
2062        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
2063        _ifxhc->phase=HC_WAITING;
2064        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2065        return 1;
2066    }
2067    else if (hcint.b.nak)
2068    {
2069        _urbd->error_count = 0;
2070        _ifxhc->phase=HC_WAITING;
2071        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2072        return 1;
2073    }
2074    else if (hcint.b.xacterr)
2075    {
2076        _urbd->error_count++;
2077        if(_urbd->error_count>=3)
2078        {
2079            _urbd->error_count=0;
2080            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2081        }
2082        else
2083        {
2084            _ifxhc->phase=HC_WAITING;
2085            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2086        }
2087        return 1;
2088    }
2089    else if(hcint.b.bblerr )
2090    {
2091        _urbd->error_count =0;
2092        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2093        return 1;
2094    }
2095    else if(hcint.b.stall )
2096    {
2097        _urbd->error_count =0;
2098        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2099        return 1;
2100    }
2101    else if(hcint.b.datatglerr )
2102    {
2103        _urbd->error_count =0;
2104        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
2105        return 1;
2106    }
2107    else if(hcint.b.frmovrun )
2108    {
2109        _urbd->error_count =0;
2110        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2111        return 1;
2112    }
2113    else if(hcint.b.nyet )
2114    {
2115    }
2116    else if(hcint.b.xfercomp )
2117    {
2118    }
2119    return 0;
2120}
2121////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2122static int32_t chhltd_ctrl_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2123                                      ifxhcd_hc_t *_ifxhc,
2124                                      ifxusb_hc_regs_t *_hc_regs,
2125                                      ifxhcd_urbd_t *_urbd)
2126{
2127    hcint_data_t hcint;
2128    hcint_data_t hcintmsk;
2129    hctsiz_data_t hctsiz;
2130    int out_nak_enh = 0;
2131
2132    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2133        out_nak_enh = 1;
2134
2135    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2136    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2137    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2138    disable_hc_int(_hc_regs,ack);
2139    disable_hc_int(_hc_regs,nak);
2140    disable_hc_int(_hc_regs,nyet);
2141
2142    if (hcint.b.ack )
2143    {
2144        _urbd->error_count=0;
2145        if (_ifxhc->control_phase != IFXHCD_CONTROL_SETUP)
2146            _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
2147        _ifxhc->split=2;
2148        _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
2149        _ifxhc->phase=HC_WAITING;
2150        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2151        return 1;
2152    }
2153    else if(hcint.b.nyet)
2154    {
2155        _urbd->error_count=0;
2156        if (_ifxhc->control_phase != IFXHCD_CONTROL_SETUP)
2157            _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
2158        _ifxhc->split=2;
2159        _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
2160        _ifxhc->phase=HC_WAITING;
2161        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2162        return 1;
2163    }
2164    else if(hcint.b.nak )
2165    {
2166        _urbd->error_count =0;
2167        _ifxhc->phase=HC_WAITING;
2168        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2169        return 1;
2170    }
2171    else if(hcint.b.xacterr )
2172    {
2173        _urbd->error_count++;
2174        if(_urbd->error_count>=3)
2175        {
2176            _urbd->error_count=0;
2177            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2178        }
2179        else
2180        {
2181            _ifxhc->phase=HC_WAITING;
2182            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2183        }
2184        return 1;
2185    }
2186    else if(hcint.b.datatglerr )
2187    {
2188        _urbd->error_count =0;
2189        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
2190        return 1;
2191    }
2192    else if(hcint.b.bblerr )
2193    {
2194        _urbd->error_count =0;
2195        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2196        return 1;
2197    }
2198    else if(hcint.b.stall )
2199    {
2200        _urbd->error_count =0;
2201        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2202        return 1;
2203    }
2204    else if(hcint.b.frmovrun )
2205    {
2206        _urbd->error_count =0;
2207        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2208        return 1;
2209    }
2210    else if(hcint.b.xfercomp )
2211    {
2212        printk(KERN_INFO "Warning: %s() %d CTRL OUT SPLIT1 COMPLETE\n",__func__,__LINE__);
2213    }
2214    return 0;
2215}
2216////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2217////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2218static int32_t chhltd_bulk_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2219                                      ifxhcd_hc_t *_ifxhc,
2220                                      ifxusb_hc_regs_t *_hc_regs,
2221                                      ifxhcd_urbd_t *_urbd)
2222{
2223    hcint_data_t hcint;
2224    hcint_data_t hcintmsk;
2225    hctsiz_data_t hctsiz;
2226
2227    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2228    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2229    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2230
2231    disable_hc_int(_hc_regs,ack);
2232    disable_hc_int(_hc_regs,nak);
2233    disable_hc_int(_hc_regs,nyet);
2234
2235    if (hcint.b.ack)
2236    {
2237        _urbd->error_count=0;
2238        _ifxhc->split=2;
2239        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
2240        _ifxhc->phase=HC_WAITING;
2241        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2242        return 1;
2243    }
2244    else if (hcint.b.nak)
2245    {
2246        _urbd->error_count = 0;
2247        _ifxhc->phase=HC_WAITING;
2248        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2249        return 1;
2250    }
2251    else if (hcint.b.xacterr)
2252    {
2253        _urbd->error_count++;
2254        if(_urbd->error_count>=3)
2255        {
2256            _urbd->error_count=0;
2257            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2258        }
2259        else
2260        {
2261            _ifxhc->phase=HC_WAITING;
2262            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2263        }
2264        return 1;
2265    }
2266    else if(hcint.b.bblerr )
2267    {
2268        _urbd->error_count =0;
2269        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2270        return 1;
2271    }
2272    else if(hcint.b.stall )
2273    {
2274        _urbd->error_count =0;
2275        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2276        return 1;
2277    }
2278    else if(hcint.b.datatglerr )
2279    {
2280        _urbd->error_count =0;
2281        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
2282        return 1;
2283    }
2284    else if(hcint.b.frmovrun )
2285    {
2286        _urbd->error_count =0;
2287        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2288        return 1;
2289    }
2290    else if(hcint.b.nyet )
2291    {
2292    }
2293    else if(hcint.b.xfercomp )
2294    {
2295    }
2296    return 0;
2297}
2298////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2299static int32_t chhltd_bulk_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2300                                      ifxhcd_hc_t *_ifxhc,
2301                                      ifxusb_hc_regs_t *_hc_regs,
2302                                      ifxhcd_urbd_t *_urbd)
2303{
2304    hcint_data_t hcint;
2305    hcint_data_t hcintmsk;
2306    hctsiz_data_t hctsiz;
2307    int out_nak_enh = 0;
2308
2309    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2310        out_nak_enh = 1;
2311
2312    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2313    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2314    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2315    disable_hc_int(_hc_regs,ack);
2316    disable_hc_int(_hc_regs,nak);
2317    disable_hc_int(_hc_regs,nyet);
2318
2319    if (hcint.b.ack )
2320    {
2321        _urbd->error_count=0;
2322        _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
2323        _ifxhc->split=2;
2324        _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
2325        _ifxhc->phase=HC_WAITING;
2326        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2327        return 1;
2328    }
2329    else if(hcint.b.nyet)
2330    {
2331        _urbd->error_count=0;
2332        _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
2333        _ifxhc->split=2;
2334        _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
2335        _ifxhc->phase=HC_WAITING;
2336        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2337        return 1;
2338    }
2339    else if(hcint.b.nak )
2340    {
2341        _urbd->error_count =0;
2342        _ifxhc->phase=HC_WAITING;
2343        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2344        return 1;
2345    }
2346    else if(hcint.b.xacterr )
2347    {
2348        _urbd->error_count++;
2349        if(_urbd->error_count>=3)
2350        {
2351            _urbd->error_count=0;
2352            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2353        }
2354        else
2355        {
2356            _ifxhc->phase=HC_WAITING;
2357            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2358        }
2359        return 1;
2360    }
2361    else if(hcint.b.datatglerr )
2362    {
2363        _urbd->error_count =0;
2364        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
2365        return 1;
2366    }
2367    else if(hcint.b.bblerr )
2368    {
2369        _urbd->error_count =0;
2370        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2371        return 1;
2372    }
2373    else if(hcint.b.stall )
2374    {
2375        _urbd->error_count =0;
2376        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2377        return 1;
2378    }
2379    else if(hcint.b.frmovrun )
2380    {
2381        _urbd->error_count =0;
2382        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2383        return 1;
2384    }
2385    else if(hcint.b.xfercomp )
2386    {
2387        printk(KERN_INFO "Warning: %s() %d BULK OUT SPLIT1 COMPLETE\n",__func__,__LINE__);
2388    }
2389    return 0;
2390}
2391////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2392////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2393static int32_t chhltd_intr_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2394                                  ifxhcd_hc_t *_ifxhc,
2395                                  ifxusb_hc_regs_t *_hc_regs,
2396                                  ifxhcd_urbd_t *_urbd)
2397{
2398    hcint_data_t hcint;
2399    hcint_data_t hcintmsk;
2400    hctsiz_data_t hctsiz;
2401
2402    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2403    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2404    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2405
2406    disable_hc_int(_hc_regs,ack);
2407    disable_hc_int(_hc_regs,nak);
2408    disable_hc_int(_hc_regs,nyet);
2409
2410    if (hcint.b.ack)
2411    {
2412        _urbd->error_count=0;
2413        _ifxhc->split=2;
2414        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
2415        _ifxhc->phase=HC_WAITING;
2416        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2417        return 1;
2418    }
2419    else if(hcint.b.nak)
2420    {
2421        _urbd->error_count=0;
2422        _ifxhc->phase=HC_WAITING;
2423        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2424        return 1;
2425    }
2426    else if(hcint.b.xacterr)
2427    {
2428        hcchar_data_t hcchar;
2429        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
2430        _urbd->error_count=hcchar.b.multicnt;
2431        if(_urbd->error_count>=3)
2432        {
2433            _urbd->error_count=0;
2434            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2435        }
2436        else
2437        {
2438            _ifxhc->phase=HC_WAITING;
2439            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2440        }
2441        return 1;
2442    }
2443    else if(hcint.b.stall )
2444    {
2445        _urbd->error_count =0;
2446        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2447        return 1;
2448    }
2449    else if(hcint.b.bblerr )
2450    {
2451        _urbd->error_count =0;
2452        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2453        return 1;
2454    }
2455    else if(hcint.b.frmovrun )
2456    {
2457        _ifxhc->phase=HC_WAITING;
2458        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2459        return 1;
2460    }
2461    else if(hcint.b.datatglerr )
2462    {
2463        _urbd->error_count =0;
2464        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
2465        return 1;
2466    }
2467    else if(hcint.b.xfercomp )
2468    {
2469    }
2470    return 0;
2471}
2472////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2473static int32_t chhltd_intr_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2474                                  ifxhcd_hc_t *_ifxhc,
2475                                  ifxusb_hc_regs_t *_hc_regs,
2476                                  ifxhcd_urbd_t *_urbd)
2477{
2478    hcint_data_t hcint;
2479    hcint_data_t hcintmsk;
2480    hctsiz_data_t hctsiz;
2481    int out_nak_enh = 0;
2482
2483    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2484        out_nak_enh = 1;
2485
2486    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2487    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2488    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2489
2490    disable_hc_int(_hc_regs,ack);
2491    disable_hc_int(_hc_regs,nak);
2492    disable_hc_int(_hc_regs,nyet);
2493
2494    if (hcint.b.ack )
2495    {
2496        _urbd->error_count=0;
2497        _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
2498        _ifxhc->split=2;
2499        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
2500        _ifxhc->phase=HC_WAITING;
2501        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2502        return 1;
2503    }
2504    else if(hcint.b.nyet)
2505    {
2506        _urbd->error_count=0;
2507        _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
2508        _ifxhc->split=2;
2509        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
2510        _ifxhc->phase=HC_WAITING;
2511        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2512        return 1;
2513    }
2514    else if(hcint.b.nak )
2515    {
2516        _urbd->error_count =0;
2517        _ifxhc->phase=HC_WAITING;
2518        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2519        return 1;
2520    }
2521    else if(hcint.b.frmovrun )
2522    {
2523        _urbd->error_count =0;
2524        _ifxhc->phase=HC_WAITING;
2525        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2526        return 1;
2527    }
2528    else if(hcint.b.xacterr )
2529    {
2530        hcchar_data_t hcchar;
2531        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
2532        _urbd->error_count=hcchar.b.multicnt;
2533        if(_urbd->error_count>=3)
2534        {
2535            _urbd->error_count=0;
2536            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2537        }
2538        else
2539        {
2540            enable_hc_int(_hc_regs,ack);
2541            enable_hc_int(_hc_regs,nak);
2542            enable_hc_int(_hc_regs,nyet);
2543            _ifxhc->phase=HC_WAITING;
2544            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2545        }
2546        return 1;
2547    }
2548    else if(hcint.b.datatglerr )
2549    {
2550        _urbd->error_count =0;
2551        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
2552        return 1;
2553    }
2554    else if(hcint.b.bblerr )
2555    {
2556        _urbd->error_count =0;
2557        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2558        return 1;
2559    }
2560    else if(hcint.b.stall )
2561    {
2562        _urbd->error_count =0;
2563        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2564        return 1;
2565    }
2566    else if(hcint.b.xfercomp )
2567    {
2568    }
2569    return 0;
2570}
2571////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2572////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2573static int32_t chhltd_isoc_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2574                                   ifxhcd_hc_t *_ifxhc,
2575                                   ifxusb_hc_regs_t *_hc_regs,
2576                                   ifxhcd_urbd_t *_urbd)
2577{
2578    #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
2579        hcint_data_t hcint;
2580        hcint_data_t hcintmsk;
2581        hctsiz_data_t hctsiz;
2582
2583        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2584        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2585        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2586        if (hcint.b.ack )
2587        {
2588            Do Complete Split
2589        }
2590        else if(hcint.b.frmovrun )
2591        {
2592            Rewind Buffer Pointers
2593            Retry Start Split (in next b_interval ¡V 1 uF)
2594        }
2595        else if(hcint.b.datatglerr )
2596        {
2597            //warning
2598        }
2599        else if(hcint.b.bblerr )
2600        {
2601            //warning
2602        }
2603        else if(hcint.b.xacterr )
2604        {
2605            //warning
2606        }
2607        else if(hcint.b.stall )
2608        {
2609            //warning
2610        }
2611        else if(hcint.b.nak )
2612        {
2613            //warning
2614        }
2615        else if(hcint.b.xfercomp )
2616        {
2617            //warning
2618        }
2619        else if(hcint.b.nyet)
2620        {
2621            //warning
2622        }
2623    #endif
2624    return 0;
2625}
2626////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2627static int32_t chhltd_isoc_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2628                                   ifxhcd_hc_t *_ifxhc,
2629                                   ifxusb_hc_regs_t *_hc_regs,
2630                                   ifxhcd_urbd_t *_urbd)
2631{
2632    #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
2633        hcint_data_t hcint;
2634        hcint_data_t hcintmsk;
2635        hctsiz_data_t hctsiz;
2636        int out_nak_enh = 0;
2637
2638        if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2639            out_nak_enh = 1;
2640
2641        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2642        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2643        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2644        if (hcint.b.ack )
2645        {
2646            //Do Next Start Split (in next b_interval ¡V 1 uF)
2647        }
2648        else if(hcint.b.frmovrun )
2649        {
2650            //Do Next Transaction in next frame.
2651        }
2652        else if(hcint.b.datatglerr )
2653        {
2654            //warning
2655        }
2656        else if(hcint.b.bblerr )
2657        {
2658            //warning
2659        }
2660        else if(hcint.b.xacterr )
2661        {
2662            //warning
2663        }
2664        else if(hcint.b.stall )
2665        {
2666            //warning
2667        }
2668        else if(hcint.b.nak )
2669        {
2670            //warning
2671        }
2672        else if(hcint.b.xfercomp )
2673        {
2674            //warning
2675        }
2676        else if(hcint.b.nyet)
2677        {
2678            //warning
2679        }
2680    #endif
2681    return 0;
2682}
2683////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2684////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2685////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2686static int32_t chhltd_ctrl_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
2687                                      ifxhcd_hc_t *_ifxhc,
2688                                      ifxusb_hc_regs_t *_hc_regs,
2689                                      ifxhcd_urbd_t *_urbd)
2690{
2691    hcint_data_t hcint;
2692    hcint_data_t hcintmsk;
2693    hctsiz_data_t hctsiz;
2694
2695    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2696    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2697    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2698    disable_hc_int(_hc_regs,ack);
2699    disable_hc_int(_hc_regs,nak);
2700    disable_hc_int(_hc_regs,nyet);
2701
2702    if (hcint.b.xfercomp)
2703    {
2704        _urbd->error_count =0;
2705        _ifxhc->split=1;
2706        complete_channel(_ifxhcd, _ifxhc, _urbd);
2707        return 1;
2708    }
2709    else if (hcint.b.nak)
2710    {
2711        _ifxhc->split = 1;
2712        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
2713        {
2714            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2715            _ifxhc->xfer_count = _urbd->urb->actual_length;
2716        }
2717        _ifxhc->phase=HC_WAITING;
2718        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2719        return 1;
2720    }
2721    else if(hcint.b.nyet)
2722    {
2723        _urbd->error_count=0;
2724        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2725        _ifxhc->phase=HC_WAITING;
2726        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2727        return 1;
2728    }
2729    else if(hcint.b.stall || hcint.b.bblerr )
2730    {
2731        _urbd->error_count=0;
2732        if (hcint.b.stall)
2733            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2734        else if(hcint.b.bblerr )
2735            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2736        return 1;
2737    }
2738    else if(hcint.b.xacterr )
2739    {
2740        _urbd->error_count++;
2741        if(_urbd->error_count>=3)
2742        {
2743            _urbd->error_count=0;
2744            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2745        }
2746        else
2747        {
2748            _ifxhc->split=1;
2749            if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
2750            {
2751                _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2752                _ifxhc->xfer_count = _urbd->urb->actual_length;
2753            }
2754            _ifxhc->phase=HC_WAITING;
2755            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2756        }
2757        return 1;
2758    }
2759    else if(hcint.b.datatglerr )
2760    {
2761        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
2762            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
2763        else
2764            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2765        _ifxhc->split=1;
2766        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
2767        {
2768            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2769            _ifxhc->xfer_count = _urbd->urb->actual_length;
2770        }
2771        _ifxhc->phase=HC_WAITING;
2772        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2773        return 1;
2774    }
2775    else if(hcint.b.frmovrun )
2776    {
2777        _urbd->error_count=0;
2778        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2779        return 1;
2780    }
2781    return 0;
2782}
2783////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2784static int32_t chhltd_ctrl_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
2785                                      ifxhcd_hc_t *_ifxhc,
2786                                      ifxusb_hc_regs_t *_hc_regs,
2787                                      ifxhcd_urbd_t *_urbd)
2788{
2789    hcint_data_t hcint;
2790    hcint_data_t hcintmsk;
2791    hctsiz_data_t hctsiz;
2792    int out_nak_enh = 0;
2793
2794    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2795        out_nak_enh = 1;
2796
2797    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2798    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2799    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2800    disable_hc_int(_hc_regs,ack);
2801    disable_hc_int(_hc_regs,nak);
2802    disable_hc_int(_hc_regs,nyet);
2803
2804    if(hcint.b.xfercomp )
2805    {
2806        _urbd->error_count=0;
2807        _ifxhc->split=1;
2808        #if 0
2809        if(_ifxhc->xfer_len==0 && !hcint.b.ack && (hcint.b.nak || hcint.b.nyet))
2810        {
2811            // Walkaround: When sending ZLP and receive NYEY or NAK but also issue CMPT intr
2812            // Solution: NoSplit: Resend at next SOF
2813            // Split : Resend at next SOF with SSPLIT
2814            _ifxhc->xfer_len = 0;
2815            _ifxhc->xfer_count = 0;
2816            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2817            _ifxhc->phase=HC_WAITING;
2818            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2819        }
2820        else
2821        #endif
2822        {
2823            complete_channel(_ifxhcd, _ifxhc, _urbd);
2824        }
2825        return 1;
2826    }
2827    else if(hcint.b.nak )
2828    {
2829        _ifxhc->split = 1;
2830        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
2831        {
2832            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2833            _ifxhc->xfer_count = _urbd->urb->actual_length;
2834        }
2835        _ifxhc->phase=HC_WAITING;
2836        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2837        return 1;
2838    }
2839    else if(hcint.b.nyet)
2840    {
2841        //Retry Complete Split
2842        // Issue Retry instantly on next SOF, without gothrough process_channels
2843        _urbd->error_count=0;
2844        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2845        _ifxhc->phase=HC_WAITING;
2846        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2847        return 1;
2848    }
2849    else if(hcint.b.stall )
2850    {
2851        _urbd->error_count=0;
2852        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2853        return 1;
2854    }
2855    else if(hcint.b.xacterr )
2856    {
2857        _urbd->error_count++;
2858        if(_urbd->error_count>=3)
2859        {
2860            _urbd->error_count=0;
2861            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2862        }
2863        else
2864        {
2865            _ifxhc->split=1;
2866            if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
2867            {
2868                _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2869                _ifxhc->xfer_count = _urbd->urb->actual_length;
2870            }
2871            _ifxhc->phase=HC_WAITING;
2872            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2873        }
2874        return 1;
2875    }
2876    else if(hcint.b.datatglerr )
2877    {
2878        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
2879            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
2880        else
2881            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2882        _ifxhc->split=1;
2883        if(_ifxhc->control_phase == IFXHCD_CONTROL_DATA)
2884        {
2885            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2886            _ifxhc->xfer_count = _urbd->urb->actual_length;
2887        }
2888        _ifxhc->phase=HC_WAITING;
2889        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2890        return 1;
2891    }
2892    else if(hcint.b.frmovrun )
2893    {
2894        _urbd->error_count=0;
2895        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2896        return 1;
2897    }
2898    else if(hcint.b.bblerr )
2899    {
2900        _urbd->error_count=0;
2901        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2902        return 1;
2903    }
2904    return 0;
2905}
2906////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2907////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2908static int32_t chhltd_bulk_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
2909                                      ifxhcd_hc_t *_ifxhc,
2910                                      ifxusb_hc_regs_t *_hc_regs,
2911                                      ifxhcd_urbd_t *_urbd)
2912{
2913    hcint_data_t hcint;
2914    hcint_data_t hcintmsk;
2915    hctsiz_data_t hctsiz;
2916
2917    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2918    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2919    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2920    disable_hc_int(_hc_regs,ack);
2921    disable_hc_int(_hc_regs,nak);
2922    disable_hc_int(_hc_regs,nyet);
2923
2924    if (hcint.b.xfercomp)
2925    {
2926        _urbd->error_count =0;
2927        _ifxhc->split=1;
2928        complete_channel(_ifxhcd, _ifxhc, _urbd);
2929        return 1;
2930    }
2931    else if (hcint.b.nak)
2932    {
2933        _ifxhc->split = 1;
2934        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2935        _ifxhc->xfer_count = _urbd->urb->actual_length;
2936        _ifxhc->phase=HC_WAITING;
2937        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2938        return 1;
2939    }
2940    else if(hcint.b.nyet)
2941    {
2942        _urbd->error_count=0;
2943        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2944        _ifxhc->phase=HC_WAITING;
2945        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2946        return 1;
2947    }
2948    else if(hcint.b.stall || hcint.b.bblerr )
2949    {
2950        _urbd->error_count=0;
2951        if (hcint.b.stall)
2952            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2953        else if(hcint.b.bblerr )
2954            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2955        return 1;
2956    }
2957    else if(hcint.b.xacterr )
2958    {
2959        _urbd->error_count++;
2960        if(_urbd->error_count>=3)
2961        {
2962            _urbd->error_count=0;
2963            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2964        }
2965        else
2966        {
2967            _ifxhc->split=1;
2968            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2969            _ifxhc->xfer_count = _urbd->urb->actual_length;
2970            _ifxhc->phase=HC_WAITING;
2971            ifxhcd_hc_start(_ifxhcd, _ifxhc);
2972        }
2973        return 1;
2974    }
2975    else if(hcint.b.datatglerr )
2976    {
2977        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
2978            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
2979        else
2980            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2981        _ifxhc->split=1;
2982        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2983        _ifxhc->xfer_count = _urbd->urb->actual_length;
2984        _ifxhc->phase=HC_WAITING;
2985        ifxhcd_hc_start(_ifxhcd, _ifxhc);
2986        return 1;
2987    }
2988    else if(hcint.b.frmovrun )
2989    {
2990        _urbd->error_count=0;
2991        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2992        return 1;
2993    }
2994    return 0;
2995}
2996////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2997static int32_t chhltd_bulk_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
2998                                      ifxhcd_hc_t *_ifxhc,
2999                                      ifxusb_hc_regs_t *_hc_regs,
3000                                      ifxhcd_urbd_t *_urbd)
3001{
3002    hcint_data_t hcint;
3003    hcint_data_t hcintmsk;
3004    hctsiz_data_t hctsiz;
3005    int out_nak_enh = 0;
3006
3007    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
3008        out_nak_enh = 1;
3009
3010    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
3011    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
3012    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
3013    disable_hc_int(_hc_regs,ack);
3014    disable_hc_int(_hc_regs,nak);
3015    disable_hc_int(_hc_regs,nyet);
3016
3017    if(hcint.b.xfercomp )
3018    {
3019        _urbd->error_count=0;
3020        _ifxhc->split=1;
3021        #if 0
3022        if(_ifxhc->xfer_len==0 && !hcint.b.ack && (hcint.b.nak || hcint.b.nyet))
3023        {
3024            // Walkaround: When sending ZLP and receive NYEY or NAK but also issue CMPT intr
3025            // Solution: NoSplit: Resend at next SOF
3026            // Split : Resend at next SOF with SSPLIT
3027            _ifxhc->xfer_len = 0;
3028            _ifxhc->xfer_count = 0;
3029            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
3030            _ifxhc->phase=HC_WAITING;
3031            ifxhcd_hc_start(_ifxhcd, _ifxhc);
3032        }
3033        else
3034        #endif
3035        {
3036            complete_channel(_ifxhcd, _ifxhc, _urbd);
3037        }
3038        return 1;
3039    }
3040    else if(hcint.b.nak )
3041    {
3042        _ifxhc->split = 1;
3043        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
3044        _ifxhc->xfer_count = _urbd->urb->actual_length;
3045        _ifxhc->phase=HC_WAITING;
3046        ifxhcd_hc_start(_ifxhcd, _ifxhc);
3047        return 1;
3048    }
3049    else if(hcint.b.nyet)
3050    {
3051        //Retry Complete Split
3052        // Issue Retry instantly on next SOF, without gothrough process_channels
3053        _urbd->error_count=0;
3054        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
3055        _ifxhc->phase=HC_WAITING;
3056        ifxhcd_hc_start(_ifxhcd, _ifxhc);
3057        return 1;
3058    }
3059    else if(hcint.b.stall )
3060    {
3061        _urbd->error_count=0;
3062        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
3063        return 1;
3064    }
3065    else if(hcint.b.xacterr )
3066    {
3067        _urbd->error_count++;
3068        if(_urbd->error_count>=3)
3069        {
3070            _urbd->error_count=0;
3071            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
3072        }
3073        else
3074        {
3075            _ifxhc->split=1;
3076            _ifxhc->epqh->do_ping=1;
3077            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
3078            _ifxhc->xfer_count = _urbd->urb->actual_length;
3079            _ifxhc->phase=HC_WAITING;
3080            ifxhcd_hc_start(_ifxhcd, _ifxhc);
3081        }
3082        return 1;
3083    }
3084    else if(hcint.b.datatglerr )
3085    {
3086        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
3087            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
3088        else
3089            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
3090        _ifxhc->split=1;
3091        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
3092        _ifxhc->xfer_count = _urbd->urb->actual_length;
3093        _ifxhc->phase=HC_WAITING;
3094        ifxhcd_hc_start(_ifxhcd, _ifxhc);
3095        return 1;
3096    }
3097    else if(hcint.b.frmovrun )
3098    {
3099        _urbd->error_count=0;
3100        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
3101        return 1;
3102    }
3103    else if(hcint.b.bblerr )
3104    {
3105        _urbd->error_count=0;
3106        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
3107        return 1;
3108    }
3109    return 0;
3110}
3111////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3112////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3113static int32_t chhltd_intr_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
3114                                  ifxhcd_hc_t *_ifxhc,
3115                                  ifxusb_hc_regs_t *_hc_regs,
3116                                  ifxhcd_urbd_t *_urbd)
3117{
3118    hcint_data_t hcint;
3119    hcint_data_t hcintmsk;
3120    hctsiz_data_t hctsiz;
3121
3122    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
3123    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
3124    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
3125    disable_hc_int(_hc_regs,ack);
3126    disable_hc_int(_hc_regs,nak);
3127    disable_hc_int(_hc_regs,nyet);
3128
3129    if (hcint.b.xfercomp )
3130    {
3131        _urbd->error_count=0;
3132        _ifxhc->split=1;
3133        complete_channel(_ifxhcd, _ifxhc, _urbd);
3134        return 1;
3135    }
3136    else if(hcint.b.nak )
3137    {
3138        _ifxhc->split = 1;
3139        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
3140        _ifxhc->xfer_count = _urbd->urb->actual_length;
3141        _ifxhc->phase=HC_WAITING;
3142        ifxhcd_hc_start(_ifxhcd, _ifxhc);
3143        return 1;
3144    }
3145    else if(hcint.b.nyet)
3146    {
3147        _urbd->error_count=0;
3148        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
3149        _ifxhc->phase=HC_WAITING;
3150        ifxhcd_hc_start(_ifxhcd, _ifxhc);
3151        return 1;
3152    }
3153    else if(hcint.b.frmovrun || hcint.b.bblerr || hcint.b.stall )
3154    {
3155        _urbd->error_count=0;
3156        if (hcint.b.stall)
3157            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
3158        else if(hcint.b.bblerr )
3159            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
3160        else if(hcint.b.frmovrun )
3161            release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
3162        return 1;
3163    }
3164    else if(hcint.b.xacterr )
3165    {
3166        hcchar_data_t hcchar;
3167        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
3168        _urbd->error_count=hcchar.b.multicnt;
3169        if(_urbd->error_count>=3)
3170        {
3171            _urbd->error_count=0;
3172            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
3173        }
3174        else
3175        {
3176            _ifxhc->split=1;
3177            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
3178            _ifxhc->xfer_count = _urbd->urb->actual_length;
3179            _ifxhc->phase=HC_WAITING;
3180            ifxhcd_hc_start(_ifxhcd, _ifxhc);
3181        }
3182        return 1;
3183    }
3184    else if(hcint.b.datatglerr )
3185    {
3186        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
3187            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
3188        else
3189            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
3190        _ifxhc->split=1;
3191        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
3192        _ifxhc->xfer_count = _urbd->urb->actual_length;
3193        _ifxhc->phase=HC_WAITING;
3194        ifxhcd_hc_start(_ifxhcd, _ifxhc);
3195        return 1;
3196    }
3197    return 0;
3198}
3199////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3200static int32_t chhltd_intr_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
3201                                  ifxhcd_hc_t *_ifxhc,
3202                                  ifxusb_hc_regs_t *_hc_regs,
3203                                  ifxhcd_urbd_t *_urbd)
3204{
3205    hcint_data_t hcint;
3206    hcint_data_t hcintmsk;
3207    hctsiz_data_t hctsiz;
3208    int out_nak_enh = 0;
3209
3210    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
3211        out_nak_enh = 1;
3212
3213    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
3214    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
3215    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
3216    disable_hc_int(_hc_regs,ack);
3217    disable_hc_int(_hc_regs,nak);
3218    disable_hc_int(_hc_regs,nyet);
3219
3220    if(hcint.b.xfercomp )
3221    {
3222        _urbd->error_count=0;
3223        _ifxhc->split=1;
3224        complete_channel(_ifxhcd, _ifxhc, _urbd);
3225        return 1;
3226    }
3227    else if(hcint.b.nak )
3228    {
3229        _ifxhc->split = 1;
3230        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
3231        _ifxhc->xfer_count = _urbd->urb->actual_length;
3232        _ifxhc->phase=HC_WAITING;
3233        ifxhcd_hc_start(_ifxhcd, _ifxhc);
3234        return 1;
3235    }
3236    else if(hcint.b.nyet)
3237    {
3238        _urbd->error_count=0;
3239        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
3240        _ifxhc->phase=HC_WAITING;
3241        ifxhcd_hc_start(_ifxhcd, _ifxhc);
3242        return 1;
3243    }
3244    else if(hcint.b.stall || hcint.b.frmovrun)
3245    {
3246        _urbd->error_count=0;
3247        if (hcint.b.stall)
3248            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
3249        else if(hcint.b.frmovrun )
3250            release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
3251        return 1;
3252    }
3253    else if(hcint.b.xacterr )
3254    {
3255        hcchar_data_t hcchar;
3256        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
3257        _urbd->error_count=hcchar.b.multicnt;
3258        if(_urbd->error_count>=3)
3259        {
3260            _urbd->error_count=0;
3261            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
3262        }
3263        else
3264        {
3265            _ifxhc->split=1;
3266            _ifxhc->epqh->do_ping=1;
3267            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
3268            _ifxhc->xfer_count = _urbd->urb->actual_length;
3269            _ifxhc->phase=HC_WAITING;
3270            ifxhcd_hc_start(_ifxhcd, _ifxhc);
3271        }
3272        return 1;
3273    }
3274    else if(hcint.b.datatglerr )
3275    {
3276        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
3277            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
3278        else
3279            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
3280        _ifxhc->split=1;
3281        _ifxhc->epqh->do_ping=1;
3282        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
3283        _ifxhc->xfer_count = _urbd->urb->actual_length;
3284        _ifxhc->phase=HC_WAITING;
3285        ifxhcd_hc_start(_ifxhcd, _ifxhc);
3286        return 1;
3287    }
3288    else if(hcint.b.bblerr )
3289    {
3290        _urbd->error_count=0;
3291        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
3292        return 1;
3293    }
3294    return 0;
3295}
3296////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3297////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3298static int32_t chhltd_isoc_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
3299                                   ifxhcd_hc_t *_ifxhc,
3300                                   ifxusb_hc_regs_t *_hc_regs,
3301                                   ifxhcd_urbd_t *_urbd)
3302{
3303    #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
3304        hcint_data_t hcint;
3305        hcint_data_t hcintmsk;
3306        hctsiz_data_t hctsiz;
3307
3308        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
3309        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
3310        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
3311        if(hcint.b.xfercomp )
3312        {
3313            disable_hc_int(_hc_regs,ack);
3314            disable_hc_int(_hc_regs,nak);
3315            disable_hc_int(_hc_regs,nyet);
3316            _urbd->error_count=0;
3317            _ifxhc->split=1;
3318            complete_channel(_ifxhcd, _ifxhc, _urbd);
3319            return 1;
3320        }
3321        else if(hcint.b.nak )
3322        {
3323            Retry Start Split (in next b_interval ¡V 1 uF)
3324        }
3325        else if(hcint.b.nyet)
3326        {
3327            //Do Next Complete Split
3328            // Issue Retry instantly on next SOF, without gothrough process_channels
3329            _urbd->error_count=0;
3330            //disable_hc_int(_hc_regs,ack);
3331            //disable_hc_int(_hc_regs,nak);
3332            //disable_hc_int(_hc_regs,datatglerr);
3333            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
3334            _ifxhc->phase=HC_WAITING;
3335            ifxhcd_hc_start(_ifxhcd, _ifxhc);
3336            return 1;
3337        }
3338        else if(hcint.b.frmovrun || hcint.b.stall || hcint.b.bblerr)
3339        {
3340            _urbd->error_count=0;
3341            disable_hc_int(_hc_regs,ack);
3342            disable_hc_int(_hc_regs,nyet);
3343            disable_hc_int(_hc_regs,nak);
3344            _ifxhc->wait_for_sof = 0;
3345
3346            //if(hctsiz.b.pktcnt==0)
3347            //{
3348            // complete_channel(_ifxhcd, _ifxhc, _urbd);
3349            // return 1;
3350            //}
3351            //else
3352            // _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
3353            if (hcint.b.stall)
3354                release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
3355            else if(hcint.b.frmovrun )
3356            else if(hcint.b.bblerr )
3357            return 1;
3358        }
3359        else if(hcint.b.xacterr )
3360        {
3361            Rewind Buffer Pointers
3362            if (HCCHARn.EC = = 3) // ERR response received
3363            {
3364                Record ERR error
3365                Do Next Start Split (in next frame)
3366            }
3367            else
3368            {
3369                De-allocate Channel
3370            }
3371        }
3372        else if(hcint.b.datatglerr )
3373        {
3374            warning
3375        }
3376        else if(hcint.b.ack )
3377        {
3378            warning
3379        }
3380    #endif
3381    return 0;
3382}
3383////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3384static int32_t chhltd_isoc_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
3385                                   ifxhcd_hc_t *_ifxhc,
3386                                   ifxusb_hc_regs_t *_hc_regs,
3387                                   ifxhcd_urbd_t *_urbd)
3388{
3389    #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
3390        hcint_data_t hcint;
3391        hcint_data_t hcintmsk;
3392        hctsiz_data_t hctsiz;
3393        int out_nak_enh = 0;
3394
3395        if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
3396            out_nak_enh = 1;
3397
3398        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
3399        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
3400        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
3401        warning
3402    #endif
3403    return 0;
3404}
3405////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3406////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3407////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
3408
3409/*!
3410     \fn static int32_t handle_hc_chhltd_intr(ifxhcd_hcd_t *_ifxhcd,
3411                                     ifxhcd_hc_t *_ifxhc,
3412                                     ifxusb_hc_regs_t *_hc_regs,
3413                                     ifxhcd_urbd_t *_urbd)
3414     \brief This function handles halted interrupts of host channels.
3415     \param _ifxhcd Pointer to the sate of HCD structure
3416     \param _ifxhc Pointer to host channel descriptor
3417     \param _hc_regs Pointer to host channel registers
3418     \param _urbd Pointer to URB descriptor
3419     \return 0 OK
3420     \ingroup IFXUSB_HCD
3421 */
3422static
3423int32_t handle_hc_chhltd_intr(ifxhcd_hcd_t *_ifxhcd,
3424                                     ifxhcd_hc_t *_ifxhc,
3425                                     ifxusb_hc_regs_t *_hc_regs,
3426                                     ifxhcd_urbd_t *_urbd)
3427{
3428    IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: Channel Halted--\n", _ifxhc->hc_num);
3429
3430    _ifxhc->phase = HC_STOPPED;
3431    if(_ifxhc->epqh)
3432        if(_ifxhc->epqh->urbd)
3433            _ifxhc->epqh->urbd->phase=URBD_ACTIVE;
3434
3435    if (_ifxhc->halt_status == HC_XFER_URB_DEQUEUE ||
3436        _ifxhc->halt_status == HC_XFER_AHB_ERR) {
3437        /*
3438         * Just release the channel. A dequeue can happen on a
3439         * transfer timeout. In the case of an AHB Error, the channel
3440         * was forced to halt because there's no way to gracefully
3441         * recover.
3442         */
3443        if(_ifxhc->epqh)
3444            if(_ifxhc->epqh->urbd)
3445                _ifxhc->epqh->urbd->phase=URBD_DEQUEUEING;
3446        release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
3447        return 1;
3448    }
3449
3450    if (_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL)
3451    {
3452        if (_ifxhc->split==0)
3453        {
3454            if(_ifxhc->is_in)
3455                return (chhltd_ctrl_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3456            else
3457                return (chhltd_ctrl_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3458        }
3459        else if(_ifxhc->split==1)
3460        {
3461            if(_ifxhc->is_in)
3462                return (chhltd_ctrl_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3463            else
3464                return (chhltd_ctrl_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3465        }
3466        else if(_ifxhc->split==2)
3467        {
3468            if(_ifxhc->is_in)
3469                return (chhltd_ctrl_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3470            else
3471                return (chhltd_ctrl_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3472        }
3473    }
3474    else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
3475    {
3476        if (_ifxhc->split==0)
3477        {
3478            if(_ifxhc->is_in)
3479                return (chhltd_bulk_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3480            else
3481                return (chhltd_bulk_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3482        }
3483        else if(_ifxhc->split==1)
3484        {
3485            if(_ifxhc->is_in)
3486                return (chhltd_bulk_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3487            else
3488                return (chhltd_bulk_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3489        }
3490        else if(_ifxhc->split==2)
3491        {
3492            if(_ifxhc->is_in)
3493                return (chhltd_bulk_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3494            else
3495                return (chhltd_bulk_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3496        }
3497    }
3498    else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR)
3499    {
3500        if (_ifxhc->split==0)
3501        {
3502            if(_ifxhc->is_in)
3503                return (chhltd_intr_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3504            else
3505                return (chhltd_intr_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3506        }
3507        else if(_ifxhc->split==1)
3508        {
3509            if(_ifxhc->is_in)
3510                return (chhltd_intr_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3511            else
3512                return (chhltd_intr_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3513        }
3514        else if(_ifxhc->split==2)
3515        {
3516            if(_ifxhc->is_in)
3517                return (chhltd_intr_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3518            else
3519                return (chhltd_intr_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3520        }
3521    }
3522    else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
3523    {
3524        if (_ifxhc->split==0)
3525        {
3526            if(_ifxhc->is_in)
3527                return (chhltd_isoc_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3528            else
3529                return (chhltd_isoc_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3530        }
3531        else if(_ifxhc->split==1)
3532        {
3533            if(_ifxhc->is_in)
3534                return (chhltd_isoc_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3535            else
3536                return (chhltd_isoc_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3537        }
3538        else if(_ifxhc->split==2)
3539        {
3540            if(_ifxhc->is_in)
3541                return (chhltd_isoc_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3542            else
3543                return (chhltd_isoc_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
3544        }
3545    }
3546    return 0;
3547}
3548
3549/*
3550 * Handles a host channel AHB error interrupt. This handler is only called in
3551 * DMA mode.
3552 */
3553static void hc_other_intr_dump(ifxhcd_hcd_t *_ifxhcd,
3554                               ifxhcd_hc_t *_ifxhc,
3555                               ifxusb_hc_regs_t *_hc_regs,
3556                               ifxhcd_urbd_t *_urbd)
3557{
3558    #ifdef __DEBUG__
3559        hcchar_data_t hcchar;
3560        hcsplt_data_t hcsplt;
3561        hctsiz_data_t hctsiz;
3562        uint32_t hcdma;
3563        struct urb *urb = _urbd->urb;
3564        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
3565        hcsplt.d32 = ifxusb_rreg(&_hc_regs->hcsplt);
3566        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
3567        hcdma = ifxusb_rreg(&_hc_regs->hcdma);
3568
3569        IFX_ERROR("Channel %d\n", _ifxhc->hc_num);
3570        IFX_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
3571        IFX_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
3572        IFX_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe));
3573        IFX_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
3574                (usb_pipein(urb->pipe) ? "IN" : "OUT"));
3575        IFX_ERROR(" Endpoint type: %s\n",
3576                ({char *pipetype;
3577                switch (usb_pipetype(urb->pipe)) {
3578                    case PIPE_CONTROL: pipetype = "CTRL"; break;
3579                    case PIPE_BULK: pipetype = "BULK"; break;
3580                    case PIPE_INTERRUPT: pipetype = "INTR"; break;
3581                    case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break;
3582                    default: pipetype = "????"; break;
3583                }; pipetype;}));
3584        IFX_ERROR(" Speed: %s\n",
3585                ({char *speed;
3586                switch (urb->dev->speed) {
3587                    case USB_SPEED_HIGH: speed = "HS"; break;
3588                    case USB_SPEED_FULL: speed = "FS"; break;
3589                    case USB_SPEED_LOW: speed = "LS"; break;
3590                    default: speed = "????"; break;
3591                }; speed;}));
3592        IFX_ERROR(" Max packet size: %d\n",
3593                usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
3594        IFX_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length);
3595        IFX_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
3596                urb->transfer_buffer, (void *)urb->transfer_dma);
3597        IFX_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
3598                urb->setup_packet, (void *)urb->setup_dma);
3599        IFX_ERROR(" Interval: %d\n", urb->interval);
3600    #endif //__DEBUG__
3601}
3602
3603/*
3604 * Handles a host channel ACK interrupt. This interrupt is enabled when
3605 * errors occur, and during Start Split transactions.
3606 */
3607static
3608int32_t handle_hc_ack_intr(ifxhcd_hcd_t *_ifxhcd,
3609                                  ifxhcd_hc_t *_ifxhc,
3610                                  ifxusb_hc_regs_t *_hc_regs,
3611                                  ifxhcd_urbd_t *_urbd)
3612{
3613    _urbd->error_count=0;
3614    _ifxhc->erron = 0;
3615
3616    disable_hc_int(_hc_regs,nyet);
3617
3618    #ifdef __NAKSTOP__
3619    if(!_ifxhc->stop_on)
3620    {
3621        disable_hc_int(_hc_regs,ack);
3622        disable_hc_int(_hc_regs,nak);
3623    }
3624    #else
3625        disable_hc_int(_hc_regs,ack);
3626        disable_hc_int(_hc_regs,nak);
3627    #endif
3628    return 1;
3629}
3630
3631/*
3632 * Handles a host channel ACK interrupt. This interrupt is enabled when
3633 * errors occur, and during Start Split transactions.
3634 */
3635static
3636int32_t handle_hc_nak_intr(ifxhcd_hcd_t *_ifxhcd,
3637                                  ifxhcd_hc_t *_ifxhc,
3638                                  ifxusb_hc_regs_t *_hc_regs,
3639                                  ifxhcd_urbd_t *_urbd)
3640{
3641    _urbd->error_count=0;
3642    _ifxhc->erron=0;
3643    disable_hc_int(_hc_regs,nyet);
3644    disable_hc_int(_hc_regs,ack);
3645    disable_hc_int(_hc_regs,nak);
3646    #ifdef __NAKSTOP__
3647    if(_ifxhc->stop_on)
3648    {
3649        hcchar_data_t hcchar;
3650        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
3651        if(hcchar.b.chen)
3652        {
3653            hcchar.b.chdis = 1;
3654            _ifxhc->halt_status = HC_XFER_NAK;
3655            ifxusb_wreg(&_hc_regs->hcchar, hcchar.d32);
3656        }
3657    }
3658    #endif
3659    return 1;
3660}
3661
3662static
3663int32_t handle_hc_nyet_intr(ifxhcd_hcd_t *_ifxhcd,
3664                                   ifxhcd_hc_t *_ifxhc,
3665                                   ifxusb_hc_regs_t *_hc_regs,
3666                                   ifxhcd_urbd_t *_urbd)
3667{
3668    _urbd->error_count=0;
3669    _ifxhc->erron = 0;
3670
3671    disable_hc_int(_hc_regs,nyet);
3672    #ifdef __NAKSTOP__
3673    if(!_ifxhc->stop_on)
3674    {
3675        disable_hc_int(_hc_regs,ack);
3676        disable_hc_int(_hc_regs,nak);
3677    }
3678    #else
3679        disable_hc_int(_hc_regs,ack);
3680        disable_hc_int(_hc_regs,nak);
3681    #endif
3682    return 1;
3683}
3684
3685/*
3686 * Handles a host channel AHB error interrupt. This handler is only called in
3687 * DMA mode.
3688 */
3689static int32_t handle_hc_ahberr_intr(ifxhcd_hcd_t *_ifxhcd,
3690                                     ifxhcd_hc_t *_ifxhc,
3691                                     ifxusb_hc_regs_t *_hc_regs,
3692                                     ifxhcd_urbd_t *_urbd)
3693{
3694    IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
3695            "AHB Error--\n", _ifxhc->hc_num);
3696    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3697
3698    ifxhcd_hc_halt(&_ifxhcd->core_if, _ifxhc, HC_XFER_AHB_ERR);
3699    return 1;
3700}
3701
3702/*
3703 * Datatoggle
3704 */
3705static int32_t handle_hc_datatglerr_intr(ifxhcd_hcd_t *_ifxhcd,
3706                                         ifxhcd_hc_t *_ifxhc,
3707                                         ifxusb_hc_regs_t *_hc_regs,
3708                                         ifxhcd_urbd_t *_urbd)
3709{
3710    IFX_ERROR( "--Host Channel %d Interrupt: "
3711            "DATATOGGLE Error--\n", _ifxhc->hc_num);
3712    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3713    disable_hc_int(_hc_regs,datatglerr);
3714    return 1;
3715}
3716
3717
3718/*
3719 * Interrupts which should not been triggered
3720 */
3721static int32_t handle_hc_frmovrun_intr(ifxhcd_hcd_t *_ifxhcd,
3722                                       ifxhcd_hc_t *_ifxhc,
3723                                       ifxusb_hc_regs_t *_hc_regs,
3724                                       ifxhcd_urbd_t *_urbd)
3725{
3726    IFX_ERROR( "--Host Channel %d Interrupt: "
3727            "FrameOverRun Error--\n", _ifxhc->hc_num);
3728    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3729    disable_hc_int(_hc_regs,frmovrun);
3730    return 1;
3731}
3732
3733static int32_t handle_hc_bblerr_intr(ifxhcd_hcd_t *_ifxhcd,
3734                                     ifxhcd_hc_t *_ifxhc,
3735                                     ifxusb_hc_regs_t *_hc_regs,
3736                                     ifxhcd_urbd_t *_urbd)
3737{
3738    IFX_ERROR( "--Host Channel %d Interrupt: "
3739            "BBL Error--\n", _ifxhc->hc_num);
3740    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3741    disable_hc_int(_hc_regs,bblerr);
3742    return 1;
3743}
3744
3745static int32_t handle_hc_xacterr_intr(ifxhcd_hcd_t *_ifxhcd,
3746                                      ifxhcd_hc_t *_ifxhc,
3747                                      ifxusb_hc_regs_t *_hc_regs,
3748                                      ifxhcd_urbd_t *_urbd)
3749{
3750    IFX_ERROR( "--Host Channel %d Interrupt: "
3751            "XACT Error--\n", _ifxhc->hc_num);
3752    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3753    disable_hc_int(_hc_regs,xacterr);
3754    return 1;
3755}
3756
3757
3758static int32_t handle_hc_stall_intr(ifxhcd_hcd_t *_ifxhcd,
3759                                    ifxhcd_hc_t *_ifxhc,
3760                                    ifxusb_hc_regs_t *_hc_regs,
3761                                    ifxhcd_urbd_t *_urbd)
3762{
3763    IFX_ERROR( "--Host Channel %d Interrupt: "
3764            "STALL--\n", _ifxhc->hc_num);
3765    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3766    disable_hc_int(_hc_regs,stall);
3767    return 1;
3768}
3769
3770static int32_t handle_hc_xfercomp_intr(ifxhcd_hcd_t *_ifxhcd,
3771                                       ifxhcd_hc_t *_ifxhc,
3772                                       ifxusb_hc_regs_t *_hc_regs,
3773                                       ifxhcd_urbd_t *_urbd)
3774{
3775    IFX_ERROR( "--Host Channel %d Interrupt: "
3776            "XFERCOMP--\n", _ifxhc->hc_num);
3777    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3778    disable_hc_int(_hc_regs,xfercomp);
3779    return 1;
3780}
3781
3782/* This interrupt indicates that the specified host channels has a pending
3783 * interrupt. There are multiple conditions that can cause each host channel
3784 * interrupt. This function determines which conditions have occurred for this
3785 * host channel interrupt and handles them appropriately. */
3786static int32_t handle_hc_n_intr (ifxhcd_hcd_t *_ifxhcd, uint32_t _num)
3787{
3788    uint32_t hcintval,hcintmsk;
3789    hcint_data_t hcint;
3790    ifxhcd_hc_t *ifxhc;
3791    ifxusb_hc_regs_t *hc_regs;
3792    ifxhcd_urbd_t *urbd;
3793
3794    int retval = 0;
3795
3796    IFX_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num);
3797
3798    ifxhc = &_ifxhcd->ifxhc[_num];
3799    hc_regs = _ifxhcd->core_if.hc_regs[_num];
3800
3801    hcintval = ifxusb_rreg(&hc_regs->hcint);
3802    hcintmsk = ifxusb_rreg(&hc_regs->hcintmsk);
3803    hcint.d32 = hcintval & hcintmsk;
3804    IFX_DEBUGPL(DBG_HCDV, " 0x%08x & 0x%08x = 0x%08x\n",
3805            hcintval, hcintmsk, hcint.d32);
3806
3807    urbd = ifxhc->epqh->urbd;
3808
3809    if (hcint.b.ahberr)
3810        retval |= handle_hc_ahberr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3811    else if (hcint.b.chhltd)
3812        retval |= handle_hc_chhltd_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3813    else
3814    {
3815        if (hcint.b.datatglerr)
3816            retval |= handle_hc_datatglerr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3817        if (hcint.b.frmovrun)
3818            retval |= handle_hc_frmovrun_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3819        if (hcint.b.bblerr)
3820            retval |= handle_hc_bblerr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3821        if (hcint.b.xacterr)
3822            retval |= handle_hc_xacterr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3823        if (hcint.b.nyet)
3824            retval |= handle_hc_nyet_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3825        if (hcint.b.ack)
3826            retval |= handle_hc_ack_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3827        if (hcint.b.nak)
3828            retval |= handle_hc_nak_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3829        if (hcint.b.stall)
3830            retval |= handle_hc_stall_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3831        if (hcint.b.xfercomp)
3832            retval |= handle_hc_xfercomp_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3833    }
3834
3835    ifxusb_wreg(&hc_regs->hcint,hcintval);
3836
3837    return retval;
3838}
3839
3840
3841static uint8_t update_interval_counter(ifxhcd_epqh_t *_epqh,uint32_t _diff)
3842{
3843    if(_diff>=_epqh->period_counter)
3844    {
3845        _epqh->period_do=1;
3846        if(_diff>_epqh->interval)
3847            _epqh->period_counter=1;
3848        else
3849            _epqh->period_counter=_epqh->period_counter+_epqh->interval-_diff;
3850        return 1;
3851    }
3852    _epqh->period_counter=_epqh->period_counter-_diff;
3853    return 0;
3854}
3855
3856static
3857void process_unaligned( ifxhcd_epqh_t *_epqh, ifxusb_core_if_t *_core_if)
3858{
3859    ifxhcd_urbd_t *urbd;
3860    urbd =_epqh->urbd;
3861
3862    #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
3863    if(!urbd->aligned_checked)
3864    {
3865        #if defined(__UNALIGNED_BUF_ADJ__)
3866            uint32_t xfer_len;
3867            xfer_len=urbd->xfer_len;
3868            if(urbd->is_in && xfer_len<_epqh->mps)
3869                xfer_len = _epqh->mps;
3870// urbd->using_aligned_buf=0;
3871
3872            if(xfer_len > 0 && ((unsigned long)urbd->xfer_buff) & _core_if->unaligned_mask)
3873            {
3874                if( urbd->aligned_buf
3875                   && urbd->aligned_buf_len > 0
3876                   && urbd->aligned_buf_len < xfer_len
3877                  )
3878                {
3879                    ifxusb_free_buf_h(urbd->aligned_buf);
3880                    urbd->aligned_buf=NULL;
3881                    urbd->aligned_buf_len=0;
3882                }
3883                if(! urbd->aligned_buf || ! urbd->aligned_buf_len)
3884                {
3885                    urbd->aligned_buf = ifxusb_alloc_buf_h(xfer_len, urbd->is_in);
3886                    if(urbd->aligned_buf)
3887                        urbd->aligned_buf_len = xfer_len;
3888                }
3889                if(urbd->aligned_buf)
3890                {
3891                    if(!urbd->is_in)
3892                        memcpy(urbd->aligned_buf, urbd->xfer_buff, xfer_len);
3893// urbd->using_aligned_buf=1;
3894                    _epqh->hc->xfer_buff = urbd->aligned_buf;
3895                }
3896                else
3897                    IFX_WARN("%s():%d\n",__func__,__LINE__);
3898            }
3899            if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
3900            {
3901// urbd->using_aligned_setup=0;
3902                if(((unsigned long)urbd->setup_buff) & _core_if->unaligned_mask)
3903                {
3904                    if(! urbd->aligned_setup)
3905                        urbd->aligned_setup = ifxusb_alloc_buf_h(8,0);
3906                    if(urbd->aligned_setup)
3907                    {
3908                        memcpy(urbd->aligned_setup, urbd->setup_buff, 8);
3909// urbd->using_aligned_setup=1;
3910                    }
3911                    else
3912                        IFX_WARN("%s():%d\n",__func__,__LINE__);
3913                    _epqh->hc->xfer_buff = urbd->aligned_setup;
3914                }
3915            }
3916        #elif defined(__UNALIGNED_BUF_CHK__)
3917            if(_epqh->urbd->is_in)
3918            {
3919                if(_epqh->urbd->xfer_len==0)
3920                    IFX_WARN("%s():%d IN xfer while length is zero \n",__func__,__LINE__);
3921                else{
3922                    if(_epqh->urbd->xfer_len < _epqh->mps)
3923                        IFX_WARN("%s():%d IN xfer while length < mps \n",__func__,__LINE__);
3924                    if(((unsigned long)_epqh->urbd->xfer_buff) & _core_if->unaligned_mask)
3925                        IFX_WARN("%s():%d IN xfer Buffer UNALIGNED\n",__func__,__LINE__);
3926                }
3927            }
3928            else
3929            {
3930                if(_epqh->urbd->xfer_len > 0 && (((unsigned long)_epqh->urbd->xfer_buff) & _core_if->unaligned_mask))
3931                    IFX_WARN("%s():%d OUT xfer Buffer UNALIGNED\n",__func__,__LINE__);
3932            }
3933            if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
3934            {
3935                if(((unsigned long)_epqh->urbd->setup_buff) & _core_if->unaligned_mask)
3936                    IFX_WARN("%s():%d SETUP xfer Buffer UNALIGNED\n",__func__,__LINE__);
3937            }
3938        #endif
3939    }
3940    urbd->aligned_checked=1;
3941    #endif
3942}
3943
3944/*!
3945 \brief Assigns transactions from a URBD to a free host channel and initializes the
3946 host channel to perform the transactions. The host channel is removed from
3947 the free list.
3948 \param _ifxhcd The HCD state structure.
3949 \param _epqh Transactions from the first URBD for this EPQH are selected and assigned to a free host channel.
3950 */
3951static
3952int assign_hc(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh,ifxhcd_urbd_t *_urbd)
3953{
3954    ifxhcd_hc_t *ifxhc;
3955    struct urb *urb;
3956
3957    IFX_DEBUGPL(DBG_HCDV, "%s(%p,%p)\n", __func__, _ifxhcd, _epqh);
3958
3959    if(_ifxhcd->disconnecting)
3960    {
3961        printk(KERN_INFO "Warning: %s() Port is in discoonection\n",__func__);
3962        return 0;
3963    }
3964
3965    if(!_epqh) return 0;
3966    if(!_urbd) return 0;
3967    if(!_urbd->urb) return 0;
3968
3969    {
3970        int i;
3971        int num_channels = _ifxhcd->core_if.params.host_channels;
3972        for(i=0;i<num_channels ; i++)
3973        {
3974            hcchar_data_t hcchar;
3975            ifxusb_hc_regs_t *hc_regs;
3976            hc_regs = _ifxhcd->core_if.hc_regs[i];
3977            if(_ifxhcd->ifxhc[i].phase!=HC_IDLE)
3978            {
3979                continue;
3980            }
3981            hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
3982            if(hcchar.b.chen || hcchar.b.chdis)
3983            {
3984                continue;
3985            }
3986            break;
3987        }
3988
3989        if(i<num_channels)
3990        {
3991            ifxhc=&_ifxhcd->ifxhc[i];
3992            ifxhc->phase=HC_ASSIGNED;
3993        }
3994        else
3995            return 0;
3996    }
3997
3998    urb = _urbd->urb;
3999    _epqh->hc = ifxhc;
4000    _epqh->urbd = _urbd;
4001    ifxhc->epqh = _epqh;
4002    /*
4003     * Use usb_pipedevice to determine device address. This address is
4004     * 0 before the SET_ADDRESS command and the correct address afterward.
4005     */
4006    ifxhc->dev_addr = usb_pipedevice(urb->pipe);
4007    ifxhc->ep_num = usb_pipeendpoint(urb->pipe);
4008
4009    if (urb->dev->speed == USB_SPEED_LOW) ifxhc->speed = IFXUSB_EP_SPEED_LOW;
4010    else if (urb->dev->speed == USB_SPEED_FULL) ifxhc->speed = IFXUSB_EP_SPEED_FULL;
4011    else ifxhc->speed = IFXUSB_EP_SPEED_HIGH;
4012
4013    ifxhc->mps = _epqh->mps;
4014    ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
4015    ifxhc->ep_type = _epqh->ep_type;
4016
4017    ifxhc->split = 0;
4018    if (_epqh->need_split)
4019    {
4020        ifxhc->split = 1;
4021        ifxhc->hub_addr = urb->dev->tt->hub->devnum;
4022        ifxhc->port_addr = urb->dev->ttport;
4023    }
4024    return 1;
4025}
4026
4027/*!
4028 \brief Assigns transactions from a URBD to a free host channel and initializes the
4029 host channel to perform the transactions. The host channel is removed from
4030 the free list.
4031 \param _ifxhcd The HCD state structure.
4032 \param _epqh Transactions from the first URBD for this EPQH are selected and assigned to a free host channel.
4033 */
4034static
4035void init_hc(ifxhcd_epqh_t *_epqh)
4036{
4037    ifxhcd_hc_t *ifxhc;
4038    ifxhcd_urbd_t *urbd;
4039    struct urb *urb;
4040    ifxhcd_hcd_t *ifxhcd;
4041
4042    IFX_DEBUGPL(DBG_HCDV, "%s(%p)\n", __func__, _epqh);
4043
4044    ifxhc =_epqh->hc;
4045    urbd =_epqh->urbd;
4046    ifxhcd=_epqh->ifxhcd;
4047    urb = urbd->urb;
4048    #if defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
4049    urbd->aligned_checked=0;
4050    #endif
4051
4052    ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
4053
4054    if(_epqh->ep_type==IFXUSB_EP_TYPE_CTRL)
4055    {
4056        ifxhc->control_phase =IFXHCD_CONTROL_SETUP;
4057        ifxhc->is_in = 0;
4058        ifxhc->data_pid_start = IFXUSB_HC_PID_SETUP;
4059        ifxhc->xfer_buff = urbd->setup_buff;
4060        ifxhc->xfer_len = 8;
4061        ifxhc->xfer_count = 0;
4062        ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
4063        ifxhc->sof_delay = 0;
4064        _epqh->do_ping=0;
4065        if(!ifxhc->is_in && ifxhc->split==0)
4066            _epqh->do_ping=1;
4067    }
4068    else if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
4069    {
4070        #ifdef __EN_ISOC__
4071            struct usb_iso_packet_descriptor *frame_desc;
4072            ifxhc->is_in = urbd->is_in;
4073            frame_desc = &urb->iso_frame_desc[urbd->isoc_frame_index];
4074            urbd->xfer_len = ifxhc->xfer_len = frame_desc->length;
4075            ifxhc->xfer_buff = urbd->xfer_buff;
4076            ifxhc->xfer_buff += frame_desc->offset;
4077            ifxhc->xfer_count = 0;
4078            ifxhc->sof_delay = 0;
4079            if(usb_gettoggle (urb->dev,usb_pipeendpoint (urb->pipe), (ifxhc->is_in)?0:1))
4080                ifxhc->data_pid_start = IFXUSB_HCTSIZ_DATA1;
4081            else
4082                ifxhc->data_pid_start = IFXUSB_HCTSIZ_DATA0;
4083
4084            if(ifxhc->is_in)
4085                ifxhc->short_rw =0;
4086            else
4087                ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
4088            #ifdef __EN_ISOC_SPLIT__
4089                ifxhc->isoc_xact_pos = IFXUSB_HCSPLIT_XACTPOS_ALL;
4090            #endif
4091
4092            _epqh->isoc_frame_index=0;
4093            _epqh->isoc_now=0;
4094            _epqh->isoc_start_frame=0;
4095            if(_urb->transfer_flags && URB_ISO_ASAP)
4096                _epqh->isoc_now=1;
4097            else
4098                _epqh->isoc_start_frame=_urb->start_frame;
4099            #ifdef __EN_ISOC_SPLIT__
4100                _epqh->isoc_split_pos =0;
4101                _epqh->isoc_split_offset=0;
4102            #endif
4103            _epqh->do_ping=0;
4104        #endif
4105    }
4106    else
4107    {
4108        ifxhc->is_in = urbd->is_in;
4109        ifxhc->xfer_buff = urbd->xfer_buff;
4110        ifxhc->xfer_len = urbd->xfer_len;
4111        ifxhc->xfer_count = 0;
4112        ifxhc->sof_delay = 0;
4113// if(ifxhc->xfer_len==13 && ifxhc->is_in && _epqh->ep_type==IFXUSB_EP_TYPE_BULK && ifxhc->split==0)
4114// ifxhc->sof_delay = 8;
4115        if(usb_gettoggle (urb->dev,usb_pipeendpoint (urb->pipe), (ifxhc->is_in)?0:1))
4116            ifxhc->data_pid_start = IFXUSB_HCTSIZ_DATA1;
4117        else
4118            ifxhc->data_pid_start = IFXUSB_HCTSIZ_DATA0;
4119        if(ifxhc->is_in)
4120            ifxhc->short_rw =0;
4121        else
4122            ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
4123        _epqh->do_ping=0;
4124        if(!ifxhc->is_in && ifxhc->split==0)
4125        {
4126            if(_epqh->ep_type==IFXUSB_EP_TYPE_BULK) _epqh->do_ping=1;
4127        }
4128    }
4129
4130    {
4131        hcint_data_t hc_intr_mask;
4132        uint8_t hc_num = ifxhc->hc_num;
4133        ifxusb_hc_regs_t *hc_regs = ifxhcd->core_if.hc_regs[hc_num];
4134
4135        /* Clear old interrupt conditions for this host channel. */
4136        hc_intr_mask.d32 = 0xFFFFFFFF;
4137        hc_intr_mask.b.reserved = 0;
4138        ifxusb_wreg(&hc_regs->hcint, hc_intr_mask.d32);
4139
4140        /* Enable channel interrupts required for this transfer. */
4141        hc_intr_mask.d32 = 0;
4142        hc_intr_mask.b.chhltd = 1;
4143        hc_intr_mask.b.ahberr = 1;
4144
4145        ifxusb_wreg(&hc_regs->hcintmsk, hc_intr_mask.d32);
4146
4147        /* Enable the top level host channel interrupt. */
4148        {
4149            uint32_t intr_enable;
4150            intr_enable = (1 << hc_num);
4151            ifxusb_mreg(&ifxhcd->core_if.host_global_regs->haintmsk, 0, intr_enable);
4152        }
4153
4154        /* Make sure host channel interrupts are enabled. */
4155        {
4156            gint_data_t gintmsk ={.d32 = 0};
4157            gintmsk.b.hcintr = 1;
4158            ifxusb_mreg(&ifxhcd->core_if.core_global_regs->gintmsk, 0, gintmsk.d32);
4159        }
4160
4161        /*
4162         * Program the HCCHARn register with the endpoint characteristics for
4163         * the current transfer.
4164         */
4165        {
4166            hcchar_data_t hcchar;
4167
4168            hcchar.d32 = 0;
4169            hcchar.b.devaddr = ifxhc->dev_addr;
4170            hcchar.b.epnum = ifxhc->ep_num;
4171            hcchar.b.lspddev = (ifxhc->speed == IFXUSB_EP_SPEED_LOW);
4172            hcchar.b.eptype = ifxhc->ep_type;
4173            hcchar.b.mps = ifxhc->mps;
4174            ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
4175
4176            IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, ifxhc->hc_num);
4177            IFX_DEBUGPL(DBG_HCDV, " Dev Addr: %d\n" , hcchar.b.devaddr);
4178            IFX_DEBUGPL(DBG_HCDV, " Ep Num: %d\n" , hcchar.b.epnum);
4179            IFX_DEBUGPL(DBG_HCDV, " Is Low Speed: %d\n", hcchar.b.lspddev);
4180            IFX_DEBUGPL(DBG_HCDV, " Ep Type: %d\n" , hcchar.b.eptype);
4181            IFX_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n" , hcchar.b.mps);
4182            IFX_DEBUGPL(DBG_HCDV, " Multi Cnt: %d\n" , hcchar.b.multicnt);
4183        }
4184        /* Program the HCSPLIT register for SPLITs */
4185        {
4186            hcsplt_data_t hcsplt;
4187
4188            hcsplt.d32 = 0;
4189            if (ifxhc->split)
4190            {
4191                IFX_DEBUGPL(DBG_HCDV, "Programming HC %d with split --> %s\n", ifxhc->hc_num,
4192                       (ifxhc->split==2) ? "CSPLIT" : "SSPLIT");
4193                hcsplt.b.spltena = 1;
4194                hcsplt.b.compsplt = (ifxhc->split==2);
4195                #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
4196                    if(_epqh->ep_type==IFXUSB_EP_TYPE_ISOC)
4197                        hcsplt.b.xactpos = ifxhc->isoc_xact_pos;
4198                    else
4199                #endif
4200                    hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL;
4201                hcsplt.b.hubaddr = ifxhc->hub_addr;
4202                hcsplt.b.prtaddr = ifxhc->port_addr;
4203                IFX_DEBUGPL(DBG_HCDV, " comp split %d\n" , hcsplt.b.compsplt);
4204                IFX_DEBUGPL(DBG_HCDV, " xact pos %d\n" , hcsplt.b.xactpos);
4205                IFX_DEBUGPL(DBG_HCDV, " hub addr %d\n" , hcsplt.b.hubaddr);
4206                IFX_DEBUGPL(DBG_HCDV, " port addr %d\n" , hcsplt.b.prtaddr);
4207                IFX_DEBUGPL(DBG_HCDV, " is_in %d\n" , ifxhc->is_in);
4208                IFX_DEBUGPL(DBG_HCDV, " Max Pkt: %d\n" , ifxhc->mps);
4209                IFX_DEBUGPL(DBG_HCDV, " xferlen: %d\n" , ifxhc->xfer_len);
4210            }
4211            ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
4212        }
4213    }
4214    process_unaligned(_epqh,&ifxhcd->core_if);
4215
4216
4217    #ifdef __NAKSTOP__
4218        ifxhc->stop_on=0;
4219        if (!ifxhc->split && ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
4220        {
4221            #ifdef __INNAKSTOP_BULK__
4222                if(ifxhc->is_in)
4223                    ifxhc->stop_on=1;
4224            #endif
4225            #ifdef __PINGSTOP_BULK__
4226                if(!ifxhc->is_in)
4227                    ifxhc->stop_on=1;
4228            #endif
4229        }
4230    #endif
4231}
4232
4233
4234static
4235void select_eps_sub(ifxhcd_hcd_t *_ifxhcd)
4236{
4237    struct list_head *epqh_ptr;
4238    ifxhcd_epqh_t *epqh;
4239    struct list_head *urbd_ptr;
4240    unsigned long flags;
4241    ifxhcd_urbd_t *urbd;
4242
4243    hfnum_data_t hfnum;
4244    uint32_t fndiff;
4245
4246    if(_ifxhcd->disconnecting)
4247    {
4248// printk(KERN_INFO "Warning: %s() Port is in discoonection\n",__func__);
4249        return ;
4250    }
4251
4252    local_irq_save(flags);
4253    LOCK_EPQH_LIST(_ifxhcd);
4254
4255    hfnum.d32 = ifxusb_rreg(&_ifxhcd->core_if.host_global_regs->hfnum);
4256    fndiff = hfnum.b.frnum;
4257    fndiff+= 0x00004000;
4258    fndiff-= _ifxhcd->lastframe ;
4259    fndiff&= 0x00003FFF;
4260    if(!fndiff) fndiff =1;
4261
4262    #ifdef __EN_ISOC__
4263        epqh_ptr = _ifxhcd->epqh_list_isoc.next;
4264        while (epqh_ptr != &_ifxhcd->epqh_list_isoc)
4265        {
4266            epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, ql);
4267            epqh_ptr = epqh_ptr->next;
4268
4269            #ifdef __DYN_SOF_INTR__
4270            if (!list_empty(&epqh->urbd_list))
4271                _ifxhcd->dyn_sof_count = DYN_SOF_COUNT_DEF;
4272            #endif
4273
4274            if(epqh->pause)
4275                continue;
4276            if(epqh->phase==EPQH_READY)
4277            {
4278                if(update_interval_counter(epqh,fndiff) || epqh->isoc_now)
4279                {
4280                    LOCK_URBD_LIST(epqh);
4281                    urbd_ptr = epqh->urbd_list.next;
4282                    while (urbd_ptr != &epqh->urbd_list)
4283                    {
4284                        urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, ql);
4285                        urbd_ptr=urbd_ptr->next;
4286                        if(urbd->phase==URBD_IDLE)
4287                        {
4288                            if(assign_hc(_ifxhcd, epqh,urbd))
4289                            {
4290                                IFX_DEBUGPL(DBG_HCD, " select_eps ISOC\n");
4291                                #ifdef __EPQD_DESTROY_TIMEOUT__
4292                                    del_timer(&epqh->destroy_timer);
4293                                #endif
4294                                epqh->isoc_now=0;
4295                                list_del_init (&epqh->ql);
4296                                list_add_tail(&epqh->ql, &_ifxhcd->epqh_list_isoc);
4297                                init_hc(epqh);
4298                                epqh->phase=EPQH_ACTIVE;
4299                                urbd->phase==URBD_ACTIVE;
4300                                epqh->hc.phase=HC_WAITING;
4301                                ifxhcd_hc_start(_ifxhcd, epqh->hc);
4302                            }
4303                            break;
4304                        }
4305                    }
4306                    UNLOCK_URBD_LIST(epqh);
4307                }
4308            }
4309        }
4310    #endif //__EN_ISOC__
4311
4312    epqh_ptr = _ifxhcd->epqh_list_intr.next;
4313    while (epqh_ptr != &_ifxhcd->epqh_list_intr)
4314    {
4315        epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, ql);
4316        epqh_ptr = epqh_ptr->next;
4317        #ifdef __DYN_SOF_INTR__
4318        if (!list_empty(&epqh->urbd_list))
4319            _ifxhcd->dyn_sof_count = DYN_SOF_COUNT_DEF;
4320        #endif
4321        if(epqh->pause)
4322            continue;
4323        if(epqh->phase==EPQH_READY)
4324        {
4325            if(update_interval_counter(epqh,fndiff))
4326            {
4327                LOCK_URBD_LIST(epqh);
4328                urbd_ptr = epqh->urbd_list.next;
4329                while (urbd_ptr != &epqh->urbd_list)
4330                {
4331                    urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, ql);
4332                    urbd_ptr=urbd_ptr->next;
4333                    if(urbd->phase==URBD_IDLE)
4334                    {
4335                        if(assign_hc(_ifxhcd, epqh,urbd))
4336                        {
4337                            IFX_DEBUGPL(DBG_HCD, " select_eps INTR\n");
4338                            #ifdef __EPQD_DESTROY_TIMEOUT__
4339                                del_timer(&epqh->destroy_timer);
4340                            #endif
4341                            list_del_init (&epqh->ql);
4342                            list_add_tail(&epqh->ql, &_ifxhcd->epqh_list_intr);
4343                            init_hc(epqh);
4344                            epqh->phase=EPQH_ACTIVE;
4345                            urbd->phase=URBD_ACTIVE;
4346                            epqh->hc->phase=HC_WAITING;
4347                            ifxhcd_hc_start(_ifxhcd, epqh->hc);
4348                        }
4349                        break;
4350                    }
4351                }
4352                UNLOCK_URBD_LIST(epqh);
4353            }
4354        }
4355        else if(epqh->phase==EPQH_STDBY)
4356        {
4357            if(epqh->period_counter > 0 )
4358                epqh->period_counter --;
4359            if(epqh->period_counter == 0)
4360                ifxhcd_epqh_idle_periodic(epqh);
4361            update_interval_counter(epqh,fndiff);
4362        }
4363        else
4364            update_interval_counter(epqh,fndiff);
4365    }
4366
4367    epqh_ptr = _ifxhcd->epqh_list_np.next;
4368    while (epqh_ptr != &_ifxhcd->epqh_list_np) // may need to preserve at lease one for period
4369    {
4370        epqh = list_entry(epqh_ptr, ifxhcd_epqh_t, ql);
4371        epqh_ptr = epqh_ptr->next;
4372        #ifdef __DYN_SOF_INTR__
4373        if (!list_empty(&epqh->urbd_list))
4374            _ifxhcd->dyn_sof_count = DYN_SOF_COUNT_DEF;
4375        #endif
4376        if(epqh->pause)
4377            continue;
4378        if(epqh->phase==EPQH_READY)
4379        {
4380            LOCK_URBD_LIST(epqh);
4381            urbd_ptr = epqh->urbd_list.next;
4382            while (urbd_ptr != &epqh->urbd_list)
4383            {
4384                urbd = list_entry(urbd_ptr, ifxhcd_urbd_t, ql);
4385                urbd_ptr=urbd_ptr->next;
4386                if(urbd->phase==URBD_IDLE)
4387                {
4388                    if(assign_hc(_ifxhcd, epqh,urbd))
4389                    {
4390                        IFX_DEBUGPL(DBG_HCD, " select_eps Non-Period\n");
4391                        #ifdef __EPQD_DESTROY_TIMEOUT__
4392                            del_timer(&epqh->destroy_timer);
4393                        #endif
4394                        list_del_init (&epqh->ql);
4395                        list_add_tail(&epqh->ql, &_ifxhcd->epqh_list_np);
4396                        init_hc(epqh);
4397                        epqh->phase=EPQH_ACTIVE;
4398                        urbd->phase=URBD_ACTIVE;
4399                        epqh->hc->phase=HC_WAITING;
4400                        ifxhcd_hc_start(_ifxhcd, epqh->hc);
4401                    }
4402                    break;
4403                }
4404            }
4405            UNLOCK_URBD_LIST(epqh);
4406        }
4407    }
4408
4409    _ifxhcd->lastframe=hfnum.b.frnum;
4410
4411    UNLOCK_EPQH_LIST(_ifxhcd);
4412    local_irq_restore(flags);
4413}
4414
4415static
4416void select_eps_func(unsigned long data)
4417{
4418    ifxhcd_hcd_t *ifxhcd;
4419    ifxhcd=((ifxhcd_hcd_t *)data);
4420
4421    select_eps_sub(ifxhcd);
4422}
4423
4424/*!
4425     \fn void select_eps(ifxhcd_hcd_t *_ifxhcd)
4426     \brief This function selects transactions from the HCD transfer schedule and assigns them to available host channels.
4427     \param _ifxhcd Pointer to the sate of HCD structure
4428     \ingroup IFXUSB_HCD
4429 */
4430void select_eps(ifxhcd_hcd_t *_ifxhcd)
4431{
4432    if(in_irq())
4433    {
4434        if(!_ifxhcd->tasklet_select_eps.func)
4435        {
4436            _ifxhcd->tasklet_select_eps.next = NULL;
4437            _ifxhcd->tasklet_select_eps.state = 0;
4438            atomic_set( &_ifxhcd->tasklet_select_eps.count, 0);
4439            _ifxhcd->tasklet_select_eps.func = select_eps_func;
4440            _ifxhcd->tasklet_select_eps.data = (unsigned long)_ifxhcd;
4441        }
4442        tasklet_schedule(&_ifxhcd->tasklet_select_eps);
4443    }
4444    else
4445    {
4446        select_eps_sub(_ifxhcd);
4447    }
4448}
4449
4450static
4451void ifxhcd_hc_kickstart(ifxhcd_hcd_t *_ifxhcd)
4452{
4453    int num_channels;
4454    ifxusb_hc_regs_t *hc_regs;
4455    int i;
4456    ifxhcd_hc_t *ifxhc;
4457    num_channels = _ifxhcd->core_if.params.host_channels;
4458
4459    for (i = 0; i < num_channels; i++)
4460    {
4461        ifxhc=&_ifxhcd->ifxhc[i];
4462        if(ifxhc->phase==HC_STARTING)
4463        {
4464            if(ifxhc->sof_delay) ifxhc->sof_delay--;
4465            if(!ifxhc->sof_delay)
4466            {
4467                hcint_data_t hcint;
4468// ifxhc->erron=0;
4469                hc_regs = _ifxhcd->core_if.hc_regs[i];
4470                hcint.d32 =0xFFFFFFFF;
4471                ifxusb_wreg(&hc_regs->hcint, hcint.d32);
4472                hcint.d32 =ifxusb_rreg(&hc_regs->hcintmsk);
4473                hcint.b.nak =0;
4474                hcint.b.ack =0;
4475                hcint.b.nyet=0;
4476                if(ifxhc->erron)
4477                {
4478                    hcint.b.ack =1;
4479                    hcint.b.nak =1;
4480                    hcint.b.nyet =1;
4481                }
4482                #ifdef __NAKSTOP__
4483                if(ifxhc->stop_on)
4484                {
4485                    hcint.b.ack =1;
4486                    hcint.b.nak =1;
4487                }
4488                #endif
4489                ifxusb_wreg(&hc_regs->hcintmsk, hcint.d32);
4490                ifxusb_wreg(&hc_regs->hcchar, ifxhc->hcchar);
4491                ifxhc->phase=HC_STARTED;
4492            }
4493        }
4494    }
4495
4496    for (i = 0; i < num_channels; i++)
4497    {
4498        ifxhc=&_ifxhcd->ifxhc[i];
4499        if(ifxhc->phase==HC_WAITING &&
4500            (ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
4501          )
4502        {
4503            ifxhcd_hc_start(_ifxhcd, ifxhc);
4504        }
4505    }
4506
4507    for (i = 0; i < num_channels; i++)
4508    {
4509        ifxhc=&_ifxhcd->ifxhc[i];
4510        if(ifxhc->phase==HC_WAITING)
4511        {
4512            ifxhcd_hc_start(_ifxhcd, ifxhc);
4513        }
4514    }
4515}
4516
4517/*
4518 * Handles the start-of-frame interrupt in host mode. Non-periodic
4519 * transactions may be queued to the DWC_otg controller for the current
4520 * (micro)frame. Periodic transactions may be queued to the controller for the
4521 * next (micro)frame.
4522 */
4523static
4524int32_t handle_sof_intr (ifxhcd_hcd_t *_ifxhcd)
4525{
4526    _ifxhcd->pkt_remaining=_ifxhcd->pkt_remaining_reload;
4527    ifxhcd_hc_kickstart(_ifxhcd);
4528
4529    select_eps(_ifxhcd);
4530
4531    /* Clear interrupt */
4532    {
4533        gint_data_t gintsts;
4534        gintsts.d32=0;
4535        gintsts.b.sofintr = 1;
4536        ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
4537
4538        #ifdef __DYN_SOF_INTR__
4539            if(_ifxhcd->dyn_sof_count)
4540                _ifxhcd->dyn_sof_count--;
4541            if(!_ifxhcd->dyn_sof_count)
4542                ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, gintsts.d32,0);
4543        #endif
4544    }
4545    return 1;
4546}
4547
4548
4549
4550/* There are multiple conditions that can cause a port interrupt. This function
4551 * determines which interrupt conditions have occurred and handles them
4552 * appropriately. */
4553static int32_t handle_port_intr (ifxhcd_hcd_t *_ifxhcd)
4554{
4555    int retval = 0;
4556    hprt0_data_t hprt0;
4557    hprt0_data_t hprt0_modify;
4558
4559    hprt0.d32 =
4560    hprt0_modify.d32 = ifxusb_rreg(_ifxhcd->core_if.hprt0);
4561
4562    /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
4563     * GINTSTS */
4564
4565    hprt0_modify.b.prtena = 0;
4566    hprt0_modify.b.prtconndet = 0;
4567    hprt0_modify.b.prtenchng = 0;
4568    hprt0_modify.b.prtovrcurrchng = 0;
4569
4570    /* Port Connect Detected
4571     * Set flag and clear if detected */
4572    if (hprt0.b.prtconndet) {
4573        IFX_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
4574                "Port Connect Detected--\n", hprt0.d32);
4575        _ifxhcd->flags.b.port_connect_status_change = 1;
4576        _ifxhcd->flags.b.port_connect_status = 1;
4577        hprt0_modify.b.prtconndet = 1;
4578
4579        /* The Hub driver asserts a reset when it sees port connect
4580         * status change flag */
4581        retval |= 1;
4582    }
4583
4584    /* Port Enable Changed
4585     * Clear if detected - Set internal flag if disabled */
4586    if (hprt0.b.prtenchng) {
4587        IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
4588                "Port Enable Changed--\n", hprt0.d32);
4589        hprt0_modify.b.prtenchng = 1;
4590        if (hprt0.b.prtena == 1)
4591        {
4592            /* Port has been enabled set the reset change flag */
4593            _ifxhcd->flags.b.port_reset_change = 1;
4594            if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
4595                _ifxhcd->pkt_remaining_reload=_ifxhcd->pkt_remaining_reload_hs;
4596            else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
4597                _ifxhcd->pkt_remaining_reload=_ifxhcd->pkt_remaining_reload_ls;
4598            else
4599                _ifxhcd->pkt_remaining_reload=_ifxhcd->pkt_remaining_reload_fs;
4600        }
4601        else
4602            _ifxhcd->flags.b.port_enable_change = 1;
4603        retval |= 1;
4604    }
4605
4606    /* Overcurrent Change Interrupt */
4607
4608    if (hprt0.b.prtovrcurrchng) {
4609        IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
4610                "Port Overcurrent Changed--\n", hprt0.d32);
4611        _ifxhcd->flags.b.port_over_current_change = 1;
4612        hprt0_modify.b.prtovrcurrchng = 1;
4613        retval |= 1;
4614    }
4615
4616    /* Clear Port Interrupts */
4617    ifxusb_wreg(_ifxhcd->core_if.hprt0, hprt0_modify.d32);
4618    return retval;
4619}
4620
4621/*
4622 * This interrupt indicates that SUSPEND state has been detected on
4623 * the USB.
4624 * No Functioning in Host Mode
4625 */
4626static int32_t handle_usb_suspend_intr(ifxhcd_hcd_t *_ifxhcd)
4627{
4628    gint_data_t gintsts;
4629    IFX_DEBUGP("USB SUSPEND RECEIVED!\n");
4630    /* Clear interrupt */
4631    gintsts.d32 = 0;
4632    gintsts.b.usbsuspend = 1;
4633    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
4634    return 1;
4635}
4636
4637/*
4638 * This interrupt indicates that the IFXUSB controller has detected a
4639 * resume or remote wakeup sequence. If the IFXUSB controller is in
4640 * low power mode, the handler must brings the controller out of low
4641 * power mode. The controller automatically begins resume
4642 * signaling. The handler schedules a time to stop resume signaling.
4643 */
4644static int32_t handle_wakeup_detected_intr(ifxhcd_hcd_t *_ifxhcd)
4645{
4646    gint_data_t gintsts;
4647    hprt0_data_t hprt0 = {.d32=0};
4648    pcgcctl_data_t pcgcctl = {.d32=0};
4649    ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
4650
4651    IFX_DEBUGPL(DBG_ANY, "++Resume and Remote Wakeup Detected Interrupt++\n");
4652
4653    /*
4654     * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
4655     * so that OPT tests pass with all PHYs).
4656     */
4657    /* Restart the Phy Clock */
4658    pcgcctl.b.stoppclk = 1;
4659    ifxusb_mreg(core_if->pcgcctl, pcgcctl.d32, 0);
4660    UDELAY(10);
4661
4662    /* Now wait for 70 ms. */
4663    hprt0.d32 = ifxusb_read_hprt0( core_if );
4664    IFX_DEBUGPL(DBG_ANY,"Resume: HPRT0=%0x\n", hprt0.d32);
4665    MDELAY(70);
4666    hprt0.b.prtres = 0; /* Resume */
4667    ifxusb_wreg(core_if->hprt0, hprt0.d32);
4668    IFX_DEBUGPL(DBG_ANY,"Clear Resume: HPRT0=%0x\n", ifxusb_rreg(core_if->hprt0));
4669
4670    /* Clear interrupt */
4671    gintsts.d32 = 0;
4672    gintsts.b.wkupintr = 1;
4673    ifxusb_wreg(&core_if->core_global_regs->gintsts, gintsts.d32);
4674    return 1;
4675}
4676
4677/*
4678 * This interrupt indicates that a device is initiating the Session
4679 * Request Protocol to request the host to turn on bus power so a new
4680 * session can begin. The handler responds by turning on bus power. If
4681 * the DWC_otg controller is in low power mode, the handler brings the
4682 * controller out of low power mode before turning on bus power.
4683 */
4684static int32_t handle_session_req_intr(ifxhcd_hcd_t *_ifxhcd)
4685{
4686    /* Clear interrupt */
4687    gint_data_t gintsts = { .d32 = 0 };
4688    gintsts.b.sessreqintr = 1;
4689    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
4690    return 1;
4691}
4692
4693/*
4694 * This interrupt indicates that a device has been disconnected from
4695 * the root port.
4696 */
4697static int32_t handle_disconnect_intr(ifxhcd_hcd_t *_ifxhcd)
4698{
4699    gint_data_t gintsts;
4700
4701    ifxhcd_disconnect(_ifxhcd);
4702
4703    gintsts.d32 = 0;
4704    gintsts.b.disconnect = 1;
4705    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
4706    return 1;
4707}
4708
4709/*
4710 * This function handles the Connector ID Status Change Interrupt. It
4711 * reads the OTG Interrupt Register (GOTCTL) to determine whether this
4712 * is a Device to Host Mode transition or a Host Mode to Device
4713 * Transition.
4714 * This only occurs when the cable is connected/removed from the PHY
4715 * connector.
4716 */
4717static int32_t handle_conn_id_status_change_intr(ifxhcd_hcd_t *_ifxhcd)
4718{
4719    gint_data_t gintsts;
4720
4721    IFX_WARN("ID Status Change Interrupt: currently in %s mode\n",
4722         ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device");
4723
4724    gintsts.d32 = 0;
4725    gintsts.b.conidstschng = 1;
4726    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
4727    return 1;
4728}
4729
4730static int32_t handle_otg_intr(ifxhcd_hcd_t *_ifxhcd)
4731{
4732    ifxusb_core_global_regs_t *global_regs = _ifxhcd->core_if.core_global_regs;
4733    gotgint_data_t gotgint;
4734    gotgint.d32 = ifxusb_rreg( &global_regs->gotgint);
4735    /* Clear GOTGINT */
4736    ifxusb_wreg (&global_regs->gotgint, gotgint.d32);
4737    return 1;
4738}
4739
4740/** This function will log a debug message */
4741static int32_t handle_mode_mismatch_intr(ifxhcd_hcd_t *_ifxhcd)
4742{
4743    gint_data_t gintsts;
4744
4745    IFX_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
4746         ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device");
4747    gintsts.d32 = 0;
4748    gintsts.b.modemismatch = 1;
4749    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
4750    return 1;
4751}
4752
4753/** This function handles interrupts for the HCD. */
4754int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd)
4755{
4756    int retval = 0;
4757
4758    ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
4759    gint_data_t gintsts,gintsts2;
4760
4761    /* Check if HOST Mode */
4762    if (ifxusb_is_device_mode(core_if))
4763    {
4764        IFX_ERROR("%s() CRITICAL! IN DEVICE MODE\n", __func__);
4765        return 0;
4766    }
4767
4768    gintsts.d32 = ifxusb_read_core_intr(core_if);
4769    gintsts2.d32 = 0;
4770
4771    if (!gintsts.d32)
4772        return 0;
4773
4774    //Common INT
4775    if (gintsts.b.modemismatch)
4776    {
4777        retval |= handle_mode_mismatch_intr(_ifxhcd);
4778        gintsts.b.modemismatch=0;
4779        gintsts2.b.modemismatch=1;
4780    }
4781    if (gintsts.b.otgintr)
4782    {
4783        retval |= handle_otg_intr(_ifxhcd);
4784        gintsts.b.otgintr=0;
4785        gintsts2.b.otgintr=1;
4786    }
4787    if (gintsts.b.conidstschng)
4788    {
4789        retval |= handle_conn_id_status_change_intr(_ifxhcd);
4790        gintsts.b.conidstschng=0;
4791        gintsts2.b.conidstschng=1;
4792    }
4793    if (gintsts.b.disconnect)
4794    {
4795        retval |= handle_disconnect_intr(_ifxhcd);
4796        gintsts.b.disconnect=0;
4797        gintsts2.b.disconnect=1;
4798    }
4799    if (gintsts.b.sessreqintr)
4800    {
4801        retval |= handle_session_req_intr(_ifxhcd);
4802        gintsts.b.sessreqintr=0;
4803        gintsts2.b.sessreqintr=1;
4804    }
4805    if (gintsts.b.wkupintr)
4806    {
4807        retval |= handle_wakeup_detected_intr(_ifxhcd);
4808        gintsts.b.wkupintr=0;
4809        gintsts2.b.wkupintr=1;
4810    }
4811    if (gintsts.b.usbsuspend)
4812    {
4813        retval |= handle_usb_suspend_intr(_ifxhcd);
4814        gintsts.b.usbsuspend=0;
4815        gintsts2.b.usbsuspend=1;
4816    }
4817
4818    //Host Int
4819    if (gintsts.b.sofintr)
4820    {
4821        retval |= handle_sof_intr (_ifxhcd);
4822        gintsts.b.sofintr=0;
4823        gintsts2.b.sofintr=1;
4824    }
4825    if (gintsts.b.portintr)
4826    {
4827        retval |= handle_port_intr (_ifxhcd);
4828        gintsts.b.portintr=0;
4829        gintsts2.b.portintr=1;
4830    }
4831    if (gintsts.b.hcintr)
4832    {
4833        int i;
4834        haint_data_t haint;
4835        haint.d32 = ifxusb_read_host_all_channels_intr(core_if);
4836        for (i=0; i<MAX_EPS_CHANNELS && i< core_if->params.host_channels; i++)
4837            if (haint.b2.chint & (1 << i))
4838                retval |= handle_hc_n_intr (_ifxhcd, i);
4839        gintsts.b.hcintr=0;
4840        gintsts2.b.hcintr=1;
4841    }
4842    return retval;
4843}
4844
4845

Archive Download this file



interactive