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

📄 ohci.h

📁 host usb 主设备程序 支持sd卡 mouse keyboard 的最单单的驱动程序 gcc编译
💻 H
📖 第 1 页 / 共 2 页
字号:
 */struct ohci_hcd {	spinlock_t		lock;	/*	 * I/O memory used to communicate with the HC (dma-consistent)	 */	struct ohci_regs __iomem *regs;	/*	 * main memory used to communicate with the HC (dma-consistent).	 * hcd adds to schedule for a live hc any time, but removals finish	 * only at the start of the next frame.	 */	struct ohci_hcca	*hcca;	dma_addr_t		hcca_dma;	struct ed		*ed_rm_list;		/* to be removed */	struct ed		*ed_bulktail;		/* last in bulk list */	struct ed		*ed_controltail;	/* last in ctrl list */	struct ed		*periodic [NUM_INTS];	/* shadow int_table */	/*	 * OTG controllers and transceivers need software interaction;	 * other external transceivers should be software-transparent	 */	struct otg_transceiver	*transceiver;	/*	 * memory management for queue data structures	 */	struct dma_pool		*td_cache;	struct dma_pool		*ed_cache;	struct td		*td_hash [TD_HASH_SIZE];	struct list_head	pending;	/*	 * driver state	 */	int			num_ports;	int			load [NUM_INTS];	u32			hc_control;	/* copy of hc control reg */	unsigned long		next_statechange;	/* suspend/resume */	u32			fminterval;		/* saved register */	unsigned		autostop:1;	/* rh auto stopping/stopped */	unsigned long		flags;		/* for HC bugs */#define	OHCI_QUIRK_AMD756	0x01			/* erratum #4 */#define	OHCI_QUIRK_SUPERIO	0x02			/* natsemi */#define	OHCI_QUIRK_INITRESET	0x04			/* SiS, OPTi, ... */#define	OHCI_QUIRK_BE_DESC	0x08			/* BE descriptors */#define	OHCI_QUIRK_BE_MMIO	0x10			/* BE registers */#define	OHCI_QUIRK_ZFMICRO	0x20			/* Compaq ZFMicro chipset*/	// there are also chip quirks/bugs in init logic};/* convert between an hcd pointer and the corresponding ohci_hcd */static inline struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd){	return (struct ohci_hcd *) (hcd->hcd_priv);}static inline struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci){	return container_of ((void *) ohci, struct usb_hcd, hcd_priv);}/*-------------------------------------------------------------------------*/#ifndef DEBUG#define STUB_DEBUG_FILES#endif	/* DEBUG */#define ohci_dbg(ohci, fmt, args...) \	dev_dbg (ohci_to_hcd(ohci)->self.controller , fmt , ## args )#define ohci_err(ohci, fmt, args...) \	dev_err (ohci_to_hcd(ohci)->self.controller , fmt , ## args )#define ohci_info(ohci, fmt, args...) \	dev_info (ohci_to_hcd(ohci)->self.controller , fmt , ## args )#define ohci_warn(ohci, fmt, args...) \	dev_warn (ohci_to_hcd(ohci)->self.controller , fmt , ## args )#ifdef OHCI_VERBOSE_DEBUG#	define ohci_vdbg ohci_dbg#else#	define ohci_vdbg(ohci, fmt, args...) do { } while (0)#endif/*-------------------------------------------------------------------------*//* * While most USB host controllers implement their registers and * in-memory communication descriptors in little-endian format, * a minority (notably the IBM STB04XXX and the Motorola MPC5200 * processors) implement them in big endian format. * * In addition some more exotic implementations like the Toshiba * Spider (aka SCC) cell southbridge are "mixed" endian, that is, * they have a different endianness for registers vs. in-memory * descriptors. * * This attempts to support either format at compile time without a * runtime penalty, or both formats with the additional overhead * of checking a flag bit. * * That leads to some tricky Kconfig rules howevber. There are * different defaults based on some arch/ppc platforms, though * the basic rules are: * * Controller type              Kconfig options needed * ---------------              ---------------------- * little endian                CONFIG_USB_OHCI_LITTLE_ENDIAN * * fully big endian             CONFIG_USB_OHCI_BIG_ENDIAN_DESC _and_ *                              CONFIG_USB_OHCI_BIG_ENDIAN_MMIO * * mixed endian                 CONFIG_USB_OHCI_LITTLE_ENDIAN _and_ *                              CONFIG_USB_OHCI_BIG_ENDIAN_{MMIO,DESC} * * (If you have a mixed endian controller, you -must- also define * CONFIG_USB_OHCI_LITTLE_ENDIAN or things will not work when building * both your mixed endian and a fully big endian controller support in * the same kernel image). */#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_DESC#ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN#define big_endian_desc(ohci)	(ohci->flags & OHCI_QUIRK_BE_DESC)#else#define big_endian_desc(ohci)	1		/* only big endian */#endif#else#define big_endian_desc(ohci)	0		/* only little endian */#endif#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO#ifdef CONFIG_USB_OHCI_LITTLE_ENDIAN#define big_endian_mmio(ohci)	(ohci->flags & OHCI_QUIRK_BE_MMIO)#else#define big_endian_mmio(ohci)	1		/* only big endian */#endif#else#define big_endian_mmio(ohci)	0		/* only little endian */#endif/* * Big-endian read/write functions are arch-specific. * Other arches can be added if/when they're needed. * * REVISIT: arch/powerpc now has readl/writel_be, so the * definition below can die once the STB04xxx support is * finally ported over. */#if defined(CONFIG_PPC) && !defined(CONFIG_PPC_MERGE)#define readl_be(addr)		in_be32((__force unsigned *)addr)#define writel_be(val, addr)	out_be32((__force unsigned *)addr, val)#endifstatic inline unsigned int _ohci_readl (const struct ohci_hcd *ohci,					__hc32 __iomem * regs){#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO	return big_endian_mmio(ohci) ?		readl_be (regs) :		readl (regs);#else	return readl (regs);#endif}static inline void _ohci_writel (const struct ohci_hcd *ohci,				 const unsigned int val, __hc32 __iomem *regs){#ifdef CONFIG_USB_OHCI_BIG_ENDIAN_MMIO	big_endian_mmio(ohci) ?		writel_be (val, regs) :		writel (val, regs);#else		writel (val, regs);#endif}#ifdef CONFIG_ARCH_LH7A404/* Marc Singer: at the time this code was written, the LH7A404 * had a problem reading the USB host registers.  This * implementation of the ohci_readl function performs the read * twice as a work-around. */#define ohci_readl(o,r)		(_ohci_readl(o,r),_ohci_readl(o,r))#define ohci_writel(o,v,r)	_ohci_writel(o,v,r)#else#define ohci_readl(o,r)		_ohci_readl(o,r)#define ohci_writel(o,v,r)	_ohci_writel(o,v,r)#endif/*-------------------------------------------------------------------------*//* cpu to ohci */static inline __hc16 cpu_to_hc16 (const struct ohci_hcd *ohci, const u16 x){	return big_endian_desc(ohci) ?		(__force __hc16)cpu_to_be16(x) :		(__force __hc16)cpu_to_le16(x);}static inline __hc16 cpu_to_hc16p (const struct ohci_hcd *ohci, const u16 *x){	return big_endian_desc(ohci) ?		cpu_to_be16p(x) :		cpu_to_le16p(x);}static inline __hc32 cpu_to_hc32 (const struct ohci_hcd *ohci, const u32 x){	return big_endian_desc(ohci) ?		(__force __hc32)cpu_to_be32(x) :		(__force __hc32)cpu_to_le32(x);}static inline __hc32 cpu_to_hc32p (const struct ohci_hcd *ohci, const u32 *x){	return big_endian_desc(ohci) ?		cpu_to_be32p(x) :		cpu_to_le32p(x);}/* ohci to cpu */static inline u16 hc16_to_cpu (const struct ohci_hcd *ohci, const __hc16 x){	return big_endian_desc(ohci) ?		be16_to_cpu((__force __be16)x) :		le16_to_cpu((__force __le16)x);}static inline u16 hc16_to_cpup (const struct ohci_hcd *ohci, const __hc16 *x){	return big_endian_desc(ohci) ?		be16_to_cpup((__force __be16 *)x) :		le16_to_cpup((__force __le16 *)x);}static inline u32 hc32_to_cpu (const struct ohci_hcd *ohci, const __hc32 x){	return big_endian_desc(ohci) ?		be32_to_cpu((__force __be32)x) :		le32_to_cpu((__force __le32)x);}static inline u32 hc32_to_cpup (const struct ohci_hcd *ohci, const __hc32 *x){	return big_endian_desc(ohci) ?		be32_to_cpup((__force __be32 *)x) :		le32_to_cpup((__force __le32 *)x);}/*-------------------------------------------------------------------------*//* HCCA frame number is 16 bits, but is accessed as 32 bits since not all * hardware handles 16 bit reads.  That creates a different confusion on * some big-endian SOC implementations.  Same thing happens with PSW access. * * FIXME: Deal with that as a runtime quirk when STB03xxx is ported over * to arch/powerpc */#ifdef CONFIG_STB03xxx#define OHCI_BE_FRAME_NO_SHIFT	16#else#define OHCI_BE_FRAME_NO_SHIFT	0#endifstatic inline u16 ohci_frame_no(const struct ohci_hcd *ohci){	u32 tmp;	if (big_endian_desc(ohci)) {		tmp = be32_to_cpup((__force __be32 *)&ohci->hcca->frame_no);		tmp >>= OHCI_BE_FRAME_NO_SHIFT;	} else		tmp = le32_to_cpup((__force __le32 *)&ohci->hcca->frame_no);	return (u16)tmp;}static inline __hc16 *ohci_hwPSWp(const struct ohci_hcd *ohci,                                 const struct td *td, int index){	return (__hc16 *)(big_endian_desc(ohci) ?			&td->hwPSW[index ^ 1] : &td->hwPSW[index]);}static inline u16 ohci_hwPSW(const struct ohci_hcd *ohci,                               const struct td *td, int index){	return hc16_to_cpup(ohci, ohci_hwPSWp(ohci, td, index));}/*-------------------------------------------------------------------------*/static inline void disable (struct ohci_hcd *ohci){	ohci_to_hcd(ohci)->state = HC_STATE_HALT;}#define	FI			0x2edf		/* 12000 bits per frame (-1) */#define	FSMP(fi)		(0x7fff & ((6 * ((fi) - 210)) / 7))#define	FIT			(1 << 31)#define LSTHRESH		0x628		/* lowspeed bit threshold */static inline void periodic_reinit (struct ohci_hcd *ohci){	u32	fi = ohci->fminterval & 0x03fff;	u32	fit = ohci_readl(ohci, &ohci->regs->fminterval) & FIT;	ohci_writel (ohci, (fit ^ FIT) | ohci->fminterval,						&ohci->regs->fminterval);	ohci_writel (ohci, ((9 * fi) / 10) & 0x3fff,						&ohci->regs->periodicstart);}/* AMD-756 (D2 rev) reports corrupt register contents in some cases. * The erratum (#4) description is incorrect.  AMD's workaround waits * till some bits (mostly reserved) are clear; ok for all revs. */#define read_roothub(hc, register, mask) ({ \	u32 temp = ohci_readl (hc, &hc->regs->roothub.register); \	if (temp == -1) \		disable (hc); \	else if (hc->flags & OHCI_QUIRK_AMD756) \		while (temp & mask) \			temp = ohci_readl (hc, &hc->regs->roothub.register); \	temp; })static inline u32 roothub_a (struct ohci_hcd *hc)	{ return read_roothub (hc, a, 0xfc0fe000); }static inline u32 roothub_b (struct ohci_hcd *hc)	{ return ohci_readl (hc, &hc->regs->roothub.b); }static inline u32 roothub_status (struct ohci_hcd *hc)	{ return ohci_readl (hc, &hc->regs->roothub.status); }static inline u32 roothub_portstatus (struct ohci_hcd *hc, int i)	{ return read_roothub (hc, portstatus [i], 0xffe0fce0); }

⌨️ 快捷键说明

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