Update usb host driver as in Axis SDK2.20

SVN-Revision: 14409
This commit is contained in:
Claudio Mignanti 2009-02-04 18:00:13 +00:00
parent 02cc61b0e4
commit 1adabd363c
4 changed files with 5163 additions and 9952 deletions

File diff suppressed because it is too large Load Diff

View File

@ -4,77 +4,92 @@
#include <linux/types.h>
#include <linux/list.h>
typedef struct USB_IN_Desc {
struct USB_IN_Desc {
volatile __u16 sw_len;
volatile __u16 command;
volatile unsigned long next;
volatile unsigned long buf;
volatile __u16 hw_len;
volatile __u16 status;
} USB_IN_Desc_t;
};
typedef struct USB_SB_Desc {
struct USB_SB_Desc {
volatile __u16 sw_len;
volatile __u16 command;
volatile unsigned long next;
volatile unsigned long buf;
__u32 dummy;
} USB_SB_Desc_t;
};
typedef struct USB_EP_Desc {
struct USB_EP_Desc {
volatile __u16 hw_len;
volatile __u16 command;
volatile unsigned long sub;
volatile unsigned long next;
__u32 dummy;
} USB_EP_Desc_t;
struct virt_root_hub {
int devnum;
void *urb;
void *int_addr;
int send;
int interval;
int numports;
struct timer_list rh_int_timer;
volatile __u16 wPortChange_1;
volatile __u16 wPortChange_2;
volatile __u16 prev_wPortStatus_1;
volatile __u16 prev_wPortStatus_2;
};
struct etrax_usb_intr_traffic {
int sleeping;
int error;
struct wait_queue *wq;
/* Root Hub port status struct */
struct crisv10_rh {
volatile __u16 wPortChange[2];
volatile __u16 wPortStatusPrev[2];
};
/* HCD description */
struct crisv10_hcd {
spinlock_t lock;
__u8 num_ports;
__u8 running;
};
/* Endpoint HC private data description */
struct crisv10_ep_priv {
int epid;
};
/* Additional software state info for a USB Controller epid */
struct etrax_epid {
__u8 inuse; /* !0 = setup in Etrax and used for a endpoint */
__u8 disabled; /* !0 = Temporarly disabled to avoid resubmission */
__u8 type; /* Setup as: PIPE_BULK, PIPE_CONTROL ... */
__u8 out_traffic; /* !0 = This epid is for out traffic */
};
/* Struct to hold information of scheduled later URB completion */
struct urb_later_data {
struct delayed_work dws;
struct usb_hcd *hcd;
struct urb *urb;
int urb_num;
int status;
};
typedef struct etrax_usb_hc {
struct usb_bus *bus;
struct virt_root_hub rh;
struct etrax_usb_intr_traffic intr;
} etrax_hc_t;
typedef enum {
STARTED,
NOT_STARTED,
UNLINK,
TRANSFER_DONE,
WAITING_FOR_DESCR_INTR
} etrax_usb_urb_state_t;
} crisv10_urb_state_t;
struct crisv10_urb_priv {
/* Sequence number for this URB. Every new submited URB gets this from
a incrementing counter. Used when a URB is scheduled for later finish to
be sure that the intended URB hasn't already been completed (device
drivers has a tendency to reuse URBs once they are completed, causing us
to not be able to single old ones out only based on the URB pointer.) */
__u32 urb_num;
typedef struct etrax_usb_urb_priv {
/* The first_sb field is used for freeing all SB descriptors belonging
to an urb. The corresponding ep descriptor's sub pointer cannot be
used for this since the DMA advances the sub pointer as it processes
the sb list. */
USB_SB_Desc_t *first_sb;
struct USB_SB_Desc *first_sb;
/* The last_sb field referes to the last SB descriptor that belongs to
this urb. This is important to know so we can free the SB descriptors
that ranges between first_sb and last_sb. */
USB_SB_Desc_t *last_sb;
struct USB_SB_Desc *last_sb;
/* The rx_offset field is used in ctrl and bulk traffic to keep track
of the offset in the urb's transfer_buffer where incoming data should be
@ -85,9 +100,25 @@ typedef struct etrax_usb_urb_priv {
number of packets received/transmitted. */
__u32 isoc_packet_counter;
/* This field is used to pass information about the urb's current state between
the various interrupt handlers (thus marked volatile). */
volatile etrax_usb_urb_state_t urb_state;
/* Flag that marks if this Isoc Out URB has finished it's transfer. Used
because several URBs can be finished before list is processed */
__u8 isoc_out_done;
/* This field is used to pass information about the urb's current state
between the various interrupt handlers (thus marked volatile). */
volatile crisv10_urb_state_t urb_state;
/* In Ctrl transfers consist of (at least) 3 packets: SETUP, IN and ZOUT.
When DMA8 sub-channel 2 has processed the SB list for this sequence we
get a interrupt. We also get a interrupt for In transfers and which
one of these interrupts that comes first depends of data size and device.
To be sure that we have got both interrupts before we complete the URB
we have these to flags that shows which part that has completed.
We can then check when we get one of the interrupts that if the other has
occured it's safe for us to complete the URB, otherwise we set appropriate
flag and do the completion when we get the other interrupt. */
volatile unsigned char ctrl_zout_done;
volatile unsigned char ctrl_rx_done;
/* Connection between the submitted urb and ETRAX epid number */
__u8 epid;
@ -98,12 +129,31 @@ typedef struct etrax_usb_urb_priv {
use this intermediate storage because we don't know when it's safe to
reuse the transfer_buffer (FIXME?). */
struct list_head rx_data_list;
} etrax_urb_priv_t;
/* This struct is for passing data from the top half to the bottom half. */
typedef struct usb_interrupt_registers
{
etrax_hc_t *hc;
/* The interval time rounded up to closest 2^N */
int interval;
/* Pool of EP descriptors needed if it's a INTR transfer.
Amount of EPs in pool correspons to how many INTR that should
be inserted in TxIntrEPList (max 128, defined by MAX_INTR_INTERVAL) */
struct USB_EP_Desc* intr_ep_pool[128];
/* The mount of EPs allocated for this INTR URB */
int intr_ep_pool_length;
/* Pointer to info struct if URB is scheduled to be finished later */
struct urb_later_data* later_data;
/* Allocated bandwidth for isochronous and interrupt traffic */
int bandwidth;
};
/* This struct is for passing data from the top half to the bottom half irq
handlers */
struct crisv10_irq_reg {
struct usb_hcd* hcd;
__u32 r_usb_epid_attn;
__u8 r_usb_status;
__u16 r_usb_rh_port_status_1;
@ -111,24 +161,18 @@ typedef struct usb_interrupt_registers
__u32 r_usb_irq_mask_read;
__u32 r_usb_fm_number;
struct work_struct usb_bh;
} usb_interrupt_registers_t;
};
/* This struct is for passing data from the isoc top half to the isoc bottom half. */
typedef struct usb_isoc_complete_data
{
/* This struct is for passing data from the isoc top half to the isoc bottom
half. */
struct crisv10_isoc_complete_data {
struct usb_hcd *hcd;
struct urb *urb;
struct work_struct usb_bh;
} usb_isoc_complete_data_t;
/* This struct holds data we get from the rx descriptors for DMA channel 9
for periodic traffic (intr and isoc). */
typedef struct rx_data
{
void *data;
int length;
struct list_head list;
} rx_data_t;
};
/* Entry item for URB lists for each endpint */
typedef struct urb_entry
{
struct urb *urb;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff