Linux&UVC驱动
+ -

LINUX&UVC驱动的uvc_probe函数之参数分析

2024-03-13 28 0

当一个UVC设备被USBCore识别后,会调用UVC驱动的probe函数。这个probe函数就是Windows驱动中类似的AddDevice回调。

struct uvc_driver uvc_driver = {
    .driver = {
        .name        = "uvcvideo",
        .probe        = uvc_probe,
        .disconnect    = uvc_disconnect,
        .suspend    = uvc_suspend,
        .resume        = uvc_resume,
        .reset_resume    = uvc_reset_resume,
        .id_table    = uvc_ids,
        .supports_autosuspend = 1,
    },
};

回调函数uvc_probe的原型如下:

static int uvc_probe(struct usb_interface *intf,
             const struct usb_device_id *id)

其两个入参是由USBCore提供的。
第一个参数可以看到是usb_interface的指针,而不是usb_device类型的指针。这就涉及到usb规范的定义了。USB设备一个物理设备可以支持多个逻辑设备,比如一个USB设备可以包括UVC相机,UAC相机,甚至再加一个HID设备。而USB设备的这种复合通过是通过接口描述符实现的。对于占用多个接口的USB设备,其通过接口关联描述符描述该设备占用的接口范围。所以这里可以充分理解USB接口描述符其实是描述USB功能的最小单位。这个最小单位就是单一的逻辑设备。

在Windows系统中,也有一个专门的驱动usbccgp来拆解USB物理设备的逻辑功能,但在LINUX系统中,这个体力活交给了USBCore了。

USB规范通过各个描述符定义了USB设备灵活多样的特征。一个USB设备可以有多个USB配置,一个USB设备又因其复合接口描述符而实现多个逻辑设备功能。而备用接口描述符引入的又可以让USB逻辑设备根据带宽的不同,提供不同质量的数据传输。在Linux系统中,这些都有对应的对构体来描述。其分别为usb_device,usb_host_config,usb_interface。

struct usb_interface {
    /* array of alternate settings for this interface,
     * stored in no particular order */
    struct usb_host_interface *altsetting;

    struct usb_host_interface *cur_altsetting;    /* the currently
                     * active alternate setting */
    unsigned num_altsetting;    /* number of alternate settings */

    /* If there is an interface association descriptor then it will list
     * the associated interfaces */
    struct usb_interface_assoc_descriptor *intf_assoc;

    int minor;            /* minor number this interface is
                     * bound to */
    enum usb_interface_condition condition;        /* state of binding */
    unsigned sysfs_files_created:1;    /* the sysfs attributes exist */
    unsigned ep_devs_created:1;    /* endpoint "devices" exist */
    unsigned unregistering:1;    /* unregistration is in progress */
    unsigned needs_remote_wakeup:1;    /* driver requires remote wakeup */
    unsigned needs_altsetting0:1;    /* switch to altsetting 0 is pending */
    unsigned needs_binding:1;    /* needs delayed unbind/rebind */
    unsigned resetting_device:1;    /* true: bandwidth alloc after reset */
    unsigned authorized:1;        /* used for interface authorization */

    struct device dev;        /* interface specific device info */
    struct device *usb_dev;
    struct work_struct reset_ws;    /* for resets in atomic context */
};

对于usb_interface指针,可以通过函数interface_to_usbdev获取USB设备。

struct usb_device *udev = interface_to_usbdev(intf);

更详细的可详见:https://www.usbzh.com/article/detail-1317.html

第二个参数usb_device_id指针描述了该USB逻辑设备的基本信息。这里可以通过其结构体来查看:

struct usb_device_id {
    /* which fields to match against? */
    __u16        match_flags;

    /* Used for product specific matches; range is inclusive */
    __u16        idVendor;
    __u16        idProduct;
    __u16        bcdDevice_lo;
    __u16        bcdDevice_hi;

    /* Used for device class matches */
    __u8        bDeviceClass;
    __u8        bDeviceSubClass;
    __u8        bDeviceProtocol;

    /* Used for interface class matches */
    __u8        bInterfaceClass;
    __u8        bInterfaceSubClass;
    __u8        bInterfaceProtocol;

    /* Used for vendor-specific interface matches */
    __u8        bInterfaceNumber;

    /* not matched against */
    kernel_ulong_t    driver_info
        __attribute__((aligned(sizeof(kernel_ulong_t))));
};

这些是通过解析USB设备描述符,USB接口描述符而获取到的。

0 篇笔记 写笔记

USB驱动数据结构usb_device/usb_host_config/usb_interface/usb_host_interface/usb_host_endpoint
相对于USB规范中的USB相关描述符,Linux定义了几个相关的结构体。这几个结构体可在以下位置查看:https://elixir.bootlin.com/linux/v5.5-rc2/source/include/linux/usb.h以下介绍的USB结构体关系如下:struct usb_de......
LINUX&UVC驱动的uvc_probe函数之参数分析
当一个UVC设备被USBCore识别后,会调用UVC驱动的probe函数。这个probe函数就是Windows驱动中类似的AddDevice回调。struct uvc_driver uvc_driver = { .driver = { .name = &quo......
LINUX&UVC驱动的uvc_probe函数主体分析
UVC驱动的prob函数原型如下:static int uvc_probe(struct usb_interface *intf, const struct usb_device_id *id);这是由USBCore回调并提供相关的USB逻辑设备相关的参数,这我们在上一......
关注公众号
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

您的支持,是我们前进的动力!