struct usb_hcd >
来源:互联网 发布:三星电视怎么连接网络 编辑:程序博客网 时间:2024/06/05 12:43
20.2.1 USB主机驱动的整体结构
USB主机控制器有3种规格:OHCI (Open Host Controller Interface)、UHCI (Universal Host Controller Interface) 和EHCI (Enhanced Host Controller Interface)。OHCI驱动程序用来为非PC 系统上以及带有SiS和ALi芯片组的 PC 主板上的USB芯片提供支持。UHCI驱动程序多用来为大多数其他PC主板(包括 Intel和Via)上的USB芯片提供支持。EHCI由USB 2.0规范所提出,它兼容于OHCI 和UHCI。UHCI的硬件线路比OHCI简单,所以成本较低,但需要较复杂的驱动程序,CPU负荷稍重。本节将重点介绍嵌入式系统中常用的OHCI主机控制器驱动。
1.主机控制器驱动
在Linux内核中,用usb_hcd结构体描述USB主机控制器驱动,它包含USB主机控制器的“家务”信息、硬件资源、状态描述和用于操作主机控制器的hc_driver等,其定义如代码清单20.6所示。
代码清单20.6 usb_hcd结构体
1 struct usb_hcd2 {3 /* 管理“家务” */4 struct usb_bus self;5 const char *product_desc; /* 产品/厂商字符串 */6 char irq_descr[24]; /* 驱动 + 总线 # */7 8 struct timer_list rh_timer; /* 根Hub轮询 */9 struct urb *status_urb; /* 目前的状态urb */10 11 /* 硬件信息/状态 */12 const struct hc_driver *driver; /* 硬件特定的钩子函数 */13 14 /* 需要维护的标志 */15 unsigned long flags;16 #define HCD_FLAG_HW_ACCESSIBLE 0x0000000117 #define HCD_FLAG_SAW_IRQ 0x0000000218 19 unsigned rh_registered: 1; /* 根Hub注册? */20 21 /* 下一个标志的采用只是“权益之计”,当所有HCDs支持新的根Hub轮询机制后将移除 */22 unsigned uses_new_polling: 1;23 unsigned poll_rh: 1; /* 轮询根Hub状态? */24 unsigned poll_pending: 1; /* 状态已经改变? */25 26 int irq; /* 被分配的irq */27 void _ _iomem *regs; /* 设备内存和I/O */28 u64 rsrc_start; /* 内存和I/O资源开始位置 */29 u64 rsrc_len; /* 内存和I/O资源长度 */30 unsigned power_budget; /* mA, 0 = 无限制 */31 32 #define HCD_BUFFER_POOLS 433 struct dma_pool *pool[HCD_BUFFER_POOLS];34 35 int state;36 #define _ _ACTIVE 0x0137 #define _ _SUSPEND 0x0438 #define _ _TRANSIENT 0x8039 40 #define HC_STATE_HALT 041 #define HC_STATE_RUNNING (_ _ACTIVE)42 #define HC_STATE_QUIESCING (_ _SUSPEND|_ _TRANSIENT|_ _ACTIVE)43 #define HC_STATE_RESUMING (_ _SUSPEND|_ _TRANSIENT)44 #define HC_STATE_SUSPENDED (_ _SUSPEND)45 46 #define HC_IS_RUNNING(state) ((state) & _ _ACTIVE)47 #define HC_IS_SUSPENDED(state) ((state) & _ _SUSPEND)48 /* 主机控制器驱动的私有数据 */49 unsigned long hcd_priv[0]_ _attribute_ _((aligned(sizeof(unsigned long))));50 };
usb_hcd中的hc_driver成员非常重要,它包含具体的用于操作主机控制器的钩子函数,其定义如代码清单20.7所示。
代码清单20.7 hc_driver结构体
1 struct hc_driver2 {3 const char *description; /* "ehci-hcd" 等 */4 const char *product_desc; /* 产品/厂商字符串 */5 size_t hcd_priv_size; /* 私有数据的大小 */6 7 /* 中断处理函数 */8 irqreturn_t(*irq)(struct usb_hcd *hcd, struct pt_regs *regs);9 10 int flags;11 #define HCD_MEMORY 0x0001 /* HC寄存器使用的内存和I/O */12 #define HCD_USB11 0x0010 /* USB 1.1 */13 #define HCD_USB2 0x0020 /* USB 2.0 */14 15 /* 被调用以初始化HCD和根Hub */16 int(*reset)(struct usb_hcd *hcd);17 int(*start)(struct usb_hcd *hcd);18 19 /* 挂起Hub后,进入D3(etc)前被调用 */20 int(*suspend)(struct usb_hcd *hcd, pm_message_t message);21 22 /* 在进入D0(etc)后,恢复Hub前调用 */23 int(*resume)(struct usb_hcd *hcd);24 25 /* 使HCD停止写内存和进行I/O操作 */26 void(*stop)(struct usb_hcd *hcd);27 28 /* 返回目前的帧数 */29 int(*get_frame_number)(struct usb_hcd *hcd);30 31 /* 管理I/O请求和设备状态 */32 int(*urb_enqueue)(struct usb_hcd *hcd, struct usb_host_endpoint *ep, struct33 urb *urb, gfp_t mem_flags);34 int(*urb_dequeue)(struct usb_hcd *hcd, struct urb *urb);35 36 /* 释放endpoint资源 */37 void(*endpoint_disable)(struct usb_hcd *hcd, struct usb_host_endpoint *ep);38 39 /* 根Hub支持 */40 int(*hub_status_data)(struct usb_hcd *hcd, char *buf);41 int(*hub_control)(struct usb_hcd *hcd, u16 typeReq, u16 wValue, u16 wIndex,42 char *buf, u16 wLength);43 int(*bus_suspend)(struct usb_hcd*);44 int(*bus_resume)(struct usb_hcd*);45 int(*start_port_reset)(struct usb_hcd *, unsigned port_num);46 void(*hub_irq_enable)(struct usb_hcd*);47 };
在Linux内核中,使用如下函数来创建HCD:
struct usb_hcd *usb_create_hcd (const struct hc_driver *driver, struct device *dev, char *bus_name);
如下函数被用来增加和移除HCD:
int usb_add_hcd(struct usb_hcd *hcd, unsigned int irqnum, unsigned long irqflags);void usb_remove_hcd(struct usb_hcd *hcd);
2.OHCI主机控制器驱动
OHCI HCD驱动属于HCD驱动的实例,它定义了一个ohci_hcd结构体,作为代码清单20.6给出的usb_hcd结构体的私有数据,这个结构体的定义如代码清单20.8所示。
代码清单20.8 ohci_hcd结构体
1 struct ohci_hcd2 {3 spinlock_t lock;4 5 /* 与主机控制器通信的I/O内存(DMA一致) */6 struct ohci_regs _ _iomem *regs;7 8 /* 与主机控制器通信的主存(DMA一致) */9 struct ohci_hcca *hcca;10 dma_addr_t hcca_dma;11 12 struct ed *ed_rm_list; /* 将被移除 */13 struct ed *ed_bulktail; /* 批量队列尾 */14 struct ed *ed_controltail; /* 控制队列尾 */15 struct ed *periodic[NUM_INTS]; /* int_table“影子” */16 17 /* OTG控制器和收发器需要软件交互,其他的外部收发器应该是软件透明的 */18 struct otg_transceiver *transceiver;19 20 /* 队列数据的内存管理 */21 struct dma_pool *td_cache;22 struct dma_pool *ed_cache;23 struct td *td_hash[TD_HASH_SIZE];24 struct list_head pending;25 26 /* driver状态 */27 int num_ports;28 int load[NUM_INTS];29 u32 hc_control; /* 主机控制器控制寄存器的复制 */30 unsigned long next_statechange; /* 挂起/恢复 */31 u32 fminterval; /* 被保存的寄存器 */32 33 struct notifier_block reboot_notifier;34 unsigned long flags;35 };
使用如下内联函数可实现usb_hcd和ohci_hcd的相互转换:
struct ohci_hcd *hcd_to_ohci (struct usb_hcd *hcd);struct usb_hcd *ohci_to_hcd (const struct ohci_hcd *ohci);
从usb_hcd得到ohci_hcd只是取得“私有”数据,而从ohci_hcd得到usb_hcd则是通过container_of()从结构体成员获得结构体指针。
使用如下函数可初始化OHCI主机控制器:
int ohci_init (struct ohci_hcd *ohci);
如下函数分别用于开启、停止及复位OHCI控制器:
int ohci_run (struct ohci_hcd *ohci);void ohci_stop (struct usb_hcd *hcd);void ohci_usb_reset (struct ohci_hcd *ohci);
OHCI主机控制器驱动的主机工作仍然是实现代码清单20.7给出的hc_driver结构体中的成员函数。
- struct usb_hcd >
- struct usb_hcd
- Struct
- struct
- struct
- struct
- Struct
- struct
- struct
- struct
- struct
- struct
- struct
- struct
- struct
- struct
- struct
- struct
- 浅谈对待Exception
- 言不顺,则事不成
- dmalloc 原文 翻译整理(1)
- 士大夫士大夫
- 基础算法--递归(二)
- struct usb_hcd >
- 数据库设计技巧
- Handler详解
- TIBCO RV在市场数据系统(MDS, Market Data System)里的运用
- modem串口解析
- i miss her
- linux命令
- ui设计
- 回溯法介绍