[lantiq] add ltq-hcd
[openwrt.git] / package / platform / lantiq / ltq-hcd / src / ifxhcd.h
diff --git a/package/platform/lantiq/ltq-hcd/src/ifxhcd.h b/package/platform/lantiq/ltq-hcd/src/ifxhcd.h
new file mode 100644 (file)
index 0000000..243c5f5
--- /dev/null
@@ -0,0 +1,758 @@
+/*****************************************************************************
+ **   FILE NAME       : ifxhcd.h
+ **   PROJECT         : IFX USB sub-system V3
+ **   MODULES         : IFX USB sub-system Host and Device driver
+ **   SRC VERSION     : 3.2
+ **   DATE            : 1/Jan/2011
+ **   AUTHOR          : Chen, Howard
+ **   DESCRIPTION     : This file contains the structures, constants, and interfaces for
+ **                     the Host Contoller Driver (HCD).
+ **
+ **                     The Host Controller Driver (HCD) is responsible for translating requests
+ **                     from the USB Driver into the appropriate actions on the IFXUSB controller.
+ **                     It isolates the USBD from the specifics of the controller by providing an
+ **                     API to the USBD.
+ **   FUNCTIONS       :
+ **   COMPILER        : gcc
+ **   REFERENCE       : Synopsys DWC-OTG Driver 2.7
+ **   COPYRIGHT       :  Copyright (c) 2010
+ **                      LANTIQ DEUTSCHLAND GMBH,
+ **                      Am Campeon 3, 85579 Neubiberg, Germany
+ **
+ **    This program is free software; you can redistribute it and/or modify
+ **    it under the terms of the GNU General Public License as published by
+ **    the Free Software Foundation; either version 2 of the License, or
+ **    (at your option) any later version.
+ **
+ **  Version Control Section  **
+ **   $Author$
+ **   $Date$
+ **   $Revisions$
+ **   $Log$       Revision history
+ *****************************************************************************/
+
+/*
+ * This file contains code fragments from Synopsys HS OTG Linux Software Driver.
+ * For this code the following notice is applicable:
+ *
+ * ==========================================================================
+ *
+ * Synopsys HS OTG Linux Software Driver and documentation (hereinafter,
+ * "Software") is an Unsupported proprietary work of Synopsys, Inc. unless
+ * otherwise expressly agreed to in writing between Synopsys and you.
+ *
+ * The Software IS NOT an item of Licensed Software or Licensed Product under
+ * any End User Software License Agreement or Agreement for Licensed Product
+ * with Synopsys or any supplement thereto. You are permitted to use and
+ * redistribute this Software in source and binary forms, with or without
+ * modification, provided that redistributions of source code must retain this
+ * notice. You may not view, use, disclose, copy or distribute this file or
+ * any information contained herein except pursuant to this license grant from
+ * Synopsys. If you do not agree with this notice, including the disclaimer
+ * below, then you are not authorized to use the Software.
+ *
+ * THIS SOFTWARE IS BEING DISTRIBUTED BY SYNOPSYS SOLELY ON AN "AS IS" BASIS
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE HEREBY DISCLAIMED. IN NO EVENT SHALL SYNOPSYS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ * ========================================================================== */
+
+/*!
+  \defgroup IFXUSB_HCD HCD Interface
+  \ingroup IFXUSB_DRIVER_V3
+  \brief  The Host Controller Driver (HCD) is responsible for translating requests
+ from the USB Driver into the appropriate actions on the IFXUSB controller.
+ It isolates the USBD from the specifics of the controller by providing an
+ API to the USBD.
+ */
+
+
+/*!
+  \file ifxhcd.h
+  \ingroup IFXUSB_DRIVER_V3
+  \brief This file contains the structures, constants, and interfaces for
+ the Host Contoller Driver (HCD).
+ */
+
+#if !defined(__IFXHCD_H__)
+#define __IFXHCD_H__
+
+
+#define __STRICT_ORDER__
+
+
+#include <linux/list.h>
+#include <linux/usb.h>
+
+#include <linux/usb/hcd.h>
+
+#include "ifxusb_cif.h"
+#include "ifxusb_plat.h"
+
+
+#undef __INNAKSTOP__
+#if !defined(__INNAKSTOP__) && defined(__INNAKSTOP_CTRL__)
+       #define __INNAKSTOP__ 1
+#endif
+#if !defined(__INNAKSTOP__) && defined(__INNAKSTOP_BULK__)
+       #define __INNAKSTOP__ 1
+#endif
+
+#undef __PINGSTOP__
+#if !defined(__PINGSTOP__) && defined(__PINGSTOP_CTRL__)
+       #define __PINGSTOP__ 1
+#endif
+#if !defined(__PINGSTOP__) && defined(__PINGSTOP_BULK__)
+       #define __PINGSTOP__ 1
+#endif
+
+#undef __NAKSTOP__
+#if defined(__INNAKSTOP__) || defined(__PINGSTOP__)
+       #define __NAKSTOP__ 1
+#endif
+
+
+/* Phases for control transfers.*/
+typedef enum ifxhcd_epqh_phase {
+       EPQH_IDLE=0,
+       EPQH_DISABLING,
+//     EPQH_COMPLETING,
+       EPQH_STDBY,
+       EPQH_READY,
+       EPQH_ACTIVE
+} ifxhcd_epqh_phase_e;
+
+/* Phases for control transfers.*/
+typedef enum ifxhcd_urbd_phase {
+       URBD_IDLE=0,
+       URBD_ACTIVE,
+       URBD_STARTING,
+       URBD_STARTED,
+       URBD_FINISHING,    //URB_Complete already scheduled
+       URBD_COMPLETING,   //To URB_Complete, it's normal finish
+       URBD_DEQUEUEING,   //To URB_Complete, it's abnormal finish
+} ifxhcd_urbd_phase_e;
+
+/* Phases for control transfers.*/
+typedef enum ifxhcd_hc_phase {
+       HC_IDLE=0,
+       HC_ASSIGNED,
+       HC_WAITING,
+       HC_STARTING,
+       HC_STARTED,
+       HC_STOPPING,
+       HC_STOPPED,
+} ifxhcd_hc_phase_e;
+
+/*!
+  \addtogroup IFXUSB_HCD
+ */
+/*@{*/
+
+/*! \typedef  ifxhcd_control_phase_e
+       \brief Phases for control transfers.
+*/
+
+typedef enum ifxhcd_control_phase {
+       IFXHCD_CONTROL_SETUP,
+       IFXHCD_CONTROL_DATA,
+       IFXHCD_CONTROL_STATUS
+} ifxhcd_control_phase_e;
+
+/*! \typedef  ifxhcd_halt_status_e
+       \brief Reasons for halting a host channel.
+*/
+typedef enum ifxhcd_halt_status
+{
+       HC_XFER_NO_HALT_STATUS,         // Initial
+       HC_XFER_COMPLETE,               // Xact complete without error, upward
+       HC_XFER_URB_COMPLETE,           // Xfer complete without error, short upward
+       HC_XFER_STALL,                  // HC stopped abnormally, upward/downward
+       HC_XFER_XACT_ERR,               // HC stopped abnormally, upward
+       HC_XFER_FRAME_OVERRUN,          // HC stopped abnormally, upward
+       HC_XFER_BABBLE_ERR,             // HC stopped abnormally, upward
+       HC_XFER_AHB_ERR,                // HC stopped abnormally, upward
+       HC_XFER_DATA_TOGGLE_ERR,
+       HC_XFER_URB_DEQUEUE,            // HC stopper manually, downward
+       HC_XFER_NO_URB,                 // HC stopper manually, downward
+       HC_XFER_NO_EPQH,                // HC stopper manually, downward
+       #ifdef __NAKSTOP__
+               HC_XFER_NAK,                // HC stopped by nak monitor, downward
+       #endif
+       #if defined(__INTRNAKRETRY__) || defined(__INTRINCRETRY__)
+               HC_XFER_INTR_NAK_RETRY,     // HC stopped by nak monitor, downward
+       #endif
+} ifxhcd_halt_status_e;
+
+struct ifxhcd_urbd;
+struct ifxhcd_hc ;
+struct ifxhcd_epqh ;
+struct ifxhcd_hcd;
+
+/*! typedef ifxhcd_urbd_t
+ \brief A URB Descriptor (URBD) holds the state of a bulk, control,
+  interrupt, or isochronous transfer. A single URBD is created for each URB
+  (of one of these types) submitted to the HCD. The transfer associated with
+  a URBD may require one or multiple transactions.
+
+  A URBD is linked to a EP Queue Head, which is entered in either the
+  isoc, intr or non-periodic schedule for execution. When a URBD is chosen for
+  execution, some or all of its transactions may be executed. After
+  execution, the state of the URBD is updated. The URBD may be retired if all
+  its transactions are complete or if an error occurred. Otherwise, it
+  remains in the schedule so more transactions can be executed later.
+ */
+typedef struct ifxhcd_urbd {
+       ifxhcd_urbd_phase_e       phase;
+       struct list_head          ql;               // Hook for EPQH->urbd_list
+       struct urb               *urb;              /*!< URB for this transfer */
+                                                   //struct urb {
+                                                   //  struct list_head urb_list;
+                                                   //  struct list_head anchor_list;
+                                                   //  struct usb_anchor * anchor;
+                                                   //  struct usb_device * dev;
+                                                   //  struct usb_host_endpoint * ep;
+                                                   //  unsigned int pipe;
+                                                   //  int status;
+                                                   //  unsigned int transfer_flags;
+                                                   //  void * transfer_buffer;
+                                                   //  dma_addr_t transfer_dma;
+                                                   //  u32 transfer_buffer_length;
+                                                   //  u32 actual_length;
+                                                   //  unsigned char * setup_packet;
+                                                   //  dma_addr_t setup_dma;
+                                                   //  int start_frame;
+                                                   //  int number_of_packets;
+                                                   //  int interval;
+                                                   //  int error_count;
+                                                   //  void * context;
+                                                   //  usb_complete_t complete;
+                                                   //  struct usb_iso_packet_descriptor iso_frame_desc[0];
+                                                   //};
+                                                   //urb_list         For use by current owner of the URB.
+                                                   //anchor_list      membership in the list of an anchor
+                                                   //anchor           to anchor URBs to a common mooring
+                                                   //dev              Identifies the USB device to perform the request.
+                                                   //ep               Points to the endpoint's data structure. Will
+                                                   //                 eventually replace pipe.
+                                                   //pipe             Holds endpoint number, direction, type, and more.
+                                                   //                 Create these values with the eight macros available; u
+                                                   //                 sb_{snd,rcv}TYPEpipe(dev,endpoint), where the TYPE is
+                                                   //                  "ctrl", "bulk", "int" or "iso". For example
+                                                   //                 usb_sndbulkpipe or usb_rcvintpipe. Endpoint numbers
+                                                   //                 range from zero to fifteen. Note that "in" endpoint two
+                                                   //                 is a different endpoint (and pipe) from "out" endpoint
+                                                   //                 two. The current configuration controls the existence,
+                                                   //                 type, and maximum packet size of any given endpoint.
+                                                   //status           This is read in non-iso completion functions to get
+                                                   //                 the status of the particular request. ISO requests
+                                                   //                 only use it to tell whether the URB was unlinked;
+                                                   //                 detailed status for each frame is in the fields of
+                                                   //                 the iso_frame-desc.
+                                                   //transfer_flags   A variety of flags may be used to affect how URB
+                                                   //                 submission, unlinking, or operation are handled.
+                                                   //                 Different kinds of URB can use different flags.
+                                                   //                      URB_SHORT_NOT_OK
+                                                   //                      URB_ISO_ASAP
+                                                   //                      URB_NO_TRANSFER_DMA_MAP
+                                                   //                      URB_NO_SETUP_DMA_MAP
+                                                   //                      URB_NO_FSBR
+                                                   //                      URB_ZERO_PACKET
+                                                   //                      URB_NO_INTERRUPT
+                                                   //transfer_buffer  This identifies the buffer to (or from) which the I/O
+                                                   //                 request will be performed (unless URB_NO_TRANSFER_DMA_MAP
+                                                   //                 is set). This buffer must be suitable for DMA; allocate it
+                                                   //                 with kmalloc or equivalent. For transfers to "in"
+                                                   //                 endpoints, contents of this buffer will be modified. This
+                                                   //                 buffer is used for the data stage of control transfers.
+                                                   //transfer_dma     When transfer_flags includes URB_NO_TRANSFER_DMA_MAP, the
+                                                   //                 device driver is saying that it provided this DMA address,
+                                                   //                 which the host controller driver should use in preference
+                                                   //                 to the transfer_buffer.
+                                                   //transfer_buffer_length How big is transfer_buffer. The transfer may be broken
+                                                   //                 up into chunks according to the current maximum packet size
+                                                   //                 for the endpoint, which is a function of the configuration
+                                                   //                 and is encoded in the pipe. When the length is zero, neither
+                                                   //                 transfer_buffer nor transfer_dma is used.
+                                                   //actual_length    This is read in non-iso completion functions, and it tells
+                                                   //                 how many bytes (out of transfer_buffer_length) were transferred.
+                                                   //                 It will normally be the same as requested, unless either an error
+                                                   //                 was reported or a short read was performed. The URB_SHORT_NOT_OK
+                                                   //                 transfer flag may be used to make such short reads be reported
+                                                   //                 as errors.
+                                                   //setup_packet     Only used for control transfers, this points to eight bytes of
+                                                   //                 setup data. Control transfers always start by sending this data
+                                                   //                 to the device. Then transfer_buffer is read or written, if needed.
+                                                   //setup_dma        For control transfers with URB_NO_SETUP_DMA_MAP set, the device
+                                                   //                 driver has provided this DMA address for the setup packet. The
+                                                   //                 host controller driver should use this in preference to setup_packet.
+                                                   //start_frame      Returns the initial frame for isochronous transfers.
+                                                   //number_of_packets Lists the number of ISO transfer buffers.
+                                                   //interval         Specifies the polling interval for interrupt or isochronous transfers.
+                                                   //                 The units are frames (milliseconds) for for full and low speed devices,
+                                                   //                 and microframes (1/8 millisecond) for highspeed ones.
+                                                   //error_count      Returns the number of ISO transfers that reported errors.
+                                                   //context          For use in completion functions. This normally points to request-specific
+                                                   //                 driver context.
+                                                   //complete         Completion handler. This URB is passed as the parameter to the completion
+                                                   //                 function. The completion function may then do what it likes with the URB,
+                                                   //                 including resubmitting or freeing it.
+                                                   //iso_frame_desc[0] Used to provide arrays of ISO transfer buffers and to collect the transfer
+                                                   //                 status for each buffer.
+
+       struct ifxhcd_epqh       *epqh;
+                                                // Actual data portion, not SETUP or STATUS in case of CTRL XFER
+                                                // DMA adjusted
+       uint8_t                  *setup_buff;       /*!< Pointer to the entire transfer buffer. (CPU accessable)*/
+       uint8_t                  *xfer_buff;        /*!< Pointer to the entire transfer buffer. (CPU accessable)*/
+       uint32_t                  xfer_len;         /*!< Total number of bytes to transfer in this xfer. */
+
+       #if   defined(__UNALIGNED_BUF_ADJ__)
+//             uint8_t using_aligned_setup;
+               uint8_t *aligned_setup;
+//             uint8_t using_aligned_buf;
+               uint8_t *aligned_buf;
+               unsigned aligned_buf_len : 19;
+       #endif
+       #if   defined(__UNALIGNED_BUF_ADJ__) || defined(__UNALIGNED_BUF_CHK__)
+               unsigned aligned_checked :  1;
+       #endif
+       unsigned     is_in           :1;
+       #ifndef __STRICT_ORDER__
+               struct tasklet_struct  complete_urb_sub;
+       #endif
+
+                                 // For ALL XFER
+       uint8_t                   error_count;    /*!< Holds the number of bus errors that have occurred for a transaction
+                                                      within this transfer.
+                                                  */
+                                 // For ISOC XFER only
+       #ifdef __EN_ISOC__
+               int                   isoc_frame_index; /*!< Index of the next frame descriptor for an isochronous transfer. A
+                                                            frame descriptor describes the buffer position and length of the
+                                                            data to be transferred in the next scheduled (micro)frame of an
+                                                            isochronous transfer. It also holds status for that transaction.
+                                                            The frame index starts at 0.
+                                                        */
+       #endif
+       int status;
+} ifxhcd_urbd_t;
+
+/*! typedef ifxhcd_epqh_t
+ \brief A EP Queue Head (EPQH) holds the static characteristics of an endpoint and
+ maintains a list of transfers (URBDs) for that endpoint. A EPQH structure may
+ be entered in either the isoc, intr or non-periodic schedule.
+ */
+
+typedef struct ifxhcd_epqh {
+       struct ifxhcd_hcd    *ifxhcd;
+       struct usb_host_endpoint *sysep;
+       uint8_t devno;
+
+       ifxhcd_epqh_phase_e  phase;
+       struct list_head     ql_all;
+       struct list_head     ql;                // Hook for EP Queues
+       struct list_head     urbd_list;         /*!< List of URBDs for this EPQH. */
+       #ifdef __STRICT_ORDER__
+               struct list_head     release_list;
+               struct tasklet_struct  complete_urb_sub;
+       #endif
+       struct ifxhcd_hc    *hc;                /*!< Host channel currently processing transfers for this EPQH. */
+       struct ifxhcd_urbd  *urbd;              /*!< URBD currently assigned to a host channel for this EPQH. */
+       uint8_t              ep_type;           /*!< Endpoint type. One of the following values:
+                                                    - IFXUSB_EP_TYPE_CTRL
+                                                    - IFXUSB_EP_TYPE_ISOC
+                                                    - IFXUSB_EP_TYPE_BULK
+                                                    - IFXUSB_EP_TYPE_INTR
+                                                */
+       uint16_t             mps;               /*!< wMaxPacketSize Field of Endpoint Descriptor. */
+       #ifdef __EPQD_DESTROY_TIMEOUT__
+               struct timer_list destroy_timer;
+       #endif
+
+       unsigned need_split     : 1 ;
+       unsigned do_ping        : 1 ; /*!< Set to 1 to indicate that a PING request should be issued on this
+                                         channel. If 0, process normally.
+                                     */
+       unsigned pause          : 1;
+       unsigned period_do      : 1;
+       uint16_t             interval;          /*!< Interval between transfers in (micro)frames. (for INTR)*/
+       uint16_t             period_counter;    /*!< Interval between transfers in (micro)frames. */
+
+       #ifdef __EN_ISOC__
+               struct tasklet_struct  tasklet_next_isoc;
+               uint8_t               isoc_now;
+               uint32_t              isoc_start_frame;
+                                 // For SPLITed ISOC XFER only
+               #ifdef __EN_ISOC_SPLIT__
+                       uint8_t           isoc_split_pos;   /*!< Position of the ISOC split on full/low speed */
+                       uint16_t          isoc_split_offset;/*!< Position of the ISOC split in the buffer for the current frame */
+               #endif
+       #endif
+       spinlock_t      urbd_list_lock;
+       int urbd_count;
+} ifxhcd_epqh_t;
+
+
+/*! typedef ifxhcd_hc_t
+ \brief Host channel descriptor. This structure represents the state of a single
+ host channel when acting in host mode. It contains the data items needed to
+ transfer packets to an endpoint via a host channel.
+ */
+typedef struct ifxhcd_hc
+{
+       struct ifxhcd_epqh *epqh        ; /*!< EP Queue Head for the transfer being processed by this channel. */
+       uint8_t  hc_num                 ; /*!< Host channel number used for register address lookup */
+       uint8_t *xfer_buff              ; /*!< Pointer to the entire transfer buffer. */
+       uint32_t xfer_count             ; /*!< Number of bytes transferred so far. The offset of the begin of the buf */
+       uint32_t xfer_len               ; /*!< Total number of bytes to transfer in this xfer. */
+       uint16_t start_pkt_count        ; /*!< Packet count at start of transfer. Used to calculate the actual xfer size*/
+       ifxhcd_halt_status_e halt_status; /*!< Reason for halting the host channel. */
+       ifxhcd_hc_phase_e  phase;
+
+       unsigned dev_addr       : 7; /*!< Device to access */
+       unsigned ep_num         : 4; /*!< EP to access */
+       unsigned is_in          : 1; /*!< EP direction. 0: OUT, 1: IN */
+       unsigned speed          : 2; /*!< EP speed. */
+       unsigned ep_type        : 2; /*!< Endpoint type. */
+       unsigned mps            :11; /*!< Max packet size in bytes */
+       unsigned data_pid_start : 2; /*!< PID for initial transaction. */
+       unsigned short_rw       : 1; /*!< When Tx, means termination needed.
+                                         When Rx, indicate Short Read  */
+       /* Split settings for the host channel */
+       unsigned split          : 2; /*!< Split: 0-Non Split, 1-SSPLIT, 2&3 CSPLIT */
+
+       unsigned sof_delay      :16;
+       unsigned erron          : 1;
+
+       #ifdef __NAKSTOP__
+               unsigned stop_on            : 1;
+//             unsigned wait_for_sof_quick : 1;
+       #endif
+
+       ifxhcd_control_phase_e    control_phase;  /*!< Current phase for control transfers (Setup, Data, or Status). */
+       uint32_t ssplit_out_xfer_count; /*!< How many bytes transferred during SSPLIT OUT */
+       #ifdef __DEBUG__
+               uint32_t          start_hcchar_val;
+       #endif
+       uint32_t hcchar;
+
+       /* Split settings for the host channel */
+       uint8_t hub_addr;          /*!< Address of high speed hub */
+       uint8_t port_addr;         /*!< Port of the low/full speed device */
+       #if defined(__EN_ISOC__) && defined(__EN_ISOC_SPLIT__)
+               uint8_t isoc_xact_pos;          /*!< Split transaction position */
+       #endif
+} ifxhcd_hc_t;
+
+
+/*! typedef ifxhcd_hcd_t
+ \brief This structure holds the state of the HCD, including the non-periodic and
+ periodic schedules.
+ */
+typedef struct ifxhcd_hcd
+{
+       struct device *dev;
+       struct hc_driver hc_driver;
+       ifxusb_core_if_t core_if;   /*!< Pointer to the core interface structure. */
+       struct usb_hcd *syshcd;
+
+       volatile union
+       {
+               uint32_t d32;
+               struct
+               {
+                       unsigned port_connect_status_change : 1;
+                       unsigned port_connect_status        : 1;
+                       unsigned port_reset_change          : 1;
+                       unsigned port_enable_change         : 1;
+                       unsigned port_suspend_change        : 1;
+                       unsigned port_over_current_change   : 1;
+                       unsigned reserved                   : 27;
+               } b;
+       } flags; /*!< Internal HCD Flags */
+
+       struct ifxhcd_hc ifxhc[MAX_EPS_CHANNELS];         /*!< Array of pointers to the host channel descriptors. Allows accessing
+                                                              a host channel descriptor given the host channel number. This is
+                                                              useful in interrupt handlers.
+                                                          */
+       uint8_t   *status_buf;                            /*!< Buffer to use for any data received during the status phase of a
+                                                              control transfer. Normally no data is transferred during the status
+                                                              phase. This buffer is used as a bit bucket.
+                                                          */
+               #define IFXHCD_STATUS_BUF_SIZE 64             /*!< buffer size of status phase in CTRL xfer */
+
+       struct list_head epqh_list_all;
+       struct list_head epqh_list_np;
+       struct list_head epqh_list_intr;
+       #ifdef __EN_ISOC__
+               struct list_head epqh_list_isoc;
+       #endif
+
+       uint32_t lastframe;
+
+       uint16_t pkt_remaining;
+       uint16_t pkt_remaining_reload;
+       uint16_t pkt_remaining_reload_hs;
+       uint16_t pkt_remaining_reload_fs;
+       uint16_t pkt_remaining_reload_ls;
+               #define PKT_REMAINING_RELOAD_HS  88
+               #define PKT_REMAINING_RELOAD_FS  10
+               #define PKT_REMAINING_RELOAD_LS  20
+       #ifdef __EN_ISOC__
+               uint8_t isoc_ep_count;
+       #endif
+
+       spinlock_t      epqh_list_lock;
+       spinlock_t      epqh_list_all_lock;
+
+       struct timer_list host_probe_timer;
+       struct timer_list autoprobe_timer;
+
+       unsigned        power_status;
+       int             probe_sec;
+       int             autoprobe_sec;
+       #ifdef __DYN_SOF_INTR__
+               uint32_t dyn_sof_count;
+               #define DYN_SOF_COUNT_DEF 40000
+       #endif
+       struct tasklet_struct  tasklet_select_eps;        /*!<  Tasket to do a reset */
+       struct tasklet_struct  tasklet_free_epqh_list ;        /*!<  Tasket to do a reset */
+       unsigned disconnecting     : 1 ;
+
+       uint8_t              pkt_count_limit_bo;
+       uint8_t              pkt_count_limit_bi;
+} ifxhcd_hcd_t;
+
+/* Gets the ifxhcd_hcd from a struct usb_hcd */
+static inline ifxhcd_hcd_t *syshcd_to_ifxhcd(struct usb_hcd *syshcd)
+{
+       return (ifxhcd_hcd_t *)(syshcd->hcd_priv[0]);
+}
+
+/* Gets the struct usb_hcd that contains a ifxhcd_hcd_t. */
+static inline struct usb_hcd *ifxhcd_to_syshcd(ifxhcd_hcd_t *ifxhcd)
+{
+       return (struct usb_hcd *)(ifxhcd->syshcd);
+}
+
+
+extern ifxhcd_epqh_t * sysep_to_epqh(ifxhcd_hcd_t *_ifxhcd, struct usb_host_endpoint *_sysep);
+
+/* HCD Create/Destroy Functions */
+       extern int  ifxhcd_init  (ifxhcd_hcd_t *_ifxhcd);
+       extern void ifxhcd_remove(ifxhcd_hcd_t *_ifxhcd);
+
+/*Linux HC Driver API Functions */
+
+extern int  ifxhcd_start(struct usb_hcd *hcd);
+extern void ifxhcd_stop (struct usb_hcd *hcd);
+extern int  ifxhcd_get_frame_number(struct usb_hcd *hcd);
+
+
+/*!
+   \brief This function does the setup for a data transfer for a host channel and
+  starts the transfer. May be called in either Slave mode or DMA mode. In
+  Slave mode, the caller must ensure that there is sufficient space in the
+  request queue and Tx Data FIFO.
+
+  For an OUT transfer in Slave mode, it loads a data packet into the
+  appropriate FIFO. If necessary, additional data packets will be loaded in
+  the Host ISR.
+
+  For an IN transfer in Slave mode, a data packet is requested. The data
+  packets are unloaded from the Rx FIFO in the Host ISR. If necessary,
+  additional data packets are requested in the Host ISR.
+
+  For a PING transfer in Slave mode, the Do Ping bit is set in the HCTSIZ
+  register along with a packet count of 1 and the channel is enabled. This
+  causes a single PING transaction to occur. Other fields in HCTSIZ are
+  simply set to 0 since no data transfer occurs in this case.
+
+  For a PING transfer in DMA mode, the HCTSIZ register is initialized with
+  all the information required to perform the subsequent data transfer. In
+  addition, the Do Ping bit is set in the HCTSIZ register. In this case, the
+  controller performs the entire PING protocol, then starts the data
+  transfer.
+
+  @param _ifxhc Information needed to initialize the host channel. The xfer_len
+  value may be reduced to accommodate the max widths of the XferSize and
+  PktCnt fields in the HCTSIZn register. The multi_count value may be changed
+  to reflect the final xfer_len value.
+ */
+extern void ifxhcd_hc_start(ifxhcd_hcd_t *_ifxhcd, ifxhcd_hc_t *_ifxhc);
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep, struct urb *_urb, gfp_t mem_flags);
+extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb);
+#else
+extern int ifxhcd_urb_enqueue(struct usb_hcd *_syshcd, struct urb *_urb, gfp_t mem_flags);
+extern int ifxhcd_urb_dequeue(struct usb_hcd *_syshcd, struct urb *_urb, int status);
+#endif
+extern irqreturn_t ifxhcd_irq(struct usb_hcd *_syshcd);
+
+extern void ifxhcd_endpoint_disable(struct usb_hcd *_syshcd, struct usb_host_endpoint *_sysep);
+
+extern int ifxhcd_hub_status_data(struct usb_hcd *_syshcd, char *_buf);
+extern int ifxhcd_hub_control( struct usb_hcd *_syshcd,
+                               u16             _typeReq,
+                               u16             _wValue,
+                               u16             _wIndex,
+                               char           *_buf,
+                               u16             _wLength);
+
+/*@}*/
+
+/*! \brief Transaction Execution Functions */
+/*@{*/
+extern void                      ifxhcd_complete_urb       (ifxhcd_hcd_t *_ifxhcd, ifxhcd_urbd_t *_urbd,  int _status);
+
+/*!
+   \brief Clears the transfer state for a host channel. This function is normally
+  called after a transfer is done and the host channel is being released.
+ */
+extern void ifxhcd_hc_cleanup(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc);
+
+/*!
+   \brief Attempts to halt a host channel. This function should only be called in
+  Slave mode or to abort a transfer in either Slave mode or DMA mode. Under
+  normal circumstances in DMA mode, the controller halts the channel when the
+  transfer is complete or a condition occurs that requires application
+  intervention.
+
+  In DMA mode, always sets the Channel Enable and Channel Disable bits of the
+  HCCHARn register. The controller ensures there is space in the request
+  queue before submitting the halt request.
+
+  Some time may elapse before the core flushes any posted requests for this
+  host channel and halts. The Channel Halted interrupt handler completes the
+  deactivation of the host channel.
+ */
+extern int ifxhcd_hc_halt(ifxusb_core_if_t *_core_if,
+                    ifxhcd_hc_t *_ifxhc,
+                    ifxhcd_halt_status_e _halt_status);
+
+/*!
+   \brief Prepares a host channel for transferring packets to/from a specific
+  endpoint. The HCCHARn register is set up with the characteristics specified
+  in _ifxhc. Host channel interrupts that may need to be serviced while this
+  transfer is in progress are enabled.
+ */
+extern void ifxhcd_hc_init(ifxusb_core_if_t *_core_if, ifxhcd_hc_t *_ifxhc);
+
+/*!
+   \brief This function is called to handle the disconnection of host port.
+ */
+int32_t ifxhcd_disconnect(ifxhcd_hcd_t *_ifxhcd);
+/*@}*/
+
+/*!  \brief Interrupt Handler Functions */
+/*@{*/
+extern irqreturn_t ifxhcd_oc_irq(int _irq, void *_dev);
+
+extern int32_t ifxhcd_handle_oc_intr(ifxhcd_hcd_t *_ifxhcd);
+extern int32_t ifxhcd_handle_intr   (ifxhcd_hcd_t *_ifxhcd);
+/*@}*/
+
+
+/*! \brief Schedule Queue Functions */
+/*@{*/
+extern void           ifxhcd_epqh_free   (ifxhcd_epqh_t *_epqh);
+extern void           select_eps      (ifxhcd_hcd_t *_ifxhcd);
+extern void           ifxhcd_epqh_idle(ifxhcd_epqh_t *_epqh);
+extern void           ifxhcd_epqh_idle_periodic(ifxhcd_epqh_t *_epqh);
+extern ifxhcd_epqh_t *ifxhcd_urbd_create (ifxhcd_hcd_t *_ifxhcd,struct urb *_urb);
+/*@}*/
+
+/*! \brief Gets the usb_host_endpoint associated with an URB. */
+static inline struct usb_host_endpoint *ifxhcd_urb_to_endpoint(struct urb *_urb)
+{
+       struct usb_device *dev = _urb->dev;
+       int    ep_num = usb_pipeendpoint(_urb->pipe);
+
+       return (usb_pipein(_urb->pipe))?(dev->ep_in[ep_num]):(dev->ep_out[ep_num]);
+}
+
+/*!
+ * \brief Gets the endpoint number from a _bEndpointAddress argument. The endpoint is
+ * qualified with its direction (possible 32 endpoints per device).
+ */
+#define ifxhcd_ep_addr_to_endpoint(_bEndpointAddress_) ((_bEndpointAddress_ & USB_ENDPOINT_NUMBER_MASK) | \
+                                                       ((_bEndpointAddress_ & USB_DIR_IN) != 0) << 4)
+
+
+
+/*! Internal debug function */
+void         ifxhcd_dump_state(ifxhcd_hcd_t *_ifxhcd);
+
+/*@}*//*IFXUSB_HCD*/
+
+extern struct usb_device *usb_alloc_dev  (struct usb_device *parent, struct usb_bus *, unsigned port);
+extern int                usb_add_hcd    (struct usb_hcd *syshcd, unsigned int irqnum, unsigned long irqflags);
+extern void               usb_remove_hcd (struct usb_hcd *syshcd);
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+extern struct usb_hcd    *usb_create_hcd (const struct hc_driver *driver, struct device *dev, char *bus_name);
+#else
+extern struct usb_hcd    *usb_create_hcd (const struct hc_driver *driver, struct device *dev, const char *bus_name);
+#endif
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,32)
+extern void               usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb);
+#else
+extern void               usb_hcd_giveback_urb (struct usb_hcd *syshcd, struct urb *urb,int status);
+#endif
+
+extern void               usb_put_hcd       (struct usb_hcd *syshcd);
+extern long               usb_calc_bus_time (int speed, int is_input, int isoc, int bytecount);
+extern char *syserr(int errno);
+
+
+
+static inline void INIT_EPQH_LIST_ALL(ifxhcd_hcd_t   *_ifxhcd)
+{
+       spin_lock_init(&_ifxhcd->epqh_list_all_lock);
+}
+static inline void LOCK_EPQH_LIST_ALL(ifxhcd_hcd_t   *_ifxhcd)
+{
+       spin_lock(&_ifxhcd->epqh_list_all_lock);
+}
+static inline void UNLOCK_EPQH_LIST_ALL(ifxhcd_hcd_t *_ifxhcd)
+{
+       spin_unlock(&_ifxhcd->epqh_list_all_lock);
+}
+
+static inline void INIT_EPQH_LIST(ifxhcd_hcd_t   *_ifxhcd)
+{
+       spin_lock_init(&_ifxhcd->epqh_list_lock);
+}
+static inline void LOCK_EPQH_LIST(ifxhcd_hcd_t   *_ifxhcd)
+{
+       spin_lock(&_ifxhcd->epqh_list_lock);
+}
+static inline void UNLOCK_EPQH_LIST(ifxhcd_hcd_t *_ifxhcd)
+{
+       spin_unlock(&_ifxhcd->epqh_list_lock);
+}
+
+static inline void INIT_URBD_LIST(ifxhcd_epqh_t    *_epqh)
+{
+       spin_lock_init(&_epqh->urbd_list_lock);
+}
+static inline void LOCK_URBD_LIST(ifxhcd_epqh_t    *_epqh)
+{
+       spin_lock(&_epqh->urbd_list_lock);
+}
+static inline void UNLOCK_URBD_LIST(ifxhcd_epqh_t  *_epqh)
+{
+       spin_unlock(&_epqh->urbd_list_lock);
+}
+
+#endif // __IFXHCD_H__
+