Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (46 commits)
  UIO: Fix mapping of logical and virtual memory
  UIO: add automata sercos3 pci card support
  UIO: Change driver name of uio_pdrv
  UIO: Add alignment warnings for uio-mem
  Driver core: add bus_sort_breadthfirst() function
  NET: convert the phy_device file to use bus_find_device_by_name
  kobject: Cleanup kobject_rename and !CONFIG_SYSFS
  kobject: Fix kobject_rename and !CONFIG_SYSFS
  sysfs: Make dir and name args to sysfs_notify() const
  platform: add new device registration helper
  sysfs: use ilookup5() instead of ilookup5_nowait()
  PNP: create device attributes via default device attributes
  Driver core: make bus_find_device_by_name() more robust
  usb: turn dev_warn+WARN_ON combos into dev_WARN
  debug: use dev_WARN() rather than WARN_ON() in device_pm_add()
  debug: Introduce a dev_WARN() function
  sysfs: fix deadlock
  device model: Do a quickcheck for driver binding before doing an expensive check
  Driver core: Fix cleanup in device_create_vargs().
  Driver core: Clarify device cleanup.
  ...
This commit is contained in:
Linus Torvalds
2008-10-16 12:40:26 -07:00
131 changed files with 1786 additions and 617 deletions
+2 -3
View File
@@ -362,9 +362,8 @@ static int init_coda_psdev(void)
goto out_chrdev;
}
for (i = 0; i < MAX_CODADEVS; i++)
device_create_drvdata(coda_psdev_class, NULL,
MKDEV(CODA_PSDEV_MAJOR, i),
NULL, "cfs%d", i);
device_create(coda_psdev_class, NULL,
MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i);
coda_sysctl_init();
goto out;
+31 -11
View File
@@ -61,6 +61,7 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
int size = dentry->d_inode->i_size;
loff_t offs = *off;
int count = min_t(size_t, bytes, PAGE_SIZE);
char *temp;
if (size) {
if (offs > size)
@@ -69,23 +70,33 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
count = size - offs;
}
temp = kmalloc(count, GFP_KERNEL);
if (!temp)
return -ENOMEM;
mutex_lock(&bb->mutex);
count = fill_read(dentry, bb->buffer, offs, count);
if (count < 0)
goto out_unlock;
if (count < 0) {
mutex_unlock(&bb->mutex);
goto out_free;
}
if (copy_to_user(userbuf, bb->buffer, count)) {
memcpy(temp, bb->buffer, count);
mutex_unlock(&bb->mutex);
if (copy_to_user(userbuf, temp, count)) {
count = -EFAULT;
goto out_unlock;
goto out_free;
}
pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count);
*off = offs + count;
out_unlock:
mutex_unlock(&bb->mutex);
out_free:
kfree(temp);
return count;
}
@@ -118,6 +129,7 @@ static ssize_t write(struct file *file, const char __user *userbuf,
int size = dentry->d_inode->i_size;
loff_t offs = *off;
int count = min_t(size_t, bytes, PAGE_SIZE);
char *temp;
if (size) {
if (offs > size)
@@ -126,19 +138,27 @@ static ssize_t write(struct file *file, const char __user *userbuf,
count = size - offs;
}
mutex_lock(&bb->mutex);
temp = kmalloc(count, GFP_KERNEL);
if (!temp)
return -ENOMEM;
if (copy_from_user(bb->buffer, userbuf, count)) {
if (copy_from_user(temp, userbuf, count)) {
count = -EFAULT;
goto out_unlock;
goto out_free;
}
mutex_lock(&bb->mutex);
memcpy(bb->buffer, temp, count);
count = flush_write(dentry, bb->buffer, offs, count);
mutex_unlock(&bb->mutex);
if (count > 0)
*off = offs + count;
out_unlock:
mutex_unlock(&bb->mutex);
out_free:
kfree(temp);
return count;
}
+10 -14
View File
@@ -370,17 +370,17 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
memset(acxt, 0, sizeof(*acxt));
acxt->parent_sd = parent_sd;
/* Lookup parent inode. inode initialization and I_NEW
* clearing are protected by sysfs_mutex. By grabbing it and
* looking up with _nowait variant, inode state can be
* determined reliably.
/* Lookup parent inode. inode initialization is protected by
* sysfs_mutex, so inode existence can be determined by
* looking up inode while holding sysfs_mutex.
*/
mutex_lock(&sysfs_mutex);
inode = ilookup5_nowait(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
parent_sd);
inode = ilookup5(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
parent_sd);
if (inode) {
WARN_ON(inode->i_state & I_NEW);
if (inode && !(inode->i_state & I_NEW)) {
/* parent inode available */
acxt->parent_inode = inode;
@@ -393,8 +393,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
mutex_lock(&inode->i_mutex);
mutex_lock(&sysfs_mutex);
}
} else
iput(inode);
}
}
/**
@@ -636,6 +635,7 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
return sd;
}
EXPORT_SYMBOL_GPL(sysfs_get_dirent);
static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
const char *name, struct sysfs_dirent **p_sd)
@@ -829,16 +829,12 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
if (!new_dentry)
goto out_unlock;
/* rename kobject and sysfs_dirent */
/* rename sysfs_dirent */
error = -ENOMEM;
new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
if (!new_name)
goto out_unlock;
error = kobject_set_name(kobj, "%s", new_name);
if (error)
goto out_unlock;
dup_name = sd->s_name;
sd->s_name = new_name;
+32 -14
View File
@@ -19,10 +19,18 @@
#include <linux/poll.h>
#include <linux/list.h>
#include <linux/mutex.h>
#include <linux/limits.h>
#include <asm/uaccess.h>
#include "sysfs.h"
/* used in crash dumps to help with debugging */
static char last_sysfs_file[PATH_MAX];
void sysfs_printk_last_file(void)
{
printk(KERN_EMERG "last sysfs file: %s\n", last_sysfs_file);
}
/*
* There's one sysfs_buffer for each open file and one
* sysfs_open_dirent for each sysfs_dirent with one or more open
@@ -328,6 +336,11 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
struct sysfs_buffer *buffer;
struct sysfs_ops *ops;
int error = -EACCES;
char *p;
p = d_path(&file->f_path, last_sysfs_file, sizeof(last_sysfs_file));
if (p)
memmove(last_sysfs_file, p, strlen(p) + 1);
/* need attr_sd for attr and ops, its parent for kobj */
if (!sysfs_get_active_two(attr_sd))
@@ -440,7 +453,23 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
return POLLERR|POLLPRI;
}
void sysfs_notify(struct kobject *k, char *dir, char *attr)
void sysfs_notify_dirent(struct sysfs_dirent *sd)
{
struct sysfs_open_dirent *od;
spin_lock(&sysfs_open_dirent_lock);
od = sd->s_attr.open;
if (od) {
atomic_inc(&od->event);
wake_up_interruptible(&od->poll);
}
spin_unlock(&sysfs_open_dirent_lock);
}
EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
{
struct sysfs_dirent *sd = k->sd;
@@ -450,19 +479,8 @@ void sysfs_notify(struct kobject *k, char *dir, char *attr)
sd = sysfs_find_dirent(sd, dir);
if (sd && attr)
sd = sysfs_find_dirent(sd, attr);
if (sd) {
struct sysfs_open_dirent *od;
spin_lock(&sysfs_open_dirent_lock);
od = sd->s_attr.open;
if (od) {
atomic_inc(&od->event);
wake_up_interruptible(&od->poll);
}
spin_unlock(&sysfs_open_dirent_lock);
}
if (sd)
sysfs_notify_dirent(sd);
mutex_unlock(&sysfs_mutex);
}
+15
View File
@@ -16,6 +16,7 @@
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/init.h>
#include <linux/module.h>
#include "sysfs.h"
@@ -115,3 +116,17 @@ out_err:
sysfs_dir_cachep = NULL;
goto out;
}
#undef sysfs_get
struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
{
return __sysfs_get(sd);
}
EXPORT_SYMBOL_GPL(sysfs_get);
#undef sysfs_put
void sysfs_put(struct sysfs_dirent *sd)
{
__sysfs_put(sd);
}
EXPORT_SYMBOL_GPL(sysfs_put);
+4 -2
View File
@@ -124,7 +124,7 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
struct sysfs_dirent **p_sd);
void sysfs_remove_subdir(struct sysfs_dirent *sd);
static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
{
if (sd) {
WARN_ON(!atomic_read(&sd->s_count));
@@ -132,12 +132,14 @@ static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
}
return sd;
}
#define sysfs_get(sd) __sysfs_get(sd)
static inline void sysfs_put(struct sysfs_dirent *sd)
static inline void __sysfs_put(struct sysfs_dirent *sd)
{
if (sd && atomic_dec_and_test(&sd->s_count))
release_sysfs_dirent(sd);
}
#define sysfs_put(sd) __sysfs_put(sd)
/*
* inode.c