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
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/driver-2.6:
  sysfs: fix build errors: uevent with CONFIG_SYSFS=n
  pcmcia: some class_device fallout
  Driver core: device_add_attrs() cleanup
  debugfs: Remove misleading comments.
  debugfs: implement symbolic links
  Driver: remove redundant kobject_unregister checks
  kobject: kobj->k_name verification fix
  serial: Add PCMCIA IDs for Quatech DSP-100 dual RS232 adapter.
  Driver core: let request_module() send a /sys/modules/kmod/-uevent
  Driver.h copyright update
  • Loading branch information
Linus Torvalds committed Feb 19, 2007
2 parents 460223d + ef665c1 commit 5fe8252
Show file tree
Hide file tree
Showing 18 changed files with 343 additions and 77 deletions.
22 changes: 10 additions & 12 deletions drivers/base/bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -324,27 +324,25 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
return error;
}

static int device_add_attrs(struct bus_type * bus, struct device * 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;
if (!bus->dev_attrs)
return 0;

for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
error = device_create_file(dev,&bus->dev_attrs[i]);
if (error) {
while (--i >= 0)
device_remove_file(dev, &bus->dev_attrs[i]);
break;
}
}
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;
Expand Down
3 changes: 1 addition & 2 deletions drivers/base/class.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,8 +163,7 @@ int class_register(struct class * cls)
void class_unregister(struct class * cls)
{
pr_debug("device class '%s': unregistering\n", cls->name);
if (cls->virtual_dir)
kobject_unregister(cls->virtual_dir);
kobject_unregister(cls->virtual_dir);
remove_class_attrs(cls);
subsystem_unregister(&cls->subsys);
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/pcmcia/at91_cf.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
board->det_pin, board->irq_pin);

cf->socket.owner = THIS_MODULE;
cf->socket.dev.dev = &pdev->dev;
cf->socket.dev.parent = &pdev->dev;
cf->socket.ops = &at91_cf_ops;
cf->socket.resource_ops = &pccard_static_ops;
cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
Expand Down
8 changes: 4 additions & 4 deletions drivers/pcmcia/soc_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i
*
* Returns: the number of characters added to the buffer
*/
static ssize_t show_status(struct device *dev, char *buf)
static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
{
struct soc_pcmcia_socket *skt =
container_of(dev, struct soc_pcmcia_socket, socket.dev);
Expand All @@ -501,7 +501,7 @@ static ssize_t show_status(struct device *dev, char *buf)

return p-buf;
}
static CLASS_DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);


static struct pccard_operations soc_common_pcmcia_operations = {
Expand Down Expand Up @@ -660,7 +660,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops

skt->socket.ops = &soc_common_pcmcia_operations;
skt->socket.owner = ops->owner;
skt->socket.dev.dev = dev;
skt->socket.dev.parent = dev;

init_timer(&skt->poll_timer);
skt->poll_timer.function = soc_common_pcmcia_poll_event;
Expand Down Expand Up @@ -747,7 +747,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops

add_timer(&skt->poll_timer);

device_create_file(&skt->socket.dev, &device_attr_status);
device_create_file(&skt->socket.dev, &dev_attr_status);
}

dev_set_drvdata(dev, sinfo);
Expand Down
5 changes: 5 additions & 0 deletions drivers/serial/serial_cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ static const struct serial_quirk quirks[] = {
.manfid = MANFID_QUATECH,
.prodid = PRODID_QUATECH_DUAL_RS232_D1,
.multi = 2,
}, {
.manfid = MANFID_QUATECH,
.prodid = PRODID_QUATECH_DUAL_RS232_G,
.multi = 2,
}, {
.manfid = MANFID_QUATECH,
.prodid = PRODID_QUATECH_QUAD_RS232,
Expand Down Expand Up @@ -891,6 +895,7 @@ static struct pcmcia_device_id serial_ids[] = {
PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a),
PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab),
PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
Expand Down
12 changes: 12 additions & 0 deletions fs/debugfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/namei.h>
#include <linux/debugfs.h>

