1 /*****************************************************************************
2 ** FILE NAME : ifxhcd.c
3 ** PROJECT : IFX USB sub-system V3
4 ** MODULES : IFX USB sub-system Host and Device driver
7 ** AUTHOR : Chen, Howard
8 ** DESCRIPTION : This file contains the structures, constants, and
9 ** interfaces for the Host Contoller Driver (HCD).
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.
18 ** REFERENCE : Synopsys DWC-OTG Driver 2.7
19 ** COPYRIGHT : Copyright (c) 2010
20 ** LANTIQ DEUTSCHLAND GMBH,
21 ** Am Campeon 3, 85579 Neubiberg, Germany
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.
28 ** Version Control Section **
32 ** $Log$ Revision history
33 *****************************************************************************/
36 * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
37 * For this code the following notice is applicable:
39 * ==========================================================================
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.
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.
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
66 * ========================================================================== */
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.
75 #include <linux/version.h>
76 #include "ifxusb_version.h"
78 #include <linux/kernel.h>
79 #include <linux/module.h>
80 #include <linux/moduleparam.h>
81 #include <linux/init.h>
83 #include <linux/device.h>
85 #include <linux/errno.h>
86 #include <linux/list.h>
87 #include <linux/interrupt.h>
88 #include <linux/string.h>
90 #include <linux/dma-mapping.h>
93 #include "ifxusb_plat.h"
94 #include "ifxusb_regs.h"
95 #include "ifxusb_cif.h"
101 static void dump_urb_info(struct urb
*_urb
, char* _fn_name
);
103 static void dump_channel_info(ifxhcd_hcd_t
*_ifxhcd
,
104 ifxhcd_epqh_t
*_epqh
);
108 static void ifxhcd_complete_urb_sub(ifxhcd_urbd_t
*_urbd
)
110 ifxhcd_hcd_t
*ifxhcd
;
111 struct urb
*urb
=NULL
;
113 if (!list_empty(&_urbd
->ql
))
115 list_del_init(&_urbd
->ql
);
116 _urbd
->epqh
->urbd_count
--;
119 IFX_ERROR("%s: urb(%p) not connect to any epqh\n",
122 ifxhcd
=_urbd
->epqh
->ifxhcd
;
125 IFX_ERROR("%s: invalid urb\n",__func__
);
128 if(urb
->hcpriv
!= _urbd
)
129 IFX_ERROR("%s: invalid"
130 " urb(%p)->hcpriv(%p) != _urbd(%p)\n",
135 #if defined(__UNALIGNED_BUF_ADJ__)
137 // _urbd->using_aligned_buf &&
139 memcpy(_urbd
->xfer_buff
,
142 if(_urbd
->aligned_buf
)
143 ifxusb_free_buf_h(_urbd
->aligned_buf
);
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
);
150 usb_hcd_giveback_urb(ifxhcd_to_syshcd(ifxhcd
), urb
,
157 #ifdef __STRICT_ORDER__
158 static void ifxhcd_complete_urb_func(unsigned long data
)
163 struct list_head
*item
;
167 epqh
=((ifxhcd_epqh_t
*)data
);
169 while (!list_empty(&epqh
->release_list
) && count
)
171 item
= epqh
->release_list
.next
;
172 urbd
= list_entry(item
, ifxhcd_urbd_t
, ql
);
174 IFX_ERROR("%s: invalid urbd\n",__func__
);
175 else if (!urbd
->epqh
)
176 IFX_ERROR("%s: invalid epqd\n",__func__
);
179 ifxhcd_epqh_t
*epqh2
;
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
);
189 if(!list_empty(&epqh
->release_list
))
190 tasklet_schedule(&epqh
->complete_urb_sub
);
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.
197 void ifxhcd_complete_urb(ifxhcd_hcd_t
*_ifxhcd
,
198 ifxhcd_urbd_t
*_urbd
,
205 IFX_ERROR("%s: invalid urbd\n",__func__
);
210 IFX_ERROR("%s: invalid epqh\n",__func__
);
214 local_irq_save(flags
);
215 LOCK_URBD_LIST(_urbd
->epqh
);
217 if (CHK_DEBUG_LEVEL(DBG_HCDV
| DBG_HCD_URB
))
219 IFX_PRINT("%s: ehqh %p _urbd %p, urb %p,"
220 " device %d, ep %d %s/%s, status=%d\n",
221 __func__
,_urbd
->epqh
,
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",
228 if ((_urbd
->urb
)&& _urbd
->epqh
->ep_type
== IFXUSB_EP_TYPE_ISOC
)
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
);
236 _urbd
->status
= _status
;
238 if(_urbd
->phase
!=URBD_FINISHING
)
240 if(_urbd
->phase
!=URBD_DEQUEUEING
&& _urbd
->phase
!=URBD_COMPLETING
)
241 printk(KERN_INFO
"Warning: %s() Strange URBD PHASE %d\n",__func__
,_urbd
->phase
);
244 if( _urbd
->status
== 0
245 && _urbd
->phase
==URBD_COMPLETING
248 list_move_tail(&_urbd
->ql
,&_urbd
->epqh
->release_list
);
249 if(!_urbd
->epqh
->complete_urb_sub
.func
)
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
;
257 tasklet_schedule(&_urbd
->epqh
->complete_urb_sub
);
261 _urbd
->phase
=URBD_FINISHING
;
262 ifxhcd_complete_urb_sub(_urbd
);
264 UNLOCK_URBD_LIST(_urbd
->epqh
);
268 UNLOCK_URBD_LIST(_urbd
->epqh
);
274 printk(KERN_INFO
"Warning: %s() Double Completing \n",__func__
);
275 UNLOCK_URBD_LIST(_urbd
->epqh
);
278 local_irq_restore (flags
);
281 static void ifxhcd_complete_urb_func(unsigned long data
)
286 urbd
=((ifxhcd_urbd_t
*)data
);
288 // local_irq_save(flags);
290 IFX_ERROR("%s: invalid urbd\n",__func__
);
291 else if (!urbd
->epqh
)
292 IFX_ERROR("%s: invalid epqd\n",__func__
);
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
);
301 // local_irq_restore (flags);
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.
309 void ifxhcd_complete_urb(ifxhcd_hcd_t
*_ifxhcd
, ifxhcd_urbd_t
*_urbd
, int _status
)
315 IFX_ERROR("%s: invalid urbd\n",__func__
);
320 IFX_ERROR("%s: invalid epqh\n",__func__
);
324 local_irq_save(flags
);
325 LOCK_URBD_LIST(_urbd
->epqh
);
327 if (CHK_DEBUG_LEVEL(DBG_HCDV
| DBG_HCD_URB
))
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",
336 if ((_urbd
->urb
)&& _urbd
->epqh
->ep_type
== IFXUSB_EP_TYPE_ISOC
)
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
);
344 _urbd
->status
= _status
;
346 if(_urbd
->phase
!=URBD_FINISHING
)
348 if(_urbd
->phase
!=URBD_DEQUEUEING
&& _urbd
->phase
!=URBD_COMPLETING
)
349 printk(KERN_INFO
"Warning: %s() Strange URBD PHASE %d\n",__func__
,_urbd
->phase
);
352 if( _urbd
->status
== 0
353 && _urbd
->phase
==URBD_COMPLETING
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
);
368 _urbd
->phase
=URBD_FINISHING
;
369 ifxhcd_complete_urb_sub(_urbd
);
376 printk(KERN_INFO
"Warning: %s() Double Completing \n",__func__
);
377 UNLOCK_URBD_LIST(_urbd
->epqh
);
378 local_irq_restore (flags
);
383 \brief Processes all the URBs in a single EPQHs. Completes them with
384 status and frees the URBD.
387 void kill_all_urbs_in_epqh(ifxhcd_hcd_t
*_ifxhcd
, ifxhcd_epqh_t
*_epqh
, int _status
)
389 struct list_head
*item
;
390 struct list_head
*next
;
396 IFX_DEBUGPL(DBG_HCDV
, "%s %p\n",__func__
,_epqh
);
397 LOCK_URBD_LIST(_epqh
);
398 list_for_each(item
, &_epqh
->urbd_list
)
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
405 urbd
->phase
=URBD_DEQUEUEING
;
407 list_for_each_safe(item
, next
, &_epqh
->urbd_list
)
409 urbd
= list_entry(item
, ifxhcd_urbd_t
, ql
);
410 if(urbd
->phase
==URBD_DEQUEUEING
)
412 urbd
->urb
->status
= _status
;
413 urbd
->phase
= URBD_FINISHING
;
414 ifxhcd_complete_urb_sub(urbd
);
416 else if( urbd
->phase
==URBD_STARTED
417 || urbd
->phase
==URBD_STARTING
418 // || urbd->phase==URBD_ACTIVE
421 if(ifxhcd_hc_halt(&_ifxhcd
->core_if
, _epqh
->hc
, HC_XFER_URB_DEQUEUE
))
423 urbd
->urb
->status
= _status
;
424 urbd
->phase
=URBD_FINISHING
;
425 ifxhcd_complete_urb_sub(urbd
);
429 IFX_ERROR("%s: invalid urb phase:%d \n",__func__
,urbd
->phase
);
431 UNLOCK_URBD_LIST(_epqh
);
432 IFX_DEBUGPL(DBG_HCDV
, "%s %p finish\n",__func__
,_epqh
);
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.
441 void epqh_list_free_1(ifxhcd_hcd_t
*_ifxhcd
, struct list_head
*_epqh_list
)
444 struct list_head
*item
;
450 IFX_DEBUGPL(DBG_HCDV
, "%s %p\n",__func__
,_epqh_list
);
452 item
= _epqh_list
->next
;
453 while(item
!= _epqh_list
&& item
!= item
->next
)
455 epqh
= list_entry(item
, ifxhcd_epqh_t
, ql
);
456 epqh
->phase
=EPQH_DISABLING
;
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
))
462 if(list_empty(&epqh
->urbd_list
))
464 ifxhcd_epqh_free(epqh
);
466 IFX_DEBUGPL(DBG_HCDV
, "%s %p finish\n",__func__
,_epqh_list
);
467 /* Ensure there are no URBDs or URBs left. */
471 void epqh_list_free_2(ifxhcd_hcd_t
*_ifxhcd
, struct list_head
*_epqh_list
)
474 struct list_head
*item
;
475 struct list_head
*next
;
481 IFX_DEBUGPL(DBG_HCDV
, "%s %p\n",__func__
,_epqh_list
);
482 list_for_each_safe(item
, next
, _epqh_list
)
484 epqh
= list_entry(item
, ifxhcd_epqh_t
, ql
);
485 if(item
== item
->next
)
487 ifxhcd_epqh_free(epqh
);
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);
495 for(;!list_empty(&epqh
->urbd_list
) && count
> 0; count
--) udelay(1);
498 IFX_ERROR("%s: unable to clear urbd in epqh \n",__func__
);
499 ifxhcd_epqh_free(epqh
);
502 IFX_DEBUGPL(DBG_HCDV
, "%s %p finish\n",__func__
,_epqh_list
);
503 /* Ensure there are no URBDs or URBs left. */
507 void epqh_list_free_all_sub(unsigned long data
)
509 ifxhcd_hcd_t
*ifxhcd
;
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
);
515 epqh_list_free_1(ifxhcd
, &ifxhcd
->epqh_list_isoc
);
518 epqh_list_free_2(ifxhcd
, &ifxhcd
->epqh_list_np
);
519 epqh_list_free_2(ifxhcd
, &ifxhcd
->epqh_list_intr
);
521 epqh_list_free_2(ifxhcd
, &ifxhcd
->epqh_list_isoc
);
526 void epqh_list_free_all(ifxhcd_hcd_t
*_ifxhcd
)
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
);
538 \brief This function is called to handle the disconnection of host port.
540 int32_t ifxhcd_disconnect(ifxhcd_hcd_t
*_ifxhcd
)
542 IFX_DEBUGPL(DBG_HCDV
, "%s(%p)\n", __func__
, _ifxhcd
);
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;
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.
555 gint_data_t intr
= { .d32
= 0 };
556 intr
.b
.nptxfempty
= 1;
557 intr
.b
.ptxfempty
= 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);
563 /* Respond with an error status to all URBs in the schedule. */
564 epqh_list_free_all(_ifxhcd
);
566 /* Clean up any host channels that were in use. */
569 ifxhcd_hc_t
*channel
;
570 ifxusb_hc_regs_t
*hc_regs
;
571 hcchar_data_t hcchar
;
574 num_channels
= _ifxhcd
->core_if
.params
.host_channels
;
576 for (i
= 0; i
< num_channels
; i
++)
578 channel
= &_ifxhcd
->ifxhc
[i
];
579 hc_regs
= _ifxhcd
->core_if
.hc_regs
[i
];
580 hcchar
.d32
= ifxusb_rreg(&hc_regs
->hcchar
);
582 printk(KERN_INFO
"Warning: %s() HC still enabled\n",__func__
);
583 ifxhcd_hc_cleanup(&_ifxhcd
->core_if
, channel
);
586 IFX_DEBUGPL(DBG_HCDV
, "%s(%p) finish\n", __func__
, _ifxhcd
);
592 \brief Frees secondary storage associated with the ifxhcd_hcd structure contained
593 in the struct usb_hcd field.
595 static void ifxhcd_freeextra(struct usb_hcd
*_syshcd
)
597 ifxhcd_hcd_t
*ifxhcd
= syshcd_to_ifxhcd(_syshcd
);
599 IFX_DEBUGPL(DBG_HCD
, "IFXUSB HCD FREE\n");
601 /* Free memory for EPQH/URBD lists */
602 epqh_list_free_all(ifxhcd
);
604 /* Free memory for the host channels. */
605 ifxusb_free_buf_h(ifxhcd
->status_buf
);
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.
615 int ifxhcd_init(ifxhcd_hcd_t
*_ifxhcd
)
618 struct usb_hcd
*syshcd
= NULL
;
620 IFX_DEBUGPL(DBG_HCD
, "IFX USB HCD INIT\n");
622 INIT_EPQH_LIST_ALL(_ifxhcd
);
623 INIT_EPQH_LIST(_ifxhcd
);
625 init_timer(&_ifxhcd
->autoprobe_timer
);
626 init_timer(&_ifxhcd
->host_probe_timer
);
627 _ifxhcd
->probe_sec
= 5;
628 _ifxhcd
->autoprobe_sec
= 30;
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;
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
);
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;
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
);
677 INIT_LIST_HEAD(&_ifxhcd
->epqh_list_isoc
);
681 * Create a host channel descriptor for each host channel implemented
682 * in the controller. Initialize the channel descriptor array.
685 int num_channels
= _ifxhcd
->core_if
.params
.host_channels
;
687 for (i
= 0; i
< num_channels
; i
++)
689 _ifxhcd
->ifxhc
[i
].hc_num
= i
;
690 IFX_DEBUGPL(DBG_HCDV
, "HCD Added channel #%d\n", i
);
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;
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.
704 retval
= usb_add_hcd(syshcd
, _ifxhcd
->core_if
.irq
, 0 | IRQF_SHARED
);
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
714 _ifxhcd
->status_buf
= ifxusb_alloc_buf_h(IFXHCD_STATUS_BUF_SIZE
, 1);
716 if (_ifxhcd
->status_buf
)
718 IFX_DEBUGPL(DBG_HCD
, "IFX USB HCD Initialized, bus=%s, usbbus=%d\n", _ifxhcd
->core_if
.core_name
, syshcd
->self
.busnum
);
721 IFX_ERROR("%s: status_buf allocation failed\n", __func__
);
723 /* Error conditions */
724 usb_remove_hcd(syshcd
);
726 ifxhcd_freeextra(syshcd
);
733 \brief Removes the HCD.
734 Frees memory and resources associated with the HCD and deregisters the bus.
736 void ifxhcd_remove(ifxhcd_hcd_t
*_ifxhcd
)
738 struct usb_hcd
*syshcd
= ifxhcd_to_syshcd(_ifxhcd
);
740 IFX_DEBUGPL(DBG_HCD
, "IFX USB HCD REMOVE\n");
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);
746 usb_remove_hcd(syshcd
);
747 ifxhcd_freeextra(syshcd
);
754 /* =========================================================================
755 * Linux HC Driver Functions
756 * ========================================================================= */
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.
764 int ifxhcd_start(struct usb_hcd
*_syshcd
)
766 ifxhcd_hcd_t
*ifxhcd
= syshcd_to_ifxhcd (_syshcd
);
767 ifxusb_core_if_t
*core_if
= &ifxhcd
->core_if
;
770 IFX_DEBUGPL(DBG_HCD
, "IFX USB HCD START\n");
772 bus
= hcd_to_bus(_syshcd
);
774 /* Initialize the bus state. */
775 _syshcd
->state
= HC_STATE_RUNNING
;
777 /* Initialize and connect root hub if one is not already attached */
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
);
785 ifxhcd
->flags
.d32
= 0;
787 /* Put all channels in the free channel list and clean up channel states.*/
789 int num_channels
= ifxhcd
->core_if
.params
.host_channels
;
791 for (i
= 0; i
< num_channels
; i
++)
793 ifxhcd_hc_t
*channel
;
794 channel
= &ifxhcd
->ifxhc
[i
];
795 ifxhcd_hc_cleanup(&ifxhcd
->core_if
, channel
);
798 /* Initialize the USB core for host mode operation. */
800 ifxusb_host_enable_interrupts(core_if
);
801 ifxusb_enable_global_interrupts_h(core_if
);
802 ifxusb_phy_power_on_h (core_if
);
804 ifxusb_vbus_init(core_if
);
806 /* Turn on the vbus power. */
809 hprt0
.d32
= ifxusb_read_hprt0(core_if
);
811 IFX_PRINT("Init: Power Port (%d)\n", hprt0
.b
.prtpwr
);
812 if (hprt0
.b
.prtpwr
== 0 )
815 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
816 ifxusb_vbus_on(core_if
);
823 \brief Halts the IFXUSB host mode operations in a clean manner. USB transfers are
826 #if defined(__IS_AR10__)
827 void ifxusb_oc_int_free(int port
);
829 void ifxusb_oc_int_free(void);
832 void ifxhcd_stop(struct usb_hcd
*_syshcd
)
834 ifxhcd_hcd_t
*ifxhcd
= syshcd_to_ifxhcd(_syshcd
);
835 hprt0_data_t hprt0
= { .d32
=0 };
837 IFX_DEBUGPL(DBG_HCD
, "IFX USB HCD STOP\n");
839 /* Turn off all interrupts. */
840 ifxusb_disable_global_interrupts_h(&ifxhcd
->core_if
);
841 ifxusb_host_disable_interrupts(&ifxhcd
->core_if
);
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).
849 /* Turn off the vbus power */
850 IFX_PRINT("PortPower off\n");
852 ifxusb_vbus_off(&ifxhcd
->core_if
);
855 #if defined(__IS_AR10__)
856 ifxusb_oc_int_free(ifxhcd
->core_if
.core_no
);
858 ifxusb_oc_int_free();
862 ifxusb_vbus_free(&ifxhcd
->core_if
);
864 ifxusb_wreg(ifxhcd
->core_if
.hprt0
, hprt0
.d32
);
869 \brief Returns the current frame number
871 int ifxhcd_get_frame_number(struct usb_hcd
*_syshcd
)
873 ifxhcd_hcd_t
*ifxhcd
= syshcd_to_ifxhcd(_syshcd
);
876 hfnum
.d32
= ifxusb_rreg(&ifxhcd
->core_if
.host_global_regs
->hfnum
);
878 return hfnum
.b
.frnum
;
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
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
,
893 ifxhcd_hcd_t
*ifxhcd
= syshcd_to_ifxhcd (_syshcd
);
894 ifxhcd_epqh_t
*epqh
= NULL
;
897 if (CHK_DEBUG_LEVEL(DBG_HCDV
| DBG_HCD_URB
))
898 dump_urb_info(_urb
, "ifxusb_hcd_urb_enqueue");
901 if (!ifxhcd
->flags
.b
.port_connect_status
) /* No longer connected. */
904 #if !defined(__EN_ISOC__)
905 if(usb_pipetype(_urb
->pipe
) == PIPE_ISOCHRONOUS
)
907 IFX_ERROR("ISOC transfer not supported!!!\n");
914 IFX_WARN("%s() Previous urb->hcpriv exist %p\n",__func__
,_urb
->hcpriv
);
920 epqh
=ifxhcd_urbd_create (ifxhcd
,_urb
);
923 IFX_ERROR("IFXUSB HCD URB Enqueue failed creating URBD\n");
926 if(epqh
->phase
==EPQH_DISABLING
)
928 IFX_ERROR("Enqueue to a DISABLING EP!!!\n");
932 #ifdef __DYN_SOF_INTR__
933 ifxhcd
->dyn_sof_count
= DYN_SOF_COUNT_DEF
;
935 //enable_sof(ifxhcd);
939 gintsts
.b
.sofintr
= 1;
940 ifxusb_mreg(&ifxhcd
->core_if
.core_global_regs
->gintmsk
, 0,gintsts
.d32
);
943 if(epqh
->phase
==EPQH_IDLE
|| epqh
->phase
==EPQH_STDBY
)
945 epqh
->phase
=EPQH_READY
;
946 #ifdef __EPQD_DESTROY_TIMEOUT__
947 del_timer(&epqh
->destroy_timer
);
955 \brief Aborts/cancels a USB transfer request. Always returns 0 to indicate
958 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
959 int ifxhcd_urb_dequeue(struct usb_hcd
*_syshcd
, struct urb
*_urb
)
961 int ifxhcd_urb_dequeue(struct usb_hcd
*_syshcd
, struct urb
*_urb
, int status
)
964 ifxhcd_hcd_t
*ifxhcd
;
965 struct usb_host_endpoint
*sysep
;
969 IFX_DEBUGPL(DBG_HCD
, "IFXUSB HCD URB Dequeue\n");
970 #if !defined(__EN_ISOC__)
971 if(usb_pipetype(_urb
->pipe
) == PIPE_ISOCHRONOUS
)
975 ifxhcd
= syshcd_to_ifxhcd(_syshcd
);
977 urbd
= (ifxhcd_urbd_t
*) _urb
->hcpriv
;
980 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
981 _urb
->status
=-ETIMEDOUT
;
982 usb_hcd_giveback_urb(_syshcd
, _urb
);
984 // usb_hcd_giveback_urb(_syshcd, _urb,-ETIMEDOUT);
985 usb_hcd_giveback_urb(_syshcd
, _urb
,status
);
990 sysep
= ifxhcd_urb_to_endpoint(_urb
);
993 LOCK_EPQH_LIST_ALL(ifxhcd
);
994 epqh
= sysep_to_epqh(ifxhcd
,sysep
);
995 UNLOCK_EPQH_LIST_ALL(ifxhcd
);
997 IFX_ERROR("%s inconsistant epqh %p %p\n",__func__
,epqh
,urbd
->epqh
);
1000 epqh
= (ifxhcd_epqh_t
*) urbd
->epqh
;
1001 if(!ifxhcd
->flags
.b
.port_connect_status
|| !epqh
)
1003 urbd
->phase
=URBD_DEQUEUEING
;
1004 ifxhcd_complete_urb(ifxhcd
, urbd
, -ENODEV
);
1008 LOCK_URBD_LIST(epqh
);
1009 if( urbd
->phase
==URBD_IDLE
1010 || urbd
->phase
==URBD_ACTIVE
1011 // || urbd->phase==URBD_STARTING
1014 urbd
->phase
=URBD_DEQUEUEING
;
1015 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
1016 ifxhcd_complete_urb(ifxhcd
, urbd
, -ETIMEDOUT
);
1018 ifxhcd_complete_urb(ifxhcd
, urbd
, status
);
1021 else if( urbd
->phase
==URBD_STARTED
1022 || urbd
->phase
==URBD_STARTING
1023 // || urbd->phase==URBD_ACTIVE
1026 if(ifxhcd_hc_halt(&ifxhcd
->core_if
, epqh
->hc
, HC_XFER_URB_DEQUEUE
))
1028 urbd
->phase
=URBD_DEQUEUEING
;
1029 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
1030 ifxhcd_complete_urb(ifxhcd
, urbd
, -ETIMEDOUT
);
1032 ifxhcd_complete_urb(ifxhcd
, urbd
, status
);
1034 ifxhcd_epqh_idle(epqh
);
1037 UNLOCK_URBD_LIST(epqh
);
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.
1048 void ifxhcd_endpoint_disable( struct usb_hcd
*_syshcd
,
1049 struct usb_host_endpoint
*_sysep
)
1051 ifxhcd_hcd_t
*ifxhcd
;
1052 ifxhcd_epqh_t
*epqh
;
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
));
1058 ifxhcd
= syshcd_to_ifxhcd(_syshcd
);
1060 LOCK_EPQH_LIST_ALL(ifxhcd
);
1061 epqh
= sysep_to_epqh(ifxhcd
,_sysep
);
1062 UNLOCK_EPQH_LIST_ALL(ifxhcd
);
1070 if (epqh
->sysep
!=_sysep
)
1072 IFX_ERROR("%s inconsistant sysep %p %p %p\n",__func__
,epqh
,epqh
->sysep
,_sysep
);
1076 epqh
->phase
=EPQH_DISABLING
;
1077 kill_all_urbs_in_epqh(ifxhcd
, epqh
, -ETIMEDOUT
);
1079 uint32_t count
=0x80000;
1080 for(;!list_empty(&epqh
->urbd_list
) && count
> 0; count
--) udelay(1);
1082 IFX_ERROR("%s: unable to clear urbd in epqh \n",__func__
);
1084 ifxhcd_epqh_free(epqh
);
1086 IFX_DEBUGPL(DBG_HCD
, "IFXUSB HCD EP DISABLE: done\n");
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
1095 This function is called by the USB core when an interrupt occurs
1097 irqreturn_t
ifxhcd_irq(struct usb_hcd
*_syshcd
)
1099 ifxhcd_hcd_t
*ifxhcd
= syshcd_to_ifxhcd (_syshcd
);
1102 //mask_and_ack_ifx_irq (ifxhcd->core_if.irq);
1103 retval
= ifxhcd_handle_intr(ifxhcd
);
1104 return IRQ_RETVAL(retval
);
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.
1115 int ifxhcd_hub_status_data(struct usb_hcd
*_syshcd
, char *_buf
)
1117 ifxhcd_hcd_t
*ifxhcd
= syshcd_to_ifxhcd (_syshcd
);
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;
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
);
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
);
1154 return (_buf
[0] != 0);
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__
1163 \brief Handles hub class-specific requests.
1165 int ifxhcd_hub_control( struct usb_hcd
*_syshcd
,
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};
1178 uint32_t port_status
;
1182 case ClearHubFeature
:
1183 IFX_DEBUGPL (DBG_HCD
, "IFXUSB HCD HUB CONTROL - "
1184 "ClearHubFeature 0x%x\n", _wValue
);
1187 case C_HUB_LOCAL_POWER
:
1188 case C_HUB_OVER_CURRENT
:
1189 /* Nothing required here */
1193 IFX_ERROR ("IFXUSB HCD - "
1194 "ClearHubFeature request %xh unknown\n", _wValue
);
1197 case ClearPortFeature
:
1198 if (!_wIndex
|| _wIndex
> 1)
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
);
1208 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
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
);
1215 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
1216 /* Clear Resume bit */
1219 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
1221 case USB_PORT_FEAT_POWER
:
1222 IFX_DEBUGPL (DBG_HCD
, "IFXUSB HCD HUB CONTROL - "
1223 "ClearPortFeature USB_PORT_FEAT_POWER\n");
1225 ifxusb_vbus_off(core_if
);
1227 ifxusb_vbus_off(core_if
);
1229 hprt0
.d32
= ifxusb_read_hprt0 (core_if
);
1231 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
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 */
1238 case USB_PORT_FEAT_C_CONNECTION
:
1239 /* Clears drivers internal connect status change
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;
1245 case USB_PORT_FEAT_C_RESET
:
1246 /* Clears the driver's internal Port Reset Change
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;
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;
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;
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;
1274 IFX_ERROR ("IFXUSB HCD - "
1275 "ClearPortFeature request %xh "
1276 "unknown or unsupported\n", _wValue
);
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;
1290 desc
->u
.hs
.DeviceRemovable
[0] = 0;
1291 desc
->u
.hs
.DeviceRemovable
[1] = 1;
1292 /*desc->bitmap[0] = 0;
1293 desc->bitmap[1] = 0xff;*/
1296 IFX_DEBUGPL (DBG_HCD
, "IFXUSB HCD HUB CONTROL - "
1298 memset (_buf
, 0, 4);
1301 IFX_DEBUGPL (DBG_HCD
, "IFXUSB HCD HUB CONTROL - "
1303 if (!_wIndex
|| _wIndex
> 1)
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
)
1316 IFX_ERROR("Device Not Supported\n");
1317 port_status
|= (1 << USB_PORT_FEAT_C_OVER_CURRENT
);
1319 if (!ifxhcd
->flags
.b
.port_connect_status
)
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.
1328 *((u32
*) _buf
) = cpu_to_le32(port_status
);
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
);
1338 ifxhcd
->disconnecting
=0;
1339 port_status
|= (1 << USB_PORT_FEAT_ENABLE
);
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
);
1346 port_status
|= (1 << USB_PORT_FEAT_RESET
);
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
);
1359 IFX_DEBUGPL (DBG_HCD
, "IFXUSB HCD HUB CONTROL - "
1361 /* No HUB features supported */
1363 case SetPortFeature
:
1364 if (_wValue
!= USB_PORT_FEAT_TEST
&& (!_wIndex
|| _wIndex
> 1))
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
1373 if (!ifxhcd
->flags
.b
.port_connect_status
)
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 */
1386 pcgcctl_data_t pcgcctl
= {.d32
=0};
1387 pcgcctl
.b
.stoppclk
= 1;
1388 ifxusb_wreg(core_if
->pcgcctl
, pcgcctl
.d32
);
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
);
1397 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
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
);
1404 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
1405 /* Clear reset bit in 10ms (FS/LS) or 50ms (HS) */
1408 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
1410 #ifdef __WITH_HS_ELECT_TST__
1411 case USB_PORT_FEAT_TEST
:
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
);
1421 hprt0
.d32
= ifxusb_read_hprt0 (core_if
);
1422 hprt0
.b
.prttstctl
= t
;
1423 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
1425 else if (t
== 6) /* HS_HOST_PORT_SUSPEND_RESUME */
1427 /* Save current interrupt mask */
1428 gintmsk
.d32
= ifxusb_rreg(&core_if
->core_global_regs
->gintmsk
);
1430 /* Disable all interrupts while we muck with
1431 * the hardware directly
1433 ifxusb_wreg(&core_if
->core_global_regs
->gintmsk
, 0);
1435 /* 15 second delay per the test spec */
1438 /* Drive suspend on the root port */
1439 hprt0
.d32
= ifxusb_read_hprt0 (core_if
);
1440 hprt0
.b
.prtsusp
= 1;
1442 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
1444 /* 15 second delay per the test spec */
1447 /* Drive resume on the root port */
1448 hprt0
.d32
= ifxusb_read_hprt0 (core_if
);
1449 hprt0
.b
.prtsusp
= 0;
1451 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
1454 /* Clear the resume bit */
1456 ifxusb_wreg(core_if
->hprt0
, hprt0
.d32
);
1458 /* Restore interrupts */
1459 ifxusb_wreg(&core_if
->core_global_regs
->gintmsk
, gintmsk
.d32
);
1461 else if (t
== 7) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR setup */
1463 /* Save current interrupt mask */
1464 gintmsk
.d32
= ifxusb_rreg(&core_if
->core_global_regs
->gintmsk
);
1466 /* Disable all interrupts while we muck with
1467 * the hardware directly
1469 ifxusb_wreg(&core_if
->core_global_regs
->gintmsk
, 0);
1471 /* 15 second delay per the test spec */
1474 /* Send the Setup packet */
1477 /* 15 second delay so nothing else happens for awhile */
1480 /* Restore interrupts */
1481 ifxusb_wreg(&core_if
->core_global_regs
->gintmsk
, gintmsk
.d32
);
1484 else if (t
== 8) /* SINGLE_STEP_GET_DEVICE_DESCRIPTOR execute */
1486 /* Save current interrupt mask */
1487 gintmsk
.d32
= ifxusb_rreg(&core_if
->core_global_regs
->gintmsk
);
1489 /* Disable all interrupts while we muck with
1490 * the hardware directly
1492 ifxusb_wreg(&core_if
->core_global_regs
->gintmsk
, 0);
1494 /* Send the Setup packet */
1497 /* 15 second delay so nothing else happens for awhile */
1500 /* Send the In and Ack packets */
1503 /* 15 second delay so nothing else happens for awhile */
1506 /* Restore interrupts */
1507 ifxusb_wreg(&core_if
->core_global_regs
->gintmsk
, gintmsk
.d32
);
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");
1519 IFX_ERROR ("IFXUSB HCD - "
1520 "SetPortFeature request %xh "
1521 "unknown or unsupported\n", _wValue
);
1527 IFX_WARN ("IFXUSB HCD - "
1528 "Unknown hub control request type or invalid typeReq: %xh wIndex: %xh wValue: %xh\n",
1529 _typeReq
, _wIndex
, _wValue
);
1538 \brief This function trigger a data transfer for a host channel and
1539 starts the transfer.
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.
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
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.
1557 void ifxhcd_hc_start(ifxhcd_hcd_t
*_ifxhcd
, ifxhcd_hc_t
*_ifxhc
)
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
];
1567 if(_ifxhc
->epqh
->urbd
->phase
==URBD_DEQUEUEING
)
1570 hprt0
.d32
= ifxusb_read_hprt0(core_if
);
1572 if(_ifxhcd
->pkt_remaining
==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__
);
1587 if (hprt0
.b
.prtspd
== IFXUSB_HPRT0_PRTSPD_HIGH_SPEED
)
1591 if(max_hc_pkt_count
> _ifxhcd
->pkt_remaining
)
1592 max_hc_pkt_count
= _ifxhcd
->pkt_remaining
;
1594 else if(_ifxhc
->ep_type
== IFXUSB_EP_TYPE_BULK
)
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;
1605 if(max_hc_pkt_count
> _ifxhcd
->pkt_remaining
)
1606 max_hc_pkt_count
= _ifxhcd
->pkt_remaining
;
1609 else if (hprt0
.b
.prtspd
== IFXUSB_HPRT0_PRTSPD_LOW_SPEED
)
1611 if(max_hc_pkt_count
> _ifxhcd
->pkt_remaining
)
1612 max_hc_pkt_count
= _ifxhcd
->pkt_remaining
;
1616 if(max_hc_pkt_count
> _ifxhcd
->pkt_remaining
)
1617 max_hc_pkt_count
= _ifxhcd
->pkt_remaining
;
1620 if(max_hc_pkt_count
==0)
1623 if(max_hc_pkt_count
* _ifxhc
->mps
< max_hc_xfer_size
)
1624 max_hc_xfer_size
= max_hc_pkt_count
* _ifxhc
->mps
;
1626 _ifxhc
->epqh
->urbd
->phase
=URBD_STARTING
;
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;
1635 if (_ifxhc
->split
> 0)
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;
1645 else if(_ifxhc
->is_in
)
1647 _ifxhc
->short_rw
= 0;
1648 if (_ifxhc
->xfer_len
> 0)
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
;
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
;
1660 else //non-split out
1662 if (_ifxhc
->xfer_len
== 0)
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__
,
1667 _ifxhc
->epqh
->urbd
->xfer_len
);
1668 _ifxhc
->start_pkt_count
= 1;
1672 if (_ifxhc
->xfer_len
> max_hc_xfer_size
)
1674 _ifxhc
->start_pkt_count
= (max_hc_xfer_size
/ _ifxhc
->mps
);
1675 _ifxhc
->xfer_len
= _ifxhc
->start_pkt_count
* _ifxhc
->mps
;
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;
1686 if (hprt0
.b
.prtspd
== IFXUSB_HPRT0_PRTSPD_HIGH_SPEED
)
1690 if( _ifxhcd
->pkt_remaining
> _ifxhc
->start_pkt_count
)
1691 _ifxhcd
->pkt_remaining
-= _ifxhc
->start_pkt_count
;
1693 _ifxhcd
->pkt_remaining
= 0;
1695 else if(_ifxhc
->ep_type
== IFXUSB_EP_TYPE_BULK
)
1697 if( _ifxhcd
->pkt_remaining
*8 > _ifxhc
->start_pkt_count
)
1698 _ifxhcd
->pkt_remaining
-= (_ifxhc
->start_pkt_count
*8);
1700 _ifxhcd
->pkt_remaining
= 0;
1704 if( _ifxhcd
->pkt_remaining
> _ifxhc
->start_pkt_count
)
1705 _ifxhcd
->pkt_remaining
-= _ifxhc
->start_pkt_count
;
1707 _ifxhcd
->pkt_remaining
= 0;
1710 else if (hprt0
.b
.prtspd
== IFXUSB_HPRT0_PRTSPD_LOW_SPEED
)
1712 if( _ifxhcd
->pkt_remaining
> _ifxhc
->start_pkt_count
)
1713 _ifxhcd
->pkt_remaining
-= _ifxhc
->start_pkt_count
;
1715 _ifxhcd
->pkt_remaining
= 0;
1719 if( _ifxhcd
->pkt_remaining
> _ifxhc
->start_pkt_count
)
1720 _ifxhcd
->pkt_remaining
-= _ifxhc
->start_pkt_count
;
1722 _ifxhcd
->pkt_remaining
= 0;
1726 if (_ifxhc
->ep_type
== IFXUSB_EP_TYPE_ISOC
)
1728 /* Set up the initial PID for the transfer. */
1730 _ifxhc
->data_pid_start
= IFXUSB_HC_PID_DATA0
;
1732 if (_ifxhc
->speed
== IFXUSB_EP_SPEED_HIGH
)
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
;
1741 _ifxhc
->data_pid_start
= IFXUSB_HC_PID_DATA2
;
1745 if (_ifxhc
->multi_count
== 1)
1746 _ifxhc
->data_pid_start
= IFXUSB_HC_PID_DATA0
;
1748 _ifxhc
->data_pid_start
= IFXUSB_HC_PID_MDATA
;
1752 _ifxhc
->data_pid_start
= IFXUSB_HC_PID_DATA0
;
1757 IFX_DEBUGPL(DBG_HCDV
, "%s: Channel %d\n", __func__
, _ifxhc
->hc_num
);
1759 hctsiz_data_t hctsiz
= { .d32
=0 };
1761 hctsiz
.b
.dopng
= _ifxhc
->epqh
->do_ping
;
1762 _ifxhc
->epqh
->do_ping
=0;
1764 if(_ifxhc
->is_in
|| _ifxhc
->speed
!= IFXUSB_EP_SPEED_HIGH
|| _ifxhc
->xfer_len
==0)
1766 if(_ifxhc
->ep_type
== IFXUSB_EP_TYPE_INTR
|| _ifxhc
->ep_type
== IFXUSB_EP_TYPE_ISOC
)
1768 if(_ifxhc
->ep_type
== IFXUSB_EP_TYPE_CTRL
&& _ifxhc
->control_phase
!= IFXHCD_CONTROL_DATA
)
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
);
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
);
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
)));
1783 /* Start the split */
1784 if (_ifxhc
->split
>0)
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;
1792 hcsplt
.b
.compsplt
= 0;
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
;
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
);
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;
1810 if (_ifxhc
->ep_type
== IFXUSB_EP_TYPE_INTR
|| _ifxhc
->ep_type
== IFXUSB_EP_TYPE_ISOC
)
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;
1818 _ifxhc
->start_hcchar_val
= hcchar
.d32
;
1820 IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n",
1821 __func__
, _ifxhc
->hc_num
, hcchar
.d32
);
1824 /* Set host channel enable after all other setup is complete. */
1827 hcchar
.b
.epdir
= _ifxhc
->is_in
;
1828 _ifxhc
->hcchar
=hcchar
.d32
;
1831 IFX_DEBUGPL(DBG_HCDV
, " HCCHART: 0x%08x\n", _ifxhc
->hcchar
);
1833 _ifxhc
->phase
=HC_STARTING
;
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.
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.
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.
1850 int ifxhcd_hc_halt(ifxusb_core_if_t
*_core_if
,
1851 ifxhcd_hc_t
*_ifxhc
,
1852 ifxhcd_halt_status_e _halt_status
)
1854 hcchar_data_t hcchar
;
1855 ifxusb_hc_regs_t
*hc_regs
;
1856 hc_regs
= _core_if
->hc_regs
[_ifxhc
->hc_num
];
1858 WARN_ON(_halt_status
== HC_XFER_NO_HALT_STATUS
);
1862 hprt0
.d32
= ifxusb_rreg(_core_if
->hprt0
);
1863 if(hprt0
.b
.prtena
== 0)
1867 if (_halt_status
== HC_XFER_URB_DEQUEUE
||
1868 _halt_status
== HC_XFER_AHB_ERR
)
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.
1876 hcint_data_t hcintmsk
;
1878 hcintmsk
.b
.chhltd
= 1;
1879 ifxusb_wreg(&hc_regs
->hcintmsk
, hcintmsk
.d32
);
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.
1886 ifxusb_wreg(&hc_regs
->hcint
, ~hcintmsk
.d32
);
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
1893 _ifxhc
->halt_status
= _halt_status
;
1896 hcchar
.d32
= ifxusb_rreg(&hc_regs
->hcchar
);
1897 if (hcchar
.b
.chen
== 0)
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
1910 _ifxhc
->phase
=HC_IDLE
;
1914 if (_ifxhc
->phase
==HC_STOPPING
)
1917 * A halt has already been issued for this channel. This might
1918 * happen when a transfer is aborted by a higher level in
1922 IFX_PRINT("*** %s: Channel %d, double halt a channel***\n",
1923 __func__
, _ifxhc
->hc_num
);
1927 hcchar
.d32
= ifxusb_rreg(&hc_regs
->hcchar
);
1931 ifxusb_wreg(&hc_regs
->hcchar
, hcchar
.d32
);
1933 _ifxhc
->halt_status
= _halt_status
;
1934 _ifxhc
->phase
=HC_STOPPING
;
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
);
1944 \brief Clears a host channel.
1946 void ifxhcd_hc_cleanup(ifxusb_core_if_t
*_core_if
, ifxhcd_hc_t
*_ifxhc
)
1948 ifxusb_hc_regs_t
*hc_regs
;
1950 _ifxhc
->phase
=HC_IDLE
;
1954 * Clear channel interrupt enables and any unhandled channel interrupt
1957 hc_regs
= _core_if
->hc_regs
[_ifxhc
->hc_num
];
1958 ifxusb_wreg(&hc_regs
->hcintmsk
, 0);
1959 ifxusb_wreg(&hc_regs
->hcint
, 0xFFFFFFFF);
1963 hcchar_data_t hcchar
;
1964 hcchar
.d32
= ifxusb_rreg(&hc_regs
->hcchar
);
1966 IFX_WARN("%s: chdis set, channel %d, hcchar 0x%08x\n", __func__
, _ifxhc
->hc_num
, hcchar
.d32
);
1976 static void dump_urb_info(struct urb
*_urb
, char* _fn_name
)
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",
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;
1993 IFX_PRINT(" Speed: %s\n",
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;
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
)
2014 for (i
= 0; i
< _urb
->number_of_packets
; i
++)
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
);
2025 static void dump_channel_info(ifxhcd_hcd_t
*_ifxhcd
, ifxhcd_epqh_t
*_epqh
)
2027 if (_epqh
->hc
!= NULL
)
2029 ifxhcd_hc_t
*hc
= _epqh
->hc
;
2030 struct list_head
*item
;
2031 ifxhcd_epqh_t
*epqh_item
;
2033 ifxusb_hc_regs_t
*hc_regs
;
2035 hcchar_data_t hcchar
;
2036 hcsplt_data_t hcsplt
;
2037 hctsiz_data_t hctsiz
;
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
);
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
)
2061 epqh_item
= list_entry(item
, ifxhcd_epqh_t
, ql
);
2062 IFX_PRINT(" %p\n", epqh_item
);
2064 IFX_PRINT(" INTR :\n");
2065 list_for_each(item
, &_ifxhcd
->epqh_list_intr
)
2067 epqh_item
= list_entry(item
, ifxhcd_epqh_t
, ql
);
2068 IFX_PRINT(" %p\n", epqh_item
);
2071 IFX_PRINT(" ISOC:\n");
2072 list_for_each(item
, &_ifxhcd
->epqh_list_isoc
)
2074 epqh_item
= list_entry(item
, ifxhcd_epqh_t
, ql
);
2075 IFX_PRINT(" %p\n", epqh_item
);
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
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.
2095 #ifdef __ENABLE_DUMP__
2096 void ifxhcd_dump_state(ifxhcd_hcd_t
*_ifxhcd
)
2100 num_channels
= _ifxhcd
->core_if
.params
.host_channels
;
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
);
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
);
2130 IFX_PRINT(" do_ping: %d\n" , hc
->epqh
->do_ping
);
2132 IFX_PRINT(" start_pkt_count: %d\n" , hc
->start_pkt_count
);
2134 IFX_PRINT("************************************************************\n");
2137 #endif //__ENABLE_DUMP__