Linux那些事儿 之 戏说USB(14)端点

端点是USB数据传输的终点。看看它在内核里的定义

include/linux/usb.h

struct usb_host_endpoint {
	struct usb_endpoint_descriptor		desc;
	struct usb_ss_ep_comp_descriptor	ss_ep_comp;
	struct list_head		urb_list;
	void				*hcpriv;
	struct ep_device		*ep_dev;	/* For sysfs info */

	unsigned char *extra;   /* Extra descriptors */
	int extralen;
	int enabled;
	int streams;
};

2行,desc,端点描述符,四大描述符的第二个隆重登场了。它也在 include/uapi/linux/usb/ch9.h 里定义
/* USB_DT_ENDPOINT: Endpoint descriptor */
struct usb_endpoint_descriptor {
	__u8  bLength;
	__u8  bDescriptorType;

	__u8  bEndpointAddress;
	__u8  bmAttributes;
	__le16 wMaxPacketSize;
	__u8  bInterval;

	/* NOTE:  these two are _only_ in audio endpoints. */
	/* use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof. */
	__u8  bRefresh;
	__u8  bSynchAddress;
} __attribute__ ((packed));

#define USB_DT_ENDPOINT_SIZE		7
#define USB_DT_ENDPOINT_AUDIO_SIZE	9	/* Audio extension */
这个结构与spec Table 9.13是一一对应的,0号端点仍然保持着它特殊的地位,它没有自己的端点描述符。
bLength,描述符的字节长度,数一下,前边儿有7个(__u8算一个,__le16算两个),后边儿又多了两个字节,那是针对音频设备扩展的,不用管它
bDescriptorType,描述符类型,这里对于端点就是USB_DT_ENDPOINT,0x05。
bEndpointAddress,这个字段描述的信息挺多的,比如这个端点是输入端点还是输出端点,这个端点的地址,以及这个端点的端点号。它的bits 0~3表示的就是端点号,你使用0x0f和它相与就可以得到端点号。不过,开发内核的同志想的都很周到,定义好了一个掩码USB_ENDPOINT_NUMBER_MASK,它的值就是0x0f,当然,这是为了让咱们更容易去读他们的代码,也为了以后的扩展。另外,它的bit 8表示方向,输入还是输出,同样有掩码USB_ENDPOINT_DIR_MASK,值为0x80,将它和bEndpointAddress相与,并结合USB_DIR_IN和USB_DIR_OUT作判断就可以得到端点的方向。
/*
 * USB directions
 *
 * This bit flag is used in endpoint descriptors' bEndpointAddress field.
 * It's also one of three fields in control requests bRequestType.
 */
#define USB_DIR_OUT			0		/* to device */
#define USB_DIR_IN			0x80		/* to host */
bmAttributes,属性,总共8位,其中bit1和bit0 共同称为Transfer Type,即传输类型, 00 表示控制,01 表示等时,10 表示批量,11 表示中断。前面的端点号还有端点方向都有配对儿的掩码,这里当然也有,就在struct usb_endpoint_descriptor定义的下面
#define USB_ENDPOINT_XFERTYPE_MASK	0x03	/* in bmAttributes */
#define USB_ENDPOINT_XFER_CONTROL	0
#define USB_ENDPOINT_XFER_ISOC		1
#define USB_ENDPOINT_XFER_BULK		2
#define USB_ENDPOINT_XFER_INT		3
wMaxPacketSize,端点一次可以处理的最大字节数。比如你老板比较看重你,一次给你交代了几个任务,于是你大声的疾呼,神啊,我一次只能做一个,当然神是听不到的,怎么办那,加班加点儿,一个一个的分开做呗。端点也是,如果你发送的数据量大于端点的这个值,也会分成多次一次一次来传输。友情提醒一下,这个字段还是有点门道的,对不同的传输类型也有不同的要求,日后碰到了再说。
bInterval, USB是轮询式的总线,这个值表达了端点一种美好的期待,希望主机轮询自己的时间间隔,但实际上批准不批准就是host的事了。不同的传输类型bInterval也有不同的意义,暂时就提这么一下,碰到各个实际的传输类型了再去说它。不是俺捂盘惜售,而是初次照面儿就对人家寻根问底的不大礼貌,这里先留个印象,有缘总会再相见的。
回到struct usb_host_endpoint,urb_list,端点要处理的urb队列。urb是什么?这年头儿钱不多就是新名词儿多,是个新名词爆炸的时代,不过urb可是usb通信的主角,它包含了执行urb传输所需要的所有信息,你要想和你的usb通信,就得创建一个urb,并且为它赋好值,交给咱们的usb core,它会找到合适的host controller,从而进行具体的数据传输。设备中的每个端点都可以处理一个urb队列,当然,urb是内核里对usb传输数据的封装也叫抽象吧,协议里可不这么叫。基于urb特殊的江湖地位,接下来的哪一个黄道吉日里,我会对它大书特书的。
hcpriv,这是提供给HCD(host controller driver)用的。比如等时端点会在里边儿放一个ehci_iso_stream,什么意思?郑板桥告诉我们要难得糊涂。
ep_dev,这个字段是供sysfs用的。好奇的话可以去/sys下看一看
localhost:/usr/src/linux/drivers/usb/core # ls /sys/bus/usb/devices/usb1/ep_00/
bEndpointAddress bmAtributes direction subsystem wMaxpacketSize
bInterval dev interval type
bLength device power uevent
ep_00端点目录下的这些文件从哪儿来的?就是在usb_create_ep_files函数里使用ep_dev创建的。
extra,extralen,有关一些额外扩展的描述符的,和struct usb_host_interface里差不多,只是这里的是针对端点的,如果你请求从设备里获得描述符信息,它们会跟在标准的端点描述符后面返回给你。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值