summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 21:40:26 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2008-10-16 21:40:26 +0200
commitc813b4e16ead3c3df98ac84419d4df2adf33fe01 (patch)
tree2ca4a5b6966d833b6149e3dda7a4e85d1255779c
parentMerge git://git.kernel.org/pub/scm/linux/kernel/git/rusty/linux-2.6-for-linus (diff)
parentUIO: Fix mapping of logical and virtual memory (diff)
downloadlinux-c813b4e16ead3c3df98ac84419d4df2adf33fe01.tar.xz
linux-c813b4e16ead3c3df98ac84419d4df2adf33fe01.zip
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (46 commits) UIO: Fix mapping of logical and virtual memory UIO: add automata sercos3 pci card support UIO: Change driver name of uio_pdrv UIO: Add alignment warnings for uio-mem Driver core: add bus_sort_breadthfirst() function NET: convert the phy_device file to use bus_find_device_by_name kobject: Cleanup kobject_rename and !CONFIG_SYSFS kobject: Fix kobject_rename and !CONFIG_SYSFS sysfs: Make dir and name args to sysfs_notify() const platform: add new device registration helper sysfs: use ilookup5() instead of ilookup5_nowait() PNP: create device attributes via default device attributes Driver core: make bus_find_device_by_name() more robust usb: turn dev_warn+WARN_ON combos into dev_WARN debug: use dev_WARN() rather than WARN_ON() in device_pm_add() debug: Introduce a dev_WARN() function sysfs: fix deadlock device model: Do a quickcheck for driver binding before doing an expensive check Driver core: Fix cleanup in device_create_vargs(). Driver core: Clarify device cleanup. ...
-rw-r--r--Documentation/kernel-parameters.txt5
-rw-r--r--Documentation/kobject.txt4
-rw-r--r--arch/mips/kernel/rtlx.c4
-rw-r--r--arch/mips/sibyte/common/sb_tbprof.c3
-rw-r--r--arch/x86/kernel/cpuid.c4
-rw-r--r--arch/x86/kernel/dumpstack_32.c2
-rw-r--r--arch/x86/kernel/dumpstack_64.c2
-rw-r--r--arch/x86/kernel/msr.c4
-rw-r--r--block/bsg.c3
-rw-r--r--drivers/base/bus.c54
-rw-r--r--drivers/base/core.c30
-rw-r--r--drivers/base/dd.c3
-rw-r--r--drivers/base/platform.c49
-rw-r--r--drivers/base/power/main.c2
-rw-r--r--drivers/block/aoe/aoechr.c6
-rw-r--r--drivers/block/paride/pg.c5
-rw-r--r--drivers/block/paride/pt.c10
-rw-r--r--drivers/block/pktcdvd.c5
-rw-r--r--drivers/char/bsr.c5
-rw-r--r--drivers/char/dsp56k.c4
-rw-r--r--drivers/char/ip2/ip2main.c12
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c2
-rw-r--r--drivers/char/istallion.c5
-rw-r--r--drivers/char/lp.c4
-rw-r--r--drivers/char/mem.c6
-rw-r--r--drivers/char/misc.c4
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c2
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c3
-rw-r--r--drivers/char/ppdev.c5
-rw-r--r--drivers/char/raw.c7
-rw-r--r--drivers/char/snsc.c4
-rw-r--r--drivers/char/stallion.c4
-rw-r--r--drivers/char/tty_io.c2
-rw-r--r--drivers/char/vc_screen.c12
-rw-r--r--drivers/char/viotape.c8
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c3
-rw-r--r--drivers/dca/dca-sysfs.c8
-rw-r--r--drivers/firmware/iscsi_ibft.c18
-rw-r--r--drivers/hid/hidraw.c5
-rw-r--r--drivers/hwmon/hwmon.c4
-rw-r--r--drivers/i2c/i2c-dev.c6
-rw-r--r--drivers/ide/ide-probe.c4
-rw-r--r--drivers/ide/ide-tape.c11
-rw-r--r--drivers/ieee1394/dv1394.c8
-rw-r--r--drivers/ieee1394/raw1394.c8
-rw-r--r--drivers/ieee1394/video1394.c5
-rw-r--r--drivers/infiniband/core/cm.c6
-rw-r--r--drivers/infiniband/core/user_mad.c12
-rw-r--r--drivers/infiniband/core/uverbs_main.c9
-rw-r--r--drivers/infiniband/hw/ipath/ipath_file_ops.c2
-rw-r--r--drivers/isdn/capi/capi.c3
-rw-r--r--drivers/leds/led-class.c4
-rw-r--r--drivers/macintosh/adb.c3
-rw-r--r--drivers/media/dvb/dvb-core/dvbdev.c2
-rw-r--r--drivers/misc/phantom.c6
-rw-r--r--drivers/mtd/mtdchar.c10
-rw-r--r--drivers/net/phy/phy_device.c8
-rw-r--r--drivers/net/ppp_generic.c4
-rw-r--r--drivers/net/wan/cosa.c4
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c6
-rw-r--r--drivers/pci/probe.c50
-rw-r--r--drivers/pnp/base.h2
-rw-r--r--drivers/pnp/core.c10
-rw-r--r--drivers/pnp/driver.c1
-rw-r--r--drivers/pnp/interface.c37
-rw-r--r--drivers/power/power_supply_core.c4
-rw-r--r--drivers/s390/char/raw3270.c14
-rw-r--r--drivers/s390/char/tape_class.c6
-rw-r--r--drivers/s390/char/vmlogrdr.c8
-rw-r--r--drivers/s390/char/vmur.c5
-rw-r--r--drivers/scsi/ch.c6
-rw-r--r--drivers/scsi/dpt_i2o.c2
-rw-r--r--drivers/scsi/osst.c3
-rw-r--r--drivers/scsi/sg.c10
-rw-r--r--drivers/scsi/st.c11
-rw-r--r--drivers/spi/spidev.c7
-rw-r--r--drivers/uio/Kconfig13
-rw-r--r--drivers/uio/Makefile1
-rw-r--r--drivers/uio/uio.c26
-rw-r--r--drivers/uio/uio_pdrv.c2
-rw-r--r--drivers/uio/uio_sercos3.c243
-rw-r--r--drivers/usb/core/devio.c6
-rw-r--r--drivers/usb/core/file.c6
-rw-r--r--drivers/usb/core/hcd.c5
-rw-r--r--drivers/usb/gadget/Makefile23
-rw-r--r--drivers/usb/gadget/cdc2.c25
-rw-r--r--drivers/usb/gadget/ether.c28
-rw-r--r--drivers/usb/gadget/f_ecm.c108
-rw-r--r--drivers/usb/gadget/f_loopback.c34
-rw-r--r--drivers/usb/gadget/f_subset.c44
-rw-r--r--drivers/usb/gadget/file_storage.c12
-rw-r--r--drivers/usb/gadget/gmidi.c15
-rw-r--r--drivers/usb/gadget/printer.c18
-rw-r--r--drivers/usb/gadget/rndis.c115
-rw-r--r--drivers/usb/gadget/serial.c18
-rw-r--r--drivers/usb/gadget/u_ether.c4
-rw-r--r--drivers/usb/gadget/zero.c17
-rw-r--r--drivers/usb/host/uhci-q.c24
-rw-r--r--drivers/usb/misc/phidgetkit.c5
-rw-r--r--drivers/usb/misc/phidgetmotorcontrol.c5
-rw-r--r--drivers/usb/misc/phidgetservo.c5
-rw-r--r--drivers/usb/mon/mon_bin.c6
-rw-r--r--drivers/video/console/fbcon.c4
-rw-r--r--drivers/video/display/display-sysfs.c9
-rw-r--r--drivers/video/fbmem.c5
-rw-r--r--fs/coda/psdev.c5
-rw-r--r--fs/sysfs/bin.c42
-rw-r--r--fs/sysfs/dir.c24
-rw-r--r--fs/sysfs/file.c46
-rw-r--r--fs/sysfs/mount.c15
-rw-r--r--fs/sysfs/sysfs.h6
-rw-r--r--include/asm-generic/vmlinux.lds.h10
-rw-r--r--include/linux/device.h18
-rw-r--r--include/linux/dynamic_printk.h93
-rw-r--r--include/linux/kernel.h7
-rw-r--r--include/linux/module.h1
-rw-r--r--include/linux/platform_device.h2
-rw-r--r--include/linux/sysfs.h36
-rw-r--r--kernel/module.c33
-rw-r--r--lib/Kconfig.debug55
-rw-r--r--lib/Makefile2
-rw-r--r--lib/dynamic_printk.c418
-rw-r--r--lib/kobject.c35
-rw-r--r--net/netfilter/nf_conntrack_pptp.c2
-rw-r--r--scripts/Makefile.lib11
-rw-r--r--scripts/basic/Makefile2
-rw-r--r--scripts/basic/hash.c64
-rw-r--r--sound/core/init.c6
-rw-r--r--sound/core/sound.c5
-rw-r--r--sound/oss/soundcard.c15
-rw-r--r--sound/sound_core.c5
131 files changed, 1786 insertions, 617 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 82c561f3abbd..dd28a0d56981 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1714,6 +1714,11 @@ and is between 256 and 4096 characters. It is defined in the file
autoconfiguration.
Ranges are in pairs (memory base and size).
+ dynamic_printk
+ Enables pr_debug()/dev_dbg() calls if
+ CONFIG_DYNAMIC_PRINTK_DEBUG has been enabled. These can also
+ be switched on/off via <debugfs>/dynamic_printk/modules
+
print-fatal-signals=
[KNL] debug: print fatal signals
print-fatal-signals=1: print segfault info to
diff --git a/Documentation/kobject.txt b/Documentation/kobject.txt
index 51a8021ee532..f5d2aad65a67 100644
--- a/Documentation/kobject.txt
+++ b/Documentation/kobject.txt
@@ -118,6 +118,10 @@ the name of the kobject, call kobject_rename():
int kobject_rename(struct kobject *kobj, const char *new_name);
+Note kobject_rename does perform any locking or have a solid notion of
+what names are valid so the provide must provide their own sanity checking
+and serialization.
+
There is a function called kobject_set_name() but that is legacy cruft and
is being removed. If your code needs to call this function, it is
incorrect and needs to be fixed.
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c
index dfd868b68364..4ce93aa7b372 100644
--- a/arch/mips/kernel/rtlx.c
+++ b/arch/mips/kernel/rtlx.c
@@ -522,8 +522,8 @@ static int __init rtlx_module_init(void)
atomic_set(&channel_wqs[i].in_open, 0);
mutex_init(&channel_wqs[i].mutex);
- dev = device_create_drvdata(mt_class, NULL, MKDEV(major, i),
- NULL, "%s%d", module_name, i);
+ dev = device_create(mt_class, NULL, MKDEV(major, i), NULL,
+ "%s%d", module_name, i);
if (IS_ERR(dev)) {
err = PTR_ERR(dev);
goto out_chrdev;
diff --git a/arch/mips/sibyte/common/sb_tbprof.c b/arch/mips/sibyte/common/sb_tbprof.c
index 66e3e3fb311f..637a194e5cd5 100644
--- a/arch/mips/sibyte/common/sb_tbprof.c
+++ b/arch/mips/sibyte/common/sb_tbprof.c
@@ -576,8 +576,7 @@ static int __init sbprof_tb_init(void)
tb_class = tbc;
- dev = device_create_drvdata(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0),
- NULL, "tb");
+ dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), NULL, "tb");
if (IS_ERR(dev)) {
err = PTR_ERR(dev);
goto out_class;
diff --git a/arch/x86/kernel/cpuid.c b/arch/x86/kernel/cpuid.c
index 6a44d6465991..72cefd1e649b 100644
--- a/arch/x86/kernel/cpuid.c
+++ b/arch/x86/kernel/cpuid.c
@@ -147,8 +147,8 @@ static __cpuinit int cpuid_device_create(int cpu)
{
struct device *dev;
- dev = device_create_drvdata(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
- NULL, "cpu%d", cpu);
+ dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu), NULL,
+ "cpu%d", cpu);
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
diff --git a/arch/x86/kernel/dumpstack_32.c b/arch/x86/kernel/dumpstack_32.c
index 201ee359a1a9..1a78180f08d3 100644
--- a/arch/x86/kernel/dumpstack_32.c
+++ b/arch/x86/kernel/dumpstack_32.c
@@ -13,6 +13,7 @@
#include <linux/kexec.h>
#include <linux/bug.h>
#include <linux/nmi.h>
+#include <linux/sysfs.h>
#include <asm/stacktrace.h>
@@ -343,6 +344,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
printk("DEBUG_PAGEALLOC");
#endif
printk("\n");
+ sysfs_printk_last_file();
if (notify_die(DIE_OOPS, str, regs, err,
current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
return 1;
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index 086cc8118e39..96a5db7da8a7 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -13,6 +13,7 @@
#include <linux/kexec.h>
#include <linux/bug.h>
#include <linux/nmi.h>
+#include <linux/sysfs.h>
#include <asm/stacktrace.h>
@@ -489,6 +490,7 @@ int __kprobes __die(const char *str, struct pt_regs *regs, long err)
printk("DEBUG_PAGEALLOC");
#endif
printk("\n");
+ sysfs_printk_last_file();
if (notify_die(DIE_OOPS, str, regs, err,
current->thread.trap_no, SIGSEGV) == NOTIFY_STOP)
return 1;
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 2e2af5d18191..82a7c7ed6d45 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -163,8 +163,8 @@ static int __cpuinit msr_device_create(int cpu)
{
struct device *dev;
- dev = device_create_drvdata(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
- NULL, "msr%d", cpu);
+ dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu), NULL,
+ "msr%d", cpu);
return IS_ERR(dev) ? PTR_ERR(dev) : 0;
}
diff --git a/block/bsg.c b/block/bsg.c
index 56cb343c76d8..034112bfe1f3 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -1024,8 +1024,7 @@ int bsg_register_queue(struct request_queue *q, struct device *parent,
bcd->release = release;
kref_init(&bcd->ref);
dev = MKDEV(bsg_major, bcd->minor);
- class_dev = device_create_drvdata(bsg_class, parent, dev, NULL,
- "%s", devname);
+ class_dev = device_create(bsg_class, parent, dev, NULL, "%s", devname);
if (IS_ERR(class_dev)) {
ret = PTR_ERR(class_dev);
goto put_dev;
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index ef522ae55480..5aee1c0169ea 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -333,9 +333,7 @@ static int match_name(struct device *dev, void *data)
{
const char *name = data;
- if (strcmp(name, dev->bus_id) == 0)
- return 1;
- return 0;
+ return sysfs_streq(name, dev->bus_id);
}
/**
@@ -982,6 +980,56 @@ struct klist *bus_get_device_klist(struct bus_type *bus)
}
EXPORT_SYMBOL_GPL(bus_get_device_klist);
+/*
+ * Yes, this forcably breaks the klist abstraction temporarily. It
+ * just wants to sort the klist, not change reference counts and
+ * take/drop locks rapidly in the process. It does all this while
+ * holding the lock for the list, so objects can't otherwise be
+ * added/removed while we're swizzling.
+ */
+static void device_insertion_sort_klist(struct device *a, struct list_head *list,
+ int (*compare)(const struct device *a,
+ const struct device *b))
+{
+ struct list_head *pos;
+ struct klist_node *n;
+ struct device *b;
+
+ list_for_each(pos, list) {
+ n = container_of(pos, struct klist_node, n_node);
+ b = container_of(n, struct device, knode_bus);
+ if (compare(a, b) <= 0) {
+ list_move_tail(&a->knode_bus.n_node,
+ &b->knode_bus.n_node);
+ return;
+ }
+ }
+ list_move_tail(&a->knode_bus.n_node, list);
+}
+
+void bus_sort_breadthfirst(struct bus_type *bus,
+ int (*compare)(const struct device *a,
+ const struct device *b))
+{
+ LIST_HEAD(sorted_devices);
+ struct list_head *pos, *tmp;
+ struct klist_node *n;
+ struct device *dev;
+ struct klist *device_klist;
+
+ device_klist = bus_get_device_klist(bus);
+
+ spin_lock(&device_klist->k_lock);
+ list_for_each_safe(pos, tmp, &device_klist->k_list) {
+ n = container_of(pos, struct klist_node, n_node);
+ dev = container_of(n, struct device, knode_bus);
+ device_insertion_sort_klist(dev, &sorted_devices, compare);
+ }
+ list_splice(&sorted_devices, &device_klist->k_list);
+ spin_unlock(&device_klist->k_lock);
+}
+EXPORT_SYMBOL_GPL(bus_sort_breadthfirst);
+
int __init buses_init(void)
{
bus_kset = kset_create_and_add("bus", &bus_uevent_ops, NULL);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index b98cb1416a2d..8c2cc2648f5a 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -523,11 +523,16 @@ static void klist_children_put(struct klist_node *n)
* device_initialize - init device structure.
* @dev: device.
*
- * This prepares the device for use by other layers,
- * including adding it to the device hierarchy.
+ * This prepares the device for use by other layers by initializing
+ * its fields.
* It is the first half of device_register(), if called by
- * that, though it can also be called separately, so one
- * may use @dev's fields (e.g. the refcount).
+ * that function, though it can also be called separately, so one
+ * may use @dev's fields. In particular, get_device()/put_device()
+ * may be used for reference counting of @dev after calling this
+ * function.
+ *
+ * NOTE: Use put_device() to give up your reference instead of freeing
+ * @dev directly once you have called this function.
*/
void device_initialize(struct device *dev)
{
@@ -835,9 +840,13 @@ static void device_remove_sys_dev_entry(struct device *dev)
* This is part 2 of device_register(), though may be called
* separately _iff_ device_initialize() has been called separately.
*
- * This adds it to the kobject hierarchy via kobject_add(), adds it
+ * This adds @dev to the kobject hierarchy via kobject_add(), adds it
* to the global and sibling lists for the device, then
* adds it to the other relevant subsystems of the driver model.
+ *
+ * NOTE: _Never_ directly free @dev after calling this function, even
+ * if it returned an error! Always use put_device() to give up your
+ * reference instead.
*/
int device_add(struct device *dev)
{
@@ -965,6 +974,10 @@ done:
* I.e. you should only call the two helpers separately if
* have a clearly defined need to use and refcount the device
* before it is added to the hierarchy.
+ *
+ * NOTE: _Never_ directly free @dev after calling this function, even
+ * if it returned an error! Always use put_device() to give up the
+ * reference initialized in this function instead.
*/
int device_register(struct device *dev)
{
@@ -1243,7 +1256,7 @@ struct device *device_create_vargs(struct class *class, struct device *parent,
return dev;
error:
- kfree(dev);
+ put_device(dev);
return ERR_PTR(retval);
}
EXPORT_SYMBOL_GPL(device_create_vargs);
@@ -1314,6 +1327,11 @@ EXPORT_SYMBOL_GPL(device_destroy);
* device_rename - renames a device
* @dev: the pointer to the struct device to be renamed
* @new_name: the new name of the device
+ *
+ * It is the responsibility of the caller to provide mutual
+ * exclusion between two different calls of device_rename
+ * on the same device to ensure that new_name is valid and
+ * won't conflict with other devices.
*/
int device_rename(struct device *dev, char *new_name)
{
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 3ac443b2ac08..20febc00a525 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -257,6 +257,9 @@ static int __driver_attach(struct device *dev, void *data)
* is an error.
*/
+ if (drv->bus->match && !drv->bus->match(dev, drv))
+ return 0;
+
if (dev->parent) /* Needed for USB */
down(&dev->parent->sem);
down(&dev->sem);
diff --git a/drivers/base/platform.c b/drivers/base/platform.c
index 66b710c28812..dfcbfe504867 100644
--- a/drivers/base/platform.c
+++ b/drivers/base/platform.c
@@ -394,6 +394,53 @@ error:
}
EXPORT_SYMBOL_GPL(platform_device_register_simple);
+/**
+ * platform_device_register_data
+ * @parent: parent device for the device we're adding
+ * @name: base name of the device we're adding
+ * @id: instance id
+ * @data: platform specific data for this platform device
+ * @size: size of platform specific data
+ *
+ * This function creates a simple platform device that requires minimal
+ * resource and memory management. Canned release function freeing memory
+ * allocated for the device allows drivers using such devices to be
+ * unloaded without waiting for the last reference to the device to be
+ * dropped.
+ */
+struct platform_device *platform_device_register_data(
+ struct device *parent,
+ const char *name, int id,
+ const void *data, size_t size)
+{
+ struct platform_device *pdev;
+ int retval;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev) {
+ retval = -ENOMEM;
+ goto error;
+ }
+
+ pdev->dev.parent = parent;
+
+ if (size) {
+ retval = platform_device_add_data(pdev, data, size);
+ if (retval)
+ goto error;
+ }
+
+ retval = platform_device_add(pdev);
+ if (retval)
+ goto error;
+
+ return pdev;
+
+error:
+ platform_device_put(pdev);
+ return ERR_PTR(retval);
+}
+
static int platform_drv_probe(struct device *_dev)
{
struct platform_driver *drv = to_platform_driver(_dev->driver);
@@ -865,7 +912,7 @@ static int platform_pm_restore_noirq(struct device *dev)
#endif /* !CONFIG_HIBERNATION */
-struct pm_ext_ops platform_pm_ops = {
+static struct pm_ext_ops platform_pm_ops = {
.base = {
.prepare = platform_pm_prepare,
.complete = platform_pm_complete,
diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 03bde7524bc3..692c20ba5144 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -83,7 +83,7 @@ void device_pm_add(struct device *dev)
* transition is in progress in order to avoid leaving them
* unhandled down the road
*/
- WARN_ON(true);
+ dev_WARN(dev, "Parentless device registered during a PM transaction\n");
}
list_add_tail(&dev->power.entry, &dpm_list);
diff --git a/drivers/block/aoe/aoechr.c b/drivers/block/aoe/aoechr.c
index 1f56d2c5b7fc..200efc4d2c1e 100644
--- a/drivers/block/aoe/aoechr.c
+++ b/drivers/block/aoe/aoechr.c
@@ -284,9 +284,9 @@ aoechr_init(void)
return PTR_ERR(aoe_class);
}
for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
- device_create_drvdata(aoe_class, NULL,
- MKDEV(AOE_MAJOR, chardevs[i].minor),
- NULL, chardevs[i].name);
+ device_create(aoe_class, NULL,
+ MKDEV(AOE_MAJOR, chardevs[i].minor), NULL,
+ chardevs[i].name);
return 0;
}
diff --git a/drivers/block/paride/pg.c b/drivers/block/paride/pg.c
index d731ca42f802..9dfa27163001 100644
--- a/drivers/block/paride/pg.c
+++ b/drivers/block/paride/pg.c
@@ -686,9 +686,8 @@ static int __init pg_init(void)
for (unit = 0; unit < PG_UNITS; unit++) {
struct pg *dev = &devices[unit];
if (dev->present)
- device_create_drvdata(pg_class, NULL,
- MKDEV(major, unit), NULL,
- "pg%u", unit);
+ device_create(pg_class, NULL, MKDEV(major, unit), NULL,
+ "pg%u", unit);
}
err = 0;
goto out;
diff --git a/drivers/block/paride/pt.c b/drivers/block/paride/pt.c
index 673b8b2fd337..5ae229656eaa 100644
--- a/drivers/block/paride/pt.c
+++ b/drivers/block/paride/pt.c
@@ -979,12 +979,10 @@ static int __init pt_init(void)
for (unit = 0; unit < PT_UNITS; unit++)
if (pt[unit].present) {
- device_create_drvdata(pt_class, NULL,
- MKDEV(major, unit), NULL,
- "pt%d", unit);
- device_create_drvdata(pt_class, NULL,
- MKDEV(major, unit + 128), NULL,
- "pt%dn", unit);
+ device_create(pt_class, NULL, MKDEV(major, unit), NULL,
+ "pt%d", unit);
+ device_create(pt_class, NULL, MKDEV(major, unit + 128),
+ NULL, "pt%dn", unit);
}
goto out;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 0e077150568b..195ca7c720f5 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -302,9 +302,8 @@ static struct kobj_type kobj_pkt_type_wqueue = {
static void pkt_sysfs_dev_new(struct pktcdvd_device *pd)
{
if (class_pktcdvd) {
- pd->dev = device_create_drvdata(class_pktcdvd, NULL,
- pd->pkt_dev, NULL,
- "%s", pd->name);
+ pd->dev = device_create(class_pktcdvd, NULL, pd->pkt_dev, NULL,
+ "%s", pd->name);
if (IS_ERR(pd->dev))
pd->dev = NULL;
}
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
index b650b4e48e50..456f54db73e2 100644
--- a/drivers/char/bsr.c
+++ b/drivers/char/bsr.c
@@ -229,9 +229,8 @@ static int bsr_create_devs(struct device_node *bn)
if (result)
goto out_err;
- cur->bsr_device = device_create_drvdata(bsr_class, NULL,
- cur->bsr_dev,
- cur, cur->bsr_name);
+ cur->bsr_device = device_create(bsr_class, NULL, cur->bsr_dev,
+ cur, cur->bsr_name);
if (!cur->bsr_device) {
printk(KERN_ERR "device_create failed for %s\n",
cur->bsr_name);
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index ca7c72a486b2..85832ab924e6 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -508,8 +508,8 @@ static int __init dsp56k_init_driver(void)
err = PTR_ERR(dsp56k_class);
goto out_chrdev;
}
- device_create_drvdata(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0),
- NULL, "dsp56k");
+ device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), NULL,
+ "dsp56k");
printk(banner);
goto out;
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 6774572d3759..70e0ebc30bd0 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -745,12 +745,12 @@ static int __init ip2_loadmain(void)
pB = i2BoardPtrTable[i];
if (pB != NULL) {
- device_create_drvdata(ip2_class, NULL,
- MKDEV(IP2_IPL_MAJOR, 4 * i),
- NULL, "ipl%d", i);
- device_create_drvdata(ip2_class, NULL,
- MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
- NULL, "stat%d", i);
+ device_create(ip2_class, NULL,
+ MKDEV(IP2_IPL_MAJOR, 4 * i),
+ NULL, "ipl%d", i);
+ device_create(ip2_class, NULL,
+ MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
+ NULL, "stat%d", i);
for (box = 0; box < ABS_MAX_BOXES; box++)
for (j = 0; j < ABS_BIGGEST_BOX; j++)
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 64e1c169e826..835a33c8d5f5 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -871,7 +871,7 @@ static void ipmi_new_smi(int if_num, struct device *device)
entry->dev = dev;
mutex_lock(&reg_list_mutex);
- device_create_drvdata(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
+ device_create(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
list_add(&entry->link, &reg_list);
mutex_unlock(&reg_list_mutex);
}
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 505d7a1f6b8c..44e5d60f517e 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -4600,9 +4600,8 @@ static int __init istallion_module_init(void)
istallion_class = class_create(THIS_MODULE, "staliomem");
for (i = 0; i < 4; i++)
- device_create_drvdata(istallion_class, NULL,
- MKDEV(STL_SIOMEMMAJOR, i),
- NULL, "staliomem%d", i);
+ device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
+ NULL, "staliomem%d", i);
return 0;
err_deinit:
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 3f2719b9f77b..e444c2dba160 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -813,8 +813,8 @@ static int lp_register(int nr, struct parport *port)
if (reset)
lp_reset(nr);
- device_create_drvdata(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL,
- "lp%d", nr);
+ device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), NULL,
+ "lp%d", nr);
printk(KERN_INFO "lp%d: using %s (%s).\n", nr, port->name,
(port->irq == PARPORT_IRQ_NONE)?"polling":"interrupt-driven");
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 672b08e694d0..6431f6921a67 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -992,9 +992,9 @@ static int __init chr_dev_init(void)
mem_class = class_create(THIS_MODULE, "mem");
for (i = 0; i < ARRAY_SIZE(devlist); i++)
- device_create_drvdata(mem_class, NULL,
- MKDEV(MEM_MAJOR, devlist[i].minor),
- NULL, devlist[i].name);
+ device_create(mem_class, NULL,
+ MKDEV(MEM_MAJOR, devlist[i].minor), NULL,
+ devlist[i].name);
return 0;
}
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index 999aa779c08a..a5e0db9d7662 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -217,8 +217,8 @@ int misc_register(struct miscdevice * misc)
misc_minors[misc->minor >> 3] |= 1 << (misc->minor & 7);
dev = MKDEV(MISC_MAJOR, misc->minor);
- misc->this_device = device_create_drvdata(misc_class, misc->parent,
- dev, NULL, "%s", misc->name);
+ misc->this_device = device_create(misc_class, misc->parent, dev, NULL,
+ "%s", misc->name);
if (IS_ERR(misc->this_device)) {
err = PTR_ERR(misc->this_device);
goto out;
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 1c5bf99895ed..dbb912574569 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1871,7 +1871,7 @@ static int cm4000_probe(struct pcmcia_device *link)
return ret;
}
- device_create_drvdata(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i);
+ device_create(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i);
return 0;
}
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 2d7c906435b7..4f0723b07974 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -637,8 +637,7 @@ static int reader_probe(struct pcmcia_device *link)
return ret;
}
- device_create_drvdata(cmx_class, NULL, MKDEV(major, i), NULL,
- "cmx%d", i);
+ device_create(cmx_class, NULL, MKDEV(major, i), NULL, "cmx%d", i);
return 0;
}
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index bee39fdfba73..c84c34fb1231 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -760,9 +760,8 @@ static const struct file_operations pp_fops = {
static void pp_attach(struct parport *port)
{
- device_create_drvdata(ppdev_class, port->dev,
- MKDEV(PP_MAJOR, port->number),
- NULL, "parport%d", port->number);
+ device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number),
+ NULL, "parport%d", port->number);
}
static void pp_detach(struct parport *port)
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index 47b8cf281d4a..e139372d0e69 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -131,8 +131,8 @@ raw_ioctl(struct inode *inode, struct file *filp,
static void bind_device(struct raw_config_request *rq)
{
device_destroy(raw_class, MKDEV(RAW_MAJOR, rq->raw_minor));
- device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
- NULL, "raw%d", rq->raw_minor);
+ device_create(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor), NULL,
+ "raw%d", rq->raw_minor);
}
/*
@@ -283,8 +283,7 @@ static int __init raw_init(void)
ret = PTR_ERR(raw_class);
goto error_region;
}
- device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL,
- "rawctl");
+ device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL, "rawctl");
return 0;
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 3ce60df14c0a..32b74de18f5f 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -444,8 +444,8 @@ scdrv_init(void)
continue;
}
- device_create_drvdata(snsc_class, NULL, dev, NULL,
- "%s", devname);
+ device_create(snsc_class, NULL, dev, NULL,
+ "%s", devname);
ia64_sn_irtr_intr_enable(scd->scd_nasid,
0 /*ignored */ ,
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index 8b8f07a7f505..963b03fb29e5 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -4743,8 +4743,8 @@ static int __init stallion_module_init(void)
if (IS_ERR(stallion_class))
printk("STALLION: failed to create class\n");
for (i = 0; i < 4; i++)
- device_create_drvdata(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
- NULL, "staliomem%d", i);
+ device_create(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
+ NULL, "staliomem%d", i);
return 0;
err_unrtty:
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index 3f48d88cffc0..59f472143f08 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -2850,7 +2850,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index,
else
tty_line_name(driver, index, name);
- return device_create_drvdata(tty_class, device, dev, NULL, name);
+ return device_create(tty_class, device, dev, NULL, name);
}
EXPORT_SYMBOL(tty_register_device);
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index c2ae52dd53d1..4f3b3f95fc42 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -481,10 +481,10 @@ static struct class *vc_class;
void vcs_make_sysfs(struct tty_struct *tty)
{
- device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
- NULL, "vcs%u", tty->index + 1);
- device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
- NULL, "vcsa%u", tty->index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1), NULL,
+ "vcs%u", tty->index + 1);
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129), NULL,
+ "vcsa%u", tty->index + 1);
}
void vcs_remove_sysfs(struct tty_struct *tty)
@@ -499,7 +499,7 @@ int __init vcs_init(void)
panic("unable to get major %d for vcs device", VCS_MAJOR);
vc_class = class_create(THIS_MODULE, "vc");
- device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
- device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+ device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
return 0;
}
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 7a70a40ad639..ffc9254f7e02 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -886,10 +886,10 @@ static int viotape_probe(struct vio_dev *vdev, const struct vio_device_id *id)
state[i].cur_part = 0;
for (j = 0; j < MAX_PARTITIONS; ++j)
state[i].part_stat_rwi[j] = VIOT_IDLE;
- device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i),
- NULL, "iseries!vt%d", i);
- device_create_drvdata(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
- NULL, "iseries!nvt%d", i);
+ device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i), NULL,
+ "iseries!vt%d", i);
+ device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80), NULL,
+ "iseries!nvt%d", i);
printk(VIOTAPE_KERN_INFO "tape iseries/vt%d is iSeries "
"resource %10.10s type %4.4s, model %3.3s\n",
i, viotape_unitinfo[i].rsrcname,
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 278c9857bcf5..ed132fe55d3d 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -657,8 +657,7 @@ static int __devinit hwicap_setup(struct device *dev, int id,
goto failed3;
}
- device_create_drvdata(icap_class, dev, devt, NULL,
- "%s%d", DRIVER_NAME, id);
+ device_create(icap_class, dev, devt, NULL, "%s%d", DRIVER_NAME, id);
return 0; /* success */
failed3:
diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
index 7af4b403bd2d..bb538b9690e0 100644
--- a/drivers/dca/dca-sysfs.c
+++ b/drivers/dca/dca-sysfs.c
@@ -15,9 +15,8 @@ int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
struct device *cd;
static int req_count;
- cd = device_create_drvdata(dca_class, dca->cd,
- MKDEV(0, slot + 1), NULL,
- "requester%d", req_count++);
+ cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1), NULL,
+ "requester%d", req_count++);
if (IS_ERR(cd))
return PTR_ERR(cd);
return 0;
@@ -48,8 +47,7 @@ idr_try_again:
return err;
}
- cd = device_create_drvdata(dca_class, dev, MKDEV(0, 0), NULL,
- "dca%d", dca->id);
+ cd = device_create(dca_class, dev, MKDEV(0, 0), NULL, "dca%d", dca->id);
if (IS_ERR(cd)) {
spin_lock(&dca_idr_lock);
idr_remove(&dca_idr, dca->id);
diff --git a/drivers/firmware/iscsi_ibft.c b/drivers/firmware/iscsi_ibft.c
index b91ef63126ed..deb154aa47c4 100644
--- a/drivers/firmware/iscsi_ibft.c
+++ b/drivers/firmware/iscsi_ibft.c
@@ -334,9 +334,9 @@ static void ibft_release(struct kobject *kobj)
/*
* Routines for parsing the iBFT data to be human readable.
*/
-ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
- struct ibft_attribute *attr,
- char *buf)
+static ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
+ struct ibft_attribute *attr,
+ char *buf)
{
struct ibft_initiator *initiator = entry->initiator;
void *ibft_loc = entry->header;
@@ -376,9 +376,9 @@ ssize_t ibft_attr_show_initiator(struct ibft_kobject *entry,
return str - buf;
}
-ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
- struct ibft_attribute *attr,
- char *buf)
+static ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
+ struct ibft_attribute *attr,
+ char *buf)
{
struct ibft_nic *nic = entry->nic;
void *ibft_loc = entry->header;
@@ -440,9 +440,9 @@ ssize_t ibft_attr_show_nic(struct ibft_kobject *entry,
return str - buf;
};
-ssize_t ibft_attr_show_target(struct ibft_kobject *entry,
- struct ibft_attribute *attr,
- char *buf)
+static ssize_t ibft_attr_show_target(struct ibft_kobject *entry,
+ struct ibft_attribute *attr,
+ char *buf)
{
struct ibft_tgt *tgt = entry->tgt;
void *ibft_loc = entry->header;
diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c
index 497e0d1dd3c3..af3edb98df43 100644
--- a/drivers/hid/hidraw.c
+++ b/drivers/hid/hidraw.c
@@ -326,9 +326,8 @@ int hidraw_connect(struct hid_device *hid)
goto out;
}
- dev->dev = device_create_drvdata(hidraw_class, NULL,
- MKDEV(hidraw_major, minor), NULL,
- "%s%d", "hidraw", minor);
+ dev->dev = device_create(hidraw_class, NULL, MKDEV(hidraw_major, minor),
+ NULL, "%s%d", "hidraw", minor);
if (IS_ERR(dev->dev)) {
spin_lock(&minors_lock);
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 7321a88a5112..076a59cdabe9 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -55,8 +55,8 @@ again:
return ERR_PTR(err);
id = id & MAX_ID_MASK;
- hwdev = device_create_drvdata(hwmon_class, dev, MKDEV(0, 0), NULL,
- HWMON_ID_FORMAT, id);
+ hwdev = device_create(hwmon_class, dev, MKDEV(0, 0), NULL,
+ HWMON_ID_FORMAT, id);
if (IS_ERR(hwdev)) {
spin_lock(&idr_lock);
diff --git a/drivers/i2c/i2c-dev.c b/drivers/i2c/i2c-dev.c
index 307d976c9b69..c171988a9f51 100644
--- a/drivers/i2c/i2c-dev.c
+++ b/drivers/i2c/i2c-dev.c
@@ -521,9 +521,9 @@ static int i2cdev_attach_adapter(struct i2c_adapter *adap)
return PTR_ERR(i2c_dev);
/* register this i2c device with the driver core */
- i2c_dev->dev = device_create_drvdata(i2c_dev_class, &adap->dev,
- MKDEV(I2C_MAJOR, adap->nr),
- NULL, "i2c-%d", adap->nr);
+ i2c_dev->dev = device_create(i2c_dev_class, &adap->dev,
+ MKDEV(I2C_MAJOR, adap->nr), NULL,
+ "i2c-%d", adap->nr);
if (IS_ERR(i2c_dev->dev)) {
res = PTR_ERR(i2c_dev->dev);
goto error;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index f27baa5f140e..19f8c7770a25 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -657,8 +657,8 @@ static int ide_register_port(ide_hwif_t *hwif)
goto out;
}
- hwif->portdev = device_create_drvdata(ide_port_class, &hwif->gendev,
- MKDEV(0, 0), hwif, hwif->name);
+ hwif->portdev = device_create(ide_port_class, &hwif->gendev,
+ MKDEV(0, 0), hwif, hwif->name);
if (IS_ERR(hwif->portdev)) {
ret = PTR_ERR(hwif->portdev);
device_unregister(&hwif->gendev);
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 25ac60f53273..d879c7797cde 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -2420,12 +2420,11 @@ static int ide_tape_probe(ide_drive_t *drive)
idetape_setup(drive, tape, minor);
- device_create_drvdata(idetape_sysfs_class, &drive->gendev,
- MKDEV(IDETAPE_MAJOR, minor), NULL,
- "%s", tape->name);
- device_create_drvdata(idetape_sysfs_class, &drive->gendev,
- MKDEV(IDETAPE_MAJOR, minor + 128), NULL,
- "n%s", tape->name);
+ device_create(idetape_sysfs_class, &drive->gendev,
+ MKDEV(IDETAPE_MAJOR, minor), NULL, "%s", tape->name);
+ device_create(idetape_sysfs_class, &drive->gendev,
+ MKDEV(IDETAPE_MAJOR, minor + 128), NULL,
+ "n%s", tape->name);
g->fops = &idetape_block_ops;
ide_register_region(g);
diff --git a/drivers/ieee1394/dv1394.c b/drivers/ieee1394/dv1394.c
index b6eb2cf25914..9236c0d5a122 100644
--- a/drivers/ieee1394/dv1394.c
+++ b/drivers/ieee1394/dv1394.c
@@ -2296,10 +2296,10 @@ static void dv1394_add_host(struct hpsb_host *host)
ohci = (struct ti_ohci *)host->hostdata;
- device_create_drvdata(hpsb_protocol_class, NULL,
- MKDEV(IEEE1394_MAJOR,
- IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)), NULL,
- "dv1394-%d", id);
+ device_create(hpsb_protocol_class, NULL,
+ MKDEV(IEEE1394_MAJOR,
+ IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
+ NULL, "dv1394-%d", id);
dv1394_init(ohci, DV1394_NTSC, MODE_RECEIVE);
dv1394_init(ohci, DV1394_NTSC, MODE_TRANSMIT);
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index 6fa9e4a21840..c7833bb37ae1 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -3010,10 +3010,10 @@ static int __init init_raw1394(void)
hpsb_register_highlevel(&raw1394_highlevel);
if (IS_ERR
- (device_create_drvdata(
- hpsb_protocol_class, NULL,
- MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
- NULL, RAW1394_DEVICE_NAME))) {
+ (device_create(hpsb_protocol_class, NULL,
+ MKDEV(IEEE1394_MAJOR,
+ IEEE1394_MINOR_BLOCK_RAW1394 * 16),
+ NULL, RAW1394_DEVICE_NAME))) {
ret = -EFAULT;
goto out_unreg;
}
diff --git a/drivers/ieee1394/video1394.c b/drivers/ieee1394/video1394.c
index 25db6e67fa4e..6e73b06eed4f 100644
--- a/drivers/ieee1394/video1394.c
+++ b/drivers/ieee1394/video1394.c
@@ -1341,9 +1341,8 @@ static void video1394_add_host (struct hpsb_host *host)
hpsb_set_hostinfo_key(&video1394_highlevel, host, ohci->host->id);
minor = IEEE1394_MINOR_BLOCK_VIDEO1394 * 16 + ohci->host->id;
- device_create_drvdata(hpsb_protocol_class, NULL,
- MKDEV(IEEE1394_MAJOR, minor), NULL,
- "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
+ device_create(hpsb_protocol_class, NULL, MKDEV(IEEE1394_MAJOR, minor),
+ NULL, "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
}
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 3cab0cedfca2..a78d35aecee3 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -3691,9 +3691,9 @@ static void cm_add_one(struct ib_device *ib_device)
cm_dev->ib_device = ib_device;
cm_get_ack_delay(cm_dev);
- cm_dev->device = device_create_drvdata(&cm_class, &ib_device->dev,
- MKDEV(0, 0), NULL,
- "%s", ib_device->name);
+ cm_dev->device = device_create(&cm_class, &ib_device->dev,
+ MKDEV(0, 0), NULL,
+ "%s", ib_device->name);
if (!cm_dev->device) {
kfree(cm_dev);
return;
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 268a2d23b7c9..8c46f2257098 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -1016,9 +1016,9 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
if (cdev_add(port->cdev, base_dev + port->dev_num, 1))
goto err_cdev;
- port->dev = device_create_drvdata(umad_class, device->dma_device,
- port->cdev->dev, port,
- "umad%d", port->dev_num);
+ port->dev = device_create(umad_class, device->dma_device,
+ port->cdev->dev, port,
+ "umad%d", port->dev_num);
if (IS_ERR(port->dev))
goto err_cdev;
@@ -1036,9 +1036,9 @@ static int ib_umad_init_port(struct ib_device *device, int port_num,
if (cdev_add(port->sm_cdev, base_dev + port->dev_num + IB_UMAD_MAX_PORTS, 1))
goto err_sm_cdev;
- port->sm_dev = device_create_drvdata(umad_class, device->dma_device,
- port->sm_cdev->dev, port,
- "issm%d", port->dev_num);
+ port->sm_dev = device_create(umad_class, device->dma_device,
+ port->sm_cdev->dev, port,
+ "issm%d", port->dev_num);
if (IS_ERR(port->sm_dev))
goto err_sm_cdev;
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index aeee856c4060..d85af1b67027 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -764,12 +764,9 @@ static void ib_uverbs_add_one(struct ib_device *device)
if (cdev_add(uverbs_dev->cdev, IB_UVERBS_BASE_DEV + uverbs_dev->devnum, 1))
goto err_cdev;
- uverbs_dev->dev = device_create_drvdata(uverbs_class,
- device->dma_device,
- uverbs_dev->cdev->dev,
- uverbs_dev,
- "uverbs%d",
- uverbs_dev->devnum);
+ uverbs_dev->dev = device_create(uverbs_class, device->dma_device,
+ uverbs_dev->cdev->dev, uverbs_dev,
+ "uverbs%d", uverbs_dev->devnum);
if (IS_ERR(uverbs_dev->dev))
goto err_cdev;
diff --git a/drivers/infiniband/hw/ipath/ipath_file_ops.c b/drivers/infiniband/hw/ipath/ipath_file_ops.c
index 56c0eda3c077..1af1f3a907c6 100644
--- a/drivers/infiniband/hw/ipath/ipath_file_ops.c
+++ b/drivers/infiniband/hw/ipath/ipath_file_ops.c
@@ -2455,7 +2455,7 @@ static int init_cdev(int minor, char *name, const struct file_operations *fops,
goto err_cdev;
}
- device = device_create_drvdata(ipath_class, NULL, dev, NULL, name);
+ device = device_create(ipath_class, NULL, dev, NULL, name);
if (IS_ERR(device)) {
ret = PTR_ERR(device);
diff --git a/drivers/isdn/capi/capi.c b/drivers/isdn/capi/capi.c
index 798d7f3e42ef..1b5bf87c4cf4 100644
--- a/drivers/isdn/capi/capi.c
+++ b/drivers/isdn/capi/capi.c
@@ -1553,8 +1553,7 @@ static int __init capi_init(void)
return PTR_ERR(capi_class);
}
- device_create_drvdata(capi_class, NULL, MKDEV(capi_major, 0), NULL,
- "capi");
+ device_create(capi_class, NULL, MKDEV(capi_major, 0), NULL, "capi");
#ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
if (capinc_tty_init() < 0) {
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c
index 559a40861c39..ee74ee7b2acc 100644
--- a/drivers/leds/led-class.c
+++ b/drivers/leds/led-class.c
@@ -103,8 +103,8 @@ int led_classdev_register(struct device *parent, struct led_classdev *led_cdev)
{
int rc;
- led_cdev->dev = device_create_drvdata(leds_class, parent, 0, led_cdev,
- "%s", led_cdev->name);
+ led_cdev->dev = device_create(leds_class, parent, 0, led_cdev,
+ "%s", led_cdev->name);
if (IS_ERR(led_cdev->dev))
return PTR_ERR(led_cdev->dev);
diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c
index cae52485208a..23741cec45e3 100644
--- a/drivers/macintosh/adb.c
+++ b/drivers/macintosh/adb.c
@@ -862,8 +862,7 @@ adbdev_init(void)
adb_dev_class = class_create(THIS_MODULE, "adb");
if (IS_ERR(adb_dev_class))
return;
- device_create_drvdata(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL,
- "adb");
+ device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL, "adb");
platform_device_register(&adb_pfdev);
platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
diff --git a/drivers/media/dvb/dvb-core/dvbdev.c b/drivers/media/dvb/dvb-core/dvbdev.c
index e7132770a3bf..665776d72a48 100644
--- a/drivers/media/dvb/dvb-core/dvbdev.c
+++ b/drivers/media/dvb/dvb-core/dvbdev.c
@@ -233,7 +233,7 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
mutex_unlock(&dvbdev_register_lock);
- clsdev = device_create_drvdata(dvb_class, adap->device,
+ clsdev = device_create(dvb_class, adap->device,
MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
if (IS_ERR(clsdev)) {
diff --git a/drivers/misc/phantom.c b/drivers/misc/phantom.c
index daf585689ce3..abdebe347383 100644
--- a/drivers/misc/phantom.c
+++ b/drivers/misc/phantom.c
@@ -399,9 +399,9 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
goto err_irq;
}
- if (IS_ERR(device_create_drvdata(phantom_class, &pdev->dev,
- MKDEV(phantom_major, minor),
- NULL, "phantom%u", minor)))
+ if (IS_ERR(device_create(phantom_class, &pdev->dev,
+ MKDEV(phantom_major, minor), NULL,
+ "phantom%u", minor)))
dev_err(&pdev->dev, "can't create device\n");
pci_set_drvdata(pdev, pht);
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index e00d424e6575..1c74762dec89 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -26,13 +26,11 @@ static void mtd_notify_add(struct mtd_info* mtd)
if (!mtd)
return;
- device_create_drvdata(mtd_class, NULL,
- MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
- NULL, "mtd%d", mtd->index);
+ device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2),
+ NULL, "mtd%d", mtd->index);
- device_create_drvdata(mtd_class, NULL,
- MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
- NULL, "mtd%dro", mtd->index);
+ device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2+1),
+ NULL, "mtd%dro", mtd->index);
}
static void mtd_notify_remove(struct mtd_info* mtd)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index f11e900b437b..e11b03b2b25a 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -309,11 +309,6 @@ void phy_disconnect(struct phy_device *phydev)
}
EXPORT_SYMBOL(phy_disconnect);
-static int phy_compare_id(struct device *dev, void *data)
-{
- return strcmp((char *)data, dev->bus_id) ? 0 : 1;
-}
-
/**
* phy_attach - attach a network device to a particular PHY device
* @dev: network device to attach
@@ -337,8 +332,7 @@ struct phy_device *phy_attach(struct net_device *dev,
/* Search the list of PHY devices on the mdio bus for the
* PHY with the requested name */
- d = bus_find_device(bus, NULL, (void *)bus_id, phy_compare_id);
-
+ d = bus_find_device_by_name(bus, NULL, bus_id);
if (d) {
phydev = to_phy_device(d);
} else {
diff --git a/drivers/net/ppp_generic.c b/drivers/net/ppp_generic.c
index 94818ee3cef5..7e857e938adb 100644
--- a/drivers/net/ppp_generic.c
+++ b/drivers/net/ppp_generic.c
@@ -866,8 +866,8 @@ static int __init ppp_init(void)
err = PTR_ERR(ppp_class);
goto out_chrdev;
}
- device_create_drvdata(ppp_class, NULL, MKDEV(PPP_MAJOR, 0),
- NULL, "ppp");
+ device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), NULL,
+ "ppp");
}
out:
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index f14051556c87..7f97f8d08c39 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -388,8 +388,8 @@ static int __init cosa_init(void)
goto out_chrdev;
}
for (i = 0; i < nr_cards; i++)
- device_create_drvdata(cosa_class, NULL, MKDEV(cosa_major, i),
- NULL, "cosa%d", i);
+ device_create(cosa_class, NULL, MKDEV(cosa_major, i), NULL,
+ "cosa%d", i);
err = 0;
goto out;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index c9e4a435b2fc..1a019e98dac3 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -533,11 +533,11 @@ static int __init init_mac80211_hwsim(void)
data = hw->priv;
data->hw = hw;
- data->dev = device_create_drvdata(hwsim_class, NULL, 0, hw,
- "hwsim%d", i);
+ data->dev = device_create(hwsim_class, NULL, 0, hw,
+ "hwsim%d", i);
if (IS_ERR(data->dev)) {
printk(KERN_DEBUG
- "mac80211_hwsim: device_create_drvdata "
+ "mac80211_hwsim: device_create "
"failed (%ld)\n", PTR_ERR(data->dev));
err = -ENOMEM;
goto failed_drvdata;
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 36698e57b97f..dd9161a054e1 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -1237,8 +1237,11 @@ EXPORT_SYMBOL(pci_scan_bridge);
EXPORT_SYMBOL_GPL(pci_scan_child_bus);
#endif
-static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev *b)
+static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b)
{
+ const struct pci_dev *a = to_pci_dev(d_a);
+ const struct pci_dev *b = to_pci_dev(d_b);
+
if (pci_domain_nr(a->bus) < pci_domain_nr(b->bus)) return -1;
else if (pci_domain_nr(a->bus) > pci_domain_nr(b->bus)) return 1;
@@ -1251,50 +1254,7 @@ static int __init pci_sort_bf_cmp(const struct pci_dev *a, const struct pci_dev
return 0;
}
-/*
- * Yes, this forcably breaks the klist abstraction temporarily. It
- * just wants to sort the klist, not change reference counts and
- * take/drop locks rapidly in the process. It does all this while
- * holding the lock for the list, so objects can't otherwise be
- * added/removed while we're swizzling.
- */
-static void __init pci_insertion_sort_klist(struct pci_dev *a, struct list_head *list)
-{
- struct list_head *pos;
- struct klist_node *n;
- struct device *dev;
- struct pci_dev *b;
-
- list_for_each(pos, list) {
- n = container_of(pos, struct klist_node, n_node);
- dev = container_of(n, struct device, knode_bus);
- b = to_pci_dev(dev);
- if (pci_sort_bf_cmp(a, b) <= 0) {
- list_move_tail(&a->dev.knode_bus.n_node, &b->dev.knode_bus.n_node);
- return;
- }
- }
- list_move_tail(&a->dev.knode_bus.n_node, list);
-}
-
void __init pci_sort_breadthfirst(void)
{
- LIST_HEAD(sorted_devices);
- struct list_head *pos, *tmp;
- struct klist_node *n;
- struct device *dev;
- struct pci_dev *pdev;
- struct klist *device_klist;
-
- device_klist = bus_get_device_klist(&pci_bus_type);
-
- spin_lock(&device_klist->k_lock);
- list_for_each_safe(pos, tmp, &device_klist->k_list) {
- n = container_of(pos, struct klist_node, n_node);
- dev = container_of(n, struct device, knode_bus);
- pdev = to_pci_dev(dev);
- pci_insertion_sort_klist(pdev, &sorted_devices);
- }
- list_splice(&sorted_devices, &device_klist->k_list);
- spin_unlock(&device_klist->k_lock);
+ bus_sort_breadthfirst(&pci_bus_type, &pci_sort_bf_cmp);
}
diff --git a/drivers/pnp/base.h b/drivers/pnp/base.h
index 7cc7bf5304aa..3b8b9d3cb03d 100644
--- a/drivers/pnp/base.h
+++ b/drivers/pnp/base.h
@@ -4,6 +4,7 @@
*/
extern spinlock_t pnp_lock;
+extern struct device_attribute pnp_interface_attrs[];
void *pnp_alloc(long size);
int pnp_register_protocol(struct pnp_protocol *protocol);
@@ -16,7 +17,6 @@ struct pnp_card *pnp_alloc_card(struct pnp_protocol *, int id, char *pnpid);
int pnp_add_device(struct pnp_dev *dev);
struct pnp_id *pnp_add_id(struct pnp_dev *dev, char *id);
-int pnp_interface_attach_device(struct pnp_dev *dev);
int pnp_add_card(struct pnp_card *card);
void pnp_remove_card(struct pnp_card *card);
diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c
index cc0aeaed6179..817fe626e15b 100644
--- a/drivers/pnp/core.c
+++ b/drivers/pnp/core.c
@@ -159,21 +159,13 @@ struct pnp_dev *pnp_alloc_dev(struct pnp_protocol *protocol, int id, char *pnpid
int __pnp_add_device(struct pnp_dev *dev)
{
- int ret;
-
pnp_fixup_device(dev);
dev->status = PNP_READY;
spin_lock(&pnp_lock);
list_add_tail(&dev->global_list, &pnp_global);
list_add_tail(&dev->protocol_list, &dev->protocol->devices);
spin_unlock(&pnp_lock);
-
- ret = device_register(&dev->dev);
- if (ret)
- return ret;
-
- pnp_interface_attach_device(dev);
- return 0;
+ return device_register(&dev->dev);
}
/*
diff --git a/drivers/pnp/driver.c b/drivers/pnp/driver.c
index d3f869ee1d92..e3f7e89c4dfb 100644
--- a/drivers/pnp/driver.c
+++ b/drivers/pnp/driver.c
@@ -206,6 +206,7 @@ struct bus_type pnp_bus_type = {
.remove = pnp_device_remove,
.suspend = pnp_bus_suspend,
.resume = pnp_bus_resume,
+ .dev_attrs = pnp_interface_attrs,
};
int pnp_register_driver(struct pnp_driver *drv)
diff --git a/drivers/pnp/interface.c b/drivers/pnp/interface.c
index a876ecf7028c..478a4a739c00 100644
--- a/drivers/pnp/interface.c
+++ b/drivers/pnp/interface.c
@@ -243,8 +243,6 @@ static ssize_t pnp_show_options(struct device *dmdev,
return ret;
}
-static DEVICE_ATTR(options, S_IRUGO, pnp_show_options, NULL);
-
static ssize_t pnp_show_current_resources(struct device *dmdev,
struct device_attribute *attr,
char *buf)
@@ -420,9 +418,6 @@ done:
return count;
}
-static DEVICE_ATTR(resources, S_IRUGO | S_IWUSR,
- pnp_show_current_resources, pnp_set_current_resources);
-
static ssize_t pnp_show_current_ids(struct device *dmdev,
struct device_attribute *attr, char *buf)
{
@@ -437,27 +432,11 @@ static ssize_t pnp_show_current_ids(struct device *dmdev,
return (str - buf);
}
-static DEVICE_ATTR(id, S_IRUGO, pnp_show_current_ids, NULL);
-
-int pnp_interface_attach_device(struct pnp_dev *dev)
-{
- int rc = device_create_file(&dev->dev, &dev_attr_options);
-
- if (rc)
- goto err;
- rc = device_create_file(&dev->dev, &dev_attr_resources);
- if (rc)
- goto err_opt;
- rc = device_create_file(&dev->dev, &dev_attr_id);
- if (rc)
- goto err_res;
-
- return 0;
-
-err_res:
- device_remove_file(&dev->dev, &dev_attr_resources);
-err_opt:
- device_remove_file(&dev->dev, &dev_attr_options);
-err:
- return rc;
-}
+struct device_attribute pnp_interface_attrs[] = {
+ __ATTR(resources, S_IRUGO | S_IWUSR,
+ pnp_show_current_resources,
+ pnp_set_current_resources),
+ __ATTR(options, S_IRUGO, pnp_show_options, NULL),
+ __ATTR(id, S_IRUGO, pnp_show_current_ids, NULL),
+ __ATTR_NULL,
+};
diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c
index cb1ccb472921..3007695f90c8 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -91,8 +91,8 @@ int power_supply_register(struct device *parent, struct power_supply *psy)
{
int rc = 0;
- psy->dev = device_create_drvdata(power_supply_class, parent, 0,
- psy, "%s", psy->name);
+ psy->dev = device_create(power_supply_class, parent, 0, psy,
+ "%s", psy->name);
if (IS_ERR(psy->dev)) {
rc = PTR_ERR(psy->dev);
goto dev_create_failed;
diff --git a/drivers/s390/char/raw3270.c b/drivers/s390/char/raw3270.c
index 1792b2c0130e..0b15cf107ec9 100644
--- a/drivers/s390/char/raw3270.c
+++ b/drivers/s390/char/raw3270.c
@@ -1168,19 +1168,17 @@ static int raw3270_create_attributes(struct raw3270 *rp)
if (rc)
goto out;
- rp->clttydev = device_create_drvdata(class3270, &rp->cdev->dev,
- MKDEV(IBM_TTY3270_MAJOR, rp->minor),
- NULL,
- "tty%s", dev_name(&rp->cdev->dev));
+ rp->clttydev = device_create(class3270, &rp->cdev->dev,
+ MKDEV(IBM_TTY3270_MAJOR, rp->minor), NULL,
+ "tty%s", dev_name(&rp->cdev->dev));
if (IS_ERR(rp->clttydev)) {
rc = PTR_ERR(rp->clttydev);
goto out_ttydev;
}
- rp->cltubdev = device_create_drvdata(class3270, &rp->cdev->dev,
- MKDEV(IBM_FS3270_MAJOR, rp->minor),
- NULL,
- "tub%s", dev_name(&rp->cdev->dev));
+ rp->cltubdev = device_create(class3270, &rp->cdev->dev,
+ MKDEV(IBM_FS3270_MAJOR, rp->minor), NULL,
+ "tub%s", dev_name(&rp->cdev->dev));
if (!IS_ERR(rp->cltubdev))
goto out;
diff --git a/drivers/s390/char/tape_class.c b/drivers/s390/char/tape_class.c
index 12c2a5aaf31b..ddc914ccea8f 100644
--- a/drivers/s390/char/tape_class.c
+++ b/drivers/s390/char/tape_class.c
@@ -69,9 +69,9 @@ struct tape_class_device *register_tape_dev(
if (rc)
goto fail_with_cdev;
- tcd->class_device = device_create_drvdata(tape_class, device,
- tcd->char_device->dev,
- NULL, "%s", tcd->device_name);
+ tcd->class_device = device_create(tape_class, device,
+ tcd->char_device->dev, NULL,
+ "%s", tcd->device_name);
rc = IS_ERR(tcd->class_device) ? PTR_ERR(tcd->class_device) : 0;
if (rc)
goto fail_with_cdev;
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 42173cc34610..24762727bc27 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -747,10 +747,10 @@ static int vmlogrdr_register_device(struct vmlogrdr_priv_t *priv)
device_unregister(dev);
return ret;
}
- priv->class_device = device_create_drvdata(vmlogrdr_class, dev,
- MKDEV(vmlogrdr_major,
- priv->minor_num),
- priv, "%s", dev_name(dev));
+ priv->class_device = device_create(vmlogrdr_class, dev,
+ MKDEV(vmlogrdr_major,
+ priv->minor_num),
+ priv, "%s", dev_name(dev));
if (IS_ERR(priv->class_device)) {
ret = PTR_ERR(priv->class_device);
priv->class_device=NULL;
diff --git a/drivers/s390/char/vmur.c b/drivers/s390/char/vmur.c
index 6fdfa5ddeca8..9020eba620ee 100644
--- a/drivers/s390/char/vmur.c
+++ b/drivers/s390/char/vmur.c
@@ -896,9 +896,8 @@ static int ur_set_online(struct ccw_device *cdev)
goto fail_free_cdev;
}
- urd->device = device_create_drvdata(vmur_class, NULL,
- urd->char_device->dev, NULL,
- "%s", node_id);
+ urd->device = device_create(vmur_class, NULL, urd->char_device->dev,
+ NULL, "%s", node_id);
if (IS_ERR(urd->device)) {
rc = PTR_ERR(urd->device);
TRACE("ur_set_online: device_create rc=%d\n", rc);
diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c
index 3c257fe0893e..88ecf94ad979 100644
--- a/drivers/scsi/ch.c
+++ b/drivers/scsi/ch.c
@@ -914,9 +914,9 @@ static int ch_probe(struct device *dev)
ch->minor = minor;
sprintf(ch->name,"ch%d",ch->minor);
- class_dev = device_create_drvdata(ch_sysfs_class, dev,
- MKDEV(SCSI_CHANGER_MAJOR, ch->minor),
- ch, "s%s", ch->name);
+ class_dev = device_create(ch_sysfs_class, dev,
+ MKDEV(SCSI_CHANGER_MAJOR, ch->minor), ch,
+ "s%s", ch->name);
if (IS_ERR(class_dev)) {
printk(KERN_WARNING "ch%d: device_create failed\n",
ch->minor);
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index 1fe0901e8119..8aba4fdfb522 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -271,7 +271,7 @@ rebuild_sys_tab:
pHba->initialized = TRUE;
pHba->state &= ~DPTI_STATE_RESET;
if (adpt_sysfs_class) {
- struct device *dev = device_create_drvdata(adpt_sysfs_class,
+ struct device *dev = device_create(adpt_sysfs_class,
NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL,
"dpti%d", pHba->unit);
if (IS_ERR(dev)) {
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 1c79f9794f4e..0ea78d9a37db 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -5708,7 +5708,8 @@ static int osst_sysfs_add(dev_t dev, struct device *device, struct osst_tape * S
struct device *osst_member;
int err;
- osst_member = device_create_drvdata(osst_sysfs_class, device, dev, STp, "%s", name);
+ osst_member = device_create(osst_sysfs_class, device, dev, STp,
+ "%s", name);
if (IS_ERR(osst_member)) {
printk(KERN_WARNING "osst :W: Unable to add sysfs class member %s\n", name);
return PTR_ERR(osst_member);
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index ba9b9bbd4e73..93bd59a1ed79 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1450,12 +1450,10 @@ sg_add(struct device *cl_dev, struct class_interface *cl_intf)
if (sg_sysfs_valid) {
struct device *sg_class_member;
- sg_class_member = device_create_drvdata(sg_sysfs_class,
- cl_dev->parent,
- MKDEV(SCSI_GENERIC_MAJOR,
- sdp->index),
- sdp,
- "%s", disk->disk_name);
+ sg_class_member = device_create(sg_sysfs_class, cl_dev->parent,
+ MKDEV(SCSI_GENERIC_MAJOR,
+ sdp->index),
+ sdp, "%s", disk->disk_name);
if (IS_ERR(sg_class_member)) {
printk(KERN_ERR "sg_add: "
"device_create failed\n");
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index c2bb53e3d941..5c28d08f18f4 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -4428,13 +4428,10 @@ static int do_create_class_files(struct scsi_tape *STp, int dev_num, int mode)
snprintf(name, 10, "%s%s%s", rew ? "n" : "",
STp->disk->disk_name, st_formats[i]);
st_class_member =
- device_create_drvdata(st_sysfs_class,
- &STp->device->sdev_gendev,
- MKDEV(SCSI_TAPE_MAJOR,
- TAPE_MINOR(dev_num,
- mode, rew)),
- &STp->modes[mode],
- "%s", name);
+ device_create(st_sysfs_class, &STp->device->sdev_gendev,
+ MKDEV(SCSI_TAPE_MAJOR,
+ TAPE_MINOR(dev_num, mode, rew)),
+ &STp->modes[mode], "%s", name);
if (IS_ERR(st_class_member)) {
printk(KERN_WARNING "st%d: device_create failed\n",
dev_num);
diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c
index e5e0cfed5e3b..89a43755a453 100644
--- a/drivers/spi/spidev.c
+++ b/drivers/spi/spidev.c
@@ -583,10 +583,9 @@ static int spidev_probe(struct spi_device *spi)
struct device *dev;
spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
- dev = device_create_drvdata(spidev_class, &spi->dev,
- spidev->devt, spidev,
- "spidev%d.%d",
- spi->master->bus_num, spi->chip_select);
+ dev = device_create(spidev_class, &spi->dev, spidev->devt,
+ spidev, "spidev%d.%d",
+ spi->master->bus_num, spi->chip_select);
status = IS_ERR(dev) ? PTR_ERR(dev) : 0;
} else {
dev_dbg(&spi->dev, "no minor number available!\n");
diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
index 4190be64917f..04b954cfce76 100644
--- a/drivers/uio/Kconfig
+++ b/drivers/uio/Kconfig
@@ -58,4 +58,17 @@ config UIO_SMX
If you compile this as a module, it will be called uio_smx.
+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
+ available for download from the Automata GmbH web site.
+
+ Automata GmbH: http://www.automataweb.com
+ Sercos III interface: http://www.sercos.com
+
+ If you compile this as a module, it will be called uio_sercos3.
+
endif
diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
index 8667bbdef904..e69558149859 100644
--- a/drivers/uio/Makefile
+++ b/drivers/uio/Makefile
@@ -3,3 +3,4 @@ obj-$(CONFIG_UIO_CIF) += uio_cif.o
obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
obj-$(CONFIG_UIO_PDRV_GENIRQ) += uio_pdrv_genirq.o
obj-$(CONFIG_UIO_SMX) += uio_smx.o
+obj-$(CONFIG_UIO_SERCOS3) += uio_sercos3.o
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
index 3a6934bf7131..5dccf057a7dd 100644
--- a/drivers/uio/uio.c
+++ b/drivers/uio/uio.c
@@ -67,6 +67,11 @@ static ssize_t map_size_show(struct uio_mem *mem, char *buf)
return sprintf(buf, "0x%lx\n", mem->size);
}
+static ssize_t map_offset_show(struct uio_mem *mem, char *buf)
+{
+ return sprintf(buf, "0x%lx\n", mem->addr & ~PAGE_MASK);
+}
+
struct uio_sysfs_entry {
struct attribute attr;
ssize_t (*show)(struct uio_mem *, char *);
@@ -77,10 +82,13 @@ static struct uio_sysfs_entry addr_attribute =
__ATTR(addr, S_IRUGO, map_addr_show, NULL);
static struct uio_sysfs_entry size_attribute =
__ATTR(size, S_IRUGO, map_size_show, NULL);
+static struct uio_sysfs_entry offset_attribute =
+ __ATTR(offset, S_IRUGO, map_offset_show, NULL);
static struct attribute *attrs[] = {
&addr_attribute.attr,
&size_attribute.attr,
+ &offset_attribute.attr,
NULL, /* need to NULL terminate the list of attributes */
};
@@ -482,15 +490,23 @@ static int uio_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
struct uio_device *idev = vma->vm_private_data;
struct page *page;
+ unsigned long offset;
int mi = uio_find_mem_index(vma);
if (mi < 0)
return VM_FAULT_SIGBUS;
+ /*
+ * We need to subtract mi because userspace uses offset = N*PAGE_SIZE
+ * to use mem[N].
+ */
+ offset = (vmf->pgoff - mi) << PAGE_SHIFT;
+
if (idev->info->mem[mi].memtype == UIO_MEM_LOGICAL)
- page = virt_to_page(idev->info->mem[mi].addr);
+ page = virt_to_page(idev->info->mem[mi].addr + offset);
else
- page = vmalloc_to_page((void*)idev->info->mem[mi].addr);
+ page = vmalloc_to_page((void *)idev->info->mem[mi].addr
+ + offset);
get_page(page);
vmf->page = page;
return 0;
@@ -682,9 +698,9 @@ int __uio_register_device(struct module *owner,
if (ret)
goto err_get_minor;
- idev->dev = device_create_drvdata(uio_class->class, parent,
- MKDEV(uio_major, idev->minor), idev,
- "uio%d", idev->minor);
+ idev->dev = device_create(uio_class->class, parent,
+ MKDEV(uio_major, idev->minor), idev,
+ "uio%d", idev->minor);
if (IS_ERR(idev->dev)) {
printk(KERN_ERR "UIO: device register failed\n");
ret = PTR_ERR(idev->dev);
diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
index 0b4ef39cd85d..d494ce9288c3 100644
--- a/drivers/uio/uio_pdrv.c
+++ b/drivers/uio/uio_pdrv.c
@@ -12,7 +12,7 @@
#include <linux/uio_driver.h>
#include <linux/stringify.h>
-#define DRIVER_NAME "uio"
+#define DRIVER_NAME "uio_pdrv"
struct uio_platdata {
struct uio_info *uioinfo;
diff --git a/drivers/uio/uio_sercos3.c b/drivers/uio/uio_sercos3.c
new file mode 100644
index 000000000000..a6d1b2bc47f3
--- /dev/null
+++ b/drivers/uio/uio_sercos3.c
@@ -0,0 +1,243 @@
+/* sercos3: UIO driver for the Automata Sercos III PCI card
+
+ Copyright (C) 2008 Linutronix GmbH
+ Author: John Ogness <john.ogness@linutronix.de>
+
+ This is a straight-forward UIO driver, where interrupts are disabled
+ by the interrupt handler and re-enabled via a write to the UIO device
+ by the userspace-part.
+
+ The only part that may seem odd is the use of a logical OR when
+ storing and restoring enabled interrupts. This is done because the
+ userspace-part could directly modify the Interrupt Enable Register
+ at any time. To reduce possible conflicts, the kernel driver uses
+ a logical OR to make more controlled changes (rather than blindly
+ overwriting previous values).
+
+ Race conditions exist if the userspace-part directly modifies the
+ Interrupt Enable Register while in operation. The consequences are
+ that certain interrupts would fail to be enabled or disabled. For
+ this reason, the userspace-part should only directly modify the
+ Interrupt Enable Register at the beginning (to get things going).
+ The userspace-part can safely disable interrupts at any time using
+ a write to the UIO device.
+*/
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/uio_driver.h>
+#include <linux/io.h>
+
+/* ID's for SERCOS III PCI card (PLX 9030) */
+#define SERCOS_SUB_VENDOR_ID 0x1971
+#define SERCOS_SUB_SYSID_3530 0x3530
+#define SERCOS_SUB_SYSID_3535 0x3535
+#define SERCOS_SUB_SYSID_3780 0x3780
+
+/* Interrupt Enable Register */
+#define IER0_OFFSET 0x08
+
+/* Interrupt Status Register */
+#define ISR0_OFFSET 0x18
+
+struct sercos3_priv {
+ u32 ier0_cache;
+ spinlock_t ier0_cache_lock;
+};
+
+/* this function assumes ier0_cache_lock is locked! */
+static void sercos3_disable_interrupts(struct uio_info *info,
+ struct sercos3_priv *priv)
+{
+ void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET;
+
+ /* add enabled interrupts to cache */
+ priv->ier0_cache |= ioread32(ier0);
+
+ /* disable interrupts */
+ iowrite32(0, ier0);
+}
+
+/* this function assumes ier0_cache_lock is locked! */
+static void sercos3_enable_interrupts(struct uio_info *info,
+ struct sercos3_priv *priv)
+{
+ void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET;
+
+ /* restore previously enabled interrupts */
+ iowrite32(ioread32(ier0) | priv->ier0_cache, ier0);
+ priv->ier0_cache = 0;
+}
+
+static irqreturn_t sercos3_handler(int irq, struct uio_info *info)
+{
+ struct sercos3_priv *priv = info->priv;
+ void __iomem *isr0 = info->mem[3].internal_addr + ISR0_OFFSET;
+ void __iomem *ier0 = info->mem[3].internal_addr + IER0_OFFSET;
+
+ if (!(ioread32(isr0) & ioread32(ier0)))
+ return IRQ_NONE;
+
+ spin_lock(&priv->ier0_cache_lock);
+ sercos3_disable_interrupts(info, priv);
+ spin_unlock(&priv->ier0_cache_lock);
+
+ return IRQ_HANDLED;
+}
+
+static int sercos3_irqcontrol(struct uio_info *info, s32 irq_on)
+{
+ struct sercos3_priv *priv = info->priv;
+
+ spin_lock_irq(&priv->ier0_cache_lock);
+ if (irq_on)
+ sercos3_enable_interrupts(info, priv);
+ else
+ sercos3_disable_interrupts(info, priv);
+ spin_unlock_irq(&priv->ier0_cache_lock);
+
+ return 0;
+}
+
+static int sercos3_setup_iomem(struct pci_dev *dev, struct uio_info *info,
+ int n, int pci_bar)
+{
+ info->mem[n].addr = pci_resource_start(dev, pci_bar);
+ if (!info->mem[n].addr)
+ return -1;
+ info->mem[n].internal_addr = ioremap(pci_resource_start(dev, pci_bar),
+ pci_resource_len(dev, pci_bar));
+ if (!info->mem[n].internal_addr)
+ return -1;
+ info->mem[n].size = pci_resource_len(dev, pci_bar);
+ info->mem[n].memtype = UIO_MEM_PHYS;
+ return 0;
+}
+
+static int __devinit sercos3_pci_probe(struct pci_dev *dev,
+ const struct pci_device_id *id)
+{
+ struct uio_info *info;
+ struct sercos3_priv *priv;
+ int i;
+
+ info = kzalloc(sizeof(struct uio_info), GFP_KERNEL);
+ if (!info)
+ return -ENOMEM;
+
+ priv = kzalloc(sizeof(struct sercos3_priv), GFP_KERNEL);
+ if (!priv)
+ goto out_free;
+
+ if (pci_enable_device(dev))
+ goto out_free_priv;
+
+ if (pci_request_regions(dev, "sercos3"))
+ goto out_disable;
+
+ /* we only need PCI BAR's 0, 2, 3, 4, 5 */
+ if (sercos3_setup_iomem(dev, info, 0, 0))
+ goto out_unmap;
+ if (sercos3_setup_iomem(dev, info, 1, 2))
+ goto out_unmap;
+ if (sercos3_setup_iomem(dev, info, 2, 3))
+ goto out_unmap;
+ if (sercos3_setup_iomem(dev, info, 3, 4))
+ goto out_unmap;
+ if (sercos3_setup_iomem(dev, info, 4, 5))
+ goto out_unmap;
+
+ spin_lock_init(&priv->ier0_cache_lock);
+ info->priv = priv;
+ info->name = "Sercos_III_PCI";
+ info->version = "0.0.1";
+ info->irq = dev->irq;
+ info->irq_flags = IRQF_DISABLED | IRQF_SHARED;
+ info->handler = sercos3_handler;
+ info->irqcontrol = sercos3_irqcontrol;
+
+ pci_set_drvdata(dev, info);
+
+ if (uio_register_device(&dev->dev, info))
+ goto out_unmap;
+
+ return 0;
+
+out_unmap:
+ for (i = 0; i < 5; i++) {
+ if (info->mem[i].internal_addr)
+ iounmap(info->mem[i].internal_addr);
+ }
+ pci_release_regions(dev);
+out_disable:
+ pci_disable_device(dev);
+out_free_priv:
+ kfree(priv);
+out_free:
+ kfree(info);
+ return -ENODEV;
+}
+
+static void sercos3_pci_remove(struct pci_dev *dev)
+{
+ struct uio_info *info = pci_get_drvdata(dev);
+ int i;
+
+ uio_unregister_device(info);
+ pci_release_regions(dev);
+ pci_disable_device(dev);
+ pci_set_drvdata(dev, NULL);
+ for (i = 0; i < 5; i++) {
+ if (info->mem[i].internal_addr)
+ iounmap(info->mem[i].internal_addr);
+ }
+ kfree(info->priv);
+ kfree(info);
+}
+
+static struct pci_device_id sercos3_pci_ids[] __devinitdata = {
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9030,
+ .subvendor = SERCOS_SUB_VENDOR_ID,
+ .subdevice = SERCOS_SUB_SYSID_3530,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9030,
+ .subvendor = SERCOS_SUB_VENDOR_ID,
+ .subdevice = SERCOS_SUB_SYSID_3535,
+ },
+ {
+ .vendor = PCI_VENDOR_ID_PLX,
+ .device = PCI_DEVICE_ID_PLX_9030,
+ .subvendor = SERCOS_SUB_VENDOR_ID,
+ .subdevice = SERCOS_SUB_SYSID_3780,
+ },
+ { 0, }
+};
+
+static struct pci_driver sercos3_pci_driver = {
+ .name = "sercos3",
+ .id_table = sercos3_pci_ids,
+ .probe = sercos3_pci_probe,
+ .remove = sercos3_pci_remove,
+};
+
+static int __init sercos3_init_module(void)
+{
+ return pci_register_driver(&sercos3_pci_driver);
+}
+
+static void __exit sercos3_exit_module(void)
+{
+ pci_unregister_driver(&sercos3_pci_driver);
+}
+
+module_init(sercos3_init_module);
+module_exit(sercos3_exit_module);
+
+MODULE_DESCRIPTION("UIO driver for the Automata Sercos III PCI card");
+MODULE_AUTHOR("John Ogness <john.ogness@linutronix.de>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 20290c5b1562..7a4fa791dc19 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -1729,9 +1729,9 @@ static int usb_classdev_add(struct usb_device *dev)
{
struct device *cldev;
- cldev = device_create_drvdata(usb_classdev_class, &dev->dev,
- dev->dev.devt, NULL, "usbdev%d.%d",
- dev->bus->busnum, dev->devnum);
+ cldev = device_create(usb_classdev_class, &dev->dev, dev->dev.devt,
+ NULL, "usbdev%d.%d", dev->bus->busnum,
+ dev->devnum);
if (IS_ERR(cldev))
return PTR_ERR(cldev);
dev->usb_classdev = cldev;
diff --git a/drivers/usb/core/file.c b/drivers/usb/core/file.c
index 6b1b229e38cd..55f7f310924b 100644
--- a/drivers/usb/core/file.c
+++ b/drivers/usb/core/file.c
@@ -196,9 +196,9 @@ int usb_register_dev(struct usb_interface *intf,
++temp;
else
temp = name;
- intf->usb_dev = device_create_drvdata(usb_class->class, &intf->dev,
- MKDEV(USB_MAJOR, minor), NULL,
- "%s", temp);
+ intf->usb_dev = device_create(usb_class->class, &intf->dev,
+ MKDEV(USB_MAJOR, minor), NULL,
+ "%s", temp);
if (IS_ERR(intf->usb_dev)) {
down_write(&minor_rwsem);
usb_minors[intf->minor] = NULL;
diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
index 8ab389dca2b9..c8035a8216bd 100644
--- a/drivers/usb/core/hcd.c
+++ b/drivers/usb/core/hcd.c
@@ -818,9 +818,8 @@ static int usb_register_bus(struct usb_bus *bus)
set_bit (busnum, busmap.busmap);
bus->busnum = busnum;
- bus->dev = device_create_drvdata(usb_host_class, bus->controller,
- MKDEV(0, 0), bus,
- "usb_host%d", busnum);
+ bus->dev = device_create(usb_host_class, bus->controller, MKDEV(0, 0),
+ bus, "usb_host%d", busnum);
result = PTR_ERR(bus->dev);
if (IS_ERR(bus->dev))
goto error_create_class_dev;
diff --git a/drivers/usb/gadget/Makefile b/drivers/usb/gadget/Makefile
index fcb5cb9094d9..2267fa0b51b2 100644
--- a/drivers/usb/gadget/Makefile
+++ b/drivers/usb/gadget/Makefile
@@ -22,24 +22,15 @@ obj-$(CONFIG_USB_M66592) += m66592-udc.o
#
# USB gadget drivers
#
-C_UTILS = composite.o usbstring.o config.o epautoconf.o
-
-g_zero-objs := zero.o f_sourcesink.o f_loopback.o $(C_UTILS)
-g_ether-objs := ether.o u_ether.o f_subset.o f_ecm.o $(C_UTILS)
-g_serial-objs := serial.o u_serial.o f_acm.o f_serial.o $(C_UTILS)
-g_midi-objs := gmidi.o usbstring.o config.o epautoconf.o
+g_zero-objs := zero.o
+g_ether-objs := ether.o
+g_serial-objs := serial.o
+g_midi-objs := gmidi.o
gadgetfs-objs := inode.o
-g_file_storage-objs := file_storage.o usbstring.o config.o \
- epautoconf.o
-g_printer-objs := printer.o usbstring.o config.o \
- epautoconf.o
-g_cdc-objs := cdc2.o u_ether.o f_ecm.o \
- u_serial.o f_acm.o $(C_UTILS)
+g_file_storage-objs := file_storage.o
+g_printer-objs := printer.o
+g_cdc-objs := cdc2.o
-ifeq ($(CONFIG_USB_ETH_RNDIS),y)
- g_ether-objs += f_rndis.o rndis.o
-endif
-
obj-$(CONFIG_USB_ZERO) += g_zero.o
obj-$(CONFIG_USB_ETH) += g_ether.o
obj-$(CONFIG_USB_GADGETFS) += gadgetfs.o
diff --git a/drivers/usb/gadget/cdc2.c b/drivers/usb/gadget/cdc2.c
index a39a4b940c33..a724fc149850 100644
--- a/drivers/usb/gadget/cdc2.c
+++ b/drivers/usb/gadget/cdc2.c
@@ -43,6 +43,25 @@
/*-------------------------------------------------------------------------*/
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+#include "u_serial.c"
+#include "f_acm.c"
+#include "f_ecm.c"
+#include "u_ether.c"
+
+/*-------------------------------------------------------------------------*/
+
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
@@ -148,7 +167,8 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
int status;
if (!can_support_ecm(cdev->gadget)) {
- ERROR(cdev, "controller '%s' not usable\n", gadget->name);
+ dev_err(&gadget->dev, "controller '%s' not usable\n",
+ gadget->name);
return -EINVAL;
}
@@ -203,7 +223,8 @@ static int __init cdc_bind(struct usb_composite_dev *cdev)
if (status < 0)
goto fail1;
- INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC);
+ dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+ DRIVER_DESC);
return 0;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index bcac2e68660d..944c8e889ab4 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -96,6 +96,28 @@ static inline bool has_rndis(void)
/*-------------------------------------------------------------------------*/
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "f_ecm.c"
+#include "f_subset.c"
+#ifdef CONFIG_USB_ETH_RNDIS
+#include "f_rndis.c"
+#include "rndis.c"
+#endif
+#include "u_ether.c"
+
+/*-------------------------------------------------------------------------*/
+
/* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
* Instead: allocate your own, using normal USB-IF procedures.
*/
@@ -293,7 +315,8 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
* but if the controller isn't recognized at all then
* that assumption is a bit more likely to be wrong.
*/
- WARNING(cdev, "controller '%s' not recognized; trying %s\n",
+ dev_warn(&gadget->dev,
+ "controller '%s' not recognized; trying %s\n",
gadget->name,
eth_config_driver.label);
device_desc.bcdDevice =
@@ -332,7 +355,8 @@ static int __init eth_bind(struct usb_composite_dev *cdev)
if (status < 0)
goto fail;
- INFO(cdev, "%s, version: " DRIVER_VERSION "\n", DRIVER_DESC);
+ dev_info(&gadget->dev, "%s, version: " DRIVER_VERSION "\n",
+ DRIVER_DESC);
return 0;
diff --git a/drivers/usb/gadget/f_ecm.c b/drivers/usb/gadget/f_ecm.c
index a2b5c092bda0..4ae579948e54 100644
--- a/drivers/usb/gadget/f_ecm.c
+++ b/drivers/usb/gadget/f_ecm.c
@@ -83,7 +83,7 @@ static inline struct f_ecm *func_to_ecm(struct usb_function *f)
}
/* peak (theoretical) bulk transfer rate in bits-per-second */
-static inline unsigned bitrate(struct usb_gadget *g)
+static inline unsigned ecm_bitrate(struct usb_gadget *g)
{
if (gadget_is_dualspeed(g) && g->speed == USB_SPEED_HIGH)
return 13 * 512 * 8 * 1000 * 8;
@@ -107,7 +107,7 @@ static inline unsigned bitrate(struct usb_gadget *g)
*/
#define LOG2_STATUS_INTERVAL_MSEC 5 /* 1 << 5 == 32 msec */
-#define STATUS_BYTECOUNT 16 /* 8 byte header + data */
+#define ECM_STATUS_BYTECOUNT 16 /* 8 byte header + data */
/* interface descriptor: */
@@ -125,8 +125,8 @@ static struct usb_interface_descriptor ecm_control_intf __initdata = {
/* .iInterface = DYNAMIC */
};
-static struct usb_cdc_header_desc header_desc __initdata = {
- .bLength = sizeof header_desc,
+static struct usb_cdc_header_desc ecm_header_desc __initdata = {
+ .bLength = sizeof ecm_header_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
@@ -141,8 +141,8 @@ static struct usb_cdc_union_desc ecm_union_desc __initdata = {
/* .bSlaveInterface0 = DYNAMIC */
};
-static struct usb_cdc_ether_desc ether_desc __initdata = {
- .bLength = sizeof ether_desc,
+static struct usb_cdc_ether_desc ecm_desc __initdata = {
+ .bLength = sizeof ecm_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_ETHERNET_TYPE,
@@ -186,17 +186,17 @@ static struct usb_interface_descriptor ecm_data_intf __initdata = {
/* full speed support: */
-static struct usb_endpoint_descriptor fs_notify_desc __initdata = {
+static struct usb_endpoint_descriptor fs_ecm_notify_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = 1 << LOG2_STATUS_INTERVAL_MSEC,
};
-static struct usb_endpoint_descriptor fs_in_desc __initdata = {
+static struct usb_endpoint_descriptor fs_ecm_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -204,7 +204,7 @@ static struct usb_endpoint_descriptor fs_in_desc __initdata = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
-static struct usb_endpoint_descriptor fs_out_desc __initdata = {
+static struct usb_endpoint_descriptor fs_ecm_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -212,34 +212,34 @@ static struct usb_endpoint_descriptor fs_out_desc __initdata = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
-static struct usb_descriptor_header *eth_fs_function[] __initdata = {
+static struct usb_descriptor_header *ecm_fs_function[] __initdata = {
/* CDC ECM control descriptors */
(struct usb_descriptor_header *) &ecm_control_intf,
- (struct usb_descriptor_header *) &header_desc,
+ (struct usb_descriptor_header *) &ecm_header_desc,
(struct usb_descriptor_header *) &ecm_union_desc,
- (struct usb_descriptor_header *) &ether_desc,
+ (struct usb_descriptor_header *) &ecm_desc,
/* NOTE: status endpoint might need to be removed */
- (struct usb_descriptor_header *) &fs_notify_desc,
+ (struct usb_descriptor_header *) &fs_ecm_notify_desc,
/* data interface, altsettings 0 and 1 */
(struct usb_descriptor_header *) &ecm_data_nop_intf,
(struct usb_descriptor_header *) &ecm_data_intf,
- (struct usb_descriptor_header *) &fs_in_desc,
- (struct usb_descriptor_header *) &fs_out_desc,
+ (struct usb_descriptor_header *) &fs_ecm_in_desc,
+ (struct usb_descriptor_header *) &fs_ecm_out_desc,
NULL,
};
/* high speed support: */
-static struct usb_endpoint_descriptor hs_notify_desc __initdata = {
+static struct usb_endpoint_descriptor hs_ecm_notify_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = USB_DIR_IN,
.bmAttributes = USB_ENDPOINT_XFER_INT,
- .wMaxPacketSize = __constant_cpu_to_le16(STATUS_BYTECOUNT),
+ .wMaxPacketSize = __constant_cpu_to_le16(ECM_STATUS_BYTECOUNT),
.bInterval = LOG2_STATUS_INTERVAL_MSEC + 4,
};
-static struct usb_endpoint_descriptor hs_in_desc __initdata = {
+static struct usb_endpoint_descriptor hs_ecm_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -248,7 +248,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
.wMaxPacketSize = __constant_cpu_to_le16(512),
};
-static struct usb_endpoint_descriptor hs_out_desc __initdata = {
+static struct usb_endpoint_descriptor hs_ecm_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -257,19 +257,19 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
.wMaxPacketSize = __constant_cpu_to_le16(512),
};
-static struct usb_descriptor_header *eth_hs_function[] __initdata = {
+static struct usb_descriptor_header *ecm_hs_function[] __initdata = {
/* CDC ECM control descriptors */
(struct usb_descriptor_header *) &ecm_control_intf,
- (struct usb_descriptor_header *) &header_desc,
+ (struct usb_descriptor_header *) &ecm_header_desc,
(struct usb_descriptor_header *) &ecm_union_desc,
- (struct usb_descriptor_header *) &ether_desc,
+ (struct usb_descriptor_header *) &ecm_desc,
/* NOTE: status endpoint might need to be removed */
- (struct usb_descriptor_header *) &hs_notify_desc,
+ (struct usb_descriptor_header *) &hs_ecm_notify_desc,
/* data interface, altsettings 0 and 1 */
(struct usb_descriptor_header *) &ecm_data_nop_intf,
(struct usb_descriptor_header *) &ecm_data_intf,
- (struct usb_descriptor_header *) &hs_in_desc,
- (struct usb_descriptor_header *) &hs_out_desc,
+ (struct usb_descriptor_header *) &hs_ecm_in_desc,
+ (struct usb_descriptor_header *) &hs_ecm_out_desc,
NULL,
};
@@ -329,14 +329,14 @@ static void ecm_do_notify(struct f_ecm *ecm)
event->bNotificationType = USB_CDC_NOTIFY_SPEED_CHANGE;
event->wValue = cpu_to_le16(0);
event->wLength = cpu_to_le16(8);
- req->length = STATUS_BYTECOUNT;
+ req->length = ECM_STATUS_BYTECOUNT;
/* SPEED_CHANGE data is up/down speeds in bits/sec */
data = req->buf + sizeof *event;
- data[0] = cpu_to_le32(bitrate(cdev->gadget));
+ data[0] = cpu_to_le32(ecm_bitrate(cdev->gadget));
data[1] = data[0];
- DBG(cdev, "notify speed %d\n", bitrate(cdev->gadget));
+ DBG(cdev, "notify speed %d\n", ecm_bitrate(cdev->gadget));
ecm->notify_state = ECM_NOTIFY_NONE;
break;
}
@@ -628,13 +628,13 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
status = -ENODEV;
/* allocate instance-specific endpoints */
- ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_in_desc);
if (!ep)
goto fail;
ecm->port.in_ep = ep;
ep->driver_data = cdev; /* claim */
- ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_out_desc);
if (!ep)
goto fail;
ecm->port.out_ep = ep;
@@ -644,7 +644,7 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
* don't treat it that way. It's simpler, and some newer CDC
* profiles (wireless handsets) no longer treat it as optional.
*/
- ep = usb_ep_autoconfig(cdev->gadget, &fs_notify_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_ecm_notify_desc);
if (!ep)
goto fail;
ecm->notify = ep;
@@ -656,47 +656,47 @@ ecm_bind(struct usb_configuration *c, struct usb_function *f)
ecm->notify_req = usb_ep_alloc_request(ep, GFP_KERNEL);
if (!ecm->notify_req)
goto fail;
- ecm->notify_req->buf = kmalloc(STATUS_BYTECOUNT, GFP_KERNEL);
+ ecm->notify_req->buf = kmalloc(ECM_STATUS_BYTECOUNT, GFP_KERNEL);
if (!ecm->notify_req->buf)
goto fail;
ecm->notify_req->context = ecm;
ecm->notify_req->complete = ecm_notify_complete;
/* copy descriptors, and track endpoint copies */
- f->descriptors = usb_copy_descriptors(eth_fs_function);
+ f->descriptors = usb_copy_descriptors(ecm_fs_function);
if (!f->descriptors)
goto fail;
- ecm->fs.in = usb_find_endpoint(eth_fs_function,
- f->descriptors, &fs_in_desc);
- ecm->fs.out = usb_find_endpoint(eth_fs_function,
- f->descriptors, &fs_out_desc);
- ecm->fs.notify = usb_find_endpoint(eth_fs_function,
- f->descriptors, &fs_notify_desc);
+ ecm->fs.in = usb_find_endpoint(ecm_fs_function,
+ f->descriptors, &fs_ecm_in_desc);
+ ecm->fs.out = usb_find_endpoint(ecm_fs_function,
+ f->descriptors, &fs_ecm_out_desc);
+ ecm->fs.notify = usb_find_endpoint(ecm_fs_function,
+ f->descriptors, &fs_ecm_notify_desc);
/* support all relevant hardware speeds... we expect that when
* hardware is dual speed, all bulk-capable endpoints work at
* both speeds
*/
if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_in_desc.bEndpointAddress =
- fs_in_desc.bEndpointAddress;
- hs_out_desc.bEndpointAddress =
- fs_out_desc.bEndpointAddress;
- hs_notify_desc.bEndpointAddress =
- fs_notify_desc.bEndpointAddress;
+ hs_ecm_in_desc.bEndpointAddress =
+ fs_ecm_in_desc.bEndpointAddress;
+ hs_ecm_out_desc.bEndpointAddress =
+ fs_ecm_out_desc.bEndpointAddress;
+ hs_ecm_notify_desc.bEndpointAddress =
+ fs_ecm_notify_desc.bEndpointAddress;
/* copy descriptors, and track endpoint copies */
- f->hs_descriptors = usb_copy_descriptors(eth_hs_function);
+ f->hs_descriptors = usb_copy_descriptors(ecm_hs_function);
if (!f->hs_descriptors)
goto fail;
- ecm->hs.in = usb_find_endpoint(eth_hs_function,
- f->hs_descriptors, &hs_in_desc);
- ecm->hs.out = usb_find_endpoint(eth_hs_function,
- f->hs_descriptors, &hs_out_desc);
- ecm->hs.notify = usb_find_endpoint(eth_hs_function,
- f->hs_descriptors, &hs_notify_desc);
+ ecm->hs.in = usb_find_endpoint(ecm_hs_function,
+ f->hs_descriptors, &hs_ecm_in_desc);
+ ecm->hs.out = usb_find_endpoint(ecm_hs_function,
+ f->hs_descriptors, &hs_ecm_out_desc);
+ ecm->hs.notify = usb_find_endpoint(ecm_hs_function,
+ f->hs_descriptors, &hs_ecm_notify_desc);
}
/* NOTE: all that is done without knowing or caring about
@@ -795,7 +795,7 @@ int __init ecm_bind_config(struct usb_configuration *c, u8 ethaddr[ETH_ALEN])
if (status < 0)
return status;
ecm_string_defs[1].id = status;
- ether_desc.iMACAddress = status;
+ ecm_desc.iMACAddress = status;
}
/* allocate and initialize one new instance */
diff --git a/drivers/usb/gadget/f_loopback.c b/drivers/usb/gadget/f_loopback.c
index eda4cde72c82..87dde012dacc 100644
--- a/drivers/usb/gadget/f_loopback.c
+++ b/drivers/usb/gadget/f_loopback.c
@@ -70,7 +70,7 @@ static struct usb_interface_descriptor loopback_intf = {
/* full speed support: */
-static struct usb_endpoint_descriptor fs_source_desc = {
+static struct usb_endpoint_descriptor fs_loop_source_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -78,7 +78,7 @@ static struct usb_endpoint_descriptor fs_source_desc = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
-static struct usb_endpoint_descriptor fs_sink_desc = {
+static struct usb_endpoint_descriptor fs_loop_sink_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -88,14 +88,14 @@ static struct usb_endpoint_descriptor fs_sink_desc = {
static struct usb_descriptor_header *fs_loopback_descs[] = {
(struct usb_descriptor_header *) &loopback_intf,
- (struct usb_descriptor_header *) &fs_sink_desc,
- (struct usb_descriptor_header *) &fs_source_desc,
+ (struct usb_descriptor_header *) &fs_loop_sink_desc,
+ (struct usb_descriptor_header *) &fs_loop_source_desc,
NULL,
};
/* high speed support: */
-static struct usb_endpoint_descriptor hs_source_desc = {
+static struct usb_endpoint_descriptor hs_loop_source_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -103,7 +103,7 @@ static struct usb_endpoint_descriptor hs_source_desc = {
.wMaxPacketSize = __constant_cpu_to_le16(512),
};
-static struct usb_endpoint_descriptor hs_sink_desc = {
+static struct usb_endpoint_descriptor hs_loop_sink_desc = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -113,8 +113,8 @@ static struct usb_endpoint_descriptor hs_sink_desc = {
static struct usb_descriptor_header *hs_loopback_descs[] = {
(struct usb_descriptor_header *) &loopback_intf,
- (struct usb_descriptor_header *) &hs_source_desc,
- (struct usb_descriptor_header *) &hs_sink_desc,
+ (struct usb_descriptor_header *) &hs_loop_source_desc,
+ (struct usb_descriptor_header *) &hs_loop_sink_desc,
NULL,
};
@@ -152,7 +152,7 @@ loopback_bind(struct usb_configuration *c, struct usb_function *f)
/* allocate endpoints */
- loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_source_desc);
+ loop->in_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_source_desc);
if (!loop->in_ep) {
autoconf_fail:
ERROR(cdev, "%s: can't autoconfigure on %s\n",
@@ -161,17 +161,17 @@ autoconf_fail:
}
loop->in_ep->driver_data = cdev; /* claim */
- loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_sink_desc);
+ loop->out_ep = usb_ep_autoconfig(cdev->gadget, &fs_loop_sink_desc);
if (!loop->out_ep)
goto autoconf_fail;
loop->out_ep->driver_data = cdev; /* claim */
/* support high speed hardware */
if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_source_desc.bEndpointAddress =
- fs_source_desc.bEndpointAddress;
- hs_sink_desc.bEndpointAddress =
- fs_sink_desc.bEndpointAddress;
+ hs_loop_source_desc.bEndpointAddress =
+ fs_loop_source_desc.bEndpointAddress;
+ hs_loop_sink_desc.bEndpointAddress =
+ fs_loop_sink_desc.bEndpointAddress;
f->hs_descriptors = hs_loopback_descs;
}
@@ -255,8 +255,10 @@ enable_loopback(struct usb_composite_dev *cdev, struct f_loopback *loop)
struct usb_request *req;
unsigned i;
- src = ep_choose(cdev->gadget, &hs_source_desc, &fs_source_desc);
- sink = ep_choose(cdev->gadget, &hs_sink_desc, &fs_sink_desc);
+ src = ep_choose(cdev->gadget,
+ &hs_loop_source_desc, &fs_loop_source_desc);
+ sink = ep_choose(cdev->gadget,
+ &hs_loop_sink_desc, &fs_loop_sink_desc);
/* one endpoint writes data back IN to the host */
ep = loop->in_ep;
diff --git a/drivers/usb/gadget/f_subset.c b/drivers/usb/gadget/f_subset.c
index acb8d233aa1d..fe1832875771 100644
--- a/drivers/usb/gadget/f_subset.c
+++ b/drivers/usb/gadget/f_subset.c
@@ -103,8 +103,8 @@ static struct usb_interface_descriptor subset_data_intf __initdata = {
/* .iInterface = DYNAMIC */
};
-static struct usb_cdc_header_desc header_desc __initdata = {
- .bLength = sizeof header_desc,
+static struct usb_cdc_header_desc mdlm_header_desc __initdata = {
+ .bLength = sizeof mdlm_header_desc,
.bDescriptorType = USB_DT_CS_INTERFACE,
.bDescriptorSubType = USB_CDC_HEADER_TYPE,
@@ -152,7 +152,7 @@ static struct usb_cdc_ether_desc ether_desc __initdata = {
/* full speed support: */
-static struct usb_endpoint_descriptor fs_in_desc __initdata = {
+static struct usb_endpoint_descriptor fs_subset_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -160,7 +160,7 @@ static struct usb_endpoint_descriptor fs_in_desc __initdata = {
.bmAttributes = USB_ENDPOINT_XFER_BULK,
};
-static struct usb_endpoint_descriptor fs_out_desc __initdata = {
+static struct usb_endpoint_descriptor fs_subset_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -170,18 +170,18 @@ static struct usb_endpoint_descriptor fs_out_desc __initdata = {
static struct usb_descriptor_header *fs_eth_function[] __initdata = {
(struct usb_descriptor_header *) &subset_data_intf,
- (struct usb_descriptor_header *) &header_desc,
+ (struct usb_descriptor_header *) &mdlm_header_desc,
(struct usb_descriptor_header *) &mdlm_desc,
(struct usb_descriptor_header *) &mdlm_detail_desc,
(struct usb_descriptor_header *) &ether_desc,
- (struct usb_descriptor_header *) &fs_in_desc,
- (struct usb_descriptor_header *) &fs_out_desc,
+ (struct usb_descriptor_header *) &fs_subset_in_desc,
+ (struct usb_descriptor_header *) &fs_subset_out_desc,
NULL,
};
/* high speed support: */
-static struct usb_endpoint_descriptor hs_in_desc __initdata = {
+static struct usb_endpoint_descriptor hs_subset_in_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -189,7 +189,7 @@ static struct usb_endpoint_descriptor hs_in_desc __initdata = {
.wMaxPacketSize = __constant_cpu_to_le16(512),
};
-static struct usb_endpoint_descriptor hs_out_desc __initdata = {
+static struct usb_endpoint_descriptor hs_subset_out_desc __initdata = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
@@ -199,12 +199,12 @@ static struct usb_endpoint_descriptor hs_out_desc __initdata = {
static struct usb_descriptor_header *hs_eth_function[] __initdata = {
(struct usb_descriptor_header *) &subset_data_intf,
- (struct usb_descriptor_header *) &header_desc,
+ (struct usb_descriptor_header *) &mdlm_header_desc,
(struct usb_descriptor_header *) &mdlm_desc,
(struct usb_descriptor_header *) &mdlm_detail_desc,
(struct usb_descriptor_header *) &ether_desc,
- (struct usb_descriptor_header *) &hs_in_desc,
- (struct usb_descriptor_header *) &hs_out_desc,
+ (struct usb_descriptor_header *) &hs_subset_in_desc,
+ (struct usb_descriptor_header *) &hs_subset_out_desc,
NULL,
};
@@ -281,13 +281,13 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
status = -ENODEV;
/* allocate instance-specific endpoints */
- ep = usb_ep_autoconfig(cdev->gadget, &fs_in_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_in_desc);
if (!ep)
goto fail;
geth->port.in_ep = ep;
ep->driver_data = cdev; /* claim */
- ep = usb_ep_autoconfig(cdev->gadget, &fs_out_desc);
+ ep = usb_ep_autoconfig(cdev->gadget, &fs_subset_out_desc);
if (!ep)
goto fail;
geth->port.out_ep = ep;
@@ -297,9 +297,9 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
f->descriptors = usb_copy_descriptors(fs_eth_function);
geth->fs.in = usb_find_endpoint(fs_eth_function,
- f->descriptors, &fs_in_desc);
+ f->descriptors, &fs_subset_in_desc);
geth->fs.out = usb_find_endpoint(fs_eth_function,
- f->descriptors, &fs_out_desc);
+ f->descriptors, &fs_subset_out_desc);
/* support all relevant hardware speeds... we expect that when
@@ -307,18 +307,18 @@ geth_bind(struct usb_configuration *c, struct usb_function *f)
* both speeds
*/
if (gadget_is_dualspeed(c->cdev->gadget)) {
- hs_in_desc.bEndpointAddress =
- fs_in_desc.bEndpointAddress;
- hs_out_desc.bEndpointAddress =
- fs_out_desc.bEndpointAddress;
+ hs_subset_in_desc.bEndpointAddress =
+ fs_subset_in_desc.bEndpointAddress;
+ hs_subset_out_desc.bEndpointAddress =
+ fs_subset_out_desc.bEndpointAddress;
/* copy descriptors, and track endpoint copies */
f->hs_descriptors = usb_copy_descriptors(hs_eth_function);
geth->hs.in = usb_find_endpoint(hs_eth_function,
- f->hs_descriptors, &hs_in_desc);
+ f->hs_descriptors, &hs_subset_in_desc);
geth->hs.out = usb_find_endpoint(hs_eth_function,
- f->hs_descriptors, &hs_out_desc);
+ f->hs_descriptors, &hs_subset_out_desc);
}
/* NOTE: all that is done without knowing or caring about
diff --git a/drivers/usb/gadget/file_storage.c b/drivers/usb/gadget/file_storage.c
index ea2c31d18080..0c632d22a631 100644
--- a/drivers/usb/gadget/file_storage.c
+++ b/drivers/usb/gadget/file_storage.c
@@ -245,6 +245,18 @@
#include "gadget_chips.h"
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
/*-------------------------------------------------------------------------*/
#define DRIVER_DESC "File-backed Storage Gadget"
diff --git a/drivers/usb/gadget/gmidi.c b/drivers/usb/gadget/gmidi.c
index ea8651e3da1a..6eee760410d6 100644
--- a/drivers/usb/gadget/gmidi.c
+++ b/drivers/usb/gadget/gmidi.c
@@ -35,6 +35,21 @@
#include "gadget_chips.h"
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+/*-------------------------------------------------------------------------*/
+
+
MODULE_AUTHOR("Ben Williamson");
MODULE_LICENSE("GPL v2");
diff --git a/drivers/usb/gadget/printer.c b/drivers/usb/gadget/printer.c
index e0090085b78e..2b3b9e1dd2ee 100644
--- a/drivers/usb/gadget/printer.c
+++ b/drivers/usb/gadget/printer.c
@@ -53,6 +53,20 @@
#include "gadget_chips.h"
+
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+/*-------------------------------------------------------------------------*/
+
#define DRIVER_DESC "Printer Gadget"
#define DRIVER_VERSION "2007 OCT 06"
@@ -1360,8 +1374,8 @@ printer_bind(struct usb_gadget *gadget)
/* Setup the sysfs files for the printer gadget. */
- dev->pdev = device_create_drvdata(usb_gadget_class, NULL,
- g_printer_devno, NULL, "g_printer");
+ dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
+ NULL, "g_printer");
if (IS_ERR(dev->pdev)) {
ERROR(dev, "Failed to create device: g_printer\n");
goto fail;
diff --git a/drivers/usb/gadget/rndis.c b/drivers/usb/gadget/rndis.c
index 7228e8562236..8c26f5ea2b83 100644
--- a/drivers/usb/gadget/rndis.c
+++ b/drivers/usb/gadget/rndis.c
@@ -57,11 +57,6 @@ MODULE_PARM_DESC (rndis_debug, "enable debugging");
#define rndis_debug 0
#endif
-#define DBG(str,args...) do { \
- if (rndis_debug) \
- pr_debug(str , ## args); \
- } while (0)
-
#define RNDIS_MAX_CONFIGS 1
@@ -183,9 +178,9 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
if (!resp) return -ENOMEM;
if (buf_len && rndis_debug > 1) {
- DBG("query OID %08x value, len %d:\n", OID, buf_len);
+ pr_debug("query OID %08x value, len %d:\n", OID, buf_len);
for (i = 0; i < buf_len; i += 16) {
- DBG("%03d: %08x %08x %08x %08x\n", i,
+ pr_debug("%03d: %08x %08x %08x %08x\n", i,
get_unaligned_le32(&buf[i]),
get_unaligned_le32(&buf[i + 4]),
get_unaligned_le32(&buf[i + 8]),
@@ -209,7 +204,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_SUPPORTED_LIST:
- DBG("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
+ pr_debug("%s: OID_GEN_SUPPORTED_LIST\n", __func__);
length = sizeof (oid_supported_list);
count = length / sizeof (u32);
for (i = 0; i < count; i++)
@@ -219,7 +214,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_HARDWARE_STATUS:
- DBG("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
+ pr_debug("%s: OID_GEN_HARDWARE_STATUS\n", __func__);
/* Bogus question!
* Hardware must be ready to receive high level protocols.
* BTW:
@@ -232,14 +227,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_MEDIA_SUPPORTED:
- DBG("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
+ pr_debug("%s: OID_GEN_MEDIA_SUPPORTED\n", __func__);
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
retval = 0;
break;
/* mandatory */
case OID_GEN_MEDIA_IN_USE:
- DBG("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
+ pr_debug("%s: OID_GEN_MEDIA_IN_USE\n", __func__);
/* one medium, one transport... (maybe you do it better) */
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr].medium);
retval = 0;
@@ -247,7 +242,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_MAXIMUM_FRAME_SIZE:
- DBG("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
+ pr_debug("%s: OID_GEN_MAXIMUM_FRAME_SIZE\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
*outbuf = cpu_to_le32 (
rndis_per_dev_params [configNr].dev->mtu);
@@ -258,7 +253,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_LINK_SPEED:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_LINK_SPEED\n", __func__);
+ pr_debug("%s: OID_GEN_LINK_SPEED\n", __func__);
if (rndis_per_dev_params [configNr].media_state
== NDIS_MEDIA_STATE_DISCONNECTED)
*outbuf = __constant_cpu_to_le32 (0);
@@ -270,7 +265,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_TRANSMIT_BLOCK_SIZE:
- DBG("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
+ pr_debug("%s: OID_GEN_TRANSMIT_BLOCK_SIZE\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
*outbuf = cpu_to_le32 (
rndis_per_dev_params [configNr].dev->mtu);
@@ -280,7 +275,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_RECEIVE_BLOCK_SIZE:
- DBG("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
+ pr_debug("%s: OID_GEN_RECEIVE_BLOCK_SIZE\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
*outbuf = cpu_to_le32 (
rndis_per_dev_params [configNr].dev->mtu);
@@ -290,7 +285,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_VENDOR_ID:
- DBG("%s: OID_GEN_VENDOR_ID\n", __func__);
+ pr_debug("%s: OID_GEN_VENDOR_ID\n", __func__);
*outbuf = cpu_to_le32 (
rndis_per_dev_params [configNr].vendorID);
retval = 0;
@@ -298,7 +293,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_VENDOR_DESCRIPTION:
- DBG("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
+ pr_debug("%s: OID_GEN_VENDOR_DESCRIPTION\n", __func__);
length = strlen (rndis_per_dev_params [configNr].vendorDescr);
memcpy (outbuf,
rndis_per_dev_params [configNr].vendorDescr, length);
@@ -306,7 +301,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
break;
case OID_GEN_VENDOR_DRIVER_VERSION:
- DBG("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
+ pr_debug("%s: OID_GEN_VENDOR_DRIVER_VERSION\n", __func__);
/* Created as LE */
*outbuf = rndis_driver_version;
retval = 0;
@@ -314,14 +309,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_CURRENT_PACKET_FILTER:
- DBG("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
+ pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER\n", __func__);
*outbuf = cpu_to_le32 (*rndis_per_dev_params[configNr].filter);
retval = 0;
break;
/* mandatory */
case OID_GEN_MAXIMUM_TOTAL_SIZE:
- DBG("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
+ pr_debug("%s: OID_GEN_MAXIMUM_TOTAL_SIZE\n", __func__);
*outbuf = __constant_cpu_to_le32(RNDIS_MAX_TOTAL_SIZE);
retval = 0;
break;
@@ -329,14 +324,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_MEDIA_CONNECT_STATUS:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
+ pr_debug("%s: OID_GEN_MEDIA_CONNECT_STATUS\n", __func__);
*outbuf = cpu_to_le32 (rndis_per_dev_params [configNr]
.media_state);
retval = 0;
break;
case OID_GEN_PHYSICAL_MEDIUM:
- DBG("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
+ pr_debug("%s: OID_GEN_PHYSICAL_MEDIUM\n", __func__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
@@ -346,7 +341,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
* versions emit undefined RNDIS messages. DOCUMENT ALL THESE!
*/
case OID_GEN_MAC_OPTIONS: /* from WinME */
- DBG("%s: OID_GEN_MAC_OPTIONS\n", __func__);
+ pr_debug("%s: OID_GEN_MAC_OPTIONS\n", __func__);
*outbuf = __constant_cpu_to_le32(
NDIS_MAC_OPTION_RECEIVE_SERIALIZED
| NDIS_MAC_OPTION_FULL_DUPLEX);
@@ -358,7 +353,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_XMIT_OK:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_XMIT_OK\n", __func__);
+ pr_debug("%s: OID_GEN_XMIT_OK\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->tx_packets
- stats->tx_errors - stats->tx_dropped);
@@ -369,7 +364,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_RCV_OK:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_RCV_OK\n", __func__);
+ pr_debug("%s: OID_GEN_RCV_OK\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->rx_packets
- stats->rx_errors - stats->rx_dropped);
@@ -380,7 +375,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_XMIT_ERROR:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_XMIT_ERROR\n", __func__);
+ pr_debug("%s: OID_GEN_XMIT_ERROR\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->tx_errors);
retval = 0;
@@ -390,7 +385,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_RCV_ERROR:
if (rndis_debug > 1)
- DBG("%s: OID_GEN_RCV_ERROR\n", __func__);
+ pr_debug("%s: OID_GEN_RCV_ERROR\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->rx_errors);
retval = 0;
@@ -399,7 +394,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_GEN_RCV_NO_BUFFER:
- DBG("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
+ pr_debug("%s: OID_GEN_RCV_NO_BUFFER\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->rx_dropped);
retval = 0;
@@ -410,7 +405,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_PERMANENT_ADDRESS:
- DBG("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
+ pr_debug("%s: OID_802_3_PERMANENT_ADDRESS\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
length = ETH_ALEN;
memcpy (outbuf,
@@ -422,7 +417,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_CURRENT_ADDRESS:
- DBG("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
+ pr_debug("%s: OID_802_3_CURRENT_ADDRESS\n", __func__);
if (rndis_per_dev_params [configNr].dev) {
length = ETH_ALEN;
memcpy (outbuf,
@@ -434,7 +429,7 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_MULTICAST_LIST:
- DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
+ pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
/* Multicast base address only */
*outbuf = __constant_cpu_to_le32 (0xE0000000);
retval = 0;
@@ -442,21 +437,21 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_MAXIMUM_LIST_SIZE:
- DBG("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
+ pr_debug("%s: OID_802_3_MAXIMUM_LIST_SIZE\n", __func__);
/* Multicast base address only */
*outbuf = __constant_cpu_to_le32 (1);
retval = 0;
break;
case OID_802_3_MAC_OPTIONS:
- DBG("%s: OID_802_3_MAC_OPTIONS\n", __func__);
+ pr_debug("%s: OID_802_3_MAC_OPTIONS\n", __func__);
break;
/* ieee802.3 statistics OIDs (table 4-4) */
/* mandatory */
case OID_802_3_RCV_ERROR_ALIGNMENT:
- DBG("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
+ pr_debug("%s: OID_802_3_RCV_ERROR_ALIGNMENT\n", __func__);
if (stats) {
*outbuf = cpu_to_le32(stats->rx_frame_errors);
retval = 0;
@@ -465,14 +460,14 @@ gen_ndis_query_resp (int configNr, u32 OID, u8 *buf, unsigned buf_len,
/* mandatory */
case OID_802_3_XMIT_ONE_COLLISION:
- DBG("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
+ pr_debug("%s: OID_802_3_XMIT_ONE_COLLISION\n", __func__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
/* mandatory */
case OID_802_3_XMIT_MORE_COLLISIONS:
- DBG("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
+ pr_debug("%s: OID_802_3_XMIT_MORE_COLLISIONS\n", __func__);
*outbuf = __constant_cpu_to_le32 (0);
retval = 0;
break;
@@ -504,9 +499,9 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
return -ENOMEM;
if (buf_len && rndis_debug > 1) {
- DBG("set OID %08x value, len %d:\n", OID, buf_len);
+ pr_debug("set OID %08x value, len %d:\n", OID, buf_len);
for (i = 0; i < buf_len; i += 16) {
- DBG("%03d: %08x %08x %08x %08x\n", i,
+ pr_debug("%03d: %08x %08x %08x %08x\n", i,
get_unaligned_le32(&buf[i]),
get_unaligned_le32(&buf[i + 4]),
get_unaligned_le32(&buf[i + 8]),
@@ -525,7 +520,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
* MULTICAST, ALL_MULTICAST, BROADCAST
*/
*params->filter = (u16)get_unaligned_le32(buf);
- DBG("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
+ pr_debug("%s: OID_GEN_CURRENT_PACKET_FILTER %08x\n",
__func__, *params->filter);
/* this call has a significant side effect: it's
@@ -547,7 +542,7 @@ static int gen_ndis_set_resp (u8 configNr, u32 OID, u8 *buf, u32 buf_len,
case OID_802_3_MULTICAST_LIST:
/* I think we can ignore this */
- DBG("%s: OID_802_3_MULTICAST_LIST\n", __func__);
+ pr_debug("%s: OID_802_3_MULTICAST_LIST\n", __func__);
retval = 0;
break;
@@ -606,7 +601,7 @@ static int rndis_query_response (int configNr, rndis_query_msg_type *buf)
rndis_resp_t *r;
struct rndis_params *params = rndis_per_dev_params + configNr;
- // DBG("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID));
+ /* pr_debug("%s: OID = %08X\n", __func__, cpu_to_le32(buf->OID)); */
if (!params->dev)
return -ENOTSUPP;
@@ -659,15 +654,15 @@ static int rndis_set_response (int configNr, rndis_set_msg_type *buf)
BufOffset = le32_to_cpu (buf->InformationBufferOffset);
#ifdef VERBOSE_DEBUG
- DBG("%s: Length: %d\n", __func__, BufLength);
- DBG("%s: Offset: %d\n", __func__, BufOffset);
- DBG("%s: InfoBuffer: ", __func__);
+ pr_debug("%s: Length: %d\n", __func__, BufLength);
+ pr_debug("%s: Offset: %d\n", __func__, BufOffset);
+ pr_debug("%s: InfoBuffer: ", __func__);
for (i = 0; i < BufLength; i++) {
- DBG("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
+ pr_debug("%02x ", *(((u8 *) buf) + i + 8 + BufOffset));
}
- DBG("\n");
+ pr_debug("\n");
#endif
resp->MessageType = __constant_cpu_to_le32 (REMOTE_NDIS_SET_CMPLT);
@@ -821,14 +816,14 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
/* For USB: responses may take up to 10 seconds */
switch (MsgType) {
case REMOTE_NDIS_INITIALIZE_MSG:
- DBG("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
+ pr_debug("%s: REMOTE_NDIS_INITIALIZE_MSG\n",
__func__ );
params->state = RNDIS_INITIALIZED;
return rndis_init_response (configNr,
(rndis_init_msg_type *) buf);
case REMOTE_NDIS_HALT_MSG:
- DBG("%s: REMOTE_NDIS_HALT_MSG\n",
+ pr_debug("%s: REMOTE_NDIS_HALT_MSG\n",
__func__ );
params->state = RNDIS_UNINITIALIZED;
if (params->dev) {
@@ -846,7 +841,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
(rndis_set_msg_type *) buf);
case REMOTE_NDIS_RESET_MSG:
- DBG("%s: REMOTE_NDIS_RESET_MSG\n",
+ pr_debug("%s: REMOTE_NDIS_RESET_MSG\n",
__func__ );
return rndis_reset_response (configNr,
(rndis_reset_msg_type *) buf);
@@ -854,7 +849,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
case REMOTE_NDIS_KEEPALIVE_MSG:
/* For USB: host does this every 5 seconds */
if (rndis_debug > 1)
- DBG("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
+ pr_debug("%s: REMOTE_NDIS_KEEPALIVE_MSG\n",
__func__ );
return rndis_keepalive_response (configNr,
(rndis_keepalive_msg_type *)
@@ -870,7 +865,7 @@ int rndis_msg_parser (u8 configNr, u8 *buf)
{
unsigned i;
for (i = 0; i < MsgLength; i += 16) {
- DBG("%03d: "
+ pr_debug("%03d: "
" %02x %02x %02x %02x"
" %02x %02x %02x %02x"
" %02x %02x %02x %02x"
@@ -905,18 +900,18 @@ int rndis_register(void (*resp_avail)(void *v), void *v)
rndis_per_dev_params [i].used = 1;
rndis_per_dev_params [i].resp_avail = resp_avail;
rndis_per_dev_params [i].v = v;
- DBG("%s: configNr = %d\n", __func__, i);
+ pr_debug("%s: configNr = %d\n", __func__, i);
return i;
}
}
- DBG("failed\n");
+ pr_debug("failed\n");
return -ENODEV;
}
void rndis_deregister (int configNr)
{
- DBG("%s: \n", __func__ );
+ pr_debug("%s: \n", __func__);
if (configNr >= RNDIS_MAX_CONFIGS) return;
rndis_per_dev_params [configNr].used = 0;
@@ -926,7 +921,7 @@ void rndis_deregister (int configNr)
int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
{
- DBG("%s:\n", __func__ );
+ pr_debug("%s:\n", __func__);
if (!dev)
return -EINVAL;
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
@@ -939,7 +934,7 @@ int rndis_set_param_dev(u8 configNr, struct net_device *dev, u16 *cdc_filter)
int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
{
- DBG("%s:\n", __func__ );
+ pr_debug("%s:\n", __func__);
if (!vendorDescr) return -1;
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
@@ -951,7 +946,7 @@ int rndis_set_param_vendor (u8 configNr, u32 vendorID, const char *vendorDescr)
int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed)
{
- DBG("%s: %u %u\n", __func__, medium, speed);
+ pr_debug("%s: %u %u\n", __func__, medium, speed);
if (configNr >= RNDIS_MAX_CONFIGS) return -1;
rndis_per_dev_params [configNr].medium = medium;
@@ -1114,7 +1109,7 @@ static ssize_t rndis_proc_write(struct file *file, const char __user *buffer,
break;
default:
if (fl_speed) p->speed = speed;
- else DBG("%c is not valid\n", c);
+ else pr_debug("%c is not valid\n", c);
break;
}
@@ -1159,12 +1154,12 @@ int __init rndis_init (void)
&rndis_proc_fops,
(void *)(rndis_per_dev_params + i))))
{
- DBG("%s :remove entries", __func__);
+ pr_debug("%s :remove entries", __func__);
while (i) {
sprintf (name, NAME_TEMPLATE, --i);
remove_proc_entry (name, NULL);
}
- DBG("\n");
+ pr_debug("\n");
return -EIO;
}
#endif
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index b3699afff002..3faa7a7022df 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -30,6 +30,24 @@
/*-------------------------------------------------------------------------*/
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "f_acm.c"
+#include "f_serial.c"
+#include "u_serial.c"
+
+/*-------------------------------------------------------------------------*/
+
/* Thanks to NetChip Technologies for donating this product ID.
*
* DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!!
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c
index 3791e6271903..dbd575a194f3 100644
--- a/drivers/usb/gadget/u_ether.c
+++ b/drivers/usb/gadget/u_ether.c
@@ -52,7 +52,7 @@
* this single "physical" link to be used by multiple virtual links.)
*/
-#define DRIVER_VERSION "29-May-2008"
+#define UETH__VERSION "29-May-2008"
struct eth_dev {
/* lock is held while accessing port_usb
@@ -170,7 +170,7 @@ static void eth_get_drvinfo(struct net_device *net, struct ethtool_drvinfo *p)
struct eth_dev *dev = netdev_priv(net);
strlcpy(p->driver, "g_ether", sizeof p->driver);
- strlcpy(p->version, DRIVER_VERSION, sizeof p->version);
+ strlcpy(p->version, UETH__VERSION, sizeof p->version);
strlcpy(p->fw_version, dev->gadget->name, sizeof p->fw_version);
strlcpy(p->bus_info, dev_name(&dev->gadget->dev), sizeof p->bus_info);
}
diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c
index aa0bd4f126a1..361d9659ac48 100644
--- a/drivers/usb/gadget/zero.c
+++ b/drivers/usb/gadget/zero.c
@@ -59,6 +59,23 @@
/*-------------------------------------------------------------------------*/
+/*
+ * Kbuild is not very cooperative with respect to linking separately
+ * compiled library objects into one module. So for now we won't use
+ * separate compilation ... ensuring init/exit sections work to shrink
+ * the runtime footprint, and giving us at least some parts of what
+ * a "gcc --combine ... part1.c part2.c part3.c ... " build would.
+ */
+#include "composite.c"
+#include "usbstring.c"
+#include "config.c"
+#include "epautoconf.c"
+
+#include "f_sourcesink.c"
+#include "f_loopback.c"
+
+/*-------------------------------------------------------------------------*/
+
#define DRIVER_VERSION "Cinco de Mayo 2008"
static const char longname[] = "Gadget Zero";
diff --git a/drivers/usb/host/uhci-q.c b/drivers/usb/host/uhci-q.c
index db645936eedd..1f0c2cf26e5d 100644
--- a/drivers/usb/host/uhci-q.c
+++ b/drivers/usb/host/uhci-q.c
@@ -123,14 +123,10 @@ static struct uhci_td *uhci_alloc_td(struct uhci_hcd *uhci)
static void uhci_free_td(struct uhci_hcd *uhci, struct uhci_td *td)
{
- if (!list_empty(&td->list)) {
- dev_warn(uhci_dev(uhci), "td %p still in list!\n", td);
- WARN_ON(1);
- }
- if (!list_empty(&td->fl_list)) {
- dev_warn(uhci_dev(uhci), "td %p still in fl_list!\n", td);
- WARN_ON(1);
- }
+ if (!list_empty(&td->list))
+ dev_WARN(uhci_dev(uhci), "td %p still in list!\n", td);
+ if (!list_empty(&td->fl_list))
+ dev_WARN(uhci_dev(uhci), "td %p still in fl_list!\n", td);
dma_pool_free(uhci->td_pool, td, td->dma_handle);
}
@@ -295,10 +291,8 @@ static struct uhci_qh *uhci_alloc_qh(struct uhci_hcd *uhci,
static void uhci_free_qh(struct uhci_hcd *uhci, struct uhci_qh *qh)
{
WARN_ON(qh->state != QH_STATE_IDLE && qh->udev);
- if (!list_empty(&qh->queue)) {
- dev_warn(uhci_dev(uhci), "qh %p list not empty!\n", qh);
- WARN_ON(1);
- }
+ if (!list_empty(&qh->queue))
+ dev_WARN(uhci_dev(uhci), "qh %p list not empty!\n", qh);
list_del(&qh->node);
if (qh->udev) {
@@ -746,11 +740,9 @@ static void uhci_free_urb_priv(struct uhci_hcd *uhci,
{
struct uhci_td *td, *tmp;
- if (!list_empty(&urbp->node)) {
- dev_warn(uhci_dev(uhci), "urb %p still on QH's list!\n",
+ if (!list_empty(&urbp->node))
+ dev_WARN(uhci_dev(uhci), "urb %p still on QH's list!\n",
urbp->urb);
- WARN_ON(1);
- }
list_for_each_entry_safe(td, tmp, &urbp->td_list, list) {
uhci_remove_td_from_urbp(td);
diff --git a/drivers/usb/misc/phidgetkit.c b/drivers/usb/misc/phidgetkit.c
index 4cfa25b0f44e..cc8e0a926f99 100644
--- a/drivers/usb/misc/phidgetkit.c
+++ b/drivers/usb/misc/phidgetkit.c
@@ -595,9 +595,8 @@ static int interfacekit_probe(struct usb_interface *intf, const struct usb_devic
} while(value);
kit->dev_no = bit;
- kit->dev = device_create_drvdata(phidget_class, &kit->udev->dev,
- MKDEV(0, 0), kit,
- "interfacekit%d", kit->dev_no);
+ kit->dev = device_create(phidget_class, &kit->udev->dev, MKDEV(0, 0),
+ kit, "interfacekit%d", kit->dev_no);
if (IS_ERR(kit->dev)) {
rc = PTR_ERR(kit->dev);
kit->dev = NULL;
diff --git a/drivers/usb/misc/phidgetmotorcontrol.c b/drivers/usb/misc/phidgetmotorcontrol.c
index 9b4696f21b22..38088b44349e 100644
--- a/drivers/usb/misc/phidgetmotorcontrol.c
+++ b/drivers/usb/misc/phidgetmotorcontrol.c
@@ -365,9 +365,8 @@ static int motorcontrol_probe(struct usb_interface *intf, const struct usb_devic
} while(value);
mc->dev_no = bit;
- mc->dev = device_create_drvdata(phidget_class, &mc->udev->dev,
- MKDEV(0, 0), mc,
- "motorcontrol%d", mc->dev_no);
+ mc->dev = device_create(phidget_class, &mc->udev->dev, MKDEV(0, 0), mc,
+ "motorcontrol%d", mc->dev_no);
if (IS_ERR(mc->dev)) {
rc = PTR_ERR(mc->dev);
mc->dev = NULL;
diff --git a/drivers/usb/misc/phidgetservo.c b/drivers/usb/misc/phidgetservo.c
index 1ca7ddb41d4d..bef6fe16364b 100644
--- a/drivers/usb/misc/phidgetservo.c
+++ b/drivers/usb/misc/phidgetservo.c
@@ -275,9 +275,8 @@ servo_probe(struct usb_interface *interface, const struct usb_device_id *id)
} while (value);
dev->dev_no = bit;
- dev->dev = device_create_drvdata(phidget_class, &dev->udev->dev,
- MKDEV(0, 0), dev,
- "servo%d", dev->dev_no);
+ dev->dev = device_create(phidget_class, &dev->udev->dev, MKDEV(0, 0),
+ dev, "servo%d", dev->dev_no);
if (IS_ERR(dev->dev)) {
rc = PTR_ERR(dev->dev);
dev->dev = NULL;
diff --git a/drivers/usb/mon/mon_bin.c b/drivers/usb/mon/mon_bin.c
index 6566fc0a3228..c9de3f027aab 100644
--- a/drivers/usb/mon/mon_bin.c
+++ b/drivers/usb/mon/mon_bin.c
@@ -1162,9 +1162,9 @@ int mon_bin_add(struct mon_bus *mbus, const struct usb_bus *ubus)
if (minor >= MON_BIN_MAX_MINOR)
return 0;
- dev = device_create_drvdata(mon_bin_class, ubus? ubus->controller: NULL,
- MKDEV(MAJOR(mon_bin_dev0), minor), NULL,
- "usbmon%d", minor);
+ dev = device_create(mon_bin_class, ubus ? ubus->controller : NULL,
+ MKDEV(MAJOR(mon_bin_dev0), minor), NULL,
+ "usbmon%d", minor);
if (IS_ERR(dev))
return 0;
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 93a080e827cc..64b3d30027b8 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -3573,8 +3573,8 @@ static int __init fb_console_init(void)
acquire_console_sem();
fb_register_client(&fbcon_event_notifier);
- fbcon_device = device_create_drvdata(fb_class, NULL, MKDEV(0, 0),
- NULL, "fbcon");
+ fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), NULL,
+ "fbcon");
if (IS_ERR(fbcon_device)) {
printk(KERN_WARNING "Unable to create device "
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c
index 6ef800bdf482..4830b1bf51e5 100644
--- a/drivers/video/display/display-sysfs.c
+++ b/drivers/video/display/display-sysfs.c
@@ -153,12 +153,9 @@ struct display_device *display_device_register(struct display_driver *driver,
mutex_unlock(&allocated_dsp_lock);
if (!ret) {
- new_dev->dev = device_create_drvdata(display_class,
- parent,
- MKDEV(0,0),
- new_dev,
- "display%d",
- new_dev->idx);
+ new_dev->dev = device_create(display_class, parent,
+ MKDEV(0, 0), new_dev,
+ "display%d", new_dev->idx);
if (!IS_ERR(new_dev->dev)) {
new_dev->parent = parent;
new_dev->driver = driver;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 3f18bb9abad0..217c5118ae9e 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1430,9 +1430,8 @@ register_framebuffer(struct fb_info *fb_info)
break;
fb_info->node = i;
- fb_info->dev = device_create_drvdata(fb_class, fb_info->device,
- MKDEV(FB_MAJOR, i), NULL,
- "fb%d", i);
+ fb_info->dev = device_create(fb_class, fb_info->device,
+ MKDEV(FB_MAJOR, i), NULL, "fb%d", i);
if (IS_ERR(fb_info->dev)) {
/* Not fatal */
printk(KERN_WARNING "Unable to create device for framebuffer %d; errno = %ld\n", i, PTR_ERR(fb_info->dev));
diff --git a/fs/coda/psdev.c b/fs/coda/psdev.c
index 0d9b80ec689c..cfd29da714d1 100644
--- a/fs/coda/psdev.c
+++ b/fs/coda/psdev.c
@@ -362,9 +362,8 @@ static int init_coda_psdev(void)
goto out_chrdev;
}
for (i = 0; i < MAX_CODADEVS; i++)
- device_create_drvdata(coda_psdev_class, NULL,
- MKDEV(CODA_PSDEV_MAJOR, i),
- NULL, "cfs%d", i);
+ device_create(coda_psdev_class, NULL,
+ MKDEV(CODA_PSDEV_MAJOR, i), NULL, "cfs%d", i);
coda_sysctl_init();
goto out;
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c
index 006fc64227dd..66f6e58a7e4b 100644
--- a/fs/sysfs/bin.c
+++ b/fs/sysfs/bin.c
@@ -61,6 +61,7 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
int size = dentry->d_inode->i_size;
loff_t offs = *off;
int count = min_t(size_t, bytes, PAGE_SIZE);
+ char *temp;
if (size) {
if (offs > size)
@@ -69,23 +70,33 @@ read(struct file *file, char __user *userbuf, size_t bytes, loff_t *off)
count = size - offs;
}
+ temp = kmalloc(count, GFP_KERNEL);
+ if (!temp)
+ return -ENOMEM;
+
mutex_lock(&bb->mutex);
count = fill_read(dentry, bb->buffer, offs, count);
- if (count < 0)
- goto out_unlock;
+ if (count < 0) {
+ mutex_unlock(&bb->mutex);
+ goto out_free;
+ }
- if (copy_to_user(userbuf, bb->buffer, count)) {
+ memcpy(temp, bb->buffer, count);
+
+ mutex_unlock(&bb->mutex);
+
+ if (copy_to_user(userbuf, temp, count)) {
count = -EFAULT;
- goto out_unlock;
+ goto out_free;
}
pr_debug("offs = %lld, *off = %lld, count = %d\n", offs, *off, count);
*off = offs + count;
- out_unlock:
- mutex_unlock(&bb->mutex);
+ out_free:
+ kfree(temp);
return count;
}
@@ -118,6 +129,7 @@ static ssize_t write(struct file *file, const char __user *userbuf,
int size = dentry->d_inode->i_size;
loff_t offs = *off;
int count = min_t(size_t, bytes, PAGE_SIZE);
+ char *temp;
if (size) {
if (offs > size)
@@ -126,19 +138,27 @@ static ssize_t write(struct file *file, const char __user *userbuf,
count = size - offs;
}
- mutex_lock(&bb->mutex);
+ temp = kmalloc(count, GFP_KERNEL);
+ if (!temp)
+ return -ENOMEM;
- if (copy_from_user(bb->buffer, userbuf, count)) {
+ if (copy_from_user(temp, userbuf, count)) {
count = -EFAULT;
- goto out_unlock;
+ goto out_free;
}
+ mutex_lock(&bb->mutex);
+
+ memcpy(bb->buffer, temp, count);
+
count = flush_write(dentry, bb->buffer, offs, count);
+ mutex_unlock(&bb->mutex);
+
if (count > 0)
*off = offs + count;
- out_unlock:
- mutex_unlock(&bb->mutex);
+out_free:
+ kfree(temp);
return count;
}
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index aedaeba82ae5..3a05a596e3b4 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -370,17 +370,17 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
memset(acxt, 0, sizeof(*acxt));
acxt->parent_sd = parent_sd;
- /* Lookup parent inode. inode initialization and I_NEW
- * clearing are protected by sysfs_mutex. By grabbing it and
- * looking up with _nowait variant, inode state can be
- * determined reliably.
+ /* Lookup parent inode. inode initialization is protected by
+ * sysfs_mutex, so inode existence can be determined by
+ * looking up inode while holding sysfs_mutex.
*/
mutex_lock(&sysfs_mutex);
- inode = ilookup5_nowait(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
- parent_sd);
+ inode = ilookup5(sysfs_sb, parent_sd->s_ino, sysfs_ilookup_test,
+ parent_sd);
+ if (inode) {
+ WARN_ON(inode->i_state & I_NEW);
- if (inode && !(inode->i_state & I_NEW)) {
/* parent inode available */
acxt->parent_inode = inode;
@@ -393,8 +393,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
mutex_lock(&inode->i_mutex);
mutex_lock(&sysfs_mutex);
}
- } else
- iput(inode);
+ }
}
/**
@@ -636,6 +635,7 @@ struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
return sd;
}
+EXPORT_SYMBOL_GPL(sysfs_get_dirent);
static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd,
const char *name, struct sysfs_dirent **p_sd)
@@ -829,16 +829,12 @@ int sysfs_rename_dir(struct kobject * kobj, const char *new_name)
if (!new_dentry)
goto out_unlock;
- /* rename kobject and sysfs_dirent */
+ /* rename sysfs_dirent */
error = -ENOMEM;
new_name = dup_name = kstrdup(new_name, GFP_KERNEL);
if (!new_name)
goto out_unlock;
- error = kobject_set_name(kobj, "%s", new_name);
- if (error)
- goto out_unlock;
-
dup_name = sd->s_name;
sd->s_name = new_name;
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index c9e4e5091da1..1f4a3f877262 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -19,10 +19,18 @@
#include <linux/poll.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/limits.h>
#include <asm/uaccess.h>
#include "sysfs.h"
+/* used in crash dumps to help with debugging */
+static char last_sysfs_file[PATH_MAX];
+void sysfs_printk_last_file(void)
+{
+ printk(KERN_EMERG "last sysfs file: %s\n", last_sysfs_file);
+}
+
/*
* There's one sysfs_buffer for each open file and one
* sysfs_open_dirent for each sysfs_dirent with one or more open
@@ -328,6 +336,11 @@ static int sysfs_open_file(struct inode *inode, struct file *file)
struct sysfs_buffer *buffer;
struct sysfs_ops *ops;
int error = -EACCES;
+ char *p;
+
+ p = d_path(&file->f_path, last_sysfs_file, sizeof(last_sysfs_file));
+ if (p)
+ memmove(last_sysfs_file, p, strlen(p) + 1);
/* need attr_sd for attr and ops, its parent for kobj */
if (!sysfs_get_active_two(attr_sd))
@@ -440,7 +453,23 @@ static unsigned int sysfs_poll(struct file *filp, poll_table *wait)
return POLLERR|POLLPRI;
}
-void sysfs_notify(struct kobject *k, char *dir, char *attr)
+void sysfs_notify_dirent(struct sysfs_dirent *sd)
+{
+ struct sysfs_open_dirent *od;
+
+ spin_lock(&sysfs_open_dirent_lock);
+
+ od = sd->s_attr.open;
+ if (od) {
+ atomic_inc(&od->event);
+ wake_up_interruptible(&od->poll);
+ }
+
+ spin_unlock(&sysfs_open_dirent_lock);
+}
+EXPORT_SYMBOL_GPL(sysfs_notify_dirent);
+
+void sysfs_notify(struct kobject *k, const char *dir, const char *attr)
{
struct sysfs_dirent *sd = k->sd;
@@ -450,19 +479,8 @@ void sysfs_notify(struct kobject *k, char *dir, char *attr)
sd = sysfs_find_dirent(sd, dir);
if (sd && attr)
sd = sysfs_find_dirent(sd, attr);
- if (sd) {
- struct sysfs_open_dirent *od;
-
- spin_lock(&sysfs_open_dirent_lock);
-
- od = sd->s_attr.open;
- if (od) {
- atomic_inc(&od->event);
- wake_up_interruptible(&od->poll);
- }
-
- spin_unlock(&sysfs_open_dirent_lock);
- }
+ if (sd)
+ sysfs_notify_dirent(sd);
mutex_unlock(&sysfs_mutex);
}
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 14f0023984d7..ab343e371d64 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -16,6 +16,7 @@
#include <linux/mount.h>
#include <linux/pagemap.h>
#include <linux/init.h>
+#include <linux/module.h>
#include "sysfs.h"
@@ -115,3 +116,17 @@ out_err:
sysfs_dir_cachep = NULL;
goto out;
}
+
+#undef sysfs_get
+struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+{
+ return __sysfs_get(sd);
+}
+EXPORT_SYMBOL_GPL(sysfs_get);
+
+#undef sysfs_put
+void sysfs_put(struct sysfs_dirent *sd)
+{
+ __sysfs_put(sd);
+}
+EXPORT_SYMBOL_GPL(sysfs_put);
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
index a5db496f71c7..93c6d6b27c4d 100644
--- a/fs/sysfs/sysfs.h
+++ b/fs/sysfs/sysfs.h
@@ -124,7 +124,7 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name,
struct sysfs_dirent **p_sd);
void sysfs_remove_subdir(struct sysfs_dirent *sd);
-static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd)
{
if (sd) {
WARN_ON(!atomic_read(&sd->s_count));
@@ -132,12 +132,14 @@ static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
}
return sd;
}
+#define sysfs_get(sd) __sysfs_get(sd)
-static inline void sysfs_put(struct sysfs_dirent *sd)
+static inline void __sysfs_put(struct sysfs_dirent *sd)
{
if (sd && atomic_dec_and_test(&sd->s_count))
release_sysfs_dirent(sd);
}
+#define sysfs_put(sd) __sysfs_put(sd)
/*
* inode.c
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index 7440a0dceddb..74c5faf26c05 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -268,7 +268,15 @@
CPU_DISCARD(init.data) \
CPU_DISCARD(init.rodata) \
MEM_DISCARD(init.data) \
- MEM_DISCARD(init.rodata)
+ MEM_DISCARD(init.rodata) \
+ /* implement dynamic printk debug */ \
+ VMLINUX_SYMBOL(__start___verbose_strings) = .; \
+ *(__verbose_strings) \
+ VMLINUX_SYMBOL(__stop___verbose_strings) = .; \
+ . = ALIGN(8); \
+ VMLINUX_SYMBOL(__start___verbose) = .; \
+ *(__verbose) \
+ VMLINUX_SYMBOL(__stop___verbose) = .;
#define INIT_TEXT \
*(.init.text) \
diff --git a/include/linux/device.h b/include/linux/device.h
index 246937c9cbc7..987f5912720a 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -90,6 +90,9 @@ int __must_check bus_for_each_drv(struct bus_type *bus,
struct device_driver *start, void *data,
int (*fn)(struct device_driver *, void *));
+void bus_sort_breadthfirst(struct bus_type *bus,
+ int (*compare)(const struct device *a,
+ const struct device *b));
/*
* Bus notifiers: Get notified of addition/removal of devices
* and binding/unbinding of drivers to devices.
@@ -502,7 +505,6 @@ extern struct device *device_create(struct class *cls, struct device *parent,
dev_t devt, void *drvdata,
const char *fmt, ...)
__attribute__((format(printf, 5, 6)));
-#define device_create_drvdata device_create
extern void device_destroy(struct class *cls, dev_t devt);
/*
@@ -551,7 +553,11 @@ extern const char *dev_driver_string(const struct device *dev);
#define dev_info(dev, format, arg...) \
dev_printk(KERN_INFO , dev , format , ## arg)
-#ifdef DEBUG
+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+#define dev_dbg(dev, format, ...) do { \
+ dynamic_dev_dbg(dev, format, ##__VA_ARGS__); \
+ } while (0)
+#elif defined(DEBUG)
#define dev_dbg(dev, format, arg...) \
dev_printk(KERN_DEBUG , dev , format , ## arg)
#else
@@ -567,6 +573,14 @@ extern const char *dev_driver_string(const struct device *dev);
({ if (0) dev_printk(KERN_DEBUG, dev, format, ##arg); 0; })
#endif
+/*
+ * dev_WARN() acts like dev_printk(), but with the key difference
+ * of using a WARN/WARN_ON to get the message out, including the
+ * file/line information and a backtrace.
+ */
+#define dev_WARN(dev, format, arg...) \
+ WARN(1, "Device: %s\n" format, dev_driver_string(dev), ## arg);
+
/* Create alias, so I can be autoloaded. */
#define MODULE_ALIAS_CHARDEV(major,minor) \
MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor))
diff --git a/include/linux/dynamic_printk.h b/include/linux/dynamic_printk.h
new file mode 100644
index 000000000000..2d528d009074
--- /dev/null
+++ b/include/linux/dynamic_printk.h
@@ -0,0 +1,93 @@
+#ifndef _DYNAMIC_PRINTK_H
+#define _DYNAMIC_PRINTK_H
+
+#define DYNAMIC_DEBUG_HASH_BITS 6
+#define DEBUG_HASH_TABLE_SIZE (1 << DYNAMIC_DEBUG_HASH_BITS)
+
+#define TYPE_BOOLEAN 1
+
+#define DYNAMIC_ENABLED_ALL 0
+#define DYNAMIC_ENABLED_NONE 1
+#define DYNAMIC_ENABLED_SOME 2
+
+extern int dynamic_enabled;
+
+/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
+ * use independent hash functions, to reduce the chance of false positives.
+ */
+extern long long dynamic_printk_enabled;
+extern long long dynamic_printk_enabled2;
+
+struct mod_debug {
+ char *modname;
+ char *logical_modname;
+ char *flag_names;
+ int type;
+ int hash;
+ int hash2;
+} __attribute__((aligned(8)));
+
+int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
+ char *flags, int hash, int hash2);
+
+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+extern int unregister_dynamic_debug_module(char *mod_name);
+extern int __dynamic_dbg_enabled_helper(char *modname, int type,
+ int value, int hash);
+
+#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ \
+ int __ret = 0; \
+ if (unlikely((dynamic_printk_enabled & (1LL << DEBUG_HASH)) && \
+ (dynamic_printk_enabled2 & (1LL << DEBUG_HASH2)))) \
+ __ret = __dynamic_dbg_enabled_helper(module, type, \
+ value, hash);\
+ __ret; })
+
+#define dynamic_pr_debug(fmt, ...) do { \
+ static char mod_name[] \
+ __attribute__((section("__verbose_strings"))) \
+ = KBUILD_MODNAME; \
+ static struct mod_debug descriptor \
+ __used \
+ __attribute__((section("__verbose"), aligned(8))) = \
+ { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
+ if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
+ 0, 0, DEBUG_HASH)) \
+ printk(KERN_DEBUG KBUILD_MODNAME ":" fmt, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#define dynamic_dev_dbg(dev, format, ...) do { \
+ static char mod_name[] \
+ __attribute__((section("__verbose_strings"))) \
+ = KBUILD_MODNAME; \
+ static struct mod_debug descriptor \
+ __used \
+ __attribute__((section("__verbose"), aligned(8))) = \
+ { mod_name, mod_name, NULL, TYPE_BOOLEAN, DEBUG_HASH, DEBUG_HASH2 };\
+ if (__dynamic_dbg_enabled(KBUILD_MODNAME, TYPE_BOOLEAN, \
+ 0, 0, DEBUG_HASH)) \
+ dev_printk(KERN_DEBUG, dev, \
+ KBUILD_MODNAME ": " format, \
+ ##__VA_ARGS__); \
+ } while (0)
+
+#else
+
+static inline int unregister_dynamic_debug_module(const char *mod_name)
+{
+ return 0;
+}
+static inline int __dynamic_dbg_enabled_helper(char *modname, int type,
+ int value, int hash)
+{
+ return 0;
+}
+
+#define __dynamic_dbg_enabled(module, type, value, level, hash) ({ 0; })
+#define dynamic_pr_debug(fmt, ...) do { } while (0)
+#define dynamic_dev_dbg(dev, format, ...) do { } while (0)
+#endif
+
+#endif
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index e971c55f45ac..1f3cd8ad0523 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -16,6 +16,7 @@
#include <linux/log2.h>
#include <linux/typecheck.h>
#include <linux/ratelimit.h>
+#include <linux/dynamic_printk.h>
#include <asm/byteorder.h>
#include <asm/bug.h>
@@ -304,8 +305,12 @@ static inline char *pack_hex_byte(char *buf, u8 byte)
#define pr_info(fmt, arg...) \
printk(KERN_INFO fmt, ##arg)
-#ifdef DEBUG
/* If you are writing a driver, please use dev_dbg instead */
+#if defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
+#define pr_debug(fmt, ...) do { \
+ dynamic_pr_debug(fmt, ##__VA_ARGS__); \
+ } while (0)
+#elif defined(DEBUG)
#define pr_debug(fmt, arg...) \
printk(KERN_DEBUG fmt, ##arg)
#else
diff --git a/include/linux/module.h b/include/linux/module.h
index 68e09557c951..a41555cbe00a 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -345,7 +345,6 @@ struct module
/* Reference counts */
struct module_ref ref[NR_CPUS];
#endif
-
};
#ifndef MODULE_ARCH_INIT
#define MODULE_ARCH_INIT {}
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 95ac21ab3a09..4b8cc6a32479 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -37,6 +37,8 @@ extern int platform_add_devices(struct platform_device **, int);
extern struct platform_device *platform_device_register_simple(const char *, int id,
struct resource *, unsigned int);
+extern struct platform_device *platform_device_register_data(struct device *,
+ const char *, int, const void *, size_t);
extern struct platform_device *platform_device_alloc(const char *name, int id);
extern int platform_device_add_resources(struct platform_device *pdev, struct resource *res, unsigned int num);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 37fa24152bd8..b330e289d71f 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -78,6 +78,8 @@ struct sysfs_ops {
ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t);
};
+struct sysfs_dirent;
+
#ifdef CONFIG_SYSFS
int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
@@ -117,9 +119,14 @@ int sysfs_add_file_to_group(struct kobject *kobj,
void sysfs_remove_file_from_group(struct kobject *kobj,
const struct attribute *attr, const char *group);
-void sysfs_notify(struct kobject *kobj, char *dir, char *attr);
-
-extern int __must_check sysfs_init(void);
+void sysfs_notify(struct kobject *kobj, const char *dir, const char *attr);
+void sysfs_notify_dirent(struct sysfs_dirent *sd);
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name);
+struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd);
+void sysfs_put(struct sysfs_dirent *sd);
+void sysfs_printk_last_file(void);
+int __must_check sysfs_init(void);
#else /* CONFIG_SYSFS */
@@ -222,7 +229,24 @@ static inline void sysfs_remove_file_from_group(struct kobject *kobj,
{
}
-static inline void sysfs_notify(struct kobject *kobj, char *dir, char *attr)
+static inline void sysfs_notify(struct kobject *kobj, const char *dir,
+ const char *attr)
+{
+}
+static inline void sysfs_notify_dirent(struct sysfs_dirent *sd)
+{
+}
+static inline
+struct sysfs_dirent *sysfs_get_dirent(struct sysfs_dirent *parent_sd,
+ const unsigned char *name)
+{
+ return NULL;
+}
+static inline struct sysfs_dirent *sysfs_get(struct sysfs_dirent *sd)
+{
+ return NULL;
+}
+static inline void sysfs_put(struct sysfs_dirent *sd)
{
}
@@ -231,6 +255,10 @@ static inline int __must_check sysfs_init(void)
return 0;
}
+static inline void sysfs_printk_last_file(void)
+{
+}
+
#endif /* CONFIG_SYSFS */
#endif /* _SYSFS_H_ */
diff --git a/kernel/module.c b/kernel/module.c
index dd9ac6ad5cb9..b7205f67cfaf 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -784,6 +784,7 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
mutex_lock(&module_mutex);
/* Store the name of the last unloaded module for diagnostic purposes */
strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module));
+ unregister_dynamic_debug_module(mod->name);
free_module(mod);
out:
@@ -1173,7 +1174,7 @@ static void free_notes_attrs(struct module_notes_attrs *notes_attrs,
while (i-- > 0)
sysfs_remove_bin_file(notes_attrs->dir,
&notes_attrs->attrs[i]);
- kobject_del(notes_attrs->dir);
+ kobject_put(notes_attrs->dir);
}
kfree(notes_attrs);
}
@@ -1783,6 +1784,33 @@ static inline void add_kallsyms(struct module *mod,
}
#endif /* CONFIG_KALLSYMS */
+#ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
+static void dynamic_printk_setup(Elf_Shdr *sechdrs, unsigned int verboseindex)
+{
+ struct mod_debug *debug_info;
+ unsigned long pos, end;
+ unsigned int num_verbose;
+
+ pos = sechdrs[verboseindex].sh_addr;
+ num_verbose = sechdrs[verboseindex].sh_size /
+ sizeof(struct mod_debug);
+ end = pos + (num_verbose * sizeof(struct mod_debug));
+
+ for (; pos < end; pos += sizeof(struct mod_debug)) {
+ debug_info = (struct mod_debug *)pos;
+ register_dynamic_debug_module(debug_info->modname,
+ debug_info->type, debug_info->logical_modname,
+ debug_info->flag_names, debug_info->hash,
+ debug_info->hash2);
+ }
+}
+#else
+static inline void dynamic_printk_setup(Elf_Shdr *sechdrs,
+ unsigned int verboseindex)
+{
+}
+#endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */
+
static void *module_alloc_update_bounds(unsigned long size)
{
void *ret = module_alloc(size);
@@ -1831,6 +1859,7 @@ static noinline struct module *load_module(void __user *umod,
#endif
unsigned int markersindex;
unsigned int markersstringsindex;
+ unsigned int verboseindex;
struct module *mod;
long err = 0;
void *percpu = NULL, *ptr = NULL; /* Stops spurious gcc warning */
@@ -2117,6 +2146,7 @@ static noinline struct module *load_module(void __user *umod,
markersindex = find_sec(hdr, sechdrs, secstrings, "__markers");
markersstringsindex = find_sec(hdr, sechdrs, secstrings,
"__markers_strings");
+ verboseindex = find_sec(hdr, sechdrs, secstrings, "__verbose");
/* Now do relocations. */
for (i = 1; i < hdr->e_shnum; i++) {
@@ -2167,6 +2197,7 @@ static noinline struct module *load_module(void __user *umod,
marker_update_probe_range(mod->markers,
mod->markers + mod->num_markers);
#endif
+ dynamic_printk_setup(sechdrs, verboseindex);
err = module_finalize(hdr, sechdrs, mod);
if (err < 0)
goto cleanup;
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index aa81d2848448..31d784dd80d0 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -807,6 +807,61 @@ menuconfig BUILD_DOCSRC
Say N if you are unsure.
+config DYNAMIC_PRINTK_DEBUG
+ bool "Enable dynamic printk() call support"
+ default n
+ depends on PRINTK
+ select PRINTK_DEBUG
+ help
+
+ Compiles debug level messages into the kernel, which would not
+ otherwise be available at runtime. These messages can then be
+ enabled/disabled on a per module basis. This mechanism implicitly
+ enables all pr_debug() and dev_dbg() calls. The impact of this
+ compile option is a larger kernel text size of about 2%.
+
+ Usage:
+
+ Dynamic debugging is controlled by the debugfs file,
+ dynamic_printk/modules. This file contains a list of the modules that
+ can be enabled. The format of the file is the module name, followed
+ by a set of flags that can be enabled. The first flag is always the
+ 'enabled' flag. For example:
+
+ <module_name> <enabled=0/1>
+ .
+ .
+ .
+
+ <module_name> : Name of the module in which the debug call resides
+ <enabled=0/1> : whether the messages are enabled or not
+
+ From a live system:
+
+ snd_hda_intel enabled=0
+ fixup enabled=0
+ driver enabled=0
+
+ Enable a module:
+
+ $echo "set enabled=1 <module_name>" > dynamic_printk/modules
+
+ Disable a module:
+
+ $echo "set enabled=0 <module_name>" > dynamic_printk/modules
+
+ Enable all modules:
+
+ $echo "set enabled=1 all" > dynamic_printk/modules
+
+ Disable all modules:
+
+ $echo "set enabled=0 all" > dynamic_printk/modules
+
+ Finally, passing "dynamic_printk" at the command line enables
+ debugging for all modules. This mode can be turned off via the above
+ disable command.
+
source "samples/Kconfig"
source "lib/Kconfig.kgdb"
diff --git a/lib/Makefile b/lib/Makefile
index 44001af76a7d..16feaab057b2 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -81,6 +81,8 @@ obj-$(CONFIG_HAVE_LMB) += lmb.o
obj-$(CONFIG_HAVE_ARCH_TRACEHOOK) += syscall.o
+obj-$(CONFIG_DYNAMIC_PRINTK_DEBUG) += dynamic_printk.o
+
hostprogs-y := gen_crc32table
clean-files := crc32table.h
diff --git a/lib/dynamic_printk.c b/lib/dynamic_printk.c
new file mode 100644
index 000000000000..d640f87bdc9e
--- /dev/null
+++ b/lib/dynamic_printk.c
@@ -0,0 +1,418 @@
+/*
+ * lib/dynamic_printk.c
+ *
+ * make pr_debug()/dev_dbg() calls runtime configurable based upon their
+ * their source module.
+ *
+ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/uaccess.h>
+#include <linux/seq_file.h>
+#include <linux/debugfs.h>
+#include <linux/fs.h>
+
+extern struct mod_debug __start___verbose[];
+extern struct mod_debug __stop___verbose[];
+
+struct debug_name {
+ struct hlist_node hlist;
+ struct hlist_node hlist2;
+ int hash1;
+ int hash2;
+ char *name;
+ int enable;
+ int type;
+};
+
+static int nr_entries;
+static int num_enabled;
+int dynamic_enabled = DYNAMIC_ENABLED_NONE;
+static struct hlist_head module_table[DEBUG_HASH_TABLE_SIZE] =
+ { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
+static struct hlist_head module_table2[DEBUG_HASH_TABLE_SIZE] =
+ { [0 ... DEBUG_HASH_TABLE_SIZE-1] = HLIST_HEAD_INIT };
+static DECLARE_MUTEX(debug_list_mutex);
+
+/* dynamic_printk_enabled, and dynamic_printk_enabled2 are bitmasks in which
+ * bit n is set to 1 if any modname hashes into the bucket n, 0 otherwise. They
+ * use independent hash functions, to reduce the chance of false positives.
+ */
+long long dynamic_printk_enabled;
+EXPORT_SYMBOL_GPL(dynamic_printk_enabled);
+long long dynamic_printk_enabled2;
+EXPORT_SYMBOL_GPL(dynamic_printk_enabled2);
+
+/* returns the debug module pointer. */
+static struct debug_name *find_debug_module(char *module_name)
+{
+ int i;
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct debug_name *element;
+
+ element = NULL;
+ for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
+ head = &module_table[i];
+ hlist_for_each_entry_rcu(element, node, head, hlist)
+ if (!strcmp(element->name, module_name))
+ return element;
+ }
+ return NULL;
+}
+
+/* returns the debug module pointer. */
+static struct debug_name *find_debug_module_hash(char *module_name, int hash)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct debug_name *element;
+
+ element = NULL;
+ head = &module_table[hash];
+ hlist_for_each_entry_rcu(element, node, head, hlist)
+ if (!strcmp(element->name, module_name))
+ return element;
+ return NULL;
+}
+
+/* caller must hold mutex*/
+static int __add_debug_module(char *mod_name, int hash, int hash2)
+{
+ struct debug_name *new;
+ char *module_name;
+ int ret = 0;
+
+ if (find_debug_module(mod_name)) {
+ ret = -EINVAL;
+ goto out;
+ }
+ module_name = kmalloc(strlen(mod_name) + 1, GFP_KERNEL);
+ if (!module_name) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ module_name = strcpy(module_name, mod_name);
+ module_name[strlen(mod_name)] = '\0';
+ new = kzalloc(sizeof(struct debug_name), GFP_KERNEL);
+ if (!new) {
+ kfree(module_name);
+ ret = -ENOMEM;
+ goto out;
+ }
+ INIT_HLIST_NODE(&new->hlist);
+ INIT_HLIST_NODE(&new->hlist2);
+ new->name = module_name;
+ new->hash1 = hash;
+ new->hash2 = hash2;
+ hlist_add_head_rcu(&new->hlist, &module_table[hash]);
+ hlist_add_head_rcu(&new->hlist2, &module_table2[hash2]);
+ nr_entries++;
+out:
+ return ret;
+}
+
+int unregister_dynamic_debug_module(char *mod_name)
+{
+ struct debug_name *element;
+ int ret = 0;
+
+ down(&debug_list_mutex);
+ element = find_debug_module(mod_name);
+ if (!element) {
+ ret = -EINVAL;
+ goto out;
+ }
+ hlist_del_rcu(&element->hlist);
+ hlist_del_rcu(&element->hlist2);
+ synchronize_rcu();
+ kfree(element->name);
+ if (element->enable)
+ num_enabled--;
+ kfree(element);
+ nr_entries--;
+out:
+ up(&debug_list_mutex);
+ return 0;
+}
+EXPORT_SYMBOL_GPL(unregister_dynamic_debug_module);
+
+int register_dynamic_debug_module(char *mod_name, int type, char *share_name,
+ char *flags, int hash, int hash2)
+{
+ struct debug_name *elem;
+ int ret = 0;
+
+ down(&debug_list_mutex);
+ elem = find_debug_module(mod_name);
+ if (!elem) {
+ if (__add_debug_module(mod_name, hash, hash2))
+ goto out;
+ elem = find_debug_module(mod_name);
+ if (dynamic_enabled == DYNAMIC_ENABLED_ALL &&
+ !strcmp(mod_name, share_name)) {
+ elem->enable = true;
+ num_enabled++;
+ }
+ }
+ elem->type |= type;
+out:
+ up(&debug_list_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(register_dynamic_debug_module);
+
+int __dynamic_dbg_enabled_helper(char *mod_name, int type, int value, int hash)
+{
+ struct debug_name *elem;
+ int ret = 0;
+
+ if (dynamic_enabled == DYNAMIC_ENABLED_ALL)
+ return 1;
+ rcu_read_lock();
+ elem = find_debug_module_hash(mod_name, hash);
+ if (elem && elem->enable)
+ ret = 1;
+ rcu_read_unlock();
+ return ret;
+}
+EXPORT_SYMBOL_GPL(__dynamic_dbg_enabled_helper);
+
+static void set_all(bool enable)
+{
+ struct debug_name *e;
+ struct hlist_node *node;
+ int i;
+ long long enable_mask;
+
+ for (i = 0; i < DEBUG_HASH_TABLE_SIZE; i++) {
+ if (module_table[i].first != NULL) {
+ hlist_for_each_entry(e, node, &module_table[i], hlist) {
+ e->enable = enable;
+ }
+ }
+ }
+ if (enable)
+ enable_mask = ULLONG_MAX;
+ else
+ enable_mask = 0;
+ dynamic_printk_enabled = enable_mask;
+ dynamic_printk_enabled2 = enable_mask;
+}
+
+static int disabled_hash(int i, bool first_table)
+{
+ struct debug_name *e;
+ struct hlist_node *node;
+
+ if (first_table) {
+ hlist_for_each_entry(e, node, &module_table[i], hlist) {
+ if (e->enable)
+ return 0;
+ }
+ } else {
+ hlist_for_each_entry(e, node, &module_table2[i], hlist2) {
+ if (e->enable)
+ return 0;
+ }
+ }
+ return 1;
+}
+
+static ssize_t pr_debug_write(struct file *file, const char __user *buf,
+ size_t length, loff_t *ppos)
+{
+ char *buffer, *s, *value_str, *setting_str;
+ int err, value;
+ struct debug_name *elem = NULL;
+ int all = 0;
+
+ if (length > PAGE_SIZE || length < 0)
+ return -EINVAL;
+
+ buffer = (char *)__get_free_page(GFP_KERNEL);
+ if (!buffer)
+ return -ENOMEM;
+
+ err = -EFAULT;
+ if (copy_from_user(buffer, buf, length))
+ goto out;
+
+ err = -EINVAL;
+ if (length < PAGE_SIZE)
+ buffer[length] = '\0';
+ else if (buffer[PAGE_SIZE-1])
+ goto out;
+
+ err = -EINVAL;
+ down(&debug_list_mutex);
+
+ if (strncmp("set", buffer, 3))
+ goto out_up;
+ s = buffer + 3;
+ setting_str = strsep(&s, "=");
+ if (s == NULL)
+ goto out_up;
+ setting_str = strstrip(setting_str);
+ value_str = strsep(&s, " ");
+ if (s == NULL)
+ goto out_up;
+ s = strstrip(s);
+ if (!strncmp(s, "all", 3))
+ all = 1;
+ else
+ elem = find_debug_module(s);
+ if (!strncmp(setting_str, "enable", 6)) {
+ value = !!simple_strtol(value_str, NULL, 10);
+ if (all) {
+ if (value) {
+ set_all(true);
+ num_enabled = nr_entries;
+ dynamic_enabled = DYNAMIC_ENABLED_ALL;
+ } else {
+ set_all(false);
+ num_enabled = 0;
+ dynamic_enabled = DYNAMIC_ENABLED_NONE;
+ }
+ err = 0;
+ } else {
+ if (elem) {
+ if (value && (elem->enable == 0)) {
+ dynamic_printk_enabled |=
+ (1LL << elem->hash1);
+ dynamic_printk_enabled2 |=
+ (1LL << elem->hash2);
+ elem->enable = 1;
+ num_enabled++;
+ dynamic_enabled = DYNAMIC_ENABLED_SOME;
+ err = 0;
+ printk(KERN_DEBUG
+ "debugging enabled for module %s",
+ elem->name);
+ } else if (!value && (elem->enable == 1)) {
+ elem->enable = 0;
+ num_enabled--;
+ if (disabled_hash(elem->hash1, true))
+ dynamic_printk_enabled &=
+ ~(1LL << elem->hash1);
+ if (disabled_hash(elem->hash2, false))
+ dynamic_printk_enabled2 &=
+ ~(1LL << elem->hash2);
+ if (num_enabled)
+ dynamic_enabled =
+ DYNAMIC_ENABLED_SOME;
+ else
+ dynamic_enabled =
+ DYNAMIC_ENABLED_NONE;
+ err = 0;
+ printk(KERN_DEBUG
+ "debugging disabled for module "
+ "%s", elem->name);
+ }
+ }
+ }
+ }
+ if (!err)
+ err = length;
+out_up:
+ up(&debug_list_mutex);
+out:
+ free_page((unsigned long)buffer);
+ return err;
+}
+
+static void *pr_debug_seq_start(struct seq_file *f, loff_t *pos)
+{
+ return (*pos < DEBUG_HASH_TABLE_SIZE) ? pos : NULL;
+}
+
+static void *pr_debug_seq_next(struct seq_file *s, void *v, loff_t *pos)
+{
+ (*pos)++;
+ if (*pos >= DEBUG_HASH_TABLE_SIZE)
+ return NULL;
+ return pos;
+}
+
+static void pr_debug_seq_stop(struct seq_file *s, void *v)
+{
+ /* Nothing to do */
+}
+
+static int pr_debug_seq_show(struct seq_file *s, void *v)
+{
+ struct hlist_head *head;
+ struct hlist_node *node;
+ struct debug_name *elem;
+ unsigned int i = *(loff_t *) v;
+
+ rcu_read_lock();
+ head = &module_table[i];
+ hlist_for_each_entry_rcu(elem, node, head, hlist) {
+ seq_printf(s, "%s enabled=%d", elem->name, elem->enable);
+ seq_printf(s, "\n");
+ }
+ rcu_read_unlock();
+ return 0;
+}
+
+static struct seq_operations pr_debug_seq_ops = {
+ .start = pr_debug_seq_start,
+ .next = pr_debug_seq_next,
+ .stop = pr_debug_seq_stop,
+ .show = pr_debug_seq_show
+};
+
+static int pr_debug_open(struct inode *inode, struct file *filp)
+{
+ return seq_open(filp, &pr_debug_seq_ops);
+}
+
+static const struct file_operations pr_debug_operations = {
+ .open = pr_debug_open,
+ .read = seq_read,
+ .write = pr_debug_write,
+ .llseek = seq_lseek,
+ .release = seq_release,
+};
+
+static int __init dynamic_printk_init(void)
+{
+ struct dentry *dir, *file;
+ struct mod_debug *iter;
+ unsigned long value;
+
+ dir = debugfs_create_dir("dynamic_printk", NULL);
+ if (!dir)
+ return -ENOMEM;
+ file = debugfs_create_file("modules", 0644, dir, NULL,
+ &pr_debug_operations);
+ if (!file) {
+ debugfs_remove(dir);
+ return -ENOMEM;
+ }
+ for (value = (unsigned long)__start___verbose;
+ value < (unsigned long)__stop___verbose;
+ value += sizeof(struct mod_debug)) {
+ iter = (struct mod_debug *)value;
+ register_dynamic_debug_module(iter->modname,
+ iter->type,
+ iter->logical_modname,
+ iter->flag_names, iter->hash, iter->hash2);
+ }
+ return 0;
+}
+module_init(dynamic_printk_init);
+/* may want to move this earlier so we can get traces as early as possible */
+
+static int __init dynamic_printk_setup(char *str)
+{
+ if (str)
+ return -ENOENT;
+ set_all(true);
+ return 0;
+}
+/* Use early_param(), so we can get debug output as early as possible */
+early_param("dynamic_printk", dynamic_printk_setup);
diff --git a/lib/kobject.c b/lib/kobject.c
index fbf0ae282376..0487d1f64806 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -387,11 +387,17 @@ EXPORT_SYMBOL_GPL(kobject_init_and_add);
* kobject_rename - change the name of an object
* @kobj: object in question.
* @new_name: object's new name
+ *
+ * It is the responsibility of the caller to provide mutual
+ * exclusion between two different calls of kobject_rename
+ * on the same kobject and to ensure that new_name is valid and
+ * won't conflict with other kobjects.
*/
int kobject_rename(struct kobject *kobj, const char *new_name)
{
int error = 0;
const char *devpath = NULL;
+ const char *dup_name = NULL, *name;
char *devpath_string = NULL;
char *envp[2];
@@ -401,19 +407,6 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
if (!kobj->parent)
return -EINVAL;
- /* see if this name is already in use */
- if (kobj->kset) {
- struct kobject *temp_kobj;
- temp_kobj = kset_find_obj(kobj->kset, new_name);
- if (temp_kobj) {
- printk(KERN_WARNING "kobject '%s' cannot be renamed "
- "to '%s' as '%s' is already in existence.\n",
- kobject_name(kobj), new_name, new_name);
- kobject_put(temp_kobj);
- return -EINVAL;
- }
- }
-
devpath = kobject_get_path(kobj, GFP_KERNEL);
if (!devpath) {
error = -ENOMEM;
@@ -428,15 +421,27 @@ int kobject_rename(struct kobject *kobj, const char *new_name)
envp[0] = devpath_string;
envp[1] = NULL;
+ name = dup_name = kstrdup(new_name, GFP_KERNEL);
+ if (!name) {
+ error = -ENOMEM;
+ goto out;
+ }
+
error = sysfs_rename_dir(kobj, new_name);
+ if (error)
+ goto out;
+
+ /* Install the new kobject name */
+ dup_name = kobj->name;
+ kobj->name = name;
/* This function is mostly/only used for network interface.
* Some hotplug package track interfaces by their name and
* therefore want to know when the name is changed by the user. */
- if (!error)
- kobject_uevent_env(kobj, KOBJ_MOVE, envp);
+ kobject_uevent_env(kobj, KOBJ_MOVE, envp);
out:
+ kfree(dup_name);
kfree(devpath_string);
kfree(devpath);
kobject_put(kobj);
diff --git a/net/netfilter/nf_conntrack_pptp.c b/net/netfilter/nf_conntrack_pptp.c
index 373e51e91ce5..1bc3001d1827 100644
--- a/net/netfilter/nf_conntrack_pptp.c
+++ b/net/netfilter/nf_conntrack_pptp.c
@@ -65,7 +65,7 @@ void
struct nf_conntrack_expect *exp) __read_mostly;
EXPORT_SYMBOL_GPL(nf_nat_pptp_hook_expectfn);
-#ifdef DEBUG
+#if defined(DEBUG) || defined(CONFIG_DYNAMIC_PRINTK_DEBUG)
/* PptpControlMessageType names */
const char *const pptp_msg_name[] = {
"UNKNOWN_MESSAGE",
diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib
index ea48b82a3707..b4ca38a21158 100644
--- a/scripts/Makefile.lib
+++ b/scripts/Makefile.lib
@@ -96,6 +96,14 @@ basename_flags = -D"KBUILD_BASENAME=KBUILD_STR($(call name-fix,$(basetarget)))"
modname_flags = $(if $(filter 1,$(words $(modname))),\
-D"KBUILD_MODNAME=KBUILD_STR($(call name-fix,$(modname)))")
+#hash values
+ifdef CONFIG_DYNAMIC_PRINTK_DEBUG
+debug_flags = -D"DEBUG_HASH=$(shell ./scripts/basic/hash djb2 $(@D)$(modname))"\
+ -D"DEBUG_HASH2=$(shell ./scripts/basic/hash r5 $(@D)$(modname))"
+else
+debug_flags =
+endif
+
orig_c_flags = $(KBUILD_CFLAGS) $(ccflags-y) $(CFLAGS_$(basetarget).o)
_c_flags = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags))
_a_flags = $(KBUILD_AFLAGS) $(asflags-y) $(AFLAGS_$(basetarget).o)
@@ -121,7 +129,8 @@ endif
c_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
$(__c_flags) $(modkern_cflags) \
- -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags)
+ -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) \
+ $(debug_flags)
a_flags = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) \
$(__a_flags) $(modkern_aflags)
diff --git a/scripts/basic/Makefile b/scripts/basic/Makefile
index 4c324a1f1e0e..09559951df12 100644
--- a/scripts/basic/Makefile
+++ b/scripts/basic/Makefile
@@ -9,7 +9,7 @@
# fixdep: Used to generate dependency information during build process
# docproc: Used in Documentation/DocBook
-hostprogs-y := fixdep docproc
+hostprogs-y := fixdep docproc hash
always := $(hostprogs-y)
# fixdep is needed to compile other host programs
diff --git a/scripts/basic/hash.c b/scripts/basic/hash.c
new file mode 100644
index 000000000000..3299ad7fc8c0
--- /dev/null
+++ b/scripts/basic/hash.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 Red Hat, Inc., Jason Baron <jbaron@redhat.com>
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define DYNAMIC_DEBUG_HASH_BITS 6
+
+static const char *program;
+
+static void usage(void)
+{
+ printf("Usage: %s <djb2|r5> <modname>\n", program);
+ exit(1);
+}
+
+/* djb2 hashing algorithm by Dan Bernstein. From:
+ * http://www.cse.yorku.ca/~oz/hash.html
+ */
+
+unsigned int djb2_hash(char *str)
+{
+ unsigned long hash = 5381;
+ int c;
+
+ c = *str;
+ while (c) {
+ hash = ((hash << 5) + hash) + c;
+ c = *++str;
+ }
+ return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
+}
+
+unsigned int r5_hash(char *str)
+{
+ unsigned long hash = 0;
+ int c;
+
+ c = *str;
+ while (c) {
+ hash = (hash + (c << 4) + (c >> 4)) * 11;
+ c = *++str;
+ }
+ return (unsigned int)(hash & ((1 << DYNAMIC_DEBUG_HASH_BITS) - 1));
+}
+
+int main(int argc, char *argv[])
+{
+ program = argv[0];
+
+ if (argc != 3)
+ usage();
+ if (!strcmp(argv[1], "djb2"))
+ printf("%d\n", djb2_hash(argv[2]));
+ else if (!strcmp(argv[1], "r5"))
+ printf("%d\n", r5_hash(argv[2]));
+ else
+ usage();
+ exit(0);
+}
+
diff --git a/sound/core/init.c b/sound/core/init.c
index 8af467df9245..ef2352c2e451 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -549,9 +549,9 @@ int snd_card_register(struct snd_card *card)
return -EINVAL;
#ifndef CONFIG_SYSFS_DEPRECATED
if (!card->card_dev) {
- card->card_dev = device_create_drvdata(sound_class, card->dev,
- MKDEV(0, 0), NULL,
- "card%i", card->number);
+ card->card_dev = device_create(sound_class, card->dev,
+ MKDEV(0, 0), NULL,
+ "card%i", card->number);
if (IS_ERR(card->card_dev))
card->card_dev = NULL;
}
diff --git a/sound/core/sound.c b/sound/core/sound.c
index c0685e2f0afa..44a69bb8d4f0 100644
--- a/sound/core/sound.c
+++ b/sound/core/sound.c
@@ -274,9 +274,8 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev,
return minor;
}
snd_minors[minor] = preg;
- preg->dev = device_create_drvdata(sound_class, device,
- MKDEV(major, minor),
- private_data, "%s", name);
+ preg->dev = device_create(sound_class, device, MKDEV(major, minor),
+ private_data, "%s", name);
if (IS_ERR(preg->dev)) {
snd_minors[minor] = NULL;
mutex_unlock(&sound_mutex);
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 7d89c081a086..61aaedae6b7e 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -560,19 +560,18 @@ static int __init oss_init(void)
sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
- device_create_drvdata(sound_class, NULL,
- MKDEV(SOUND_MAJOR, dev_list[i].minor),
- NULL, "%s", dev_list[i].name);
+ device_create(sound_class, NULL,
+ MKDEV(SOUND_MAJOR, dev_list[i].minor), NULL,
+ "%s", dev_list[i].name);
if (!dev_list[i].num)
continue;
for (j = 1; j < *dev_list[i].num; j++)
- device_create_drvdata(sound_class, NULL,
- MKDEV(SOUND_MAJOR,
- dev_list[i].minor + (j*0x10)),
- NULL,
- "%s%d", dev_list[i].name, j);
+ device_create(sound_class, NULL,
+ MKDEV(SOUND_MAJOR,
+ dev_list[i].minor + (j*0x10)),
+ NULL, "%s%d", dev_list[i].name, j);
}
if (sound_nblocks >= 1024)
diff --git a/sound/sound_core.c b/sound/sound_core.c
index 4ae07e236b36..faef87a9bc3f 100644
--- a/sound/sound_core.c
+++ b/sound/sound_core.c
@@ -220,9 +220,8 @@ static int sound_insert_unit(struct sound_unit **list, const struct file_operati
else
sprintf(s->name, "sound/%s%d", name, r / SOUND_STEP);
- device_create_drvdata(sound_class, dev,
- MKDEV(SOUND_MAJOR, s->unit_minor),
- NULL, s->name+6);
+ device_create(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),
+ NULL, s->name+6);
return r;
fail: