patch-2.3.34 linux/drivers/usb/ohci-hcd.h
Next file: linux/drivers/usb/ohci-root-hub.c
Previous file: linux/drivers/usb/ohci-hcd.c
Back to the patch index
Back to the overall index
- Lines: 507
- Date:
Fri Dec 17 16:49:45 1999
- Orig file:
v2.3.33/linux/drivers/usb/ohci-hcd.h
- Orig date:
Wed Oct 27 16:34:12 1999
diff -u --recursive --new-file v2.3.33/linux/drivers/usb/ohci-hcd.h linux/drivers/usb/ohci-hcd.h
@@ -1,105 +1,91 @@
/*
- * OHCI HCD (Host Controller Driver) for USB.
- *
- * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
- *
- * The OHCI HCD layer is a simple but nearly complete implementation of what the
- * USB people would call a HCD for the OHCI.
- * (ISO comming soon, Bulk, INT u. CTRL transfers enabled)
- * The layer on top of it, is for interfacing to the alternate-usb device-drivers.
+ * URB OHCI HCD (Host Controller Driver) for USB.
*
- * [ This is based on Linus' UHCI code and gregs OHCI fragments (0.03c source tree). ]
- * [ Open Host Controller Interface driver for USB. ]
- * [ (C) Copyright 1999 Linus Torvalds (uhci.c) ]
- * [ (C) Copyright 1999 Gregory P. Smith <greg@electricrain.com> ]
- * [ _Log: ohci-hcd.h,v _
- * [ Revision 1.1 1999/04/05 08:32:30 greg ]
+ *(C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
*
- * v4.0 1999/08/18
- * v2.1 1999/05/09 ep_addr correction, code clean up
- * v2.0 1999/05/04
- * v1.0 1999/04/27
* ohci-hcd.h
+ *
*/
-
-#define OHCI_DBG /* printk some debug information */
-#include <linux/config.h>
+#define MODSTR "ohci: "
-// #ifdef CONFIG_USB_OHCI_VROOTHUB
-#define VROOTHUB
-// #endif
-/* enables virtual root hub
- * (root hub will be managed by the hub controller
- * hub.c of the alternate usb driver)
- * must be on now
- */
-
-
-
-#ifdef OHCI_DBG
-#define OHCI_DEBUG(X) X
-#else
-#define OHCI_DEBUG(X)
-#endif
-
-/* for readl writel functions */
-#include <linux/list.h>
-#include <asm/io.h>
-struct usb_ohci_ed;
-struct usb_ohci_td;
-/* for ED and TD structures */
-typedef void * __OHCI_BAG;
-typedef int (*f_handler )(void * ohci, struct usb_ohci_td *td, void *data, int data_len, int dlen, int status, __OHCI_BAG lw0, __OHCI_BAG lw1);
+static int cc_to_error[16] = {
+
+/* mapping of the OHCI CC status to error codes */
+#ifdef USB_ST_CRC /* status codes */
+ /* No Error */ USB_ST_NOERROR,
+ /* CRC Error */ USB_ST_CRC,
+ /* Bit Stuff */ USB_ST_BITSTUFF,
+ /* Data Togg */ USB_ST_CRC,
+ /* Stall */ USB_ST_STALL,
+ /* DevNotResp */ USB_ST_NORESPONSE,
+ /* PIDCheck */ USB_ST_BITSTUFF,
+ /* UnExpPID */ USB_ST_BITSTUFF,
+ /* DataOver */ USB_ST_DATAOVERRUN,
+ /* DataUnder */ USB_ST_DATAUNDERRUN,
+ /* reservd */ USB_ST_NORESPONSE,
+ /* reservd */ USB_ST_NORESPONSE,
+ /* BufferOver */ USB_ST_BUFFEROVERRUN,
+ /* BuffUnder */ USB_ST_BUFFERUNDERRUN,
+ /* Not Access */ USB_ST_NORESPONSE,
+ /* Not Access */ USB_ST_NORESPONSE
+};
+
+#else /* error codes */
+ /* No Error */ 0,
+ /* CRC Error */ -EILSEQ,
+ /* Bit Stuff */ -EPROTO,
+ /* Data Togg */ -EILSEQ,
+ /* Stall */ -EPIPE,
+ /* DevNotResp */ -ETIMEDOUT,
+ /* PIDCheck */ -EPROTO,
+ /* UnExpPID */ -EPROTO,
+ /* DataOver */ -EOVERFLOW,
+ /* DataUnder */ -EREMOTEIO,
+ /* reservd */ -ETIMEDOUT,
+ /* reservd */ -ETIMEDOUT,
+ /* BufferOver */ -ECOMM,
+ /* BuffUnder */ -ECOMM,
+ /* Not Access */ -ETIMEDOUT,
+ /* Not Access */ -ETIMEDOUT
+};
+#define USB_ST_URB_PENDING -EINPROGRESS
+#endif
-
+
+struct ed;
+struct td;
+/* for ED and TD structures */
+
/* ED States */
#define ED_NEW 0x00
#define ED_UNLINK 0x01
#define ED_OPER 0x02
-#define ED_STOP 0x03
#define ED_DEL 0x04
-#define ED_TD_DEL 0x05
-#define ED_RH 0x07 /* marker for RH ED */
-
-#define ED_STATE(ed) (((ed)->hwINFO >> 29) & 0x7)
-#define ED_setSTATE(ed,state) (ed)->hwINFO = ((ed)->hwINFO & ~(0x7 << 29)) | (((state)& 0x7) << 29)
-#define ED_TYPE(ed) (((ed)->hwINFO >> 27) & 0x3)
+#define ED_URB_DEL 0x08
-struct usb_ohci_ed {
+/* usb_ohci_ed */
+typedef struct ed {
__u32 hwINFO;
__u32 hwTailP;
__u32 hwHeadP;
__u32 hwNextED;
-
- void * buffer_start;
- unsigned int len;
- struct usb_ohci_ed *ed_prev;
+
+ struct ed * ed_prev;
__u8 int_period;
__u8 int_branch;
__u8 int_load;
__u8 int_interval;
+ __u8 state;
+ __u8 type;
+ __u16 last_iso;
+ struct ed * ed_rm_list;
-} __attribute((aligned(32)));
-
-struct usb_hcd_ed {
- int endpoint;
- int function;
- int out;
- int type;
- int slow;
- int maxpack;
-};
-
-struct ohci_state {
- int len;
- int status;
-};
-
+} ed_t;
/* TD info field */
@@ -138,23 +124,21 @@
#define TD_NOTACCESSED 0x0F
-#define MAXPSW 2
+#define MAXPSW 1
-struct usb_ohci_td {
+typedef struct td {
__u32 hwINFO;
__u32 hwCBP; /* Current Buffer Pointer */
__u32 hwNextTD; /* Next TD Pointer */
__u32 hwBE; /* Memory Buffer End Pointer */
__u16 hwPSW[MAXPSW];
- __u32 type;
- void * buffer_start;
- f_handler handler;
- struct usb_ohci_ed *ed;
- struct usb_ohci_td *next_dl_td;
- __OHCI_BAG lw0;
- __OHCI_BAG lw1;
-} __attribute((aligned(32)));
+ __u8 type;
+ __u8 index;
+ struct ed * ed;
+ struct td * next_dl_td;
+ urb_t * urb;
+} td_t;
/* TD types */
@@ -162,39 +146,21 @@
#define INT 0x01
#define CTRL 0x02
#define ISO 0x00
-/* TD types with direction */
-#define BULK_IN 0x07
-#define BULK_OUT 0x03
-#define INT_IN 0x05
-#define INT_OUT 0x01
-#define CTRL_IN 0x06
-#define CTRL_OUT 0x02
-#define ISO_IN 0x04
-#define ISO_OUT 0x00
-
-#define CTRL_SETUP 0x102
-#define CTRL_DATA_IN 0x206
-#define CTRL_DATA_OUT 0x202
-#define CTRL_STATUS_IN 0x306
-#define CTRL_STATUS_OUT 0x302
-
-#define SEND 0x00001000
-#define ST_ADDR 0x00002000
-#define ADD_LEN 0x00004000
-#define DEL 0x00008000
-#define DEL_ED 0x00040000
-#define TD_RM 0x00080000
+#define SEND 0x01
+#define ST_ADDR 0x02
+#define ADD_LEN 0x04
+#define DEL 0x08
+
#define OHCI_ED_SKIP (1 << 14)
-
-
/*
* The HCCA (Host Controller Communications Area) is a 256 byte
* structure defined in the OHCI spec. that the host controller is
* told the base address of. It must be 256-byte aligned.
*/
+
#define NUM_INTS 32 /* part of the OHCI standard */
struct ohci_hcca {
__u32 int_table[NUM_INTS]; /* Interrupt ED table */
@@ -206,14 +172,7 @@
/*
- * This is the maximum number of root hub ports. I don't think we'll
- * ever see more than two as that's the space available on an ATX
- * motherboard's case, but it could happen. The OHCI spec allows for
- * up to 15... (which is insane!)
- *
- * Although I suppose several "ports" could be connected directly to
- * internal laptop devices such as a keyboard, mouse, camera and
- * serial/parallel ports. hmm... That'd be neat.
+ * Maximum number of root hub ports.
*/
#define MAX_ROOT_PORTS 15 /* maximum OHCI root hub ports */
@@ -253,17 +212,6 @@
} roothub;
} __attribute((aligned(32)));
-
-/*
- * Read a MMIO register and re-write it after ANDing with (m)
- */
-#define writel_mask(m, a) writel( (readl((__u32)(a))) & (__u32)(m), (__u32)(a) )
-
-/*
- * Read a MMIO register and re-write it after ORing with (b)
- */
-#define writel_set(b, a) writel( (readl((__u32)(a))) | (__u32)(b), (__u32)(a) )
-
/*
* cmdstatus register */
#define OHCI_CLF 0x02
@@ -286,18 +234,103 @@
* Control register masks
*/
#define OHCI_USB_RESET 0
+#define OHCI_USB_RESUME (1 << 6)
#define OHCI_USB_OPER (2 << 6)
#define OHCI_USB_SUSPEND (3 << 6)
+
+/* Virtual Root HUB */
struct virt_root_hub {
int devnum; /* Address of Root Hub endpoint */
- usb_device_irq handler;
- void * dev_id;
+ void * urb;
void * int_addr;
int send;
int interval;
struct timer_list rh_int_timer;
};
+
+/* destination of request */
+#define RH_INTERFACE 0x01
+#define RH_ENDPOINT 0x02
+#define RH_OTHER 0x03
+
+#define RH_CLASS 0x20
+#define RH_VENDOR 0x40
+
+/* Requests: bRequest << 8 | bmRequestType */
+#define RH_GET_STATUS 0x0080
+#define RH_CLEAR_FEATURE 0x0100
+#define RH_SET_FEATURE 0x0300
+#define RH_SET_ADDRESS 0x0500
+#define RH_GET_DESCRIPTOR 0x0680
+#define RH_SET_DESCRIPTOR 0x0700
+#define RH_GET_CONFIGURATION 0x0880
+#define RH_SET_CONFIGURATION 0x0900
+#define RH_GET_STATE 0x0280
+#define RH_GET_INTERFACE 0x0A80
+#define RH_SET_INTERFACE 0x0B00
+#define RH_SYNC_FRAME 0x0C80
+/* Our Vendor Specific Request */
+#define RH_SET_EP 0x2000
+
+
+/* Hub port features */
+#define RH_PORT_CONNECTION 0x00
+#define RH_PORT_ENABLE 0x01
+#define RH_PORT_SUSPEND 0x02
+#define RH_PORT_OVER_CURRENT 0x03
+#define RH_PORT_RESET 0x04
+#define RH_PORT_POWER 0x08
+#define RH_PORT_LOW_SPEED 0x09
+#define RH_C_PORT_CONNECTION 0x10
+#define RH_C_PORT_ENABLE 0x11
+#define RH_C_PORT_SUSPEND 0x12
+#define RH_C_PORT_OVER_CURRENT 0x13
+#define RH_C_PORT_RESET 0x14
+
+/* Hub features */
+#define RH_C_HUB_LOCAL_POWER 0x00
+#define RH_C_HUB_OVER_CURRENT 0x01
+
+#define RH_DEVICE_REMOTE_WAKEUP 0x00
+#define RH_ENDPOINT_STALL 0x01
+
+#define RH_ACK 0x01
+#define RH_REQ_ERR -1
+#define RH_NACK 0x00
+
+/* Root-Hub Register info */
+
+#define RH_PS_CCS 0x00000001
+#define RH_PS_PES 0x00000002
+#define RH_PS_PSS 0x00000004
+#define RH_PS_POCI 0x00000008
+#define RH_PS_PRS 0x00000010
+#define RH_PS_PPS 0x00000100
+#define RH_PS_LSDA 0x00000200
+#define RH_PS_CSC 0x00010000
+#define RH_PS_PESC 0x00020000
+#define RH_PS_PSSC 0x00040000
+#define RH_PS_OCIC 0x00080000
+#define RH_PS_PRSC 0x00100000
+
+
+#define min(a,b) (((a)<(b))?(a):(b))
+
+
+/* urb */
+typedef struct
+{
+ ed_t * ed;
+ __u16 length; // number of tds associated with this request
+ __u16 td_cnt; // number of tds already serviced
+ int state;
+ void * wait;
+ td_t * td[0]; // list pointer to all corresponding TDs associated with this request
+
+} urb_priv_t;
+#define URB_DEL 1
+
/*
* This is the full ohci controller description
*
@@ -306,86 +339,62 @@
*/
-struct ohci {
- int irq;
- struct ohci_regs *regs; /* OHCI controller's memory */
- struct ohci_hc_area *hc_area; /* hcca, int ed-tree, ohci itself .. */
+typedef struct ohci {
+ struct ohci_hcca hcca; /* hcca */
+ int irq;
+ struct ohci_regs * regs; /* OHCI controller's memory */
struct list_head ohci_hcd_list; /* list of all ohci_hcd */
+ struct ohci * next; // chain of uhci device contexts
+ struct list_head urb_list; // list of all pending urbs
+ spinlock_t urb_list_lock; // lock to keep consistency
+
int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load ballancing)*/
- struct usb_ohci_ed * ed_rm_list; /* list of all endpoints to be removed */
- struct usb_ohci_ed * ed_bulktail; /* last endpoint of bulk list */
- struct usb_ohci_ed * ed_controltail; /* last endpoint of control list */
- struct usb_ohci_ed * ed_isotail; /* last endpoint of iso list */
+ ed_t * ed_rm_list[2]; /* lists of all endpoints to be removed */
+ ed_t * ed_bulktail; /* last endpoint of bulk list */
+ ed_t * ed_controltail; /* last endpoint of control list */
+ ed_t * ed_isotail; /* last endpoint of iso list */
int intrstatus;
- struct ohci_rep_td *repl_queue; /* for internal requests */
- int rh_int_interval;
- int rh_int_timer;
- struct usb_bus *bus;
+ __u32 hc_control; /* copy of the hc control reg */
+ struct usb_bus * bus;
+ struct usb_device * dev[128];
struct virt_root_hub rh;
-};
+} ohci_t;
#define NUM_TDS 0 /* num of preallocated transfer descriptors */
#define NUM_EDS 32 /* num of preallocated endpoint descriptors */
-struct ohci_hc_area {
- struct ohci_hcca hcca; /* OHCI mem. mapped IO area 256 Bytes*/
- struct ohci ohci;
-
-};
struct ohci_device {
- struct usb_device *usb;
- atomic_t refcnt;
- struct ohci *ohci;
- struct usb_ohci_ed ed[NUM_EDS];
- unsigned long data[16];
+ ed_t ed[NUM_EDS];
+ int ed_cnt;
+ void * wait;
};
-#define ohci_to_usb(ohci) ((ohci)->usb)
+// #define ohci_to_usb(ohci) ((ohci)->usb)
#define usb_to_ohci(usb) ((struct ohci_device *)(usb)->hcpriv)
/* hcd */
-struct usb_ohci_td * ohci_trans_req(struct ohci * ohci, struct usb_ohci_ed * ed, int cmd_len, void *cmd, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1, unsigned int type, f_handler handler);
-struct usb_ohci_ed *usb_ohci_add_ep(struct usb_device * usb_dev, struct usb_hcd_ed * hcd_ed, int interval, int load);
-int usb_ohci_rm_function(struct usb_device * usb_dev, f_handler handler, __OHCI_BAG lw0, __OHCI_BAG lw1);
-int usb_ohci_rm_ep(struct usb_device * usb_dev, struct usb_ohci_ed *ed, f_handler handler, __OHCI_BAG lw0, __OHCI_BAG lw1, int send);
-struct usb_ohci_ed * ohci_find_ep(struct usb_device * usb_dev, struct usb_hcd_ed *hcd_ed);
-
-/* roothub */
-
-int root_hub_control_msg(struct usb_device *usb_dev, unsigned int pipe, devrequest *cmd, void *data, int len);
-int root_hub_release_irq(struct usb_device *usb_dev, void * ed);
-int root_hub_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id, void **handle);
-
-/* Root-Hub Register info */
-
-#define RH_PS_CCS 0x00000001
-#define RH_PS_PES 0x00000002
-#define RH_PS_PSS 0x00000004
-#define RH_PS_POCI 0x00000008
-#define RH_PS_PRS 0x00000010
-#define RH_PS_PPS 0x00000100
-#define RH_PS_LSDA 0x00000200
-#define RH_PS_CSC 0x00010000
-#define RH_PS_PESC 0x00020000
-#define RH_PS_PSSC 0x00040000
-#define RH_PS_OCIC 0x00080000
-#define RH_PS_PRSC 0x00100000
-
+/* endpoint */
+static int ep_link(ohci_t * ohci, ed_t * ed);
+static int ep_unlink(ohci_t * ohci, ed_t * ed);
+static ed_t * ep_add_ed(struct usb_device * usb_dev, unsigned int pipe, int interval, int load);
+static void ep_rm_ed(struct usb_device * usb_dev, ed_t * ed);
+/* td */
+static void td_fill(unsigned int info, void * data, int len, urb_t * urb, int type, int index);
+static void td_submit_urb(urb_t * urb);
+/* root hub */
+static int rh_submit_urb(urb_t * urb);
+static int rh_unlink_urb(urb_t * urb);
+static int rh_init_int_timer(urb_t * urb);
-#ifdef OHCI_DBG
+#ifdef DEBUG
#define OHCI_FREE(x) kfree(x); printk("OHCI FREE: %d: %4x\n", -- __ohci_free_cnt, (unsigned int) x)
-#define OHCI_ALLOC(x,size) (x) = kmalloc(size, GFP_KERNEL); printk("OHCI ALLO: %d: %4x\n", ++ __ohci_free_cnt,(unsigned int) x)
-#define USB_FREE(x) kfree(x); printk("USB FREE: %d: %4x\n", -- __ohci_free1_cnt, (unsigned int) x)
-#define USB_ALLOC(x,size) (x) = kmalloc(size, GFP_KERNEL); printk("USB ALLO: %d: %4x\n", ++ __ohci_free1_cnt, (unsigned int) x)
+#define OHCI_ALLOC(x,size) (x) = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); printk("OHCI ALLO: %d: %4x\n", ++ __ohci_free_cnt,(unsigned int) x)
static int __ohci_free_cnt = 0;
-static int __ohci_free1_cnt = 0;
#else
#define OHCI_FREE(x) kfree(x)
-#define OHCI_ALLOC(x,size) (x) = kmalloc(size, GFP_KERNEL)
-#define USB_FREE(x) kfree(x)
-#define USB_ALLOC(x,size) (x) = kmalloc(size, GFP_KERNEL)
+#define OHCI_ALLOC(x,size) (x) = kmalloc(size, in_interrupt() ? GFP_ATOMIC : GFP_KERNEL)
#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)