static ssize_t default_read_file(struct file *file, char __user *buf,
Expand Down Expand Up @@ -44,6 +45,17 @@ const struct file_operations debugfs_file_operations = {
.open = default_open,
};

static void *debugfs_follow_link(struct dentry *dentry, struct nameidata *nd)
{
nd_set_link(nd, dentry->d_inode->i_private);
return NULL;
}

const struct inode_operations debugfs_link_operations = {
.readlink = generic_readlink,
.follow_link = debugfs_follow_link,
};

static void debugfs_u8_set(void *data, u64 val)
{
*(u8 *)data = val;
Expand Down
82 changes: 72 additions & 10 deletions fs/debugfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
#include <linux/namei.h>
#include <linux/debugfs.h>
#include <linux/fsnotify.h>
#include <linux/string.h>

#define DEBUGFS_MAGIC 0x64626720

/* declared over in file.c */
extern struct file_operations debugfs_file_operations;
extern struct inode_operations debugfs_link_operations;

static struct vfsmount *debugfs_mount;
static int debugfs_mount_count;
Expand All @@ -51,6 +53,9 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
case S_IFREG:
inode->i_fop = &debugfs_file_operations;
break;
case S_IFLNK:
inode->i_op = &debugfs_link_operations;
break;
case S_IFDIR:
inode->i_op = &simple_dir_inode_operations;
inode->i_fop = &simple_dir_operations;
Expand Down Expand Up @@ -96,6 +101,12 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
return res;
}

static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode)
{
mode = (mode & S_IALLUGO) | S_IFLNK;
return debugfs_mknod(dir, dentry, mode, 0);
}

static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
{
int res;
Expand Down Expand Up @@ -158,10 +169,17 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
mutex_lock(&parent->d_inode->i_mutex);
*dentry = lookup_one_len(name, parent, strlen(name));
if (!IS_ERR(*dentry)) {
if ((mode & S_IFMT) == S_IFDIR)
switch (mode & S_IFMT) {
case S_IFDIR:
error = debugfs_mkdir(parent->d_inode, *dentry, mode);
else
break;
case S_IFLNK:
error = debugfs_link(parent->d_inode, *dentry, mode);
break;
default:
error = debugfs_create(parent->d_inode, *dentry, mode);
break;
}
dput(*dentry);
} else
error = PTR_ERR(*dentry);
Expand Down Expand Up @@ -194,9 +212,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
* you are responsible here.) If an error occurs, %NULL will be returned.
*
* If debugfs is not enabled in the kernel, the value -%ENODEV will be
* returned. It is not wise to check for this value, but rather, check for
* %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
* code.
* returned.
*/
struct dentry *debugfs_create_file(const char *name, mode_t mode,
struct dentry *parent, void *data,
Expand Down Expand Up @@ -246,9 +262,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
* you are responsible here.) If an error occurs, %NULL will be returned.
*
* If debugfs is not enabled in the kernel, the value -%ENODEV will be
* returned. It is not wise to check for this value, but rather, check for
* %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
* code.
* returned.
*/
struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
{
Expand All @@ -258,6 +272,47 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
}
EXPORT_SYMBOL_GPL(debugfs_create_dir);

/**
* debugfs_create_symlink- create a symbolic link in the debugfs filesystem
* @name: a pointer to a string containing the name of the symbolic link to
* create.
* @parent: a pointer to the parent dentry for this symbolic link. This
* should be a directory dentry if set. If this paramater is NULL,
* then the symbolic link will be created in the root of the debugfs
* filesystem.
* @target: a pointer to a string containing the path to the target of the
* symbolic link.
*
* This function creates a symbolic link with the given name in debugfs that
* links to the given target path.
*
* This function will return a pointer to a dentry if it succeeds. This
* pointer must be passed to the debugfs_remove() function when the symbolic
* link is to be removed (no automatic cleanup happens if your module is
* unloaded, you are responsible here.) If an error occurs, %NULL will be
* returned.
*
* If debugfs is not enabled in the kernel, the value -%ENODEV will be
* returned.
*/
struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
const char *target)
{
struct dentry *result;
char *link;

link = kstrdup(target, GFP_KERNEL);
if (!link)
return NULL;

result = debugfs_create_file(name, S_IFLNK | S_IRWXUGO, parent, link,
NULL);
if (!result)
kfree(link);
return result;
}
EXPORT_SYMBOL_GPL(debugfs_create_symlink);

