您的位置:首页 > 运维架构 > Linux

USB标准请求传输下的linux驱动

2017-05-10 12:09 260 查看

1.设备请求(转载)

在枚举过程中,USB主机会向USB设备请求参数,用于读取描述符信息,为USB设备分配设备地址等等。USB设备通过默认控制管道响应这些请求,这些请求参数在SETUP数据包中,长度为8个字节。Linux对于请求参数结构体定义如下:

146 struct usb_ctrlrequest {

147         __u8 bRequestType;

148         __u8 bRequest;

149         __le16 wValue;

150         __le16 wIndex;

151         __le16 wLength;

152 } __attribute__ ((packed));

bRequestType: 位详细定义如下。

                           D7 数据传输方向

                                 0 主机到设备

                                 1 设备到主机

                           D6~D5 类型

                                 0 Standard

                                 1 Class

                                 2 Vendor

                                 3 Reserved

                           D4~D0 接收者

                                 0 设备

                                 1 接口

                                 2 端点

                                 3 Other

                                 4~31 Reserved

bRequest: 特定请求。

wValue:

wIndex:

wLength: 这三个参数视具体请求而定。

标准设备请求代码有:



1 Clear Feature



用于清除或禁止某些feature,该请求为OUT传输,接收者为设备、接口和端点。

2 Get Configuration



用于返回当前设备配置值,IN传输。

3 Get Descriptor



用于获取描述符,IN传输,wValue高字节为描述符类型,例如,设备描述符、配置描述符等等,wValue低字节用于选择特殊的描述符,例如设备有多个配置描述符、或者多个字符串描述符时需要使用该参数去指定索引,wIndex为字符串描述符中的LanguageID,wLength为请求的数据长度,例如,读取设备描述符请求字段如下:

0x80    0x06    0x0100    0x00    0x0012

4 Get Interface



5 Get Status



6 Set Address



用于为设备分配设备地址,OUT传输,wValue为分配的设备地址。

7 Set Configuration



用于选择一个设备配置,OUT传输,wValue为配置值。

8 Set Descriptor



该请求是可选的,用于更新描述符信息,OUT传输。

9 Set Feature



用于设置或使能某些feature,OUT传输。

10 Set Interface



11 Synch Frame



2.linux下设备请求驱动开发

2.1  分配urb

2.2  结构体:根据需求填充结构体
struct usb_ctrlrequest {

__u8 bRequestType; //

__u8 bRequest;  //请求ID

__le16 wValue; //数据

__le16 wIndex; //偏移地址

__le16 wLength;//字节数

} __attribute__ ((packed));

2.3 创建接收发送管道
usb_sndctrlpipe(dev->udev,0);

usb_rcvctrlpipe(dev->udev,0);

2.4 填充控制urb
usb_fill_control_urb()//关联填充请求,数据,地址,控制完成

2.5 提交urb
usb_submit_urb();

同步情况例子usb_control_msg()

static int mos7840_get_reg_sync(struct usb_serial_port *port, __u16 reg,
__u16 *val)

{
struct usb_device *dev = port->serial->dev;
int ret = 0;
u8 *buf;

buf = kmalloc(VENDOR_READ_LENGTH, GFP_KERNEL);
if (!buf)
return -ENOMEM;

ret =
usb_control_msg(dev, usb_rcvctrlpipe(dev, 0), MCS_RDREQ,
     MCS_RD_RTYPE, 0, reg, buf, VENDOR_READ_LENGTH,
     MOS_WDR_TIMEOUT);
*val = buf[0];
dev_dbg(&port->dev, "%s offset is %x, return val %x\n", __func__, reg, *val);

kfree(buf);
return ret;

}

static int usb_internal_control_msg(struct usb_device *usb_dev,
   unsigned int pipe,
   struct usb_ctrlrequest *cmd,
   void *data, int len, int timeout)

{
struct urb *urb;
int retv;
int length;

urb = usb_alloc_urb(0, GFP_NOIO);
if (!urb)
return -ENOMEM;

usb_fill_control_urb(urb, usb_dev, pipe, (unsigned char *)cmd, data,
    len, usb_api_blocking_completion, NULL);

retv = usb_start_wait_urb(urb, timeout, &length);
if (retv < 0)
return retv;
else
return length;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux