Skip to content

Commit

Permalink
Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6
Browse files Browse the repository at this point in the history
  • Loading branch information
Linus Torvalds committed Sep 6, 2005
2 parents 8566cfc + d856f1e commit f65e776
Show file tree
Hide file tree
Showing 10 changed files with 178 additions and 70 deletions.
28 changes: 14 additions & 14 deletions Documentation/filesystems/sysfs.txt
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ void device_remove_file(struct device *, struct device_attribute *);

It also defines this helper for defining device attributes:

#define DEVICE_ATTR(_name,_mode,_show,_store) \
#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = { \
.attr = {.name = __stringify(_name) , .mode = _mode }, \
.show = _show, \
Expand All @@ -99,14 +99,14 @@ struct device_attribute dev_attr_##_name = { \

For example, declaring

static DEVICE_ATTR(foo,0644,show_foo,store_foo);
static DEVICE_ATTR(foo, S_IWUSR | S_IRUGO, show_foo, store_foo);

is equivalent to doing:

static struct device_attribute dev_attr_foo = {
.attr = {
.name = "foo",
.mode = 0644,
.mode = S_IWUSR | S_IRUGO,
},
.show = show_foo,
.store = store_foo,
Expand All @@ -121,8 +121,8 @@ set of sysfs operations for forwarding read and write calls to the
show and store methods of the attribute owners.

struct sysfs_ops {
ssize_t (*show)(struct kobject *, struct attribute *,char *);
ssize_t (*store)(struct kobject *,struct attribute *,const char *);
ssize_t (*show)(struct kobject *, struct attribute *, char *);
ssize_t (*store)(struct kobject *, struct attribute *, const char *);
};

[ Subsystems should have already defined a struct kobj_type as a
Expand All @@ -137,7 +137,7 @@ calls the associated methods.

To illustrate:

#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
#define to_dev_attr(_attr) container_of(_attr, struct device_attribute, attr)
#define to_dev(d) container_of(d, struct device, kobj)

static ssize_t
Expand All @@ -148,7 +148,7 @@ dev_attr_show(struct kobject * kobj, struct attribute * attr, char * buf)
ssize_t ret = 0;

if (dev_attr->show)
ret = dev_attr->show(dev,buf);
ret = dev_attr->show(dev, buf);
return ret;
}

Expand Down Expand Up @@ -216,16 +216,16 @@ A very simple (and naive) implementation of a device attribute is:

static ssize_t show_name(struct device *dev, struct device_attribute *attr, char *buf)
{
return sprintf(buf,"%s\n",dev->name);
return snprintf(buf, PAGE_SIZE, "%s\n", dev->name);
}

static ssize_t store_name(struct device * dev, const char * buf)
{
sscanf(buf,"%20s",dev->name);
return strlen(buf);
sscanf(buf, "%20s", dev->name);
return strnlen(buf, PAGE_SIZE);
}

static DEVICE_ATTR(name,S_IRUGO,show_name,store_name);
static DEVICE_ATTR(name, S_IRUGO, show_name, store_name);


(Note that the real implementation doesn't allow userspace to set the
Expand Down Expand Up @@ -290,7 +290,7 @@ struct device_attribute {

Declaring:

DEVICE_ATTR(_name,_str,_mode,_show,_store);
DEVICE_ATTR(_name, _str, _mode, _show, _store);

Creation/Removal:

Expand All @@ -310,7 +310,7 @@ struct bus_attribute {

Declaring:

BUS_ATTR(_name,_mode,_show,_store)
BUS_ATTR(_name, _mode, _show, _store)

Creation/Removal:

Expand All @@ -331,7 +331,7 @@ struct driver_attribute {

Declaring:

DRIVER_ATTR(_name,_mode,_show,_store)
DRIVER_ATTR(_name, _mode, _show, _store)

Creation/Removal:

Expand Down
8 changes: 5 additions & 3 deletions drivers/base/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,9 @@ static ssize_t driver_unbind(struct device_driver *drv,
device_release_driver(dev);
err = count;
}
return err;
if (err)
return err;
return count;
}
static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind);

Expand Down Expand Up @@ -358,7 +360,7 @@ int bus_add_device(struct device * dev)
if (bus) {
pr_debug("bus %s: add device %s\n", bus->name, dev->bus_id);
device_attach(dev);
klist_add_tail(&bus->klist_devices, &dev->knode_bus);
klist_add_tail(&dev->knode_bus, &bus->klist_devices);
error = device_add_attrs(bus, dev);
if (!error) {
sysfs_create_link(&bus->devices.kobj, &dev->kobj, dev->bus_id);
Expand Down Expand Up @@ -446,7 +448,7 @@ int bus_add_driver(struct device_driver * drv)
}

driver_attach(drv);
klist_add_tail(&bus->klist_drivers, &drv->knode_bus);
klist_add_tail(&drv->knode_bus, &bus->klist_drivers);
module_add_driver(drv->owner, drv);

driver_add_attrs(bus, drv);
Expand Down
39 changes: 33 additions & 6 deletions drivers/base/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -299,10 +299,8 @@ static void class_dev_release(struct kobject * kobj)

pr_debug("device class '%s': release.\n", cd->class_id);

if (cd->devt_attr) {
kfree(cd->devt_attr);
cd->devt_attr = NULL;
}
kfree(cd->devt_attr);
cd->devt_attr = NULL;

if (cls->release)
cls->release(cd);
Expand Down Expand Up @@ -452,10 +450,29 @@ void class_device_initialize(struct class_device *class_dev)
INIT_LIST_HEAD(&class_dev->node);
}

static char *make_class_name(struct class_device *class_dev)
{
char *name;
int size;

size = strlen(class_dev->class->name) +
strlen(kobject_name(&class_dev->kobj)) + 2;

name = kmalloc(size, GFP_KERNEL);
if (!name)
return ERR_PTR(-ENOMEM);

strcpy(name, class_dev->class->name);
strcat(name, ":");
strcat(name, kobject_name(&class_dev->kobj));
return name;
}

int class_device_add(struct class_device *class_dev)
{
struct class * parent = NULL;
struct class_interface * class_intf;
char *class_name = NULL;
int error;

class_dev = class_device_get(class_dev);
Expand Down Expand Up @@ -500,9 +517,13 @@ int class_device_add(struct class_device *class_dev)
}

class_device_add_attrs(class_dev);
if (class_dev->dev)
if (class_dev->dev) {
class_name = make_class_name(class_dev);
sysfs_create_link(&class_dev->kobj,
&class_dev->dev->kobj, "device");
sysfs_create_link(&class_dev->dev->kobj, &class_dev->kobj,
class_name);
}

/* notify any interfaces this device is now here */
if (parent) {
Expand All @@ -519,6 +540,7 @@ int class_device_add(struct class_device *class_dev)
if (error && parent)
class_put(parent);
class_device_put(class_dev);
kfree(class_name);
return error;
}

Expand Down Expand Up @@ -584,6 +606,7 @@ void class_device_del(struct class_device *class_dev)
{
struct class * parent = class_dev->class;
struct class_interface * class_intf;
char *class_name = NULL;

if (parent) {
down(&parent->sem);
Expand All @@ -594,8 +617,11 @@ void class_device_del(struct class_device *class_dev)
up(&parent->sem);
}

if (class_dev->dev)
if (class_dev->dev) {
class_name = make_class_name(class_dev);
sysfs_remove_link(&class_dev->kobj, "device");
sysfs_remove_link(&class_dev->dev->kobj, class_name);
}
if (class_dev->devt_attr)
class_device_remove_file(class_dev, class_dev->devt_attr);
class_device_remove_attrs(class_dev);
Expand All @@ -605,6 +631,7 @@ void class_device_del(struct class_device *class_dev)

if (parent)
class_put(parent);
kfree(class_name);
}

void class_device_unregister(struct class_device *class_dev)
Expand Down
2 changes: 1 addition & 1 deletion drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ int device_add(struct device *dev)
if ((error = bus_add_device(dev)))
goto BusError;
if (parent)
klist_add_tail(&parent->klist_children, &dev->knode_parent);
klist_add_tail(&dev->knode_parent, &parent->klist_children);

/* notify platform of device entry */
if (platform_notify)
Expand Down
2 changes: 1 addition & 1 deletion drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void device_bind_driver(struct device * dev)
{
pr_debug("bound device '%s' to driver '%s'\n",
dev->bus_id, dev->driver->name);
klist_add_tail(&dev->driver->klist_devices, &dev->knode_driver);
klist_add_tail(&dev->knode_driver, &dev->driver->klist_devices);
sysfs_create_link(&dev->driver->kobj, &dev->kobj,
kobject_name(&dev->kobj));
sysfs_create_link(&dev->kobj, &dev->driver->kobj, "driver");
Expand Down
Loading

0 comments on commit f65e776

Please sign in to comment.