Esempio n. 1
0
/**
 * bus_add_device - add device to bus
 * @dev: device being added
 *
 * - Add device's bus attributes.
 * - Create links to device's bus.
 * - Add the device to its bus's list of devices.
 */
int bus_add_device(struct device *dev)
{
	struct bus_type *bus = bus_get(dev->bus);
	int error = 0;

	if (bus) {
		pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));
		error = device_add_attrs(bus, dev);
		if (error)
			goto out_put;
		error = sysfs_create_link(&bus->p->devices_kset->kobj,
						&dev->kobj, dev_name(dev));
		if (error)
			goto out_id;
		error = sysfs_create_link(&dev->kobj,
				&dev->bus->p->subsys.kobj, "subsystem");
		if (error)
			goto out_subsys;
		klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
	}
	return 0;

out_subsys:
	sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
out_id:
	device_remove_attrs(bus, dev);
out_put:
	bus_put(dev->bus);
	return error;
}
Esempio n. 2
0
static ssize_t driver_bind(struct device_driver *drv,
			   const char *buf, size_t count)
{
	struct bus_type *bus = bus_get(drv->bus);
	struct device *dev;
	int err = -ENODEV;

	dev = bus_find_device_by_name(bus, NULL, buf);
	if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
		if (dev->parent)	
			down(&dev->parent->sem);
		down(&dev->sem);
		err = driver_probe_device(drv, dev);
		up(&dev->sem);
		if (dev->parent)
			up(&dev->parent->sem);

		if (err > 0) {
			
			err = count;
		} else if (err == 0) {
			
			err = -ENODEV;
		}
	}
	put_device(dev);
	bus_put(bus);
	return err;
}
Esempio n. 3
0
/*
 * Manually attach a device to a driver.
 * Note: the driver must want to bind to the device,
 * it is not possible to override the driver's id table.
 */
static ssize_t driver_bind(struct device_driver *drv,
			   const char *buf, size_t count)
{
	struct bus_type *bus = bus_get(drv->bus);
	struct device *dev;
	int err = -ENODEV;

	dev = bus_find_device_by_name(bus, NULL, buf);
	if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
		if (dev->parent)	/* Needed for USB */
			device_lock(dev->parent);
		device_lock(dev);
		err = driver_probe_device(drv, dev);
		device_unlock(dev);
		if (dev->parent)
			device_unlock(dev->parent);

		if (err > 0) {
			/* success */
			err = count;
		} else if (err == 0) {
			/* driver didn't accept device */
			err = -ENODEV;
		}
	}
	put_device(dev);
	bus_put(bus);
	return err;
}
Esempio n. 4
0
void bus_remove_file(struct bus_type *bus, struct bus_attribute *attr)
{
	if (bus_get(bus)) {
		sysfs_remove_file(&bus->p->subsys.kobj, &attr->attr);
		bus_put(bus);
	}
}
Esempio n. 5
0
//在sysfs中添加两个链接: 一个在总线目录下指向设备,另一个在设备的目录下指向总线子系统。
int bus_add_device(struct device * dev)
{
	struct bus_type * bus = bus_get(dev->bus);
	int error = 0;

	if (bus) {
		pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
		error = device_add_attrs(bus, dev);
		if (error)
			goto out_put;
		error = sysfs_create_link(&bus->devices.kobj,
						&dev->kobj, dev->bus_id);
		if (error)
			goto out_id;
		error = sysfs_create_link(&dev->kobj,
				&dev->bus->subsys.kobj, "subsystem");
		if (error)
			goto out_subsys;
		error = make_deprecated_bus_links(dev);
		if (error)
			goto out_deprecated;
	}
	return 0;

out_deprecated:
	sysfs_remove_link(&dev->kobj, "subsystem");
out_subsys:
	sysfs_remove_link(&bus->devices.kobj, dev->bus_id);
out_id:
	device_remove_attrs(bus, dev);
out_put:
	bus_put(dev->bus);
	return error;
}
Esempio n. 6
0
/*
 * Manually attach a device to a driver.
 * Note: the driver must want to bind to the device,
 * it is not possible to override the driver's id table.
 */
static ssize_t driver_bind(struct device_driver *drv, const char *buf, size_t count)
{
	struct bus_type *bus = bus_get(drv->bus);
	struct device *dev;
	int err = -ENODEV;

	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
	if (dev && dev->driver == NULL) 
	{
		if (dev->parent)	/* Needed for USB */
			down(&dev->parent->sem);
		down(&dev->sem);
		err = driver_probe_device(drv, dev);
		up(&dev->sem);
		if (dev->parent)
			up(&dev->parent->sem);

		if (err > 0) 		/* success */
			err = count;
		else if (err == 0)	/* driver didn't accept device */
			err = -ENODEV;
	}
	put_device(dev);
	bus_put(bus);
	return err;
}
Esempio n. 7
0
int bus_create_file(struct bus_type *bus, struct bus_attribute *attr)
{
	int error;
	if (bus_get(bus)) {
		error = sysfs_create_file(&bus->p->subsys.kobj, &attr->attr);
		bus_put(bus);
	} else
		error = -EINVAL;
	return error;
}
Esempio n. 8
0
static gboolean on_handle_activate_session_on_seat(
                                              LoginKitManager *interface,
                                              GDBusMethodInvocation *invocation,
                                              const gchar *arg_session,
                                              const gchar *arg_seat,
                                              gpointer user_data)
{
	GDBusConnection *bus;
	GVariant *reply;
	GError *error = NULL;
	char *session;
	gboolean ret = FALSE;

	g_log(G_LOG_DOMAIN,
	      G_LOG_LEVEL_INFO,
	      "activating %s on %s",
	      arg_session,
	      arg_seat);

	bus = bus_get();
	if (NULL == bus)
		goto end;

	/* find the session with the passed ID */
	session = get_session_by_id(bus, arg_session);
	if (NULL == session)
		goto end;

	reply = g_dbus_connection_call_sync(bus,
	                                    "org.freedesktop.ConsoleKit",
	                                    arg_session,
	                                    "org.freedesktop.ConsoleKit.Session",
	                                    "Activate",
	                                    NULL,
	                                    NULL,
	                                    G_DBUS_CALL_FLAGS_NONE,
	                                    -1,
	                                    NULL,
	                                    &error);
	if (NULL == reply) {
		if (NULL != error)
			g_error_free(error);
		goto end;
	}

	g_variant_unref(reply);

	ret = TRUE;

end:
	login_kit_manager_complete_activate_session_on_seat(interface, invocation);
	return ret;
}
Esempio n. 9
0
/**
 *	bus_add_driver - Add a driver to the bus.
 *	@drv:	driver.
 *
 */
