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