四、usb设备注册

一.usb设备驱动注册

  1. static inline int usb_register(struct usb_driver *driver)  
  2. {  
  3.     return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);  
  4. }  

usb_register_driver

  1. int usb_register_driver(struct usb_driver *new_driver, struct module *owner,const char *mod_name)  
  2. {  
  3.     int retval = 0;  
  4.     if (usb_disabled())  
  5.         return -ENODEV;  
  6.     new_driver->drvwrap.for_devices = 0; //usb接口设备   
  7.     new_driver->drvwrap.driver.name = (char *) new_driver->name;  //设置设备名   
  8.     new_driver->drvwrap.driver.bus = &usb_bus_type;  //设置总线类型   
  9.     new_driver->drvwrap.driver.probe = usb_probe_interface;  //设置probe方法   
  10.     new_driver->drvwrap.driver.remove = usb_unbind_interface;    //设置remove方法   
  11.     new_driver->drvwrap.driver.owner = owner;    //设置模块所有者   
  12.     new_driver->drvwrap.driver.mod_name = mod_name;  
  13.     spin_lock_init(&new_driver->dynids.lock);  
  14.     INIT_LIST_HEAD(&new_driver->dynids.list);  
  15.     retval = driver_register(&new_driver->drvwrap.driver);   //注册设备驱动   
  16.     if (retval)  
  17.         goto out;  
  18.     usbfs_update_special();  
  19.     retval = usb_create_newid_file(new_driver);  
  20.     if (retval)  
  21.         goto out_newid;  
  22.     retval = usb_create_removeid_file(new_driver);  
  23.     if (retval)  
  24.         goto out_removeid;  
  25.     pr_info("%s: registered new interface driver %s\n",usbcore_name, new_driver->name);  
  26. out:  
  27.     return retval;  
  28. out_removeid:  
  29.     usb_remove_newid_file(new_driver);  
  30. out_newid:  
  31.     driver_unregister(&new_driver->drvwrap.driver);  
  32.     printk(KERN_ERR "%s: error %d registering interface driver %s\n",usbcore_name, retval, new_driver->name);  
  33.     goto out;  
  34. }  

注册设备驱动后会调用总线的match方法

  1. static int usb_device_match(struct device *dev, struct device_driver *drv)  
  2. {  
  3.     if (is_usb_device(dev)) {   //usb设备   
  4.         if (!is_usb_device_driver(drv))  
  5.             return 0;  
  6.         return 1;  
  7.     } else if (is_usb_interface(dev)) { //usb接口   
  8.         struct usb_interface *intf;  
  9.         struct usb_driver *usb_drv;  
  10.         const struct usb_device_id *id;  
  11.         if (is_usb_device_driver(drv))  
  12.             return 0;  
  13.         intf = to_usb_interface(dev);   //获取usb接口结构体   
  14.         usb_drv = to_usb_driver(drv);   //获取usb_driver   
  15.         id = usb_match_id(intf, usb_drv->id_table);  //id匹配   
  16.         if (id)  
  17.             return 1;  
  18.         id = usb_match_dynamic_id(intf, usb_drv);  
  19.         if (id)  
  20.             return 1;  
  21.     }  
  22.     return 0;  
  23. }  

usb_match_id

[cpp]  view plain copy
  1. const struct usb_device_id *usb_match_id(struct usb_interface *interface,const struct usb_device_id *id)  
  2. {  
  3.     if (id == NULL)  
  4.         return NULL;  
  5.     for (; id->idVendor || id->idProduct || id->bDeviceClass ||id->bInterfaceClass || id->driver_info; id++) {  
  6.         if (usb_match_one_id(interface, id))  
  7.             return id;  
  8.     }  
  9.     return NULL;  
  10. }  

usb_match_one_id

  1. int usb_match_one_id(struct usb_interface *interface,const struct usb_device_id *id)  
  2. {  
  3.     struct usb_host_interface *intf;  
  4.     struct usb_device *dev;  
  5.     if (id == NULL)  
  6.         return 0;  
  7.     intf = interface->cur_altsetting;  
  8.     dev = interface_to_usbdev(interface);  
  9.     if (!usb_match_device(dev, id))  
  10.         return 0;  
  11.     if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&  
  12.     (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |USB_DEVICE_ID_MATCH_INT_SUBCLASS |USB_DEVICE_ID_MATCH_INT_PROTOCOL)))  
  13.         return 0;  
  14.     if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&(id->bInterfaceClass != intf->desc.bInterfaceClass))  
  15.         return 0;  
  16.     if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&(id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))  
  17.         return 0;  
  18.     if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&(id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))  
  19.         return 0;  
  20.     return 1;  
  21. }  