int bus_add_driver(struct device_driver *drv)
{
	struct bus_type * bus = bus_get(drv->bus);
	int error = 0;

	if (!bus)
		return -EINVAL;

	pr_debug("bus %s: add driver %s\n", bus->name, drv->name);
	error = kobject_set_name(&drv->kobj, "%s", drv->name);
	if (error)
		goto out_put_bus;
	drv->kobj.kset = &bus->drivers;
	error = kobject_register(&drv->kobj);
	if (error)
		goto out_put_bus;

	//如果总线支持自动探测,则调用driver_attach。
	if (drv->bus->drivers_autoprobe)
	{
		error = driver_attach(drv);
		if (error)
			goto out_unregister;
	}
	//将该驱动程序添加到总线上注册的所有驱动程序的链表中
	klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
	module_add_driver(drv->owner, drv);

	error = driver_create_file(drv, &driver_attr_uevent);
	if (error)
	{
		printk(KERN_ERR "%s: uevent attr (%s) failed\n", __FUNCTION__, drv->name);
	}
	error = driver_add_attrs(bus, drv);
	if (error) 
	{
		/* How the hell do we get out of this pickle? Give up */
		printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", __FUNCTION__, drv->name);
	}
	error = add_bind_files(drv);
	if (error)
	{
		/* Ditto */
		printk(KERN_ERR "%s: add_bind_files(%s) failed\n", __FUNCTION__, drv->name);
	}

	return error;
out_unregister:
	kobject_unregister(&drv->kobj);
out_put_bus:
	bus_put(bus);
	return error;
}
Esempio n. 10
0
File: bus.c Progetto: Anjali05/linux
/* Manually detach a device from its associated driver. */
static ssize_t unbind_store(struct device_driver *drv, const char *buf,
			    size_t count)
{
	struct bus_type *bus = bus_get(drv->bus);
	struct device *dev;
	int err = -ENODEV;

	dev = bus_find_device_by_name(bus, NULL, buf);
	if (dev && dev->driver == drv) {
		device_driver_detach(dev);
		err = count;
	}
	put_device(dev);
	bus_put(bus);
	return err;
}
Esempio n. 11
0
static void signals_unsubscribe(void)
{
	GDBusConnection *bus;

	bus = bus_get();
	if (NULL == bus)
		return;

	if (0 != g_added_signal) {
		g_dbus_connection_signal_unsubscribe(bus, g_added_signal);
		g_added_signal = 0;
	}

	if (0 != g_removed_signal) {
		g_dbus_connection_signal_unsubscribe(bus, g_removed_signal);
		g_removed_signal = 0;
	}
}
Esempio n. 12
0
/* Manually detach a device from its associated driver. */
static ssize_t driver_unbind(struct device_driver *drv,
			     const char *buf, size_t count)
{
	struct bus_type *bus = bus_get(drv->bus);
	struct device *dev;
	int err = -ENODEV;

	dev = bus_find_device_by_name(bus, NULL, buf);
	if (dev && dev->driver == drv) {
		if (dev->parent)	/* Needed for USB */
			device_lock(dev->parent);
		device_release_driver(dev);
		if (dev->parent)
			device_unlock(dev->parent);
		err = count;
	}
	put_device(dev);
	bus_put(bus);
	return err;
}
Esempio n. 13
0
static ssize_t driver_unbind(struct device_driver *drv,
			     const char *buf, size_t count)
{
	struct bus_type *bus = bus_get(drv->bus);
	struct device *dev;
	int err = -ENODEV;

	dev = bus_find_device(bus, NULL, (void *)buf, driver_helper);
	if (dev && dev->driver == drv) {
		if (dev->parent)	/* Needed for USB */
			down(&dev->parent->sem);
		device_release_driver(dev);
		if (dev->parent)
			up(&dev->parent->sem);
		err = count;
	}
	put_device(dev);
	bus_put(bus);
	return err;
}
Esempio n. 14
0
/**
 * bus_add_device :设备dev和其所在的bus之间创建符号链接
 * @dev:待加入设备 
 */
int bus_add_device(struct device *dev)
{
	struct bus_type *bus = bus_get(dev->bus);
	int error = 0;

	if (bus) {
		pr_debug("bus: '%s': add device %s\n", bus->name, dev_name(dev));
		/*在dev->kobj目录下创建设备的属性文件,属性文件为bus的属性文件*/
		error = device_add_attrs(bus, dev);
		if (error)
			goto out_put;
		/*在dev所属bus的device目录下创建指向dev->kobj目录的符号链接,
		 *名字为dev_name(dev)*/
		error = sysfs_create_link(&bus->p->devices_kset->kobj,
						&dev->kobj, dev_name(dev));
		if (error)
			goto out_id;
		/*在dev->kobj目录下创建指向其所在bus目录的符号链接,
		 * 符号名称为subsystem*/
		error = sysfs_create_link(&dev->kobj,
				&dev->bus->p->subsys.kobj, "subsystem");
		if (error)
			goto out_subsys;
		error = make_deprecated_bus_links(dev);
		if (error)
			goto out_deprecated;
		/*dev链入的bus的设备链表中*/
		klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
	}
	return 0;

out_deprecated:
	sysfs_remove_link(&dev->kobj, "subsystem");
out_subsys:
	sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev));
out_id:
	device_remove_attrs(bus, dev);
out_put:
	bus_put(dev->bus);
	return error;
}
Esempio n. 15
0
File: bus.c Progetto: Anjali05/linux
/*
 * Manually attach a device to a driver.
 * Note: the driver must want to bind to the device,
 * it is not possible to override the driver's id table.
 */
static ssize_t bind_store(struct device_driver *drv, const char *buf,
			  size_t count)
{
	struct bus_type *bus = bus_get(drv->bus);
	struct device *dev;
	int err = -ENODEV;

	dev = bus_find_device_by_name(bus, NULL, buf);
	if (dev && dev->driver == NULL && driver_match_device(drv, dev)) {
		err = device_driver_attach(drv, dev);

		if (err > 0) {
			/* success */
			err = count;
		} else if (err == 0) {
			/* driver didn't accept device */
			err = -ENODEV;
		}
	}
	put_device(dev);
	bus_put(bus);
	return err;
}
Esempio n. 16
0
/**
 * bus_add_driver - Add a driver to the bus.
 * @drv: driver.
 */
int bus_add_driver(struct device_driver *drv)
{
	struct bus_type *bus;
	struct driver_private *priv;
	int error = 0;

	bus = bus_get(drv->bus);
	if (!bus)
		return -EINVAL;

	pr_debug("bus: '%s': add driver %s\n", bus->name, drv->name);

	priv = kzalloc(sizeof(*priv), GFP_KERNEL);
	if (!priv) {
		error = -ENOMEM;
		goto out_put_bus;
	}
	klist_init(&priv->klist_devices, NULL, NULL);
	priv->driver = drv;
	drv->p = priv;
	priv->kobj.kset = bus->p->drivers_kset;
	error = kobject_init_and_add(&priv->kobj, &driver_ktype, NULL,
				     "%s", drv->name);
	if (error)
		goto out_unregister;

	if (drv->bus->p->drivers_autoprobe) {
		error = driver_attach(drv);
		if (error)
			goto out_unregister;
	}
	klist_add_tail(&priv->knode_bus, &bus->p->klist_drivers);
	module_add_driver(drv->owner, drv);

	error = driver_create_file(drv, &driver_attr_uevent);
	if (error) {
		printk(KERN_ERR "%s: uevent attr (%s) failed\n",
			__func__, drv->name);
	}
	error = driver_add_attrs(bus, drv);
	if (error) {
		/* How the hell do we get out of this pickle? Give up */
		printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n",
			__func__, drv->name);
	}

	if (!drv->suppress_bind_attrs) {
		error = add_bind_files(drv);
		if (error) {
			/* Ditto */
			printk(KERN_ERR "%s: add_bind_files(%s) failed\n",
				__func__, drv->name);
		}
	}

	kobject_uevent(&priv->kobj, KOBJ_ADD);
	return 0;

out_unregister:
	kfree(drv->p);
	drv->p = NULL;
	kobject_put(&priv->kobj);
out_put_bus:
	bus_put(bus);
	return error;
}
Esempio n. 17
0
/* the logind documentation says: "ListSeats() returns an array with all
 * currently available seats. The structure in the array consists of the
 * following fields: seat id, seat object path.". however, ConsoleKit's
 * GetSeats method returns only the object path, so we have to call
 * GetId for each seat */
static gboolean on_handle_list_seats(LoginKitManager *interface,
                                     GDBusMethodInvocation *invocation,
                                     gpointer user_data)
{
	GVariantIter iter;
	GVariant *reply;
	GError *error = NULL;
	GDBusConnection *bus;
	GVariantBuilder *builder;
	GVariant *ret;
	GVariant *seats;
	char *seat;
	char *id;

	g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "listing available seats");

	bus = bus_get();
	if (NULL == bus)
		return FALSE;

	/* list all seats */
	reply = g_dbus_connection_call_sync(bus,
	                                    "org.freedesktop.ConsoleKit",
	                                    "/org/freedesktop/ConsoleKit/Manager",
	                                    "org.freedesktop.ConsoleKit.Manager",
	                                    "GetSeats",
	                                    NULL,
	                                    G_VARIANT_TYPE("(ao)"),
	                                    G_DBUS_CALL_FLAGS_NONE,
	                                    -1,
	                                    NULL,
	                                    &error);
	if (NULL == reply) {
		if (NULL != error)
			g_error_free(error);
		return FALSE;
	}

	seats = g_variant_get_child_value(reply, 0);
	g_variant_iter_init(&iter, seats);

	/* create a builder object, to initialize an array */
	builder = g_variant_builder_new(G_VARIANT_TYPE("a(so)"));

	/* do a best-effort attempt to enumerate all seats */
	while (TRUE == g_variant_iter_loop(&iter, "o", &seat, NULL)) {
		id = get_seat_id(bus, seat);
		if (NULL == id)
			continue;
		g_variant_builder_add(builder, "(so)", id, seat);
	}

	g_variant_unref(reply);
	g_variant_unref(seats);

	ret = g_variant_new("a(so)", builder);
	g_variant_builder_unref(builder);

	login_kit_manager_complete_list_seats(interface, invocation, ret);

	return TRUE;
}