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;