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