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

📄 usb-ohci.h

📁 基于S3CEB2410平台LINUX操作系统下 USB驱动源代码
💻 H
📖 第 1 页 / 共 2 页
字号:
#define	RH_A_NPS	(1 << 9)		/* no power switching */#define	RH_A_DT		(1 << 10)		/* device type (mbz) */#define	RH_A_OCPM	(1 << 11)		/* over current protection mode */#define	RH_A_NOCP	(1 << 12)		/* no over current protection */#define	RH_A_POTPGT	(0xff << 24)		/* power on to power good time *//* 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;	wait_queue_head_t * wait;	td_t * td[0];	// list pointer to all corresponding TDs associated with this request} urb_priv_t;#define URB_DEL 1/* Hash struct used for TD/ED hashing */struct hash_t {	void		*virt;	dma_addr_t	dma;	struct hash_t	*next; // chaining for collision cases};/* List of TD/ED hash entries */struct hash_list_t {	struct hash_t	*head;	struct hash_t	*tail;};#define TD_HASH_SIZE    64    /* power'o'two */#define ED_HASH_SIZE    64    /* power'o'two */#define TD_HASH_FUNC(td_dma) ((td_dma ^ (td_dma >> 5)) % TD_HASH_SIZE)#define ED_HASH_FUNC(ed_dma) ((ed_dma ^ (ed_dma >> 5)) % ED_HASH_SIZE)/* * This is the full ohci controller description * * Note how the "proper" USB information is just * a subset of what the full implementation needs. (Linus) */typedef struct ohci {	struct ohci_hcca *hcca;		/* hcca */	dma_addr_t hcca_dma;	int irq;	int disabled;			/* e.g. got a UE, we're hung */	int sleeping;	atomic_t resume_count;		/* defending against multiple resumes */	unsigned long flags;		/* for HC bugs */#define	OHCI_QUIRK_AMD756	0x01		/* erratum #4 */	struct ohci_regs * regs;	/* OHCI controller's memory */	struct list_head ohci_hcd_list;	/* list of all ohci_hcd */	struct ohci * next; 		// chain of ohci device contexts	struct list_head timeout_list;	// 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 balancing)*/	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;	__u32 hc_control;		/* copy of the hc control reg */	struct usb_bus * bus;    	struct usb_device * dev[128];	struct virt_root_hub rh;	/* PCI device handle, settings, ... */	struct pci_dev	*ohci_dev;	const char	*slot_name;	u8		pci_latency;	struct pci_pool	*td_cache;	struct pci_pool	*dev_cache;	struct hash_list_t	td_hash[TD_HASH_SIZE];	struct hash_list_t	ed_hash[ED_HASH_SIZE];} ohci_t;#define NUM_EDS 32		/* num of preallocated endpoint descriptors */struct ohci_device {	ed_t 	ed[NUM_EDS];	dma_addr_t dma;	int ed_cnt;	wait_queue_head_t * wait;};// #define ohci_to_usb(ohci)	((ohci)->usb)#define usb_to_ohci(usb)	((struct ohci_device *)(usb)->hcpriv)#ifndef OHCI_HW_DRIVER/* hcd *//* endpoint */static int ep_link(ohci_t * ohci, ed_t * edi);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, int mem_flags);static void ep_rm_ed(struct usb_device * usb_dev, ed_t * ed);/* td */static void td_fill(ohci_t * ohci, unsigned int info, dma_addr_t data, int len, urb_t * urb, 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);/*-------------------------------------------------------------------------*/#define ALLOC_FLAGS (in_interrupt () ? GFP_ATOMIC : GFP_KERNEL)#ifdef DEBUG#	define OHCI_MEM_FLAGS	SLAB_POISON#else#	define OHCI_MEM_FLAGS	0#endif #ifndef CONFIG_PCI//#	error "usb-ohci currently requires PCI-based controllers"	/* to support non-PCI OHCIs, you need custom bus/mem/... glue */#endif/* Recover a TD/ED using its collision chain */static inline void *dma_to_ed_td (struct hash_list_t * entry, dma_addr_t dma){	struct hash_t * scan = entry->head;	while (scan && scan->dma != dma)		scan = scan->next;	if (!scan)		BUG();	return scan->virt;}static inline struct ed *dma_to_ed (struct ohci * hc, dma_addr_t ed_dma){	return (struct ed *) dma_to_ed_td(&(hc->ed_hash[ED_HASH_FUNC(ed_dma)]),				      ed_dma);}static inline struct td *dma_to_td (struct ohci * hc, dma_addr_t td_dma){	return (struct td *) dma_to_ed_td(&(hc->td_hash[TD_HASH_FUNC(td_dma)]),				      td_dma);}/* Add a hash entry for a TD/ED; return true on success */static inline inthash_add_ed_td(struct hash_list_t * entry, void * virt, dma_addr_t dma){	struct hash_t * scan;		scan = (struct hash_t *)kmalloc(sizeof(struct hash_t), ALLOC_FLAGS);	if (!scan)		return 0;		if (!entry->tail) {		entry->head = entry->tail = scan;	} else {		entry->tail->next = scan;		entry->tail = scan;	}		scan->virt = virt;	scan->dma = dma;	scan->next = NULL;	return 1;}static inline inthash_add_ed (struct ohci * hc, struct ed * ed){	return hash_add_ed_td (&(hc->ed_hash[ED_HASH_FUNC(ed->dma)]),			ed, ed->dma);}static inline inthash_add_td (struct ohci * hc, struct td * td){	return hash_add_ed_td (&(hc->td_hash[TD_HASH_FUNC(td->td_dma)]),			td, td->td_dma);}static inline voidhash_free_ed_td (struct hash_list_t * entry, void * virt){	struct hash_t *scan, *prev;	scan = prev = entry->head;	// Find and unlink hash entry	while (scan && scan->virt != virt) {		prev = scan;		scan = scan->next;	}	if (scan) {		if (scan == entry->head) {			if (entry->head == entry->tail)				entry->head = entry->tail = NULL;			else				entry->head = scan->next;		} else if (scan == entry->tail) {			entry->tail = prev;			prev->next = NULL;		} else			prev->next = scan->next;		kfree(scan);	}}static inline voidhash_free_ed (struct ohci * hc, struct ed * ed){	hash_free_ed_td (&(hc->ed_hash[ED_HASH_FUNC(ed->dma)]), ed);}static inline voidhash_free_td (struct ohci * hc, struct td * td){	hash_free_ed_td (&(hc->td_hash[TD_HASH_FUNC(td->td_dma)]), td);}static int ohci_mem_init (struct ohci *ohci){	ohci->td_cache = pci_pool_create ("ohci_td", ohci->ohci_dev,		sizeof (struct td),		32 /* byte alignment */,		0 /* no page-crossing issues */,		GFP_KERNEL | OHCI_MEM_FLAGS);	if (!ohci->td_cache)		return -ENOMEM;	ohci->dev_cache = pci_pool_create ("ohci_dev", ohci->ohci_dev,		sizeof (struct ohci_device),		16 /* byte alignment */,		0 /* no page-crossing issues */,		GFP_KERNEL | OHCI_MEM_FLAGS);	if (!ohci->dev_cache)		return -ENOMEM;	return 0;}static void ohci_mem_cleanup (struct ohci *ohci){	if (ohci->td_cache) {		printk(__FUNCTION__"(%d)\n", __LINE__);		pci_pool_destroy (ohci->td_cache);		printk(__FUNCTION__"(%d)\n", __LINE__);		ohci->td_cache = 0;	}	if (ohci->dev_cache) {		printk(__FUNCTION__"(%d)\n", __LINE__);		pci_pool_destroy (ohci->dev_cache);		printk(__FUNCTION__"(%d)\n", __LINE__);		ohci->dev_cache = 0;	}}/* TDs ... */static inline struct td *td_alloc (struct ohci *hc, int mem_flags){	dma_addr_t	dma;	struct td	*td;	td = pci_pool_alloc (hc->td_cache, mem_flags, &dma);	if (td) {		td->td_dma = dma;		/* hash it for later reverse mapping */		if (!hash_add_td (hc, td)) {			pci_pool_free (hc->td_cache, td, dma);			return NULL;		}	}	return td;}static inline voidtd_free (struct ohci *hc, struct td *td){	hash_free_td (hc, td);	pci_pool_free (hc->td_cache, td, td->td_dma);}/* DEV + EDs ... only the EDs need to be consistent */static inline struct ohci_device *dev_alloc (struct ohci *hc, int mem_flags){	dma_addr_t		dma;	struct ohci_device	*dev;	int			i, offset;	dev = pci_pool_alloc (hc->dev_cache, mem_flags, &dma);	if (dev) {		memset (dev, 0, sizeof (*dev));		dev->dma = dma;		offset = ((char *)&dev->ed) - ((char *)dev);		for (i = 0; i < NUM_EDS; i++, offset += sizeof dev->ed [0])			dev->ed [i].dma = dma + offset;		/* add to hashtable if used */	}	return dev;}static inline voiddev_free (struct ohci *hc, struct ohci_device *dev){	pci_pool_free (hc->dev_cache, dev, dev->dma);}#endif // not OHCI_HW_DRIVER#endif // USB_OHCI_H

⌨️ 快捷键说明

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