linux下gadget复合设备,Linux gadget驱动分析3------复合设备驱动

windows上面对usb复合设备的识别须要下面条件。html

“linux

若是设备知足下列要求,则总线驱动程序还会报告 USB\COMPOSITE 的兼容标识符:windows

设备描述符的设备类字段 (bDeviceClass) 必须包含一个零值,或者设备描述符的类 (bDeviceClass)、子类 (bDeviceSubClass) 和协议 (bDeviceProtocol) 字段必须分别具备值 0xEF、0x02 和 0x01,如 USB 接口关联描述符中所述。this

设备必须具备多个接口。spa

设备必须具备一个配置。“code

下面是linux /driver/usb/gadget/mass_storage.c 中定义的设备描述符:blog

1 static struct usb_device_descriptor msg_device_desc ={2 .bLength = sizeofmsg_device_desc,3 .bDescriptorType =USB_DT_DEVICE,4

5 .bcdUSB = cpu_to_le16(0x0200),6 .bDeviceClass =USB_CLASS_PER_INTERFACE,7

8 /*Vendor and product id can be overridden by module parameters.*/

9 .idVendor =cpu_to_le16(FSG_VENDOR_ID),10 .idProduct =cpu_to_le16(FSG_PRODUCT_ID),11 /*.bcdDevice = f(hardware)*/

12 /*.iManufacturer = DYNAMIC*/

13 /*.iProduct = DYNAMIC*/

14 /*NO SERIAL NUMBER*/

15 .bNumConfigurations = 1,16 };

其中:接口

.bDeviceClass = USB_CLASS_PER_INTERFACE,ip

即为0,

注意到其实mass storage类是被定义为:

#define USB_CLASS_MASS_STORAGE 8

没有给.bDeviceClass 赋值为8,这样gadget 设备就会在windows上识别时得到 USB\COMPOSITE 的兼容标识符

1 /*

2 * Device and/or Interface Class codes3 * as found in bDeviceClass or bInterfaceClass4 * and defined by www.usb.org documents5 */

6 #define USB_CLASS_PER_INTERFACE 0 /* for DeviceClass */

7 #define USB_CLASS_AUDIO 1

8 #define USB_CLASS_COMM 2

9 #define USB_CLASS_HID 3

10 #define USB_CLASS_PHYSICAL 5

11 #define USB_CLASS_STILL_IMAGE 6

12 #define USB_CLASS_PRINTER 7

13 #define USB_CLASS_MASS_STORAGE 8

14 #define USB_CLASS_HUB 9

15 #define USB_CLASS_CDC_DATA 0x0a

16 #define USB_CLASS_CSCID 0x0b /* chip+ smart card */

17 #define USB_CLASS_CONTENT_SEC 0x0d /* content security */

18 #define USB_CLASS_VIDEO 0x0e

19 #define USB_CLASS_WIRELESS_CONTROLLER 0xe0

20 #define USB_CLASS_MISC 0xef

21 #define USB_CLASS_APP_SPEC 0xfe

22 #define USB_CLASS_VENDOR_SPEC 0xff

23

24 #define USB_SUBCLASS_VENDOR_SPEC 0xff

上面那个结构体中:

.idVendor = cpu_to_le16(FSG_VENDOR_ID),

.idProduct = cpu_to_le16(FSG_PRODUCT_ID),

若是不作修改,windows会直接找到通用的mass sotrage驱动 ,而不会加载USB 通用父驱动程序 (Usbccgp.sys),就不会i识别成复合设备,而是直使用设备的第一个接口,设备管理器只看到一个设备。

widows的机制不是很了解

我这里改为

.idVendor =             cpu_to_le16(0x022b),

.idProduct = cpu_to_le16(0x1234),

而后增长一个接口,即设备两个接口同时

static int fsg_add(struct usb_composite_dev *cdev,struct usb_configuration *c,struct fsg_common *common)

{struct fsg_dev *fsg;intrc;

fsg= kzalloc(sizeof *fsg, GFP_KERNEL);if (unlikely(!fsg))return -ENOMEM;

fsg->function.name =FSG_DRIVER_DESC;

fsg->function.strings =fsg_strings_array;

fsg->function.bind =fsg_bind;

fsg->function.unbind =fsg_unbind;

fsg->function.setup =fsg_setup;

fsg->function.set_alt =fsg_set_alt;

fsg->function.disable =fsg_disable;

fsg->common =common;/*Our caller holds a reference to common structure so we

* don't have to be worry about it being freed until we return

* from this function. So instead of incrementing counter now

* and decrement in error recovery we increment it only when

* call to usb_add_function() was successful.*/rc= usb_add_function(c, &fsg->function);if(unlikely(rc))

kfree(fsg);elsefsg_common_get(fsg->common);struct f_sourcesink *ss;intstatus;

ss= kzalloc(sizeof *ss, GFP_KERNEL);if (!ss)return -ENOMEM;

init_completion(&ss->gdt_completion);

ss->function.name = "source/sink"; //就是f_sourcesink.c中的接口,gadget zero中使用那个

ss->function.descriptors =fs_source_sink_descs;

ss->function.bind =sourcesink_bind;

ss->function.unbind =sourcesink_unbind;

ss->function.set_alt =sourcesink_set_alt;

ss->function.disable =sourcesink_disable;

status= usb_add_function(c, &ss->function);if(status)

kfree(ss);returnrc;

}

调用两次usb_add_function,给设备添加两个接口。

另外,在nuc900系列中,须要注意的是端点描述符里面

1 static struct usb_endpoint_descriptor hs_source_desc ={2 .bLength =USB_DT_ENDPOINT_SIZE,3 .bDescriptorType =USB_DT_ENDPOINT,4

5 .bmAttributes =USB_ENDPOINT_XFER_BULK,6 .wMaxPacketSize = cpu_to_le16(512),7 };8

9 static struct usb_endpoint_descriptor hs_sink_desc ={10 .bLength =USB_DT_ENDPOINT_SIZE,11 .bDescriptorType =USB_DT_ENDPOINT,12

13 .bmAttributes =USB_ENDPOINT_XFER_BULK,14 .wMaxPacketSize = cpu_to_le16(512),15 };16 .wMaxPacketSize = cpu_to_le16(512),

每个端点的maxpacketsize 加起来不能超过udc 控制器中定义的sram_data大小2048。

如今就是一个设备有两个不一样功能的接口,能够同时工做,其中一个是标准的mass storage类设备,windows有相应驱动,不用管,令一个是以前用的gadget zero的接口,须要gadget zero的驱动。

这里随便找一个usb驱动(只是先识别,并不能工做),修改一下.inf文件让它识别个人这个接口。

须要改一下vid pid就好了,

修改这两行为:

%USB\VID_022b&PID_1234.DeviceDesc%=SECBULK.Dev, USB\VID_022b&PID_1234&REV_0000&MI_01

USB\VID_022b&PID_1234.DeviceDesc="test device"

一般设备驱动的.inf 没有后面 &REV_0000&MI_01,这个应该就是指的第几个接口. .inf 文件不太了解,便用边查吧。

而后安装驱动,识别出来就是一个test device 一个 USB Mass Storage Device,两个接口。这样设备及能够做为mass storage设备有可用做test device设备。

7e623b1461a69fbeea0ba604d16cca32.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值