⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ohci.h

📁 超小usb协议栈
💻 H
字号:
#ifndef __LINUX_OHCI_H#define __LINUX_OHCI_H/* * Open Host Controller Interface data structures and defines. * * (C) Copyright 1999 Gregory P. Smith <greg@electricrain.com> * * $Id: ohci.h,v 1.6 1999/04/24 22:50:06 greg Exp $ */#include <linux/list.h>#include <asm/io.h>#include "usb.h"/* * Each TD must be aligned on a 16-byte boundary.  From the OHCI v1.0 spec * it does not state that TDs must be contiguious in memory (due to the * use of the next_td field).  This gives us extra room at the end of a * TD for our own driver specific data. * * This structure's size must be a multiple of 16 bytes. */struct ohci_td {    	/* OHCI Hardware fields */    	__u32 info;	__u32 cur_buf;		/* Current Buffer Pointer */	__u32 next_td;		/* Next TD Pointer */	__u32 buf_end;		/* Memory Buffer End Pointer */	/* Driver specific fields */	struct list_head irq_list;	/* Active interrupt list */	usb_device_irq completed;	/* Completion handler routine */	void *data;	/* XXX ? */	void *dev_id;	/* XXX ? */	__u32 ed_bus;			/* bus address of original ED */} __attribute((aligned(32)));#define OHCI_TD_ROUND	(1 << 18)	/* buffer rounding bit */#define OHCI_TD_D	(3 << 11)	/* direction of xfer: */#define OHCI_TD_D_IN	(2 << 11)#define OHCI_TD_D_OUT	(1 << 11)#define OHCI_TD_D_SETUP (0)#define td_set_dir_in(d)	((d) ? OHCI_TD_D_IN : OHCI_TD_D_OUT )#define td_set_dir_out(d)	((d) ? OHCI_TD_D_OUT : OHCI_TD_D_IN )#define OHCI_TD_IOC_DELAY (7 << 21)	/* frame delay allowed before int. */#define OHCI_TD_IOC_OFF	(OHCI_TD_IOC_DELAY)	/* no interrupt on complete */#define OHCI_TD_DT	(3 << 24)	/* data toggle bits */#define td_force_toggle(b)	(((b) | 2) << 24)#define OHCI_TD_ERRCNT	(3 << 26)	/* error count */#define td_errorcount(td)	(((td) >> 26) & 3)#define OHCI_TD_CC	(0xf << 28)	/* condition code */#define OHCI_TD_CC_NEW	(OHCI_TD_CC)	/* set this on all unaccessed TDs! */#define td_cc_notaccessed(td)	((td >> 29) == 7)#define td_cc_accessed(td)	((td >> 29) != 7)#define td_cc_noerror(td)	(((td) & OHCI_TD_CC) == 0)#define td_active(td)	(!td_cc_noerror((td)) && (td_errorcount((td)) < 3))#define td_done(td)	(td_cc_noerror((td)) || (td_errorcount((td)) == 3))/* * The endpoint descriptors also requires 16-byte alignment */struct ohci_ed {	/* OHCI hardware fields */	__u32 status;	__u32 tail_td;	/* TD Queue tail pointer */	__u32 head_td;	/* TD Queue head pointer */	__u32 next_ed;	/* Next ED */} __attribute((aligned(16)));#define OHCI_ED_SKIP	(1 << 14)#define OHCI_ED_MPS	(0x7ff << 16)/* FIXME: should cap at the USB max packet size [0x4ff] */#define ed_set_maxpacket(s)	(((s) << 16) & OHCI_ED_MPS)#define OHCI_ED_F_NORM	(0)#define OHCI_ED_F_ISOC	(1 << 15)#define ed_set_type_isoc(i)	((i) ? OHCI_ED_F_ISOC : OHCI_ED_F_NORM)#define OHCI_ED_S_LOW	(1 << 13)#define OHCI_ED_S_HIGH	(0)#define ed_set_speed(s)		((s) ? OHCI_ED_S_LOW : OHCI_ED_S_HIGH)#define OHCI_ED_D	(3 << 11)#define OHCI_ED_D_IN	(2 << 11)#define OHCI_ED_D_OUT	(1 << 11)#define ed_set_dir_in(d)	((d) ? OHCI_ED_D_IN : OHCI_ED_D_OUT)#define ed_set_dir_out(d)	((d) ? OHCI_ED_D_OUT : OHCI_ED_D_IN)#define OHCI_ED_EN	(0xf << 7)#define OHCI_ED_FA	(0x7f)/* NOTE: bits 27-31 of the status dword are reserved for the driver *//* * We'll use this status flag for the non-predefined EDs to mark if * they're in use or not. * * FIXME: unimplemented (needed?) */#define ED_USED	(1 << 31)/* * 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 */	__u16	frame_no;		/* current frame number */	__u16	pad1;			/* set to 0 on each frame_no change */	__u32	donehead;		/* info returned for an interrupt */	u8	reserved_for_hc[116];} __attribute((aligned(256)));/* * The TD entries here are pre-allocated as Linus did with his simple * UHCI implementation.  With the current state of this driver that * shouldn't be a problem.  However if someone ever connects 127 * supported devices to this driver and tries to use them all at once: * 	a)  They're insane! * 	b)  They should code in dynamic allocation */struct ohci;/* *  Warning: These constants must not be so large as to cause the *  ohci_device structure to exceed one 4096 byte page.  Or "weird *  things will happen" as the alloc_ohci() function assumes that *  its less than one page.  (FIXME) */#define NUM_TDS	32		/* num of preallocated transfer descriptors */#define DATA_BUF_LEN 16		/* num of unsigned long's for the data buf *//* * For this "simple" driver we only support a single ED for each * polling rate. * * Later on this driver should be extended to use a full tree of EDs * so that there can be 32 different 32ms polling frames, etc. * Individual devices shouldn't need as many as the root hub in that * case; complicating how things are done at the moment. * * Bulk and Control transfers hang off of their own ED lists. */#define NUM_EDS 16		/* num of preallocated endpoint descriptors */#define ohci_to_usb(ohci)	((ohci)->usb)#define usb_to_ohci(usb)	((struct ohci_device *)(usb)->hcpriv)/* The usb_device must be first! */struct ohci_device {    	struct usb_device	*usb;	struct ohci		*ohci;	struct ohci_hcca 	*hcca;		/* OHCI mem. mapped IO area */	struct ohci_ed		ed[NUM_EDS];	/* Endpoint Descriptors */	struct ohci_td		td[NUM_TDS];	/* Transfer Descriptors */	unsigned long		data[DATA_BUF_LEN];};/* .... */#define ED_INT_1	0#define ED_INT_2	1#define ED_INT_4	2#define ED_INT_8	3#define ED_INT_16	4#define ED_INT_32	5#define ED_CONTROL	6#define ED_BULK		7#define ED_ISO		ED_INT_1	/* same as 1ms interrupt queue */#define ED_FIRST_AVAIL  8		/* first non-reserved ED *//* * Given a period p in ms, convert it to the closest endpoint * interrupt frequency; rounding down.  I'm sure many feel that this * is a gross macro.  Feel free to toss it for actual code. */#define ms_to_ed_int(p) \	((p >= 32) ? ED_INT_32 : \	 ((p & 16) ? ED_INT_16 : \	  ((p & 8) ? ED_INT_8 : \	   ((p & 4) ? ED_INT_4 : \	    ((p & 2) ? ED_INT_2 : \	     ED_INT_1)))))  /* hmm.. scheme or lisp anyone? *//* * 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. */#define MAX_ROOT_PORTS	15	/* maximum OHCI root hub ports *//* * This is the structure of the OHCI controller's memory mapped I/O * region.  This is Memory Mapped I/O.  You must use the readl() and * writel() macros defined in asm/io.h to access these!! */struct ohci_regs {	/* control and status registers */	__u32	revision;	__u32	control;	__u32	cmdstatus;	__u32	intrstatus;	__u32	intrenable;	__u32	intrdisable;	/* memory pointers */	__u32	hcca;	__u32	ed_periodcurrent;	__u32	ed_controlhead;	__u32	ed_controlcurrent;	__u32	ed_bulkhead;	__u32	ed_bulkcurrent;	__u32	current_donehead; /* The driver should get this from the HCCA */	/* frame counters */	__u32	fminterval;	__u32	fmremaining;	__u32	fmnumber;	__u32	periodicstart;	__u32	lsthresh;	/* Root hub ports */	struct	ohci_roothub_regs {		__u32	a;		__u32	b;		__u32	status;		__u32	portstatus[MAX_ROOT_PORTS];	} 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) )#define PORT_CCS	(1)		/* port current connect status */#define PORT_PES	(1 << 1)	/* port enable status */#define PORT_PSS	(1 << 2)	/* port suspend status */#define PORT_POCI	(1 << 3)	/* port overcurrent indicator */#define PORT_PRS	(1 << 4)	/* port reset status */#define PORT_PPS	(1 << 8)	/* port power status */#define PORT_LSDA	(1 << 9)	/* port low speed dev. attached */#define PORT_CSC	(1 << 16)	/* port connect status change */#define PORT_PESC	(1 << 17)	/* port enable status change */#define PORT_PSSC	(1 << 18)	/* port suspend status change */#define PORT_OCIC	(1 << 19)	/* port over current indicator chg */#define PORT_PRSC	(1 << 20)	/* port reset status change *//* * Interrupt register masks */#define OHCI_INTR_SO	(1)#define OHCI_INTR_WDH	(1 << 1)#define OHCI_INTR_SF	(1 << 2)#define OHCI_INTR_RD	(1 << 3)#define OHCI_INTR_UE	(1 << 4)#define OHCI_INTR_FNO	(1 << 5)#define OHCI_INTR_RHSC	(1 << 6)#define OHCI_INTR_OC	(1 << 30)#define OHCI_INTR_MIE	(1 << 31)/* * Control register masks */#define OHCI_USB_OPER		(2 << 6)#define OHCI_USB_SUSPEND	(3 << 6)/* * This is the full ohci controller description * * Note how the "proper" USB information is just * a subset of what the full implementation needs. (Linus) */struct ohci {    	int irq;	struct ohci_regs *regs;			/* OHCI controller's memory */	struct usb_bus *bus;	struct ohci_device *root_hub;		/* Root hub & controller */	struct list_head interrupt_list;	/* List of interrupt active TDs for this OHCI */};/* Debugging code */void show_ed(struct ohci_ed *ed);void show_td(struct ohci_td *td);void show_status(struct ohci *ohci);#endif/* vim:sw=8 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -