⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bus.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
		device_detach_shutdown(dev);		if (drv->remove)			drv->remove(dev);		dev->driver = NULL;	}}/** *	driver_detach - detach driver from all devices it controls. *	@drv:	driver. */static void driver_detach(struct device_driver * drv){	struct list_head * entry, * next;	list_for_each_safe(entry, next, &drv->devices) {		struct device * dev = container_of(entry, struct device, driver_list);		device_release_driver(dev);	}}static int device_add_attrs(struct bus_type * bus, struct device * dev){	int error = 0;	int i;	if (bus->dev_attrs) {		for (i = 0; attr_name(bus->dev_attrs[i]); i++) {			error = device_create_file(dev,&bus->dev_attrs[i]);			if (error)				goto Err;		}	} Done:	return error; Err:	while (--i >= 0)		device_remove_file(dev,&bus->dev_attrs[i]);	goto Done;}static void device_remove_attrs(struct bus_type * bus, struct device * dev){	int i;	if (bus->dev_attrs) {		for (i = 0; attr_name(bus->dev_attrs[i]); i++)			device_remove_file(dev,&bus->dev_attrs[i]);	}}/** *	bus_add_device - add device to bus *	@dev:	device being added * *	- Add the device to its bus's list of devices. *	- Try to attach to driver. *	- Create link to device's physical location. */int bus_add_device(struct device * dev){	struct bus_type * bus = get_bus(dev->bus);	int error = 0;	if (bus) {		down_write(&dev->bus->subsys.rwsem);		pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);		list_add_tail(&dev->bus_list, &dev->bus->devices.list);		device_attach(dev);		up_write(&dev->bus->subsys.rwsem);		device_add_attrs(bus, dev);		sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);	}	return error;}/** *	bus_remove_device - remove device from bus *	@dev:	device to be removed * *	- Remove symlink from bus's directory. *	- Delete device from bus's list. *	- Detach from its driver. *	- Drop reference taken in bus_add_device(). */void bus_remove_device(struct device * dev){	if (dev->bus) {		sysfs_remove_link(&dev->bus->devices.kobj, dev->bus_id);		device_remove_attrs(dev->bus, dev);		down_write(&dev->bus->subsys.rwsem);		pr_debug("bus %s: remove device %s\n", dev->bus->name, dev->bus_id);		device_release_driver(dev);		list_del_init(&dev->bus_list);		up_write(&dev->bus->subsys.rwsem);		put_bus(dev->bus);	}}static int driver_add_attrs(struct bus_type * bus, struct device_driver * drv){	int error = 0;	int i;	if (bus->drv_attrs) {		for (i = 0; attr_name(bus->drv_attrs[i]); i++) {			error = driver_create_file(drv, &bus->drv_attrs[i]);			if (error)				goto Err;		}	} Done:	return error; Err:	while (--i >= 0)		driver_remove_file(drv, &bus->drv_attrs[i]);	goto Done;}static void driver_remove_attrs(struct bus_type * bus, struct device_driver * drv){	int i;	if (bus->drv_attrs) {		for (i = 0; attr_name(bus->drv_attrs[i]); i++)			driver_remove_file(drv, &bus->drv_attrs[i]);	}}/** *	bus_add_driver - Add a driver to the bus. *	@drv:	driver. * */int bus_add_driver(struct device_driver * drv){	struct bus_type * bus = get_bus(drv->bus);	int error = 0;	if (bus) {		pr_debug("bus %s: add driver %s\n", bus->name, drv->name);		error = kobject_set_name(&drv->kobj, drv->name);		if (error) {			put_bus(bus);			return error;		}		drv->kobj.kset = &bus->drivers;		if ((error = kobject_register(&drv->kobj))) {			put_bus(bus);			return error;		}		down_write(&bus->subsys.rwsem);		driver_attach(drv);		up_write(&bus->subsys.rwsem);		driver_add_attrs(bus, drv);	}	return error;}/** *	bus_remove_driver - delete driver from bus's knowledge. *	@drv:	driver. * *	Detach the driver from the devices it controls, and remove *	it from its bus's list of drivers. Finally, we drop the reference *	to the bus we took in bus_add_driver(). */void bus_remove_driver(struct device_driver * drv){	if (drv->bus) {		driver_remove_attrs(drv->bus, drv);		down_write(&drv->bus->subsys.rwsem);		pr_debug("bus %s: remove driver %s\n", drv->bus->name, drv->name);		driver_detach(drv);		up_write(&drv->bus->subsys.rwsem);		kobject_unregister(&drv->kobj);		put_bus(drv->bus);	}}/* Helper for bus_rescan_devices's iter */static int bus_rescan_devices_helper(struct device *dev, void *data){	int *count = data;	if (!dev->driver && device_attach(dev))		(*count)++;	return 0;}/** *	bus_rescan_devices - rescan devices on the bus for possible drivers *	@bus:	the bus to scan. * *	This function will look for devices on the bus with no driver *	attached and rescan it against existing drivers to see if it *	matches any. Calls device_attach(). Returns the number of devices *	that were sucessfully bound to a driver. */int bus_rescan_devices(struct bus_type * bus){	int count = 0;	bus_for_each_dev(bus, NULL, &count, bus_rescan_devices_helper);	return count;}struct bus_type * get_bus(struct bus_type * bus){	return bus ? container_of(subsys_get(&bus->subsys), struct bus_type, subsys) : NULL;}void put_bus(struct bus_type * bus){	subsys_put(&bus->subsys);}/** *	find_bus - locate bus by name. *	@name:	name of bus. * *	Call kset_find_obj() to iterate over list of buses to *	find a bus by name. Return bus if found. * *	Note that kset_find_obj increments bus' reference count. */struct bus_type * find_bus(char * name){	struct kobject * k = kset_find_obj(&bus_subsys.kset, name);	return k ? to_bus(k) : NULL;}/** *	bus_add_attrs - Add default attributes for this bus. *	@bus:	Bus that has just been registered. */static int bus_add_attrs(struct bus_type * bus){	int error = 0;	int i;	if (bus->bus_attrs) {		for (i = 0; attr_name(bus->bus_attrs[i]); i++) {			if ((error = bus_create_file(bus,&bus->bus_attrs[i])))				goto Err;		}	} Done:	return error; Err:	while (--i >= 0)		bus_remove_file(bus,&bus->bus_attrs[i]);	goto Done;}static void bus_remove_attrs(struct bus_type * bus){	int i;	if (bus->bus_attrs) {		for (i = 0; attr_name(bus->bus_attrs[i]); i++)			bus_remove_file(bus,&bus->bus_attrs[i]);	}}/** *	bus_register - register a bus with the system. *	@bus:	bus. * *	Once we have that, we registered the bus with the kobject *	infrastructure, then register the children subsystems it has: *	the devices and drivers that belong to the bus. */int bus_register(struct bus_type * bus){	int retval;	retval = kobject_set_name(&bus->subsys.kset.kobj, bus->name);	if (retval)		goto out;	subsys_set_kset(bus, bus_subsys);	retval = subsystem_register(&bus->subsys);	if (retval)		goto out;	kobject_set_name(&bus->devices.kobj, "devices");	bus->devices.subsys = &bus->subsys;	retval = kset_register(&bus->devices);	if (retval)		goto bus_devices_fail;	kobject_set_name(&bus->drivers.kobj, "drivers");	bus->drivers.subsys = &bus->subsys;	bus->drivers.ktype = &ktype_driver;	retval = kset_register(&bus->drivers);	if (retval)		goto bus_drivers_fail;	bus_add_attrs(bus);	pr_debug("bus type '%s' registered\n", bus->name);	return 0;bus_drivers_fail:	kset_unregister(&bus->devices);bus_devices_fail:	subsystem_unregister(&bus->subsys);out:	return retval;}/** *	bus_unregister - remove a bus from the system *	@bus:	bus. * *	Unregister the child subsystems and the bus itself. *	Finally, we call put_bus() to release the refcount */void bus_unregister(struct bus_type * bus){	pr_debug("bus %s: unregistering\n", bus->name);	bus_remove_attrs(bus);	kset_unregister(&bus->drivers);	kset_unregister(&bus->devices);	subsystem_unregister(&bus->subsys);}int __init buses_init(void){	return subsystem_register(&bus_subsys);}EXPORT_SYMBOL(bus_for_each_dev);EXPORT_SYMBOL(bus_for_each_drv);EXPORT_SYMBOL(device_bind_driver);EXPORT_SYMBOL(device_release_driver);EXPORT_SYMBOL(bus_add_device);EXPORT_SYMBOL(bus_remove_device);EXPORT_SYMBOL(bus_register);EXPORT_SYMBOL(bus_unregister);EXPORT_SYMBOL(bus_rescan_devices);EXPORT_SYMBOL(get_bus);EXPORT_SYMBOL(put_bus);EXPORT_SYMBOL(find_bus);EXPORT_SYMBOL(bus_create_file);EXPORT_SYMBOL(bus_remove_file);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -