3fb00e0324c68af704d85baa6c87115b48e3c115
[openwrt/openwrt.git] / package / kernel / 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 | IRQF_SHARED);
705 if (retval < 0)
706 goto error2;
707
708 /*
709 * Allocate space for storing data on status transactions. Normally no
710 * data is sent, but this space acts as a bit bucket. This must be
711 * done after usb_add_hcd since that function allocates the DMA buffer
712 * pool.
713 */
714 _ifxhcd->status_buf = ifxusb_alloc_buf_h(IFXHCD_STATUS_BUF_SIZE, 1);
715
716 if (_ifxhcd->status_buf)
717 {
718 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd->core_if.core_name, syshcd->self.busnum);
719 return 0;
720 }
721 IFX_ERROR("%s: status_buf allocation failed\n", __func__);
722
723 /* Error conditions */
724 usb_remove_hcd(syshcd);
725 error2:
726 ifxhcd_freeextra(syshcd);
727 usb_put_hcd(syshcd);
728 error1:
729 return retval;
730 }
731
732 /*!
733 \brief Removes the HCD.
734 Frees memory and resources associated with the HCD and deregisters the bus.
735 */
736 void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd)
737 {
738 struct usb_hcd *syshcd = ifxhcd_to_syshcd(_ifxhcd);
739
740 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD REMOVE\n");
741
742 /* Turn off all interrupts */
743 ifxusb_wreg (&_ifxhcd->core_if.core_global_regs->gintmsk, 0);
744 ifxusb_mreg (&_ifxhcd->core_if.core_global_regs->gahbcfg, 1, 0);
745
746 usb_remove_hcd(syshcd);
747 ifxhcd_freeextra(syshcd);
748 usb_put_hcd(syshcd);
749
750 return;
751 }
752
753
754 /* =========================================================================
755 * Linux HC Driver Functions
756 * ========================================================================= */
757
758 /*!
759 \brief Initializes the IFXUSB controller and its root hub and prepares it for host
760 mode operation. Activates the root port. Returns 0 on success and a negative
761 error code on failure.
762 Called by USB stack.
763 */
764 int ifxhcd_start(struct usb_hcd *_syshcd)
765 {
766 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
767 ifxusb_core_if_t *core_if = &ifxhcd->core_if;
768 struct usb_bus *bus;
769
770 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD START\n");
771
772 bus = hcd_to_bus(_syshcd);
773
774 /* Initialize the bus state. */
775 _syshcd->state = HC_STATE_RUNNING;
776
777 /* Initialize and connect root hub if one is not already attached */
778 if (bus->root_hub)
779 {
780 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD Has Root Hub\n");
781 /* Inform the HUB driver to resume. */
782 usb_hcd_resume_root_hub(_syshcd);
783 }
784
785 ifxhcd->flags.d32 = 0;
786
787 /* Put all channels in the free channel list and clean up channel states.*/
788 {
789 int num_channels = ifxhcd->core_if.params.host_channels;
790 int i;
791 for (i = 0; i < num_channels; i++)
792 {
793 ifxhcd_hc_t *channel;
794 channel = &ifxhcd->ifxhc[i];
795 ifxhcd_hc_cleanup(&ifxhcd->core_if, channel);
796 }
797 }
798 /* Initialize the USB core for host mode operation. */
799
800 ifxusb_host_enable_interrupts(core_if);
801 ifxusb_enable_global_interrupts_h(core_if);
802 ifxusb_phy_power_on_h (core_if);
803
804 ifxusb_vbus_init(core_if);
805
806 /* Turn on the vbus power. */
807 {
808 hprt0_data_t hprt0;
809 hprt0.d32 = ifxusb_read_hprt0(core_if);
810
811 IFX_PRINT("Init: Power Port (%d)\n", hprt0.b.prtpwr);
812 if (hprt0.b.prtpwr == 0 )
813 {
814 hprt0.b.prtpwr = 1;
815 ifxusb_wreg(core_if->hprt0, hprt0.d32);
816 ifxusb_vbus_on(core_if);
817 }
818 }
819 return 0;
820 }
821
822 /*!
823 \brief Halts the IFXUSB host mode operations in a clean manner. USB transfers are
824 stopped.
825 */
826 #if defined(__IS_AR10__)
827 void ifxusb_oc_int_free(int port);
828 #else
829 void ifxusb_oc_int_free(void);
830 #endif
831
832 void ifxhcd_stop(struct usb_hcd *_syshcd)
833 {
834 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
835 hprt0_data_t hprt0 = { .d32=0 };
836
837 IFX_DEBUGPL(DBG_HCD, "IFX USB HCD STOP\n");
838
839 /* Turn off all interrupts. */
840 ifxusb_disable_global_interrupts_h(&ifxhcd->core_if );
841 ifxusb_host_disable_interrupts(&ifxhcd->core_if );
842
843 /*
844 * The root hub should be disconnected before this function is called.
845 * The disconnect will clear the URBD lists (via ..._hcd_urb_dequeue)
846 * and the EPQH lists (via ..._hcd_endpoint_disable).
847 */
848
849 /* Turn off the vbus power */
850 IFX_PRINT("PortPower off\n");
851
852 ifxusb_vbus_off(&ifxhcd->core_if );
853
854
855 #if defined(__IS_AR10__)
856 ifxusb_oc_int_free(ifxhcd->core_if.core_no);
857 #else
858 ifxusb_oc_int_free();
859 #endif
860
861
862 ifxusb_vbus_free(&ifxhcd->core_if );
863 hprt0.b.prtpwr = 0;
864 ifxusb_wreg(ifxhcd->core_if.hprt0, hprt0.d32);
865 return;
866 }
867
868 /*!
869 \brief Returns the current frame number
870 */
871 int ifxhcd_get_frame_number(struct usb_hcd *_syshcd)
872 {
873 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd(_syshcd);
874 hfnum_data_t hfnum;
875
876 hfnum.d32 = ifxusb_rreg(&ifxhcd->core_if.host_global_regs->hfnum);
877
878 return hfnum.b.frnum;
879 }
880
881 /*!
882 \brief Starts processing a USB transfer request specified by a USB Request Block
883 (URB). mem_flags indicates the type of memory allocation to use while
884 processing this URB.
885 */
886 int ifxhcd_urb_enqueue( struct usb_hcd *_syshcd,
887 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
888 struct usb_host_endpoint *_sysep,
889 #endif
890 struct urb *_urb,
891 gfp_t _mem_flags)
892 {
893 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
894 ifxhcd_epqh_t *epqh = NULL;
895
896 #ifdef __DEBUG__
897 if (CHK_DEBUG_LEVEL(DBG_HCDV | DBG_HCD_URB))
898 dump_urb_info(_urb, "ifxusb_hcd_urb_enqueue");
899 #endif //__DEBUG__
900
901 if (!ifxhcd->flags.b.port_connect_status) /* No longer connected. */
902 return -ENODEV;
903
904 #if !defined(__EN_ISOC__)
905 if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
906 {
907 IFX_ERROR("ISOC transfer not supported!!!\n");
908 return -ENODEV;
909 }
910 #endif
911
912 if(_urb->hcpriv)
913 {
914 IFX_WARN("%s() Previous urb->hcpriv exist %p\n",__func__,_urb->hcpriv);
915 #if 1
916 return -ENOSPC;
917 #endif
918 }
919
920 epqh=ifxhcd_urbd_create (ifxhcd,_urb);
921 if (!epqh)
922 {
923 IFX_ERROR("IFXUSB HCD URB Enqueue failed creating URBD\n");
924 return -ENOSPC;
925 }
926 if(epqh->phase==EPQH_DISABLING )
927 {
928 IFX_ERROR("Enqueue to a DISABLING EP!!!\n");
929 return -ENODEV;
930 }
931
932 #ifdef __DYN_SOF_INTR__
933 ifxhcd->dyn_sof_count = DYN_SOF_COUNT_DEF;
934 #endif
935 //enable_sof(ifxhcd);
936 {
937 gint_data_t gintsts;
938 gintsts.d32=0;
939 gintsts.b.sofintr = 1;
940 ifxusb_mreg(&ifxhcd->core_if.core_global_regs->gintmsk, 0,gintsts.d32);
941 }
942
943 if(epqh->phase==EPQH_IDLE || epqh->phase==EPQH_STDBY )
944 {
945 epqh->phase=EPQH_READY;
946 #ifdef __EPQD_DESTROY_TIMEOUT__
947 del_timer(&epqh->destroy_timer);
948 #endif
949 }
950 select_eps(ifxhcd);
951 return 0;
952 }
953
954 /*!
955 \brief Aborts/cancels a USB transfer request. Always returns 0 to indicate
956 success.
957 */
958 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
959 int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb)
960 #else
961 int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb, int status)
962 #endif
963 {
964 ifxhcd_hcd_t *ifxhcd;
965 struct usb_host_endpoint *sysep;
966 ifxhcd_urbd_t *urbd;
967 ifxhcd_epqh_t *epqh;
968
969 IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD URB Dequeue\n");
970 #if !defined(__EN_ISOC__)
971 if(usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
972 return 0;
973 #endif
974
975 ifxhcd = syshcd_to_ifxhcd(_syshcd);
976
977 urbd = (ifxhcd_urbd_t *) _urb->hcpriv;
978 if(!urbd)
979 {
980 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
981 _urb->status=-ETIMEDOUT;
982 usb_hcd_giveback_urb(_syshcd, _urb);
983 #else
984 // usb_hcd_giveback_urb(_syshcd, _urb,-ETIMEDOUT);
985 usb_hcd_giveback_urb(_syshcd, _urb,status);
986 #endif
987 return 0;
988 }
989
990 sysep = ifxhcd_urb_to_endpoint(_urb);
991 if(sysep)
992 {
993 LOCK_EPQH_LIST_ALL(ifxhcd);
994 epqh = sysep_to_epqh(ifxhcd,sysep);
995 UNLOCK_EPQH_LIST_ALL(ifxhcd);
996 if(epqh!=urbd->epqh)
997 IFX_ERROR("%s inconsistant epqh %p %p\n",__func__,epqh,urbd->epqh);
998 }
999 else
1000 epqh = (ifxhcd_epqh_t *) urbd->epqh;
1001 if(!ifxhcd->flags.b.port_connect_status || !epqh)
1002 {
1003 urbd->phase=URBD_DEQUEUEING;
1004 ifxhcd_complete_urb(ifxhcd, urbd, -ENODEV);
1005 }
1006 else
1007 {
1008 LOCK_URBD_LIST(epqh);
1009 if( urbd->phase==URBD_IDLE
1010 || urbd->phase==URBD_ACTIVE
1011 // || urbd->phase==URBD_STARTING
1012 )
1013 {
1014 urbd->phase=URBD_DEQUEUEING;
1015 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
1016 ifxhcd_complete_urb(ifxhcd, urbd, -ETIMEDOUT);
1017 #else
1018 ifxhcd_complete_urb(ifxhcd, urbd, status);
1019 #endif
1020 }
1021 else if( urbd->phase==URBD_STARTED
1022 || urbd->phase==URBD_STARTING
1023 // || urbd->phase==URBD_ACTIVE
1024 )
1025 {
1026 if(ifxhcd_hc_halt(&ifxhcd->core_if, epqh->hc, HC_XFER_URB_DEQUEUE))
1027 {
1028 urbd->phase=URBD_DEQUEUEING;
1029 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
1030 ifxhcd_complete_urb(ifxhcd, urbd, -ETIMEDOUT);
1031 #else
1032 ifxhcd_complete_urb(ifxhcd, urbd, status);
1033 #endif
1034 ifxhcd_epqh_idle(epqh);
1035 }
1036 }
1037 UNLOCK_URBD_LIST(epqh);
1038 }
1039 return 0;
1040 }
1041
1042
1043 /*!
1044 \brief Frees resources in the IFXUSB controller related to a given endpoint. Also
1045 clears state in the HCD related to the endpoint. Any URBs for the endpoint
1046 must already be dequeued.
1047 */
1048 void ifxhcd_endpoint_disable( struct usb_hcd *_syshcd,
1049 struct usb_host_endpoint *_sysep)
1050 {
1051 ifxhcd_hcd_t *ifxhcd;
1052 ifxhcd_epqh_t *epqh;
1053
1054 IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD EP DISABLE: _bEndpointAddress=0x%02x, "
1055 "endpoint=%d\n", _sysep->desc.bEndpointAddress,
1056 ifxhcd_ep_addr_to_endpoint(_sysep->desc.bEndpointAddress));
1057
1058 ifxhcd = syshcd_to_ifxhcd(_syshcd);
1059
1060 LOCK_EPQH_LIST_ALL(ifxhcd);
1061 epqh = sysep_to_epqh(ifxhcd,_sysep);
1062 UNLOCK_EPQH_LIST_ALL(ifxhcd);
1063
1064 if (!epqh)
1065 {
1066 return;
1067 }
1068 else
1069 {
1070 if (epqh->sysep!=_sysep)
1071 {
1072 IFX_ERROR("%s inconsistant sysep %p %p %p\n",__func__,epqh,epqh->sysep,_sysep);
1073 return;
1074 }
1075
1076 epqh->phase=EPQH_DISABLING;
1077 kill_all_urbs_in_epqh(ifxhcd, epqh, -ETIMEDOUT);
1078 {
1079 uint32_t count=0x80000;
1080 for(;!list_empty(&epqh->urbd_list) && count> 0; count--) udelay(1);
1081 if(!count)
1082 IFX_ERROR("%s: unable to clear urbd in epqh \n",__func__);
1083 }
1084 ifxhcd_epqh_free(epqh);
1085 }
1086 IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD EP DISABLE: done\n");
1087 }
1088
1089
1090 /*!
1091 \brief Handles host mode interrupts for the IFXUSB controller. Returns IRQ_NONE if
1092 there was no interrupt to handle. Returns IRQ_HANDLED if there was a valid
1093 interrupt.
1094
1095 This function is called by the USB core when an interrupt occurs
1096 */
1097 irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd)
1098 {
1099 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
1100 int32_t retval=0;
1101
1102 //mask_and_ack_ifx_irq (ifxhcd->core_if.irq);
1103 retval = ifxhcd_handle_intr(ifxhcd);
1104 return IRQ_RETVAL(retval);
1105 }
1106
1107
1108
1109 /*!
1110 \brief Creates Status Change bitmap for the root hub and root port. The bitmap is
1111 returned in buf. Bit 0 is the status change indicator for the root hub. Bit 1
1112 is the status change indicator for the single root port. Returns 1 if either
1113 change indicator is 1, otherwise returns 0.
1114 */
1115 int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf)
1116 {
1117 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
1118
1119 _buf[0] = 0;
1120 _buf[0] |= (ifxhcd->flags.b.port_connect_status_change ||
1121 ifxhcd->flags.b.port_reset_change ||
1122 ifxhcd->flags.b.port_enable_change ||
1123 ifxhcd->flags.b.port_suspend_change ||
1124 ifxhcd->flags.b.port_over_current_change) << 1;
1125
1126 #ifdef __DEBUG__
1127 if (_buf[0])
1128 {
1129 IFX_DEBUGPL(DBG_HCD, "IFXUSB HCD HUB STATUS DATA:"
1130 " Root port status changed\n");
1131 IFX_DEBUGPL(DBG_HCDV, " port_connect_status_change: %d\n",
1132 ifxhcd->flags.b.port_connect_status_change);
1133 IFX_DEBUGPL(DBG_HCDV, " port_reset_change: %d\n",
1134 ifxhcd->flags.b.port_reset_change);
1135 IFX_DEBUGPL(DBG_HCDV, " port_enable_change: %d\n",
1136 ifxhcd->flags.b.port_enable_change);
1137 IFX_DEBUGPL(DBG_HCDV, " port_suspend_change: %d\n",
1138 ifxhcd->flags.b.port_suspend_change);
1139 IFX_DEBUGPL(DBG_HCDV, " port_over_current_change: %d\n",
1140 ifxhcd->flags.b.port_over_current_change);
1141 {
1142 hprt0_data_t hprt0;
1143 hprt0.d32 = ifxusb_rreg(ifxhcd->core_if.hprt0);
1144 IFX_DEBUGPL(DBG_HCDV, " port reg :%08X\n",hprt0.d32);
1145 IFX_DEBUGPL(DBG_HCDV, " port reg :connect: %d/%d\n",hprt0.b.prtconnsts,hprt0.b.prtconndet);
1146 IFX_DEBUGPL(DBG_HCDV, " port reg :enable: %d/%d\n",hprt0.b.prtena,hprt0.b.prtenchng);
1147 IFX_DEBUGPL(DBG_HCDV, " port reg :OC: %d/%d\n",hprt0.b.prtovrcurract,hprt0.b.prtovrcurrchng);
1148 IFX_DEBUGPL(DBG_HCDV, " port reg :rsume/suspend/reset: %d/%d/%d\n",hprt0.b.prtres,hprt0.b.prtsusp,hprt0.b.prtrst);
1149 IFX_DEBUGPL(DBG_HCDV, " port reg :port power: %d/\n",hprt0.b.prtpwr);
1150 IFX_DEBUGPL(DBG_HCDV, " port reg :speed: %d/\n",hprt0.b.prtspd);
1151 }
1152 }
1153 #endif //__DEBUG__
1154 return (_buf[0] != 0);
1155 }
1156
1157 #ifdef __WITH_HS_ELECT_TST__
1158 extern void do_setup(ifxusb_core_if_t *_core_if) ;
1159 extern void do_in_ack(ifxusb_core_if_t *_core_if);
1160 #endif //__WITH_HS_ELECT_TST__
1161
1162 /*!
1163 \brief Handles hub class-specific requests.
1164 */
1165 int ifxhcd_hub_control( struct usb_hcd *_syshcd,
1166 u16 _typeReq,
1167 u16 _wValue,
1168 u16 _wIndex,
1169 char *_buf,
1170 u16 _wLength)
1171 {
1172 int retval = 0;
1173 ifxhcd_hcd_t *ifxhcd = syshcd_to_ifxhcd (_syshcd);
1174 ifxusb_core_if_t *core_if = &ifxhcd->core_if;
1175 struct usb_hub_descriptor *desc;
1176 hprt0_data_t hprt0 = {.d32 = 0};
1177
1178 uint32_t port_status;
1179
1180 switch (_typeReq)
1181 {
1182 case ClearHubFeature:
1183 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1184 "ClearHubFeature 0x%x\n", _wValue);
1185 switch (_wValue)
1186 {
1187 case C_HUB_LOCAL_POWER:
1188 case C_HUB_OVER_CURRENT:
1189 /* Nothing required here */
1190 break;
1191 default:
1192 retval = -EINVAL;
1193 IFX_ERROR ("IFXUSB HCD - "
1194 "ClearHubFeature request %xh unknown\n", _wValue);
1195 }
1196 break;
1197 case ClearPortFeature:
1198 if (!_wIndex || _wIndex > 1)
1199 goto error;
1200
1201 switch (_wValue)
1202 {
1203 case USB_PORT_FEAT_ENABLE:
1204 IFX_DEBUGPL (DBG_ANY, "IFXUSB HCD HUB CONTROL - "
1205 "ClearPortFeature USB_PORT_FEAT_ENABLE\n");
1206 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1207 hprt0.b.prtena = 1;
1208 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1209 break;
1210 case USB_PORT_FEAT_SUSPEND:
1211 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1212 "ClearPortFeature USB_PORT_FEAT_SUSPEND\n");
1213 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1214 hprt0.b.prtres = 1;
1215 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1216 /* Clear Resume bit */
1217 mdelay (100);
1218 hprt0.b.prtres = 0;
1219 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1220 break;
1221 case USB_PORT_FEAT_POWER:
1222 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1223 "ClearPortFeature USB_PORT_FEAT_POWER\n");
1224 #ifdef __IS_DUAL__
1225 ifxusb_vbus_off(core_if);
1226 #else
1227 ifxusb_vbus_off(core_if);
1228 #endif
1229 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1230 hprt0.b.prtpwr = 0;
1231 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1232 break;
1233 case USB_PORT_FEAT_INDICATOR:
1234 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1235 "ClearPortFeature USB_PORT_FEAT_INDICATOR\n");
1236 /* Port inidicator not supported */
1237 break;
1238 case USB_PORT_FEAT_C_CONNECTION:
1239 /* Clears drivers internal connect status change
1240 * flag */
1241 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1242 "ClearPortFeature USB_PORT_FEAT_C_CONNECTION\n");
1243 ifxhcd->flags.b.port_connect_status_change = 0;
1244 break;
1245 case USB_PORT_FEAT_C_RESET:
1246 /* Clears the driver's internal Port Reset Change
1247 * flag */
1248 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1249 "ClearPortFeature USB_PORT_FEAT_C_RESET\n");
1250 ifxhcd->flags.b.port_reset_change = 0;
1251 break;
1252 case USB_PORT_FEAT_C_ENABLE:
1253 /* Clears the driver's internal Port
1254 * Enable/Disable Change flag */
1255 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1256 "ClearPortFeature USB_PORT_FEAT_C_ENABLE\n");
1257 ifxhcd->flags.b.port_enable_change = 0;
1258 break;
1259 case USB_PORT_FEAT_C_SUSPEND:
1260 /* Clears the driver's internal Port Suspend
1261 * Change flag, which is set when resume signaling on
1262 * the host port is complete */
1263 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1264 "ClearPortFeature USB_PORT_FEAT_C_SUSPEND\n");
1265 ifxhcd->flags.b.port_suspend_change = 0;
1266 break;
1267 case USB_PORT_FEAT_C_OVER_CURRENT:
1268 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1269 "ClearPortFeature USB_PORT_FEAT_C_OVER_CURRENT\n");
1270 ifxhcd->flags.b.port_over_current_change = 0;
1271 break;
1272 default:
1273 retval = -EINVAL;
1274 IFX_ERROR ("IFXUSB HCD - "
1275 "ClearPortFeature request %xh "
1276 "unknown or unsupported\n", _wValue);
1277 }
1278 break;
1279 case GetHubDescriptor:
1280 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1281 "GetHubDescriptor\n");
1282 desc = (struct usb_hub_descriptor *)_buf;
1283 desc->bDescLength = 9;
1284 desc->bDescriptorType = 0x29;
1285 desc->bNbrPorts = 1;
1286 desc->wHubCharacteristics = 0x08;
1287 desc->bPwrOn2PwrGood = 1;
1288 desc->bHubContrCurrent = 0;
1289
1290 desc->u.hs.DeviceRemovable[0] = 0;
1291 desc->u.hs.DeviceRemovable[1] = 1;
1292 /*desc->bitmap[0] = 0;
1293 desc->bitmap[1] = 0xff;*/
1294 break;
1295 case GetHubStatus:
1296 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1297 "GetHubStatus\n");
1298 memset (_buf, 0, 4);
1299 break;
1300 case GetPortStatus:
1301 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1302 "GetPortStatus\n");
1303 if (!_wIndex || _wIndex > 1)
1304 goto error;
1305 port_status = 0;
1306 if (ifxhcd->flags.b.port_connect_status_change)
1307 port_status |= (1 << USB_PORT_FEAT_C_CONNECTION);
1308 if (ifxhcd->flags.b.port_enable_change)
1309 port_status |= (1 << USB_PORT_FEAT_C_ENABLE);
1310 if (ifxhcd->flags.b.port_suspend_change)
1311 port_status |= (1 << USB_PORT_FEAT_C_SUSPEND);
1312 if (ifxhcd->flags.b.port_reset_change)
1313 port_status |= (1 << USB_PORT_FEAT_C_RESET);
1314 if (ifxhcd->flags.b.port_over_current_change)
1315 {
1316 IFX_ERROR("Device Not Supported\n");
1317 port_status |= (1 << USB_PORT_FEAT_C_OVER_CURRENT);
1318 }
1319 if (!ifxhcd->flags.b.port_connect_status)
1320 {
1321 /*
1322 * The port is disconnected, which means the core is
1323 * either in device mode or it soon will be. Just
1324 * return 0's for the remainder of the port status
1325 * since the port register can't be read if the core
1326 * is in device mode.
1327 */
1328 *((u32 *) _buf) = cpu_to_le32(port_status);
1329 break;
1330 }
1331
1332 hprt0.d32 = ifxusb_rreg(core_if->hprt0);
1333 IFX_DEBUGPL(DBG_HCDV, " HPRT0: 0x%08x\n", hprt0.d32);
1334 if (hprt0.b.prtconnsts)
1335 port_status |= (1 << USB_PORT_FEAT_CONNECTION);
1336 if (hprt0.b.prtena)
1337 {
1338 ifxhcd->disconnecting=0;
1339 port_status |= (1 << USB_PORT_FEAT_ENABLE);
1340 }
1341 if (hprt0.b.prtsusp)
1342 port_status |= (1 << USB_PORT_FEAT_SUSPEND);
1343 if (hprt0.b.prtovrcurract)
1344 port_status |= (1 << USB_PORT_FEAT_OVER_CURRENT);
1345 if (hprt0.b.prtrst)
1346 port_status |= (1 << USB_PORT_FEAT_RESET);
1347 if (hprt0.b.prtpwr)
1348 port_status |= (1 << USB_PORT_FEAT_POWER);
1349 if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
1350 port_status |= USB_PORT_STAT_HIGH_SPEED;
1351 else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
1352 port_status |= USB_PORT_STAT_LOW_SPEED;
1353 if (hprt0.b.prttstctl)
1354 port_status |= (1 << USB_PORT_FEAT_TEST);
1355 /* USB_PORT_FEAT_INDICATOR unsupported always 0 */
1356 *((u32 *) _buf) = cpu_to_le32(port_status);
1357 break;
1358 case SetHubFeature:
1359 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1360 "SetHubFeature\n");
1361 /* No HUB features supported */
1362 break;
1363 case SetPortFeature:
1364 if (_wValue != USB_PORT_FEAT_TEST && (!_wIndex || _wIndex > 1))
1365 goto error;
1366 /*
1367 * The port is disconnected, which means the core is
1368 * either in device mode or it soon will be. Just
1369 * return without doing anything since the port
1370 * register can't be written if the core is in device
1371 * mode.
1372 */
1373 if (!ifxhcd->flags.b.port_connect_status)
1374 break;
1375 switch (_wValue)
1376 {
1377 case USB_PORT_FEAT_SUSPEND:
1378 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1379 "SetPortFeature - USB_PORT_FEAT_SUSPEND\n");
1380 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1381 hprt0.b.prtsusp = 1;
1382 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1383 //IFX_PRINT( "SUSPEND: HPRT0=%0x\n", hprt0.d32);
1384 /* Suspend the Phy Clock */
1385 {
1386 pcgcctl_data_t pcgcctl = {.d32=0};
1387 pcgcctl.b.stoppclk = 1;
1388 ifxusb_wreg(core_if->pcgcctl, pcgcctl.d32);
1389 }
1390 break;
1391 case USB_PORT_FEAT_POWER:
1392 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1393 "SetPortFeature - USB_PORT_FEAT_POWER\n");
1394 ifxusb_vbus_on (core_if);
1395 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1396 hprt0.b.prtpwr = 1;
1397 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1398 break;
1399 case USB_PORT_FEAT_RESET:
1400 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1401 "SetPortFeature - USB_PORT_FEAT_RESET\n");
1402 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1403 hprt0.b.prtrst = 1;
1404 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1405 /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
1406 MDELAY (60);
1407 hprt0.b.prtrst = 0;
1408 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1409 break;
1410 #ifdef __WITH_HS_ELECT_TST__
1411 case USB_PORT_FEAT_TEST:
1412 {
1413 uint32_t t;
1414 gint_data_t gintmsk;
1415 t = (_wIndex >> 8); /* MSB wIndex USB */
1416 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1417 "SetPortFeature - USB_PORT_FEAT_TEST %d\n", t);
1418 warn("USB_PORT_FEAT_TEST %d\n", t);
1419 if (t < 6)
1420 {
1421 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1422 hprt0.b.prttstctl = t;
1423 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1424 }
1425 else if (t == 6) /* HS_HOST_PORT_SUSPEND_RESUME */
1426 {
1427 /* Save current interrupt mask */
1428 gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1429
1430 /* Disable all interrupts while we muck with
1431 * the hardware directly
1432 */
1433 ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1434
1435 /* 15 second delay per the test spec */
1436 mdelay(15000);
1437
1438 /* Drive suspend on the root port */
1439 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1440 hprt0.b.prtsusp = 1;
1441 hprt0.b.prtres = 0;
1442 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1443
1444 /* 15 second delay per the test spec */
1445 mdelay(15000);
1446
1447 /* Drive resume on the root port */
1448 hprt0.d32 = ifxusb_read_hprt0 (core_if);
1449 hprt0.b.prtsusp = 0;
1450 hprt0.b.prtres = 1;
1451 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1452 mdelay(100);
1453
1454 /* Clear the resume bit */
1455 hprt0.b.prtres = 0;
1456 ifxusb_wreg(core_if->hprt0, hprt0.d32);
1457
1458 /* Restore interrupts */
1459 ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1460 }
1461 else if (t == 7) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
1462 {
1463 /* Save current interrupt mask */
1464 gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1465
1466 /* Disable all interrupts while we muck with
1467 * the hardware directly
1468 */
1469 ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1470
1471 /* 15 second delay per the test spec */
1472 mdelay(15000);
1473
1474 /* Send the Setup packet */
1475 do_setup(core_if);
1476
1477 /* 15 second delay so nothing else happens for awhile */
1478 mdelay(15000);
1479
1480 /* Restore interrupts */
1481 ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1482 }
1483
1484 else if (t == 8) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
1485 {
1486 /* Save current interrupt mask */
1487 gintmsk.d32 = ifxusb_rreg(&core_if->core_global_regs->gintmsk);
1488
1489 /* Disable all interrupts while we muck with
1490 * the hardware directly
1491 */
1492 ifxusb_wreg(&core_if->core_global_regs->gintmsk, 0);
1493
1494 /* Send the Setup packet */
1495 do_setup(core_if);
1496
1497 /* 15 second delay so nothing else happens for awhile */
1498 mdelay(15000);
1499
1500 /* Send the In and Ack packets */
1501 do_in_ack(core_if);
1502
1503 /* 15 second delay so nothing else happens for awhile */
1504 mdelay(15000);
1505
1506 /* Restore interrupts */
1507 ifxusb_wreg(&core_if->core_global_regs->gintmsk, gintmsk.d32);
1508 }
1509 }
1510 break;
1511 #endif //__WITH_HS_ELECT_TST__
1512 case USB_PORT_FEAT_INDICATOR:
1513 IFX_DEBUGPL (DBG_HCD, "IFXUSB HCD HUB CONTROL - "
1514 "SetPortFeature - USB_PORT_FEAT_INDICATOR\n");
1515 /* Not supported */
1516 break;
1517 default:
1518 retval = -EINVAL;
1519 IFX_ERROR ("IFXUSB HCD - "
1520 "SetPortFeature request %xh "
1521 "unknown or unsupported\n", _wValue);
1522 }
1523 break;
1524 default:
1525 error:
1526 retval = -EINVAL;
1527 IFX_WARN ("IFXUSB HCD - "
1528 "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
1529 _typeReq, _wIndex, _wValue);
1530 }
1531 return retval;
1532 }
1533
1534
1535
1536
1537 /*!
1538 \brief This function trigger a data transfer for a host channel and
1539 starts the transfer.
1540
1541 For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
1542 register along with a packet count of 1 and the channel is enabled. This
1543 causes a single PING transaction to occur. Other fields in HCTSIZ are
1544 simply set to 0 since no data transfer occurs in this case.
1545
1546 For a PING transfer in DMA mode, the HCTSIZ register is initialized with
1547 all the information required to perform the subsequent data transfer. In
1548 addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
1549 controller performs the entire PING protocol, then starts the data
1550 transfer.
1551 \param _core_if Pointer of core_if structure
1552 \param _ifxhc Information needed to initialize the host channel. The xfer_len
1553 value may be reduced to accommodate the max widths of the XferSize and
1554 PktCnt fields in the HCTSIZn register. The multi_count value may be changed
1555 to reflect the final xfer_len value.
1556 */
1557 void ifxhcd_hc_start(ifxhcd_hcd_t *_ifxhcd, ifxhcd_hc_t *_ifxhc)
1558 {
1559 ifxusb_core_if_t *core_if = &_ifxhcd->core_if;
1560 uint32_t max_hc_xfer_size = core_if->params.max_transfer_size;
1561 uint16_t max_hc_pkt_count = core_if->params.max_packet_count;
1562 ifxusb_hc_regs_t *hc_regs = core_if->hc_regs[_ifxhc->hc_num];
1563 hfnum_data_t hfnum;
1564
1565 hprt0_data_t hprt0;
1566
1567 if(_ifxhc->epqh->urbd->phase==URBD_DEQUEUEING)
1568 return;
1569
1570 hprt0.d32 = ifxusb_read_hprt0(core_if);
1571
1572 if(_ifxhcd->pkt_remaining==0)
1573 return;
1574
1575 #if 0
1576 if(_ifxhc->phase!=HC_WAITING)
1577 printk(KERN_INFO "%s() line %d: _ifxhc->phase!=HC_WAITING :%d\n",__func__,__LINE__,_ifxhc->phase);
1578 if(_ifxhc->epqh->urbd->phase==URBD_IDLE ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_IDLE\n",__func__,__LINE__);
1579 // if(_ifxhc->epqh->urbd->phase==URBD_ACTIVE ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_ACTIVE\n",__func__,__LINE__);
1580 if(_ifxhc->epqh->urbd->phase==URBD_STARTING ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_STARTING\n",__func__,__LINE__);
1581 if(_ifxhc->epqh->urbd->phase==URBD_STARTED ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_STARTED\n",__func__,__LINE__);
1582 if(_ifxhc->epqh->urbd->phase==URBD_COMPLETING) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_COMPLETING\n",__func__,__LINE__);
1583 if(_ifxhc->epqh->urbd->phase==URBD_DEQUEUEING) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_DEQUEUEING\n",__func__,__LINE__);
1584 if(_ifxhc->epqh->urbd->phase==URBD_FINISHING ) printk(KERN_INFO "%s() line %d: _ifxhc->epqh->urbd->phase==URBD_FINISHING\n",__func__,__LINE__);
1585 #endif
1586
1587 if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
1588 {
1589 if (_ifxhc->split)
1590 {
1591 if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
1592 max_hc_pkt_count = _ifxhcd->pkt_remaining;
1593 }
1594 else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
1595 {
1596 if( _ifxhc->is_in && _ifxhcd->pkt_count_limit_bi && max_hc_pkt_count > _ifxhcd->pkt_count_limit_bi)
1597 max_hc_pkt_count = _ifxhcd->pkt_count_limit_bi;
1598 if(!_ifxhc->is_in && _ifxhcd->pkt_count_limit_bo && max_hc_pkt_count > _ifxhcd->pkt_count_limit_bo)
1599 max_hc_pkt_count = _ifxhcd->pkt_count_limit_bo;
1600 if(max_hc_pkt_count*8 > _ifxhcd->pkt_remaining)
1601 max_hc_pkt_count = _ifxhcd->pkt_remaining/8;
1602 }
1603 else
1604 {
1605 if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
1606 max_hc_pkt_count = _ifxhcd->pkt_remaining;
1607 }
1608 }
1609 else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
1610 {
1611 if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
1612 max_hc_pkt_count = _ifxhcd->pkt_remaining;
1613 }
1614 else
1615 {
1616 if(max_hc_pkt_count > _ifxhcd->pkt_remaining)
1617 max_hc_pkt_count = _ifxhcd->pkt_remaining;
1618 }
1619
1620 if(max_hc_pkt_count==0)
1621 return;
1622
1623 if(max_hc_pkt_count * _ifxhc->mps < max_hc_xfer_size)
1624 max_hc_xfer_size = max_hc_pkt_count * _ifxhc->mps;
1625
1626 _ifxhc->epqh->urbd->phase=URBD_STARTING;
1627
1628 if(_ifxhc->is_in || _ifxhc->speed != IFXUSB_EP_SPEED_HIGH || _ifxhc->xfer_len==0)
1629 _ifxhc->epqh->do_ping=0;
1630 if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1631 _ifxhc->epqh->do_ping=0;
1632 if(_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL && _ifxhc->control_phase != IFXHCD_CONTROL_DATA )
1633 _ifxhc->epqh->do_ping=0;
1634
1635 if (_ifxhc->split > 0)
1636 {
1637 _ifxhc->start_pkt_count = 1;
1638 if(!_ifxhc->is_in && _ifxhc->split>1) // OUT CSPLIT
1639 _ifxhc->xfer_len = 0;
1640 if (_ifxhc->xfer_len > _ifxhc->mps)
1641 _ifxhc->xfer_len = _ifxhc->mps;
1642 if (_ifxhc->xfer_len > 188)
1643 _ifxhc->xfer_len = 188;
1644 }
1645 else if(_ifxhc->is_in)
1646 {
1647 _ifxhc->short_rw = 0;
1648 if (_ifxhc->xfer_len > 0)
1649 {
1650 if (_ifxhc->xfer_len > max_hc_xfer_size)
1651 _ifxhc->xfer_len = max_hc_xfer_size - _ifxhc->mps + 1;
1652 _ifxhc->start_pkt_count = (_ifxhc->xfer_len + _ifxhc->mps - 1) / _ifxhc->mps;
1653 if (_ifxhc->start_pkt_count > max_hc_pkt_count)
1654 _ifxhc->start_pkt_count = max_hc_pkt_count;
1655 }
1656 else /* Need 1 packet for transfer length of 0. */
1657 _ifxhc->start_pkt_count = 1;
1658 _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
1659 }
1660 else //non-split out
1661 {
1662 if (_ifxhc->xfer_len == 0)
1663 {
1664 if(_ifxhc->short_rw==0)
1665 printk(KERN_INFO "Info: %s() line %d: ZLP write without short_rw set! xfer_count:%d/%d \n",__func__,__LINE__,
1666 _ifxhc->xfer_count,
1667 _ifxhc->epqh->urbd->xfer_len);
1668 _ifxhc->start_pkt_count = 1;
1669 }
1670 else
1671 {
1672 if (_ifxhc->xfer_len > max_hc_xfer_size)
1673 {
1674 _ifxhc->start_pkt_count = (max_hc_xfer_size / _ifxhc->mps);
1675 _ifxhc->xfer_len = _ifxhc->start_pkt_count * _ifxhc->mps;
1676 }
1677 else
1678 {
1679 _ifxhc->start_pkt_count = (_ifxhc->xfer_len+_ifxhc->mps-1) / _ifxhc->mps;
1680 // if(_ifxhc->start_pkt_count * _ifxhc->mps == _ifxhc->xfer_len )
1681 // _ifxhc->start_pkt_count += _ifxhc->short_rw;
1682 }
1683 }
1684 }
1685
1686 if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_HIGH_SPEED)
1687 {
1688 if (_ifxhc->split)
1689 {
1690 if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
1691 _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
1692 else
1693 _ifxhcd->pkt_remaining = 0;
1694 }
1695 else if(_ifxhc->ep_type == IFXUSB_EP_TYPE_BULK)
1696 {
1697 if( _ifxhcd->pkt_remaining*8 > _ifxhc->start_pkt_count)
1698 _ifxhcd->pkt_remaining -= (_ifxhc->start_pkt_count*8);
1699 else
1700 _ifxhcd->pkt_remaining = 0;
1701 }
1702 else
1703 {
1704 if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
1705 _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
1706 else
1707 _ifxhcd->pkt_remaining = 0;
1708 }
1709 }
1710 else if (hprt0.b.prtspd == IFXUSB_HPRT0_PRTSPD_LOW_SPEED)
1711 {
1712 if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
1713 _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
1714 else
1715 _ifxhcd->pkt_remaining = 0;
1716 }
1717 else
1718 {
1719 if( _ifxhcd->pkt_remaining > _ifxhc->start_pkt_count)
1720 _ifxhcd->pkt_remaining -= _ifxhc->start_pkt_count;
1721 else
1722 _ifxhcd->pkt_remaining = 0;
1723 }
1724
1725 #ifdef __EN_ISOC__
1726 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1727 {
1728 /* Set up the initial PID for the transfer. */
1729 #if 1
1730 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
1731 #else
1732 if (_ifxhc->speed == IFXUSB_EP_SPEED_HIGH)
1733 {
1734 if (_ifxhc->is_in)
1735 {
1736 if (_ifxhc->multi_count == 1)
1737 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
1738 else if (_ifxhc->multi_count == 2)
1739 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA1;
1740 else
1741 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA2;
1742 }
1743 else
1744 {
1745 if (_ifxhc->multi_count == 1)
1746 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
1747 else
1748 _ifxhc->data_pid_start = IFXUSB_HC_PID_MDATA;
1749 }
1750 }
1751 else
1752 _ifxhc->data_pid_start = IFXUSB_HC_PID_DATA0;
1753 #endif
1754 }
1755 #endif
1756
1757 IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n", __func__, _ifxhc->hc_num);
1758 {
1759 hctsiz_data_t hctsiz= { .d32=0 };
1760
1761 hctsiz.b.dopng = _ifxhc->epqh->do_ping;
1762 _ifxhc->epqh->do_ping=0;
1763
1764 if(_ifxhc->is_in || _ifxhc->speed != IFXUSB_EP_SPEED_HIGH || _ifxhc->xfer_len==0)
1765 hctsiz.b.dopng = 0;
1766 if(_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1767 hctsiz.b.dopng = 0;
1768 if(_ifxhc->ep_type == IFXUSB_EP_TYPE_CTRL && _ifxhc->control_phase != IFXHCD_CONTROL_DATA )
1769 hctsiz.b.dopng = 0;
1770
1771 hctsiz.b.xfersize = _ifxhc->xfer_len;
1772 hctsiz.b.pktcnt = _ifxhc->start_pkt_count;
1773 hctsiz.b.pid = _ifxhc->data_pid_start;
1774 ifxusb_wreg(&hc_regs->hctsiz, hctsiz.d32);
1775
1776 IFX_DEBUGPL(DBG_HCDV, " Xfer Size: %d\n", hctsiz.b.xfersize);
1777 IFX_DEBUGPL(DBG_HCDV, " Num Pkts: %d\n" , hctsiz.b.pktcnt);
1778 IFX_DEBUGPL(DBG_HCDV, " Start PID: %d\n", hctsiz.b.pid);
1779 }
1780 IFX_DEBUGPL(DBG_HCDV, " DMA: 0x%08x\n", (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
1781 ifxusb_wreg(&hc_regs->hcdma, (uint32_t)(CPHYSADDR( ((uint32_t)(_ifxhc->xfer_buff))+ _ifxhc->xfer_count )));
1782
1783 /* Start the split */
1784 if (_ifxhc->split>0)
1785 {
1786 hcsplt_data_t hcsplt;
1787 hcsplt.d32 = ifxusb_rreg (&hc_regs->hcsplt);
1788 hcsplt.b.spltena = 1;
1789 if (_ifxhc->split>1)
1790 hcsplt.b.compsplt = 1;
1791 else
1792 hcsplt.b.compsplt = 0;
1793
1794 #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
1795 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1796 hcsplt.b.xactpos = _ifxhc->isoc_xact_pos;
1797 else
1798 #endif
1799 hcsplt.b.xactpos = IFXUSB_HCSPLIT_XACTPOS_ALL;// if not ISO
1800 ifxusb_wreg(&hc_regs->hcsplt, hcsplt.d32);
1801 IFX_DEBUGPL(DBG_HCDV, " SPLIT: XACT_POS:0x%08x\n", hcsplt.d32);
1802 }
1803
1804 {
1805 hcchar_data_t hcchar;
1806 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
1807 // hcchar.b.multicnt = _ifxhc->multi_count;
1808 hcchar.b.multicnt = 1;
1809
1810 if (_ifxhc->ep_type == IFXUSB_EP_TYPE_INTR || _ifxhc->ep_type == IFXUSB_EP_TYPE_ISOC)
1811 {
1812 hfnum.d32 = ifxusb_rreg(&core_if->host_global_regs->hfnum);
1813 /* 1 if _next_ frame is odd, 0 if it's even */
1814 hcchar.b.oddfrm = (hfnum.b.frnum & 0x1) ? 0 : 1;
1815 }
1816
1817 #ifdef __DEBUG__
1818 _ifxhc->start_hcchar_val = hcchar.d32;
1819 if (hcchar.b.chdis)
1820 IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
1821 __func__, _ifxhc->hc_num, hcchar.d32);
1822 #endif
1823
1824 /* Set host channel enable after all other setup is complete. */
1825 hcchar.b.chen = 1;
1826 hcchar.b.chdis = 0;
1827 hcchar.b.epdir = _ifxhc->is_in;
1828 _ifxhc->hcchar=hcchar.d32;
1829 }
1830
1831 IFX_DEBUGPL(DBG_HCDV, " HCCHART: 0x%08x\n", _ifxhc->hcchar);
1832
1833 _ifxhc->phase=HC_STARTING;
1834 }
1835
1836 /*!
1837 \brief Attempts to halt a host channel. This function should only be called
1838 to abort a transfer in DMA mode. Under normal circumstances in DMA mode, the
1839 controller halts the channel when the transfer is complete or a condition
1840 occurs that requires application intervention.
1841
1842 In DMA mode, always sets the Channel Enable and Channel Disable bits of the
1843 HCCHARn register. The controller ensures there is space in the request
1844 queue before submitting the halt request.
1845
1846 Some time may elapse before the core flushes any posted requests for this
1847 host channel and halts. The Channel Halted interrupt handler completes the
1848 deactivation of the host channel.
1849 */
1850 int ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
1851 ifxhcd_hc_t *_ifxhc,
1852 ifxhcd_halt_status_e _halt_status)
1853 {
1854 hcchar_data_t hcchar;
1855 ifxusb_hc_regs_t *hc_regs;
1856 hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
1857
1858 WARN_ON(_halt_status == HC_XFER_NO_HALT_STATUS);
1859
1860 {
1861 hprt0_data_t hprt0;
1862 hprt0.d32 = ifxusb_rreg(_core_if->hprt0);
1863 if(hprt0.b.prtena == 0)
1864 return -1;
1865 }
1866
1867 if (_halt_status == HC_XFER_URB_DEQUEUE ||
1868 _halt_status == HC_XFER_AHB_ERR)
1869 {
1870 /*
1871 * Disable all channel interrupts except Ch Halted. The URBD
1872 * and EPQH state associated with this transfer has been cleared
1873 * (in the case of URB_DEQUEUE), so the channel needs to be
1874 * shut down carefully to prevent crashes.
1875 */
1876 hcint_data_t hcintmsk;
1877 hcintmsk.d32 = 0;
1878 hcintmsk.b.chhltd = 1;
1879 ifxusb_wreg(&hc_regs->hcintmsk, hcintmsk.d32);
1880
1881 /*
1882 * Make sure no other interrupts besides halt are currently
1883 * pending. Handling another interrupt could cause a crash due
1884 * to the URBD and EPQH state.
1885 */
1886 ifxusb_wreg(&hc_regs->hcint, ~hcintmsk.d32);
1887
1888 /*
1889 * Make sure the halt status is set to URB_DEQUEUE or AHB_ERR
1890 * even if the channel was already halted for some other
1891 * reason.
1892 */
1893 _ifxhc->halt_status = _halt_status;
1894 }
1895
1896 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
1897 if (hcchar.b.chen == 0)
1898 {
1899 /*
1900 * The channel is either already halted or it hasn't
1901 * started yet. In DMA mode, the transfer may halt if
1902 * it finishes normally or a condition occurs that
1903 * requires driver intervention. Don't want to halt
1904 * the channel again. In either Slave or DMA mode,
1905 * it's possible that the transfer has been assigned
1906 * to a channel, but not started yet when an URB is
1907 * dequeued. Don't want to halt a channel that hasn't
1908 * started yet.
1909 */
1910 _ifxhc->phase=HC_IDLE;
1911 return -1;
1912 }
1913
1914 if (_ifxhc->phase==HC_STOPPING)
1915 {
1916 /*
1917 * A halt has already been issued for this channel. This might
1918 * happen when a transfer is aborted by a higher level in
1919 * the stack.
1920 */
1921 #ifdef __DEBUG__
1922 IFX_PRINT("*** %s: Channel %d, double halt a channel***\n",
1923 __func__, _ifxhc->hc_num);
1924 #endif
1925 return 0;
1926 }
1927 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
1928 hcchar.b.chen = 1;
1929 hcchar.b.chdis = 1;
1930
1931 ifxusb_wreg(&hc_regs->hcchar, hcchar.d32);
1932
1933 _ifxhc->halt_status = _halt_status;
1934 _ifxhc->phase=HC_STOPPING;
1935
1936 IFX_DEBUGPL(DBG_HCDV, "%s: Channel %d\n" , __func__, _ifxhc->hc_num);
1937 IFX_DEBUGPL(DBG_HCDV, " hcchar: 0x%08x\n" , hcchar.d32);
1938 IFX_DEBUGPL(DBG_HCDV, " halt_status: %d\n" , _ifxhc->halt_status);
1939
1940 return 0;
1941 }
1942
1943 /*!
1944 \brief Clears a host channel.
1945 */
1946 void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc)
1947 {
1948 ifxusb_hc_regs_t *hc_regs;
1949
1950 _ifxhc->phase=HC_IDLE;
1951 _ifxhc->epqh=0;
1952
1953 /*
1954 * Clear channel interrupt enables and any unhandled channel interrupt
1955 * conditions.
1956 */
1957 hc_regs = _core_if->hc_regs[_ifxhc->hc_num];
1958 ifxusb_wreg(&hc_regs->hcintmsk, 0);
1959 ifxusb_wreg(&hc_regs->hcint, 0xFFFFFFFF);
1960
1961 #ifdef __DEBUG__
1962 {
1963 hcchar_data_t hcchar;
1964 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
1965 if (hcchar.b.chdis)
1966 IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", __func__, _ifxhc->hc_num, hcchar.d32);
1967 }
1968 #endif
1969 }
1970
1971
1972
1973
1974
1975 #ifdef __DEBUG__
1976 static void dump_urb_info(struct urb *_urb, char* _fn_name)
1977 {
1978 IFX_PRINT("%s, urb %p\n" , _fn_name, _urb);
1979 IFX_PRINT(" Device address: %d\n", usb_pipedevice(_urb->pipe));
1980 IFX_PRINT(" Endpoint: %d, %s\n" , usb_pipeendpoint(_urb->pipe),
1981 (usb_pipein(_urb->pipe) ? "IN" : "OUT"));
1982 IFX_PRINT(" Endpoint type: %s\n",
1983 ({ char *pipetype;
1984 switch (usb_pipetype(_urb->pipe)) {
1985 case PIPE_CONTROL: pipetype = "CONTROL"; break;
1986 case PIPE_BULK: pipetype = "BULK"; break;
1987 case PIPE_INTERRUPT: pipetype = "INTERRUPT"; break;
1988 case PIPE_ISOCHRONOUS: pipetype = "ISOCHRONOUS"; break;
1989 default: pipetype = "UNKNOWN"; break;
1990 };
1991 pipetype;
1992 }));
1993 IFX_PRINT(" Speed: %s\n",
1994 ({ char *speed;
1995 switch (_urb->dev->speed) {
1996 case USB_SPEED_HIGH: speed = "HIGH"; break;
1997 case USB_SPEED_FULL: speed = "FULL"; break;
1998 case USB_SPEED_LOW: speed = "LOW"; break;
1999 default: speed = "UNKNOWN"; break;
2000 };
2001 speed;
2002 }));
2003 IFX_PRINT(" Max packet size: %d\n",
2004 usb_maxpacket(_urb->dev, _urb->pipe, usb_pipeout(_urb->pipe)));
2005 IFX_PRINT(" Data buffer length: %d\n", _urb->transfer_buffer_length);
2006 IFX_PRINT(" Transfer buffer: %p, Transfer DMA: %p\n",
2007 _urb->transfer_buffer, (void *)_urb->transfer_dma);
2008 IFX_PRINT(" Setup buffer: %p, Setup DMA: %p\n",
2009 _urb->setup_packet, (void *)_urb->setup_dma);
2010 IFX_PRINT(" Interval: %d\n", _urb->interval);
2011 if (usb_pipetype(_urb->pipe) == PIPE_ISOCHRONOUS)
2012 {
2013 int i;
2014 for (i = 0; i < _urb->number_of_packets; i++)
2015 {
2016 IFX_PRINT(" ISO Desc %d:\n", i);
2017 IFX_PRINT(" offset: %d, length %d\n",
2018 _urb->iso_frame_desc[i].offset,
2019 _urb->iso_frame_desc[i].length);
2020 }
2021 }
2022 }
2023
2024 #if 0
2025 static void dump_channel_info(ifxhcd_hcd_t *_ifxhcd, ifxhcd_epqh_t *_epqh)
2026 {
2027 if (_epqh->hc != NULL)
2028 {
2029 ifxhcd_hc_t *hc = _epqh->hc;
2030 struct list_head *item;
2031 ifxhcd_epqh_t *epqh_item;
2032
2033 ifxusb_hc_regs_t *hc_regs;
2034
2035 hcchar_data_t hcchar;
2036 hcsplt_data_t hcsplt;
2037 hctsiz_data_t hctsiz;
2038 uint32_t hcdma;
2039
2040 hc_regs = _ifxhcd->core_if.hc_regs[hc->hc_num];
2041 hcchar.d32 = ifxusb_rreg(&hc_regs->hcchar);
2042 hcsplt.d32 = ifxusb_rreg(&hc_regs->hcsplt);
2043 hctsiz.d32 = ifxusb_rreg(&hc_regs->hctsiz);
2044 hcdma = ifxusb_rreg(&hc_regs->hcdma);
2045
2046 IFX_PRINT(" Assigned to channel %d:\n" , hc->hc_num);
2047 IFX_PRINT(" hcchar 0x%08x, hcsplt 0x%08x\n", hcchar.d32, hcsplt.d32);
2048 IFX_PRINT(" hctsiz 0x%08x, hcdma 0x%08x\n" , hctsiz.d32, hcdma);
2049 IFX_PRINT(" dev_addr: %d, ep_num: %d, is_in: %d\n",
2050 hc->dev_addr, hc->ep_num, hc->is_in);
2051 IFX_PRINT(" ep_type: %d\n" , hc->ep_type);
2052 IFX_PRINT(" max_packet_size: %d\n", hc->mps);
2053 IFX_PRINT(" data_pid_start: %d\n" , hc->data_pid_start);
2054 IFX_PRINT(" halt_status: %d\n" , hc->halt_status);
2055 IFX_PRINT(" xfer_buff: %p\n" , hc->xfer_buff);
2056 IFX_PRINT(" xfer_len: %d\n" , hc->xfer_len);
2057 IFX_PRINT(" epqh: %p\n" , hc->epqh);
2058 IFX_PRINT(" NP :\n");
2059 list_for_each(item, &_ifxhcd->epqh_list_np)
2060 {
2061 epqh_item = list_entry(item, ifxhcd_epqh_t, ql);
2062 IFX_PRINT(" %p\n", epqh_item);
2063 }
2064 IFX_PRINT(" INTR :\n");
2065 list_for_each(item, &_ifxhcd->epqh_list_intr)
2066 {
2067 epqh_item = list_entry(item, ifxhcd_epqh_t, ql);
2068 IFX_PRINT(" %p\n", epqh_item);
2069 }
2070 #ifdef __EN_ISOC__
2071 IFX_PRINT(" ISOC:\n");
2072 list_for_each(item, &_ifxhcd->epqh_list_isoc)
2073 {
2074 epqh_item = list_entry(item, ifxhcd_epqh_t, ql);
2075 IFX_PRINT(" %p\n", epqh_item);
2076 }
2077 #endif
2078 }
2079 }
2080 #endif
2081 #endif //__DEBUG__
2082
2083
2084 /*!
2085 \brief This function writes a packet into the Tx FIFO associated with the Host
2086 Channel. For a channel associated with a non-periodic EP, the non-periodic
2087 Tx FIFO is written. For a channel associated with a periodic EP, the
2088 periodic Tx FIFO is written. This function should only be called in Slave
2089 mode.
2090
2091 Upon return the xfer_buff and xfer_count fields in _hc are incremented by
2092 then number of bytes written to the Tx FIFO.
2093 */
2094
2095 #ifdef __ENABLE_DUMP__
2096 void ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd)
2097 {
2098 int num_channels;
2099 int i;
2100 num_channels = _ifxhcd->core_if.params.host_channels;
2101 IFX_PRINT("\n");
2102 IFX_PRINT("************************************************************\n");
2103 IFX_PRINT("HCD State:\n");
2104 IFX_PRINT(" Num channels: %d\n", num_channels);
2105 for (i = 0; i < num_channels; i++) {
2106 ifxhcd_hc_t *hc = &_ifxhcd->ifxhc[i];
2107 IFX_PRINT(" Channel %d:\n", hc->hc_num);
2108 IFX_PRINT(" dev_addr: %d, ep_num: %d, ep_is_in: %d\n",
2109 hc->dev_addr, hc->ep_num, hc->is_in);
2110 IFX_PRINT(" speed: %d\n" , hc->speed);
2111 IFX_PRINT(" ep_type: %d\n" , hc->ep_type);
2112 IFX_PRINT(" mps: %d\n", hc->mps);
2113 IFX_PRINT(" data_pid_start: %d\n" , hc->data_pid_start);
2114 IFX_PRINT(" xfer_buff: %p\n" , hc->xfer_buff);
2115 IFX_PRINT(" xfer_len: %d\n" , hc->xfer_len);
2116 IFX_PRINT(" xfer_count: %d\n" , hc->xfer_count);
2117 IFX_PRINT(" halt_status: %d\n" , hc->halt_status);
2118 IFX_PRINT(" split: %d\n" , hc->split);
2119 IFX_PRINT(" hub_addr: %d\n" , hc->hub_addr);
2120 IFX_PRINT(" port_addr: %d\n" , hc->port_addr);
2121 #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
2122 IFX_PRINT(" isoc_xact_pos: %d\n" , hc->isoc_xact_pos);
2123 #endif
2124
2125 IFX_PRINT(" epqh: %p\n" , hc->epqh);
2126 IFX_PRINT(" short_rw: %d\n" , hc->short_rw);
2127 IFX_PRINT(" control_phase: %d\n" , hc->control_phase);
2128 if(hc->epqh)
2129 {
2130 IFX_PRINT(" do_ping: %d\n" , hc->epqh->do_ping);
2131 }
2132 IFX_PRINT(" start_pkt_count: %d\n" , hc->start_pkt_count);
2133 }
2134 IFX_PRINT("************************************************************\n");
2135 IFX_PRINT("\n");
2136 }
2137 #endif //__ENABLE_DUMP__
2138