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

📄 usb-ohci.h

📁 有关于USB的一些主机端驱动
💻 H
📖 第 1 页 / 共 3 页
字号:
#define OHCI_INTR_FNO	(1 << 5)	/* frame number overflow */
#define OHCI_INTR_RHSC	(1 << 6)	/* root hub status change */
#define OHCI_INTR_OC	(1 << 30)	/* ownership change .           OMAP1510 usb host controller does not implement ownership
                                                                                                           chang interrupts*/
#define OHCI_INTR_MIE	(1 << 31)	/* master interrupt enable */



/* Virtual Root HUB */
struct virt_root_hub {
	int devnum; /* Address of Root Hub endpoint */ 
	void * urb;
	void * int_addr;
	int send;
	int interval;
//	struct timer_list rh_int_timer;
};


/* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */
 
/* 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


/* OHCI ROOT HUB REGISTER MASKS */
 
/* roothub.portstatus [i] bits */
#define RH_PS_CCS		0x00000001   	/* current connect status */
#define RH_PS_PES		0x00000002   	/* port enable status*/
#define RH_PS_PSS		0x00000004   	/* port suspend status */
#define RH_PS_POCI		0x00000008   	/* port over current indicator */
#define RH_PS_PRS		0x00000010  	/* port reset status */
#define RH_PS_PPS		0x00000100   	/* port power status,     OMAP1510 does not provide signals from the USB Host controller
                                                                                                   to control external port power,so if required,USB host port power 
                                                                                                   control signals must be controlled through other means*/
#define RH_PS_LSDA		0x00000200   /* low speed device attached */
#define RH_PS_CSC		0x00010000 	/* connect status change */
#define RH_PS_PESC		0x00020000   	/* port enable status change */
#define RH_PS_PSSC		0x00040000   	/* port suspend status change */
#define RH_PS_OCIC		0x00080000   	/* over current indicator change */
#define RH_PS_PRSC		0x00100000   	/* port reset status change */

/* roothub.status bits */
#define RH_HS_LPS	     0x00000001	/* local power status 
                                                                           OMAP1510 does not provide signals from the USB host controller to external VBUS 
                                                                           swithching circuitry,this bit has no effect, this biy always reads as 0*/
#define RH_HS_OCI	     0x00000002	/* over current indicator 
                                                                           OMAP1510 does not provide signals for external hardware to report overcurrent status
                                                                           to the SUB host controller,this bit is always 0*/
#define RH_HS_DRWE	     0x00008000	/* device remote wakeup enable */
#define RH_HS_LPSC	     0x00010000	/* local power status change ,
                                                                           OMAP1510 root hub does not support the local power status feature*/
#define RH_HS_OCIC	     0x00020000	/* over current indicator change */
#define RH_HS_CRWE	     0x80000000	/* clear remote wakeup enable */

/* roothub.b masks */
#define RH_B_DR		0x0000ffff		/* device removable flags */
#define RH_B_PPCM	0xffff0000		/* port power control mask */

/* roothub.a masks */
#define	RH_A_NDP		(0xff << 0)	/* number of downstream ports */
#define	RH_A_PSM		(1 << 8)		/* power switching mode 
                                                             		OMAP1510 does not provide signals from the USB host controller to control external VBUS 
                                                             		swithching ,this bit defaults to 0*/
#define	RH_A_NPS		(1 << 9)		/* no power switching 
                                                                       OMAP1510 does not provide connections from the USB host controller to control external
                                                                       VBUS switching ,this bit default to 1*/
#define	RH_A_DT		(1 << 10)	/* device type (mbz) ,this bit is always 0,which indicates that the USB host controller implement
                                                                                                is not a compound device*/
#define	RH_A_OCPM		(1 << 11)	/* over current protection mode
                                                                       OMAP1510 does not provide overcurrent protection input signals,so it has no effect*/
#define	RH_A_NOCP		(1 << 12)	/* no over current protection 
                                                                       OMAP1510 does not provide overcurrent protection,so it defaults to 1*/
#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[1];	// 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 */
	unsigned long 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;
	
	struct omap_dev *ohci_dev;		//added by Changming HUANG
	/* PCI device handle, settings, ... */	
/*	struct pci_dev	*ohci_dev;			//modified by Changming HUANG
	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)
#if 0
/* hcd */
/* 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, 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);
#endif
/*-------------------------------------------------------------------------*/

#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


struct omap_driver{
//	struct device_driver drv;
	unsigned int devid;
	char *name;
	int (*probe)(struct omap_dev *);
	void (*remove)(struct omap_dev *);
	int (*suspend)(struct omap_dev *);
	int (*resume)(struct omap_dev*);
};

 struct omap_dev{
//	struct device	dev;
	unsigned int	devid;
//	struct resource res;
	void *driver_data;
	void *mapbase;
	unsigned int skpcr_mask;
//	unsigned int irq[6];
	struct omap_driver *driver;
	unsigned int irq;
	ohci_t *ohci;
//	u64 dma_mask;
 };




#if 0
/* 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 int
hash_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 int
hash_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 int
hash_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 void
hash_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 void
hash_free_ed (struct ohci * hc, struct ed * ed)
{
	hash_free_ed_td (&(hc->ed_hash[ED_HASH_FUNC(ed->dma)]), ed);
}

static inline void
hash_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) {
		pci_pool_destroy (ohci->td_cache);
		ohci->td_cache = 0;
	}
	if (ohci->dev_cache) {
		pci_pool_destroy (ohci->dev_cache);
		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 void
td_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 void
dev_free (struct ohci *hc, struct ohci_device *dev)
{
	pci_pool_free (hc->dev_cache, dev, dev->dma);
}
#endif

⌨️ 快捷键说明

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