usb_match_device

  1. int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)  
  2. {  
  3.     if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && id->idVendor != le16_to_cpu(dev->descriptor.idVendor))  
  4.         return 0;  
  5.     if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&id->idProduct != le16_to_cpu(dev->descriptor.idProduct))  
  6.         return 0;  
  7.     if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&(id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))  
  8.         return 0;  
  9.     if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&(id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))  
  10.         return 0;  
  11.     if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&(id->bDeviceClass != dev->descriptor.bDeviceClass))  
  12.         return 0;  
  13.     if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&(id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))  
  14.         return 0;  
  15.     if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))  
  16.         return 0;  
  17.     return 1;  
  18. }  

匹配成功则调用usb_probe_interface

  1. static int usb_probe_interface(struct device *dev)  
  2. {  
  3.     struct usb_driver *driver = to_usb_driver(dev->driver);  
  4.     struct usb_interface *intf = to_usb_interface(dev);  
  5.     struct usb_device *udev = interface_to_usbdev(intf);  
  6.     const struct usb_device_id *id;  
  7.     int error = -ENODEV;  
  8.     dev_dbg(dev, "%s\n", __func__);  
  9.     intf->needs_binding = 0;  
  10.     if (usb_device_is_owned(udev))  
  11.         return error;  
  12.     if (udev->authorized == 0) {  
  13.         dev_err(&intf->dev, "Device is not authorized for usage\n");  
  14.         return error;  
  15.     }  
  16.     id = usb_match_id(intf, driver->id_table);  
  17.     if (!id)  
  18.         id = usb_match_dynamic_id(intf, driver);  
  19.     if (!id)  
  20.         return error;  
  21.     dev_dbg(dev, "%s - got id\n", __func__);  
  22.     error = usb_autoresume_device(udev);  
  23.     if (error)  
  24.         return error;  
  25.     intf->condition = USB_INTERFACE_BINDING;  
  26.     pm_runtime_set_active(dev);  
  27.     pm_suspend_ignore_children(dev, false);  
  28.     if (driver->supports_autosuspend)  
  29.         pm_runtime_enable(dev);  
  30.     if (intf->needs_altsetting0) {  
  31.         error = usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);  
  32.         if (error < 0)  
  33.             goto err;  
  34.         intf->needs_altsetting0 = 0;  
  35.     }  
  36.     error = driver->probe(intf, id);  
  37.     if (error)  
  38.         goto err;  
  39.     intf->condition = USB_INTERFACE_BOUND;  
  40.     usb_autosuspend_device(udev);  
  41.     return error;  
  42.  err:  
  43.     intf->needs_remote_wakeup = 0;  
  44.     intf->condition = USB_INTERFACE_UNBOUND;  
  45.     usb_cancel_queued_reset(intf);  
  46.     if (driver->supports_autosuspend)  
  47.         pm_runtime_disable(dev);  
  48.     pm_runtime_set_suspended(dev);  
  49.     usb_autosuspend_device(udev);  
  50.     return error;  
  51. }  

