linux usb ehci 驱动解读(一)

一直都是使用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 1019  2015 usb-common.c

-rw-rw-r--   1 karry karry   3372 1019  2015 usb-common.o

-rw-rw-r--   1 karry karry  33959 1019  2015 .usb-common.o.cmd

usb host controller driver 只需关注host目录,结合core目录即可。

从数据结构来看,需要实现usbcorestruct 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

  • 1
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值