Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@penguin.transmeta.com>2002-07-31 23:38:44 -0700
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-07-31 23:38:44 -0700
commit1a6c88f4b7a57f09935775e077db56764fb50fe0 (patch)
treeca55c1f663db60dc7210f88bd2651202d821ca83
parent1bd9236b6d237f9cd928e83cc449240a76b00310 (diff)
parent9e27f077152b4aa70184166406eed14005a83faa (diff)
Merge bk://ldm.bkbits.net/linux-2.5-driverfs-api
into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
-rw-r--r--drivers/base/base.h1
-rw-r--r--drivers/base/bus.c2
-rw-r--r--drivers/base/fs.c75
-rw-r--r--drivers/base/interface.c20
-rw-r--r--drivers/pci/proc.c16
-rw-r--r--drivers/scsi/scsi_scan.c8
-rw-r--r--drivers/scsi/sg.c20
-rw-r--r--drivers/scsi/sr.c16
-rw-r--r--drivers/scsi/st.c28
-rw-r--r--drivers/usb/core/usb.c41
-rw-r--r--fs/driverfs/inode.c59
-rw-r--r--fs/partitions/check.c28
-rw-r--r--include/linux/device.h22
-rw-r--r--include/linux/driverfs_fs.h20
14 files changed, 176 insertions, 180 deletions
diff --git a/drivers/base/base.h b/drivers/base/base.h
index 5413942ce8f6..35f09fc219e1 100644
--- a/drivers/base/base.h
+++ b/drivers/base/base.h
@@ -17,6 +17,7 @@ extern int device_make_dir(struct device * dev);
extern void device_remove_dir(struct device * dev);
extern int device_bus_link(struct device * dev);
+extern void device_remove_symlink(struct driver_dir_entry * dir, const char * name);
extern int driver_attach(struct device_driver * drv);
extern void driver_detach(struct device_driver * drv);
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 95d41d896911..4f9affd88253 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -140,7 +140,7 @@ int bus_add_device(struct device * dev)
void bus_remove_device(struct device * dev)
{
if (dev->bus) {
- driverfs_remove_file(&dev->bus->device_dir,dev->bus_id);
+ device_remove_symlink(&dev->bus->device_dir,dev->bus_id);
write_lock(&dev->bus->lock);
list_del_init(&dev->bus_list);
write_unlock(&dev->bus->lock);
diff --git a/drivers/base/fs.c b/drivers/base/fs.c
index 1429392c1533..62df2c48be3f 100644
--- a/drivers/base/fs.c
+++ b/drivers/base/fs.c
@@ -15,7 +15,63 @@
#include <linux/stat.h>
#include <linux/limits.h>
-extern struct driver_file_entry * device_default_files[];
+extern struct device_attribute * device_default_files[];
+
+#define to_dev_attr(_attr) container_of(_attr,struct device_attribute,attr)
+
+#define to_device(d) container_of(d, struct device, dir)
+
+
+/* driverfs ops for device attribute files */
+
+static int
+dev_attr_open(struct driver_dir_entry * dir)
+{
+ struct device * dev = to_device(dir);
+ get_device(dev);
+ return 0;
+}
+
+static int
+dev_attr_close(struct driver_dir_entry * dir)
+{
+ struct device * dev = to_device(dir);
+ put_device(dev);
+ return 0;
+}
+
+static ssize_t
+dev_attr_show(struct driver_dir_entry * dir, struct attribute * attr,
+ char * buf, size_t count, loff_t off)
+{
+ struct device_attribute * dev_attr = to_dev_attr(attr);
+ struct device * dev = to_device(dir);
+ ssize_t ret = 0;
+
+ if (dev_attr->show)
+ ret = dev_attr->show(dev,buf,count,off);
+ return ret;
+}
+
+static ssize_t
+dev_attr_store(struct driver_dir_entry * dir, struct attribute * attr,
+ const char * buf, size_t count, loff_t off)
+{
+ struct device_attribute * dev_attr = to_dev_attr(attr);
+ struct device * dev = to_device(dir);
+ ssize_t ret = 0;
+
+ if (dev_attr->store)
+ ret = dev_attr->store(dev,buf,count,off);
+ return ret;
+}
+
+static struct driverfs_ops dev_attr_ops = {
+ open: dev_attr_open,
+ close: dev_attr_close,
+ show: dev_attr_show,
+ store: dev_attr_store,
+};
/**
* device_create_file - create a driverfs file for a device
@@ -24,13 +80,13 @@ extern struct driver_file_entry * device_default_files[];
*
* Allocate space for file entry, copy descriptor, and create.
*/
-int device_create_file(struct device * dev, struct driver_file_entry * entry)
+int device_create_file(struct device * dev, struct device_attribute * entry)
{
int error = -EINVAL;
if (dev) {
get_device(dev);
- error = driverfs_create_file(entry,&dev->dir);
+ error = driverfs_create_file(&entry->attr,&dev->dir);
put_device(dev);
}
return error;
@@ -42,11 +98,11 @@ int device_create_file(struct device * dev, struct driver_file_entry * entry)
* @name: name of the file
*
*/
-void device_remove_file(struct device * dev, const char * name)
+void device_remove_file(struct device * dev, struct device_attribute * attr)
{
if (dev) {
get_device(dev);
- driverfs_remove_file(&dev->dir,name);
+ driverfs_remove_file(&dev->dir,attr->attr.name);
put_device(dev);
}
}
@@ -61,7 +117,6 @@ void device_remove_dir(struct device * dev)
driverfs_remove_dir(&dev->dir);
}
-
static int get_devpath_length(struct device * dev)
{
int length = 1;
@@ -127,6 +182,11 @@ int device_bus_link(struct device * dev)
return error;
}
+void device_remove_symlink(struct driver_dir_entry * dir, const char * name)
+{
+ driverfs_remove_file(dir,name);
+}
+
int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * parent)
{
dir->mode = (S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO);
@@ -148,13 +208,14 @@ int device_create_dir(struct driver_dir_entry * dir, struct driver_dir_entry * p
int device_make_dir(struct device * dev)
{
struct driver_dir_entry * parent = NULL;
- struct driver_file_entry * entry;
+ struct device_attribute * entry;
int error;
int i;
if (dev->parent)
parent = &dev->parent->dir;
dev->dir.name = dev->bus_id;
+ dev->dir.ops = &dev_attr_ops;
if ((error = device_create_dir(&dev->dir,parent)))
return error;
diff --git a/drivers/base/interface.c b/drivers/base/interface.c
index 5d03984a273f..7c1f2fb94de2 100644
--- a/drivers/base/interface.c
+++ b/drivers/base/interface.c
@@ -14,11 +14,7 @@ static ssize_t device_read_name(struct device * dev, char * buf, size_t count, l
return off ? 0 : sprintf(buf,"%s\n",dev->name);
}
-static struct driver_file_entry device_name_entry = {
- name: "name",
- mode: S_IRUGO,
- show: device_read_name,
-};
+static DEVICE_ATTR(name,"name",S_IRUGO,device_read_name,NULL);
static ssize_t
device_read_power(struct device * dev, char * page, size_t count, loff_t off)
@@ -89,15 +85,11 @@ device_write_power(struct device * dev, const char * buf, size_t count, loff_t o
return error < 0 ? error : count;
}
-static struct driver_file_entry device_power_entry = {
- name: "power",
- mode: S_IWUSR | S_IRUGO,
- show: device_read_power,
- store: device_write_power,
-};
+static DEVICE_ATTR(power,"power",S_IWUSR | S_IRUGO,
+ device_read_power,device_write_power);
-struct driver_file_entry * device_default_files[] = {
- &device_name_entry,
- &device_power_entry,
+struct device_attribute * device_default_files[] = {
+ &dev_attr_name,
+ &dev_attr_power,
NULL,
};
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c
index 0359172c3d37..7dd1a28b3435 100644
--- a/drivers/pci/proc.c
+++ b/drivers/pci/proc.c
@@ -378,11 +378,7 @@ static ssize_t pci_show_irq(struct device * dev, char * buf, size_t count, loff_
return off ? 0 : sprintf(buf,"%u\n",pci_dev->irq);
}
-static struct driver_file_entry pci_irq_entry = {
- name: "irq",
- mode: S_IRUGO,
- show: pci_show_irq,
-};
+static DEVICE_ATTR(irq,"irq",S_IRUGO,pci_show_irq,NULL);
static ssize_t pci_show_resources(struct device * dev, char * buf, size_t count, loff_t off)
{
@@ -406,11 +402,7 @@ static ssize_t pci_show_resources(struct device * dev, char * buf, size_t count,
return (str - buf);
}
-static struct driver_file_entry pci_resource_entry = {
- name: "resources",
- mode: S_IRUGO,
- show: pci_show_resources,
-};
+static DEVICE_ATTR(resource,"resource",S_IRUGO,pci_show_resources,NULL);
int pci_proc_attach_device(struct pci_dev *dev)
{
@@ -432,8 +424,8 @@ int pci_proc_attach_device(struct pci_dev *dev)
e->data = dev;
e->size = PCI_CFG_SPACE_SIZE;
- device_create_file(&dev->dev,&pci_irq_entry);
- device_create_file(&dev->dev,&pci_resource_entry);
+ device_create_file(&dev->dev,&dev_attr_irq);
+ device_create_file(&dev->dev,&dev_attr_resource);
return 0;
}
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
index ab24c64763d9..bd6d234c886e 100644
--- a/drivers/scsi/scsi_scan.c
+++ b/drivers/scsi/scsi_scan.c
@@ -305,12 +305,8 @@ static ssize_t scsi_device_type_read(struct device *driverfs_dev, char *page,
return 0;
}
+static DEVICE_ATTR(type,"type",S_IRUGO,scsi_device_type_read,NULL);
-static struct driver_file_entry scsi_device_type_file = {
- name: "type",
- mode: S_IRUGO,
- show: scsi_device_type_read,
-};
/* end content handlers */
static void print_inquiry(unsigned char *data)
@@ -825,7 +821,7 @@ static int scan_scsis_single(unsigned int channel, unsigned int dev,
/* Create driverfs file entries */
device_create_file(&SDpnt->sdev_driverfs_dev,
- &scsi_device_type_file);
+ &dev_attr_type);
sprintf (devname, "host%d/bus%d/target%d/lun%d",
SDpnt->host->host_no, SDpnt->channel, SDpnt->id, SDpnt->lun);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index f77086e3a42e..e53ea226c1f6 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1401,22 +1401,14 @@ static ssize_t sg_device_kdev_read(struct device *driverfs_dev, char *page,
Sg_device * sdp=list_entry(driverfs_dev, Sg_device, sg_driverfs_dev);
return off ? 0 : sprintf(page, "%x\n",sdp->i_rdev.value);
}
-static struct driver_file_entry sg_device_kdev_file = {
- name: "kdev",
- mode: S_IRUGO,
- show: sg_device_kdev_read,
-};
+static DEVICE_ATTR(kdev,"kdev",S_IRUGO,sg_device_kdev_read,NULL);
static ssize_t sg_device_type_read(struct device *driverfs_dev, char *page,
size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "CHR\n");
}
-static struct driver_file_entry sg_device_type_file = {
- name: "type",
- mode: S_IRUGO,
- show: sg_device_type_read,
-};
+static DEVICE_ATTR(type,"type",S_IRUGO,sg_device_type_read,NULL);
static int sg_attach(Scsi_Device * scsidp)
{
@@ -1484,8 +1476,8 @@ static int sg_attach(Scsi_Device * scsidp)
sdp->sg_driverfs_dev.parent = &scsidp->sdev_driverfs_dev;
sdp->sg_driverfs_dev.bus = &scsi_driverfs_bus_type;
device_register(&sdp->sg_driverfs_dev);
- device_create_file(&sdp->sg_driverfs_dev, &sg_device_type_file);
- device_create_file(&sdp->sg_driverfs_dev, &sg_device_kdev_file);
+ device_create_file(&sdp->sg_driverfs_dev, &dev_attr_type);
+ device_create_file(&sdp->sg_driverfs_dev, &dev_attr_kdev);
sdp->de = devfs_register (scsidp->de, "generic", DEVFS_FL_DEFAULT,
SCSI_GENERIC_MAJOR, k,
@@ -1555,8 +1547,8 @@ static void sg_detach(Scsi_Device * scsidp)
}
SCSI_LOG_TIMEOUT(3, printk("sg_detach: dev=%d, dirty\n", k));
devfs_unregister (sdp->de);
- device_remove_file(&sdp->sg_driverfs_dev,sg_device_type_file.name);
- device_remove_file(&sdp->sg_driverfs_dev,sg_device_kdev_file.name);
+ device_remove_file(&sdp->sg_driverfs_dev,&dev_attr_type);
+ device_remove_file(&sdp->sg_driverfs_dev,&dev_attr_kdev);
put_device(&sdp->sg_driverfs_dev);
sdp->de = NULL;
if (NULL == sdp->headfp) {
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c
index 4a8480893d9c..c2fdb067a7fc 100644
--- a/drivers/scsi/sr.c
+++ b/drivers/scsi/sr.c
@@ -739,22 +739,14 @@ static ssize_t sr_device_kdev_read(struct device *driverfs_dev,
kdev.value=(int)driverfs_dev->driver_data;
return off ? 0 : sprintf(page, "%x\n",kdev.value);
}
-static struct driver_file_entry sr_device_kdev_file = {
- name: "kdev",
- mode: S_IRUGO,
- show: sr_device_kdev_read,
-};
+static DEVICE_ATTR(kdev,"kdev",S_IRUGO,sr_device_kdev_read,NULL);
static ssize_t sr_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "CHR\n");
}
-static struct driver_file_entry sr_device_type_file = {
- name: "type",
- mode: S_IRUGO,
- show: sr_device_type_read,
-};
+static DEVICE_ATTR(type,"type",S_IRUGO,sr_device_type_read,NULL);
void sr_finish()
@@ -813,9 +805,9 @@ void sr_finish()
(void *)__mkdev(MAJOR_NR, i);
device_register(&SCp->cdi.cdrom_driverfs_dev);
device_create_file(&SCp->cdi.cdrom_driverfs_dev,
- &sr_device_type_file);
+ &dev_attr_type);
device_create_file(&SCp->cdi.cdrom_driverfs_dev,
- &sr_device_kdev_file);
+ &dev_attr_kdev);
SCp->cdi.de = devfs_register(SCp->device->de, "cd",
DEVFS_FL_DEFAULT, MAJOR_NR, i,
S_IFBLK | S_IRUGO | S_IWUGO,
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index c2ef2a258a8f..2a3d89a994f1 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -3533,22 +3533,14 @@ static ssize_t st_device_kdev_read(struct device *driverfs_dev,
kdev.value=(int)driverfs_dev->driver_data;
return off ? 0 : sprintf(page, "%x\n",kdev.value);
}
-static struct driver_file_entry st_device_kdev_file = {
- name: "kdev",
- mode: S_IRUGO,
- show: st_device_kdev_read,
-};
+static DEVICE_ATTR(kdev,"kdev",S_IRUGO,st_device_kdev_read,NULL);
static ssize_t st_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "CHR\n");
}
-static struct driver_file_entry st_device_type_file = {
- name: "type",
- mode: S_IRUGO,
- show: st_device_type_read,
-};
+static DEVICE_ATTR(type,"type",S_IRUGO,st_device_type_read,NULL);
static struct file_operations st_fops =
@@ -3664,8 +3656,8 @@ static int st_attach(Scsi_Device * SDp)
(void *)__mkdev(MAJOR_NR, i + (mode << 5));
device_register(&tpnt->driverfs_dev_r[mode]);
device_create_file(&tpnt->driverfs_dev_r[mode],
- &st_device_type_file);
- device_create_file(&tpnt->driverfs_dev_r[mode], &st_device_kdev_file);
+ &dev_attr_type);
+ device_create_file(&tpnt->driverfs_dev_r[mode], &dev_attr_kdev);
tpnt->de_r[mode] =
devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
MAJOR_NR, i + (mode << 5),
@@ -3683,9 +3675,9 @@ static int st_attach(Scsi_Device * SDp)
(void *)__mkdev(MAJOR_NR, i + (mode << 5) + 128);
device_register(&tpnt->driverfs_dev_n[mode]);
device_create_file(&tpnt->driverfs_dev_n[mode],
- &st_device_type_file);
+ &dev_attr_type);
device_create_file(&tpnt->driverfs_dev_n[mode],
- &st_device_kdev_file);
+ &dev_attr_kdev);
tpnt->de_n[mode] =
devfs_register (SDp->de, name, DEVFS_FL_DEFAULT,
MAJOR_NR, i + (mode << 5) + 128,
@@ -3785,16 +3777,16 @@ static void st_detach(Scsi_Device * SDp)
devfs_unregister (tpnt->de_r[mode]);
tpnt->de_r[mode] = NULL;
device_remove_file(&tpnt->driverfs_dev_r[mode],
- st_device_type_file.name);
+ &dev_attr_type);
device_remove_file(&tpnt->driverfs_dev_r[mode],
- st_device_kdev_file.name);
+ &dev_attr_type);
put_device(&tpnt->driverfs_dev_r[mode]);
devfs_unregister (tpnt->de_n[mode]);
tpnt->de_n[mode] = NULL;
device_remove_file(&tpnt->driverfs_dev_n[mode],
- st_device_type_file.name);
+ &dev_attr_type);
device_remove_file(&tpnt->driverfs_dev_n[mode],
- st_device_kdev_file.name);
+ &dev_attr_kdev);
put_device(&tpnt->driverfs_dev_n[mode]);
}
if (tpnt->buffer) {
diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
index 4f53715471fb..81099c75fc80 100644
--- a/drivers/usb/core/usb.c
+++ b/drivers/usb/core/usb.c
@@ -835,11 +835,8 @@ show_config (struct device *dev, char *buf, size_t count, loff_t off)
udev = to_usb_device (dev);
return sprintf (buf, "%u\n", udev->actconfig->bConfigurationValue);
}
-static struct driver_file_entry usb_config_entry = {
- .name = "configuration",
- .mode = S_IRUGO,
- .show = show_config,
-};
+
+static DEVICE_ATTR(config,"configuration",S_IRUGO,show_config,NULL);
/* interfaces have one current setting; alternates
* can have different endpoints and class info.
@@ -854,11 +851,7 @@ show_altsetting (struct device *dev, char *buf, size_t count, loff_t off)
interface = to_usb_interface (dev);
return sprintf (buf, "%u\n", interface->altsetting->bAlternateSetting);
}
-static struct driver_file_entry usb_altsetting_entry = {
- .name = "altsetting",
- .mode = S_IRUGO,
- .show = show_altsetting,
-};
+static DEVICE_ATTR(altsetting,"altsetting",S_IRUGO,show_altsetting,NULL);
/* product driverfs file */
static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t off)
@@ -875,11 +868,7 @@ static ssize_t show_product (struct device *dev, char *buf, size_t count, loff_t
buf[len+1] = 0x00;
return len+1;
}
-static struct driver_file_entry usb_product_entry = {
- .name = "product",
- .mode = S_IRUGO,
- .show = show_product,
-};
+static DEVICE_ATTR(product,"product",S_IRUGO,show_product,NULL);
/* manufacturer driverfs file */
static ssize_t
@@ -897,11 +886,7 @@ show_manufacturer (struct device *dev, char *buf, size_t count, loff_t off)
buf[len+1] = 0x00;
return len+1;
}
-static struct driver_file_entry usb_manufacturer_entry = {
- .name = "manufacturer",
- .mode = S_IRUGO,
- .show = show_manufacturer,
-};
+static DEVICE_ATTR(manufacturer,"manufacturer",S_IRUGO,show_manufacturer,NULL);
/* serial number driverfs file */
static ssize_t
@@ -919,11 +904,7 @@ show_serial (struct device *dev, char *buf, size_t count, loff_t off)
buf[len+1] = 0x00;
return len+1;
}
-static struct driver_file_entry usb_serial_entry = {
- .name = "serial",
- .mode = S_IRUGO,
- .show = show_serial,
-};
+static DEVICE_ATTR(serial,"serial",S_IRUGO,show_serial,NULL);
/*
* This entrypoint gets called for each new device.
@@ -965,7 +946,7 @@ static void usb_find_drivers(struct usb_device *dev)
interface->altsetting->bInterfaceNumber);
}
device_register (&interface->dev);
- device_create_file (&interface->dev, &usb_altsetting_entry);
+ device_create_file (&interface->dev, &dev_attr_altsetting);
/* if this interface hasn't already been claimed */
if (!usb_interface_claimed(interface)) {
@@ -1453,13 +1434,13 @@ int usb_new_device(struct usb_device *dev)
err = device_register (&dev->dev);
if (err)
return err;
- device_create_file (&dev->dev, &usb_config_entry);
+ device_create_file (&dev->dev, &dev_attr_config);
if (dev->descriptor.iManufacturer)
- device_create_file (&dev->dev, &usb_manufacturer_entry);
+ device_create_file (&dev->dev, &dev_attr_manufacturer);
if (dev->descriptor.iProduct)
- device_create_file (&dev->dev, &usb_product_entry);
+ device_create_file (&dev->dev, &dev_attr_product);
if (dev->descriptor.iSerialNumber)
- device_create_file (&dev->dev, &usb_serial_entry);
+ device_create_file (&dev->dev, &dev_attr_serial);
/* now that the basic setup is over, add a /proc/bus/usb entry */
usbfs_add_device(dev);
diff --git a/fs/driverfs/inode.c b/fs/driverfs/inode.c
index 08df41832bb1..49b27f479355 100644
--- a/fs/driverfs/inode.c
+++ b/fs/driverfs/inode.c
@@ -32,7 +32,7 @@
#include <linux/namei.h>
#include <linux/module.h>
#include <linux/slab.h>
-#include <linux/device.h>
+#include <linux/driverfs_fs.h>
#include <asm/uaccess.h>
@@ -266,7 +266,7 @@ static int driverfs_rmdir(struct inode *dir, struct dentry *dentry)
*
* Userspace wants data from a file. It is up to the creator of the file to
* provide that data.
- * There is a struct driver_file_entry embedded in file->private_data. We
+ * There is a struct device_attribute embedded in file->private_data. We
* obtain that and check if the read callback is implemented. If so, we call
* it, passing the data field of the file entry.
* Said callback is responsible for filling the buffer and returning the number
@@ -275,26 +275,18 @@ static int driverfs_rmdir(struct inode *dir, struct dentry *dentry)
static ssize_t
driverfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos)
{
- struct driver_file_entry * entry;
+ struct attribute * attr = file->f_dentry->d_fsdata;
struct driver_dir_entry * dir;
unsigned char *page;
ssize_t retval = 0;
- struct device * dev;
dir = file->f_dentry->d_parent->d_fsdata;
- entry = (struct driver_file_entry *)file->f_dentry->d_fsdata;
- if (!entry) {
- DBG("%s: file entry is NULL\n",__FUNCTION__);
- return -ENOENT;
- }
- if (!entry->show)
+ if (!dir->ops->show)
return 0;
if (count > PAGE_SIZE)
count = PAGE_SIZE;
- dev = to_device(dir);
-
page = (unsigned char*)__get_free_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
@@ -302,7 +294,7 @@ driverfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos)
while (count > 0) {
ssize_t len;
- len = entry->show(dev,page,count,*ppos);
+ len = dir->ops->show(dir,attr,page,count,*ppos);
if (len <= 0) {
if (len < 0)
@@ -341,24 +333,13 @@ driverfs_read_file(struct file *file, char *buf, size_t count, loff_t *ppos)
static ssize_t
driverfs_write_file(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
- struct driver_file_entry * entry;
+ struct attribute * attr = file->f_dentry->d_fsdata;
struct driver_dir_entry * dir;
- struct device * dev;
ssize_t retval = 0;
char * page;
dir = file->f_dentry->d_parent->d_fsdata;
- entry = (struct driver_file_entry *)file->f_dentry->d_fsdata;
- if (!entry) {
- DBG("%s: file entry is NULL\n",__FUNCTION__);
- return -ENOENT;
- }
- if (!entry->store)
- return 0;
-
- dev = to_device(dir);
-
page = (char *)__get_free_page(GFP_KERNEL);
if (!page)
return -ENOMEM;
@@ -372,7 +353,7 @@ driverfs_write_file(struct file *file, const char *buf, size_t count, loff_t *pp
while (count > 0) {
ssize_t len;
- len = entry->store(dev,page + retval,count,*ppos);
+ len = dir->ops->store(dir,attr,page + retval,count,*ppos);
if (len <= 0) {
if (len < 0)
@@ -418,24 +399,28 @@ driverfs_file_lseek(struct file *file, loff_t offset, int orig)
static int driverfs_open_file(struct inode * inode, struct file * filp)
{
struct driver_dir_entry * dir;
- struct device * dev;
+ int error = 0;
dir = (struct driver_dir_entry *)filp->f_dentry->d_parent->d_fsdata;
- if (!dir)
- return -EFAULT;
- dev = to_device(dir);
- get_device(dev);
- return 0;
+ if (dir) {
+ struct attribute * attr = filp->f_dentry->d_fsdata;
+ if (attr && dir->ops) {
+ if (dir->ops->open)
+ error = dir->ops->open(dir);
+ goto Done;
+ }
+ }
+ error = -EINVAL;
+ Done:
+ return error;
}
static int driverfs_release(struct inode * inode, struct file * filp)
{
struct driver_dir_entry * dir;
- struct device * dev;
-
dir = (struct driver_dir_entry *)filp->f_dentry->d_parent->d_fsdata;
- dev = to_device(dir);
- put_device(dev);
+ if (dir->ops->close)
+ dir->ops->close(dir);
return 0;
}
@@ -618,7 +603,7 @@ driverfs_create_dir(struct driver_dir_entry * entry,
* @parent: directory to create it in
*/
int
-driverfs_create_file(struct driver_file_entry * entry,
+driverfs_create_file(struct attribute * entry,
struct driver_dir_entry * parent)
{
struct dentry * dentry;
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 8b61260253cf..f9342548b68a 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -212,22 +212,14 @@ static ssize_t partition_device_kdev_read(struct device *driverfs_dev,
kdev.value=(int)(long)driverfs_dev->driver_data;
return off ? 0 : sprintf (page, "%x\n",kdev.value);
}
-static struct driver_file_entry partition_device_kdev_file = {
- name: "kdev",
- mode: S_IRUGO,
- show: partition_device_kdev_read,
-};
+static DEVICE_ATTR(kdev,"kdev",S_IRUGO,partition_device_kdev_read,NULL);
static ssize_t partition_device_type_read(struct device *driverfs_dev,
char *page, size_t count, loff_t off)
{
return off ? 0 : sprintf (page, "BLK\n");
}
-static struct driver_file_entry partition_device_type_file = {
- name: "type",
- mode: S_IRUGO,
- show: partition_device_type_read,
-};
+static DEVICE_ATTR(type,"type",S_IRUGO,partition_device_type_read,NULL);
void driverfs_create_partitions(struct gendisk *hd, int minor)
{
@@ -298,9 +290,9 @@ void driverfs_create_partitions(struct gendisk *hd, int minor)
if (parent) current_driverfs_dev->bus = parent->bus;
device_register(current_driverfs_dev);
device_create_file(current_driverfs_dev,
- &partition_device_type_file);
+ &dev_attr_type);
device_create_file(current_driverfs_dev,
- &partition_device_kdev_file);
+ &dev_attr_kdev);
}
}
}
@@ -319,17 +311,17 @@ void driverfs_remove_partitions(struct gendisk *hd, int minor)
if ((p[part].nr_sects >= 1)) {
current_driverfs_dev = &p[part].hd_driverfs_dev;
device_remove_file(current_driverfs_dev,
- partition_device_type_file.name);
+ &dev_attr_type);
device_remove_file(current_driverfs_dev,
- partition_device_kdev_file.name);
+ &dev_attr_kdev);
put_device(current_driverfs_dev);
}
}
current_driverfs_dev = &p->hd_driverfs_dev;
- device_remove_file(current_driverfs_dev,
- partition_device_type_file.name);
- device_remove_file(current_driverfs_dev,
- partition_device_kdev_file.name);
+ device_remove_file(current_driverfs_dev,
+ &dev_attr_type);
+ device_remove_file(current_driverfs_dev,
+ &dev_attr_kdev);
put_device(current_driverfs_dev);
return;
}
diff --git a/include/linux/device.h b/include/linux/device.h
index a6d10931ae7f..5dfa05c2dd3a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -160,8 +160,6 @@ struct device {
void (*release)(struct device * dev);
};
-#define to_device(d) container_of(d, struct device, dir)
-
static inline struct device *
list_to_dev(struct list_head *node)
{
@@ -179,8 +177,24 @@ g_list_to_dev(struct list_head *g_list)
*/
extern int device_register(struct device * dev);
-extern int device_create_file(struct device *device, struct driver_file_entry * entry);
-extern void device_remove_file(struct device * dev, const char * name);
+
+/* driverfs interface for exporting device attributes */
+
+struct device_attribute {
+ struct attribute attr;
+ ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off);
+ ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
+};
+
+#define DEVICE_ATTR(_name,_str,_mode,_show,_store) \
+struct device_attribute dev_attr_##_name = { \
+ .attr = {.name = _str, .mode = _mode }, \
+ .show = _show, \
+ .store = _store, \
+};
+
+extern int device_create_file(struct device *device, struct device_attribute * entry);
+extern void device_remove_file(struct device * dev, struct device_attribute * attr);
/*
* Platform "fixup" functions - allow the platform to have their say
diff --git a/include/linux/driverfs_fs.h b/include/linux/driverfs_fs.h
index 758dc23f09f6..d859f8c2e041 100644
--- a/include/linux/driverfs_fs.h
+++ b/include/linux/driverfs_fs.h
@@ -26,20 +26,26 @@
#ifndef _DRIVER_FS_H_
#define _DRIVER_FS_H_
+struct driver_dir_entry;
+struct attribute;
+
+struct driverfs_ops {
+ int (*open)(struct driver_dir_entry *);
+ int (*close)(struct driver_dir_entry *);
+ ssize_t (*show)(struct driver_dir_entry *, struct attribute *,char *, size_t, loff_t);
+ ssize_t (*store)(struct driver_dir_entry *,struct attribute *,const char *, size_t, loff_t);
+};
+
struct driver_dir_entry {
char * name;
struct dentry * dentry;
mode_t mode;
+ struct driverfs_ops * ops;
};
-struct device;
-
-struct driver_file_entry {
+struct attribute {
char * name;
mode_t mode;
-
- ssize_t (*show)(struct device * dev, char * buf, size_t count, loff_t off);
- ssize_t (*store)(struct device * dev, const char * buf, size_t count, loff_t off);
};
extern int
@@ -49,7 +55,7 @@ extern void
driverfs_remove_dir(struct driver_dir_entry * entry);
extern int
-driverfs_create_file(struct driver_file_entry * entry,
+driverfs_create_file(struct attribute * attr,
struct driver_dir_entry * parent);
extern int