usb_set_interface

  1. int usb_set_interface(struct usb_device *dev, int interface, int alternate)  
  2. {  
  3.     struct usb_interface *iface;  
  4.     struct usb_host_interface *alt;  
  5.     struct usb_hcd *hcd = bus_to_hcd(dev->bus);  
  6.     int ret;  
  7.     int manual = 0;  
  8.     unsigned int epaddr;  
  9.     unsigned int pipe;  
  10.     if (dev->state == USB_STATE_SUSPENDED)  
  11.         return -EHOSTUNREACH;  
  12.     iface = usb_ifnum_to_if(dev, interface);  
  13.     if (!iface) {  
  14.         dev_dbg(&dev->dev, "selecting invalid interface %d\n",interface);  
  15.         return -EINVAL;  
  16.     }  
  17.     alt = usb_altnum_to_altsetting(iface, alternate);  
  18.     if (!alt) {  
  19.         dev_warn(&dev->dev, "selecting invalid altsetting %d\n",alternate);  
  20.         return -EINVAL;  
  21.     }  
  22.     mutex_lock(&hcd->bandwidth_mutex);  
  23.     ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt);  
  24.     if (ret < 0) {  
  25.         dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",alternate);  
  26.         mutex_unlock(&hcd->bandwidth_mutex);  
  27.         return ret;  
  28.     }  
  29.     if (dev->quirks & USB_QUIRK_NO_SET_INTF)  
  30.         ret = -EPIPE;  
  31.     else  
  32.         ret = usb_control_msg(dev, usb_sndctrlpipe(dev,0),USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,alternate, interface, NULL, 0, 5000);  
  33.     if (ret == -EPIPE && iface->num_altsetting == 1) {  
  34.         dev_dbg(&dev->dev,"manual set_interface for iface %d, alt %d\n",interface, alternate);  
  35.         manual = 1;  
  36.     } else if (ret < 0) {  
  37.         usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting);  
  38.         mutex_unlock(&hcd->bandwidth_mutex);  
  39.         return ret;  
  40.     }  
  41.     mutex_unlock(&hcd->bandwidth_mutex);  
  42.     if (iface->cur_altsetting != alt) {  
  43.         remove_intf_ep_devs(iface);  
  44.         usb_remove_sysfs_intf_files(iface);  
  45.     }  
  46.     usb_disable_interface(dev, iface, true);  
  47.     iface->cur_altsetting = alt;  
  48.     if (manual) {  
  49.         int i;  
  50.         for (i = 0; i < alt->desc.bNumEndpoints; i++) {  
  51.             epaddr = alt->endpoint[i].desc.bEndpointAddress;  
  52.             pipe = __create_pipe(dev,USB_ENDPOINT_NUMBER_MASK & epaddr) |(usb_endpoint_out(epaddr) ?USB_DIR_OUT : USB_DIR_IN);  
  53.             usb_clear_halt(dev, pipe);  
  54.         }  
  55.     }  
  56.     usb_enable_interface(dev, iface, true);  
  57.     if (device_is_registered(&iface->dev)) {  
  58.         usb_create_sysfs_intf_files(iface);  
  59.         create_intf_ep_devs(iface);  
  60.     }  
  61.     return 0;  
  62. }  


二.usb设备注册

  1. int usb_register_dev(struct usb_interface *intf,struct usb_class_driver *class_driver)  
  2. {  
  3.     int retval;  
  4.     int minor_base = class_driver->minor_base;  
  5.     int minor;  
  6.     char name[20];  
  7.     char *temp;  
  8. #ifdef CONFIG_USB_DYNAMIC_MINORS   
  9.     minor_base = 0;  
  10. #endif   
  11.     if (class_driver->fops == NULL)  
  12.         return -EINVAL;  
  13.     if (intf->minor >= 0)  
  14.         return -EADDRINUSE;  
  15.     retval = init_usb_class();  
  16.     if (retval)  
  17.         return retval;  
  18.     dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base);  
  19.     down_write(&minor_rwsem);  
  20.     for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {  
  21.         if (usb_minors[minor])  //若数组不为空   
  22.             continue;  
  23.         usb_minors[minor] = class_driver->fops;  //将操作函数集放入全局usb_minors数组中   
  24.         intf->minor = minor; //设置接口的次设备号   
  25.         break;  
  26.     }  
  27.     up_write(&minor_rwsem);  
  28.     if (intf->minor < 0)  
  29.         return -EXFULL;  
  30.     snprintf(name, sizeof(name), class_driver->name, minor - minor_base);  
  31.     temp = strrchr(name, '/');  
  32.     if (temp && (temp[1] != '\0'))  
  33.         ++temp;  
  34.     else  
  35.         temp = name;  
  36.     //创建设备   
  37.     intf->usb_dev = device_create(usb_class->class, &intf->dev,MKDEV(USB_MAJOR, minor), class_driver,"%s", temp);  
  38.     if (IS_ERR(intf->usb_dev)) {  
  39.         down_write(&minor_rwsem);  
  40.         usb_minors[minor] = NULL;  
  41.         intf->minor = -1;  
  42.         up_write(&minor_rwsem);  
  43.         retval = PTR_ERR(intf->usb_dev);  
  44.     }  
  45.     return retval;  
  46. }  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值