USB主机控制器有3种类型:
q OHCI:英文全称是Open Host Controller Interface,是用于SiS和Ali芯片组的USB控制器。
q UHCI:英文全称是Universal Host Controller Interface,用于Intel和AMD芯片组的USB控制器。UHCI类型的控制器比OHCI控制器硬件结构要简单,但是需要额外的驱动支持,因此从理论上说速度要慢。
q EHCI:是USB 2.0规范提出的一种控制器标准,可以兼容UHCI和OHCI。
Linux内核使用usb_hcd结构描述USB主机控制器驱动。usb_hcd结构描述了USB主机控制器的硬件信息、状态和操作函数,定义如下:
struct usb_hcd { /* usb_bus.hcpriv points to this */
/*
* housekeeping // 控制器基本信息
*/
struct usb_bus self; /* hcd is-a bus */
const char *product_desc; /* product/vendor string */ // 厂商名称字符串
char irq_descr[24]; /* driver + bus # */ // 驱动和总线类型
struct timer_list rh_timer; /* drives root-hub polling */ // 根hub轮询时间间隔
struct urb *status_urb; /* the current status urb */ // 当前urb状态
/*
* hardware info/state // 硬件信息和状态
*/
const struct hc_driver *driver; /* hw-specific hooks */ // 控制器驱动使用的回调函数
/* Flags that need to be manipulated atomically */
unsigned long flags;
#define HCD_FLAG_HW_ACCESSIBLE 0x00000001
#define HCD_FLAG_SAW_IRQ 0x00000002
unsigned rh_registered:1;/* is root hub registered? */ // 是否注册根hub
/* The next flag is a stopgap, to be removed when all the HCDs
* support the new root-hub polling mechanism. */
unsigned uses_new_polling:1; // 是否允许轮询根hub状态
unsigned poll_rh:1; /* poll for rh status? */
unsigned poll_pending:1; /* status has changed? */ // 状态是否改变
int irq; /* irq allocated */ // 控制器的中断请求号
void __iomem *regs; /* device memory/io */ // 控制器使用的内存和I/O
u64 rsrc_start; /* memory/io resource start */ // 控制器使用的内存和I/O起始地址
u64 rsrc_len; /* memory/io resource length */ // 控制器使用的内存和I/O资源长度
unsigned power_budget; /* in mA, 0 = no limit */
#define HCD_BUFFER_POOLS 4
struct dma_pool *pool [HCD_BUFFER_POOLS];
int state;
# define __ACTIVE 0x01
# define __SUSPEND 0x04
# define __TRANSIENT 0x80
# define HC_STATE_HALT 0
# define HC_STATE_RUNNING (__ACTIVE)
# define HC_STATE_QUIESCING (__SUSPEND|__TRANSIENT|__ACTIVE)
# define HC_STATE_RESUMING (__SUSPEND|__TRANSIENT)
# define HC_STATE_SUSPENDED (__SUSPEND)
#define HC_IS_RUNNING(state) ((state) & __ACTIVE)
#define HC_IS_SUSPENDED(state) ((state) & __SUSPEND)
/* more shared queuing code would be good; it should support
* smarter scheduling, handle transaction translators, etc;
* input size of periodic table to an interrupt scheduler.
* (ohci 32, uhci 1024, ehci 256/512/1024).
*/
/* The HC driver's private data is stored at the end of
* this structure.
*/
unsigned long hcd_priv[0]
__attribute__ ((aligned (sizeof(unsigned long))));
};
usb_hcd结构可以理解为一个通用的USB控制器描述结构。OHCI主机控制器是usb_hcd结构的具体实现,内核使用ohci_hcd结构描述OHCI主机控制器,定义如下:
struct ohci_hcd {
spinlock_t lock;
/*
* I/O memory used to communicate with the HC (dma-consistent) // 用于HC通信的I/O内存地址
*/
struct ohci_regs __iomem *regs;
/*
* main memory used to communicate with the HC (dma-consistent). // 用于HC通行的主内存地址
* hcd adds to schedule for a live hc any time, but removals finish
* only at the start of the next frame.
*/
struct ohci_hcca *hcca;
dma_addr_t hcca_dma;
struct ed *ed_rm_list; /* to be removed */ // 将被移除列表
struct ed *ed_bulktail; /* last in bulk list */ // 列表最后一项
struct ed *ed_controltail; /* last in ctrl list */ // 控制列表最后一项
struct ed *periodic [NUM_INTS]; /* shadow int_table */
/*
* OTG controllers and transceivers need software interaction;
* other external transceivers should be software-transparent
*/
struct otg_transceiver *transceiver;
/*
* memory management for queue data structures // 内存管理队列使用的数据结构
*/
struct dma_pool *td_cache;
struct dma_pool *ed_cache;
struct td *td_hash [TD_HASH_SIZE];
struct list_head pending;
/*
* driver state
*/
int num_ports;
int load [NUM_INTS];
u32 hc_control; /* copy of hc control reg */// HC控制寄存器复制
unsigned long next_statechange; /* suspend/resume */ // 挂起/恢复
u32 fminterval; /* saved register */ // 保存的寄存器
struct notifier_block reboot_notifier;
unsigned long flags; /* for HC bugs */
/* 以下是各厂家芯片ID定义 */
#define OHCI_QUIRK_AMD756 0x01 /* erratum #4 */
#define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */
#define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */
#define OHCI_BIG_ENDIAN 0x08 /* big endian HC */
#define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq ZFMicro chipset*/
// 芯片的初始化逻辑里也同样会有怪异的Bug
};
OHCI主机控制器是嵌入式系统最常用的一种USB主机控制器。