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,131 +4,175 @@
#include <linux/types.h> #include <linux/types.h>
#include <linux/list.h> #include <linux/list.h>
typedef struct USB_IN_Desc { struct USB_IN_Desc {
volatile __u16 sw_len; volatile __u16 sw_len;
volatile __u16 command; volatile __u16 command;
volatile unsigned long next; volatile unsigned long next;
volatile unsigned long buf; volatile unsigned long buf;
volatile __u16 hw_len; volatile __u16 hw_len;
volatile __u16 status; volatile __u16 status;
} USB_IN_Desc_t;
typedef 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 {
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 { struct USB_SB_Desc {
int sleeping; volatile __u16 sw_len;
int error; volatile __u16 command;
struct wait_queue *wq; volatile unsigned long next;
volatile unsigned long buf;
};
struct USB_EP_Desc {
volatile __u16 hw_len;
volatile __u16 command;
volatile unsigned long sub;
volatile unsigned long next;
};
/* 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 { typedef enum {
STARTED, STARTED,
NOT_STARTED, NOT_STARTED,
UNLINK, UNLINK,
TRANSFER_DONE, } crisv10_urb_state_t;
WAITING_FOR_DESCR_INTR
} etrax_usb_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
/* The first_sb field is used for freeing all SB descriptors belonging to an urb. The corresponding ep descriptor's sub pointer cannot be
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
used for this since the DMA advances the sub pointer as it processes the sb list. */
the sb list. */ struct USB_SB_Desc *first_sb;
USB_SB_Desc_t *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;
/* The rx_offset field is used in ctrl and bulk traffic to keep track /* The last_sb field referes to the last SB descriptor that belongs to
of the offset in the urb's transfer_buffer where incoming data should be this urb. This is important to know so we can free the SB descriptors
copied to. */ that ranges between first_sb and last_sb. */
__u32 rx_offset; 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
copied to. */
__u32 rx_offset;
/* Counter used in isochronous transfers to keep track of the
number of packets received/transmitted. */
__u32 isoc_packet_counter;
/* Counter used in isochronous transfers to keep track of the /* Flag that marks if this Isoc Out URB has finished it's transfer. Used
number of packets received/transmitted. */ because several URBs can be finished before list is processed */
__u32 isoc_packet_counter; __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;
/* This field is used to pass information about the urb's current state between /* Connection between the submitted urb and ETRAX epid number */
the various interrupt handlers (thus marked volatile). */ __u8 epid;
volatile etrax_usb_urb_state_t urb_state;
/* The rx_data_list field is used for periodic traffic, to hold
received data for later processing in the the complete_urb functions,
where the data us copied to the urb's transfer_buffer. Basically, we
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;
/* Connection between the submitted urb and ETRAX epid number */
__u8 epid;
/* The rx_data_list field is used for periodic traffic, to hold /* The interval time rounded up to closest 2^N */
received data for later processing in the the complete_urb functions, int interval;
where the data us copied to the urb's transfer_buffer. Basically, we
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. */ /* Pool of EP descriptors needed if it's a INTR transfer.
typedef struct usb_interrupt_registers Amount of EPs in pool correspons to how many INTR that should
{ be inserted in TxIntrEPList (max 128, defined by MAX_INTR_INTERVAL) */
etrax_hc_t *hc; struct USB_EP_Desc* intr_ep_pool[128];
__u32 r_usb_epid_attn;
__u8 r_usb_status;
__u16 r_usb_rh_port_status_1;
__u16 r_usb_rh_port_status_2;
__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. */ /* The mount of EPs allocated for this INTR URB */
typedef struct usb_isoc_complete_data int intr_ep_pool_length;
{
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 /* Pointer to info struct if URB is scheduled to be finished later */
for periodic traffic (intr and isoc). */ struct urb_later_data* later_data;
typedef struct rx_data
{
void *data;
int length;
struct list_head list;
} rx_data_t;
/* 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;
__u16 r_usb_rh_port_status_2;
__u32 r_usb_irq_mask_read;
__u32 r_usb_fm_number;
struct work_struct usb_bh;
};
/* 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;
};
/* Entry item for URB lists for each endpint */
typedef struct urb_entry typedef struct urb_entry
{ {
struct urb *urb; struct urb *urb;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff