Update usb host driver as in Axis SDK2.20

SVN-Revision: 14409
master
Claudio Mignanti 16 years ago
parent 02cc61b0e4
commit 1adabd363c
  1. 4985
      target/linux/etrax/files/drivers/usb/host/hc-crisv10.c
  2. 278
      target/linux/etrax/files/drivers/usb/host/hc-crisv10.h
  3. 4550
      target/linux/etrax/files/drivers/usb/host/hc_crisv10.c
  4. 5322
      target/linux/etrax/patches-2.6.25/301-usb_support.patch

File diff suppressed because it is too large Load Diff

@ -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
typedef struct etrax_usb_urb_priv { be sure that the intended URB hasn't already been completed (device
/* The first_sb field is used for freeing all SB descriptors belonging drivers has a tendency to reuse URBs once they are completed, causing us
to an urb. The corresponding ep descriptor's sub pointer cannot be to not be able to single old ones out only based on the URB pointer.) */
used for this since the DMA advances the sub pointer as it processes __u32 urb_num;
the sb list. */
USB_SB_Desc_t *first_sb; /* The first_sb field is used for freeing all SB descriptors belonging
/* The last_sb field referes to the last SB descriptor that belongs to to an urb. The corresponding ep descriptor's sub pointer cannot be
this urb. This is important to know so we can free the SB descriptors used for this since the DMA advances the sub pointer as it processes
that ranges between first_sb and last_sb. */ the sb list. */
USB_SB_Desc_t *last_sb; struct USB_SB_Desc *first_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;
/* Counter used in isochronous transfers to keep track of the /* The rx_offset field is used in ctrl and bulk traffic to keep track
number of packets received/transmitted. */ of the offset in the urb's transfer_buffer where incoming data should be
__u32 isoc_packet_counter; copied to. */
__u32 rx_offset;
/* This field is used to pass information about the urb's current state between
the various interrupt handlers (thus marked volatile). */ /* Counter used in isochronous transfers to keep track of the
volatile etrax_usb_urb_state_t urb_state; number of packets received/transmitted. */
__u32 isoc_packet_counter;
/* Connection between the submitted urb and ETRAX epid number */
__u8 epid; /* Flag that marks if this Isoc Out URB has finished it's transfer. Used
because several URBs can be finished before list is processed */
/* The rx_data_list field is used for periodic traffic, to hold __u8 isoc_out_done;
received data for later processing in the the complete_urb functions,
where the data us copied to the urb's transfer_buffer. Basically, we /* This field is used to pass information about the urb's current state
use this intermediate storage because we don't know when it's safe to between the various interrupt handlers (thus marked volatile). */
reuse the transfer_buffer (FIXME?). */ volatile crisv10_urb_state_t urb_state;
struct list_head rx_data_list;
} etrax_urb_priv_t; /* 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
/* This struct is for passing data from the top half to the bottom half. */ get a interrupt. We also get a interrupt for In transfers and which
typedef struct usb_interrupt_registers 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
etrax_hc_t *hc; we have these to flags that shows which part that has completed.
__u32 r_usb_epid_attn; We can then check when we get one of the interrupts that if the other has
__u8 r_usb_status; occured it's safe for us to complete the URB, otherwise we set appropriate
__u16 r_usb_rh_port_status_1; flag and do the completion when we get the other interrupt. */
__u16 r_usb_rh_port_status_2; volatile unsigned char ctrl_zout_done;
__u32 r_usb_irq_mask_read; volatile unsigned char ctrl_rx_done;
__u32 r_usb_fm_number;
struct work_struct usb_bh; /* Connection between the submitted urb and ETRAX epid number */
} usb_interrupt_registers_t; __u8 epid;
/* This struct is for passing data from the isoc top half to the isoc bottom half. */ /* The rx_data_list field is used for periodic traffic, to hold
typedef struct usb_isoc_complete_data received data for later processing in the the complete_urb functions,
{ where the data us copied to the urb's transfer_buffer. Basically, we
struct urb *urb; use this intermediate storage because we don't know when it's safe to
struct work_struct usb_bh; reuse the transfer_buffer (FIXME?). */
} usb_isoc_complete_data_t; struct list_head rx_data_list;
/* 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 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;
/* 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
Loading…
Cancel
Save