diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/block/genhd.c linux-2.6.31-rc4-git5-driver-core/block/genhd.c
--- linux-2.6.31-rc4-git5-usb.current/block/genhd.c 2009-07-24 11:07:31.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/block/genhd.c 2009-07-31 09:56:41.000000000 -0700
@@ -901,7 +901,7 @@
.attrs = disk_attrs,
};
-static struct attribute_group *disk_attr_groups[] = {
+static const struct attribute_group *disk_attr_groups[] = {
&disk_attr_group,
NULL
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/Documentation/DocBook/uio-howto.tmpl linux-2.6.31-rc4-git5-driver-core/Documentation/DocBook/uio-howto.tmpl
--- linux-2.6.31-rc4-git5-usb.current/Documentation/DocBook/uio-howto.tmpl 2009-06-15 12:15:18.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/Documentation/DocBook/uio-howto.tmpl 2009-07-31 09:56:42.000000000 -0700
@@ -25,6 +25,10 @@
2006-2008
Hans-Jürgen Koch.
+
+ 2009
+ Red Hat Inc, Michael S. Tsirkin (mst@redhat.com)
+
@@ -42,6 +46,13 @@
+ 0.9
+ 2009-07-16
+ mst
+ Added generic pci driver
+
+
+
0.8
2008-12-24
hjk
@@ -809,6 +820,158 @@
+
+
+Generic PCI UIO driver
+
+ The generic driver is a kernel module named uio_pci_generic.
+ It can work with any device compliant to PCI 2.3 (circa 2002) and
+ any compliant PCI Express device. Using this, you only need to
+ write the userspace driver, removing the need to write
+ a hardware-specific kernel module.
+
+
+
+Making the driver recognize the device
+
+Since the driver does not declare any device ids, it will not get loaded
+automatically and will not automatically bind to any devices, you must load it
+and allocate id to the driver yourself. For example:
+
+ modprobe uio_pci_generic
+ echo "8086 10f5" > /sys/bus/pci/drivers/uio_pci_generic/new_id
+
+
+
+If there already is a hardware specific kernel driver for your device, the
+generic driver still won't bind to it, in this case if you want to use the
+generic driver (why would you?) you'll have to manually unbind the hardware
+specific driver and bind the generic driver, like this:
+
+ echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind
+ echo -n 0000:00:19.0 > /sys/bus/pci/drivers/uio_pci_generic/bind
+
+
+
+You can verify that the device has been bound to the driver
+by looking for it in sysfs, for example like the following:
+
+ ls -l /sys/bus/pci/devices/0000:00:19.0/driver
+
+Which if successful should print
+
+ .../0000:00:19.0/driver -> ../../../bus/pci/drivers/uio_pci_generic
+
+Note that the generic driver will not bind to old PCI 2.2 devices.
+If binding the device failed, run the following command:
+
+ dmesg
+
+and look in the output for failure reasons
+
+
+
+
+Things to know about uio_pci_generic
+
+Interrupts are handled using the Interrupt Disable bit in the PCI command
+register and Interrupt Status bit in the PCI status register. All devices
+compliant to PCI 2.3 (circa 2002) and all compliant PCI Express devices should
+support these bits. uio_pci_generic detects this support, and won't bind to
+devices which do not support the Interrupt Disable Bit in the command register.
+
+
+On each interrupt, uio_pci_generic sets the Interrupt Disable bit.
+This prevents the device from generating further interrupts
+until the bit is cleared. The userspace driver should clear this
+bit before blocking and waiting for more interrupts.
+
+
+
+Writing userspace driver using uio_pci_generic
+
+Userspace driver can use pci sysfs interface, or the
+libpci libray that wraps it, to talk to the device and to
+re-enable interrupts by writing to the command register.
+
+
+
+Example code using uio_pci_generic
+
+Here is some sample userspace driver code using uio_pci_generic:
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+int main()
+{
+ int uiofd;
+ int configfd;
+ int err;
+ int i;
+ unsigned icount;
+ unsigned char command_high;
+
+ uiofd = open("/dev/uio0", O_RDONLY);
+ if (uiofd < 0) {
+ perror("uio open:");
+ return errno;
+ }
+ configfd = open("/sys/class/uio/uio0/device/config", O_RDWR);
+ if (uiofd < 0) {
+ perror("config open:");
+ return errno;
+ }
+
+ /* Read and cache command value */
+ err = pread(configfd, &command_high, 1, 5);
+ if (err != 1) {
+ perror("command config read:");
+ return errno;
+ }
+ command_high &= ~0x4;
+
+ for(i = 0;; ++i) {
+ /* Print out a message, for debugging. */
+ if (i == 0)
+ fprintf(stderr, "Started uio test driver.\n");
+ else
+ fprintf(stderr, "Interrupts: %d\n", icount);
+
+ /****************************************/
+ /* Here we got an interrupt from the
+ device. Do something to it. */
+ /****************************************/
+
+ /* Re-enable interrupts. */
+ err = pwrite(configfd, &command_high, 1, 5);
+ if (err != 1) {
+ perror("config write:");
+ break;
+ }
+
+ /* Wait for next interrupt. */
+ err = read(uiofd, &icount, 4);
+ if (err != 4) {
+ perror("uio read:");
+ break;
+ }
+
+ }
+ return errno;
+}
+
+
+
+
+
+
+
Further information
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/base.h linux-2.6.31-rc4-git5-driver-core/drivers/base/base.h
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/base.h 2009-06-15 12:15:29.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/base.h 2009-07-31 09:56:42.000000000 -0700
@@ -70,6 +70,8 @@
* @knode_parent - node in sibling list
* @knode_driver - node in driver list
* @knode_bus - node in bus list
+ * @driver_data - private pointer for driver specific info. Will turn into a
+ * list soon.
* @device - pointer back to the struct class that this structure is
* associated with.
*
@@ -80,6 +82,7 @@
struct klist_node knode_parent;
struct klist_node knode_driver;
struct klist_node knode_bus;
+ void *driver_data;
struct device *device;
};
#define to_device_private_parent(obj) \
@@ -89,6 +92,8 @@
#define to_device_private_bus(obj) \
container_of(obj, struct device_private, knode_bus)
+extern int device_private_init(struct device *dev);
+
/* initialisation functions */
extern int devices_init(void);
extern int buses_init(void);
@@ -104,7 +109,7 @@
extern int cpu_dev_init(void);
extern int bus_add_device(struct device *dev);
-extern void bus_attach_device(struct device *dev);
+extern void bus_probe_device(struct device *dev);
extern void bus_remove_device(struct device *dev);
extern int bus_add_driver(struct device_driver *drv);
@@ -134,3 +139,9 @@
struct device_driver *drv) { }
static inline void module_remove_driver(struct device_driver *drv) { }
#endif
+
+#ifdef CONFIG_DEVTMPFS
+extern int devtmpfs_init(void);
+#else
+static inline int devtmpfs_init(void) { return 0; }
+#endif
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/bus.c linux-2.6.31-rc4-git5-driver-core/drivers/base/bus.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/bus.c 2009-07-24 11:07:31.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/bus.c 2009-07-31 09:56:41.000000000 -0700
@@ -459,8 +459,9 @@
* bus_add_device - add device to bus
* @dev: device being added
*
+ * - Add device's bus attributes.
+ * - Create links to device's bus.
* - Add the device to its bus's list of devices.
- * - Create link to device's bus.
*/
int bus_add_device(struct device *dev)
{
@@ -483,6 +484,7 @@
error = make_deprecated_bus_links(dev);
if (error)
goto out_deprecated;
+ klist_add_tail(&dev->p->knode_bus, &bus->p->klist_devices);
}
return 0;
@@ -498,24 +500,19 @@
}
/**
- * bus_attach_device - add device to bus
- * @dev: device tried to attach to a driver
+ * bus_probe_device - probe drivers for a new device
+ * @dev: device to probe
*
- * - Add device to bus's list of devices.
- * - Try to attach to driver.
+ * - Automatically probe for a driver if the bus allows it.
*/
-void bus_attach_device(struct device *dev)
+void bus_probe_device(struct device *dev)
{
struct bus_type *bus = dev->bus;
- int ret = 0;
+ int ret;
- if (bus) {
- if (bus->p->drivers_autoprobe)
- ret = device_attach(dev);
+ if (bus && bus->p->drivers_autoprobe) {
+ ret = device_attach(dev);
WARN_ON(ret < 0);
- if (ret >= 0)
- klist_add_tail(&dev->p->knode_bus,
- &bus->p->klist_devices);
}
}
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/core.c linux-2.6.31-rc4-git5-driver-core/drivers/base/core.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/core.c 2009-07-24 11:07:31.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/core.c 2009-07-31 09:56:42.000000000 -0700
@@ -341,7 +341,7 @@
}
static int device_add_groups(struct device *dev,
- struct attribute_group **groups)
+ const struct attribute_group **groups)
{
int error = 0;
int i;
@@ -361,7 +361,7 @@
}
static void device_remove_groups(struct device *dev,
- struct attribute_group **groups)
+ const struct attribute_group **groups)
{
int i;
@@ -843,6 +843,17 @@
}
}
+int device_private_init(struct device *dev)
+{
+ dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
+ if (!dev->p)
+ return -ENOMEM;
+ dev->p->device = dev;
+ klist_init(&dev->p->klist_children, klist_children_get,
+ klist_children_put);
+ return 0;
+}
+
/**
* device_add - add device to device hierarchy.
* @dev: device.
@@ -868,14 +879,11 @@
if (!dev)
goto done;
- dev->p = kzalloc(sizeof(*dev->p), GFP_KERNEL);
if (!dev->p) {
- error = -ENOMEM;
- goto done;
+ error = device_private_init(dev);
+ if (error)
+ goto done;
}
- dev->p->device = dev;
- klist_init(&dev->p->klist_children, klist_children_get,
- klist_children_put);
/*
* for statically allocated devices, which should all be converted
@@ -921,6 +929,8 @@
error = device_create_sys_dev_entry(dev);
if (error)
goto devtattrError;
+
+ devtmpfs_create_node(dev);
}
error = device_add_class_symlinks(dev);
@@ -945,7 +955,7 @@
BUS_NOTIFY_ADD_DEVICE, dev);
kobject_uevent(&dev->kobj, KOBJ_ADD);
- bus_attach_device(dev);
+ bus_probe_device(dev);
if (parent)
klist_add_tail(&dev->p->knode_parent,
&parent->p->klist_children);
@@ -1067,6 +1077,7 @@
if (parent)
klist_del(&dev->p->knode_parent);
if (MAJOR(dev->devt)) {
+ devtmpfs_delete_node(dev);
device_remove_sys_dev_entry(dev);
device_remove_file(dev, &devt_attr);
}
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/dd.c linux-2.6.31-rc4-git5-driver-core/drivers/base/dd.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/dd.c 2009-07-24 11:07:31.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/dd.c 2009-07-31 09:56:41.000000000 -0700
@@ -11,8 +11,8 @@
*
* Copyright (c) 2002-5 Patrick Mochel
* Copyright (c) 2002-3 Open Source Development Labs
- * Copyright (c) 2007 Greg Kroah-Hartman
- * Copyright (c) 2007 Novell Inc.
+ * Copyright (c) 2007-2009 Greg Kroah-Hartman
+ * Copyright (c) 2007-2009 Novell Inc.
*
* This file is released under the GPLv2
*/
@@ -380,3 +380,30 @@
put_device(dev);
}
}
+
+/*
+ * These exports can't be _GPL due to .h files using this within them, and it
+ * might break something that was previously working...
+ */
+void *dev_get_drvdata(const struct device *dev)
+{
+ if (dev && dev->p)
+ return dev->p->driver_data;
+ return NULL;
+}
+EXPORT_SYMBOL(dev_get_drvdata);
+
+void dev_set_drvdata(struct device *dev, void *data)
+{
+ int error;
+
+ if (!dev)
+ return;
+ if (!dev->p) {
+ error = device_private_init(dev);
+ if (error)
+ return;
+ }
+ dev->p->driver_data = data;
+}
+EXPORT_SYMBOL(dev_set_drvdata);
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/devtmpfs.c linux-2.6.31-rc4-git5-driver-core/drivers/base/devtmpfs.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/devtmpfs.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/devtmpfs.c 2009-07-31 09:56:42.000000000 -0700
@@ -0,0 +1,367 @@
+/*
+ * devtmpfs - kernel-maintained tmpfs-based /dev
+ *
+ * Copyright (C) 2009, Kay Sievers
+ *
+ * During bootup, before any driver core device is registered,
+ * devtmpfs, a tmpfs-based filesystem is created. Every driver-core
+ * device which requests a device node, will add a node in this
+ * filesystem. The node is named after the the name of the device,
+ * or the susbsytem can provide a custom name. All devices are
+ * owned by root and have a mode of 0600.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+static struct vfsmount *dev_mnt;
+
+#if defined CONFIG_DEVTMPFS_MOUNT
+static int dev_mount = 1;
+#else
+static int dev_mount;
+#endif
+
+static int __init mount_param(char *str)
+{
+ dev_mount = simple_strtoul(str, NULL, 0);
+ return 1;
+}
+__setup("devtmpfs.mount=", mount_param);
+
+static int dev_get_sb(struct file_system_type *fs_type, int flags,
+ const char *dev_name, void *data, struct vfsmount *mnt)
+{
+ return get_sb_single(fs_type, flags, data, shmem_fill_super, mnt);
+}
+
+static struct file_system_type dev_fs_type = {
+ .name = "devtmpfs",
+ .get_sb = dev_get_sb,
+ .kill_sb = kill_litter_super,
+};
+
+#ifdef CONFIG_BLOCK
+static inline int is_blockdev(struct device *dev)
+{
+ return dev->class == &block_class;
+}
+#else
+static inline int is_blockdev(struct device *dev) { return 0; }
+#endif
+
+static int dev_mkdir(const char *name, mode_t mode)
+{
+ struct nameidata nd;
+ struct dentry *dentry;
+ int err;
+
+ err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+ name, LOOKUP_PARENT, &nd);
+ if (err)
+ return err;
+
+ dentry = lookup_create(&nd, 1);
+ if (!IS_ERR(dentry)) {
+ err = vfs_mkdir(nd.path.dentry->d_inode, dentry, mode);
+ dput(dentry);
+ } else {
+ err = PTR_ERR(dentry);
+ }
+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+ path_put(&nd.path);
+ return err;
+}
+
+static int create_path(const char *nodepath)
+{
+ char *path;
+ struct nameidata nd;
+ int err = 0;
+
+ path = kstrdup(nodepath, GFP_KERNEL);
+ if (!path)
+ return -ENOMEM;
+
+ err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+ path, LOOKUP_PARENT, &nd);
+ if (err == 0) {
+ struct dentry *dentry;
+
+ /* create directory right away */
+ dentry = lookup_create(&nd, 1);
+ if (!IS_ERR(dentry)) {
+ err = vfs_mkdir(nd.path.dentry->d_inode,
+ dentry, 0775);
+ dput(dentry);
+ }
+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+ path_put(&nd.path);
+ } else if (err == -ENOENT) {
+ char *s;
+
+ /* parent directories do not exist, create them */
+ s = path;
+ while (1) {
+ s = strchr(s, '/');
+ if (!s)
+ break;
+ s[0] = '\0';
+ err = dev_mkdir(path, 0755);
+ if (err && err != -EEXIST)
+ break;
+ s[0] = '/';
+ s++;
+ }
+ }
+
+ kfree(path);
+ return err;
+}
+
+int devtmpfs_create_node(struct device *dev)
+{
+ const char *tmp = NULL;
+ const char *nodename;
+ const struct cred *curr_cred;
+ mode_t mode;
+ struct nameidata nd;
+ struct dentry *dentry;
+ int err;
+
+ if (!dev_mnt)
+ return 0;
+
+ nodename = device_get_nodename(dev, &tmp);
+ if (!nodename)
+ return -ENOMEM;
+
+ if (is_blockdev(dev))
+ mode = S_IFBLK|0600;
+ else
+ mode = S_IFCHR|0600;
+
+ curr_cred = override_creds(&init_cred);
+ err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+ nodename, LOOKUP_PARENT, &nd);
+ if (err == -ENOENT) {
+ /* create missing parent directories */
+ create_path(nodename);
+ err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+ nodename, LOOKUP_PARENT, &nd);
+ if (err)
+ goto out;
+ }
+
+ dentry = lookup_create(&nd, 0);
+ if (!IS_ERR(dentry)) {
+ err = vfs_mknod(nd.path.dentry->d_inode,
+ dentry, mode, dev->devt);
+ /* mark as kernel created inode */
+ if (!err)
+ dentry->d_inode->i_private = &dev_mnt;
+ dput(dentry);
+ } else {
+ err = PTR_ERR(dentry);
+ }
+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+ path_put(&nd.path);
+out:
+ kfree(tmp);
+ revert_creds(curr_cred);
+ return err;
+}
+
+static int dev_rmdir(const char *name)
+{
+ struct nameidata nd;
+ struct dentry *dentry;
+ int err;
+
+ err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+ name, LOOKUP_PARENT, &nd);
+ if (err)
+ return err;
+
+ mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+ dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
+ if (!IS_ERR(dentry)) {
+ if (dentry->d_inode)
+ err = vfs_rmdir(nd.path.dentry->d_inode, dentry);
+ else
+ err = -ENOENT;
+ dput(dentry);
+ } else {
+ err = PTR_ERR(dentry);
+ }
+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+ path_put(&nd.path);
+ return err;
+}
+
+static int delete_path(const char *nodepath)
+{
+ const char *path;
+ int err = 0;
+
+ path = kstrdup(nodepath, GFP_KERNEL);
+ if (!path)
+ return -ENOMEM;
+
+ while (1) {
+ char *base;
+
+ base = strrchr(path, '/');
+ if (!base)
+ break;
+ base[0] = '\0';
+ err = dev_rmdir(path);
+ if (err)
+ break;
+ }
+
+ kfree(path);
+ return err;
+}
+
+static int dev_mynode(struct device *dev, struct inode *inode, struct kstat *stat)
+{
+ /* did we create it */
+ if (inode->i_private != &dev_mnt)
+ return 0;
+
+ /* does the dev_t match */
+ if (is_blockdev(dev)) {
+ if (!S_ISBLK(stat->mode))
+ return 0;
+ } else {
+ if (!S_ISCHR(stat->mode))
+ return 0;
+ }
+ if (stat->rdev != dev->devt)
+ return 0;
+
+ /* ours */
+ return 1;
+}
+
+int devtmpfs_delete_node(struct device *dev)
+{
+ const char *tmp = NULL;
+ const char *nodename;
+ const struct cred *curr_cred;
+ struct nameidata nd;
+ struct dentry *dentry;
+ struct kstat stat;
+ int deleted = 1;
+ int err;
+
+ if (!dev_mnt)
+ return 0;
+
+ nodename = device_get_nodename(dev, &tmp);
+ if (!nodename)
+ return -ENOMEM;
+
+ curr_cred = override_creds(&init_cred);
+ err = vfs_path_lookup(dev_mnt->mnt_root, dev_mnt,
+ nodename, LOOKUP_PARENT, &nd);
+ if (err)
+ goto out;
+
+ mutex_lock_nested(&nd.path.dentry->d_inode->i_mutex, I_MUTEX_PARENT);
+ dentry = lookup_one_len(nd.last.name, nd.path.dentry, nd.last.len);
+ if (!IS_ERR(dentry)) {
+ if (dentry->d_inode) {
+ err = vfs_getattr(nd.path.mnt, dentry, &stat);
+ if (!err && dev_mynode(dev, dentry->d_inode, &stat)) {
+ err = vfs_unlink(nd.path.dentry->d_inode,
+ dentry);
+ if (!err || err == -ENOENT)
+ deleted = 1;
+ }
+ } else {
+ err = -ENOENT;
+ }
+ dput(dentry);
+ } else {
+ err = PTR_ERR(dentry);
+ }
+ mutex_unlock(&nd.path.dentry->d_inode->i_mutex);
+
+ path_put(&nd.path);
+ if (deleted && strchr(nodename, '/'))
+ delete_path(nodename);
+out:
+ kfree(tmp);
+ revert_creds(curr_cred);
+ return err;
+}
+
+/*
+ * If configured, or requested by the commandline, devtmpfs will be
+ * auto-mounted after the kernel mounted the root filesystem.
+ */
+int devtmpfs_mount(const char *mountpoint)
+{
+ struct path path;
+ int err;
+
+ if (!dev_mount)
+ return 0;
+
+ if (!dev_mnt)
+ return 0;
+
+ err = kern_path(mountpoint, LOOKUP_FOLLOW, &path);
+ if (err)
+ return err;
+ err = do_add_mount(dev_mnt, &path, 0, NULL);
+ if (err)
+ printk(KERN_INFO "devtmpfs: error mounting %i\n", err);
+ else
+ printk(KERN_INFO "devtmpfs: mounted\n");
+ path_put(&path);
+ return err;
+}
+
+/*
+ * Create devtmpfs instance, driver-core devices will add their device
+ * nodes here.
+ */
+int __init devtmpfs_init(void)
+{
+ int err;
+ struct vfsmount *mnt;
+
+ err = register_filesystem(&dev_fs_type);
+ if (err) {
+ printk(KERN_ERR "devtmpfs: unable to register devtmpfs "
+ "type %i\n", err);
+ return err;
+ }
+
+ mnt = kern_mount(&dev_fs_type);
+ if (IS_ERR(mnt)) {
+ err = PTR_ERR(mnt);
+ printk(KERN_ERR "devtmpfs: unable to create devtmpfs %i\n", err);
+ unregister_filesystem(&dev_fs_type);
+ return err;
+ }
+ dev_mnt = mnt;
+
+ printk(KERN_INFO "devtmpfs: initialized\n");
+ return 0;
+}
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/dma-coherent.c linux-2.6.31-rc4-git5-driver-core/drivers/base/dma-coherent.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/dma-coherent.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/dma-coherent.c 2009-07-31 09:56:42.000000000 -0700
@@ -0,0 +1,176 @@
+/*
+ * Coherent per-device memory handling.
+ * Borrowed from i386
+ */
+#include
+#include
+
+struct dma_coherent_mem {
+ void *virt_base;
+ u32 device_base;
+ int size;
+ int flags;
+ unsigned long *bitmap;
+};
+
+int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
+ dma_addr_t device_addr, size_t size, int flags)
+{
+ void __iomem *mem_base = NULL;
+ int pages = size >> PAGE_SHIFT;
+ int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
+
+ if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
+ goto out;
+ if (!size)
+ goto out;
+ if (dev->dma_mem)
+ goto out;
+
+ /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
+
+ mem_base = ioremap(bus_addr, size);
+ if (!mem_base)
+ goto out;
+
+ dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
+ if (!dev->dma_mem)
+ goto out;
+ dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+ if (!dev->dma_mem->bitmap)
+ goto free1_out;
+
+ dev->dma_mem->virt_base = mem_base;
+ dev->dma_mem->device_base = device_addr;
+ dev->dma_mem->size = pages;
+ dev->dma_mem->flags = flags;
+
+ if (flags & DMA_MEMORY_MAP)
+ return DMA_MEMORY_MAP;
+
+ return DMA_MEMORY_IO;
+
+ free1_out:
+ kfree(dev->dma_mem);
+ out:
+ if (mem_base)
+ iounmap(mem_base);
+ return 0;
+}
+EXPORT_SYMBOL(dma_declare_coherent_memory);
+
+void dma_release_declared_memory(struct device *dev)
+{
+ struct dma_coherent_mem *mem = dev->dma_mem;
+
+ if (!mem)
+ return;
+ dev->dma_mem = NULL;
+ iounmap(mem->virt_base);
+ kfree(mem->bitmap);
+ kfree(mem);
+}
+EXPORT_SYMBOL(dma_release_declared_memory);
+
+void *dma_mark_declared_memory_occupied(struct device *dev,
+ dma_addr_t device_addr, size_t size)
+{
+ struct dma_coherent_mem *mem = dev->dma_mem;
+ int pos, err;
+
+ size += device_addr & ~PAGE_MASK;
+
+ if (!mem)
+ return ERR_PTR(-EINVAL);
+
+ pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
+ err = bitmap_allocate_region(mem->bitmap, pos, get_order(size));
+ if (err != 0)
+ return ERR_PTR(err);
+ return mem->virt_base + (pos << PAGE_SHIFT);
+}
+EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
+
+/**
+ * dma_alloc_from_coherent() - try to allocate memory from the per-device coherent area
+ *
+ * @dev: device from which we allocate memory
+ * @size: size of requested memory area
+ * @dma_handle: This will be filled with the correct dma handle
+ * @ret: This pointer will be filled with the virtual address
+ * to allocated area.
+ *
+ * This function should be only called from per-arch dma_alloc_coherent()
+ * to support allocation from per-device coherent memory pools.
+ *
+ * Returns 0 if dma_alloc_coherent should continue with allocating from
+ * generic memory areas, or !0 if dma_alloc_coherent should return @ret.
+ */
+int dma_alloc_from_coherent(struct device *dev, ssize_t size,
+ dma_addr_t *dma_handle, void **ret)
+{
+ struct dma_coherent_mem *mem;
+ int order = get_order(size);
+ int pageno;
+
+ if (!dev)
+ return 0;
+ mem = dev->dma_mem;
+ if (!mem)
+ return 0;
+
+ *ret = NULL;
+
+ if (unlikely(size > (mem->size << PAGE_SHIFT)))
+ goto err;
+
+ pageno = bitmap_find_free_region(mem->bitmap, mem->size, order);
+ if (unlikely(pageno < 0))
+ goto err;
+
+ /*
+ * Memory was found in the per-device area.
+ */
+ *dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
+ *ret = mem->virt_base + (pageno << PAGE_SHIFT);
+ memset(*ret, 0, size);
+
+ return 1;
+
+err:
+ /*
+ * In the case where the allocation can not be satisfied from the
+ * per-device area, try to fall back to generic memory if the
+ * constraints allow it.
+ */
+ return mem->flags & DMA_MEMORY_EXCLUSIVE;
+}
+EXPORT_SYMBOL(dma_alloc_from_coherent);
+
+/**
+ * dma_release_from_coherent() - try to free the memory allocated from per-device coherent memory pool
+ * @dev: device from which the memory was allocated
+ * @order: the order of pages allocated
+ * @vaddr: virtual address of allocated pages
+ *
+ * This checks whether the memory was allocated from the per-device
+ * coherent memory pool and if so, releases that memory.
+ *
+ * Returns 1 if we correctly released the memory, or 0 if
+ * dma_release_coherent() should proceed with releasing memory from
+ * generic pools.
+ */
+int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
+{
+ struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
+
+ if (mem && vaddr >= mem->virt_base && vaddr <
+ (mem->virt_base + (mem->size << PAGE_SHIFT))) {
+ int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
+
+ bitmap_release_region(mem->bitmap, page, order);
+ return 1;
+ }
+ return 0;
+}
+EXPORT_SYMBOL(dma_release_from_coherent);
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/driver.c linux-2.6.31-rc4-git5-driver-core/drivers/base/driver.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/driver.c 2009-06-15 12:15:29.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/driver.c 2009-07-31 09:56:41.000000000 -0700
@@ -181,7 +181,7 @@
EXPORT_SYMBOL_GPL(put_driver);
static int driver_add_groups(struct device_driver *drv,
- struct attribute_group **groups)
+ const struct attribute_group **groups)
{
int error = 0;
int i;
@@ -201,7 +201,7 @@
}
static void driver_remove_groups(struct device_driver *drv,
- struct attribute_group **groups)
+ const struct attribute_group **groups)
{
int i;
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/init.c linux-2.6.31-rc4-git5-driver-core/drivers/base/init.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/init.c 2008-04-16 22:53:28.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/init.c 2009-07-31 09:56:42.000000000 -0700
@@ -20,6 +20,7 @@
void __init driver_init(void)
{
/* These are the core pieces */
+ devtmpfs_init();
devices_init();
buses_init();
classes_init();
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/Kconfig linux-2.6.31-rc4-git5-driver-core/drivers/base/Kconfig
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/Kconfig 2009-03-24 09:43:58.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/Kconfig 2009-07-31 09:56:42.000000000 -0700
@@ -8,6 +8,31 @@
Path to uevent helper program forked by the kernel for
every uevent.
+config DEVTMPFS
+ bool "Create a kernel maintained /dev tmpfs (EXPERIMENTAL)"
+ depends on HOTPLUG && SHMEM && TMPFS
+ help
+ This creates a tmpfs filesystem, and mounts it at bootup
+ and mounts it at /dev. The kernel driver core creates device
+ nodes for all registered devices in that filesystem. All device
+ nodes are owned by root and have the default mode of 0600.
+ Userspace can add and delete the nodes as needed. This is
+ intended to simplify bootup, and make it possible to delay
+ the initial coldplug at bootup done by udev in userspace.
+ It should also provide a simpler way for rescue systems
+ to bring up a kernel with dynamic major/minor numbers.
+ Meaningful symlinks, permissions and device ownership must
+ still be handled by userspace.
+ If unsure, say N here.
+
+config DEVTMPFS_MOUNT
+ bool "Automount devtmpfs at /dev"
+ depends on DEVTMPFS
+ help
+ This will mount devtmpfs at /dev if the kernel mounts the root
+ filesystem. It will not affect initramfs based mounting.
+ If unsure, say N here.
+
config STANDALONE
bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL
default y
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/base/Makefile linux-2.6.31-rc4-git5-driver-core/drivers/base/Makefile
--- linux-2.6.31-rc4-git5-usb.current/drivers/base/Makefile 2009-03-24 09:43:58.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/base/Makefile 2009-07-31 09:56:42.000000000 -0700
@@ -4,8 +4,10 @@
driver.o class.o platform.o \
cpu.o firmware.o init.o map.o devres.o \
attribute_container.o transport_class.o
+obj-$(CONFIG_DEVTMPFS) += devtmpfs.o
obj-y += power/
obj-$(CONFIG_HAS_DMA) += dma-mapping.o
+obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
obj-$(CONFIG_ISA) += isa.o
obj-$(CONFIG_FW_LOADER) += firmware_class.o
obj-$(CONFIG_NUMA) += node.o
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/block/cciss.c linux-2.6.31-rc4-git5-driver-core/drivers/block/cciss.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/block/cciss.c 2009-07-24 11:07:31.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/block/cciss.c 2009-07-31 09:56:41.000000000 -0700
@@ -572,7 +572,7 @@
.attrs = cciss_dev_attrs,
};
-static struct attribute_group *cciss_dev_attr_groups[] = {
+static const struct attribute_group *cciss_dev_attr_groups[] = {
&cciss_dev_attr_group,
NULL
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/char/mem.c linux-2.6.31-rc4-git5-driver-core/drivers/char/mem.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/char/mem.c 2009-07-24 11:07:31.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/char/mem.c 2009-07-31 09:56:42.000000000 -0700
@@ -863,71 +863,67 @@
.write = kmsg_write,
};
-static const struct {
- unsigned int minor;
- char *name;
- umode_t mode;
- const struct file_operations *fops;
- struct backing_dev_info *dev_info;
-} devlist[] = { /* list of minor devices */
- {1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops,
- &directly_mappable_cdev_bdi},
+static const struct memdev {
+ const char *name;
+ const struct file_operations *fops;
+ struct backing_dev_info *dev_info;
+} devlist[] = {
+ [ 1] = { "mem", &mem_fops, &directly_mappable_cdev_bdi },
#ifdef CONFIG_DEVKMEM
- {2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops,
- &directly_mappable_cdev_bdi},
+ [ 2] = { "kmem", &kmem_fops, &directly_mappable_cdev_bdi },
#endif
- {3, "null", S_IRUGO | S_IWUGO, &null_fops, NULL},
+ [ 3] = {"null", &null_fops, NULL },
#ifdef CONFIG_DEVPORT
- {4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops, NULL},
+ [ 4] = { "port", &port_fops, NULL },
#endif
- {5, "zero", S_IRUGO | S_IWUGO, &zero_fops, &zero_bdi},
- {7, "full", S_IRUGO | S_IWUGO, &full_fops, NULL},
- {8, "random", S_IRUGO | S_IWUSR, &random_fops, NULL},
- {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops, NULL},
- {11,"kmsg", S_IRUGO | S_IWUSR, &kmsg_fops, NULL},
+ [ 5] = { "zero", &zero_fops, &zero_bdi },
+ [ 6] = { "full", &full_fops, NULL },
+ [ 7] = { "random", &random_fops, NULL },
+ [ 9] = { "urandom", &urandom_fops, NULL },
+ [11] = { "kmsg", &kmsg_fops, NULL },
#ifdef CONFIG_CRASH_DUMP
- {12,"oldmem", S_IRUSR | S_IWUSR | S_IRGRP, &oldmem_fops, NULL},
+ [12] = { "oldmem", &oldmem_fops, NULL },
#endif
};
static int memory_open(struct inode *inode, struct file *filp)
{
- int ret = 0;
- int i;
+ int minor;
+ const struct memdev *dev;
+ int ret = -ENXIO;
lock_kernel();
- for (i = 0; i < ARRAY_SIZE(devlist); i++) {
- if (devlist[i].minor == iminor(inode)) {
- filp->f_op = devlist[i].fops;
- if (devlist[i].dev_info) {
- filp->f_mapping->backing_dev_info =
- devlist[i].dev_info;
- }
+ minor = iminor(inode);
+ if (minor >= ARRAY_SIZE(devlist))
+ goto out;
+
+ dev = &devlist[minor];
+ if (!dev->fops)
+ goto out;
+
+ filp->f_op = dev->fops;
+ if (dev->dev_info)
+ filp->f_mapping->backing_dev_info = dev->dev_info;
- break;
- }
- }
-
- if (i == ARRAY_SIZE(devlist))
- ret = -ENXIO;
+ if (dev->fops->open)
+ ret = dev->fops->open(inode, filp);
else
- if (filp->f_op && filp->f_op->open)
- ret = filp->f_op->open(inode, filp);
-
+ ret = 0;
+out:
unlock_kernel();
return ret;
}
static const struct file_operations memory_fops = {
- .open = memory_open, /* just a selector for the real open */
+ .open = memory_open,
};
static struct class *mem_class;
static int __init chr_dev_init(void)
{
- int i;
+ int minor;
int err;
err = bdi_init(&zero_bdi);
@@ -938,10 +934,12 @@
printk("unable to get major %d for memory devs\n", MEM_MAJOR);
mem_class = class_create(THIS_MODULE, "mem");
- for (i = 0; i < ARRAY_SIZE(devlist); i++)
- device_create(mem_class, NULL,
- MKDEV(MEM_MAJOR, devlist[i].minor), NULL,
- devlist[i].name);
+ for (minor = 1; minor < ARRAY_SIZE(devlist); minor++) {
+ if (!devlist[minor].name)
+ continue;
+ device_create(mem_class, NULL, MKDEV(MEM_MAJOR, minor),
+ NULL, devlist[minor].name);
+ }
return 0;
}
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/firewire/core-device.c linux-2.6.31-rc4-git5-driver-core/drivers/firewire/core-device.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/firewire/core-device.c 2009-07-24 11:07:31.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/firewire/core-device.c 2009-07-31 09:56:41.000000000 -0700
@@ -312,7 +312,7 @@
group->groups[0] = &group->group;
group->groups[1] = NULL;
group->group.attrs = group->attrs;
- dev->groups = group->groups;
+ dev->groups = (const struct attribute_group **) group->groups;
}
static ssize_t modalias_show(struct device *dev,
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/firmware/dmi-id.c linux-2.6.31-rc4-git5-driver-core/drivers/firmware/dmi-id.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/firmware/dmi-id.c 2009-03-24 09:43:58.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/firmware/dmi-id.c 2009-07-31 09:56:41.000000000 -0700
@@ -139,7 +139,7 @@
.attrs = sys_dmi_attributes,
};
-static struct attribute_group* sys_dmi_attribute_groups[] = {
+static const struct attribute_group* sys_dmi_attribute_groups[] = {
&sys_dmi_attribute_group,
NULL
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/infiniband/hw/ehca/ehca_main.c linux-2.6.31-rc4-git5-driver-core/drivers/infiniband/hw/ehca/ehca_main.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/infiniband/hw/ehca/ehca_main.c 2009-07-24 11:07:32.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/infiniband/hw/ehca/ehca_main.c 2009-07-31 09:56:41.000000000 -0700
@@ -623,7 +623,7 @@
.attrs = ehca_drv_attrs
};
-static struct attribute_group *ehca_drv_attr_groups[] = {
+static const struct attribute_group *ehca_drv_attr_groups[] = {
&ehca_drv_attr_grp,
NULL,
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/infiniband/hw/ipath/ipath_kernel.h linux-2.6.31-rc4-git5-driver-core/drivers/infiniband/hw/ipath/ipath_kernel.h
--- linux-2.6.31-rc4-git5-usb.current/drivers/infiniband/hw/ipath/ipath_kernel.h 2009-03-24 09:43:58.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/infiniband/hw/ipath/ipath_kernel.h 2009-07-31 09:56:42.000000000 -0700
@@ -1286,7 +1286,7 @@
extern const char ib_ipath_version[];
-extern struct attribute_group *ipath_driver_attr_groups[];
+extern const struct attribute_group *ipath_driver_attr_groups[];
int ipath_device_create_group(struct device *, struct ipath_devdata *);
void ipath_device_remove_group(struct device *, struct ipath_devdata *);
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/infiniband/hw/ipath/ipath_sysfs.c linux-2.6.31-rc4-git5-driver-core/drivers/infiniband/hw/ipath/ipath_sysfs.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/infiniband/hw/ipath/ipath_sysfs.c 2008-07-18 12:15:58.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/infiniband/hw/ipath/ipath_sysfs.c 2009-07-31 09:56:42.000000000 -0700
@@ -1069,7 +1069,7 @@
return ret;
}
-struct attribute_group *ipath_driver_attr_groups[] = {
+const struct attribute_group *ipath_driver_attr_groups[] = {
&driver_attr_group,
NULL,
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/input/input.c linux-2.6.31-rc4-git5-driver-core/drivers/input/input.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/input/input.c 2009-07-24 11:07:32.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/input/input.c 2009-07-31 09:56:42.000000000 -0700
@@ -1144,7 +1144,7 @@
.attrs = input_dev_caps_attrs,
};
-static struct attribute_group *input_dev_attr_groups[] = {
+static const struct attribute_group *input_dev_attr_groups[] = {
&input_dev_attr_group,
&input_dev_id_attr_group,
&input_dev_caps_attr_group,
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/misc/enclosure.c linux-2.6.31-rc4-git5-driver-core/drivers/misc/enclosure.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/misc/enclosure.c 2009-06-15 12:15:35.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/misc/enclosure.c 2009-07-31 09:56:42.000000000 -0700
@@ -218,7 +218,7 @@
put_device(dev->parent);
}
-static struct attribute_group *enclosure_groups[];
+static const struct attribute_group *enclosure_groups[];
/**
* enclosure_component_register - add a particular component to an enclosure
@@ -507,7 +507,7 @@
.attrs = enclosure_component_attrs,
};
-static struct attribute_group *enclosure_groups[] = {
+static const struct attribute_group *enclosure_groups[] = {
&enclosure_group,
NULL
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/mmc/core/mmc.c linux-2.6.31-rc4-git5-driver-core/drivers/mmc/core/mmc.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/mmc/core/mmc.c 2009-06-15 12:15:35.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/mmc/core/mmc.c 2009-07-31 09:56:42.000000000 -0700
@@ -276,7 +276,7 @@
.attrs = mmc_std_attrs,
};
-static struct attribute_group *mmc_attr_groups[] = {
+static const struct attribute_group *mmc_attr_groups[] = {
&mmc_std_attr_group,
NULL,
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/mmc/core/sd.c linux-2.6.31-rc4-git5-driver-core/drivers/mmc/core/sd.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/mmc/core/sd.c 2009-06-15 12:15:35.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/mmc/core/sd.c 2009-07-31 09:56:42.000000000 -0700
@@ -314,7 +314,7 @@
.attrs = sd_std_attrs,
};
-static struct attribute_group *sd_attr_groups[] = {
+static const struct attribute_group *sd_attr_groups[] = {
&sd_std_attr_group,
NULL,
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/mtd/mtdcore.c linux-2.6.31-rc4-git5-driver-core/drivers/mtd/mtdcore.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/mtd/mtdcore.c 2009-07-24 11:07:37.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/mtd/mtdcore.c 2009-07-31 09:56:42.000000000 -0700
@@ -217,7 +217,7 @@
.attrs = mtd_attrs,
};
-struct attribute_group *mtd_groups[] = {
+const struct attribute_group *mtd_groups[] = {
&mtd_group,
NULL,
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/s390/cio/css.c linux-2.6.31-rc4-git5-driver-core/drivers/s390/cio/css.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/s390/cio/css.c 2009-07-24 11:07:42.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/s390/cio/css.c 2009-07-31 09:56:42.000000000 -0700
@@ -273,7 +273,7 @@
.attrs = subch_attrs,
};
-static struct attribute_group *default_subch_attr_groups[] = {
+static const struct attribute_group *default_subch_attr_groups[] = {
&subch_attr_group,
NULL,
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/s390/cio/device.c linux-2.6.31-rc4-git5-driver-core/drivers/s390/cio/device.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/s390/cio/device.c 2009-07-24 11:07:42.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/s390/cio/device.c 2009-07-31 09:56:42.000000000 -0700
@@ -624,7 +624,7 @@
.attrs = ccwdev_attrs,
};
-static struct attribute_group *ccwdev_attr_groups[] = {
+static const struct attribute_group *ccwdev_attr_groups[] = {
&ccwdev_attr_group,
NULL,
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/s390/net/netiucv.c linux-2.6.31-rc4-git5-driver-core/drivers/s390/net/netiucv.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/s390/net/netiucv.c 2009-07-24 11:07:42.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/s390/net/netiucv.c 2009-07-31 09:56:42.000000000 -0700
@@ -2159,7 +2159,7 @@
.attrs = netiucv_drv_attrs,
};
-static struct attribute_group *netiucv_drv_attr_groups[] = {
+static const struct attribute_group *netiucv_drv_attr_groups[] = {
&netiucv_drv_attr_group,
NULL,
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/scsi/scsi_priv.h linux-2.6.31-rc4-git5-driver-core/drivers/scsi/scsi_priv.h
--- linux-2.6.31-rc4-git5-usb.current/drivers/scsi/scsi_priv.h 2009-07-24 11:07:44.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/scsi/scsi_priv.h 2009-07-31 09:56:42.000000000 -0700
@@ -132,7 +132,7 @@
extern void __scsi_remove_device(struct scsi_device *);
extern struct bus_type scsi_bus_type;
-extern struct attribute_group *scsi_sysfs_shost_attr_groups[];
+extern const struct attribute_group *scsi_sysfs_shost_attr_groups[];
/* scsi_netlink.c */
#ifdef CONFIG_SCSI_NETLINK
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/scsi/scsi_sysfs.c linux-2.6.31-rc4-git5-driver-core/drivers/scsi/scsi_sysfs.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/scsi/scsi_sysfs.c 2009-07-24 11:07:44.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/scsi/scsi_sysfs.c 2009-07-31 09:56:42.000000000 -0700
@@ -275,7 +275,7 @@
.attrs = scsi_sysfs_shost_attrs,
};
-struct attribute_group *scsi_sysfs_shost_attr_groups[] = {
+const struct attribute_group *scsi_sysfs_shost_attr_groups[] = {
&scsi_shost_attr_group,
NULL
};
@@ -745,7 +745,7 @@
.attrs = scsi_sdev_attrs,
};
-static struct attribute_group *scsi_sdev_attr_groups[] = {
+static const struct attribute_group *scsi_sdev_attr_groups[] = {
&scsi_sdev_attr_group,
NULL
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/uio/Kconfig linux-2.6.31-rc4-git5-driver-core/drivers/uio/Kconfig
--- linux-2.6.31-rc4-git5-usb.current/drivers/uio/Kconfig 2009-06-15 12:15:47.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/uio/Kconfig 2009-07-31 09:56:42.000000000 -0700
@@ -1,7 +1,6 @@
menuconfig UIO
tristate "Userspace I/O drivers"
depends on !S390
- default n
help
Enable this to allow the userspace driver core code to be
built. This code allows userspace programs easy access to
@@ -16,7 +15,6 @@
config UIO_CIF
tristate "generic Hilscher CIF Card driver"
depends on PCI
- default n
help
Driver for Hilscher CIF DeviceNet and Profibus cards. This
driver requires a userspace component that handles all of the
@@ -48,7 +46,6 @@
config UIO_SMX
tristate "SMX cryptengine UIO interface"
- default n
help
Userspace IO interface to the Cryptography engine found on the
Nias Digital SMX boards. These will be available from Q4 2008
@@ -61,7 +58,6 @@
config UIO_AEC
tristate "AEC video timestamp device"
depends on PCI
- default n
help
UIO driver for the Adrienne Electronics Corporation PCI time
@@ -78,7 +74,6 @@
config UIO_SERCOS3
tristate "Automata Sercos III PCI card driver"
- default n
help
Userspace I/O interface for the Sercos III PCI card from
Automata GmbH. The userspace part of this driver will be
@@ -89,4 +84,14 @@
If you compile this as a module, it will be called uio_sercos3.
+config UIO_PCI_GENERIC
+ tristate "Generic driver for PCI 2.3 and PCI Express cards"
+ depends on PCI
+ default n
+ help
+ Generic driver that you can bind, dynamically, to any
+ PCI 2.3 compliant and PCI Express card. It is useful,
+ primarily, for virtualization scenarios.
+ If you compile this as a module, it will be called uio_pci_generic.
+
endif
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/uio/Makefile linux-2.6.31-rc4-git5-driver-core/drivers/uio/Makefile
--- linux-2.6.31-rc4-git5-usb.current/drivers/uio/Makefile 2009-06-15 12:15:47.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/uio/Makefile 2009-07-31 09:56:42.000000000 -0700
@@ -5,3 +5,4 @@
obj-$(CONFIG_UIO_SMX) += uio_smx.o
obj-$(CONFIG_UIO_AEC) += uio_aec.o
obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
+obj-$(CONFIG_UIO_PCI_GENERIC) += uio_pci_generic.o
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/uio/uio_pci_generic.c linux-2.6.31-rc4-git5-driver-core/drivers/uio/uio_pci_generic.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/uio/uio_pci_generic.c 1969-12-31 16:00:00.000000000 -0800
+++ linux-2.6.31-rc4-git5-driver-core/drivers/uio/uio_pci_generic.c 2009-07-31 09:56:42.000000000 -0700
@@ -0,0 +1,207 @@
+/* uio_pci_generic - generic UIO driver for PCI 2.3 devices
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ * Author: Michael S. Tsirkin
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.
+ *
+ * Since the driver does not declare any device ids, you must allocate
+ * id and bind the device to the driver yourself. For example:
+ *
+ * # echo "8086 10f5" > /sys/bus/pci/drivers/uio_pci_generic/new_id
+ * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/e1000e/unbind
+ * # echo -n 0000:00:19.0 > /sys/bus/pci/drivers/uio_pci_generic/bind
+ * # ls -l /sys/bus/pci/devices/0000:00:19.0/driver
+ * .../0000:00:19.0/driver -> ../../../bus/pci/drivers/uio_pci_generic
+ *
+ * Driver won't bind to devices which do not support the Interrupt Disable Bit
+ * in the command register. All devices compliant to PCI 2.3 (circa 2002) and
+ * all compliant PCI Express devices should support this bit.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#define DRIVER_VERSION "0.01.0"
+#define DRIVER_AUTHOR "Michael S. Tsirkin "
+#define DRIVER_DESC "Generic UIO driver for PCI 2.3 devices"
+
+struct uio_pci_generic_dev {
+ struct uio_info info;
+ struct pci_dev *pdev;
+ spinlock_t lock; /* guards command register accesses */
+};
+
+static inline struct uio_pci_generic_dev *
+to_uio_pci_generic_dev(struct uio_info *info)
+{
+ return container_of(info, struct uio_pci_generic_dev, info);
+}
+
+/* Interrupt handler. Read/modify/write the command register to disable
+ * the interrupt. */
+static irqreturn_t irqhandler(int irq, struct uio_info *info)
+{
+ struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
+ struct pci_dev *pdev = gdev->pdev;
+ irqreturn_t ret = IRQ_NONE;
+ u32 cmd_status_dword;
+ u16 origcmd, newcmd, status;
+
+ /* We do a single dword read to retrieve both command and status.
+ * Document assumptions that make this possible. */
+ BUILD_BUG_ON(PCI_COMMAND % 4);
+ BUILD_BUG_ON(PCI_COMMAND + 2 != PCI_STATUS);
+
+ spin_lock_irq(&gdev->lock);
+ pci_block_user_cfg_access(pdev);
+
+ /* Read both command and status registers in a single 32-bit operation.
+ * Note: we could cache the value for command and move the status read
+ * out of the lock if there was a way to get notified of user changes
+ * to command register through sysfs. Should be good for shared irqs. */
+ pci_read_config_dword(pdev, PCI_COMMAND, &cmd_status_dword);
+ origcmd = cmd_status_dword;
+ status = cmd_status_dword >> 16;
+
+ /* Check interrupt status register to see whether our device
+ * triggered the interrupt. */
+ if (!(status & PCI_STATUS_INTERRUPT))
+ goto done;
+
+ /* We triggered the interrupt, disable it. */
+ newcmd = origcmd | PCI_COMMAND_INTX_DISABLE;
+ if (newcmd != origcmd)
+ pci_write_config_word(pdev, PCI_COMMAND, newcmd);
+
+ /* UIO core will signal the user process. */
+ ret = IRQ_HANDLED;
+done:
+
+ pci_unblock_user_cfg_access(pdev);
+ spin_unlock_irq(&gdev->lock);
+ return ret;
+}
+
+/* Verify that the device supports Interrupt Disable bit in command register,
+ * per PCI 2.3, by flipping this bit and reading it back: this bit was readonly
+ * in PCI 2.2. */
+static int __devinit verify_pci_2_3(struct pci_dev *pdev)
+{
+ u16 orig, new;
+ int err = 0;
+
+ pci_block_user_cfg_access(pdev);
+ pci_read_config_word(pdev, PCI_COMMAND, &orig);
+ pci_write_config_word(pdev, PCI_COMMAND,
+ orig ^ PCI_COMMAND_INTX_DISABLE);
+ pci_read_config_word(pdev, PCI_COMMAND, &new);
+ /* There's no way to protect against
+ * hardware bugs or detect them reliably, but as long as we know
+ * what the value should be, let's go ahead and check it. */
+ if ((new ^ orig) & ~PCI_COMMAND_INTX_DISABLE) {
+ err = -EBUSY;
+ dev_err(&pdev->dev, "Command changed from 0x%x to 0x%x: "
+ "driver or HW bug?\n", orig, new);
+ goto err;
+ }
+ if (!((new ^ orig) & PCI_COMMAND_INTX_DISABLE)) {
+ dev_warn(&pdev->dev, "Device does not support "
+ "disabling interrupts: unable to bind.\n");
+ err = -ENODEV;
+ goto err;
+ }
+ /* Now restore the original value. */
+ pci_write_config_word(pdev, PCI_COMMAND, orig);
+err:
+ pci_unblock_user_cfg_access(pdev);
+ return err;
+}
+
+static int __devinit probe(struct pci_dev *pdev,
+ const struct pci_device_id *id)
+{
+ struct uio_pci_generic_dev *gdev;
+ int err;
+
+ if (!pdev->irq) {
+ dev_warn(&pdev->dev, "No IRQ assigned to device: "
+ "no support for interrupts?\n");
+ return -ENODEV;
+ }
+
+ err = pci_enable_device(pdev);
+ if (err) {
+ dev_err(&pdev->dev, "%s: pci_enable_device failed: %d\n",
+ __func__, err);
+ return err;
+ }
+
+ err = verify_pci_2_3(pdev);
+ if (err)
+ goto err_verify;
+
+ gdev = kzalloc(sizeof(struct uio_pci_generic_dev), GFP_KERNEL);
+ if (!gdev) {
+ err = -ENOMEM;
+ goto err_alloc;
+ }
+
+ gdev->info.name = "uio_pci_generic";
+ gdev->info.version = DRIVER_VERSION;
+ gdev->info.irq = pdev->irq;
+ gdev->info.irq_flags = IRQF_SHARED;
+ gdev->info.handler = irqhandler;
+ gdev->pdev = pdev;
+ spin_lock_init(&gdev->lock);
+
+ if (uio_register_device(&pdev->dev, &gdev->info))
+ goto err_register;
+ pci_set_drvdata(pdev, gdev);
+
+ return 0;
+err_register:
+ kfree(gdev);
+err_alloc:
+err_verify:
+ pci_disable_device(pdev);
+ return err;
+}
+
+static void remove(struct pci_dev *pdev)
+{
+ struct uio_pci_generic_dev *gdev = pci_get_drvdata(pdev);
+
+ uio_unregister_device(&gdev->info);
+ pci_disable_device(pdev);
+ kfree(gdev);
+}
+
+static struct pci_driver driver = {
+ .name = "uio_pci_generic",
+ .id_table = NULL, /* only dynamic id's */
+ .probe = probe,
+ .remove = remove,
+};
+
+static int __init init(void)
+{
+ pr_info(DRIVER_DESC " version: " DRIVER_VERSION "\n");
+ return pci_register_driver(&driver);
+}
+
+static void __exit cleanup(void)
+{
+ pci_unregister_driver(&driver);
+}
+
+module_init(init);
+module_exit(cleanup);
+
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/usb/core/endpoint.c linux-2.6.31-rc4-git5-driver-core/drivers/usb/core/endpoint.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/usb/core/endpoint.c 2009-07-24 11:07:46.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/usb/core/endpoint.c 2009-07-31 09:56:42.000000000 -0700
@@ -154,7 +154,7 @@
static struct attribute_group ep_dev_attr_grp = {
.attrs = ep_dev_attrs,
};
-static struct attribute_group *ep_dev_groups[] = {
+static const struct attribute_group *ep_dev_groups[] = {
&ep_dev_attr_grp,
NULL
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/usb/core/sysfs.c linux-2.6.31-rc4-git5-driver-core/drivers/usb/core/sysfs.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/usb/core/sysfs.c 2009-07-24 11:07:46.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/usb/core/sysfs.c 2009-07-31 09:56:42.000000000 -0700
@@ -573,7 +573,7 @@
.is_visible = dev_string_attrs_are_visible,
};
-struct attribute_group *usb_device_groups[] = {
+const struct attribute_group *usb_device_groups[] = {
&dev_attr_grp,
&dev_string_attr_grp,
NULL
@@ -799,7 +799,7 @@
.is_visible = intf_assoc_attrs_are_visible,
};
-struct attribute_group *usb_interface_groups[] = {
+const struct attribute_group *usb_interface_groups[] = {
&intf_attr_grp,
&intf_assoc_attr_grp,
NULL
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/usb/core/usb.h linux-2.6.31-rc4-git5-driver-core/drivers/usb/core/usb.h
--- linux-2.6.31-rc4-git5-usb.current/drivers/usb/core/usb.h 2009-07-24 11:07:47.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/usb/core/usb.h 2009-07-31 09:56:42.000000000 -0700
@@ -152,8 +152,8 @@
extern const char *usbcore_name;
/* sysfs stuff */
-extern struct attribute_group *usb_device_groups[];
-extern struct attribute_group *usb_interface_groups[];
+extern const struct attribute_group *usb_device_groups[];
+extern const struct attribute_group *usb_interface_groups[];
/* usbfs stuff */
extern struct mutex usbfs_mutex;
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/drivers/uwb/lc-dev.c linux-2.6.31-rc4-git5-driver-core/drivers/uwb/lc-dev.c
--- linux-2.6.31-rc4-git5-usb.current/drivers/uwb/lc-dev.c 2009-03-24 09:44:06.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/drivers/uwb/lc-dev.c 2009-07-31 09:56:42.000000000 -0700
@@ -255,7 +255,7 @@
.attrs = dev_attrs,
};
-static struct attribute_group *groups[] = {
+static const struct attribute_group *groups[] = {
&dev_attr_group,
NULL,
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/fs/partitions/check.c linux-2.6.31-rc4-git5-driver-core/fs/partitions/check.c
--- linux-2.6.31-rc4-git5-usb.current/fs/partitions/check.c 2009-07-24 11:07:48.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/fs/partitions/check.c 2009-07-31 09:56:42.000000000 -0700
@@ -302,7 +302,7 @@
.attrs = part_attrs,
};
-static struct attribute_group *part_attr_groups[] = {
+static const struct attribute_group *part_attr_groups[] = {
&part_attr_group,
#ifdef CONFIG_BLK_DEV_IO_TRACE
&blk_trace_attr_group,
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/include/linux/attribute_container.h linux-2.6.31-rc4-git5-driver-core/include/linux/attribute_container.h
--- linux-2.6.31-rc4-git5-usb.current/include/linux/attribute_container.h 2008-07-18 12:16:09.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/include/linux/attribute_container.h 2009-07-31 09:56:42.000000000 -0700
@@ -17,7 +17,7 @@
struct list_head node;
struct klist containers;
struct class *class;
- struct attribute_group *grp;
+ const struct attribute_group *grp;
struct device_attribute **attrs;
int (*match)(struct attribute_container *, struct device *);
#define ATTRIBUTE_CONTAINER_NO_CLASSDEVS 0x01
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/include/linux/device.h linux-2.6.31-rc4-git5-driver-core/include/linux/device.h
--- linux-2.6.31-rc4-git5-usb.current/include/linux/device.h 2009-07-24 11:07:49.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/include/linux/device.h 2009-07-31 09:56:42.000000000 -0700
@@ -2,7 +2,8 @@
* device.h - generic, centralized driver model
*
* Copyright (c) 2001-2003 Patrick Mochel
- * Copyright (c) 2004-2007 Greg Kroah-Hartman
+ * Copyright (c) 2004-2009 Greg Kroah-Hartman
+ * Copyright (c) 2008-2009 Novell Inc.
*
* This file is released under the GPLv2
*
@@ -130,7 +131,7 @@
void (*shutdown) (struct device *dev);
int (*suspend) (struct device *dev, pm_message_t state);
int (*resume) (struct device *dev);
- struct attribute_group **groups;
+ const struct attribute_group **groups;
struct dev_pm_ops *pm;
@@ -286,7 +287,7 @@
*/
struct device_type {
const char *name;
- struct attribute_group **groups;
+ const struct attribute_group **groups;
int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
char *(*nodename)(struct device *dev);
void (*release)(struct device *dev);
@@ -380,7 +381,6 @@
struct bus_type *bus; /* type of bus device is on */
struct device_driver *driver; /* which driver has allocated this
device */
- void *driver_data; /* data private to the driver */
void *platform_data; /* Platform specific data, device
core doesn't touch it */
struct dev_pm_info power;
@@ -411,7 +411,7 @@
struct klist_node knode_class;
struct class *class;
- struct attribute_group **groups; /* optional groups */
+ const struct attribute_group **groups; /* optional groups */
void (*release)(struct device *dev);
};
@@ -446,16 +446,6 @@
}
#endif
-static inline void *dev_get_drvdata(const struct device *dev)
-{
- return dev->driver_data;
-}
-
-static inline void dev_set_drvdata(struct device *dev, void *data)
-{
- dev->driver_data = data;
-}
-
static inline unsigned int dev_get_uevent_suppress(const struct device *dev)
{
return dev->kobj.uevent_suppress;
@@ -489,6 +479,8 @@
extern int device_move(struct device *dev, struct device *new_parent,
enum dpm_order dpm_order);
extern const char *device_get_nodename(struct device *dev, const char **tmp);
+extern void *dev_get_drvdata(const struct device *dev);
+extern void dev_set_drvdata(struct device *dev, void *data);
/*
* Root device objects for grouping under /sys/devices
@@ -501,6 +493,11 @@
}
extern void root_device_unregister(struct device *root);
+static inline void *dev_get_platdata(const struct device *dev)
+{
+ return dev->platform_data;
+}
+
/*
* Manual binding of a device to driver. See drivers/base/bus.c
* for information on use.
@@ -546,6 +543,16 @@
extern void wait_for_device_probe(void);
+#ifdef CONFIG_DEVTMPFS
+extern int devtmpfs_create_node(struct device *dev);
+extern int devtmpfs_delete_node(struct device *dev);
+extern int devtmpfs_mount(const char *mountpoint);
+#else
+static inline int devtmpfs_create_node(struct device *dev) { return 0; }
+static inline int devtmpfs_delete_node(struct device *dev) { return 0; }
+static inline int devtmpfs_mount(const char *mountpoint) { return 0; }
+#endif
+
/* drivers/base/power/shutdown.c */
extern void device_shutdown(void);
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/include/linux/netdevice.h linux-2.6.31-rc4-git5-driver-core/include/linux/netdevice.h
--- linux-2.6.31-rc4-git5-usb.current/include/linux/netdevice.h 2009-07-24 11:07:49.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/include/linux/netdevice.h 2009-07-31 09:56:42.000000000 -0700
@@ -889,7 +889,7 @@
/* class/net/name entry */
struct device dev;
/* space for optional statistics and wireless sysfs groups */
- struct attribute_group *sysfs_groups[3];
+ const struct attribute_group *sysfs_groups[3];
/* rtnetlink link ops */
const struct rtnl_link_ops *rtnl_link_ops;
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/include/linux/pci_regs.h linux-2.6.31-rc4-git5-driver-core/include/linux/pci_regs.h
--- linux-2.6.31-rc4-git5-usb.current/include/linux/pci_regs.h 2009-07-24 11:07:49.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/include/linux/pci_regs.h 2009-07-31 09:56:42.000000000 -0700
@@ -42,6 +42,7 @@
#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */
#define PCI_STATUS 0x06 /* 16 bits */
+#define PCI_STATUS_INTERRUPT 0x08 /* Interrupt status */
#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */
#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */
#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/include/linux/shmem_fs.h linux-2.6.31-rc4-git5-driver-core/include/linux/shmem_fs.h
--- linux-2.6.31-rc4-git5-usb.current/include/linux/shmem_fs.h 2009-07-24 11:07:49.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/include/linux/shmem_fs.h 2009-07-31 09:56:42.000000000 -0700
@@ -38,6 +38,9 @@
return container_of(inode, struct shmem_inode_info, vfs_inode);
}
+extern int init_tmpfs(void);
+extern int shmem_fill_super(struct super_block *sb, void *data, int silent);
+
#ifdef CONFIG_TMPFS_POSIX_ACL
int shmem_permission(struct inode *, int);
int shmem_acl_init(struct inode *, struct inode *);
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/include/linux/transport_class.h linux-2.6.31-rc4-git5-driver-core/include/linux/transport_class.h
--- linux-2.6.31-rc4-git5-usb.current/include/linux/transport_class.h 2008-07-18 12:16:09.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/include/linux/transport_class.h 2009-07-31 09:56:42.000000000 -0700
@@ -55,7 +55,7 @@
struct transport_container {
struct attribute_container ac;
- struct attribute_group *statistics;
+ const struct attribute_group *statistics;
};
#define attribute_container_to_transport_container(x) \
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/init/do_mounts.c linux-2.6.31-rc4-git5-driver-core/init/do_mounts.c
--- linux-2.6.31-rc4-git5-usb.current/init/do_mounts.c 2009-07-24 11:07:49.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/init/do_mounts.c 2009-07-31 09:56:42.000000000 -0700
@@ -415,7 +415,7 @@
mount_root();
out:
+ devtmpfs_mount("dev");
sys_mount(".", "/", NULL, MS_MOVE, NULL);
sys_chroot(".");
}
-
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/init/main.c linux-2.6.31-rc4-git5-driver-core/init/main.c
--- linux-2.6.31-rc4-git5-usb.current/init/main.c 2009-07-24 11:07:49.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/init/main.c 2009-07-31 09:56:42.000000000 -0700
@@ -68,6 +68,7 @@
#include
#include
#include
+#include
#include
#include
@@ -808,6 +809,7 @@
init_workqueues();
cpuset_init_smp();
usermodehelper_init();
+ init_tmpfs();
driver_init();
init_irq_proc();
do_ctors();
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/kernel/dma-coherent.c linux-2.6.31-rc4-git5-driver-core/kernel/dma-coherent.c
--- linux-2.6.31-rc4-git5-usb.current/kernel/dma-coherent.c 2009-03-24 09:44:09.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/kernel/dma-coherent.c 1969-12-31 16:00:00.000000000 -0800
@@ -1,176 +0,0 @@
-/*
- * Coherent per-device memory handling.
- * Borrowed from i386
- */
-#include
-#include
-
-struct dma_coherent_mem {
- void *virt_base;
- u32 device_base;
- int size;
- int flags;
- unsigned long *bitmap;
-};
-
-int dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
- dma_addr_t device_addr, size_t size, int flags)
-{
- void __iomem *mem_base = NULL;
- int pages = size >> PAGE_SHIFT;
- int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
-
- if ((flags & (DMA_MEMORY_MAP | DMA_MEMORY_IO)) == 0)
- goto out;
- if (!size)
- goto out;
- if (dev->dma_mem)
- goto out;
-
- /* FIXME: this routine just ignores DMA_MEMORY_INCLUDES_CHILDREN */
-
- mem_base = ioremap(bus_addr, size);
- if (!mem_base)
- goto out;
-
- dev->dma_mem = kzalloc(sizeof(struct dma_coherent_mem), GFP_KERNEL);
- if (!dev->dma_mem)
- goto out;
- dev->dma_mem->bitmap = kzalloc(bitmap_size, GFP_KERNEL);
- if (!dev->dma_mem->bitmap)
- goto free1_out;
-
- dev->dma_mem->virt_base = mem_base;
- dev->dma_mem->device_base = device_addr;
- dev->dma_mem->size = pages;
- dev->dma_mem->flags = flags;
-
- if (flags & DMA_MEMORY_MAP)
- return DMA_MEMORY_MAP;
-
- return DMA_MEMORY_IO;
-
- free1_out:
- kfree(dev->dma_mem);
- out:
- if (mem_base)
- iounmap(mem_base);
- return 0;
-}
-EXPORT_SYMBOL(dma_declare_coherent_memory);
-
-void dma_release_declared_memory(struct device *dev)
-{
- struct dma_coherent_mem *mem = dev->dma_mem;
-
- if (!mem)
- return;
- dev->dma_mem = NULL;
- iounmap(mem->virt_base);
- kfree(mem->bitmap);
- kfree(mem);
-}
-EXPORT_SYMBOL(dma_release_declared_memory);
-
-void *dma_mark_declared_memory_occupied(struct device *dev,
- dma_addr_t device_addr, size_t size)
-{
- struct dma_coherent_mem *mem = dev->dma_mem;
- int pos, err;
-
- size += device_addr & ~PAGE_MASK;
-
- if (!mem)
- return ERR_PTR(-EINVAL);
-
- pos = (device_addr - mem->device_base) >> PAGE_SHIFT;
- err = bitmap_allocate_region(mem->bitmap, pos, get_order(size));
- if (err != 0)
- return ERR_PTR(err);
- return mem->virt_base + (pos << PAGE_SHIFT);
-}
-EXPORT_SYMBOL(dma_mark_declared_memory_occupied);
-
-/**
- * dma_alloc_from_coherent() - try to allocate memory from the per-device coherent area
- *
- * @dev: device from which we allocate memory
- * @size: size of requested memory area
- * @dma_handle: This will be filled with the correct dma handle
- * @ret: This pointer will be filled with the virtual address
- * to allocated area.
- *
- * This function should be only called from per-arch dma_alloc_coherent()
- * to support allocation from per-device coherent memory pools.
- *
- * Returns 0 if dma_alloc_coherent should continue with allocating from
- * generic memory areas, or !0 if dma_alloc_coherent should return @ret.
- */
-int dma_alloc_from_coherent(struct device *dev, ssize_t size,
- dma_addr_t *dma_handle, void **ret)
-{
- struct dma_coherent_mem *mem;
- int order = get_order(size);
- int pageno;
-
- if (!dev)
- return 0;
- mem = dev->dma_mem;
- if (!mem)
- return 0;
-
- *ret = NULL;
-
- if (unlikely(size > (mem->size << PAGE_SHIFT)))
- goto err;
-
- pageno = bitmap_find_free_region(mem->bitmap, mem->size, order);
- if (unlikely(pageno < 0))
- goto err;
-
- /*
- * Memory was found in the per-device area.
- */
- *dma_handle = mem->device_base + (pageno << PAGE_SHIFT);
- *ret = mem->virt_base + (pageno << PAGE_SHIFT);
- memset(*ret, 0, size);
-
- return 1;
-
-err:
- /*
- * In the case where the allocation can not be satisfied from the
- * per-device area, try to fall back to generic memory if the
- * constraints allow it.
- */
- return mem->flags & DMA_MEMORY_EXCLUSIVE;
-}
-EXPORT_SYMBOL(dma_alloc_from_coherent);
-
-/**
- * dma_release_from_coherent() - try to free the memory allocated from per-device coherent memory pool
- * @dev: device from which the memory was allocated
- * @order: the order of pages allocated
- * @vaddr: virtual address of allocated pages
- *
- * This checks whether the memory was allocated from the per-device
- * coherent memory pool and if so, releases that memory.
- *
- * Returns 1 if we correctly released the memory, or 0 if
- * dma_release_coherent() should proceed with releasing memory from
- * generic pools.
- */
-int dma_release_from_coherent(struct device *dev, int order, void *vaddr)
-{
- struct dma_coherent_mem *mem = dev ? dev->dma_mem : NULL;
-
- if (mem && vaddr >= mem->virt_base && vaddr <
- (mem->virt_base + (mem->size << PAGE_SHIFT))) {
- int page = (vaddr - mem->virt_base) >> PAGE_SHIFT;
-
- bitmap_release_region(mem->bitmap, page, order);
- return 1;
- }
- return 0;
-}
-EXPORT_SYMBOL(dma_release_from_coherent);
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/kernel/Makefile linux-2.6.31-rc4-git5-driver-core/kernel/Makefile
--- linux-2.6.31-rc4-git5-usb.current/kernel/Makefile 2009-07-24 11:07:49.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/kernel/Makefile 2009-07-31 09:56:42.000000000 -0700
@@ -92,7 +92,6 @@
obj-$(CONFIG_MARKERS) += marker.o
obj-$(CONFIG_TRACEPOINTS) += tracepoint.o
obj-$(CONFIG_LATENCYTOP) += latencytop.o
-obj-$(CONFIG_HAVE_GENERIC_DMA_COHERENT) += dma-coherent.o
obj-$(CONFIG_FUNCTION_TRACER) += trace/
obj-$(CONFIG_TRACING) += trace/
obj-$(CONFIG_X86_DS) += trace/
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/MAINTAINERS linux-2.6.31-rc4-git5-driver-core/MAINTAINERS
--- linux-2.6.31-rc4-git5-usb.current/MAINTAINERS 2009-07-30 10:02:21.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/MAINTAINERS 2009-07-31 09:56:42.000000000 -0700
@@ -2185,6 +2185,13 @@
S: Maintained
F: include/asm-generic
+GENERIC UIO DRIVER FOR PCI DEVICES
+P: Michael S. Tsirkin
+L: kvm@vger.kernel.org
+L: linux-kernel@vger.kernel.org
+S: Supported
+F: drivers/uio/uio_pci_generic.c
+
GFS2 FILE SYSTEM
M: Steven Whitehouse
L: cluster-devel@redhat.com
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/mm/shmem.c linux-2.6.31-rc4-git5-driver-core/mm/shmem.c
--- linux-2.6.31-rc4-git5-usb.current/mm/shmem.c 2009-07-24 11:07:50.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/mm/shmem.c 2009-07-31 09:56:42.000000000 -0700
@@ -2298,8 +2298,7 @@
sb->s_fs_info = NULL;
}
-static int shmem_fill_super(struct super_block *sb,
- void *data, int silent)
+int shmem_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *inode;
struct dentry *root;
@@ -2519,7 +2518,7 @@
.kill_sb = kill_litter_super,
};
-static int __init init_tmpfs(void)
+int __init init_tmpfs(void)
{
int error;
@@ -2576,7 +2575,7 @@
.kill_sb = kill_litter_super,
};
-static int __init init_tmpfs(void)
+int __init init_tmpfs(void)
{
BUG_ON(register_filesystem(&tmpfs_fs_type) != 0);
@@ -2687,5 +2686,3 @@
vma->vm_ops = &shmem_vm_ops;
return 0;
}
-
-module_init(init_tmpfs)
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/net/bluetooth/hci_sysfs.c linux-2.6.31-rc4-git5-driver-core/net/bluetooth/hci_sysfs.c
--- linux-2.6.31-rc4-git5-usb.current/net/bluetooth/hci_sysfs.c 2009-06-15 12:15:54.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/net/bluetooth/hci_sysfs.c 2009-07-31 09:56:42.000000000 -0700
@@ -68,7 +68,7 @@
.attrs = bt_link_attrs,
};
-static struct attribute_group *bt_link_groups[] = {
+static const struct attribute_group *bt_link_groups[] = {
&bt_link_group,
NULL
};
@@ -392,7 +392,7 @@
.attrs = bt_host_attrs,
};
-static struct attribute_group *bt_host_groups[] = {
+static const struct attribute_group *bt_host_groups[] = {
&bt_host_group,
NULL
};
diff -Naur -X linux-2.6.31-rc4-git5-usb.current/Documentation/dontdiff linux-2.6.31-rc4-git5-usb.current/net/core/net-sysfs.c linux-2.6.31-rc4-git5-driver-core/net/core/net-sysfs.c
--- linux-2.6.31-rc4-git5-usb.current/net/core/net-sysfs.c 2009-07-24 11:07:50.000000000 -0700
+++ linux-2.6.31-rc4-git5-driver-core/net/core/net-sysfs.c 2009-07-31 09:56:42.000000000 -0700
@@ -493,7 +493,7 @@
int netdev_register_kobject(struct net_device *net)
{
struct device *dev = &(net->dev);
- struct attribute_group **groups = net->sysfs_groups;
+ const struct attribute_group **groups = net->sysfs_groups;
dev->class = &net_class;
dev->platform_data = net;