四、usb设备注册

一.usb设备驱动注册

static inline int usb_register(struct usb_driver *driver)
{
	return usb_register_driver(driver, THIS_MODULE, KBUILD_MODNAME);
}

usb_register_driver

int usb_register_driver(struct usb_driver *new_driver, struct module *owner,const char *mod_name)
{
	int retval = 0;
	if (usb_disabled())
		return -ENODEV;
	new_driver->drvwrap.for_devices = 0;	//usb接口设备
	new_driver->drvwrap.driver.name = (char *) new_driver->name;	//设置设备名
	new_driver->drvwrap.driver.bus = &usb_bus_type;	//设置总线类型
	new_driver->drvwrap.driver.probe = usb_probe_interface;	//设置probe方法
	new_driver->drvwrap.driver.remove = usb_unbind_interface;	//设置remove方法
	new_driver->drvwrap.driver.owner = owner;	//设置模块所有者
	new_driver->drvwrap.driver.mod_name = mod_name;
	spin_lock_init(&new_driver->dynids.lock);
	INIT_LIST_HEAD(&new_driver->dynids.list);
	retval = driver_register(&new_driver->drvwrap.driver);	//注册设备驱动
	if (retval)
		goto out;
	usbfs_update_special();
	retval = usb_create_newid_file(new_driver);
	if (retval)
		goto out_newid;
	retval = usb_create_removeid_file(new_driver);
	if (retval)
		goto out_removeid;
	pr_info("%s: registered new interface driver %s\n",usbcore_name, new_driver->name);
out:
	return retval;
out_removeid:
	usb_remove_newid_file(new_driver);
out_newid:
	driver_unregister(&new_driver->drvwrap.driver);
	printk(KERN_ERR "%s: error %d registering interface driver %s\n",usbcore_name, retval, new_driver->name);
	goto out;
}

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

static int usb_device_match(struct device *dev, struct device_driver *drv)
{
	if (is_usb_device(dev)) {	//usb设备
		if (!is_usb_device_driver(drv))
			return 0;
		return 1;
	} else if (is_usb_interface(dev)) {	//usb接口
		struct usb_interface *intf;
		struct usb_driver *usb_drv;
		const struct usb_device_id *id;
		if (is_usb_device_driver(drv))
			return 0;
		intf = to_usb_interface(dev);	//获取usb接口结构体
		usb_drv = to_usb_driver(drv);	//获取usb_driver
		id = usb_match_id(intf, usb_drv->id_table);	//id匹配
		if (id)
			return 1;
		id = usb_match_dynamic_id(intf, usb_drv);
		if (id)
			return 1;
	}
	return 0;
}

usb_match_id

const struct usb_device_id *usb_match_id(struct usb_interface *interface,const struct usb_device_id *id)
{
	if (id == NULL)
		return NULL;
	for (; id->idVendor || id->idProduct || id->bDeviceClass ||id->bInterfaceClass || id->driver_info; id++) {
		if (usb_match_one_id(interface, id))
			return id;
	}
	return NULL;
}

usb_match_one_id

int usb_match_one_id(struct usb_interface *interface,const struct usb_device_id *id)
{
	struct usb_host_interface *intf;
	struct usb_device *dev;
	if (id == NULL)
		return 0;
	intf = interface->cur_altsetting;
	dev = interface_to_usbdev(interface);
	if (!usb_match_device(dev, id))
		return 0;
	if (dev->descriptor.bDeviceClass == USB_CLASS_VENDOR_SPEC &&!(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
	(id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |USB_DEVICE_ID_MATCH_INT_SUBCLASS |USB_DEVICE_ID_MATCH_INT_PROTOCOL)))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&(id->bInterfaceClass != intf->desc.bInterfaceClass))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&(id->bInterfaceSubClass != intf->desc.bInterfaceSubClass))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&(id->bInterfaceProtocol != intf->desc.bInterfaceProtocol))
		return 0;
	return 1;
}

usb_match_device

int usb_match_device(struct usb_device *dev, const struct usb_device_id *id)
{
	if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) && id->idVendor != le16_to_cpu(dev->descriptor.idVendor))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&id->idProduct != le16_to_cpu(dev->descriptor.idProduct))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&(id->bcdDevice_lo > le16_to_cpu(dev->descriptor.bcdDevice)))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&(id->bcdDevice_hi < le16_to_cpu(dev->descriptor.bcdDevice)))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&(id->bDeviceClass != dev->descriptor.bDeviceClass))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&(id->bDeviceSubClass != dev->descriptor.bDeviceSubClass))
		return 0;
	if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&(id->bDeviceProtocol != dev->descriptor.bDeviceProtocol))
		return 0;
	return 1;
}

匹配成功则调用usb_probe_interface