/**
* debugfs_remove - removes a file or directory from the debugfs filesystem
* @dentry: a pointer to a the dentry of the file or directory to be
Expand Down Expand Up @@ -287,15 +342,22 @@ void debugfs_remove(struct dentry *dentry)
if (debugfs_positive(dentry)) {
if (dentry->d_inode) {
dget(dentry);
if (S_ISDIR(dentry->d_inode->i_mode)) {
switch (dentry->d_inode->i_mode & S_IFMT) {
case S_IFDIR:
ret = simple_rmdir(parent->d_inode, dentry);
if (ret)
printk(KERN_ERR
"DebugFS rmdir on %s failed : "
"directory not empty.\n",
dentry->d_name.name);
} else
break;
case S_IFLNK:
kfree(dentry->d_inode->i_private);
/* fall through */
default:
simple_unlink(parent->d_inode, dentry);
break;
}
if (!ret)
d_delete(dentry);
dput(dentry);
Expand Down
9 changes: 3 additions & 6 deletions fs/partitions/check.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,8 +358,7 @@ void delete_partition(struct gendisk *disk, int part)
p->ios[0] = p->ios[1] = 0;
p->sectors[0] = p->sectors[1] = 0;
sysfs_remove_link(&p->kobj, "subsystem");
if (p->holder_dir)
kobject_unregister(p->holder_dir);
kobject_unregister(p->holder_dir);
kobject_uevent(&p->kobj, KOBJ_REMOVE);
kobject_del(&p->kobj);
kobject_put(&p->kobj);
Expand Down Expand Up @@ -603,10 +602,8 @@ void del_gendisk(struct gendisk *disk)
disk->stamp = 0;

kobject_uevent(&disk->kobj, KOBJ_REMOVE);
if (disk->holder_dir)
kobject_unregister(disk->holder_dir);
if (disk->slave_dir)
kobject_unregister(disk->slave_dir);
kobject_unregister(disk->holder_dir);
kobject_unregister(disk->slave_dir);
if (disk->driverfs_dev) {
char *disk_name = make_block_name(disk);
sysfs_remove_link(&disk->kobj, "device");
Expand Down
10 changes: 10 additions & 0 deletions include/linux/debugfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode,

struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);

struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
const char *dest);

void debugfs_remove(struct dentry *dentry);

struct dentry *debugfs_create_u8(const char *name, mode_t mode,
Expand Down Expand Up @@ -70,6 +73,13 @@ static inline struct dentry *debugfs_create_dir(const char *name,
return ERR_PTR(-ENODEV);
}

static inline struct dentry *debugfs_create_symlink(const char *name,
struct dentry *parent,
const char *dest)
{
return ERR_PTR(-ENODEV);
}

static inline void debugfs_remove(struct dentry *dentry)
{ }

Expand Down
1 change: 1 addition & 0 deletions include/linux/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
* device.h - generic, centralized driver model
*
* Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
* Copyright (c) 2004-2007 Greg Kroah-Hartman <gregkh@suse.de>
*
* This file is released under the GPLv2
*
Expand Down
2 changes: 2 additions & 0 deletions include/linux/kmod.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,10 @@
#ifdef CONFIG_KMOD
/* modprobe exit status on success, -ve on error. Return value
* usually useless though. */
extern void kmod_sysfs_init(void);
extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
#else
static inline void kmod_sysfs_init(void) {};
static inline int request_module(const char * name, ...) { return -ENOSYS; }
#endif

Expand Down
Loading

0 comments on commit 5fe8252

Please sign in to comment.