第四十二篇:U-BOOT-USB 代码注释

最近都在看U-BOOT的代码


首先,归类一下

U-BOOT中的USB代码主要分为以下几种:


1. 与具体的XHC相关的代码

比如XHCI, UHCI, OHCI, EHCI

XHCI是最新的USB HOST SPEC

EHCI针对USB2.0

U/OHCI针对USB1.0/1.1


我的精力主要在XHCI上面

相关的代码包括:

\drivers\usb\host下面的

xhci.c, xhci.h, xhci-mem.c, xhci-ring.c xhci-pci.c


xhci.c/h

针对于xch SPEC硬件层面的操作,如寄存器, 相对于XHC SPEC第五章register interface, 以及部分与command interface相关的操作,如address device, configure ep


xhci-mem.c

针对XHC SPEC中的数据结构的管理,如SEGMENT, RING, CONTEXT (SLOT, EP, INPUT CONTROL)


xhci-ring.c

针对XHC SPEC中RING的操作, 如ring中元素trb的ENQUQUE,event ring中EVENT TRB的CHECK


xhci-pci.c

针对XHC是通过PCI/PCIE连接到系统中的方案,主要是取得系统给该XHC分配的BAR0地址


针对USB2.0/3.0/3.1 SEPC相关的代码:

\common\usb.c

\include\usb.h

基本上是定义了usb所需的内容与操作,如各种standard request


针对不同USB CLASS的相关代码:

\common

usb_hub.c, USB HUB类代码

usb_kbd.c, USB HID键盘类代码

usb_storage.c, USB MASS STORAGE类代码


用户操作接口代码:

\cmd\usb.c

代码提供命令行函数,让用户使用,如:usb start命令

执行该命令,做了host 初始化,设备的侦测,设备的枚举,等一系列的操作



+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

这里需要说明 的是:

每个USB HOST都自己的root hub

root hub有一个或多个root hub port

在物理上,对应的是各自的root hub port register array


xhc 的如下:

struct xhci_hcor_port_regs {
volatile uint32_t or_portsc;
volatile uint32_t or_portpmsc;
volatile uint32_t or_portli;
volatile uint32_t or_porthlpmc;
};


但在U-BOOT代码中(LINUX也是相同的,应该说U-BOOT是仿LINUX的),软件将这个root hub也当作一个USB HUB DEVICE来处理。

但为了区分,所以有了:

xhci_submit_root (xhci.c)这个函数


struct xhci_ctrl数据结构中,有一个成员:

rootdev


名字取得比较让人不知道想表达什么,起什么作用

事实上,它是记录了root hub的address


过程如下:

先弄一个usb device数据结构的实例,用来表示该root hub

其中,devnum被初始化为1

usb_dev[dev_index].devnum = dev_index + 1;


在usb_set_address函数中

对于该usb device (root hub usb device)


int usb_control_msg(struct usb_device *dev, unsigned int pipe,
unsigned char request, unsigned char requesttype,
unsigned short value, unsigned short index,
void *data, unsigned short size, int timeout)


static int usb_set_address(struct usb_device *dev)
{
int res;


debug("set address %d\n", dev->devnum);
res = usb_control_msg(dev, usb_snddefctrl(dev),
USB_REQ_SET_ADDRESS, 0,
(dev->devnum), 0,
NULL, 0, USB_CNTL_TIMEOUT);
return res;
}


请注意第五个参数:

(dev->devnum), unsigned short value



case USB_REQ_SET_ADDRESS | (USB_RECIP_DEVICE << 8):
debug("USB_REQ_SET_ADDRESS\n");
ctrl->rootdev = le16_to_cpu(req->value);
break;


将rootdev设置成了devnum


#define create_pipe(dev,endpoint) \
(((dev)->devnum << 8) | ((endpoint) << 15) | \
(dev)->maxpacketsize)


如果devnum与rootdev相同,则调用xhci_submit_root 


感觉将简单的事情复杂化了,有么有?


+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值