static int usb_probe_interface(struct device *dev)
{
	struct usb_driver *driver = to_usb_driver(dev->driver);
	struct usb_interface *intf = to_usb_interface(dev);
	struct usb_device *udev = interface_to_usbdev(intf);
	const struct usb_device_id *id;
	int error = -ENODEV;
	dev_dbg(dev, "%s\n", __func__);
	intf->needs_binding = 0;
	if (usb_device_is_owned(udev))
		return error;
	if (udev->authorized == 0) {
		dev_err(&intf->dev, "Device is not authorized for usage\n");
		return error;
	}
	id = usb_match_id(intf, driver->id_table);
	if (!id)
		id = usb_match_dynamic_id(intf, driver);
	if (!id)
		return error;
	dev_dbg(dev, "%s - got id\n", __func__);
	error = usb_autoresume_device(udev);
	if (error)
		return error;
	intf->condition = USB_INTERFACE_BINDING;
	pm_runtime_set_active(dev);
	pm_suspend_ignore_children(dev, false);
	if (driver->supports_autosuspend)
		pm_runtime_enable(dev);
	if (intf->needs_altsetting0) {
		error = usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
		if (error < 0)
			goto err;
		intf->needs_altsetting0 = 0;
	}
	error = driver->probe(intf, id);
	if (error)
		goto err;
	intf->condition = USB_INTERFACE_BOUND;
	usb_autosuspend_device(udev);
	return error;
 err:
	intf->needs_remote_wakeup = 0;
	intf->condition = USB_INTERFACE_UNBOUND;
	usb_cancel_queued_reset(intf);
	if (driver->supports_autosuspend)
		pm_runtime_disable(dev);
	pm_runtime_set_suspended(dev);
	usb_autosuspend_device(udev);
	return error;
}

usb_set_interface

int usb_set_interface(struct usb_device *dev, int interface, int alternate)
{
	struct usb_interface *iface;
	struct usb_host_interface *alt;
	struct usb_hcd *hcd = bus_to_hcd(dev->bus);
	int ret;
	int manual = 0;
	unsigned int epaddr;
	unsigned int pipe;
	if (dev->state == USB_STATE_SUSPENDED)
		return -EHOSTUNREACH;
	iface = usb_ifnum_to_if(dev, interface);
	if (!iface) {
		dev_dbg(&dev->dev, "selecting invalid interface %d\n",interface);
		return -EINVAL;
	}
	alt = usb_altnum_to_altsetting(iface, alternate);
	if (!alt) {
		dev_warn(&dev->dev, "selecting invalid altsetting %d\n",alternate);
		return -EINVAL;
	}
	mutex_lock(&hcd->bandwidth_mutex);
	ret = usb_hcd_alloc_bandwidth(dev, NULL, iface->cur_altsetting, alt);
	if (ret < 0) {
		dev_info(&dev->dev, "Not enough bandwidth for altsetting %d\n",alternate);
		mutex_unlock(&hcd->bandwidth_mutex);
		return ret;
	}
	if (dev->quirks & USB_QUIRK_NO_SET_INTF)
		ret = -EPIPE;
	else
		ret = usb_control_msg(dev, usb_sndctrlpipe(dev,0),USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,alternate, interface, NULL, 0, 5000);
	if (ret == -EPIPE && iface->num_altsetting == 1) {
		dev_dbg(&dev->dev,"manual set_interface for iface %d, alt %d\n",interface, alternate);
		manual = 1;
	} else if (ret < 0) {
		usb_hcd_alloc_bandwidth(dev, NULL, alt, iface->cur_altsetting);
		mutex_unlock(&hcd->bandwidth_mutex);
		return ret;
	}
	mutex_unlock(&hcd->bandwidth_mutex);
	if (iface->cur_altsetting != alt) {
		remove_intf_ep_devs(iface);
		usb_remove_sysfs_intf_files(iface);
	}
	usb_disable_interface(dev, iface, true);
	iface->cur_altsetting = alt;
	if (manual) {
		int i;
		for (i = 0; i < alt->desc.bNumEndpoints; i++) {
			epaddr = alt->endpoint[i].desc.bEndpointAddress;
			pipe = __create_pipe(dev,USB_ENDPOINT_NUMBER_MASK & epaddr) |(usb_endpoint_out(epaddr) ?USB_DIR_OUT : USB_DIR_IN);
			usb_clear_halt(dev, pipe);
		}
	}
	usb_enable_interface(dev, iface, true);
	if (device_is_registered(&iface->dev)) {
		usb_create_sysfs_intf_files(iface);
		create_intf_ep_devs(iface);
	}
	return 0;
}


二.usb设备注册

int usb_register_dev(struct usb_interface *intf,struct usb_class_driver *class_driver)
{
	int retval;
	int minor_base = class_driver->minor_base;
	int minor;
	char name[20];
	char *temp;
#ifdef CONFIG_USB_DYNAMIC_MINORS
	minor_base = 0;
#endif
	if (class_driver->fops == NULL)
		return -EINVAL;
	if (intf->minor >= 0)
		return -EADDRINUSE;
	retval = init_usb_class();
	if (retval)
		return retval;
	dev_dbg(&intf->dev, "looking for a minor, starting at %d", minor_base);
	down_write(&minor_rwsem);
	for (minor = minor_base; minor < MAX_USB_MINORS; ++minor) {
		if (usb_minors[minor])	//若数组不为空
			continue;
		usb_minors[minor] = class_driver->fops;	//将操作函数集放入全局usb_minors数组中
		intf->minor = minor;	//设置接口的次设备号
		break;
	}
	up_write(&minor_rwsem);
	if (intf->minor < 0)
		return -EXFULL;
	snprintf(name, sizeof(name), class_driver->name, minor - minor_base);
	temp = strrchr(name, '/');
	if (temp && (temp[1] != '\0'))
		++temp;
	else
		temp = name;
	//创建设备
	intf->usb_dev = device_create(usb_class->class, &intf->dev,MKDEV(USB_MAJOR, minor), class_driver,"%s", temp);
	if (IS_ERR(intf->usb_dev)) {
		down_write(&minor_rwsem);
		usb_minors[minor] = NULL;
		intf->minor = -1;
		up_write(&minor_rwsem);
		retval = PTR_ERR(intf->usb_dev);
	}
	return retval;
}


<---usb主控器注册
--->从usb的插入开始



 

你可能感兴趣的:(四、usb设备注册)