Commit 1a6c88f4 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://ldm.bkbits.net/linux-2.5-driverfs-api

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 1bd9236b 9e27f077
......@@ -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);
......@@ -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);
......
......@@ -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;
......
......@@ -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,
};
......@@ -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;
}
......
......@@ -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);
......
......@@ -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) {
......
......@@ -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,
......
......@@ -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) {
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment