赞
踩
一直都是使用Usb 驱动程序,从来没有好好研读过。之前项目中碰到usb相关的也是usb register配置一下就好了。
至于Usb驱动如何工作,让我们慢慢来揭开它神秘的面纱。
对usb ehci 驱动的基本框架理解得益与understanding linux usb ehci device driver。这里还是借用这张经典的usb驱动框图,明确下EHCI在整个USB驱动中所处的地位。
EHCI驱动: Linux usb host controller driver(HCD )
usb host controller驱动,负责将usb_core发来的URB传输请求转化成HC可识别的格式并启动HC传输,直至完成传输. 整个usb subsystem只有该驱动直接操作硬件寄存器.该层也支持多种不同的host controller driver,比如UHCI,OHCI等.
在整个HCD的解读之前,需要了解ehci-specification-for-usb.pdf.这里跳过规范相关说明,用到时会加以引用。或请认真阅读understanding linux usb ehci device driver(1),是对EHCI规范的部分解读。
kernel/linux-3.10.y/drivers/usb$ ls -al
drwxr-xr-x 20 karry karry 4096 9月 7 14:46 .
drwxr-xr-x 117 karry karry 4096 9月 7 14:46 ..
drwxr-xr-x 2 karry karry 4096 9月 7 14:45 core
drwxr-xr-x 3 karry karry 4096 9月 7 14:57 gadget
drwxr-xr-x 3 karry karry 4096 9月 7 14:45 host
drwxr-xr-x 2 karry karry 4096 9月 7 14:46 storage
-rw-r--r-- 1 karry karry 2462 10月19 2015 usb-common.c
-rw-rw-r-- 1 karry karry 3372 10月19 2015 usb-common.o
-rw-rw-r-- 1 karry karry 33959 10月19 2015 .usb-common.o.cmd
usb host controller driver 只需关注host目录,结合core目录即可。
从数据结构来看,需要实现usbcore中struct hc_driver定义的接口。
struct hc_driver {
const char *description; /* "ehci-hcd" etc */
const char *product_desc; /* product/vendor string */
size_t hcd_priv_size; /* size of private data */
/* irq handler */
irqreturn_t (*irq) (struct usb_hcd *hcd);
int flags;
#define HCD_MEMORY0x0001/* HC regs use memory (else I/O) */
#define HCD_LOCAL_MEM0x0002/* HC needs local memory */
#define HCD_SHARED0x0004/* Two (or more) usb_hcds share HW */
#define HCD_USB110x0010/* USB 1.1 */
#define HCD_USB20x0020/* USB 2.0 */
#define HCD_USB30x0040/* USB 3.0 */
#define HCD_MASK0x0070
/* called to init HCD and root hub */
int (*reset) (struct usb_hcd *hcd);
int (*start) (struct usb_hcd *hcd);
/* NOTE: these suspend/resume calls relate to the HC as
* a whole, not just the root hub; they're for PCI bus glue.
*/
/* called after suspending the hub, before entering D3 etc */
int (*pci_suspend)(struct usb_hcd *hcd, bool do_wakeup);
/* called after entering D0 (etc), before resuming the hub */
int (*pci_resume)(struct usb_hcd *hcd, bool hibernated);
/* cleanly make HCD stop writing memory and doing I/O */
void (*stop) (struct usb_hcd *hcd);
/* shutdown HCD */
void (*shutdown) (struct usb_hcd *hcd);
/* return current frame number */
int (*get_frame_number) (struct usb_hcd *hcd);
/* manage i/o requests, device state */
int (*urb_enqueue)(struct usb_hcd *hcd,
struct urb *urb, gfp_t mem_flags);
int (*urb_dequeue)(struct usb_hcd *hcd,
struct urb *urb, int status);
/*
* (optional) these hooks allow an HCD to override the default DMA
* mapping and unmapping routines. In general, they shouldn't be
* necessary unless the host controller has special DMA requirements,
* such as alignment contraints. If these are not specified, the
* general usb_hcd_(un)?map_urb_for_dma functions will be used instead
* (and it may be a good idea to call these functions in your HCD
* implementation)
*/
int (*map_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb,
gfp_t mem_flags);
void (*unmap_urb_for_dma)(struct usb_hcd *hcd, struct urb *urb);
/* hw synch, freeing endpoint resources that urb_dequeue can't */
void (*endpoint_disable)(struct usb_hcd *hcd,
struct usb_host_endpoint *ep);
/* (optional) reset any endpoint state such as sequence number
and current window */
void (*endpoint_reset)(struct usb_hcd *hcd,
struct usb_host_endpoint *ep);
/* root hub support */
int (*hub_status_data) (struct usb_hcd *hcd, char *buf);
int (*hub_control) (struct usb_hcd *hcd,
u16 typeReq, u16 wValue, u16 wIndex,
char *buf, u16 wLength);
int (*bus_suspend)(struct usb_hcd *);
int (*bus_resume)(struct usb_hcd *);
int (*start_port_reset)(struct usb_hcd *, unsigned port_num);
/* force handover of high-speed port to full-speed companion */
void (*relinquish_port)(struct usb_hcd *, int);
/* has a port been handed over to a companion? */
int (*port_handed_over)(struct usb_hcd *, int);
/* CLEAR_TT_BUFFER completion callback */
void (*clear_tt_buffer_complete)(struct usb_hcd *,
struct usb_host_endpoint *);
/* xHCI specific functions */
/* Called by usb_alloc_dev to alloc HC device structures */
int (*alloc_dev)(struct usb_hcd *, struct usb_device *);
/* Called by usb_disconnect to free HC dev
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。