Root/target/linux/lantiq/files/drivers/usb/ifxhcd/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 : 1.0
6 ** DATE : 1/Jan/2009
7 ** AUTHOR : Chen, Howard
8 ** DESCRIPTION : This file contains the implementation of the HCD Interrupt handlers.
9 *****************************************************************************/
10
11/*!
12 \file ifxhcd_intr.c
13 \ingroup IFXUSB_DRIVER_V3
14 \brief This file contains the implementation of the HCD Interrupt handlers.
15*/
16
17
18#include <linux/version.h>
19#include "ifxusb_version.h"
20
21#include "ifxusb_plat.h"
22#include "ifxusb_regs.h"
23#include "ifxusb_cif.h"
24
25#include "ifxhcd.h"
26
27/* AVM/WK 20100520*/
28#ifdef __EN_ISOC__
29#error AVM/WK: CONFIG_USB_HOST_IFX_WITH_ISO currently not supported!
30#endif
31
32/* Macro used to clear one channel interrupt */
33#define clear_hc_int(_hc_regs_,_intr_) \
34    do { \
35        hcint_data_t hcint_clear = {.d32 = 0}; \
36        hcint_clear.b._intr_ = 1; \
37        ifxusb_wreg(&((_hc_regs_)->hcint), hcint_clear.d32); \
38    } while (0)
39
40/*
41 * Macro used to disable one channel interrupt. Channel interrupts are
42 * disabled when the channel is halted or released by the interrupt handler.
43 * There is no need to handle further interrupts of that type until the
44 * channel is re-assigned. In fact, subsequent handling may cause crashes
45 * because the channel structures are cleaned up when the channel is released.
46 */
47#define disable_hc_int(_hc_regs_,_intr_) \
48    do { \
49        hcint_data_t hcintmsk = {.d32 = 0}; \
50        hcintmsk.b._intr_ = 1; \
51        ifxusb_mreg(&((_hc_regs_)->hcintmsk), hcintmsk.d32, 0); \
52    } while (0)
53
54#define enable_hc_int(_hc_regs_,_intr_) \
55    do { \
56        hcint_data_t hcintmsk = {.d32 = 0}; \
57        hcintmsk.b._intr_ = 1; \
58        ifxusb_mreg(&((_hc_regs_)->hcintmsk),0, hcintmsk.d32); \
59    } while (0)
60
61/*
62 * Save the starting data toggle for the next transfer. The data toggle is
63 * saved in the QH for non-control transfers and it's saved in the QTD for
64 * control transfers.
65 */
66uint8_t read_data_toggle(ifxusb_hc_regs_t *_hc_regs)
67{
68    hctsiz_data_t hctsiz;
69    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
70    return(hctsiz.b.pid);
71}
72
73
74static void release_channel_dump(ifxhcd_hc_t *ifxhc,
75                               struct urb *urb,
76                               ifxhcd_epqh_t *epqh,
77                               ifxhcd_urbd_t *urbd,
78                               ifxhcd_halt_status_e halt_status)
79{
80    #ifdef __DEBUG__
81        printk(KERN_INFO);
82        switch (halt_status)
83        {
84            case HC_XFER_NO_HALT_STATUS:
85                printk("HC_XFER_NO_HALT_STATUS");break;
86            case HC_XFER_URB_COMPLETE:
87                printk("HC_XFER_URB_COMPLETE");break;
88            case HC_XFER_AHB_ERR:
89                printk("HC_XFER_AHB_ERR");break;
90            case HC_XFER_STALL:
91                printk("HC_XFER_STALL");break;
92            case HC_XFER_BABBLE_ERR:
93                printk("HC_XFER_BABBLE_ERR");break;
94            case HC_XFER_XACT_ERR:
95                printk("HC_XFER_XACT_ERR");break;
96            case HC_XFER_URB_DEQUEUE:
97                printk("HC_XFER_URB_DEQUEUE");break;
98            case HC_XFER_FRAME_OVERRUN:
99                printk("HC_XFER_FRAME_OVERRUN");break;
100            case HC_XFER_DATA_TOGGLE_ERR:
101                printk("HC_XFER_DATA_TOGGLE_ERR");break;
102            case HC_XFER_NAK:
103                printk("HC_XFER_NAK");break;
104            case HC_XFER_COMPLETE:
105                printk("HC_XFER_COMPLETE");break;
106            default:
107                printk("KNOWN");break;
108        }
109        if(ifxhc)
110            printk("Ch %d %s%s S%d " , ifxhc->hc_num
111                ,(ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL)?"CTRL-":
112                   ((ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)?"BULK-":
113                     ((ifxhc->ep_type == IFXUSB_EP_TYPE_INTR)?"INTR-":
114                       ((ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)?"ISOC-":"????"
115                       )
116                     )
117                   )
118                ,(ifxhc->is_in)?"IN":"OUT"
119                ,(ifxhc->split)
120                );
121        else
122            printk(" [NULL HC] ");
123        printk("urb=%p epqh=%p urbd=%p\n",urb,epqh,urbd);
124
125        if(urb)
126        {
127            printk(KERN_INFO " Device address: %d\n", usb_pipedevice(urb->pipe));
128            printk(KERN_INFO " Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
129                    (usb_pipein(urb->pipe) ? "IN" : "OUT"));
130            printk(KERN_INFO " Endpoint type: %s\n",
131                    ({char *pipetype;
132                    switch (usb_pipetype(urb->pipe)) {
133                        case PIPE_CONTROL: pipetype = "CTRL"; break;
134                        case PIPE_BULK: pipetype = "BULK"; break;
135                        case PIPE_INTERRUPT: pipetype = "INTR"; break;
136                        case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break;
137                        default: pipetype = "????"; break;
138                    }; pipetype;}));
139            printk(KERN_INFO " Speed: %s\n",
140                    ({char *speed;
141                    switch (urb->dev->speed) {
142                        case USB_SPEED_HIGH: speed = "HS"; break;
143                        case USB_SPEED_FULL: speed = "FS"; break;
144                        case USB_SPEED_LOW: speed = "LS"; break;
145                        default: speed = "????"; break;
146                    }; speed;}));
147            printk(KERN_INFO " Max packet size: %d\n",
148                    usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
149            printk(KERN_INFO " Data buffer length: %d\n", urb->transfer_buffer_length);
150            printk(KERN_INFO " Transfer buffer: %p, Transfer DMA: %p\n",
151                    urb->transfer_buffer, (void *)urb->transfer_dma);
152            printk(KERN_INFO " Setup buffer: %p, Setup DMA: %p\n",
153                    urb->setup_packet, (void *)urb->setup_dma);
154            printk(KERN_INFO " Interval: %d\n", urb->interval);
155            switch (urb->status)
156            {
157                case HC_XFER_NO_HALT_STATUS:
158                    printk(KERN_INFO " STATUS:HC_XFER_NO_HALT_STATUS\n");break;
159                case HC_XFER_URB_COMPLETE:
160                    printk(KERN_INFO " STATUS:HC_XFER_URB_COMPLETE\n");break;
161                case HC_XFER_AHB_ERR:
162                    printk(KERN_INFO " STATUS:HC_XFER_AHB_ERR\n");break;
163                case HC_XFER_STALL:
164                    printk(KERN_INFO " STATUS:HC_XFER_STALL\n");break;
165                case HC_XFER_BABBLE_ERR:
166                    printk(KERN_INFO " STATUS:HC_XFER_BABBLE_ERR\n");break;
167                case HC_XFER_XACT_ERR:
168                    printk(KERN_INFO " STATUS:HC_XFER_XACT_ERR\n");break;
169                case HC_XFER_URB_DEQUEUE:
170                    printk(KERN_INFO " STATUS:HC_XFER_URB_DEQUEUE\n");break;
171                case HC_XFER_FRAME_OVERRUN:
172                    printk(KERN_INFO " STATUS:HC_XFER_FRAME_OVERRUN\n");break;
173                case HC_XFER_DATA_TOGGLE_ERR:
174                    printk(KERN_INFO " STATUS:HC_XFER_DATA_TOGGLE_ERR\n");break;
175                case HC_XFER_COMPLETE:
176                    printk(KERN_INFO " STATUS:HC_XFER_COMPLETE\n");break;
177                default:
178                    printk(KERN_INFO " STATUS:KNOWN\n");break;
179            }
180        }
181    #endif
182}
183
184
185static void release_channel(ifxhcd_hcd_t *_ifxhcd,
186                            ifxhcd_hc_t *_ifxhc,
187                            ifxhcd_halt_status_e _halt_status)
188{
189    ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num];
190    struct urb *urb = NULL;
191    ifxhcd_epqh_t *epqh = NULL;
192    ifxhcd_urbd_t *urbd = NULL;
193
194    IFX_DEBUGPL(DBG_HCDV, " %s: channel %d, halt_status %d\n",
195            __func__, _ifxhc->hc_num, _halt_status);
196
197    epqh=_ifxhc->epqh;
198
199    if(!epqh)
200        IFX_ERROR("%s epqh=null\n",__func__);
201    else
202    {
203        urbd=epqh->urbd;
204        if(!urbd)
205            IFX_ERROR("%s urbd=null\n",__func__);
206        else
207        {
208            urb=urbd->urb;
209            if(!urb)
210                IFX_ERROR("%s urb =null\n",__func__);
211            else {
212                /* == AVM/WK 20100710 Fix - Use toggle of usbcore ==*/
213                unsigned toggle = (read_data_toggle(hc_regs) == IFXUSB_HC_PID_DATA0)? 0: 1;
214                usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), usb_pipeout(urb->pipe), toggle);
215            }
216        }
217        //epqh->data_toggle = read_data_toggle(hc_regs);
218
219    }
220
221    switch (_halt_status)
222    {
223        case HC_XFER_NO_HALT_STATUS:
224            IFX_ERROR("%s: No halt_status, channel %d\n", __func__, _ifxhc->hc_num);
225            break;
226        case HC_XFER_COMPLETE:
227            IFX_ERROR("%s: Inavalid halt_status HC_XFER_COMPLETE, channel %d\n", __func__, _ifxhc->hc_num);
228            break;
229        case HC_XFER_URB_COMPLETE:
230        case HC_XFER_URB_DEQUEUE:
231        case HC_XFER_AHB_ERR:
232        case HC_XFER_XACT_ERR:
233        case HC_XFER_FRAME_OVERRUN:
234            if(urbd && urb) {
235                /* == 20110803 AVM/WK FIX set status, if still in progress == */
236                if (urb->status == -EINPROGRESS) {
237                    switch (_halt_status) {
238                    case HC_XFER_URB_COMPLETE:
239                        urb->status = 0;
240                        break;
241                    case HC_XFER_URB_DEQUEUE:
242                        urb->status = -ECONNRESET;
243                        break;
244                    case HC_XFER_AHB_ERR:
245                    case HC_XFER_XACT_ERR:
246                    case HC_XFER_FRAME_OVERRUN:
247                        urb->status = -EPROTO;
248                        break;
249                    default:
250                        break;
251                    }
252                }
253                /*== AVM/BC 20101111 Deferred Complete ==*/
254                defer_ifxhcd_complete_urb(_ifxhcd, urbd, urb->status);
255            }
256            else
257            {
258                IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
259                release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
260            }
261            if(epqh)
262                ifxhcd_epqh_idle(_ifxhcd, epqh);
263            else
264            {
265                IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
266                release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
267            }
268
269            list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list);
270            ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
271            break;
272        case HC_XFER_STALL:
273            release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
274            if(urbd)
275                /*== AVM/BC 20101111 Deferred Complete ==*/
276                defer_ifxhcd_complete_urb(_ifxhcd, urbd, -EPIPE);
277            else
278                IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
279            if(epqh)
280            {
281// epqh->data_toggle = 0;
282                ifxhcd_epqh_idle(_ifxhcd, epqh);
283            }
284            else
285                IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
286            list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list);
287            ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
288            break;
289        case HC_XFER_NAK:
290            release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
291            if(urbd)
292            {
293                //ifxhcd_complete_urb(_ifxhcd, urbd, -ETIMEDOUT);
294                urb->status = 0;
295                /*== AVM/BC 20101111 Deferred Complete ==*/
296                defer_ifxhcd_complete_urb(_ifxhcd, urbd, urb->status);
297            }
298            else
299                IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
300            if(epqh)
301                ifxhcd_epqh_idle(_ifxhcd, epqh);
302            else
303                IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
304            list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list);
305            ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
306            break;
307        case HC_XFER_BABBLE_ERR:
308        case HC_XFER_DATA_TOGGLE_ERR:
309            release_channel_dump(_ifxhc,urb,epqh,urbd,_halt_status);
310            if(urbd)
311                /*== AVM/BC 20101111 Deferred Complete ==*/
312                defer_ifxhcd_complete_urb(_ifxhcd, urbd, -EOVERFLOW);
313            else
314                IFX_WARN("WARNING %s():%d urbd=%p urb=%p\n",__func__,__LINE__,urbd,urb);
315            if(epqh)
316                ifxhcd_epqh_idle(_ifxhcd, epqh);
317            else
318                IFX_WARN("WARNING %s():%d epqh=%p\n",__func__,__LINE__,epqh);
319            list_add_tail(&_ifxhc->hc_list_entry, &_ifxhcd->free_hc_list);
320            ifxhcd_hc_cleanup(&_ifxhcd->core_if, _ifxhc);
321            break;
322    }
323    select_eps(_ifxhcd);
324}
325
326/*
327 * Updates the state of the URB after a Transfer Complete interrupt on the
328 * host channel. Updates the actual_length field of the URB based on the
329 * number of bytes transferred via the host channel. Sets the URB status
330 * if the data transfer is finished.
331 *
332 * @return 1 if the data transfer specified by the URB is completely finished,
333 * 0 otherwise.
334 */
335static int update_urb_state_xfer_comp(ifxhcd_hc_t *_ifxhc,
336                                      ifxusb_hc_regs_t *_hc_regs,
337                                      struct urb *_urb,
338                                      ifxhcd_urbd_t *_urbd)
339{
340    int xfer_done = 0;
341
342    if (_ifxhc->is_in)
343    {
344        hctsiz_data_t hctsiz;
345        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
346        _urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
347        if ((hctsiz.b.xfersize != 0) || (_urb->actual_length >= _urb->transfer_buffer_length))
348        {
349            xfer_done = 1;
350            _urb->status = 0;
351            /* 20110805 AVM/WK Workaround: catch overflow error here, hardware does not */
352            if (_urb->actual_length > _urb->transfer_buffer_length) {
353                _urb->status = -EOVERFLOW;
354            }
355            #if 0
356                if (_urb->actual_length < _urb->transfer_buffer_length && _urb->transfer_flags & URB_SHORT_NOT_OK)
357                _urb->status = -EREMOTEIO;
358            #endif
359        }
360
361    }
362    else
363    {
364        if (_ifxhc->split)
365            _urb->actual_length += _ifxhc->ssplit_out_xfer_count;
366        else
367            _urb->actual_length += _ifxhc->xfer_len;
368
369        if (_urb->actual_length >= _urb->transfer_buffer_length)
370        {
371            /*== AVM/BC WK 20110421 ZERO PACKET Workaround ==*/
372            if ((_ifxhc->short_rw == 1) && ( _ifxhc->xfer_len > 0) && ( _ifxhc->xfer_len % _ifxhc->mps == 0 ))
373            {
374                _ifxhc->short_rw = 0;
375                //Transfer not finished. Another iteration for ZLP.
376            }
377            else
378            {
379                xfer_done = 1;
380            }
381            _urb->status = 0;
382        }
383    }
384
385    #ifdef __DEBUG__
386        {
387            hctsiz_data_t hctsiz;
388            hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
389            IFX_DEBUGPL(DBG_HCDV, "IFXUSB: %s: %s, channel %d\n",
390                    __func__, (_ifxhc->is_in ? "IN" : "OUT"), _ifxhc->hc_num);
391            IFX_DEBUGPL(DBG_HCDV, " hc->xfer_len %d\n", _ifxhc->xfer_len);
392            IFX_DEBUGPL(DBG_HCDV, " hctsiz.xfersize %d\n", hctsiz.b.xfersize);
393            IFX_DEBUGPL(DBG_HCDV, " urb->transfer_buffer_length %d\n",
394                    _urb->transfer_buffer_length);
395            IFX_DEBUGPL(DBG_HCDV, " urb->actual_length %d\n", _urb->actual_length);
396        }
397    #endif
398    return xfer_done;
399}
400
401/*== AVM/BC 20101111 Function called with Lock ==*/
402
403void complete_channel(ifxhcd_hcd_t *_ifxhcd,
404                            ifxhcd_hc_t *_ifxhc,
405                            ifxhcd_urbd_t *_urbd)
406{
407    ifxusb_hc_regs_t *hc_regs = _ifxhcd->core_if.hc_regs[_ifxhc->hc_num];
408    struct urb *urb = NULL;
409    ifxhcd_epqh_t *epqh = NULL;
410    int urb_xfer_done;
411
412    IFX_DEBUGPL(DBG_HCD, "--Complete Channel %d : \n", _ifxhc->hc_num);
413
414    if(!_urbd)
415    {
416        IFX_ERROR("ERROR %s():%d urbd=%p\n",__func__,__LINE__,_urbd);
417        return;
418    }
419
420    urb = _urbd->urb;
421    epqh = _urbd->epqh;
422
423    if(!urb || !epqh)
424    {
425        IFX_ERROR("ERROR %s():%d urb=%p epqh=%p\n",__func__,__LINE__,urb,epqh);
426        return;
427    }
428
429    _ifxhc->do_ping=0;
430
431    if (_ifxhc->split)
432        _ifxhc->split = 1;
433
434    switch (epqh->ep_type)
435    {
436        case IFXUSB_EP_TYPE_CTRL:
437            switch (_ifxhc->control_phase)
438            {
439                case IFXHCD_CONTROL_SETUP:
440                    IFX_DEBUGPL(DBG_HCDV, " Control setup transaction done\n");
441                    if (_urbd->xfer_len > 0)
442                    {
443                        _ifxhc->control_phase = IFXHCD_CONTROL_DATA;
444                        _ifxhc->is_in = _urbd->is_in;
445                        _ifxhc->xfer_len = _urbd->xfer_len;
446                        #if defined(__UNALIGNED_BUFFER_ADJ__)
447                            if(epqh->using_aligned_buf)
448                                _ifxhc->xfer_buff = epqh->aligned_buf;
449                            else
450                        #endif
451                                _ifxhc->xfer_buff = _urbd->xfer_buff;
452                    }
453                    else
454                    {
455                        _ifxhc->control_phase = IFXHCD_CONTROL_STATUS;
456                        _ifxhc->is_in = 1;
457                        _ifxhc->xfer_len = 0;
458                        _ifxhc->xfer_buff = _ifxhcd->status_buf;
459                    }
460                    if(_ifxhc->is_in)
461                        _ifxhc->short_rw =0;
462                    else
463                        _ifxhc->short_rw =(urb->transfer_flags & URB_ZERO_PACKET)?1:0;
464                    _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
465                    _ifxhc->xfer_count = 0;
466                    _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
467                    /*== AVM/BC 20101111 Lock not needed ==*/
468                    process_channels_sub(_ifxhcd);
469                    break;
470                case IFXHCD_CONTROL_DATA:
471                    urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
472                    if (urb_xfer_done)
473                    {
474                        _ifxhc->control_phase = IFXHCD_CONTROL_STATUS;
475                        _ifxhc->is_in = (_urbd->is_in)?0:1;
476                        _ifxhc->xfer_len = 0;
477                        _ifxhc->xfer_count = 0;
478                        _ifxhc->xfer_buff = _ifxhcd->status_buf;
479                        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
480                        _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
481                        if(_ifxhc->is_in)
482                            _ifxhc->short_rw =0;
483                        else
484                            _ifxhc->short_rw =1;
485                    }
486                    else // continue
487                    {
488                        _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length;
489                        _ifxhc->xfer_count = urb->actual_length;
490                        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
491                        _ifxhc->data_pid_start = read_data_toggle(hc_regs);
492                    }
493                    /*== AVM/BC 20101111 Lock not needed ==*/
494                    process_channels_sub(_ifxhcd);
495                    break;
496                case IFXHCD_CONTROL_STATUS:
497                    if (urb->status == -EINPROGRESS)
498                        urb->status = 0;
499                    release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
500                    break;
501            }
502            break;
503        case IFXUSB_EP_TYPE_BULK:
504            IFX_DEBUGPL(DBG_HCDV, " Bulk transfer complete\n");
505            urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
506            if (urb_xfer_done)
507                release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
508            else
509            {
510                _ifxhc->xfer_len = _urbd->xfer_len - urb->actual_length;
511                _ifxhc->xfer_count = urb->actual_length;
512                _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
513                _ifxhc->data_pid_start = read_data_toggle(hc_regs);
514                /*== AVM/BC 20101111 Lock not needed ==*/
515                process_channels_sub(_ifxhcd);
516            }
517            break;
518        case IFXUSB_EP_TYPE_INTR:
519            urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
520            release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
521            break;
522        case IFXUSB_EP_TYPE_ISOC:
523// if (_urbd->isoc_split_pos == IFXUSB_HCSPLIT_XACTPOS_ALL)
524// halt_status = update_isoc_urb_state(_ifxhcd, _ifxhc, hc_regs, _urbd, HC_XFER_COMPLETE);
525// complete_periodic_xfer(_ifxhcd, _ifxhc, hc_regs, _urbd, halt_status);
526            urb_xfer_done = update_urb_state_xfer_comp(_ifxhc, hc_regs, urb, _urbd);
527            release_channel(_ifxhcd,_ifxhc,HC_XFER_URB_COMPLETE);
528            break;
529    }
530}
531
532
533
534void showint(uint32_t val_hcint
535            ,uint32_t val_hcintmsk
536            ,uint32_t val_hctsiz)
537{
538#ifdef __DEBUG__
539    hcint_data_t hcint = {.d32 = val_hcint};
540    hcint_data_t hcintmsk = {.d32 = val_hcintmsk};
541
542    printk(KERN_INFO " WITH FLAG: Sz:%08x I:%08X/M:%08X %s%s%s%s%s%s%s%s%s%s\n"
543        ,val_hctsiz,hcint.d32 ,hcintmsk.d32
544        ,(hcint.b.datatglerr || hcintmsk.b.datatglerr)?
545         (
546           (hcint.b.datatglerr && hcintmsk.b.datatglerr)?"datatglerr[*/*] ":
547            (
548              (hcint.b.datatglerr)?"datatglerr[*/] ":"datatglerr[/*] "
549            )
550         )
551         :""
552        ,(hcint.b.frmovrun || hcintmsk.b.frmovrun)?
553         (
554           (hcint.b.frmovrun && hcintmsk.b.frmovrun)?"frmovrun[*/*] ":
555            (
556              (hcint.b.frmovrun)?"frmovrun[*/] ":"frmovrun[/*] "
557            )
558         )
559         :""
560        ,(hcint.b.bblerr || hcintmsk.b.bblerr)?
561         (
562           (hcint.b.bblerr && hcintmsk.b.bblerr)?"bblerr[*/*] ":
563            (
564              (hcint.b.bblerr)?"bblerr[*/] ":"bblerr[/*] "
565            )
566         )
567         :""
568        ,(hcint.b.xacterr || hcintmsk.b.xacterr)?
569         (
570           (hcint.b.xacterr && hcintmsk.b.xacterr)?"xacterr[*/*] ":
571            (
572              (hcint.b.xacterr)?"xacterr[*/] ":"xacterr[/*] "
573            )
574         )
575         :""
576        ,(hcint.b.nyet || hcintmsk.b.nyet)?
577         (
578           (hcint.b.nyet && hcintmsk.b.nyet)?"nyet[*/*] ":
579            (
580              (hcint.b.nyet)?"nyet[*/] ":"nyet[/*] "
581            )
582         )
583         :""
584        ,(hcint.b.nak || hcintmsk.b.nak)?
585         (
586           (hcint.b.nak && hcintmsk.b.nak)?"nak[*/*] ":
587            (
588              (hcint.b.nak)?"nak[*/] ":"nak[/*] "
589            )
590         )
591         :""
592        ,(hcint.b.ack || hcintmsk.b.ack)?
593         (
594           (hcint.b.ack && hcintmsk.b.ack)?"ack[*/*] ":
595            (
596              (hcint.b.ack)?"ack[*/] ":"ack[/*] "
597            )
598         )
599         :""
600        ,(hcint.b.stall || hcintmsk.b.stall)?
601         (
602           (hcint.b.stall && hcintmsk.b.stall)?"stall[*/*] ":
603            (
604              (hcint.b.stall)?"stall[*/] ":"stall[/*] "
605            )
606         )
607         :""
608        ,(hcint.b.ahberr || hcintmsk.b.ahberr)?
609         (
610           (hcint.b.ahberr && hcintmsk.b.ahberr)?"ahberr[*/*] ":
611            (
612              (hcint.b.ahberr)?"ahberr[*/] ":"ahberr[/*] "
613            )
614         )
615         :""
616        ,(hcint.b.xfercomp || hcintmsk.b.xfercomp)?
617         (
618           (hcint.b.xfercomp && hcintmsk.b.xfercomp)?"xfercomp[*/*] ":
619            (
620              (hcint.b.xfercomp)?"xfercomp[*/] ":"xfercomp[/*] "
621            )
622         )
623         :""
624    );
625#endif
626}
627
628
629extern void ifxhcd_hc_dumb_rx(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc,uint8_t *dump_buf);
630
631////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
632////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
633////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
634static int32_t chhltd_ctrlbulk_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
635                                        ifxhcd_hc_t *_ifxhc,
636                                        ifxusb_hc_regs_t *_hc_regs,
637                                        ifxhcd_urbd_t *_urbd)
638{
639    hcint_data_t hcint;
640    hcint_data_t hcintmsk;
641    hctsiz_data_t hctsiz;
642
643    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
644    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
645    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
646
647    disable_hc_int(_hc_regs,ack);
648    disable_hc_int(_hc_regs,nak);
649    disable_hc_int(_hc_regs,nyet);
650    _ifxhc->do_ping = 0;
651
652    if(_ifxhc->halt_status == HC_XFER_NAK)
653    {
654        if(_ifxhc->nak_retry_r)
655        {
656            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
657            _ifxhc->nak_retry--;
658            if(_ifxhc->nak_retry)
659            {
660                _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
661                _ifxhc->xfer_count = _urbd->urb->actual_length;
662                _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
663                _ifxhc->wait_for_sof = 1;
664                _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
665                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
666            }
667            else
668            {
669                _ifxhc->wait_for_sof = 0;
670                release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
671            }
672        }
673        else
674        {
675            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
676            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
677            _ifxhc->xfer_count = _urbd->urb->actual_length;
678            _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
679            _ifxhc->wait_for_sof = 1;
680            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
681            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
682        }
683        return 1;
684    }
685
686    if (hcint.b.xfercomp)
687    {
688        _urbd->error_count =0;
689        _ifxhc->wait_for_sof =0;
690        complete_channel(_ifxhcd, _ifxhc, _urbd);
691        return 1;
692    }
693    else if (hcint.b.stall)
694    {
695        _urbd->error_count =0;
696        _ifxhc->wait_for_sof =0;
697        // ZLP shortcut
698        #if 0
699        if(hctsiz.b.pktcnt==0)
700            complete_channel(_ifxhcd, _ifxhc, _urbd);
701        else
702        #endif
703        {
704        // Stall FIFO compensation.
705        #if 0
706            int sz1,sz2;
707            sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt;
708            sz2*=_ifxhc->mps;
709            sz1=_ifxhc->xfer_len - hctsiz.b.xfersize;
710            sz2-=sz1;
711            if(sz2)
712                ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf);
713        #endif
714            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
715            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
716        }
717        return 1;
718    }
719    else if (hcint.b.bblerr)
720    {
721        _urbd->error_count =0;
722        _ifxhc->wait_for_sof =0;
723
724        // ZLP shortcut
725        #if 0
726        if(hctsiz.b.pktcnt==0)
727            complete_channel(_ifxhcd, _ifxhc, _urbd);
728        else
729        #endif
730        _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
731        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
732        return 1;
733    }
734    else if (hcint.b.xacterr)
735    {
736        // ZLP shortcut
737        #if 1
738        if(hctsiz.b.pktcnt==0)
739        {
740            _urbd->error_count =0;
741            _ifxhc->wait_for_sof =0;
742            complete_channel(_ifxhcd, _ifxhc, _urbd);
743        }
744        else
745        #endif
746        {
747            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
748            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
749            _ifxhc->xfer_count = _urbd->urb->actual_length;
750            _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
751
752            /* 20110803 AVM/WK FIX: Reset error count on any handshake */
753            if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) {
754                _urbd->error_count = 1;
755            } else {
756                _urbd->error_count++;
757            }
758
759            if (_urbd->error_count >= 3)
760            {
761                _urbd->error_count =0;
762                _ifxhc->wait_for_sof =0;
763                release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
764            }
765            else
766            {
767                _ifxhc->wait_for_sof = 1;
768                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
769            }
770        }
771        return 1;
772    }
773    else if(hcint.b.datatglerr )
774    {
775        _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
776        #if 1
777            if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
778                _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
779            else
780                _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
781            _ifxhc->wait_for_sof = 1;
782            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
783            _ifxhc->xfer_count = _urbd->urb->actual_length;
784            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
785        #else
786            release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
787        #endif
788        return 1;
789    }
790    else if(hcint.b.frmovrun )
791    {
792IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT0 FRMOVRUN [should be Period only]\n",__func__,__LINE__);
793showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
794        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
795        return 1;
796    }
797    else if(hcint.b.nyet )
798    {
799IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT0 NYET [should be Out only]\n",__func__,__LINE__);
800showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
801    }
802    return 0;
803}
804////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
805static int32_t chhltd_ctrlbulk_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
806                                        ifxhcd_hc_t *_ifxhc,
807                                        ifxusb_hc_regs_t *_hc_regs,
808                                        ifxhcd_urbd_t *_urbd)
809{
810    hcint_data_t hcint;
811    hcint_data_t hcintmsk;
812    hctsiz_data_t hctsiz;
813    int out_nak_enh = 0;
814
815#ifdef __DEBUG__
816static int first=0;
817#endif
818
819    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
820        out_nak_enh = 1;
821
822    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
823    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
824    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
825
826#ifdef __DEBUG__
827if(!first&& _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK
828   &&(hcint.b.stall || hcint.b.datatglerr || hcint.b.frmovrun || hcint.b.bblerr || hcint.b.xacterr) && !hcint.b.ack)
829{
830    showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
831    first=1;
832    printk(KERN_INFO " [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X] \n"
833    ,*(_ifxhc->xfer_buff+ 0),*(_ifxhc->xfer_buff+ 1),*(_ifxhc->xfer_buff+ 2),*(_ifxhc->xfer_buff+ 3)
834    ,*(_ifxhc->xfer_buff+ 4),*(_ifxhc->xfer_buff+ 5),*(_ifxhc->xfer_buff+ 6),*(_ifxhc->xfer_buff+ 7)
835    ,*(_ifxhc->xfer_buff+ 8),*(_ifxhc->xfer_buff+ 9),*(_ifxhc->xfer_buff+10),*(_ifxhc->xfer_buff+11)
836    ,*(_ifxhc->xfer_buff+12),*(_ifxhc->xfer_buff+13),*(_ifxhc->xfer_buff+14),*(_ifxhc->xfer_buff+15));
837
838    printk(KERN_INFO " [_urbd->urb->actual_length:%08X _ifxhc->start_pkt_count:%08X hctsiz.b.pktcnt:%08X ,_urbd->xfer_len:%08x] \n"
839    ,_urbd->urb->actual_length
840    ,_ifxhc->start_pkt_count
841    ,hctsiz.b.pktcnt
842    ,_urbd->xfer_len);
843}
844#endif
845
846    if(_ifxhc->halt_status == HC_XFER_NAK)
847    {
848        if(_ifxhc->nak_retry_r)
849        {
850            _ifxhc->nak_retry--;
851            if(_ifxhc->nak_retry)
852            {
853                if(_ifxhc->xfer_len!=0)
854                    _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
855                _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
856                _ifxhc->xfer_count = _urbd->urb->actual_length;
857                _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
858                _ifxhc->wait_for_sof = 1;
859                _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
860                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
861            }
862            else
863            {
864                _ifxhc->wait_for_sof = 0;
865                release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
866            }
867        }
868        else
869        {
870            if(_ifxhc->xfer_len!=0)
871                _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
872            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
873            _ifxhc->xfer_count = _urbd->urb->actual_length;
874            _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
875            _ifxhc->wait_for_sof = 1;
876            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
877            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
878        }
879        return 1;
880    }
881
882    if (hcint.b.xfercomp)
883    {
884        disable_hc_int(_hc_regs,ack);
885        disable_hc_int(_hc_regs,nak);
886        disable_hc_int(_hc_regs,nyet);
887        _urbd->error_count =0;
888        if(_ifxhc->xfer_len==0 && !hcint.b.ack && hcint.b.nak)
889        {
890            // Walkaround: When sending ZLP and receive NAK but also issue CMPT intr
891            // Solution: NoSplit: Resend at next SOF
892            // Split : Resend at next SOF with SSPLIT
893            if(hcint.b.nyet && !out_nak_enh)
894                _ifxhc->do_ping = 1;
895            else
896                _ifxhc->do_ping = 0;
897            _ifxhc->xfer_len = 0;
898            _ifxhc->xfer_count = 0;
899            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
900            _ifxhc->wait_for_sof = 1;
901            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
902        }
903        else
904        {
905            _ifxhc->wait_for_sof = 0;
906            _ifxhc->do_ping = 0;
907            complete_channel(_ifxhcd, _ifxhc, _urbd);
908        }
909        return 1;
910    }
911    else if (hcint.b.stall)
912    {
913        disable_hc_int(_hc_regs,ack);
914        disable_hc_int(_hc_regs,nak);
915        disable_hc_int(_hc_regs,nyet);
916        _urbd->error_count =0;
917        _ifxhc->wait_for_sof =0;
918        _ifxhc->do_ping =0;
919
920        // ZLP shortcut
921        #if 1
922        if(hctsiz.b.pktcnt==0)
923            complete_channel(_ifxhcd, _ifxhc, _urbd);
924        else
925        #endif
926        {
927            if(_ifxhc->xfer_len!=0)
928                _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
929            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
930        }
931        return 1;
932    }
933    else if (hcint.b.xacterr)
934    {
935        // ZLP shortcut
936        #if 1
937        if(hctsiz.b.pktcnt==0)
938        {
939            disable_hc_int(_hc_regs,ack);
940            disable_hc_int(_hc_regs,nak);
941            disable_hc_int(_hc_regs,nyet);
942            _urbd->error_count =0;
943            _ifxhc->wait_for_sof =0;
944            _ifxhc->do_ping =0;
945            complete_channel(_ifxhcd, _ifxhc, _urbd);
946        }
947        else
948        #endif
949        {
950            if(_ifxhc->xfer_len!=0)
951                _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
952            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
953            _ifxhc->xfer_count = _urbd->urb->actual_length;
954            _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
955
956            if (hcint.b.nak || hcint.b.nyet || hcint.b.ack)
957            {
958                _urbd->error_count =0;
959                _ifxhc->wait_for_sof =1;
960                enable_hc_int(_hc_regs,ack);
961                enable_hc_int(_hc_regs,nak);
962                enable_hc_int(_hc_regs,nyet);
963                if(!out_nak_enh)
964                    _ifxhc->do_ping =1;
965                else
966                    _ifxhc->do_ping =0;
967                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
968            }
969            else
970            {
971                _urbd->error_count ++ ;
972                if (_urbd->error_count == 3)
973                {
974                    disable_hc_int(_hc_regs,ack);
975                    disable_hc_int(_hc_regs,nak);
976                    disable_hc_int(_hc_regs,nyet);
977                    _urbd->error_count =0;
978                    _ifxhc->wait_for_sof =0;
979                    _ifxhc->do_ping =0;
980                    release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
981                }
982                else
983                {
984                    enable_hc_int(_hc_regs,ack);
985                    enable_hc_int(_hc_regs,nak);
986                    enable_hc_int(_hc_regs,nyet);
987                    _ifxhc->wait_for_sof =1;
988                    if(!out_nak_enh)
989                        _ifxhc->do_ping =1;
990                    else
991                        _ifxhc->do_ping =0;
992                    ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
993                }
994            }
995        }
996        return 1;
997    }
998    else if(hcint.b.bblerr )
999    {
1000IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT0 BABBLE [should be IN only]\n",__func__,__LINE__);
1001showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1002        _ifxhc->do_ping = 0;
1003        if(_ifxhc->xfer_len!=0)
1004            _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1005        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1006        return 1;
1007    }
1008    else if(hcint.b.nak || hcint.b.nyet)
1009    {
1010        if(!out_nak_enh)
1011        {
1012            // ZLP shortcut
1013            #if 1
1014            if(hctsiz.b.pktcnt==0)
1015            {
1016                _urbd->error_count =0;
1017                _ifxhc->wait_for_sof =0;
1018                _ifxhc->do_ping =0;
1019                complete_channel(_ifxhcd, _ifxhc, _urbd);
1020            }
1021            else
1022            #endif
1023            {
1024                if(!out_nak_enh)
1025                    _ifxhc->do_ping =1;
1026                else
1027                    _ifxhc->do_ping =0;
1028                if(_ifxhc->xfer_len!=0)
1029                {
1030                    _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1031                    _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1032                    _ifxhc->xfer_count = _urbd->urb->actual_length;
1033                }
1034                _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1035                _ifxhc->wait_for_sof = 1;
1036                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1037            }
1038            return 1;
1039        }
1040    }
1041    else if(hcint.b.datatglerr )
1042    {
1043IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT0 DATATGLERR [should be IN only]\n",__func__,__LINE__);
1044showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1045        _urbd->error_count =0;
1046        _ifxhc->wait_for_sof =0;
1047        _ifxhc->do_ping =0;
1048        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1049        return 1;
1050    }
1051    else if(hcint.b.frmovrun )
1052    {
1053IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT0 FRMOVRUN [should be PERIODIC only]\n",__func__,__LINE__);
1054showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1055        _urbd->error_count =0;
1056        _ifxhc->wait_for_sof =0;
1057        _ifxhc->do_ping =0;
1058        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1059        return 1;
1060    }
1061    return 0;
1062}
1063////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1064////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1065static int32_t chhltd_intr_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1066                                    ifxhcd_hc_t *_ifxhc,
1067                                    ifxusb_hc_regs_t *_hc_regs,
1068                                    ifxhcd_urbd_t *_urbd)
1069{
1070    hcint_data_t hcint;
1071    hcint_data_t hcintmsk;
1072    hctsiz_data_t hctsiz;
1073
1074    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1075    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1076    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1077    disable_hc_int(_hc_regs,ack);
1078    disable_hc_int(_hc_regs,nak);
1079    disable_hc_int(_hc_regs,nyet);
1080    _ifxhc->do_ping =0;
1081
1082    if(_ifxhc->halt_status == HC_XFER_NAK)
1083    {
1084        if(_ifxhc->nak_retry_r)
1085        {
1086            _ifxhc->nak_retry--;
1087            if(_ifxhc->nak_retry)
1088            {
1089                if(_ifxhc->xfer_len!=0)
1090                    _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1091                _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1092                _ifxhc->xfer_count = _urbd->urb->actual_length;
1093                _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1094                _ifxhc->wait_for_sof = 1;
1095                _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1096                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1097            }
1098            else
1099            {
1100                _ifxhc->wait_for_sof = 0;
1101                release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
1102            }
1103        }
1104        else
1105        {
1106            if(_ifxhc->xfer_len!=0)
1107                _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1108            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1109            _ifxhc->xfer_count = _urbd->urb->actual_length;
1110            _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1111            _ifxhc->wait_for_sof = 1;
1112            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1113            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1114        }
1115        return 1;
1116    }
1117
1118    if(hcint.b.xfercomp )
1119    {
1120        _urbd->error_count =0;
1121        //restart INTR immediately
1122        #if 1
1123        if(hctsiz.b.pktcnt>0)
1124        {
1125            // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
1126            _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
1127            if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
1128            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1129        }
1130        else
1131        #endif
1132        {
1133            _ifxhc->wait_for_sof =0;
1134            complete_channel(_ifxhcd, _ifxhc, _urbd);
1135        }
1136        return 1;
1137    }
1138    else if (hcint.b.stall)
1139    {
1140        _urbd->error_count =0;
1141        _ifxhc->wait_for_sof =0;
1142
1143        // Don't care shortcut
1144        #if 0
1145        if(hctsiz.b.pktcnt==0)
1146            complete_channel(_ifxhcd, _ifxhc, _urbd);
1147        else
1148        #endif
1149        {
1150            // Stall FIFO compensation.
1151            #if 0
1152                int sz1,sz2;
1153                sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt;
1154                sz2*=_ifxhc->mps;
1155                sz1=_ifxhc->xfer_len - hctsiz.b.xfersize;
1156                sz2-=sz1;
1157                if(sz2)
1158                    ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf);
1159            #endif
1160            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1161            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1162        }
1163        return 1;
1164    }
1165
1166
1167    else if (hcint.b.bblerr)
1168    {
1169        _urbd->error_count =0;
1170        _ifxhc->wait_for_sof =0;
1171
1172        // Don't care shortcut
1173        #if 0
1174        if(hctsiz.b.pktcnt==0)
1175            complete_channel(_ifxhcd, _ifxhc, _urbd);
1176        else
1177        #endif
1178        {
1179            _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1180            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1181        }
1182        return 1;
1183    }
1184    else if (hcint.b.nak || hcint.b.datatglerr || hcint.b.frmovrun)
1185    {
1186        _urbd->error_count =0;
1187        //restart INTR immediately
1188        #if 1
1189        if(hctsiz.b.pktcnt>0)
1190        {
1191            // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
1192            _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
1193            if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
1194            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1195        }
1196        else
1197        #endif
1198        {
1199            _ifxhc->wait_for_sof =0;
1200            complete_channel(_ifxhcd, _ifxhc, _urbd);
1201        }
1202        return 1;
1203    }
1204    else if (hcint.b.xacterr)
1205    {
1206        // ZLP shortcut
1207        #if 1
1208        if(hctsiz.b.pktcnt==0)
1209        {
1210            _urbd->error_count =0;
1211            _ifxhc->wait_for_sof =0;
1212            complete_channel(_ifxhcd, _ifxhc, _urbd);
1213        }
1214        else
1215        #endif
1216        {
1217            /* 20110803 AVM/WK FIX: Reset error count on any handshake */
1218            if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) {
1219                _urbd->error_count = 1;
1220            } else {
1221                _urbd->error_count++;
1222            }
1223
1224            if(_urbd->error_count>=3)
1225            {
1226                _urbd->error_count =0;
1227                _ifxhc->wait_for_sof =0;
1228                release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1229            }
1230            else
1231            {
1232                _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
1233                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1234            }
1235        }
1236        return 1;
1237    }
1238    else if(hcint.b.nyet )
1239    {
1240IFX_WARN("%s() %d Warning INTR IN SPLIT0 NYET [should be OUT only]\n",__func__,__LINE__);
1241showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1242        return 1;
1243    }
1244    return 0;
1245}
1246////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1247static int32_t chhltd_intr_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1248                                    ifxhcd_hc_t *_ifxhc,
1249                                    ifxusb_hc_regs_t *_hc_regs,
1250                                    ifxhcd_urbd_t *_urbd)
1251{
1252    hcint_data_t hcint;
1253    hcint_data_t hcintmsk;
1254    hctsiz_data_t hctsiz;
1255    int out_nak_enh = 0;
1256
1257    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1258        out_nak_enh = 1;
1259
1260    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1261    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1262    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1263
1264    if(_ifxhc->halt_status == HC_XFER_NAK)
1265    {
1266        if(_ifxhc->nak_retry_r)
1267        {
1268            _ifxhc->nak_retry--;
1269            if(_ifxhc->nak_retry)
1270            {
1271                if(_ifxhc->xfer_len!=0)
1272                    _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1273                _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1274                _ifxhc->xfer_count = _urbd->urb->actual_length;
1275                _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1276                _ifxhc->wait_for_sof = 1;
1277                _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1278                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1279            }
1280            else
1281            {
1282                _ifxhc->wait_for_sof = 0;
1283                release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
1284            }
1285        }
1286        else
1287        {
1288            if(_ifxhc->xfer_len!=0)
1289                _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1290            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1291            _ifxhc->xfer_count = _urbd->urb->actual_length;
1292            _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1293            _ifxhc->wait_for_sof = 1;
1294            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
1295            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1296        }
1297        return 1;
1298    }
1299
1300    if(hcint.b.xfercomp )
1301    {
1302        disable_hc_int(_hc_regs,ack);
1303        disable_hc_int(_hc_regs,nak);
1304        disable_hc_int(_hc_regs,nyet);
1305        _urbd->error_count =0;
1306        //restart INTR immediately
1307        #if 0
1308        if(hctsiz.b.pktcnt>0)
1309        {
1310            // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
1311            _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
1312            if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
1313            if(hcint.b.nyet && !out_nak_enh )
1314                _ifxhc->do_ping =1;
1315            else
1316                _ifxhc->do_ping =0;
1317            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1318        }
1319        else
1320        #endif
1321        {
1322            _ifxhc->wait_for_sof =0;
1323            _ifxhc->do_ping =0;
1324            complete_channel(_ifxhcd, _ifxhc, _urbd);
1325        }
1326        return 1;
1327    }
1328    else if (hcint.b.stall)
1329    {
1330        disable_hc_int(_hc_regs,ack);
1331        disable_hc_int(_hc_regs,nyet);
1332        disable_hc_int(_hc_regs,nak);
1333        _urbd->error_count =0;
1334        _ifxhc->wait_for_sof =0;
1335        _ifxhc->do_ping =0;
1336
1337        // Don't care shortcut
1338        #if 0
1339        if(hctsiz.b.pktcnt==0)
1340            complete_channel(_ifxhcd, _ifxhc, _urbd);
1341        else
1342        #endif
1343        {
1344            if(_ifxhc->xfer_len!=0)// !_ifxhc->is_in
1345                _urbd->urb->actual_length += ((_ifxhc->start_pkt_count - hctsiz.b.pktcnt ) * _ifxhc->mps);
1346            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1347        }
1348        return 1;
1349    }
1350    else if(hcint.b.nak || hcint.b.frmovrun )
1351    {
1352        disable_hc_int(_hc_regs,ack);
1353        disable_hc_int(_hc_regs,nyet);
1354        disable_hc_int(_hc_regs,nak);
1355        _urbd->error_count =0;
1356        //restart INTR immediately
1357        #if 0
1358        if(hctsiz.b.pktcnt>0)
1359        {
1360            // TODO Re-initialize Channel (in next b_interval - 1 uF/F)
1361            _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
1362            if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
1363            if(!out_nak_enh )
1364                _ifxhc->do_ping =1;
1365            else
1366                _ifxhc->do_ping =0;
1367            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1368        }
1369        else
1370        #endif
1371        {
1372            _ifxhc->wait_for_sof =0;
1373            _ifxhc->do_ping =0;
1374            complete_channel(_ifxhcd, _ifxhc, _urbd);
1375        }
1376        return 1;
1377    }
1378    else if(hcint.b.xacterr )
1379    {
1380        // ZLP shortcut
1381        #if 1
1382        if(hctsiz.b.pktcnt==0)
1383        {
1384            _urbd->error_count =0;
1385            _ifxhc->wait_for_sof =0;
1386            _ifxhc->do_ping =0;
1387            complete_channel(_ifxhcd, _ifxhc, _urbd);
1388        }
1389        else
1390        #endif
1391        {
1392            /* 20110803 AVM/WK FIX: Reset error count on any handshake */
1393            if (hcint.b.nak || hcint.b.nyet || hcint.b.ack) {
1394                _urbd->error_count = 1;
1395            } else {
1396                _urbd->error_count++;
1397            }
1398
1399            if(_urbd->error_count>=3)
1400            {
1401                _urbd->error_count =0;
1402                _ifxhc->wait_for_sof =0;
1403                _ifxhc->do_ping =0;
1404                release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1405            }
1406            else
1407            {
1408                //_ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
1409                //if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
1410                _ifxhc->wait_for_sof=1;
1411                if(!out_nak_enh )
1412                    _ifxhc->do_ping =1;
1413                else
1414                    _ifxhc->do_ping =0;
1415
1416                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1417            }
1418        }
1419        return 1;
1420    }
1421    else if(hcint.b.bblerr )
1422    {
1423IFX_WARN("%s() %d Warning INTR OUT SPLIT0 BABBLEERR [should be IN only]\n",__func__,__LINE__);
1424showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1425        _urbd->error_count =0;
1426        _ifxhc->wait_for_sof =0;
1427        _ifxhc->do_ping =0;
1428        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1429        return 1;
1430    }
1431    else if(hcint.b.datatglerr )
1432    {
1433IFX_WARN("%s() %d Warning INTR OUT SPLIT0 DATATGLERR\n",__func__,__LINE__);
1434showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1435        _urbd->error_count =0;
1436        _ifxhc->wait_for_sof =0;
1437        _ifxhc->do_ping =0;
1438        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1439        return 1;
1440    }
1441    return 0;
1442}
1443////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1444////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1445static int32_t chhltd_isoc_rx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1446                                    ifxhcd_hc_t *_ifxhc,
1447                                    ifxusb_hc_regs_t *_hc_regs,
1448                                    ifxhcd_urbd_t *_urbd)
1449{
1450    #if defined(__EN_ISOC__)
1451        hcint_data_t hcint;
1452        hcint_data_t hcintmsk;
1453        hctsiz_data_t hctsiz;
1454
1455        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1456        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1457        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1458
1459        if (hcint.b.xfercomp || hcint.b.frmovrun)
1460        {
1461            _urbd->error_count=0;
1462            disable_hc_int(_hc_regs,ack);
1463            disable_hc_int(_hc_regs,nak);
1464            disable_hc_int(_hc_regs,nyet);
1465            _ifxhc->wait_for_sof = 0;
1466            if (hcint.b.xfercomp)
1467                complete_channel(_ifxhcd, _ifxhc, _urbd);
1468            else
1469                release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1470        }
1471        else if (hcint.b.xacterr || hcint.b.bblerr)
1472        {
1473            #ifndef VR9Skip
1474                if(hctsiz.b.pktcnt==0)
1475                {
1476                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1477                }
1478                else
1479                {
1480                    int sz1,sz2;
1481                    sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt;
1482                    sz2*=_ifxhc->mps;
1483                    sz1=_ifxhc->xfer_len - hctsiz.b.xfersize;
1484                    sz2-=sz1;
1485                    if(sz2)
1486                        ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf);
1487                    _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1488                    _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1489                    _ifxhc->xfer_count = _urbd->urb->actual_length;
1490                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1491                    _urbd->error_count++;
1492                    if(_urbd->error_count>=3)
1493                    {
1494                        _urbd->error_count=0;
1495                        _ifxhc->wait_for_sof = 0;
1496                        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1497                        release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1498                    }
1499                    else
1500                    {
1501                        _ifxhc->wait_for_sof = 1;
1502                        enable_hc_int(_hc_regs,ack);
1503                        enable_hc_int(_hc_regs,nak);
1504                        enable_hc_int(_hc_regs,nyet);
1505                        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1506                    }
1507                }
1508            #endif
1509        }
1510        else if(hcint.b.datatglerr )
1511        {
1512            warning
1513        }
1514        else if(hcint.b.stall )
1515        {
1516            warning
1517        }
1518    #else
1519    #endif
1520    return 0;
1521}
1522////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1523static int32_t chhltd_isoc_tx_nonsplit(ifxhcd_hcd_t *_ifxhcd,
1524                                    ifxhcd_hc_t *_ifxhc,
1525                                    ifxusb_hc_regs_t *_hc_regs,
1526                                    ifxhcd_urbd_t *_urbd)
1527{
1528    #if defined(__EN_ISOC__)
1529        hcint_data_t hcint;
1530        hcint_data_t hcintmsk;
1531        hctsiz_data_t hctsiz;
1532        int out_nak_enh = 0;
1533
1534        if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1535            out_nak_enh = 1;
1536
1537        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1538        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1539        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1540
1541        if (hcint.b.xfercomp)
1542        {
1543            _urbd->error_count=0;
1544            disable_hc_int(_hc_regs,ack);
1545            disable_hc_int(_hc_regs,nak);
1546            disable_hc_int(_hc_regs,nyet);
1547            _ifxhc->wait_for_sof = 0;
1548            complete_channel(_ifxhcd, _ifxhc, _urbd);
1549            return 1;
1550        }
1551        else if (hcint.b.frmovrun)
1552        {
1553            #ifndef VR9Skip
1554                _urbd->error_count=0;
1555                disable_hc_int(_hc_regs,ack);
1556                disable_hc_int(_hc_regs,nak);
1557                disable_hc_int(_hc_regs,nyet);
1558                _ifxhc->wait_for_sof = 0;
1559                release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1560            #endif
1561        }
1562        else if(hcint.b.datatglerr )
1563        {
1564            warning
1565        }
1566        else if(hcint.b.bblerr )
1567        {
1568            #ifndef VR9Skip
1569                if(hctsiz.b.pktcnt==0)
1570                {
1571                    complete_channel(_ifxhcd, _ifxhc, _urbd);
1572                }
1573                else
1574                {
1575                    int sz1,sz2;
1576                    sz2=_ifxhc->start_pkt_count - hctsiz.b.pktcnt;
1577                    sz2*=_ifxhc->mps;
1578                    sz1=_ifxhc->xfer_len - hctsiz.b.xfersize;
1579                    sz2-=sz1;
1580                        if(sz2)
1581                            ifxhcd_hc_dumb_rx(&_ifxhcd->core_if, _ifxhc,_ifxhc->epqh->dump_buf);
1582                        _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
1583                    _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
1584                    _ifxhc->xfer_count = _urbd->urb->actual_length;
1585                    _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1586                    _urbd->error_count++;
1587                    if(_urbd->error_count>=3)
1588                    {
1589                        _urbd->error_count=0;
1590                        _ifxhc->wait_for_sof = 0;
1591                        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1592                    }
1593                    else
1594                    {
1595                        _ifxhc->wait_for_sof = 1;
1596                        enable_hc_int(_hc_regs,ack);
1597                        enable_hc_int(_hc_regs,nak);
1598                        enable_hc_int(_hc_regs,nyet);
1599                        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1600                    }
1601                }
1602            #endif
1603        }
1604        else if(hcint.b.xacterr )
1605        {
1606            if(hctsiz.b.pktcnt==0)
1607            {
1608                complete_channel(_ifxhcd, _ifxhc, _urbd);
1609                return 1;
1610            }
1611            _urbd->error_count++;
1612            if(_urbd->error_count>=3)
1613            {
1614                _urbd->error_count=0;
1615                _ifxhc->wait_for_sof = 0;
1616                release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1617            }
1618            else
1619            {
1620                _ifxhc->wait_for_sof = 1;
1621                ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1622            }
1623            return 1;
1624        }
1625        else if(hcint.b.stall )
1626        {
1627                warning
1628        }
1629    #else
1630    #endif
1631    return 0;
1632}
1633////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1634////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1635////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1636static int32_t chhltd_ctrlbulk_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
1637                                      ifxhcd_hc_t *_ifxhc,
1638                                      ifxusb_hc_regs_t *_hc_regs,
1639                                      ifxhcd_urbd_t *_urbd)
1640{
1641    hcint_data_t hcint;
1642    hcint_data_t hcintmsk;
1643    hctsiz_data_t hctsiz;
1644
1645    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1646    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1647    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1648
1649    disable_hc_int(_hc_regs,ack);
1650    disable_hc_int(_hc_regs,nak);
1651    disable_hc_int(_hc_regs,nyet);
1652
1653    _ifxhc->do_ping =0;
1654
1655    if (hcint.b.ack)
1656    {
1657        _urbd->error_count=0;
1658        _ifxhc->split=2;
1659        _ifxhc->wait_for_sof = 8;
1660        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1661        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1662        return 1;
1663    }
1664    else if (hcint.b.nak)
1665    {
1666        _ifxhc->wait_for_sof = 1;
1667        _urbd->error_count = 0;
1668        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1669        return 1;
1670    }
1671    else if (hcint.b.xacterr)
1672    {
1673        _urbd->error_count++;
1674        if(_urbd->error_count>=3)
1675        {
1676            _urbd->error_count=0;
1677            _ifxhc->wait_for_sof =0;
1678            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1679        }
1680        else
1681        {
1682            _ifxhc->wait_for_sof =1;
1683            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1684        }
1685        return 1;
1686    }
1687    else if(hcint.b.bblerr )
1688    {
1689        _urbd->error_count =0;
1690        _ifxhc->wait_for_sof =0;
1691        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1692        return 1;
1693    }
1694    else if(hcint.b.stall )
1695    {
1696        _urbd->error_count =0;
1697        _ifxhc->wait_for_sof =0;
1698        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1699        return 1;
1700    }
1701    else if(hcint.b.datatglerr )
1702    {
1703IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 HC_XFER_DATA_TOGGLE_ERR\n",__func__,__LINE__);
1704showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1705        _urbd->error_count =0;
1706        _ifxhc->wait_for_sof =0;
1707        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1708        return 1;
1709    }
1710    else if(hcint.b.frmovrun )
1711    {
1712IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 HC_XFER_FRAME_OVERRUN\n",__func__,__LINE__);
1713showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1714        _urbd->error_count =0;
1715        _ifxhc->wait_for_sof =0;
1716        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1717        return 1;
1718    }
1719    else if(hcint.b.nyet )
1720    {
1721IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 NYET\n",__func__,__LINE__);
1722showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1723    }
1724    else if(hcint.b.xfercomp )
1725    {
1726IFX_WARN("%s() %d Warning CTRLBULK IN SPLIT1 COMPLETE\n",__func__,__LINE__);
1727showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1728    }
1729    return 0;
1730}
1731////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1732static int32_t chhltd_ctrlbulk_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
1733                                      ifxhcd_hc_t *_ifxhc,
1734                                      ifxusb_hc_regs_t *_hc_regs,
1735                                      ifxhcd_urbd_t *_urbd)
1736{
1737    hcint_data_t hcint;
1738    hcint_data_t hcintmsk;
1739    hctsiz_data_t hctsiz;
1740    int out_nak_enh = 0;
1741
1742#ifdef __DEBUG__
1743static int first=0;
1744#endif
1745
1746    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1747        out_nak_enh = 1;
1748
1749    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1750    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1751    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1752    disable_hc_int(_hc_regs,ack);
1753    disable_hc_int(_hc_regs,nak);
1754    disable_hc_int(_hc_regs,nyet);
1755
1756#ifdef __DEBUG__
1757    if(!first&& _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK
1758       &&(hcint.b.stall || hcint.b.datatglerr || hcint.b.frmovrun || hcint.b.bblerr || hcint.b.xacterr) && !hcint.b.ack)
1759    {
1760        showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1761        first=1;
1762        printk(KERN_INFO " [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X] \n"
1763        ,*(_ifxhc->xfer_buff+ 0),*(_ifxhc->xfer_buff+ 1),*(_ifxhc->xfer_buff+ 2),*(_ifxhc->xfer_buff+ 3)
1764        ,*(_ifxhc->xfer_buff+ 4),*(_ifxhc->xfer_buff+ 5),*(_ifxhc->xfer_buff+ 6),*(_ifxhc->xfer_buff+ 7)
1765        ,*(_ifxhc->xfer_buff+ 8),*(_ifxhc->xfer_buff+ 9),*(_ifxhc->xfer_buff+10),*(_ifxhc->xfer_buff+11)
1766        ,*(_ifxhc->xfer_buff+12),*(_ifxhc->xfer_buff+13),*(_ifxhc->xfer_buff+14),*(_ifxhc->xfer_buff+15));
1767
1768        printk(KERN_INFO " [_urbd->urb->actual_length:%08X _ifxhc->start_pkt_count:%08X hctsiz.b.pktcnt:%08X ,_urbd->xfer_len:%08x] \n"
1769        ,_urbd->urb->actual_length
1770        ,_ifxhc->start_pkt_count
1771        ,hctsiz.b.pktcnt
1772        ,_urbd->xfer_len);
1773    }
1774#endif
1775
1776    if (hcint.b.ack )
1777    {
1778        _urbd->error_count=0;
1779        if (_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK || _ifxhc->control_phase != IFXHCD_CONTROL_SETUP)
1780            _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
1781        _ifxhc->split=2;
1782        _ifxhc->wait_for_sof =8;
1783        _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
1784        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1785        return 1;
1786    }
1787    else if(hcint.b.nyet)
1788    {
1789IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT1 NYET\n",__func__,__LINE__);
1790showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1791        _urbd->error_count=0;
1792        if (_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK || _ifxhc->control_phase != IFXHCD_CONTROL_SETUP)
1793            _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
1794        _ifxhc->split=2;
1795        _ifxhc->wait_for_sof =1;
1796        _ifxhc->data_pid_start =read_data_toggle(_hc_regs);
1797        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1798        return 1;
1799    }
1800    else if(hcint.b.nak )
1801    {
1802        _ifxhc->wait_for_sof =1;
1803        if(!out_nak_enh )
1804            _ifxhc->do_ping =1;
1805        else
1806            _ifxhc->do_ping =0;
1807        _urbd->error_count =0;
1808        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1809        return 1;
1810    }
1811    else if(hcint.b.xacterr )
1812    {
1813        _urbd->error_count++;
1814        if(_urbd->error_count>=3)
1815        {
1816            _urbd->error_count=0;
1817            _ifxhc->wait_for_sof =0;
1818            _ifxhc->do_ping =0;
1819            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1820        }
1821        else
1822        {
1823            _ifxhc->wait_for_sof =1;
1824            _ifxhc->do_ping =1;
1825            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1826        }
1827        return 1;
1828    }
1829    else if(hcint.b.datatglerr )
1830    {
1831        _urbd->error_count =0;
1832        _ifxhc->wait_for_sof =0;
1833        _ifxhc->do_ping =0;
1834        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1835        return 1;
1836    }
1837    else if(hcint.b.bblerr )
1838    {
1839        _urbd->error_count =0;
1840        _ifxhc->wait_for_sof =0;
1841        _ifxhc->do_ping =0;
1842        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1843        return 1;
1844    }
1845    else if(hcint.b.stall )
1846    {
1847        _urbd->error_count =0;
1848        _ifxhc->wait_for_sof =0;
1849        _ifxhc->do_ping =0;
1850        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1851        return 1;
1852    }
1853    else if(hcint.b.frmovrun )
1854    {
1855IFX_WARN("%s() %d Warning CTRLBULK OUT SPLIT1 HC_XFER_FRAME_OVERRUN\n",__func__,__LINE__);
1856showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1857        _urbd->error_count =0;
1858        _ifxhc->wait_for_sof =0;
1859        _ifxhc->do_ping =0;
1860        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
1861        return 1;
1862    }
1863    else if(hcint.b.xfercomp )
1864    {
1865        printk(KERN_INFO "%s() %d Warning CTRLBULK OUT SPLIT1 COMPLETE\n",__func__,__LINE__);
1866    }
1867    return 0;
1868}
1869////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1870////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1871static int32_t chhltd_intr_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
1872                                  ifxhcd_hc_t *_ifxhc,
1873                                  ifxusb_hc_regs_t *_hc_regs,
1874                                  ifxhcd_urbd_t *_urbd)
1875{
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    disable_hc_int(_hc_regs,ack);
1885    disable_hc_int(_hc_regs,nak);
1886    disable_hc_int(_hc_regs,nyet);
1887
1888    _ifxhc->do_ping =0;
1889
1890    if (hcint.b.ack )
1891    {
1892        /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/
1893        _ifxhc->nyet_count=0;
1894
1895        _urbd->error_count=0;
1896        _ifxhc->split=2;
1897        _ifxhc->wait_for_sof = 0;
1898        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1899        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1900        return 1;
1901    }
1902    else if(hcint.b.nak )
1903    {
1904        _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
1905        if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
1906        _urbd->error_count=0;
1907        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1908        return 1;
1909    }
1910    else if(hcint.b.xacterr )
1911    {
1912        hcchar_data_t hcchar;
1913        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
1914        _urbd->error_count=hcchar.b.multicnt;
1915        if(_urbd->error_count>=3)
1916        {
1917            _urbd->error_count=0;
1918            _ifxhc->wait_for_sof = 0;
1919            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
1920        }
1921        else
1922        {
1923            _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
1924            if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
1925            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1926        }
1927        return 1;
1928    }
1929    else if(hcint.b.stall )
1930    {
1931        _urbd->error_count =0;
1932        _ifxhc->wait_for_sof =0;
1933        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
1934        return 1;
1935    }
1936    else if(hcint.b.bblerr )
1937    {
1938        _urbd->error_count =0;
1939        _ifxhc->wait_for_sof =0;
1940        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
1941        return 1;
1942    }
1943    else if(hcint.b.frmovrun )
1944    {
1945        _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
1946        if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
1947        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1948        return 1;
1949    }
1950    else if(hcint.b.datatglerr )
1951    {
1952IFX_WARN( "%s() %d Warning INTR IN SPLIT1 DATATGLERR\n",__func__,__LINE__);
1953showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1954        _urbd->error_count =0;
1955        _ifxhc->wait_for_sof =0;
1956        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
1957        return 1;
1958    }
1959    else if(hcint.b.xfercomp )
1960    {
1961IFX_WARN("%s() %d Warning INTR IN SPLIT1 COMPLETE\n",__func__,__LINE__);
1962showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
1963    }
1964    return 0;
1965}
1966////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
1967static int32_t chhltd_intr_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
1968                                  ifxhcd_hc_t *_ifxhc,
1969                                  ifxusb_hc_regs_t *_hc_regs,
1970                                  ifxhcd_urbd_t *_urbd)
1971{
1972    hcint_data_t hcint;
1973    hcint_data_t hcintmsk;
1974    hctsiz_data_t hctsiz;
1975    int out_nak_enh = 0;
1976
1977    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1978        out_nak_enh = 1;
1979
1980    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
1981    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
1982    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
1983
1984    disable_hc_int(_hc_regs,ack);
1985    disable_hc_int(_hc_regs,nak);
1986    disable_hc_int(_hc_regs,nyet);
1987
1988    if (hcint.b.ack )
1989    {
1990        /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/
1991        _ifxhc->nyet_count=0;
1992
1993        _urbd->error_count=0;
1994        _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
1995        _ifxhc->split=2;
1996        _ifxhc->wait_for_sof = 0;
1997        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
1998        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
1999        return 1;
2000    }
2001    else if(hcint.b.nyet)
2002    {
2003IFX_WARN("%s() %d Warning INTR OUT SPLIT1 NYET\n",__func__,__LINE__);
2004showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
2005        _urbd->error_count=0;
2006        _ifxhc->ssplit_out_xfer_count = _ifxhc->xfer_len;
2007        _ifxhc->split=2;
2008        _ifxhc->wait_for_sof = 0;
2009        _ifxhc->data_pid_start = read_data_toggle(_hc_regs);
2010        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2011        return 1;
2012    }
2013    else if(hcint.b.nak )
2014    {
2015        _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
2016        if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
2017        _urbd->error_count =0;
2018        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2019        return 1;
2020    }
2021    else if(hcint.b.frmovrun )
2022    {
2023        _urbd->error_count =0;
2024        _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
2025        if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
2026        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2027        return 1;
2028    }
2029    else if(hcint.b.xacterr )
2030    {
2031        hcchar_data_t hcchar;
2032        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
2033        _urbd->error_count=hcchar.b.multicnt;
2034        if(_urbd->error_count>=3)
2035        {
2036            _urbd->error_count=0;
2037            _ifxhc->wait_for_sof =0;
2038            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2039        }
2040        else
2041        {
2042            enable_hc_int(_hc_regs,ack);
2043            enable_hc_int(_hc_regs,nak);
2044            enable_hc_int(_hc_regs,nyet);
2045            _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
2046            if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
2047            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2048        }
2049        return 1;
2050    }
2051    else if(hcint.b.datatglerr )
2052    {
2053IFX_WARN("%s() %d Warning INTR IN SPLIT1 DATATGLERR\n",__func__,__LINE__);
2054showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
2055        _urbd->error_count =0;
2056        _ifxhc->wait_for_sof =0;
2057        release_channel(_ifxhcd, _ifxhc, HC_XFER_DATA_TOGGLE_ERR);
2058        return 1;
2059    }
2060    else if(hcint.b.bblerr )
2061    {
2062IFX_WARN("%s() %d Warning INTR IN SPLIT1 BABBLEERR\n",__func__,__LINE__);
2063showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
2064        _urbd->error_count =0;
2065        _ifxhc->wait_for_sof =0;
2066        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2067        return 1;
2068    }
2069    else if(hcint.b.stall )
2070    {
2071IFX_WARN("%s() %d Warning INTR IN SPLIT1 STALL\n",__func__,__LINE__);
2072showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
2073        _urbd->error_count =0;
2074        _ifxhc->wait_for_sof =0;
2075        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2076        return 1;
2077    }
2078    else if(hcint.b.xfercomp )
2079    {
2080IFX_WARN("%s() %d Warning INTR IN SPLIT1 COMPLETE\n",__func__,__LINE__);
2081showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
2082    }
2083    return 0;
2084}
2085////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2086////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2087static int32_t chhltd_isoc_rx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2088                                   ifxhcd_hc_t *_ifxhc,
2089                                   ifxusb_hc_regs_t *_hc_regs,
2090                                   ifxhcd_urbd_t *_urbd)
2091{
2092    #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
2093        hcint_data_t hcint;
2094        hcint_data_t hcintmsk;
2095        hctsiz_data_t hctsiz;
2096
2097        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2098        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2099        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2100        if (hcint.b.ack )
2101        {
2102            Do Complete Split
2103        }
2104        else if(hcint.b.frmovrun )
2105        {
2106            Rewind Buffer Pointers
2107            Retry Start Split (in next b_interval ¡V 1 uF)
2108        }
2109        else if(hcint.b.datatglerr )
2110        {
2111            warning
2112        }
2113        else if(hcint.b.bblerr )
2114        {
2115            warning
2116        }
2117        else if(hcint.b.xacterr )
2118        {
2119            warning
2120        }
2121        else if(hcint.b.stall )
2122        {
2123            warning
2124        }
2125        else if(hcint.b.nak )
2126        {
2127            warning
2128        }
2129        else if(hcint.b.xfercomp )
2130        {
2131            warning
2132        }
2133        else if(hcint.b.nyet)
2134        {
2135            warning
2136        }
2137    #endif
2138    return 0;
2139}
2140////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2141static int32_t chhltd_isoc_tx_ssplit(ifxhcd_hcd_t *_ifxhcd,
2142                                   ifxhcd_hc_t *_ifxhc,
2143                                   ifxusb_hc_regs_t *_hc_regs,
2144                                   ifxhcd_urbd_t *_urbd)
2145{
2146    #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
2147        hcint_data_t hcint;
2148        hcint_data_t hcintmsk;
2149        hctsiz_data_t hctsiz;
2150        int out_nak_enh = 0;
2151
2152        if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2153            out_nak_enh = 1;
2154
2155        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2156        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2157        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2158        if (hcint.b.ack )
2159        {
2160            Do Next Start Split (in next b_interval ¡V 1 uF)
2161        }
2162        else if(hcint.b.frmovrun )
2163        {
2164            Do Next Transaction in next frame.
2165        }
2166        else if(hcint.b.datatglerr )
2167        {
2168            warning
2169        }
2170        else if(hcint.b.bblerr )
2171        {
2172            warning
2173        }
2174        else if(hcint.b.xacterr )
2175        {
2176            warning
2177        }
2178        else if(hcint.b.stall )
2179        {
2180            warning
2181        }
2182        else if(hcint.b.nak )
2183        {
2184            warning
2185        }
2186        else if(hcint.b.xfercomp )
2187        {
2188            warning
2189        }
2190        else if(hcint.b.nyet)
2191        {
2192            warning
2193        }
2194    #endif
2195    return 0;
2196}
2197////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2198////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2199////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2200static int32_t chhltd_ctrlbulk_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
2201                                      ifxhcd_hc_t *_ifxhc,
2202                                      ifxusb_hc_regs_t *_hc_regs,
2203                                      ifxhcd_urbd_t *_urbd)
2204{
2205    hcint_data_t hcint;
2206    hcint_data_t hcintmsk;
2207    hctsiz_data_t hctsiz;
2208
2209    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2210    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2211    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2212    disable_hc_int(_hc_regs,ack);
2213    disable_hc_int(_hc_regs,nak);
2214    disable_hc_int(_hc_regs,nyet);
2215
2216    _ifxhc->do_ping = 0;
2217
2218    if (hcint.b.xfercomp)
2219    {
2220        _urbd->error_count =0;
2221        _ifxhc->wait_for_sof = 0;
2222        _ifxhc->split=1;
2223        complete_channel(_ifxhcd, _ifxhc, _urbd);
2224        return 1;
2225    }
2226    else if (hcint.b.nak)
2227    {
2228        _urbd->error_count=0;
2229
2230        _ifxhc->split = 1;
2231        _ifxhc->wait_for_sof = 1;
2232        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2233        _ifxhc->xfer_count = _urbd->urb->actual_length;
2234        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2235        return 1;
2236    }
2237    else if(hcint.b.nyet)
2238    {
2239        _urbd->error_count=0;
2240        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2241        _ifxhc->wait_for_sof = 1;
2242        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2243        return 1;
2244    }
2245    else if(hcint.b.stall || hcint.b.bblerr )
2246    {
2247        _urbd->error_count=0;
2248        _ifxhc->wait_for_sof = 0;
2249        if (hcint.b.stall)
2250            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2251        else if(hcint.b.bblerr )
2252            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2253        return 1;
2254    }
2255    else if(hcint.b.xacterr )
2256    {
2257        _urbd->error_count++;
2258        if(_urbd->error_count>=3)
2259        {
2260            _urbd->error_count=0;
2261            _ifxhc->wait_for_sof = 0;
2262            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2263        }
2264        else
2265        {
2266            _ifxhc->split=1;
2267            _ifxhc->wait_for_sof = 1;
2268            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2269            _ifxhc->xfer_count = _urbd->urb->actual_length;
2270            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2271        }
2272        return 1;
2273    }
2274    else if(hcint.b.datatglerr )
2275    {
2276        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
2277            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
2278        else
2279            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2280        _ifxhc->split=1;
2281        _ifxhc->wait_for_sof = 1;
2282        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2283        _ifxhc->xfer_count = _urbd->urb->actual_length;
2284        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2285        return 1;
2286    }
2287    else if(hcint.b.frmovrun )
2288    {
2289        _urbd->error_count=0;
2290        _ifxhc->wait_for_sof = 0;
2291        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2292        return 1;
2293    }
2294    return 0;
2295}
2296////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2297static int32_t chhltd_ctrlbulk_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
2298                                      ifxhcd_hc_t *_ifxhc,
2299                                      ifxusb_hc_regs_t *_hc_regs,
2300                                      ifxhcd_urbd_t *_urbd)
2301{
2302    hcint_data_t hcint;
2303    hcint_data_t hcintmsk;
2304    hctsiz_data_t hctsiz;
2305    int out_nak_enh = 0;
2306
2307#if 1
2308static int first=0;
2309#endif
2310
2311    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2312        out_nak_enh = 1;
2313
2314    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2315    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2316    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2317    disable_hc_int(_hc_regs,ack);
2318    disable_hc_int(_hc_regs,nak);
2319    disable_hc_int(_hc_regs,nyet);
2320
2321#if 1
2322    if(!first&& _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK
2323       &&(hcint.b.stall || hcint.b.datatglerr || hcint.b.frmovrun || hcint.b.bblerr || hcint.b.xacterr) && !hcint.b.ack)
2324    {
2325        showint( hcint.d32,hcintmsk.d32,hctsiz.d32);
2326        first=1;
2327        printk(KERN_INFO " [%02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X] \n"
2328        ,*(_ifxhc->xfer_buff+ 0),*(_ifxhc->xfer_buff+ 1),*(_ifxhc->xfer_buff+ 2),*(_ifxhc->xfer_buff+ 3)
2329        ,*(_ifxhc->xfer_buff+ 4),*(_ifxhc->xfer_buff+ 5),*(_ifxhc->xfer_buff+ 6),*(_ifxhc->xfer_buff+ 7)
2330        ,*(_ifxhc->xfer_buff+ 8),*(_ifxhc->xfer_buff+ 9),*(_ifxhc->xfer_buff+10),*(_ifxhc->xfer_buff+11)
2331        ,*(_ifxhc->xfer_buff+12),*(_ifxhc->xfer_buff+13),*(_ifxhc->xfer_buff+14),*(_ifxhc->xfer_buff+15));
2332
2333        printk(KERN_INFO " [_urbd->urb->actual_length:%08X _ifxhc->start_pkt_count:%08X hctsiz.b.pktcnt:%08X ,_urbd->xfer_len:%08x] \n"
2334        ,_urbd->urb->actual_length
2335        ,_ifxhc->start_pkt_count
2336        ,hctsiz.b.pktcnt
2337        ,_urbd->xfer_len);
2338    }
2339#endif
2340
2341    if(hcint.b.xfercomp )
2342    {
2343        _urbd->error_count=0;
2344        _ifxhc->split=1;
2345        _ifxhc->do_ping= 0;
2346        #if 0
2347        if(_ifxhc->xfer_len==0 && !hcint.b.ack && (hcint.b.nak || hcint.b.nyet))
2348        {
2349            // Walkaround: When sending ZLP and receive NYEY or NAK but also issue CMPT intr
2350            // Solution: NoSplit: Resend at next SOF
2351            // Split : Resend at next SOF with SSPLIT
2352            _ifxhc->xfer_len = 0;
2353            _ifxhc->xfer_count = 0;
2354            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2355            _ifxhc->wait_for_sof = 1;
2356            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2357        }
2358        else
2359        #endif
2360        {
2361            _ifxhc->wait_for_sof = 0;
2362            complete_channel(_ifxhcd, _ifxhc, _urbd);
2363        }
2364        return 1;
2365    }
2366    else if(hcint.b.nak )
2367    {
2368        _urbd->error_count=0;
2369
2370        _ifxhc->split = 1;
2371        _ifxhc->wait_for_sof = 1;
2372        if(!out_nak_enh )
2373            _ifxhc->do_ping =1;
2374        else
2375            _ifxhc->do_ping =0;
2376        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2377        _ifxhc->xfer_count = _urbd->urb->actual_length;
2378        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2379        return 1;
2380    }
2381    else if(hcint.b.nyet)
2382    {
2383        //Retry Complete Split
2384        // Issue Retry instantly on next SOF, without gothrough process_channels
2385        _urbd->error_count=0;
2386        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2387        _ifxhc->wait_for_sof = 1;
2388        _ifxhc->do_ping = 0;
2389        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2390        return 1;
2391    }
2392    else if(hcint.b.stall )
2393    {
2394        _urbd->error_count=0;
2395        _ifxhc->wait_for_sof = 0;
2396        _ifxhc->do_ping = 0;
2397        release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2398        return 1;
2399    }
2400    else if(hcint.b.xacterr )
2401    {
2402        _urbd->error_count++;
2403        if(_urbd->error_count>=3)
2404        {
2405            _urbd->error_count=0;
2406            _ifxhc->wait_for_sof = 0;
2407            _ifxhc->do_ping = 0;
2408            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2409        }
2410        else
2411        {
2412            _ifxhc->split=1;
2413            _ifxhc->wait_for_sof = 1;
2414            if(!out_nak_enh )
2415                _ifxhc->do_ping =1;
2416            else
2417                _ifxhc->do_ping =0;
2418            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2419            _ifxhc->xfer_count = _urbd->urb->actual_length;
2420            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2421        }
2422        return 1;
2423    }
2424    else if(hcint.b.datatglerr )
2425    {
2426        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
2427            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
2428        else
2429            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2430        _ifxhc->split=1;
2431        _ifxhc->wait_for_sof = 1;
2432        if(!out_nak_enh )
2433            _ifxhc->do_ping =1;
2434        else
2435            _ifxhc->do_ping =0;
2436        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2437        _ifxhc->xfer_count = _urbd->urb->actual_length;
2438        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2439        return 1;
2440    }
2441    else if(hcint.b.frmovrun )
2442    {
2443        _urbd->error_count=0;
2444        _ifxhc->wait_for_sof = 0;
2445        _ifxhc->do_ping = 0;
2446        release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2447        return 1;
2448    }
2449    else if(hcint.b.bblerr )
2450    {
2451        _urbd->error_count=0;
2452        _ifxhc->wait_for_sof = 0;
2453        _ifxhc->do_ping = 0;
2454        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2455        return 1;
2456    }
2457    return 0;
2458}
2459////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2460////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2461static int32_t chhltd_intr_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
2462                                  ifxhcd_hc_t *_ifxhc,
2463                                  ifxusb_hc_regs_t *_hc_regs,
2464                                  ifxhcd_urbd_t *_urbd)
2465{
2466    hcint_data_t hcint;
2467    hcint_data_t hcintmsk;
2468    hctsiz_data_t hctsiz;
2469
2470    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2471    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2472    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2473    disable_hc_int(_hc_regs,ack);
2474    disable_hc_int(_hc_regs,nak);
2475    disable_hc_int(_hc_regs,nyet);
2476    _ifxhc->do_ping = 0;
2477
2478    if (hcint.b.xfercomp )
2479    {
2480        _urbd->error_count=0;
2481        _ifxhc->wait_for_sof = 0;
2482        _ifxhc->split=1;
2483        complete_channel(_ifxhcd, _ifxhc, _urbd);
2484        return 1;
2485    }
2486    else if(hcint.b.nak )
2487    {
2488        _urbd->error_count=0;
2489        _ifxhc->split = 1;
2490        _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
2491        if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
2492        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2493        _ifxhc->xfer_count = _urbd->urb->actual_length;
2494        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2495        return 1;
2496    }
2497    else if(hcint.b.nyet)
2498    {
2499        _urbd->error_count=0;
2500        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2501        _ifxhc->wait_for_sof = 0;
2502
2503        /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/
2504        _ifxhc->nyet_count++;
2505        if(_ifxhc->nyet_count > 2) {
2506            _ifxhc->split = 1;
2507            _ifxhc->nyet_count = 0;
2508            _ifxhc->wait_for_sof = 5;
2509        }
2510
2511        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2512        return 1;
2513    }
2514    else if(hcint.b.frmovrun || hcint.b.bblerr || hcint.b.stall )
2515    {
2516        _urbd->error_count=0;
2517        _ifxhc->wait_for_sof = 0;
2518        if (hcint.b.stall)
2519            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2520        else if(hcint.b.bblerr )
2521            release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2522        else if(hcint.b.frmovrun )
2523            release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2524        return 1;
2525    }
2526    else if(hcint.b.xacterr )
2527    {
2528        hcchar_data_t hcchar;
2529        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
2530        _urbd->error_count=hcchar.b.multicnt;
2531        if(_urbd->error_count>=3)
2532        {
2533            _urbd->error_count=0;
2534            _ifxhc->wait_for_sof = 0;
2535            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2536        }
2537        else
2538        {
2539            _ifxhc->split=1;
2540            _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
2541            if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
2542            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2543            _ifxhc->xfer_count = _urbd->urb->actual_length;
2544            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2545        }
2546        return 1;
2547    }
2548    else if(hcint.b.datatglerr )
2549    {
2550        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
2551            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
2552        else
2553            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2554        _ifxhc->split=1;
2555        _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
2556        if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
2557        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2558        _ifxhc->xfer_count = _urbd->urb->actual_length;
2559        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2560        return 1;
2561    }
2562    return 0;
2563}
2564////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2565static int32_t chhltd_intr_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
2566                                  ifxhcd_hc_t *_ifxhc,
2567                                  ifxusb_hc_regs_t *_hc_regs,
2568                                  ifxhcd_urbd_t *_urbd)
2569{
2570    hcint_data_t hcint;
2571    hcint_data_t hcintmsk;
2572    hctsiz_data_t hctsiz;
2573    int out_nak_enh = 0;
2574
2575    if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2576        out_nak_enh = 1;
2577
2578    hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2579    hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2580    hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2581    disable_hc_int(_hc_regs,ack);
2582    disable_hc_int(_hc_regs,nak);
2583    disable_hc_int(_hc_regs,nyet);
2584
2585    if(hcint.b.xfercomp )
2586    {
2587        _urbd->error_count=0;
2588        _ifxhc->wait_for_sof = 0;
2589        _ifxhc->split=1;
2590        _ifxhc->do_ping = 0;
2591        complete_channel(_ifxhcd, _ifxhc, _urbd);
2592        return 1;
2593    }
2594    else if(hcint.b.nak )
2595    {
2596        _urbd->error_count=0;
2597        _ifxhc->split = 1;
2598        _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
2599        if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
2600        if(!out_nak_enh )
2601            _ifxhc->do_ping =1;
2602        else
2603            _ifxhc->do_ping =0;
2604        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2605        _ifxhc->xfer_count = _urbd->urb->actual_length;
2606        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2607        return 1;
2608    }
2609    else if(hcint.b.nyet)
2610    {
2611        _urbd->error_count=0;
2612        _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2613        _ifxhc->wait_for_sof = 0;
2614        _ifxhc->do_ping = 0;
2615
2616        /*== AVM/BC 20100701 - Workaround FullSpeed Interrupts with HiSpeed Hub ==*/
2617        _ifxhc->nyet_count++;
2618        if(_ifxhc->nyet_count > 2) {
2619            _ifxhc->split = 1;
2620            _ifxhc->nyet_count = 0;
2621            _ifxhc->wait_for_sof = 5;
2622        }
2623
2624        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2625        return 1;
2626    }
2627    else if(hcint.b.stall || hcint.b.frmovrun)
2628    {
2629        _urbd->error_count=0;
2630        _ifxhc->wait_for_sof = 0;
2631        _ifxhc->do_ping = 0;
2632        if (hcint.b.stall)
2633            release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2634        else if(hcint.b.frmovrun )
2635            release_channel(_ifxhcd, _ifxhc, HC_XFER_FRAME_OVERRUN);
2636        return 1;
2637    }
2638    else if(hcint.b.xacterr )
2639    {
2640        hcchar_data_t hcchar;
2641        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
2642        _urbd->error_count=hcchar.b.multicnt;
2643        if(_urbd->error_count>=3)
2644        {
2645            _urbd->error_count=0;
2646            _ifxhc->wait_for_sof = 0;
2647            _ifxhc->do_ping = 0;
2648            release_channel(_ifxhcd, _ifxhc, HC_XFER_XACT_ERR);
2649        }
2650        else
2651        {
2652            _ifxhc->split=1;
2653            _ifxhc->wait_for_sof = _ifxhc->epqh->interval-1;
2654            if(!_ifxhc->wait_for_sof) _ifxhc->wait_for_sof=1;
2655            if(!out_nak_enh )
2656                _ifxhc->do_ping =1;
2657            else
2658                _ifxhc->do_ping =0;
2659            _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2660            _ifxhc->xfer_count = _urbd->urb->actual_length;
2661            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2662        }
2663        return 1;
2664    }
2665    else if(hcint.b.datatglerr )
2666    {
2667        if(_ifxhc->data_pid_start == IFXUSB_HC_PID_DATA0)
2668            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
2669        else
2670            _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
2671        _ifxhc->split=1;
2672        if(!out_nak_enh )
2673            _ifxhc->do_ping =1;
2674        else
2675            _ifxhc->do_ping =0;
2676        _ifxhc->xfer_len = _urbd->xfer_len - _urbd->urb->actual_length;
2677        _ifxhc->xfer_count = _urbd->urb->actual_length;
2678        ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2679        return 1;
2680    }
2681    else if(hcint.b.bblerr )
2682    {
2683        _urbd->error_count=0;
2684        _ifxhc->wait_for_sof = 0;
2685        _ifxhc->do_ping = 0;
2686        release_channel(_ifxhcd, _ifxhc, HC_XFER_BABBLE_ERR);
2687        return 1;
2688    }
2689    return 0;
2690}
2691////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2692////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2693static int32_t chhltd_isoc_rx_csplit(ifxhcd_hcd_t *_ifxhcd,
2694                                   ifxhcd_hc_t *_ifxhc,
2695                                   ifxusb_hc_regs_t *_hc_regs,
2696                                   ifxhcd_urbd_t *_urbd)
2697{
2698    #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
2699        hcint_data_t hcint;
2700        hcint_data_t hcintmsk;
2701        hctsiz_data_t hctsiz;
2702
2703        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2704        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2705        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2706        if(hcint.b.xfercomp )
2707        {
2708            disable_hc_int(_hc_regs,ack);
2709            disable_hc_int(_hc_regs,nak);
2710            disable_hc_int(_hc_regs,nyet);
2711            _urbd->error_count=0;
2712            _ifxhc->wait_for_sof = 0;
2713            _ifxhc->split=1;
2714            complete_channel(_ifxhcd, _ifxhc, _urbd);
2715            return 1;
2716        }
2717        else if(hcint.b.nak )
2718        {
2719            Retry Start Split (in next b_interval ¡V 1 uF)
2720        }
2721        else if(hcint.b.nyet)
2722        {
2723            //Do Next Complete Split
2724            // Issue Retry instantly on next SOF, without gothrough process_channels
2725            _urbd->error_count=0;
2726            //disable_hc_int(_hc_regs,ack);
2727            //disable_hc_int(_hc_regs,nak);
2728            //disable_hc_int(_hc_regs,datatglerr);
2729            _ifxhc->halt_status = HC_XFER_NO_HALT_STATUS;
2730            _ifxhc->wait_for_sof = 1;
2731            ifxhcd_hc_start(&_ifxhcd->core_if, _ifxhc);
2732            return 1;
2733        }
2734        else if(hcint.b.frmovrun || hcint.b.stall || hcint.b.bblerr)
2735        {
2736            _urbd->error_count=0;
2737            disable_hc_int(_hc_regs,ack);
2738            disable_hc_int(_hc_regs,nyet);
2739            disable_hc_int(_hc_regs,nak);
2740            _ifxhc->wait_for_sof = 0;
2741
2742            //if(hctsiz.b.pktcnt==0)
2743            //{
2744            // complete_channel(_ifxhcd, _ifxhc, _urbd);
2745            // return 1;
2746            //}
2747            //else
2748            // _urbd->urb->actual_length += (_ifxhc->xfer_len - hctsiz.b.xfersize);
2749            if (hcint.b.stall)
2750                release_channel(_ifxhcd, _ifxhc, HC_XFER_STALL);
2751            else if(hcint.b.frmovrun )
2752            else if(hcint.b.bblerr )
2753            return 1;
2754        }
2755        else if(hcint.b.xacterr )
2756        {
2757            Rewind Buffer Pointers
2758            if (HCCHARn.EC = = 3) // ERR response received
2759            {
2760                Record ERR error
2761                Do Next Start Split (in next frame)
2762            }
2763            else
2764            {
2765                De-allocate Channel
2766            }
2767        }
2768        else if(hcint.b.datatglerr )
2769        {
2770            warning
2771        }
2772        else if(hcint.b.ack )
2773        {
2774            warning
2775        }
2776    #endif
2777    return 0;
2778}
2779////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2780static int32_t chhltd_isoc_tx_csplit(ifxhcd_hcd_t *_ifxhcd,
2781                                   ifxhcd_hc_t *_ifxhc,
2782                                   ifxusb_hc_regs_t *_hc_regs,
2783                                   ifxhcd_urbd_t *_urbd)
2784{
2785    #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
2786        hcint_data_t hcint;
2787        hcint_data_t hcintmsk;
2788        hctsiz_data_t hctsiz;
2789        int out_nak_enh = 0;
2790
2791        if (_ifxhcd->core_if.snpsid >= 0x4f54271a && _ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
2792            out_nak_enh = 1;
2793
2794        hcint.d32 = ifxusb_rreg(&_hc_regs->hcint);
2795        hcintmsk.d32 = ifxusb_rreg(&_hc_regs->hcintmsk);
2796        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2797        warning
2798    #endif
2799    return 0;
2800}
2801////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2802////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2803////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
2804
2805static int32_t handle_hc_chhltd_intr(ifxhcd_hcd_t *_ifxhcd,
2806                                     ifxhcd_hc_t *_ifxhc,
2807                                     ifxusb_hc_regs_t *_hc_regs,
2808                                     ifxhcd_urbd_t *_urbd)
2809{
2810    IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: Channel Halted--\n", _ifxhc->hc_num);
2811
2812    _ifxhc->halting = 0;
2813    _ifxhc->xfer_started = 0;
2814
2815    if (_ifxhc->halt_status == HC_XFER_URB_DEQUEUE ||
2816        _ifxhc->halt_status == HC_XFER_AHB_ERR) {
2817        /*
2818         * Just release the channel. A dequeue can happen on a
2819         * transfer timeout. In the case of an AHB Error, the channel
2820         * was forced to halt because there's no way to gracefully
2821         * recover.
2822         */
2823        release_channel(_ifxhcd, _ifxhc, _ifxhc->halt_status);
2824        return 1;
2825    }
2826
2827    if (_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL || _ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
2828    {
2829        if (_ifxhc->split==0)
2830        {
2831            if(_ifxhc->is_in)
2832                return (chhltd_ctrlbulk_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2833            else
2834                return (chhltd_ctrlbulk_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2835        }
2836        else if(_ifxhc->split==1)
2837        {
2838            if(_ifxhc->is_in)
2839                return (chhltd_ctrlbulk_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2840            else
2841                return (chhltd_ctrlbulk_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2842        }
2843        else if(_ifxhc->split==2)
2844        {
2845            if(_ifxhc->is_in)
2846                return (chhltd_ctrlbulk_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2847            else
2848                return (chhltd_ctrlbulk_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2849        }
2850    }
2851    else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR)
2852    {
2853        if (_ifxhc->split==0)
2854        {
2855            if(_ifxhc->is_in)
2856                return (chhltd_intr_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2857            else
2858                return (chhltd_intr_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2859        }
2860        else if(_ifxhc->split==1)
2861        {
2862            if(_ifxhc->is_in)
2863                return (chhltd_intr_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2864            else
2865                return (chhltd_intr_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2866        }
2867        else if(_ifxhc->split==2)
2868        {
2869            if(_ifxhc->is_in)
2870                return (chhltd_intr_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2871            else
2872                return (chhltd_intr_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2873        }
2874    }
2875    else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
2876    {
2877        if (_ifxhc->split==0)
2878        {
2879            if(_ifxhc->is_in)
2880                return (chhltd_isoc_rx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2881            else
2882                return (chhltd_isoc_tx_nonsplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2883        }
2884        else if(_ifxhc->split==1)
2885        {
2886            if(_ifxhc->is_in)
2887                return (chhltd_isoc_rx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2888            else
2889                return (chhltd_isoc_tx_ssplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2890        }
2891        else if(_ifxhc->split==2)
2892        {
2893            if(_ifxhc->is_in)
2894                return (chhltd_isoc_rx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2895            else
2896                return (chhltd_isoc_tx_csplit(_ifxhcd,_ifxhc,_hc_regs,_urbd));
2897        }
2898    }
2899    return 0;
2900}
2901
2902/*
2903 * Handles a host channel AHB error interrupt. This handler is only called in
2904 * DMA mode.
2905 */
2906static void hc_other_intr_dump(ifxhcd_hcd_t *_ifxhcd,
2907                               ifxhcd_hc_t *_ifxhc,
2908                               ifxusb_hc_regs_t *_hc_regs,
2909                               ifxhcd_urbd_t *_urbd)
2910{
2911    #ifdef __DEBUG__
2912        hcchar_data_t hcchar;
2913        hcsplt_data_t hcsplt;
2914        hctsiz_data_t hctsiz;
2915        uint32_t hcdma;
2916        struct urb *urb = _urbd->urb;
2917        hcchar.d32 = ifxusb_rreg(&_hc_regs->hcchar);
2918        hcsplt.d32 = ifxusb_rreg(&_hc_regs->hcsplt);
2919        hctsiz.d32 = ifxusb_rreg(&_hc_regs->hctsiz);
2920        hcdma = ifxusb_rreg(&_hc_regs->hcdma);
2921
2922        IFX_ERROR("Channel %d\n", _ifxhc->hc_num);
2923        IFX_ERROR(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
2924        IFX_ERROR(" hctsiz 0x%08x, hcdma 0x%08x\n", hctsiz.d32, hcdma);
2925        IFX_ERROR(" Device address: %d\n", usb_pipedevice(urb->pipe));
2926        IFX_ERROR(" Endpoint: %d, %s\n", usb_pipeendpoint(urb->pipe),
2927                (usb_pipein(urb->pipe) ? "IN" : "OUT"));
2928        IFX_ERROR(" Endpoint type: %s\n",
2929                ({char *pipetype;
2930                switch (usb_pipetype(urb->pipe)) {
2931                    case PIPE_CONTROL: pipetype = "CTRL"; break;
2932                    case PIPE_BULK: pipetype = "BULK"; break;
2933                    case PIPE_INTERRUPT: pipetype = "INTR"; break;
2934                    case PIPE_ISOCHRONOUS: pipetype = "ISOC"; break;
2935                    default: pipetype = "????"; break;
2936                }; pipetype;}));
2937        IFX_ERROR(" Speed: %s\n",
2938                ({char *speed;
2939                switch (urb->dev->speed) {
2940                    case USB_SPEED_HIGH: speed = "HS"; break;
2941                    case USB_SPEED_FULL: speed = "FS"; break;
2942                    case USB_SPEED_LOW: speed = "LS"; break;
2943                    default: speed = "????"; break;
2944                }; speed;}));
2945        IFX_ERROR(" Max packet size: %d\n",
2946                usb_maxpacket(urb->dev, urb->pipe, usb_pipeout(urb->pipe)));
2947        IFX_ERROR(" Data buffer length: %d\n", urb->transfer_buffer_length);
2948        IFX_ERROR(" Transfer buffer: %p, Transfer DMA: %p\n",
2949                urb->transfer_buffer, (void *)urb->transfer_dma);
2950        IFX_ERROR(" Setup buffer: %p, Setup DMA: %p\n",
2951                urb->setup_packet, (void *)urb->setup_dma);
2952        IFX_ERROR(" Interval: %d\n", urb->interval);
2953    #endif //__DEBUG__
2954}
2955
2956/*
2957 * Handles a host channel ACK interrupt. This interrupt is enabled when
2958 * errors occur, and during Start Split transactions.
2959 */
2960static int32_t handle_hc_ack_intr(ifxhcd_hcd_t *_ifxhcd,
2961                                  ifxhcd_hc_t *_ifxhc,
2962                                  ifxusb_hc_regs_t *_hc_regs,
2963                                  ifxhcd_urbd_t *_urbd)
2964{
2965    _urbd->error_count=0;
2966    if(_ifxhc->nak_countdown_r)
2967    {
2968        _ifxhc->nak_retry=_ifxhc->nak_retry_r;
2969        _ifxhc->nak_countdown=_ifxhc->nak_countdown_r;
2970    }
2971    else
2972        disable_hc_int(_hc_regs,nak);
2973    disable_hc_int(_hc_regs,ack);
2974    return 1;
2975}
2976
2977/*
2978 * Handles a host channel ACK interrupt. This interrupt is enabled when
2979 * errors occur, and during Start Split transactions.
2980 */
2981static int32_t handle_hc_nak_intr(ifxhcd_hcd_t *_ifxhcd,
2982                                  ifxhcd_hc_t *_ifxhc,
2983                                  ifxusb_hc_regs_t *_hc_regs,
2984                                  ifxhcd_urbd_t *_urbd)
2985{
2986
2987    _urbd->error_count=0;
2988
2989    if(_ifxhc->nak_countdown_r)
2990    {
2991        _ifxhc->nak_countdown--;
2992        if(!_ifxhc->nak_countdown)
2993        {
2994            _ifxhc->nak_countdown=_ifxhc->nak_countdown_r;
2995            disable_hc_int(_hc_regs,ack);
2996            disable_hc_int(_hc_regs,nak);
2997            ifxhcd_hc_halt(&_ifxhcd->core_if, _ifxhc, HC_XFER_NAK);
2998        }
2999        else
3000            enable_hc_int(_hc_regs,ack);
3001    }
3002    else
3003    {
3004        disable_hc_int(_hc_regs,ack);
3005        disable_hc_int(_hc_regs,nak);
3006    }
3007    return 1;
3008}
3009
3010/*
3011 * Handles a host channel AHB error interrupt. This handler is only called in
3012 * DMA mode.
3013 */
3014static int32_t handle_hc_ahberr_intr(ifxhcd_hcd_t *_ifxhcd,
3015                                     ifxhcd_hc_t *_ifxhc,
3016                                     ifxusb_hc_regs_t *_hc_regs,
3017                                     ifxhcd_urbd_t *_urbd)
3018{
3019    IFX_DEBUGPL(DBG_HCD, "--Host Channel %d Interrupt: "
3020            "AHB Error--\n", _ifxhc->hc_num);
3021    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3022
3023    ifxhcd_hc_halt(&_ifxhcd->core_if, _ifxhc, HC_XFER_AHB_ERR);
3024    return 1;
3025}
3026
3027/*
3028 * Datatoggle
3029 */
3030static int32_t handle_hc_datatglerr_intr(ifxhcd_hcd_t *_ifxhcd,
3031                                         ifxhcd_hc_t *_ifxhc,
3032                                         ifxusb_hc_regs_t *_hc_regs,
3033                                         ifxhcd_urbd_t *_urbd)
3034{
3035    IFX_ERROR( "--Host Channel %d Interrupt: "
3036            "DATATOGGLE Error--\n", _ifxhc->hc_num);
3037    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3038    disable_hc_int(_hc_regs,datatglerr);
3039    return 1;
3040}
3041
3042
3043
3044/*
3045 * Interrupts which should not been triggered
3046 */
3047static int32_t handle_hc_frmovrun_intr(ifxhcd_hcd_t *_ifxhcd,
3048                                       ifxhcd_hc_t *_ifxhc,
3049                                       ifxusb_hc_regs_t *_hc_regs,
3050                                       ifxhcd_urbd_t *_urbd)
3051{
3052    IFX_ERROR( "--Host Channel %d Interrupt: "
3053            "FrameOverRun Error--\n", _ifxhc->hc_num);
3054    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3055    disable_hc_int(_hc_regs,frmovrun);
3056    return 1;
3057}
3058
3059static int32_t handle_hc_bblerr_intr(ifxhcd_hcd_t *_ifxhcd,
3060                                     ifxhcd_hc_t *_ifxhc,
3061                                     ifxusb_hc_regs_t *_hc_regs,
3062                                     ifxhcd_urbd_t *_urbd)
3063{
3064    IFX_ERROR( "--Host Channel %d Interrupt: "
3065            "BBL Error--\n", _ifxhc->hc_num);
3066    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3067    disable_hc_int(_hc_regs,bblerr);
3068    return 1;
3069}
3070
3071static int32_t handle_hc_xacterr_intr(ifxhcd_hcd_t *_ifxhcd,
3072                                      ifxhcd_hc_t *_ifxhc,
3073                                      ifxusb_hc_regs_t *_hc_regs,
3074                                      ifxhcd_urbd_t *_urbd)
3075{
3076    IFX_ERROR( "--Host Channel %d Interrupt: "
3077            "XACT Error--\n", _ifxhc->hc_num);
3078    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3079    disable_hc_int(_hc_regs,xacterr);
3080    return 1;
3081}
3082
3083static int32_t handle_hc_nyet_intr(ifxhcd_hcd_t *_ifxhcd,
3084                                   ifxhcd_hc_t *_ifxhc,
3085                                   ifxusb_hc_regs_t *_hc_regs,
3086                                   ifxhcd_urbd_t *_urbd)
3087{
3088    IFX_ERROR( "--Host Channel %d Interrupt: "
3089            "NYET--\n", _ifxhc->hc_num);
3090    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3091    _urbd->error_count=0;
3092    disable_hc_int(_hc_regs,nyet);
3093    return 1;
3094}
3095
3096static int32_t handle_hc_stall_intr(ifxhcd_hcd_t *_ifxhcd,
3097                                    ifxhcd_hc_t *_ifxhc,
3098                                    ifxusb_hc_regs_t *_hc_regs,
3099                                    ifxhcd_urbd_t *_urbd)
3100{
3101    IFX_ERROR( "--Host Channel %d Interrupt: "
3102            "STALL--\n", _ifxhc->hc_num);
3103    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3104    disable_hc_int(_hc_regs,stall);
3105    return 1;
3106}
3107
3108static int32_t handle_hc_xfercomp_intr(ifxhcd_hcd_t *_ifxhcd,
3109                                       ifxhcd_hc_t *_ifxhc,
3110                                       ifxusb_hc_regs_t *_hc_regs,
3111                                       ifxhcd_urbd_t *_urbd)
3112{
3113    IFX_ERROR( "--Host Channel %d Interrupt: "
3114            "XFERCOMP--\n", _ifxhc->hc_num);
3115    hc_other_intr_dump(_ifxhcd,_ifxhc,_hc_regs,_urbd);
3116    disable_hc_int(_hc_regs,xfercomp);
3117    return 1;
3118}
3119
3120
3121
3122/* This interrupt indicates that the specified host channels has a pending
3123 * interrupt. There are multiple conditions that can cause each host channel
3124 * interrupt. This function determines which conditions have occurred for this
3125 * host channel interrupt and handles them appropriately. */
3126static int32_t handle_hc_n_intr (ifxhcd_hcd_t *_ifxhcd, uint32_t _num)
3127{
3128    uint32_t hcintval,hcintmsk;
3129    hcint_data_t hcint;
3130    ifxhcd_hc_t *ifxhc;
3131    ifxusb_hc_regs_t *hc_regs;
3132    ifxhcd_urbd_t *urbd;
3133    unsigned long flags;
3134
3135    int retval = 0;
3136
3137    IFX_DEBUGPL(DBG_HCDV, "--Host Channel Interrupt--, Channel %d\n", _num);
3138
3139    /*== AVM/BC 20101111 Lock needed ==*/
3140    SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
3141
3142    ifxhc = &_ifxhcd->ifxhc[_num];
3143    hc_regs = _ifxhcd->core_if.hc_regs[_num];
3144
3145    hcintval = ifxusb_rreg(&hc_regs->hcint);
3146    hcintmsk = ifxusb_rreg(&hc_regs->hcintmsk);
3147    hcint.d32 = hcintval & hcintmsk;
3148    IFX_DEBUGPL(DBG_HCDV, " 0x%08x & 0x%08x = 0x%08x\n",
3149            hcintval, hcintmsk, hcint.d32);
3150
3151    urbd = list_entry(ifxhc->epqh->urbd_list.next, ifxhcd_urbd_t, urbd_list_entry);
3152
3153    if (hcint.b.datatglerr)
3154        retval |= handle_hc_datatglerr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3155    if (hcint.b.frmovrun)
3156        retval |= handle_hc_frmovrun_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3157    if (hcint.b.bblerr)
3158        retval |= handle_hc_bblerr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3159    if (hcint.b.xacterr)
3160        retval |= handle_hc_xacterr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3161    if (hcint.b.nyet)
3162        retval |= handle_hc_nyet_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3163    if (hcint.b.ack)
3164        retval |= handle_hc_ack_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3165    if (hcint.b.nak)
3166        retval |= handle_hc_nak_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3167    if (hcint.b.stall)
3168        retval |= handle_hc_stall_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3169    if (hcint.b.ahberr) {
3170        clear_hc_int(hc_regs, ahberr);
3171        retval |= handle_hc_ahberr_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3172    }
3173    if (hcint.b.chhltd) {
3174        /* == 20110901 AVM/WK Fix: Flag must not be cleared after restart of channel ==*/
3175        clear_hc_int(hc_regs, chhltd);
3176        retval |= handle_hc_chhltd_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3177    }
3178    if (hcint.b.xfercomp)
3179        retval |= handle_hc_xfercomp_intr(_ifxhcd, ifxhc, hc_regs, urbd);
3180
3181    /* == 20110901 AVM/WK Fix: Never clear possibly new intvals ==*/
3182    //ifxusb_wreg(&hc_regs->hcint,hcintval);
3183
3184    SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
3185
3186    return retval;
3187}
3188
3189
3190
3191
3192
3193
3194static uint8_t update_interval_counter(ifxhcd_epqh_t *_epqh,uint32_t _diff)
3195{
3196    if(_diff>=_epqh->period_counter)
3197    {
3198        _epqh->period_do=1;
3199        if(_diff>_epqh->interval)
3200            _epqh->period_counter=1;
3201        else
3202            _epqh->period_counter=_epqh->period_counter+_epqh->interval-_diff;
3203        return 1;
3204    }
3205    _epqh->period_counter=_epqh->period_counter-_diff;
3206    return 0;
3207}
3208
3209
3210
3211
3212/*
3213 * Handles the start-of-frame interrupt in host mode. Non-periodic
3214 * transactions may be queued to the DWC_otg controller for the current
3215 * (micro)frame. Periodic transactions may be queued to the controller for the
3216 * next (micro)frame.
3217 */
3218static int32_t handle_sof_intr (ifxhcd_hcd_t *_ifxhcd)
3219{
3220    #ifdef __DYN_SOF_INTR__
3221        uint8_t with_count_down=0;
3222    #endif
3223    uint8_t active_on=0;
3224    uint8_t ready_on=0;
3225    struct list_head *epqh_entry;
3226    ifxhcd_epqh_t *epqh;
3227    hfnum_data_t hfnum;
3228    uint32_t fndiff;
3229
3230    unsigned long flags;
3231#ifdef __USE_TIMER_4_SOF__
3232    uint32_t wait_for_sof = 0x10000;
3233#endif
3234
3235    SPIN_LOCK_IRQSAVE(&_ifxhcd->lock, flags);
3236
3237    {
3238        int num_channels;
3239        ifxusb_hc_regs_t *hc_regs;
3240        int i;
3241        num_channels = _ifxhcd->core_if.params.host_channels;
3242
3243// AVM/WK moved block here due to use of SOF timer
3244        hfnum.d32 = ifxusb_rreg(&_ifxhcd->core_if.host_global_regs->hfnum);
3245        fndiff = hfnum.b.frnum;
3246        fndiff+= 0x00004000;
3247        fndiff-= _ifxhcd->lastframe ;
3248        fndiff&= 0x00003FFF;
3249        if(!fndiff) fndiff =1;
3250
3251        for (i = 0; i < num_channels; i++)
3252        {
3253            if(_ifxhcd->ifxhc[i].wait_for_sof && _ifxhcd->ifxhc[i].xfer_started)
3254            {
3255#ifdef __USE_TIMER_4_SOF__
3256                if (_ifxhcd->ifxhc[i].wait_for_sof > fndiff) {
3257                    _ifxhcd->ifxhc[i].wait_for_sof -= fndiff;
3258                } else {
3259                    _ifxhcd->ifxhc[i].wait_for_sof = 0;
3260                }
3261#else
3262                _ifxhcd->ifxhc[i].wait_for_sof--;
3263#endif
3264                if(_ifxhcd->ifxhc[i].wait_for_sof==0)
3265                {
3266                    hcint_data_t hcint= { .d32=0 };
3267                    hc_regs = _ifxhcd->core_if.hc_regs[i];
3268
3269                    hcint.d32 =0xFFFFFFFF;
3270                    ifxusb_wreg(&hc_regs->hcint, hcint.d32);
3271
3272                    hcint.d32=ifxusb_rreg(&hc_regs->hcintmsk);
3273                    hcint.b.nak =0;
3274                    hcint.b.ack =0;
3275                    /* == 20110901 AVM/WK Fix: We don't need NOT YET IRQ ==*/
3276                    hcint.b.nyet=0;
3277                    _ifxhcd->ifxhc[i].nak_countdown=_ifxhcd->ifxhc[i].nak_countdown_r;
3278                    if(_ifxhcd->ifxhc[i].nak_countdown_r)
3279                        hcint.b.nak =1;
3280                    ifxusb_wreg(&hc_regs->hcintmsk, hcint.d32);
3281
3282                    /* AVM WK / BC 20100827
3283                     * FIX: Packet was ignored because of wrong Oddframe bit
3284                     */
3285                    if (_ifxhcd->ifxhc[i].ep_type == IFXUSB_EP_TYPE_INTR || _ifxhcd->ifxhc[i].ep_type == IFXUSB_EP_TYPE_ISOC)
3286                    {
3287                        hcchar_data_t hcchar;
3288                        hcchar.d32 = _ifxhcd->ifxhc[i].hcchar;
3289                        hfnum.d32 = ifxusb_rreg(&_ifxhcd->core_if.host_global_regs->hfnum);
3290                        /* 1 if _next_ frame is odd, 0 if it's even */
3291                        hcchar.b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
3292                        _ifxhcd->ifxhc[i].hcchar = hcchar.d32;
3293                    }
3294
3295                    ifxusb_wreg(&hc_regs->hcchar, _ifxhcd->ifxhc[i].hcchar);
3296
3297                }
3298            }
3299            else
3300                _ifxhcd->ifxhc[i].wait_for_sof=0;
3301
3302#ifdef __USE_TIMER_4_SOF__
3303            if (_ifxhcd->ifxhc[i].wait_for_sof && (wait_for_sof > _ifxhcd->ifxhc[i].wait_for_sof)) {
3304                wait_for_sof = _ifxhcd->ifxhc[i].wait_for_sof;
3305            }
3306#endif
3307        }
3308    }
3309
3310    // ISOC Active
3311    #ifdef __EN_ISOC__
3312        #error ISOC not supported: missing SOF code
3313        epqh_entry = _ifxhcd->epqh_isoc_active.next;
3314        while (epqh_entry != &_ifxhcd->epqh_isoc_active)
3315        {
3316            epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
3317            epqh_entry = epqh_entry->next;
3318            #ifdef __DYN_SOF_INTR__
3319                with_count_down=1;
3320            #endif
3321            active_on+=update_interval_counter(epqh,fndiff);
3322        }
3323
3324        // ISOC Ready
3325        epqh_entry = _ifxhcd->epqh_isoc_ready.next;
3326        while (epqh_entry != &_ifxhcd->epqh_isoc_ready)
3327        {
3328            epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
3329            epqh_entry = epqh_entry->next;
3330            #ifdef __DYN_SOF_INTR__
3331                with_count_down=1;
3332            #endif
3333            ready_on+=update_interval_counter(epqh,fndiff);
3334        }
3335    #endif
3336
3337    // INTR Active
3338    epqh_entry = _ifxhcd->epqh_intr_active.next;
3339    while (epqh_entry != &_ifxhcd->epqh_intr_active)
3340    {
3341        epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
3342        epqh_entry = epqh_entry->next;
3343        #ifdef __DYN_SOF_INTR__
3344            with_count_down=1;
3345        #endif
3346#ifdef __USE_TIMER_4_SOF__
3347        if (update_interval_counter(epqh,fndiff)) {
3348            active_on ++;
3349            wait_for_sof = 1;
3350        } else {
3351            if (epqh->period_counter && (wait_for_sof > epqh->period_counter)) {
3352                wait_for_sof = epqh->period_counter;
3353            }
3354        }
3355#else
3356        active_on+=update_interval_counter(epqh,fndiff);
3357#endif
3358    }
3359
3360    // INTR Ready
3361    epqh_entry = _ifxhcd->epqh_intr_ready.next;
3362    while (epqh_entry != &_ifxhcd->epqh_intr_ready)
3363    {
3364        epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
3365        epqh_entry = epqh_entry->next;
3366        #ifdef __DYN_SOF_INTR__
3367            with_count_down=1;
3368        #endif
3369#ifdef __USE_TIMER_4_SOF__
3370        if (update_interval_counter(epqh,fndiff)) {
3371            ready_on ++;
3372            wait_for_sof = 1;
3373        } else {
3374            if (epqh->period_counter && (wait_for_sof > epqh->period_counter)) {
3375                wait_for_sof = epqh->period_counter;
3376            }
3377        }
3378#else
3379        ready_on+=update_interval_counter(epqh,fndiff);
3380#endif
3381    }
3382
3383    // Stdby
3384    epqh_entry = _ifxhcd->epqh_stdby.next;
3385    while (epqh_entry != &_ifxhcd->epqh_stdby)
3386    {
3387        epqh = list_entry(epqh_entry, ifxhcd_epqh_t, epqh_list_entry);
3388        epqh_entry = epqh_entry->next;
3389        if(epqh->period_counter > 0 ) {
3390#ifdef __USE_TIMER_4_SOF__
3391            if (epqh->period_counter > fndiff) {
3392                epqh->period_counter -= fndiff;
3393            } else {
3394                epqh->period_counter = 0;
3395            }
3396#else
3397            epqh->period_counter --;
3398#endif
3399            #ifdef __DYN_SOF_INTR__
3400                with_count_down=1;
3401            #endif
3402        }
3403        if(epqh->period_counter == 0) {
3404            ifxhcd_epqh_idle_periodic(epqh);
3405        }
3406#ifdef __USE_TIMER_4_SOF__
3407        else {
3408            if (wait_for_sof > epqh->period_counter) {
3409                wait_for_sof = epqh->period_counter;
3410            }
3411        }
3412#endif
3413    }
3414    SPIN_UNLOCK_IRQRESTORE(&_ifxhcd->lock, flags);
3415
3416    if(ready_on)
3417        select_eps(_ifxhcd);
3418    else if(active_on)
3419        process_channels(_ifxhcd);
3420
3421    /* Clear interrupt */
3422    {
3423        gint_data_t gintsts;
3424        gintsts.d32=0;
3425        gintsts.b.sofintr = 1;
3426        ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
3427
3428        #ifdef __DYN_SOF_INTR__
3429            if(!with_count_down)
3430                ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, gintsts.d32,0);
3431        #endif
3432#ifdef __USE_TIMER_4_SOF__
3433        wait_for_sof &= 0xFFFF; // reduce to 16 Bits.
3434
3435        if(wait_for_sof == 1) {
3436            // enable SOF
3437                gint_data_t gintsts;
3438                gintsts.d32=0;
3439                gintsts.b.sofintr = 1;
3440                ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32);
3441        } else {
3442            // disable SOF
3443            ifxusb_mreg(&_ifxhcd->core_if.core_global_regs->gintmsk, gintsts.d32,0);
3444            if (wait_for_sof > 1) {
3445                // use timer, not SOF IRQ
3446                hprt0_data_t hprt0;
3447                ktime_t ktime;
3448                hprt0.d32 = ifxusb_read_hprt0 (&_ifxhcd->core_if);
3449                if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED) {
3450                    ktime = ktime_set(0, wait_for_sof * 125 * 1000); /*--- wakeup in n*125usec ---*/
3451                } else {
3452                    ktime = ktime_set(0, wait_for_sof * (1000*1000)); /*--- wakeup in n*1000usec ---*/
3453                }
3454                hrtimer_start(&_ifxhcd->hr_timer, ktime, HRTIMER_MODE_REL);
3455            }
3456        }
3457#endif
3458    }
3459    _ifxhcd->lastframe=hfnum.b.frnum;
3460    return 1;
3461}
3462
3463
3464
3465/* There are multiple conditions that can cause a port interrupt. This function
3466 * determines which interrupt conditions have occurred and handles them
3467 * appropriately. */
3468static int32_t handle_port_intr (ifxhcd_hcd_t *_ifxhcd)
3469{
3470    int retval = 0;
3471    hprt0_data_t hprt0;
3472    hprt0_data_t hprt0_modify;
3473
3474    hprt0.d32 =
3475    hprt0_modify.d32 = ifxusb_rreg(_ifxhcd->core_if.hprt0);
3476
3477    /* Clear appropriate bits in HPRT0 to clear the interrupt bit in
3478     * GINTSTS */
3479
3480    hprt0_modify.b.prtena = 0;
3481    hprt0_modify.b.prtconndet = 0;
3482    hprt0_modify.b.prtenchng = 0;
3483    hprt0_modify.b.prtovrcurrchng = 0;
3484
3485    /* Port Connect Detected
3486     * Set flag and clear if detected */
3487    if (hprt0.b.prtconndet) {
3488        IFX_DEBUGPL(DBG_HCD, "--Port Interrupt HPRT0=0x%08x "
3489                "Port Connect Detected--\n", hprt0.d32);
3490        _ifxhcd->flags.b.port_connect_status_change = 1;
3491        _ifxhcd->flags.b.port_connect_status = 1;
3492        hprt0_modify.b.prtconndet = 1;
3493
3494        /* The Hub driver asserts a reset when it sees port connect
3495         * status change flag */
3496        retval |= 1;
3497    }
3498
3499    /* Port Enable Changed
3500     * Clear if detected - Set internal flag if disabled */
3501    if (hprt0.b.prtenchng) {
3502
3503        IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
3504                "Port Enable Changed--\n", hprt0.d32);
3505        hprt0_modify.b.prtenchng = 1;
3506        if (hprt0.b.prtena == 1)
3507            /* Port has been enabled set the reset change flag */
3508            _ifxhcd->flags.b.port_reset_change = 1;
3509        else
3510            _ifxhcd->flags.b.port_enable_change = 1;
3511        retval |= 1;
3512    }
3513
3514    /* Overcurrent Change Interrupt */
3515
3516    if (hprt0.b.prtovrcurrchng) {
3517        IFX_DEBUGPL(DBG_HCD, " --Port Interrupt HPRT0=0x%08x "
3518                "Port Overcurrent Changed--\n", hprt0.d32);
3519        _ifxhcd->flags.b.port_over_current_change = 1;
3520        hprt0_modify.b.prtovrcurrchng = 1;
3521        retval |= 1;
3522    }
3523
3524    /* Clear Port Interrupts */
3525    ifxusb_wreg(_ifxhcd->core_if.hprt0, hprt0_modify.d32);
3526    return retval;
3527}
3528
3529/*
3530 * This interrupt indicates that SUSPEND state has been detected on
3531 * the USB.
3532 * No Functioning in Host Mode
3533 */
3534static int32_t handle_usb_suspend_intr(ifxhcd_hcd_t *_ifxhcd)
3535{
3536    gint_data_t gintsts;
3537    IFX_DEBUGP("USB SUSPEND RECEIVED!\n");
3538    /* Clear interrupt */
3539    gintsts.d32 = 0;
3540    gintsts.b.usbsuspend = 1;
3541    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
3542    return 1;
3543}
3544
3545/*
3546 * This interrupt indicates that the IFXUSB controller has detected a
3547 * resume or remote wakeup sequence. If the IFXUSB controller is in
3548 * low power mode, the handler must brings the controller out of low
3549 * power mode. The controller automatically begins resume
3550 * signaling. The handler schedules a time to stop resume signaling.
3551 */
3552static int32_t handle_wakeup_detected_intr(ifxhcd_hcd_t *_ifxhcd)
3553{
3554    gint_data_t gintsts;
3555    hprt0_data_t hprt0 = {.d32=0};
3556    pcgcctl_data_t pcgcctl = {.d32=0};
3557    ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
3558
3559    IFX_DEBUGPL(DBG_ANY, "++Resume and Remote Wakeup Detected Interrupt++\n");
3560
3561    /*
3562     * Clear the Resume after 70ms. (Need 20 ms minimum. Use 70 ms
3563     * so that OPT tests pass with all PHYs).
3564     */
3565    /* Restart the Phy Clock */
3566    pcgcctl.b.stoppclk = 1;
3567    ifxusb_mreg(core_if->pcgcctl, pcgcctl.d32, 0);
3568    UDELAY(10);
3569
3570    /* Now wait for 70 ms. */
3571    hprt0.d32 = ifxusb_read_hprt0( core_if );
3572    IFX_DEBUGPL(DBG_ANY,"Resume: HPRT0=%0x\n", hprt0.d32);
3573    MDELAY(70);
3574    hprt0.b.prtres = 0; /* Resume */
3575    ifxusb_wreg(core_if->hprt0, hprt0.d32);
3576    IFX_DEBUGPL(DBG_ANY,"Clear Resume: HPRT0=%0x\n", ifxusb_rreg(core_if->hprt0));
3577
3578    /* Clear interrupt */
3579    gintsts.d32 = 0;
3580    gintsts.b.wkupintr = 1;
3581    ifxusb_wreg(&core_if->core_global_regs->gintsts, gintsts.d32);
3582    return 1;
3583}
3584
3585/*
3586 * This interrupt indicates that a device is initiating the Session
3587 * Request Protocol to request the host to turn on bus power so a new
3588 * session can begin. The handler responds by turning on bus power. If
3589 * the DWC_otg controller is in low power mode, the handler brings the
3590 * controller out of low power mode before turning on bus power.
3591 */
3592static int32_t handle_session_req_intr(ifxhcd_hcd_t *_ifxhcd)
3593{
3594    /* Clear interrupt */
3595    gint_data_t gintsts = { .d32 = 0 };
3596    gintsts.b.sessreqintr = 1;
3597    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
3598    return 1;
3599}
3600
3601/*
3602 * This interrupt indicates that a device has been disconnected from
3603 * the root port.
3604 */
3605static int32_t handle_disconnect_intr(ifxhcd_hcd_t *_ifxhcd)
3606{
3607    gint_data_t gintsts;
3608
3609    ifxhcd_disconnect(_ifxhcd);
3610
3611    gintsts.d32 = 0;
3612    gintsts.b.disconnect = 1;
3613    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
3614    return 1;
3615}
3616
3617/*
3618 * This function handles the Connector ID Status Change Interrupt. It
3619 * reads the OTG Interrupt Register (GOTCTL) to determine whether this
3620 * is a Device to Host Mode transition or a Host Mode to Device
3621 * Transition.
3622 * This only occurs when the cable is connected/removed from the PHY
3623 * connector.
3624 */
3625static int32_t handle_conn_id_status_change_intr(ifxhcd_hcd_t *_ifxhcd)
3626{
3627    gint_data_t gintsts;
3628
3629    IFX_WARN("ID Status Change Interrupt: currently in %s mode\n",
3630         ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device");
3631
3632    gintsts.d32 = 0;
3633    gintsts.b.conidstschng = 1;
3634    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
3635    return 1;
3636}
3637
3638static int32_t handle_otg_intr(ifxhcd_hcd_t *_ifxhcd)
3639{
3640    ifxusb_core_global_regs_t *global_regs = _ifxhcd->core_if.core_global_regs;
3641    gotgint_data_t gotgint;
3642    gotgint.d32 = ifxusb_rreg( &global_regs->gotgint);
3643    /* Clear GOTGINT */
3644    ifxusb_wreg (&global_regs->gotgint, gotgint.d32);
3645    return 1;
3646}
3647
3648/** This function will log a debug message */
3649static int32_t handle_mode_mismatch_intr(ifxhcd_hcd_t *_ifxhcd)
3650{
3651    gint_data_t gintsts;
3652
3653    IFX_WARN("Mode Mismatch Interrupt: currently in %s mode\n",
3654         ifxusb_mode(&_ifxhcd->core_if) ? "Host" : "Device");
3655    gintsts.d32 = 0;
3656    gintsts.b.modemismatch = 1;
3657    ifxusb_wreg(&_ifxhcd->core_if.core_global_regs->gintsts, gintsts.d32);
3658    return 1;
3659}
3660
3661/** This function handles interrupts for the HCD. */
3662int32_t ifxhcd_handle_intr (ifxhcd_hcd_t *_ifxhcd)
3663{
3664    int retval = 0;
3665
3666    ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
3667    /* AVM/BC 20101111 Unnecesary variable removed*/
3668    //gint_data_t gintsts,gintsts2;
3669    gint_data_t gintsts;
3670
3671    /* Check if HOST Mode */
3672    if (ifxusb_is_device_mode(core_if))
3673    {
3674        IFX_ERROR("%s() CRITICAL! IN DEVICE MODE\n", __func__);
3675        return 0;
3676    }
3677
3678    gintsts.d32 = ifxusb_read_core_intr(core_if);
3679
3680    if (!gintsts.d32)
3681        return 0;
3682
3683    //Common INT
3684    if (gintsts.b.modemismatch)
3685    {
3686        retval |= handle_mode_mismatch_intr(_ifxhcd);
3687        gintsts.b.modemismatch=0;
3688    }
3689    if (gintsts.b.otgintr)
3690    {
3691        retval |= handle_otg_intr(_ifxhcd);
3692        gintsts.b.otgintr=0;
3693    }
3694    if (gintsts.b.conidstschng)
3695    {
3696        retval |= handle_conn_id_status_change_intr(_ifxhcd);
3697        gintsts.b.conidstschng=0;
3698    }
3699    if (gintsts.b.disconnect)
3700    {
3701        retval |= handle_disconnect_intr(_ifxhcd);
3702        gintsts.b.disconnect=0;
3703    }
3704    if (gintsts.b.sessreqintr)
3705    {
3706        retval |= handle_session_req_intr(_ifxhcd);
3707        gintsts.b.sessreqintr=0;
3708    }
3709    if (gintsts.b.wkupintr)
3710    {
3711        retval |= handle_wakeup_detected_intr(_ifxhcd);
3712        gintsts.b.wkupintr=0;
3713    }
3714    if (gintsts.b.usbsuspend)
3715    {
3716        retval |= handle_usb_suspend_intr(_ifxhcd);
3717        gintsts.b.usbsuspend=0;
3718    }
3719
3720    //Host Int
3721    if (gintsts.b.sofintr)
3722    {
3723        retval |= handle_sof_intr (_ifxhcd);
3724        gintsts.b.sofintr=0;
3725    }
3726    if (gintsts.b.portintr)
3727    {
3728        retval |= handle_port_intr (_ifxhcd);
3729        gintsts.b.portintr=0;
3730    }
3731    if (gintsts.b.hcintr)
3732    {
3733        int i;
3734        haint_data_t haint;
3735        haint.d32 = ifxusb_read_host_all_channels_intr(core_if);
3736        for (i=0; i< core_if->params.host_channels; i++)
3737            if (haint.b2.chint & (1 << i))
3738                retval |= handle_hc_n_intr (_ifxhcd, i);
3739        gintsts.b.hcintr=0;
3740    }
3741    return retval;
3742}
3743

Archive Download this file



interactive