]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/commitdiff
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 22 Jul 2008 20:13:47 +0000 (13:13 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 22 Jul 2008 20:13:47 +0000 (13:13 -0700)
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core-2.6: (79 commits)
  arm: bus_id -> dev_name() and dev_set_name() conversions
  sparc64: fix up bus_id changes in sparc core code
  3c59x: handle pci_name() being const
  MTD: handle pci_name() being const
  HP iLO driver
  sysdev: Convert the x86 mce tolerant sysdev attribute to generic attribute
  sysdev: Add utility functions for simple int/ulong variable sysdev attributes
  sysdev: Pass the attribute to the low level sysdev show/store function
  driver core: Suppress sysfs warnings for device_rename().
  kobject: Transmit return value of call_usermodehelper() to caller
  sysfs-rules.txt: reword API stability statement
  debugfs: Implement debugfs_remove_recursive()
  HOWTO: change email addresses of James in HOWTO
  always enable FW_LOADER unless EMBEDDED=y
  uio-howto.tmpl: use unique output names
  uio-howto.tmpl: use standard copyright/legal markings
  sysfs: don't call notify_change
  sysdev: fix debugging statements in registration code.
  kobject: should use kobject_put() in kset-example
  kobject: reorder kobject to save space on 64 bit builds
  ...

173 files changed:
Documentation/ABI/testing/sysfs-dev [new file with mode: 0644]
Documentation/DocBook/uio-howto.tmpl
Documentation/HOWTO
Documentation/filesystems/sysfs.txt
Documentation/sysfs-rules.txt
arch/arm/common/dmabounce.c
arch/arm/common/locomo.c
arch/arm/common/sa1111.c
arch/arm/common/scoop.c
arch/arm/kernel/ecard.c
arch/arm/kernel/time.c
arch/arm/mach-integrator/impd1.c
arch/arm/mach-integrator/lm.c
arch/arm/plat-omap/mailbox.c
arch/avr32/kernel/cpu.c
arch/ia64/kernel/err_inject.c
arch/mips/kernel/rtlx.c
arch/mips/sibyte/common/sb_tbprof.c
arch/powerpc/kernel/sysfs.c
arch/powerpc/platforms/cell/cbe_thermal.c
arch/powerpc/platforms/cell/spu_base.c
arch/powerpc/platforms/chrp/pci.c
arch/s390/kernel/smp.c
arch/s390/kernel/time.c
arch/sh/drivers/dma/dma-sysfs.c
arch/sparc64/kernel/ebus.c
arch/sparc64/kernel/of_device.c
arch/sparc64/kernel/pci.c
arch/sparc64/kernel/sysfs.c
arch/sparc64/kernel/vio.c
arch/x86/kernel/cpu/mcheck/mce_64.c
arch/x86/kernel/cpu/mcheck/therm_throt.c
arch/x86/kernel/cpuid.c
arch/x86/kernel/microcode.c
arch/x86/kernel/msr.c
arch/x86/kernel/pci-dma.c
arch/x86/kernel/pci-gart_64.c
block/bsg.c
block/genhd.c
drivers/acpi/fan.c
drivers/acpi/glue.c
drivers/acpi/processor_core.c
drivers/acpi/scan.c
drivers/acpi/thermal.c
drivers/acpi/video.c
drivers/base/Kconfig
drivers/base/base.h
drivers/base/class.c
drivers/base/core.c
drivers/base/cpu.c
drivers/base/memory.c
drivers/base/node.c
drivers/base/power/trace.c
drivers/base/sys.c
drivers/base/topology.c
drivers/block/aoe/aoechr.c
drivers/block/paride/pg.c
drivers/block/paride/pt.c
drivers/block/pktcdvd.c
drivers/char/dsp56k.c
drivers/char/ip2/ip2main.c
drivers/char/ipmi/ipmi_devintf.c
drivers/char/istallion.c
drivers/char/lp.c
drivers/char/mem.c
drivers/char/misc.c
drivers/char/pcmcia/cm4000_cs.c
drivers/char/pcmcia/cm4040_cs.c
drivers/char/ppdev.c
drivers/char/raw.c
drivers/char/snsc.c
drivers/char/stallion.c
drivers/char/tty_io.c
drivers/char/vc_screen.c
drivers/char/viotape.c
drivers/char/vt.c
drivers/char/xilinx_hwicap/xilinx_hwicap.c
drivers/cpuidle/sysfs.c
drivers/dca/dca-sysfs.c
drivers/eisa/Makefile
drivers/eisa/eisa-bus.c
drivers/hid/hidraw.c
drivers/hwmon/hwmon.c
drivers/i2c/i2c-core.c
drivers/i2c/i2c-dev.c
drivers/ide/ide-tape.c
drivers/ieee1394/dv1394.c
drivers/ieee1394/nodemgr.c
drivers/ieee1394/raw1394.c
drivers/ieee1394/video1394.c
drivers/infiniband/core/cm.c
drivers/infiniband/hw/ipath/ipath_file_ops.c
drivers/isdn/capi/capi.c
drivers/macintosh/adb.c
drivers/mca/mca-bus.c
drivers/media/dvb/dvb-core/dvbdev.c
drivers/memstick/host/jmb38x_ms.c
drivers/message/fusion/mptbase.c
drivers/message/fusion/mptbase.h
drivers/message/fusion/mptfc.c
drivers/misc/Kconfig
drivers/misc/Makefile
drivers/misc/hpilo.c [new file with mode: 0644]
drivers/misc/hpilo.h [new file with mode: 0644]
drivers/misc/phantom.c
drivers/mtd/devices/block2mtd.c
drivers/mtd/mtdchar.c
drivers/net/3c59x.c
drivers/net/arm/at91_ether.c
drivers/net/arm/ep93xx_eth.c
drivers/net/arm/etherh.c
drivers/net/ppp_generic.c
drivers/net/wan/cosa.c
drivers/pci/hotplug/acpiphp.h
drivers/power/apm_power.c
drivers/power/power_supply_core.c
drivers/rtc/interface.c
drivers/s390/char/raw3270.c
drivers/s390/char/tape_class.c
drivers/s390/char/vmur.c
drivers/sbus/sbus.c
drivers/scsi/dpt_i2o.c
drivers/scsi/hosts.c
drivers/scsi/scsi_transport_fc.c
drivers/scsi/scsi_transport_iscsi.c
drivers/spi/spi.c
drivers/spi/spidev.c
drivers/uio/Kconfig
drivers/uio/Makefile
drivers/uio/uio.c
drivers/uio/uio_pdrv.c [new file with mode: 0644]
drivers/usb/core/devio.c
drivers/usb/core/file.c
drivers/usb/gadget/printer.c
drivers/usb/mon/mon_bin.c
drivers/video/aty/aty128fb.c
drivers/video/aty/radeonfb.h
drivers/video/console/fbcon.c
drivers/video/fbmem.c
drivers/xen/balloon.c
fs/coda/psdev.c
fs/debugfs/inode.c
fs/partitions/check.c
fs/sysfs/dir.c
fs/sysfs/file.c
fs/sysfs/symlink.c
fs/sysfs/sysfs.h
include/linux/debugfs.h
include/linux/device.h
include/linux/eisa.h
include/linux/kobject.h
include/linux/mtd/map.h
include/linux/mtd/mtd.h
include/linux/spi/spi.h
include/linux/sysdev.h
include/linux/sysfs.h
include/linux/uio_driver.h
include/scsi/scsi_host.h
include/scsi/scsi_transport_fc.h
include/scsi/scsi_transport_iscsi.h
kernel/rtmutex-tester.c
kernel/sched.c
kernel/time/clocksource.c
lib/Kconfig.debug
lib/kobject.c
lib/kobject_uevent.c
net/bluetooth/hci_sysfs.c
samples/firmware_class/firmware_sample_firmware_class.c
samples/kobject/kset-example.c
scripts/mod/file2alias.c
sound/core/init.c
sound/oss/soundcard.c
sound/sound_core.c

diff --git a/Documentation/ABI/testing/sysfs-dev b/Documentation/ABI/testing/sysfs-dev
new file mode 100644 (file)
index 0000000..a9f2b8b
--- /dev/null
@@ -0,0 +1,20 @@
+What:          /sys/dev
+Date:          April 2008
+KernelVersion: 2.6.26
+Contact:       Dan Williams <dan.j.williams@intel.com>
+Description:   The /sys/dev tree provides a method to look up the sysfs
+               path for a device using the information returned from
+               stat(2).  There are two directories, 'block' and 'char',
+               beneath /sys/dev containing symbolic links with names of
+               the form "<major>:<minor>".  These links point to the
+               corresponding sysfs path for the given device.
+
+               Example:
+               $ readlink /sys/dev/block/8:32
+               ../../block/sdc
+
+               Entries in /sys/dev/char and /sys/dev/block will be
+               dynamically created and destroyed as devices enter and
+               leave the system.
+
+Users:         mdadm <linux-raid@vger.kernel.org>
index fdd7f4f887b75ba7bc96b7ab81b9abc7d3348d73..df87d1b93605ac54cf400bd7b8d44b0866d0789a 100644 (file)
     </affiliation>
 </author>
 
+<copyright>
+       <year>2006-2008</year>
+       <holder>Hans-Jürgen Koch.</holder>
+</copyright>
+
+<legalnotice>
+<para>
+This documentation is Free Software licensed under the terms of the
+GPL version 2.
+</para>
+</legalnotice>
+
 <pubdate>2006-12-11</pubdate>
 
 <abstract>
 </abstract>
 
 <revhistory>
+       <revision>
+       <revnumber>0.5</revnumber>
+       <date>2008-05-22</date>
+       <authorinitials>hjk</authorinitials>
+       <revremark>Added description of write() function.</revremark>
+       </revision>
        <revision>
        <revnumber>0.4</revnumber>
        <date>2007-11-26</date>
 </bookinfo>
 
 <chapter id="aboutthisdoc">
-<?dbhtml filename="about.html"?>
+<?dbhtml filename="aboutthis.html"?>
 <title>About this document</title>
 
-<sect1 id="copyright">
-<?dbhtml filename="copyright.html"?>
-<title>Copyright and License</title>
-<para>
-      Copyright (c) 2006 by Hans-Jürgen Koch.</para>
-<para>
-This documentation is Free Software licensed under the terms of the
-GPL version 2.
-</para>
-</sect1>
-
 <sect1 id="translations">
 <?dbhtml filename="translations.html"?>
 <title>Translations</title>
@@ -189,6 +196,30 @@ interested in translating it, please email me
        represents the total interrupt count. You can use this number
        to figure out if you missed some interrupts.
        </para>
+       <para>
+       For some hardware that has more than one interrupt source internally,
+       but not separate IRQ mask and status registers, there might be
+       situations where userspace cannot determine what the interrupt source
+       was if the kernel handler disables them by writing to the chip's IRQ
+       register. In such a case, the kernel has to disable the IRQ completely
+       to leave the chip's register untouched. Now the userspace part can
+       determine the cause of the interrupt, but it cannot re-enable
+       interrupts. Another cornercase is chips where re-enabling interrupts
+       is a read-modify-write operation to a combined IRQ status/acknowledge
+       register. This would be racy if a new interrupt occurred
+       simultaneously.
+       </para>
+       <para>
+       To address these problems, UIO also implements a write() function. It
+       is normally not used and can be ignored for hardware that has only a
+       single interrupt source or has separate IRQ mask and status registers.
+       If you need it, however, a write to <filename>/dev/uioX</filename>
+       will call the <function>irqcontrol()</function> function implemented
+       by the driver. You have to write a 32-bit value that is usually either
+       0 or 1 to disable or enable interrupts. If a driver does not implement
+       <function>irqcontrol()</function>, <function>write()</function> will
+       return with <varname>-ENOSYS</varname>.
+       </para>
 
        <para>
        To handle interrupts properly, your custom kernel module can
@@ -362,6 +393,14 @@ device is actually used.
 <function>open()</function>, you will probably also want a custom
 <function>release()</function> function.
 </para></listitem>
+
+<listitem><para>
+<varname>int (*irqcontrol)(struct uio_info *info, s32 irq_on)
+</varname>: Optional. If you need to be able to enable or disable
+interrupts from userspace by writing to <filename>/dev/uioX</filename>,
+you can implement this function. The parameter <varname>irq_on</varname>
+will be 0 to disable interrupts and 1 to enable them.
+</para></listitem>
 </itemizedlist>
 
 <para>
index 619e8caf30db88508a3f2859d140f41ce363f552..c2371c5a98f99b5eaa785bd0affd6c40187e84e3 100644 (file)
@@ -358,7 +358,7 @@ Here is a list of some of the different kernel trees available:
     - pcmcia, Dominik Brodowski <linux@dominikbrodowski.net>
        git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git
 
-    - SCSI, James Bottomley <James.Bottomley@SteelEye.com>
+    - SCSI, James Bottomley <James.Bottomley@hansenpartnership.com>
        git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git
 
     - x86, Ingo Molnar <mingo@elte.hu>
index 7f27b8f840d06210df1511db6ef603cedb8f0e58..9e9c348275a96fd362acf9916d2789be8a08c4c8 100644 (file)
@@ -248,6 +248,7 @@ The top level sysfs directory looks like:
 block/
 bus/
 class/
+dev/
 devices/
 firmware/
 net/
@@ -274,6 +275,11 @@ fs/ contains a directory for some filesystems.  Currently each
 filesystem wanting to export attributes must create its own hierarchy
 below fs/ (see ./fuse.txt for an example).
 
+dev/ contains two directories char/ and block/. Inside these two
+directories there are symlinks named <major>:<minor>.  These symlinks
+point to the sysfs directory for the given device.  /sys/dev provides a
+quick way to lookup the sysfs interface for a device from the result of
+a stat(2) operation.
 
 More information can driver-model specific features can be found in
 Documentation/driver-model/. 
index 80ef562160bba8697c5623ee3b5fa9b4c163ab4a..6049a2a84dda2111b9c35c628665566e0153b254 100644 (file)
@@ -3,9 +3,8 @@ Rules on how to access information in the Linux kernel sysfs
 The kernel-exported sysfs exports internal kernel implementation details
 and depends on internal kernel structures and layout. It is agreed upon
 by the kernel developers that the Linux kernel does not provide a stable
-internal API. As sysfs is a direct export of kernel internal
-structures, the sysfs interface cannot provide a stable interface either;
-it may always change along with internal kernel changes.
+internal API. Therefore, there are aspects of the sysfs interface that
+may not be stable across kernel releases.
 
 To minimize the risk of breaking users of sysfs, which are in most cases
 low-level userspace applications, with a new kernel release, the users
index 2744673314b470cb84b68d1ff9a040a0356d34af..dd2947342604b2ea43bdfa409dcc32b4b2609cf2 100644 (file)
@@ -554,9 +554,8 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
 
        device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC);
        if (!device_info) {
-               printk(KERN_ERR
-                       "Could not allocated dmabounce_device_info for %s",
-                       dev->bus_id);
+               dev_err(dev,
+                       "Could not allocated dmabounce_device_info\n");
                return -ENOMEM;
        }
 
@@ -594,8 +593,7 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
 
        dev->archdata.dmabounce = device_info;
 
-       printk(KERN_INFO "dmabounce: registered device %s on %s bus\n",
-               dev->bus_id, dev->bus->name);
+       dev_info(dev, "dmabounce: registered device\n");
 
        return 0;
 
@@ -614,16 +612,15 @@ dmabounce_unregister_dev(struct device *dev)
        dev->archdata.dmabounce = NULL;
 
        if (!device_info) {
-               printk(KERN_WARNING
-                       "%s: Never registered with dmabounce but attempting" \
-                       "to unregister!\n", dev->bus_id);
+               dev_warn(dev,
+                        "Never registered with dmabounce but attempting"
+                        "to unregister!\n");
                return;
        }
 
        if (!list_empty(&device_info->safe_buffers)) {
-               printk(KERN_ERR
-                       "%s: Removing from dmabounce with pending buffers!\n",
-                       dev->bus_id);
+               dev_err(dev,
+                       "Removing from dmabounce with pending buffers!\n");
                BUG();
        }
 
@@ -639,8 +636,7 @@ dmabounce_unregister_dev(struct device *dev)
 
        kfree(device_info);
 
-       printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n",
-               dev->bus_id, dev->bus->name);
+       dev_info(dev, "dmabounce: device unregistered\n");
 }
 
 
index d973c986f721aec8822f8ef0db8eeb97b0ec199e..c3c3a333904995273e5f7af7c68890c8baee361d 100644 (file)
@@ -543,7 +543,6 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
                goto out;
        }
 
-       strncpy(dev->dev.bus_id, info->name, sizeof(dev->dev.bus_id));
        /*
         * If the parent device has a DMA mask associated with it,
         * propagate it down to the children.
@@ -553,6 +552,7 @@ locomo_init_one_child(struct locomo *lchip, struct locomo_dev_info *info)
                dev->dev.dma_mask = &dev->dma_mask;
        }
 
+       dev_set_name(&dev->dev, "%s", info->name);
        dev->devid       = info->devid;
        dev->dev.parent  = lchip->dev;
        dev->dev.bus     = &locomo_bus_type;
index eb06d0b2cb747344c47fb1395d6f2b6fecf080d9..c8e8f0ea59e1b2ce146da5effe3f6ebada19df6d 100644 (file)
@@ -550,9 +550,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
                goto out;
        }
 
-       snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id),
-                "%4.4lx", info->offset);
-
+       dev_set_name(&dev->dev, "%4.4lx", info->offset);
        dev->devid       = info->devid;
        dev->dev.parent  = sachip->dev;
        dev->dev.bus     = &sa1111_bus_type;
@@ -560,7 +558,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
        dev->dev.coherent_dma_mask = sachip->dev->coherent_dma_mask;
        dev->res.start   = sachip->phys + info->offset;
        dev->res.end     = dev->res.start + 511;
-       dev->res.name    = dev->dev.bus_id;
+       dev->res.name    = dev_name(&dev->dev);
        dev->res.flags   = IORESOURCE_MEM;
        dev->mapbase     = sachip->base + info->offset;
        dev->skpcr_mask  = info->skpcr_mask;
@@ -570,6 +568,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
        if (ret) {
                printk("SA1111: failed to allocate resource for %s\n",
                        dev->res.name);
+               dev_set_name(&dev->dev, NULL);
                kfree(dev);
                goto out;
        }
@@ -593,7 +592,8 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
                if (dev->dma_mask != 0xffffffffUL) {
                        ret = dmabounce_register_dev(&dev->dev, 1024, 4096);
                        if (ret) {
-                               printk("SA1111: Failed to register %s with dmabounce", dev->dev.bus_id);
+                               dev_err(&dev->dev, "SA1111: Failed to register"
+                                       " with dmabounce\n");
                                device_unregister(&dev->dev);
                        }
                }
index bc299b07a6fa8a949ed72fdc352e2cea817f51ac..ae39553589ddbf34b37f37e0d2c3c3d67a1b4e9c 100644 (file)
@@ -247,7 +247,7 @@ static int __devinit scoop_probe(struct platform_device *pdev)
        devptr->gpio.base = -1;
 
        if (inf->gpio_base != 0) {
-               devptr->gpio.label = pdev->dev.bus_id;
+               devptr->gpio.label = dev_name(&pdev->dev);
                devptr->gpio.base = inf->gpio_base;
                devptr->gpio.ngpio = 12; /* PA11 = 0, PA12 = 1, etc. up to PA22 = 11 */
                devptr->gpio.set = scoop_gpio_set;
index 8bfd299bfe77a8e0dccb71fb47b330f834f73a2a..f5cfdabcb87dc8314d488dae8d864ecf4b4ca9e4 100644 (file)
@@ -783,7 +783,7 @@ static void ecard_proc_init(void)
 
 #define ec_set_resource(ec,nr,st,sz)                           \
        do {                                                    \
-               (ec)->resource[nr].name = ec->dev.bus_id;       \
+               (ec)->resource[nr].name = dev_name(&ec->dev);   \
                (ec)->resource[nr].start = st;                  \
                (ec)->resource[nr].end = (st) + (sz) - 1;       \
                (ec)->resource[nr].flags = IORESOURCE_MEM;      \
@@ -853,8 +853,7 @@ static struct expansion_card *__init ecard_alloc_card(int type, int slot)
        for (i = 0; i < ECARD_NUM_RESOURCES; i++) {
                if (ec->resource[i].flags &&
                    request_resource(&iomem_resource, &ec->resource[i])) {
-                       printk(KERN_ERR "%s: resource(s) not available\n",
-                               ec->dev.bus_id);
+                       dev_err(&ec->dev, "resource(s) not available\n");
                        ec->resource[i].end -= ec->resource[i].start;
                        ec->resource[i].start = 0;
                        ec->resource[i].flags = 0;
index cc5145b28e7f0997c3b9a9edd8b6c38ebf482c44..368d171754cf309acfabb1714f4b4dd915790086 100644 (file)
@@ -130,7 +130,9 @@ static const struct leds_evt_name evt_names[] = {
        { "red",   led_red_on,   led_red_off   },
 };
 
-static ssize_t leds_store(struct sys_device *dev, const char *buf, size_t size)
+static ssize_t leds_store(struct sys_device *dev,
+                       struct sysdev_attribute *attr,
+                       const char *buf, size_t size)
 {
        int ret = -EINVAL, len = strcspn(buf, " ");
 
index 62e653a3ea1a9f7a651a41e43a19253af1c95241..5a1588cf8242a2cea12e98bef963eb2dc065ad53 100644 (file)
@@ -393,9 +393,7 @@ static int impd1_probe(struct lm_device *dev)
                if (!d)
                        continue;
 
-               snprintf(d->dev.bus_id, sizeof(d->dev.bus_id),
-                        "lm%x:%5.5lx", dev->id, idev->offset >> 12);
-
+               dev_set_name(&d->dev, "lm%x:%5.5lx", dev->id, idev->offset >> 12);
                d->dev.parent   = &dev->dev;
                d->res.start    = dev->resource.start + idev->offset;
                d->res.end      = d->res.start + SZ_4K - 1;
@@ -407,8 +405,7 @@ static int impd1_probe(struct lm_device *dev)
 
                ret = amba_device_register(d, &dev->resource);
                if (ret) {
-                       printk("unable to register device %s: %d\n",
-                               d->dev.bus_id, ret);
+                       dev_err(&d->dev, "unable to register device: %d\n");
                        kfree(d);
                }
        }
index 622cdc4212dd6f096ca7880f85d42334f0581da1..f939c50914054081407848ecd351f2c509839fe9 100644 (file)
@@ -81,8 +81,10 @@ int lm_device_register(struct lm_device *dev)
        dev->dev.release = lm_device_release;
        dev->dev.bus = &lm_bustype;
 
-       snprintf(dev->dev.bus_id, sizeof(dev->dev.bus_id), "lm%d", dev->id);
-       dev->resource.name = dev->dev.bus_id;
+       ret = dev_set_name(&dev->dev, "lm%d", dev->id);
+       if (ret)
+               return ret;
+       dev->resource.name = dev_name(&dev->dev);
 
        ret = request_resource(&iomem_resource, &dev->resource);
        if (ret == 0) {
index 6f33f58bca4573184aaa7b5147b02d707ab6e496..ff1413eae0b84b73803c67754366e4ea09ea814f 100644 (file)
@@ -334,7 +334,7 @@ static int omap_mbox_init(struct omap_mbox *mbox)
        }
 
        mbox->dev.class = &omap_mbox_class;
-       strlcpy(mbox->dev.bus_id, mbox->name, KOBJ_NAME_LEN);
+       dev_set_name(&mbox->dev, "%s", mbox->name);
        dev_set_drvdata(&mbox->dev, mbox);
 
        ret = device_register(&mbox->dev);
index b8409caeb23dccbca394127132bcdcc9e0360eab..e84faffbbecae2df573796128243947028a556a6 100644 (file)
@@ -26,14 +26,16 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
  * XXX: If/when a SMP-capable implementation of AVR32 will ever be
  * made, we must make sure that the code executes on the correct CPU.
  */
-static ssize_t show_pc0event(struct sys_device *dev, char *buf)
+static ssize_t show_pc0event(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pccr;
 
        pccr = sysreg_read(PCCR);
        return sprintf(buf, "0x%lx\n", (pccr >> 12) & 0x3f);
 }
-static ssize_t store_pc0event(struct sys_device *dev, const char *buf,
+static ssize_t store_pc0event(struct sys_device *dev,
+                       struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long val;
@@ -46,15 +48,17 @@ static ssize_t store_pc0event(struct sys_device *dev, const char *buf,
        sysreg_write(PCCR, val);
        return count;
 }
-static ssize_t show_pc0count(struct sys_device *dev, char *buf)
+static ssize_t show_pc0count(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pcnt0;
 
        pcnt0 = sysreg_read(PCNT0);
        return sprintf(buf, "%lu\n", pcnt0);
 }
-static ssize_t store_pc0count(struct sys_device *dev, const char *buf,
-                             size_t count)
+static ssize_t store_pc0count(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
+                               const char *buf, size_t count)
 {
        unsigned long val;
        char *endp;
@@ -67,14 +71,16 @@ static ssize_t store_pc0count(struct sys_device *dev, const char *buf,
        return count;
 }
 
-static ssize_t show_pc1event(struct sys_device *dev, char *buf)
+static ssize_t show_pc1event(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pccr;
 
        pccr = sysreg_read(PCCR);
        return sprintf(buf, "0x%lx\n", (pccr >> 18) & 0x3f);
 }
-static ssize_t store_pc1event(struct sys_device *dev, const char *buf,
+static ssize_t store_pc1event(struct sys_device *dev,
+                             struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long val;
@@ -87,14 +93,16 @@ static ssize_t store_pc1event(struct sys_device *dev, const char *buf,
        sysreg_write(PCCR, val);
        return count;
 }
-static ssize_t show_pc1count(struct sys_device *dev, char *buf)
+static ssize_t show_pc1count(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pcnt1;
 
        pcnt1 = sysreg_read(PCNT1);
        return sprintf(buf, "%lu\n", pcnt1);
 }
-static ssize_t store_pc1count(struct sys_device *dev, const char *buf,
+static ssize_t store_pc1count(struct sys_device *dev,
+                               struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long val;
@@ -108,14 +116,16 @@ static ssize_t store_pc1count(struct sys_device *dev, const char *buf,
        return count;
 }
 
-static ssize_t show_pccycles(struct sys_device *dev, char *buf)
+static ssize_t show_pccycles(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pccnt;
 
        pccnt = sysreg_read(PCCNT);
        return sprintf(buf, "%lu\n", pccnt);
 }
-static ssize_t store_pccycles(struct sys_device *dev, const char *buf,
+static ssize_t store_pccycles(struct sys_device *dev,
+                               struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long val;
@@ -129,14 +139,16 @@ static ssize_t store_pccycles(struct sys_device *dev, const char *buf,
        return count;
 }
 
-static ssize_t show_pcenable(struct sys_device *dev, char *buf)
+static ssize_t show_pcenable(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        unsigned long pccr;
 
        pccr = sysreg_read(PCCR);
        return sprintf(buf, "%c\n", (pccr & 1)?'1':'0');
 }
-static ssize_t store_pcenable(struct sys_device *dev, const char *buf,
+static ssize_t store_pcenable(struct sys_device *dev,
+                             struct sysdev_attribute *attr, const char *buf,
                              size_t count)
 {
        unsigned long pccr, val;
index b642648cc2acdbd7a1548d8d76685fec568cced7..c539c689493b786f63d2cbf5b6c2c0969b447dd2 100644 (file)
@@ -55,7 +55,8 @@ static u64 resources[NR_CPUS];
 
 #define show(name)                                                     \
 static ssize_t                                                                 \
-show_##name(struct sys_device *dev, char *buf)                         \
+show_##name(struct sys_device *dev, struct sysdev_attribute *attr,     \
+               char *buf)                                              \
 {                                                                      \
        u32 cpu=dev->id;                                                \
        return sprintf(buf, "%lx\n", name[cpu]);                        \
@@ -63,7 +64,8 @@ show_##name(struct sys_device *dev, char *buf)                                \
 
 #define store(name)                                                    \
 static ssize_t                                                                 \
-store_##name(struct sys_device *dev, const char *buf, size_t size)     \
+store_##name(struct sys_device *dev, struct sysdev_attribute *attr,    \
+                                       const char *buf, size_t size)   \
 {                                                                      \
        unsigned int cpu=dev->id;                                       \
        name[cpu] = simple_strtoull(buf, NULL, 16);                     \
@@ -76,7 +78,8 @@ show(call_start)
  * processor. The cpu number in driver is only used for storing data.
  */
 static ssize_t
-store_call_start(struct sys_device *dev, const char *buf, size_t size)
+store_call_start(struct sys_device *dev, struct sysdev_attribute *attr,
+               const char *buf, size_t size)
 {
        unsigned int cpu=dev->id;
        unsigned long call_start = simple_strtoull(buf, NULL, 16);
@@ -124,14 +127,16 @@ show(err_type_info)
 store(err_type_info)
 
 static ssize_t
-show_virtual_to_phys(struct sys_device *dev, char *buf)
+show_virtual_to_phys(struct sys_device *dev, struct sysdev_attribute *attr,
+                       char *buf)
 {
        unsigned int cpu=dev->id;
        return sprintf(buf, "%lx\n", phys_addr[cpu]);
 }
 
 static ssize_t
-store_virtual_to_phys(struct sys_device *dev, const char *buf, size_t size)
+store_virtual_to_phys(struct sys_device *dev, struct sysdev_attribute *attr,
+                       const char *buf, size_t size)
 {
        unsigned int cpu=dev->id;
        u64 virt_addr=simple_strtoull(buf, NULL, 16);
@@ -154,7 +159,8 @@ show(err_struct_info)
 store(err_struct_info)
 
 static ssize_t
-show_err_data_buffer(struct sys_device *dev, char *buf)
+show_err_data_buffer(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        unsigned int cpu=dev->id;
 
@@ -165,7 +171,9 @@ show_err_data_buffer(struct sys_device *dev, char *buf)
 }
 
 static ssize_t
-store_err_data_buffer(struct sys_device *dev, const char *buf, size_t size)
+store_err_data_buffer(struct sys_device *dev,
+                       struct sysdev_attribute *attr,
+                       const char *buf, size_t size)
 {
        unsigned int cpu=dev->id;
        int ret;
index b556419612329a26fdf4493b8d4c1ee43073d4a7..dfd868b683640634f7d128f883f53165b73595fb 100644 (file)
@@ -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(mt_class, NULL, MKDEV(major, i),
-                                   "%s%d", module_name, i);
+               dev = device_create_drvdata(mt_class, NULL, MKDEV(major, i),
+                                           NULL, "%s%d", module_name, i);
                if (IS_ERR(dev)) {
                        err = PTR_ERR(dev);
                        goto out_chrdev;
index 28b012ab8dcb7ae6c06eaac75789cbf08d861a4c..66e3e3fb311f9a413ffb3dbc58aa9174fe101fe5 100644 (file)
@@ -576,7 +576,8 @@ static int __init sbprof_tb_init(void)
 
        tb_class = tbc;
 
-       dev = device_create(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0), "tb");
+       dev = device_create_drvdata(tbc, NULL, MKDEV(SBPROF_TB_MAJOR, 0),
+                                   NULL, "tb");
        if (IS_ERR(dev)) {
                err = PTR_ERR(dev);
                goto out_class;
index c8127f832df0f6d28d8efb0ee3a2097f8933dcce..aba0ba95f0629cf320df4c006a38923d805f0aa8 100644 (file)
@@ -28,7 +28,9 @@ static DEFINE_PER_CPU(struct cpu, cpu_devices);
 /* Time in microseconds we delay before sleeping in the idle loop */
 DEFINE_PER_CPU(unsigned long, smt_snooze_delay) = { 100 };
 
-static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
+static ssize_t store_smt_snooze_delay(struct sys_device *dev,
+                                     struct sysdev_attribute *attr,
+                                     const char *buf,
                                      size_t count)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
@@ -44,7 +46,9 @@ static ssize_t store_smt_snooze_delay(struct sys_device *dev, const char *buf,
        return count;
 }
 
-static ssize_t show_smt_snooze_delay(struct sys_device *dev, char *buf)
+static ssize_t show_smt_snooze_delay(struct sys_device *dev,
+                                    struct sysdev_attribute *attr,
+                                    char *buf)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
 
@@ -152,14 +156,17 @@ static unsigned long write_##NAME(unsigned long val) \
        mtspr(ADDRESS, val); \
        return 0; \
 } \
-static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+static ssize_t show_##NAME(struct sys_device *dev, \
+                       struct sysdev_attribute *attr, \
+                       char *buf) \
 { \
        struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
        unsigned long val = run_on_cpu(cpu->sysdev.id, read_##NAME, 0); \
        return sprintf(buf, "%lx\n", val); \
 } \
 static ssize_t __used \
-       store_##NAME(struct sys_device *dev, const char *buf, size_t count) \
+       store_##NAME(struct sys_device *dev, struct sysdev_attribute *attr, \
+                       const char *buf, size_t count) \
 { \
        struct cpu *cpu = container_of(dev, struct cpu, sysdev); \
        unsigned long val; \
index 4852bf312d83c0d60a224eb9ab292dd832c96a64..4d4c8c169124eb8899315bf97c895c4e22a8919f 100644 (file)
@@ -97,7 +97,8 @@ static u8 spu_read_register_value(struct sys_device *sysdev, union spe_reg __iom
        return value.spe[spu->spe_id];
 }
 
-static ssize_t spu_show_temp(struct sys_device *sysdev, char *buf)
+static ssize_t spu_show_temp(struct sys_device *sysdev, struct sysdev_attribute *attr,
+                       char *buf)
 {
        u8 value;
        struct cbe_pmd_regs __iomem *pmd_regs;
@@ -146,32 +147,38 @@ static ssize_t store_throttle(struct cbe_pmd_regs __iomem *pmd_regs, const char
        return size;
 }
 
-static ssize_t spu_show_throttle_end(struct sys_device *sysdev, char *buf)
+static ssize_t spu_show_throttle_end(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(get_pmd_regs(sysdev), buf, 0);
 }
 
-static ssize_t spu_show_throttle_begin(struct sys_device *sysdev, char *buf)
+static ssize_t spu_show_throttle_begin(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(get_pmd_regs(sysdev), buf, 8);
 }
 
-static ssize_t spu_show_throttle_full_stop(struct sys_device *sysdev, char *buf)
+static ssize_t spu_show_throttle_full_stop(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(get_pmd_regs(sysdev), buf, 16);
 }
 
-static ssize_t spu_store_throttle_end(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t spu_store_throttle_end(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(get_pmd_regs(sysdev), buf, size, 0);
 }
 
-static ssize_t spu_store_throttle_begin(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t spu_store_throttle_begin(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(get_pmd_regs(sysdev), buf, size, 8);
 }
 
-static ssize_t spu_store_throttle_full_stop(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t spu_store_throttle_full_stop(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(get_pmd_regs(sysdev), buf, size, 16);
 }
@@ -192,43 +199,51 @@ static ssize_t ppe_show_temp(struct sys_device *sysdev, char *buf, int pos)
 
 /* shows the temperature of the DTS on the PPE,
  * located near the linear thermal sensor */
-static ssize_t ppe_show_temp0(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_temp0(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return ppe_show_temp(sysdev, buf, 32);
 }
 
 /* shows the temperature of the second DTS on the PPE */
-static ssize_t ppe_show_temp1(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_temp1(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return ppe_show_temp(sysdev, buf, 0);
 }
 
-static ssize_t ppe_show_throttle_end(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_throttle_end(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 32);
 }
 
-static ssize_t ppe_show_throttle_begin(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_throttle_begin(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 40);
 }
 
-static ssize_t ppe_show_throttle_full_stop(struct sys_device *sysdev, char *buf)
+static ssize_t ppe_show_throttle_full_stop(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        return show_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, 48);
 }
 
-static ssize_t ppe_store_throttle_end(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t ppe_store_throttle_end(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 32);
 }
 
-static ssize_t ppe_store_throttle_begin(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t ppe_store_throttle_begin(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 40);
 }
 
-static ssize_t ppe_store_throttle_full_stop(struct sys_device *sysdev, const char *buf, size_t size)
+static ssize_t ppe_store_throttle_full_stop(struct sys_device *sysdev,
+                       struct sysdev_attribute *attr, const char *buf, size_t size)
 {
        return store_throttle(cbe_get_cpu_pmd_regs(sysdev->id), buf, size, 48);
 }
index 78f905bc6a42dd7774edca80287a58bd921c01dd..a5bdb89a17c3bf4b40894a0e7025877579398a06 100644 (file)
@@ -703,7 +703,8 @@ static unsigned long long spu_acct_time(struct spu *spu,
 }
 
 
-static ssize_t spu_stat_show(struct sys_device *sysdev, char *buf)
+static ssize_t spu_stat_show(struct sys_device *sysdev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct spu *spu = container_of(sysdev, struct spu, sysdev);
 
index 609c46db4a1bc36e493250ee9231697656bd4da8..768c262b936891eeaebb361a1c2612e8ef429588 100644 (file)
@@ -367,7 +367,7 @@ static void chrp_pci_fixup_vt8231_ata(struct pci_dev *viaide)
        viaisa = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8231, NULL);
        if (!viaisa)
                return;
-       printk("Fixing VIA IDE, force legacy mode on '%s'\n", viaide->dev.bus_id);
+       dev_info(&viaide->dev, "Fixing VIA IDE, force legacy mode on\n");
 
        pci_read_config_byte(viaide, PCI_CLASS_PROG, &progif);
        pci_write_config_byte(viaide, PCI_CLASS_PROG, progif & ~0x5);
index b6781030cfbd5f7ef84bf567d26a9e23abf5e134..b795b3e24afde40a4a0f24b36e26d1759adfb905 100644 (file)
@@ -864,7 +864,8 @@ int setup_profiling_timer(unsigned int multiplier)
 }
 
 #ifdef CONFIG_HOTPLUG_CPU
-static ssize_t cpu_configure_show(struct sys_device *dev, char *buf)
+static ssize_t cpu_configure_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t count;
 
@@ -874,8 +875,9 @@ static ssize_t cpu_configure_show(struct sys_device *dev, char *buf)
        return count;
 }
 
-static ssize_t cpu_configure_store(struct sys_device *dev, const char *buf,
-                                  size_t count)
+static ssize_t cpu_configure_store(struct sys_device *dev,
+                                 struct sysdev_attribute *attr,
+                                 const char *buf, size_t count)
 {
        int cpu = dev->id;
        int val, rc;
@@ -922,7 +924,8 @@ out:
 static SYSDEV_ATTR(configure, 0644, cpu_configure_show, cpu_configure_store);
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static ssize_t cpu_polarization_show(struct sys_device *dev, char *buf)
+static ssize_t cpu_polarization_show(struct sys_device *dev,
+                                    struct sysdev_attribute *attr, char *buf)
 {
        int cpu = dev->id;
        ssize_t count;
@@ -950,7 +953,8 @@ static ssize_t cpu_polarization_show(struct sys_device *dev, char *buf)
 }
 static SYSDEV_ATTR(polarization, 0444, cpu_polarization_show, NULL);
 
-static ssize_t show_cpu_address(struct sys_device *dev, char *buf)
+static ssize_t show_cpu_address(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        return sprintf(buf, "%d\n", __cpu_logical_map[dev->id]);
 }
@@ -970,7 +974,8 @@ static struct attribute_group cpu_common_attr_group = {
        .attrs = cpu_common_attrs,
 };
 
-static ssize_t show_capability(struct sys_device *dev, char *buf)
+static ssize_t show_capability(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned int capability;
        int rc;
@@ -982,7 +987,8 @@ static ssize_t show_capability(struct sys_device *dev, char *buf)
 }
 static SYSDEV_ATTR(capability, 0444, show_capability, NULL);
 
-static ssize_t show_idle_count(struct sys_device *dev, char *buf)
+static ssize_t show_idle_count(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct s390_idle_data *idle;
        unsigned long long idle_count;
@@ -995,7 +1001,8 @@ static ssize_t show_idle_count(struct sys_device *dev, char *buf)
 }
 static SYSDEV_ATTR(idle_count, 0444, show_idle_count, NULL);
 
-static ssize_t show_idle_time(struct sys_device *dev, char *buf)
+static ssize_t show_idle_time(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct s390_idle_data *idle;
        unsigned long long new_time;
@@ -1112,7 +1119,9 @@ out:
        return rc;
 }
 
-static ssize_t __ref rescan_store(struct sys_device *dev, const char *buf,
+static ssize_t __ref rescan_store(struct sys_device *dev,
+                                 struct sysdev_attribute *attr,
+                                 const char *buf,
                                  size_t count)
 {
        int rc;
@@ -1123,7 +1132,9 @@ static ssize_t __ref rescan_store(struct sys_device *dev, const char *buf,
 static SYSDEV_ATTR(rescan, 0200, NULL, rescan_store);
 #endif /* CONFIG_HOTPLUG_CPU */
 
-static ssize_t dispatching_show(struct sys_device *dev, char *buf)
+static ssize_t dispatching_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
+                               char *buf)
 {
        ssize_t count;
 
@@ -1133,8 +1144,9 @@ static ssize_t dispatching_show(struct sys_device *dev, char *buf)
        return count;
 }
 
-static ssize_t dispatching_store(struct sys_device *dev, const char *buf,
-                                size_t count)
+static ssize_t dispatching_store(struct sys_device *dev,
+                                struct sysdev_attribute *attr,
+                                const char *buf, size_t count)
 {
        int val, rc;
        char delim;
index f2cede3947b231b25d493a8c643be76721780145..ab70d9bd92616decb488820101543ebf4218f82b 100644 (file)
@@ -1100,7 +1100,9 @@ static inline struct etr_aib *etr_aib_from_dev(struct sys_device *dev)
                return etr_port1_online ? &etr_port1 : NULL;
 }
 
-static ssize_t etr_online_show(struct sys_device *dev, char *buf)
+static ssize_t etr_online_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
+                               char *buf)
 {
        unsigned int online;
 
@@ -1109,7 +1111,8 @@ static ssize_t etr_online_show(struct sys_device *dev, char *buf)
 }
 
 static ssize_t etr_online_store(struct sys_device *dev,
-                             const char *buf, size_t count)
+                               struct sysdev_attribute *attr,
+                               const char *buf, size_t count)
 {
        unsigned int value;
 
@@ -1136,7 +1139,9 @@ static ssize_t etr_online_store(struct sys_device *dev,
 
 static SYSDEV_ATTR(online, 0600, etr_online_show, etr_online_store);
 
-static ssize_t etr_stepping_control_show(struct sys_device *dev, char *buf)
+static ssize_t etr_stepping_control_show(struct sys_device *dev,
+                                       struct sysdev_attribute *attr,
+                                       char *buf)
 {
        return sprintf(buf, "%i\n", (dev == &etr_port0_dev) ?
                       etr_eacr.e0 : etr_eacr.e1);
@@ -1144,7 +1149,8 @@ static ssize_t etr_stepping_control_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(stepping_control, 0400, etr_stepping_control_show, NULL);
 
-static ssize_t etr_mode_code_show(struct sys_device *dev, char *buf)
+static ssize_t etr_mode_code_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        if (!etr_port0_online && !etr_port1_online)
                /* Status word is not uptodate if both ports are offline. */
@@ -1155,7 +1161,8 @@ static ssize_t etr_mode_code_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(state_code, 0400, etr_mode_code_show, NULL);
 
-static ssize_t etr_untuned_show(struct sys_device *dev, char *buf)
+static ssize_t etr_untuned_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1166,7 +1173,8 @@ static ssize_t etr_untuned_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(untuned, 0400, etr_untuned_show, NULL);
 
-static ssize_t etr_network_id_show(struct sys_device *dev, char *buf)
+static ssize_t etr_network_id_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1177,7 +1185,8 @@ static ssize_t etr_network_id_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(network, 0400, etr_network_id_show, NULL);
 
-static ssize_t etr_id_show(struct sys_device *dev, char *buf)
+static ssize_t etr_id_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1188,7 +1197,8 @@ static ssize_t etr_id_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(id, 0400, etr_id_show, NULL);
 
-static ssize_t etr_port_number_show(struct sys_device *dev, char *buf)
+static ssize_t etr_port_number_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1199,7 +1209,8 @@ static ssize_t etr_port_number_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(port, 0400, etr_port_number_show, NULL);
 
-static ssize_t etr_coupled_show(struct sys_device *dev, char *buf)
+static ssize_t etr_coupled_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1210,7 +1221,8 @@ static ssize_t etr_coupled_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(coupled, 0400, etr_coupled_show, NULL);
 
-static ssize_t etr_local_time_show(struct sys_device *dev, char *buf)
+static ssize_t etr_local_time_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
@@ -1221,7 +1233,8 @@ static ssize_t etr_local_time_show(struct sys_device *dev, char *buf)
 
 static SYSDEV_ATTR(local_time, 0400, etr_local_time_show, NULL);
 
-static ssize_t etr_utc_offset_show(struct sys_device *dev, char *buf)
+static ssize_t etr_utc_offset_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct etr_aib *aib = etr_aib_from_dev(dev);
 
index 51b57c0d1a3c01f98d99e4bb5071cdb1478b89d3..347ee11351ec6c4375c06a8bf3f970733f022181 100644 (file)
@@ -23,7 +23,8 @@ static struct sysdev_class dma_sysclass = {
 };
 EXPORT_SYMBOL(dma_sysclass);
 
-static ssize_t dma_show_devices(struct sys_device *dev, char *buf)
+static ssize_t dma_show_devices(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t len = 0;
        int i;
@@ -57,13 +58,15 @@ static int __init dma_sysclass_init(void)
 }
 postcore_initcall(dma_sysclass_init);
 
-static ssize_t dma_show_dev_id(struct sys_device *dev, char *buf)
+static ssize_t dma_show_dev_id(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct dma_channel *channel = to_dma_channel(dev);
        return sprintf(buf, "%s\n", channel->dev_id);
 }
 
 static ssize_t dma_store_dev_id(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
                                const char *buf, size_t count)
 {
        struct dma_channel *channel = to_dma_channel(dev);
@@ -74,6 +77,7 @@ static ssize_t dma_store_dev_id(struct sys_device *dev,
 static SYSDEV_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id);
 
 static ssize_t dma_store_config(struct sys_device *dev,
+                               struct sysdev_attribute *attr,
                                const char *buf, size_t count)
 {
        struct dma_channel *channel = to_dma_channel(dev);
@@ -87,13 +91,15 @@ static ssize_t dma_store_config(struct sys_device *dev,
 
 static SYSDEV_ATTR(config, S_IWUSR, NULL, dma_store_config);
 
-static ssize_t dma_show_mode(struct sys_device *dev, char *buf)
+static ssize_t dma_show_mode(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct dma_channel *channel = to_dma_channel(dev);
        return sprintf(buf, "0x%08x\n", channel->mode);
 }
 
 static ssize_t dma_store_mode(struct sys_device *dev,
+                             struct sysdev_attribute *attr,
                              const char *buf, size_t count)
 {
        struct dma_channel *channel = to_dma_channel(dev);
@@ -104,7 +110,8 @@ static ssize_t dma_store_mode(struct sys_device *dev,
 static SYSDEV_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode);
 
 #define dma_ro_attr(field, fmt)                                                \
-static ssize_t dma_show_##field(struct sys_device *dev, char *buf)     \
+static ssize_t dma_show_##field(struct sys_device *dev,                \
+                               struct sysdev_attribute *attr, char *buf)\
 {                                                                      \
        struct dma_channel *channel = to_dma_channel(dev);              \
        return sprintf(buf, fmt, channel->field);                       \
index c49d0388b793852af4bf1ce99ac2d20868e6e3fc..4d58d7ce708dc87206d1f0602e334c54d72c6260 100644 (file)
@@ -401,7 +401,7 @@ static void __init fill_ebus_device(struct device_node *dp, struct linux_ebus_de
        dev->ofdev.node = dp;
        dev->ofdev.dev.parent = &dev->bus->ofdev.dev;
        dev->ofdev.dev.bus = &ebus_bus_type;
-       sprintf(dev->ofdev.dev.bus_id, "ebus[%08x]", dp->node);
+       dev_set_name(&dev->ofdev.dev, "ebus[%08x]", dp->node);
 
        /* Register with core */
        if (of_device_register(&dev->ofdev) != 0)
@@ -501,7 +501,7 @@ void __init ebus_init(void)
                ebus->ofdev.node = dp;
                ebus->ofdev.dev.parent = &pdev->dev;
                ebus->ofdev.dev.bus = &ebus_bus_type;
-               sprintf(ebus->ofdev.dev.bus_id, "ebus%d", num_ebus);
+               dev_set_name(&ebus->ofdev.dev, "ebus%d", num_ebus);
 
                /* Register with core */
                if (of_device_register(&ebus->ofdev) != 0)
index d569f60c24b87fd4fc23d6e749fc37d083bb22a3..4fd48ab7dda40bef2a290e08cb07558122b3be35 100644 (file)
@@ -797,9 +797,9 @@ static struct of_device * __init scan_one_device(struct device_node *dp,
        op->dev.parent = parent;
        op->dev.bus = &of_platform_bus_type;
        if (!parent)
-               strcpy(op->dev.bus_id, "root");
+               dev_set_name(&op->dev, "root");
        else
-               sprintf(op->dev.bus_id, "%08x", dp->node);
+               dev_set_name(&op->dev, "%08x", dp->node);
 
        if (of_device_register(op)) {
                printk("%s: Could not register of device.\n",
index d00a3656c287fed07c13b4609997e1ff09f8e375..55096195458fa0d358364075c5c7f06617112a55 100644 (file)
@@ -408,7 +408,7 @@ struct pci_dev *of_create_pci_dev(struct pci_pbm_info *pbm,
        dev->class = class >> 8;
        dev->revision = class & 0xff;
 
-       sprintf(dev->dev.bus_id, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
+       dev_set_name(&dev->dev, "%04x:%02x:%02x.%d", pci_domain_nr(bus),
                dev->bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn));
 
        if (ofpci_verbose)
index e885034a6b73a865c049fa5ca62ca5dab3a88fc1..84e5ce146713383922f07f9e5b1c677874067344 100644 (file)
@@ -14,7 +14,8 @@
 static DEFINE_PER_CPU(struct hv_mmu_statistics, mmu_stats) __attribute__((aligned(64)));
 
 #define SHOW_MMUSTAT_ULONG(NAME) \
-static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+static ssize_t show_##NAME(struct sys_device *dev, \
+                       struct sysdev_attribute *attr, char *buf) \
 { \
        struct hv_mmu_statistics *p = &per_cpu(mmu_stats, dev->id); \
        return sprintf(buf, "%lu\n", p->NAME); \
@@ -135,13 +136,16 @@ static unsigned long write_mmustat_enable(unsigned long val)
        return sun4v_mmustat_conf(ra, &orig_ra);
 }
 
-static ssize_t show_mmustat_enable(struct sys_device *s, char *buf)
+static ssize_t show_mmustat_enable(struct sys_device *s,
+                               struct sysdev_attribute *attr, char *buf)
 {
        unsigned long val = run_on_cpu(s->id, read_mmustat_enable, 0);
        return sprintf(buf, "%lx\n", val);
 }
 
-static ssize_t store_mmustat_enable(struct sys_device *s, const char *buf, size_t count)
+static ssize_t store_mmustat_enable(struct sys_device *s,
+                       struct sysdev_attribute *attr, const char *buf,
+                       size_t count)
 {
        unsigned long val, err;
        int ret = sscanf(buf, "%ld", &val);
@@ -179,14 +183,16 @@ static void unregister_mmu_stats(struct sys_device *s)
 #endif
 
 #define SHOW_CPUDATA_ULONG_NAME(NAME, MEMBER) \
-static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+static ssize_t show_##NAME(struct sys_device *dev, \
+               struct sysdev_attribute *attr, char *buf) \
 { \
        cpuinfo_sparc *c = &cpu_data(dev->id); \
        return sprintf(buf, "%lu\n", c->MEMBER); \
 }
 
 #define SHOW_CPUDATA_UINT_NAME(NAME, MEMBER) \
-static ssize_t show_##NAME(struct sys_device *dev, char *buf) \
+static ssize_t show_##NAME(struct sys_device *dev, \
+               struct sysdev_attribute *attr, char *buf) \
 { \
        cpuinfo_sparc *c = &cpu_data(dev->id); \
        return sprintf(buf, "%u\n", c->MEMBER); \
index e78b3517940b6a252a13d36b544c371341f1aae0..a490077891a4c532e399e062830d3e932269af65 100644 (file)
@@ -224,7 +224,7 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        if (!strcmp(type, "domain-services-port"))
                bus_id_name = "ds";
 
-       if (strlen(bus_id_name) >= KOBJ_NAME_LEN - 4) {
+       if (strlen(bus_id_name) >= BUS_ID_SIZE - 4) {
                printk(KERN_ERR "VIO: bus_id_name [%s] is too long.\n",
                       bus_id_name);
                return NULL;
@@ -260,16 +260,14 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        vio_fill_channel_info(hp, mp, vdev);
 
        if (!id) {
-               snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s",
-                        bus_id_name);
+               dev_set_name(&vdev->dev, "%s", bus_id_name);
                vdev->dev_no = ~(u64)0;
        } else if (!cfg_handle) {
-               snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu",
-                        bus_id_name, *id);
+               dev_set_name(&vdev->dev, "%s-%lu", bus_id_name, *id);
                vdev->dev_no = *id;
        } else {
-               snprintf(vdev->dev.bus_id, BUS_ID_SIZE, "%s-%lu-%lu",
-                        bus_id_name, *cfg_handle, *id);
+               dev_set_name(&vdev->dev, "%s-%lu-%lu", bus_id_name,
+                            *cfg_handle, *id);
                vdev->dev_no = *cfg_handle;
        }
 
@@ -292,12 +290,12 @@ static struct vio_dev *vio_create_one(struct mdesc_handle *hp, u64 mp,
        }
        vdev->dp = dp;
 
-       printk(KERN_INFO "VIO: Adding device %s\n", vdev->dev.bus_id);
+       printk(KERN_INFO "VIO: Adding device %s\n", dev_name(&vdev->dev));
 
        err = device_register(&vdev->dev);
        if (err) {
                printk(KERN_ERR "VIO: Could not register device %s, err=%d\n",
-                      vdev->dev.bus_id, err);
+                      dev_name(&vdev->dev), err);
                kfree(vdev);
                return NULL;
        }
@@ -330,7 +328,7 @@ static void vio_remove(struct mdesc_handle *hp, u64 node)
        dev = device_find_child(&root_vdev->dev, (void *) node,
                                vio_md_node_match);
        if (dev) {
-               printk(KERN_INFO "VIO: Removing device %s\n", dev->bus_id);
+               printk(KERN_INFO "VIO: Removing device %s\n", dev_name(dev));
 
                device_unregister(dev);
        }
index c4a7ec31394c1b9e4abb9971d7d3cfb62228c1bc..9ab65be82427461529b4e4814f151d408cd8d1a4 100644 (file)
@@ -762,10 +762,14 @@ DEFINE_PER_CPU(struct sys_device, device_mce);
 
 /* Why are there no generic functions for this? */
 #define ACCESSOR(name, var, start) \
-       static ssize_t show_ ## name(struct sys_device *s, char *buf) { \
+       static ssize_t show_ ## name(struct sys_device *s,              \
+                                    struct sysdev_attribute *attr,     \
+                                    char *buf) {                       \
                return sprintf(buf, "%lx\n", (unsigned long)var);       \
        }                                                               \
-       static ssize_t set_ ## name(struct sys_device *s,const char *buf,size_t siz) { \
+       static ssize_t set_ ## name(struct sys_device *s,               \
+                                   struct sysdev_attribute *attr,      \
+                                   const char *buf, size_t siz) {      \
                char *end;                                              \
                unsigned long new = simple_strtoul(buf, &end, 0);       \
                if (end == buf) return -EINVAL;                         \
@@ -786,14 +790,16 @@ ACCESSOR(bank3ctl,bank[3],mce_restart())
 ACCESSOR(bank4ctl,bank[4],mce_restart())
 ACCESSOR(bank5ctl,bank[5],mce_restart())
 
-static ssize_t show_trigger(struct sys_device *s, char *buf)
+static ssize_t show_trigger(struct sys_device *s, struct sysdev_attribute *attr,
+                               char *buf)
 {
        strcpy(buf, trigger);
        strcat(buf, "\n");
        return strlen(trigger) + 1;
 }
 
-static ssize_t set_trigger(struct sys_device *s,const char *buf,size_t siz)
+static ssize_t set_trigger(struct sys_device *s, struct sysdev_attribute *attr,
+                               const char *buf,size_t siz)
 {
        char *p;
        int len;
@@ -806,12 +812,12 @@ static ssize_t set_trigger(struct sys_device *s,const char *buf,size_t siz)
 }
 
 static SYSDEV_ATTR(trigger, 0644, show_trigger, set_trigger);
-ACCESSOR(tolerant,tolerant,)
+static SYSDEV_INT_ATTR(tolerant, 0644, tolerant);
 ACCESSOR(check_interval,check_interval,mce_restart())
 static struct sysdev_attribute *mce_attributes[] = {
        &attr_bank0ctl, &attr_bank1ctl, &attr_bank2ctl,
        &attr_bank3ctl, &attr_bank4ctl, &attr_bank5ctl,
-       &attr_tolerant, &attr_check_interval, &attr_trigger,
+       &attr_tolerant.attr, &attr_check_interval, &attr_trigger,
        NULL
 };
 
index 1f4cc48c14c633be4e0a1ca62b1502616337b048..d5ae2243f0b959bf26839c476850faec8a6a4476 100644 (file)
@@ -35,6 +35,7 @@ atomic_t therm_throt_en = ATOMIC_INIT(0);
 
 #define define_therm_throt_sysdev_show_func(name)                            \
 static ssize_t therm_throt_sysdev_show_##name(struct sys_device *dev,        \
+                                       struct sysdev_attribute *attr,       \
                                               char *buf)                     \
 {                                                                            \
        unsigned int cpu = dev->id;                                          \
index 2de5fa2bbf77061c31d686035e0d48ca266c49cf..14b11b3be31ca64d600cb7281edb93f5228809b9 100644 (file)
@@ -141,8 +141,8 @@ static __cpuinit int cpuid_device_create(int cpu)
 {
        struct device *dev;
 
-       dev = device_create(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
-                           "cpu%d", cpu);
+       dev = device_create_drvdata(cpuid_class, NULL, MKDEV(CPUID_MAJOR, cpu),
+                                   NULL, "cpu%d", cpu);
        return IS_ERR(dev) ? PTR_ERR(dev) : 0;
 }
 
index 56b933119a04f5551094ce08feeb12bf2642aa6b..fc4790638b69317bffce8a0992dc92b207f7edf8 100644 (file)
@@ -644,7 +644,9 @@ static void microcode_fini_cpu(int cpu)
        mutex_unlock(&microcode_mutex);
 }
 
-static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz)
+static ssize_t reload_store(struct sys_device *dev,
+                           struct sysdev_attribute *attr,
+                           const char *buf, size_t sz)
 {
        struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
        char *end;
@@ -674,14 +676,16 @@ static ssize_t reload_store(struct sys_device *dev, const char *buf, size_t sz)
        return sz;
 }
 
-static ssize_t version_show(struct sys_device *dev, char *buf)
+static ssize_t version_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
 
        return sprintf(buf, "0x%x\n", uci->rev);
 }
 
-static ssize_t pf_show(struct sys_device *dev, char *buf)
+static ssize_t pf_show(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct ucode_cpu_info *uci = ucode_cpu_info + dev->id;
 
index a153b3905f60591cb6fb627cad9dcc6e529e25cb..9fd8095524474aa7ef0a999c2746c92c8a166565 100644 (file)
@@ -149,8 +149,8 @@ static int __cpuinit msr_device_create(int cpu)
 {
        struct device *dev;
 
-       dev = device_create(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
-                           "msr%d", cpu);
+       dev = device_create_drvdata(msr_class, NULL, MKDEV(MSR_MAJOR, cpu),
+                                   NULL, "msr%d", cpu);
        return IS_ERR(dev) ? PTR_ERR(dev) : 0;
 }
 
index a4213c00dffc355a6a8b8958c85399256a81be40..cbecb05551bbcefeb68e6048bd1dd5aeab5376f7 100644 (file)
@@ -314,8 +314,7 @@ int dma_supported(struct device *dev, u64 mask)
 {
 #ifdef CONFIG_PCI
        if (mask > 0xffffffff && forbid_dac > 0) {
-               printk(KERN_INFO "PCI: Disallowing DAC for device %s\n",
-                                dev->bus_id);
+               dev_info(dev, "PCI: Disallowing DAC for device\n");
                return 0;
        }
 #endif
@@ -342,8 +341,7 @@ int dma_supported(struct device *dev, u64 mask)
           type. Normally this doesn't make any difference, but gives
           more gentle handling of IOMMU overflow. */
        if (iommu_sac_force && (mask >= DMA_40BIT_MASK)) {
-               printk(KERN_INFO "%s: Force SAC with mask %Lx\n",
-                                dev->bus_id, mask);
+               dev_info(dev, "Force SAC with mask %Lx\n", mask);
                return 0;
        }
 
index be60961f8695681b2b96dcda25b694933b5f0d47..df5f142657d27352a9e3c1bbd911fd89f677c1fa 100644 (file)
@@ -198,9 +198,7 @@ static void iommu_full(struct device *dev, size_t size, int dir)
         * out. Hopefully no network devices use single mappings that big.
         */
 
-       printk(KERN_ERR
-               "PCI-DMA: Out of IOMMU space for %lu bytes at device %s\n",
-               size, dev->bus_id);
+       dev_err(dev, "PCI-DMA: Out of IOMMU space for %lu bytes\n", size);
 
        if (size > PAGE_SIZE*EMERGENCY_PAGES) {
                if (dir == PCI_DMA_FROMDEVICE || dir == PCI_DMA_BIDIRECTIONAL)
index 5fb9b0bdbe85b60776eb60bd6486f8f86c629587..5a68b09a69bac112758f83f855ee1a94df785df9 100644 (file)
@@ -1044,7 +1044,8 @@ 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(bsg_class, parent, dev, "%s", devname);
+       class_dev = device_create_drvdata(bsg_class, parent, dev, NULL,
+                                         "%s", devname);
        if (IS_ERR(class_dev)) {
                ret = PTR_ERR(class_dev);
                goto put_dev;
index 9074f384b0970535c9048432065ef043ff231923..c13cc77291af7d1c26378051f7fa1b9770d0f81d 100644 (file)
@@ -183,6 +183,7 @@ static int exact_lock(dev_t devt, void *data)
 void add_disk(struct gendisk *disk)
 {
        struct backing_dev_info *bdi;
+       int retval;
 
        disk->flags |= GENHD_FL_UP;
        blk_register_region(MKDEV(disk->major, disk->first_minor),
@@ -193,7 +194,8 @@ void add_disk(struct gendisk *disk)
 
        bdi = &disk->queue->backing_dev_info;
        bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor));
-       sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi");
+       retval = sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi");
+       WARN_ON(retval);
 }
 
 EXPORT_SYMBOL(add_disk);
@@ -225,89 +227,111 @@ struct gendisk *get_gendisk(dev_t devt, int *part)
 }
 
 /*
- * print a full list of all partitions - intended for places where the root
- * filesystem can't be mounted and thus to give the victim some idea of what
- * went wrong
+ * print a partitions - intended for places where the root filesystem can't be
+ * mounted and thus to give the victim some idea of what went wrong
  */
-void __init printk_all_partitions(void)
+static int printk_partition(struct device *dev, void *data)
 {
-       struct device *dev;
        struct gendisk *sgp;
        char buf[BDEVNAME_SIZE];
        int n;
 
-       mutex_lock(&block_class_lock);
-       /* For each block device... */
-       list_for_each_entry(dev, &block_class.devices, node) {
-               if (dev->type != &disk_type)
-                       continue;
-               sgp = dev_to_disk(dev);
-               /*
-                * Don't show empty devices or things that have been surpressed
-                */
-               if (get_capacity(sgp) == 0 ||
-                   (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO))
-                       continue;
+       if (dev->type != &disk_type)
+               goto exit;
 
-               /*
-                * Note, unlike /proc/partitions, I am showing the numbers in
-                * hex - the same format as the root= option takes.
-                */
-               printk("%02x%02x %10llu %s",
-                       sgp->major, sgp->first_minor,
-                       (unsigned long long)get_capacity(sgp) >> 1,
-                       disk_name(sgp, 0, buf));
-               if (sgp->driverfs_dev != NULL &&
-                   sgp->driverfs_dev->driver != NULL)
-                       printk(" driver: %s\n",
-                               sgp->driverfs_dev->driver->name);
-               else
-                       printk(" (driver?)\n");
-
-               /* now show the partitions */
-               for (n = 0; n < sgp->minors - 1; ++n) {
-                       if (sgp->part[n] == NULL)
-                               continue;
-                       if (sgp->part[n]->nr_sects == 0)
-                               continue;
-                       printk("  %02x%02x %10llu %s\n",
-                               sgp->major, n + 1 + sgp->first_minor,
-                               (unsigned long long)sgp->part[n]->nr_sects >> 1,
-                               disk_name(sgp, n + 1, buf));
-               }
+       sgp = dev_to_disk(dev);
+       /*
+        * Don't show empty devices or things that have been surpressed
+        */
+       if (get_capacity(sgp) == 0 ||
+           (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO))
+               goto exit;
+
+       /*
+        * Note, unlike /proc/partitions, I am showing the numbers in
+        * hex - the same format as the root= option takes.
+        */
+       printk("%02x%02x %10llu %s",
+               sgp->major, sgp->first_minor,
+               (unsigned long long)get_capacity(sgp) >> 1,
+               disk_name(sgp, 0, buf));
+       if (sgp->driverfs_dev != NULL &&
+           sgp->driverfs_dev->driver != NULL)
+               printk(" driver: %s\n",
+                       sgp->driverfs_dev->driver->name);
+       else
+               printk(" (driver?)\n");
+
+       /* now show the partitions */
+       for (n = 0; n < sgp->minors - 1; ++n) {
+               if (sgp->part[n] == NULL)
+                       goto exit;
+               if (sgp->part[n]->nr_sects == 0)
+                       goto exit;
+               printk("  %02x%02x %10llu %s\n",
+                       sgp->major, n + 1 + sgp->first_minor,
+                       (unsigned long long)sgp->part[n]->nr_sects >> 1,
+                       disk_name(sgp, n + 1, buf));
        }
+exit:
+       return 0;
+}
 
+/*
+ * print a full list of all partitions - intended for places where the root
+ * filesystem can't be mounted and thus to give the victim some idea of what
+ * went wrong
+ */
+void __init printk_all_partitions(void)
+{
+       mutex_lock(&block_class_lock);
+       class_for_each_device(&block_class, NULL, NULL, printk_partition);
        mutex_unlock(&block_class_lock);
 }
 
 #ifdef CONFIG_PROC_FS
 /* iterator */
+static int find_start(struct device *dev, void *data)
+{
+       loff_t k = *(loff_t *)data;
+
+       if (dev->type != &disk_type)
+               return 0;
+       if (!k--)
+               return 1;
+       return 0;
+}
+
 static void *part_start(struct seq_file *part, loff_t *pos)
 {
-       loff_t k = *pos;
        struct device *dev;
+       loff_t n = *pos;
+
+       if (!n)
+               seq_puts(part, "major minor  #blocks  name\n\n");
 
        mutex_lock(&block_class_lock);
-       list_for_each_entry(dev, &block_class.devices, node) {
-               if (dev->type != &disk_type)
-                       continue;
-               if (!k--)
-                       return dev_to_disk(dev);
-       }
+       dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
+       if (dev)
+               return dev_to_disk(dev);
        return NULL;
 }
 
+static int find_next(struct device *dev, void *data)
+{
+       if (dev->type == &disk_type)
+               return 1;
+       return 0;
+}
+
 static void *part_next(struct seq_file *part, void *v, loff_t *pos)
 {
        struct gendisk *gp = v;
        struct device *dev;
        ++*pos;
-       list_for_each_entry(dev, &gp->dev.node, node) {
-               if (&dev->node == &block_class.devices)
-                       return NULL;
-               if (dev->type == &disk_type)
-                       return dev_to_disk(dev);
-       }
+       dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
+       if (dev)
+               return dev_to_disk(dev);
        return NULL;
 }
 
@@ -322,9 +346,6 @@ static int show_partition(struct seq_file *part, void *v)
        int n;
        char buf[BDEVNAME_SIZE];
 
-       if (&sgp->dev.node == block_class.devices.next)
-               seq_puts(part, "major minor  #blocks  name\n\n");
-
        /* Don't show non-partitionable removeable devices or empty devices */
        if (!get_capacity(sgp) ||
                        (sgp->minors == 1 && (sgp->flags & GENHD_FL_REMOVABLE)))
@@ -370,7 +391,10 @@ static struct kobject *base_probe(dev_t devt, int *part, void *data)
 
 static int __init genhd_device_init(void)
 {
-       int error = class_register(&block_class);
+       int error;
+
+       block_class.dev_kobj = sysfs_dev_block_kobj;
+       error = class_register(&block_class);
        if (unlikely(error))
                return error;
        bdev_map = kobj_map_init(base_probe, &block_class_lock);
@@ -532,6 +556,7 @@ static struct device_type disk_type = {
        .release        = disk_release,
 };
 
+#ifdef CONFIG_PROC_FS
 /*
  * aggregate disk stat collector.  Uses the same stats that the sysfs
  * entries do, above, but makes them available through one seq_file.
@@ -542,16 +567,12 @@ static struct device_type disk_type = {
 
 static void *diskstats_start(struct seq_file *part, loff_t *pos)
 {
-       loff_t k = *pos;
        struct device *dev;
 
        mutex_lock(&block_class_lock);
-       list_for_each_entry(dev, &block_class.devices, node) {
-               if (dev->type != &disk_type)
-                       continue;
-               if (!k--)
-                       return dev_to_disk(dev);
-       }
+       dev = class_find_device(&block_class, NULL, (void *)pos, find_start);
+       if (dev)
+               return dev_to_disk(dev);
        return NULL;
 }
 
@@ -561,12 +582,9 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos)
        struct device *dev;
 
        ++*pos;
-       list_for_each_entry(dev, &gp->dev.node, node) {
-               if (&dev->node == &block_class.devices)
-                       return NULL;
-               if (dev->type == &disk_type)
-                       return dev_to_disk(dev);
-       }
+       dev = class_find_device(&block_class, &gp->dev, NULL, find_next);
+       if (dev)
+               return dev_to_disk(dev);
        return NULL;
 }
 
@@ -641,6 +659,7 @@ const struct seq_operations diskstats_op = {
        .stop   = diskstats_stop,
        .show   = diskstats_show
 };
+#endif /* CONFIG_PROC_FS */
 
 static void media_change_notify_thread(struct work_struct *work)
 {
@@ -665,24 +684,38 @@ void genhd_media_change_notify(struct gendisk *disk)
 EXPORT_SYMBOL_GPL(genhd_media_change_notify);
 #endif  /*  0  */
 
+struct find_block {
+       const char *name;
+       int part;
+};
+
+static int match_id(struct device *dev, void *data)
+{
+       struct find_block *find = data;
+
+       if (dev->type != &disk_type)
+               return 0;
+       if (strcmp(dev->bus_id, find->name) == 0) {
+               struct gendisk *disk = dev_to_disk(dev);
+               if (find->part < disk->minors)
+                       return 1;
+       }
+       return 0;
+}
+
 dev_t blk_lookup_devt(const char *name, int part)
 {
        struct device *dev;
        dev_t devt = MKDEV(0, 0);
+       struct find_block find;
 
        mutex_lock(&block_class_lock);
-       list_for_each_entry(dev, &block_class.devices, node) {
-               if (dev->type != &disk_type)
-                       continue;
-               if (strcmp(dev->bus_id, name) == 0) {
-                       struct gendisk *disk = dev_to_disk(dev);
-
-                       if (part < disk->minors)
-                               devt = MKDEV(MAJOR(dev->devt),
-                                            MINOR(dev->devt) + part);
-                       break;
-               }
-       }
+       find.name = name;
+       find.part = part;
+       dev = class_find_device(&block_class, NULL, (void *)&find, match_id);
+       if (dev)
+               devt = MKDEV(MAJOR(dev->devt),
+                            MINOR(dev->devt) + part);
        mutex_unlock(&block_class_lock);
 
        return devt;
index 55c17afbe669c86cc6da590994a143fe6d543e77..2655bc1b4eebc7cbb02a16afc715e703dd0e3499 100644 (file)
@@ -263,22 +263,22 @@ static int acpi_fan_add(struct acpi_device *device)
                goto end;
        }
 
-       printk(KERN_INFO PREFIX
-               "%s is registered as cooling_device%d\n",
-               device->dev.bus_id, cdev->id);
+       dev_info(&device->dev, "registered as cooling_device%d\n", cdev->id);
 
        acpi_driver_data(device) = cdev;
        result = sysfs_create_link(&device->dev.kobj,
                                   &cdev->device.kobj,
                                   "thermal_cooling");
        if (result)
-               printk(KERN_ERR PREFIX "Create sysfs link\n");
+               dev_err(&device->dev, "Failed to create sysfs link "
+                       "'thermal_cooling'\n");
 
        result = sysfs_create_link(&cdev->device.kobj,
                                   &device->dev.kobj,
                                   "device");
        if (result)
-               printk(KERN_ERR PREFIX "Create sysfs link\n");
+               dev_err(&device->dev, "Failed to create sysfs link "
+                       "'device'\n");
 
        result = acpi_fan_add_fs(device);
        if (result)
index 2f173e83f8a76bf0291f93689fe075d3fb4e7edf..084109507c9f5101a1cdcf678db34005984a2855 100644 (file)
@@ -146,8 +146,7 @@ static int acpi_bind_one(struct device *dev, acpi_handle handle)
        acpi_status status;
 
        if (dev->archdata.acpi_handle) {
-               printk(KERN_WARNING PREFIX
-                      "Drivers changed 'acpi_handle' for %s\n", dev->bus_id);
+               dev_warn(dev, "Drivers changed 'acpi_handle'\n");
                return -EINVAL;
        }
        get_device(dev);
@@ -195,8 +194,7 @@ static int acpi_unbind_one(struct device *dev)
                /* acpi_bind_one increase refcnt by one */
                put_device(dev);
        } else {
-               printk(KERN_ERR PREFIX
-                      "Oops, 'acpi_handle' corrupt for %s\n", dev->bus_id);
+               dev_err(dev, "Oops, 'acpi_handle' corrupt\n");
        }
        return 0;
 }
index ec0f2d581ece851d67e98f51f4107552f9146f50..e36422a7122c7e974ce9728fce8b97b21e8fe49a 100644 (file)
@@ -714,9 +714,8 @@ static int __cpuinit acpi_processor_start(struct acpi_device *device)
                goto end;
        }
 
-       printk(KERN_INFO PREFIX
-               "%s is registered as cooling_device%d\n",
-               device->dev.bus_id, pr->cdev->id);
+       dev_info(&device->dev, "registered as cooling_device%d\n",
+                pr->cdev->id);
 
        result = sysfs_create_link(&device->dev.kobj,
                                   &pr->cdev->device.kobj,
index f3132aa47a69d7b0656d9fe4fa40e9c5a9f8edcf..f6f52c1a2abad88cecc73a41ea65c4bddfafc0ae 100644 (file)
@@ -471,7 +471,7 @@ static int acpi_device_register(struct acpi_device *device,
        device->dev.release = &acpi_device_release;
        result = device_add(&device->dev);
        if(result) {
-               printk(KERN_ERR PREFIX "Error adding device %s", device->dev.bus_id);
+               dev_err(&device->dev, "Error adding device\n");
                goto end;
        }
 
index 84c795fb9b1ebef3a787907ba372cc368923a6c2..30a3413379334e9ee24071f8d704dc3156bc118c 100644 (file)
@@ -1179,8 +1179,8 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
 
        tz->tz_enabled = 1;
 
-       printk(KERN_INFO PREFIX "%s is registered as thermal_zone%d\n",
-                       tz->device->dev.bus_id, tz->thermal_zone->id);
+       dev_info(&tz->device->dev, "registered as thermal_zone%d\n",
+                tz->thermal_zone->id);
        return 0;
 }
 
index 64c889331f3bd97be35ca4eeb0153e50aae74111..37b9e16710d60596442c780e683d24441e797a61 100644 (file)
@@ -762,9 +762,8 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device)
                if (IS_ERR(device->cdev))
                        return;
 
-               printk(KERN_INFO PREFIX
-                       "%s is registered as cooling_device%d\n",
-                       device->dev->dev.bus_id, device->cdev->id);
+               dev_info(&device->dev->dev, "registered as cooling_device%d\n",
+                        device->cdev->id);
                result = sysfs_create_link(&device->dev->dev.kobj,
                                &device->cdev->device.kobj,
                                "thermal_cooling");
index d47482fa1d212644a5e152b8d8c033e40c9a8626..6318f6b573608f345129234abf85c2629f6df4a1 100644 (file)
@@ -27,8 +27,9 @@ config PREVENT_FIRMWARE_BUILD
          If unsure say Y here.
 
 config FW_LOADER
-       tristate "Userspace firmware loading support"
+       tristate "Userspace firmware loading support" if EMBEDDED
        depends on HOTPLUG
+       default y
        ---help---
          This option is provided for the case where no in-kernel-tree modules
          require userspace firmware loading support, but a module built outside
index 2c9ae43e221933607e81f32b26c40f7156447dc5..31dc0cd84afa2474c8f3a4a511e07c30ef1febe6 100644 (file)
@@ -36,6 +36,33 @@ struct driver_private {
 };
 #define to_driver(obj) container_of(obj, struct driver_private, kobj)
 
+
+/**
+ * struct class_private - structure to hold the private to the driver core portions of the class structure.
+ *
+ * @class_subsys - the struct kset that defines this class.  This is the main kobject
+ * @class_devices - list of devices associated with this class
+ * @class_interfaces - list of class_interfaces associated with this class
+ * @class_dirs - "glue" directory for virtual devices associated with this class
+ * @class_mutex - mutex to protect the children, devices, and interfaces lists.
+ * @class - pointer back to the struct class that this structure is associated
+ * with.
+ *
+ * This structure is the one that is the actual kobject allowing struct
+ * class to be statically allocated safely.  Nothing outside of the driver
+ * core should ever touch these fields.
+ */
+struct class_private {
+       struct kset class_subsys;
+       struct list_head class_devices;
+       struct list_head class_interfaces;
+       struct kset class_dirs;
+       struct mutex class_mutex;
+       struct class *class;
+};
+#define to_class(obj)  \
+       container_of(obj, struct class_private, class_subsys.kobj)
+
 /* initialisation functions */
 extern int devices_init(void);
 extern int buses_init(void);
index e085af0ff94fb93007e7dce12f98443e4c5daa6d..839d27cecb36c8acb3bf8e9e4880ba720e6fe53b 100644 (file)
 #include <linux/err.h>
 #include <linux/slab.h>
 #include <linux/genhd.h>
+#include <linux/mutex.h>
 #include "base.h"
 
 #define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
-#define to_class(obj) container_of(obj, struct class, subsys.kobj)
 
 static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr,
                               char *buf)
 {
        struct class_attribute *class_attr = to_class_attr(attr);
-       struct class *dc = to_class(kobj);
+       struct class_private *cp = to_class(kobj);
        ssize_t ret = -EIO;
 
        if (class_attr->show)
-               ret = class_attr->show(dc, buf);
+               ret = class_attr->show(cp->class, buf);
        return ret;
 }
 
@@ -39,17 +39,18 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr,
                                const char *buf, size_t count)
 {
        struct class_attribute *class_attr = to_class_attr(attr);
-       struct class *dc = to_class(kobj);
+       struct class_private *cp = to_class(kobj);
        ssize_t ret = -EIO;
 
        if (class_attr->store)
-               ret = class_attr->store(dc, buf, count);
+               ret = class_attr->store(cp->class, buf, count);
        return ret;
 }
 
 static void class_release(struct kobject *kobj)
 {
-       struct class *class = to_class(kobj);
+       struct class_private *cp = to_class(kobj);
+       struct class *class = cp->class;
 
        pr_debug("class '%s': release.\n", class->name);
 
@@ -70,7 +71,7 @@ static struct kobj_type class_ktype = {
        .release        = class_release,
 };
 
-/* Hotplug events for classes go to the class_obj subsys */
+/* Hotplug events for classes go to the class class_subsys */
 static struct kset *class_kset;
 
 
@@ -78,7 +79,8 @@ int class_create_file(struct class *cls, const struct class_attribute *attr)
 {
        int error;
        if (cls)
-               error = sysfs_create_file(&cls->subsys.kobj, &attr->attr);
+               error = sysfs_create_file(&cls->p->class_subsys.kobj,
+                                         &attr->attr);
        else
                error = -EINVAL;
        return error;
@@ -87,21 +89,20 @@ int class_create_file(struct class *cls, const struct class_attribute *attr)
 void class_remove_file(struct class *cls, const struct class_attribute *attr)
 {
        if (cls)
-               sysfs_remove_file(&cls->subsys.kobj, &attr->attr);
+               sysfs_remove_file(&cls->p->class_subsys.kobj, &attr->attr);
 }
 
 static struct class *class_get(struct class *cls)
 {
        if (cls)
-               return container_of(kset_get(&cls->subsys),
-                                   struct class, subsys);
-       return NULL;
+               kset_get(&cls->p->class_subsys);
+       return cls;
 }
 
 static void class_put(struct class *cls)
 {
        if (cls)
-               kset_put(&cls->subsys);
+               kset_put(&cls->p->class_subsys);
 }
 
 static int add_class_attrs(struct class *cls)
@@ -134,42 +135,57 @@ static void remove_class_attrs(struct class *cls)
        }
 }
 
-int class_register(struct class *cls)
+int __class_register(struct class *cls, struct lock_class_key *key)
 {
+       struct class_private *cp;
        int error;
 
        pr_debug("device class '%s': registering\n", cls->name);
 
-       INIT_LIST_HEAD(&cls->devices);
-       INIT_LIST_HEAD(&cls->interfaces);
-       kset_init(&cls->class_dirs);
-       init_MUTEX(&cls->sem);
-       error = kobject_set_name(&cls->subsys.kobj, "%s", cls->name);
-       if (error)
+       cp = kzalloc(sizeof(*cp), GFP_KERNEL);
+       if (!cp)
+               return -ENOMEM;
+       INIT_LIST_HEAD(&cp->class_devices);
+       INIT_LIST_HEAD(&cp->class_interfaces);
+       kset_init(&cp->class_dirs);
+       __mutex_init(&cp->class_mutex, "struct class mutex", key);
+       error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name);
+       if (error) {
+               kfree(cp);
                return error;
+       }
+
+       /* set the default /sys/dev directory for devices of this class */
+       if (!cls->dev_kobj)
+               cls->dev_kobj = sysfs_dev_char_kobj;
 
 #if defined(CONFIG_SYSFS_DEPRECATED) && defined(CONFIG_BLOCK)
        /* let the block class directory show up in the root of sysfs */
        if (cls != &block_class)
-               cls->subsys.kobj.kset = class_kset;
+               cp->class_subsys.kobj.kset = class_kset;
 #else
-       cls->subsys.kobj.kset = class_kset;
+       cp->class_subsys.kobj.kset = class_kset;
 #endif
-       cls->subsys.kobj.ktype = &class_ktype;
+       cp->class_subsys.kobj.ktype = &class_ktype;
+       cp->class = cls;
+       cls->p = cp;
 
-       error = kset_register(&cls->subsys);
-       if (!error) {
-               error = add_class_attrs(class_get(cls));
-               class_put(cls);
+       error = kset_register(&cp->class_subsys);
+       if (error) {
+               kfree(cp);
+               return error;
        }
+       error = add_class_attrs(class_get(cls));
+       class_put(cls);
        return error;
 }
+EXPORT_SYMBOL_GPL(__class_register);
 
 void class_unregister(struct class *cls)
 {
        pr_debug("device class '%s': unregistering\n", cls->name);
        remove_class_attrs(cls);
-       kset_unregister(&cls->subsys);
+       kset_unregister(&cls->p->class_subsys);
 }
 
 static void class_create_release(struct class *cls)
@@ -189,7 +205,8 @@ static void class_create_release(struct class *cls)
  * Note, the pointer created here is to be destroyed when finished by
  * making a call to class_destroy().
  */
-struct class *class_create(struct module *owner, const char *name)
+struct class *__class_create(struct module *owner, const char *name,
+                            struct lock_class_key *key)
 {
        struct class *cls;
        int retval;
@@ -204,7 +221,7 @@ struct class *class_create(struct module *owner, const char *name)
        cls->owner = owner;
        cls->class_release = class_create_release;
 
-       retval = class_register(cls);
+       retval = __class_register(cls, key);
        if (retval)
                goto error;
 
@@ -214,6 +231,7 @@ error:
        kfree(cls);
        return ERR_PTR(retval);
 }
+EXPORT_SYMBOL_GPL(__class_create);
 
 /**
  * class_destroy - destroys a struct class structure
@@ -252,39 +270,44 @@ char *make_class_name(const char *name, struct kobject *kobj)
 /**
  * class_for_each_device - device iterator
  * @class: the class we're iterating
+ * @start: the device to start with in the list, if any.
  * @data: data for the callback
  * @fn: function to be called for each device
  *
  * Iterate over @class's list of devices, and call @fn for each,
- * passing it @data.
+ * passing it @data.  If @start is set, the list iteration will start
+ * there, otherwise if it is NULL, the iteration starts at the
+ * beginning of the list.
  *
  * We check the return of @fn each time. If it returns anything
  * other than 0, we break out and return that value.
  *
- * Note, we hold class->sem in this function, so it can not be
+ * Note, we hold class->class_mutex in this function, so it can not be
  * re-acquired in @fn, otherwise it will self-deadlocking. For
  * example, calls to add or remove class members would be verboten.
  */
-int class_for_each_device(struct class *class, void *data,
-                          int (*fn)(struct device *, void *))
+int class_for_each_device(struct class *class, struct device *start,
+                         void *data, int (*fn)(struct device *, void *))
 {
        struct device *dev;
        int error = 0;
 
        if (!class)
                return -EINVAL;
-       down(&class->sem);
-       list_for_each_entry(dev, &class->devices, node) {
+       mutex_lock(&class->p->class_mutex);
+       list_for_each_entry(dev, &class->p->class_devices, node) {
+               if (start) {
+                       if (start == dev)
+                               start = NULL;
+                       continue;
+               }
                dev = get_device(dev);
-               if (dev) {
-                       error = fn(dev, data);
-                       put_device(dev);
-               } else
-                       error = -ENODEV;
+               error = fn(dev, data);
+               put_device(dev);
                if (error)
                        break;
        }
-       up(&class->sem);
+       mutex_unlock(&class->p->class_mutex);
 
        return error;
 }
@@ -293,6 +316,7 @@ EXPORT_SYMBOL_GPL(class_for_each_device);
 /**
  * class_find_device - device iterator for locating a particular device
  * @class: the class we're iterating
+ * @start: Device to begin with
  * @data: data for the match function
  * @match: function to check device
  *
@@ -306,12 +330,13 @@ EXPORT_SYMBOL_GPL(class_for_each_device);
  *
  * Note, you will need to drop the reference with put_device() after use.
  *
- * We hold class->sem in this function, so it can not be
+ * We hold class->class_mutex in this function, so it can not be
  * re-acquired in @match, otherwise it will self-deadlocking. For
  * example, calls to add or remove class members would be verboten.
  */
-struct device *class_find_device(struct class *class, void *data,
-                                  int (*match)(struct device *, void *))
+struct device *class_find_device(struct class *class, struct device *start,
+                                void *data,
+                                int (*match)(struct device *, void *))
 {
        struct device *dev;
        int found = 0;
@@ -319,19 +344,21 @@ struct device *class_find_device(struct class *class, void *data,
        if (!class)
                return NULL;
 
-       down(&class->sem);
-       list_for_each_entry(dev, &class->devices, node) {
+       mutex_lock(&class->p->class_mutex);
+       list_for_each_entry(dev, &class->p->class_devices, node) {
+               if (start) {
+                       if (start == dev)
+                               start = NULL;
+                       continue;
+               }
                dev = get_device(dev);
-               if (dev) {
-                       if (match(dev, data)) {
-                               found = 1;
-                               break;
-                       } else
-                               put_device(dev);
-               } else
+               if (match(dev, data)) {
+                       found = 1;
                        break;
+               } else
+                       put_device(dev);
        }
-       up(&class->sem);
+       mutex_unlock(&class->p->class_mutex);
 
        return found ? dev : NULL;
 }
@@ -349,13 +376,13 @@ int class_interface_register(struct class_interface *class_intf)
        if (!parent)
                return -EINVAL;
 
-       down(&parent->sem);
-       list_add_tail(&class_intf->node, &parent->interfaces);
+       mutex_lock(&parent->p->class_mutex);
+       list_add_tail(&class_intf->node, &parent->p->class_interfaces);
        if (class_intf->add_dev) {
-               list_for_each_entry(dev, &parent->devices, node)
+               list_for_each_entry(dev, &parent->p->class_devices, node)
                        class_intf->add_dev(dev, class_intf);
        }
-       up(&parent->sem);
+       mutex_unlock(&parent->p->class_mutex);
 
        return 0;
 }
@@ -368,13 +395,13 @@ void class_interface_unregister(struct class_interface *class_intf)
        if (!parent)
                return;
 
-       down(&parent->sem);
+       mutex_lock(&parent->p->class_mutex);
        list_del_init(&class_intf->node);
        if (class_intf->remove_dev) {
-               list_for_each_entry(dev, &parent->devices, node)
+               list_for_each_entry(dev, &parent->p->class_devices, node)
                        class_intf->remove_dev(dev, class_intf);
        }
-       up(&parent->sem);
+       mutex_unlock(&parent->p->class_mutex);
 
        class_put(parent);
 }
@@ -389,9 +416,7 @@ int __init classes_init(void)
 
 EXPORT_SYMBOL_GPL(class_create_file);
 EXPORT_SYMBOL_GPL(class_remove_file);
-EXPORT_SYMBOL_GPL(class_register);
 EXPORT_SYMBOL_GPL(class_unregister);
-EXPORT_SYMBOL_GPL(class_create);
 EXPORT_SYMBOL_GPL(class_destroy);
 
 EXPORT_SYMBOL_GPL(class_interface_register);
index ee0a51a3a41d876451395b0f2a93b6a06a430394..7d5c63c81a599fb220b0b2f831c95afaa454caed 100644 (file)
 #include <linux/genhd.h>
 #include <linux/kallsyms.h>
 #include <linux/semaphore.h>
+#include <linux/mutex.h>
 
 #include "base.h"
 #include "power/power.h"
 
 int (*platform_notify)(struct device *dev) = NULL;
 int (*platform_notify_remove)(struct device *dev) = NULL;
+static struct kobject *dev_kobj;
+struct kobject *sysfs_dev_char_kobj;
+struct kobject *sysfs_dev_block_kobj;
 
 #ifdef CONFIG_BLOCK
 static inline int device_is_not_partition(struct device *dev)
@@ -548,7 +552,7 @@ static struct kobject *get_device_parent(struct device *dev,
 {
        /* class devices without a parent live in /sys/class/<classname>/ */
        if (dev->class && (!parent || parent->class != dev->class))
-               return &dev->class->subsys.kobj;
+               return &dev->class->p->class_subsys.kobj;
        /* all other devices keep their parent */
        else if (parent)
                return &parent->kobj;
@@ -594,13 +598,13 @@ static struct kobject *get_device_parent(struct device *dev,
                        parent_kobj = &parent->kobj;
 
                /* find our class-directory at the parent and reference it */
-               spin_lock(&dev->class->class_dirs.list_lock);
-               list_for_each_entry(k, &dev->class->class_dirs.list, entry)
+               spin_lock(&dev->class->p->class_dirs.list_lock);
+               list_for_each_entry(k, &dev->class->p->class_dirs.list, entry)
                        if (k->parent == parent_kobj) {
                                kobj = kobject_get(k);
                                break;
                        }
-               spin_unlock(&dev->class->class_dirs.list_lock);
+               spin_unlock(&dev->class->p->class_dirs.list_lock);
                if (kobj)
                        return kobj;
 
@@ -608,7 +612,7 @@ static struct kobject *get_device_parent(struct device *dev,
                k = kobject_create();
                if (!k)
                        return NULL;
-               k->kset = &dev->class->class_dirs;
+               k->kset = &dev->class->p->class_dirs;
                retval = kobject_add(k, parent_kobj, "%s", dev->class->name);
                if (retval < 0) {
                        kobject_put(k);
@@ -627,7 +631,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir)
 {
        /* see if we live in a "glue" directory */
        if (!glue_dir || !dev->class ||
-           glue_dir->kset != &dev->class->class_dirs)
+           glue_dir->kset != &dev->class->p->class_dirs)
                return;
 
        kobject_put(glue_dir);
@@ -654,17 +658,18 @@ static int device_add_class_symlinks(struct device *dev)
        if (!dev->class)
                return 0;
 
-       error = sysfs_create_link(&dev->kobj, &dev->class->subsys.kobj,
+       error = sysfs_create_link(&dev->kobj,
+                                 &dev->class->p->class_subsys.kobj,
                                  "subsystem");
        if (error)
                goto out;
 
 #ifdef CONFIG_SYSFS_DEPRECATED
        /* stacked class devices need a symlink in the class directory */
-       if (dev->kobj.parent != &dev->class->subsys.kobj &&
+       if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
            device_is_not_partition(dev)) {
-               error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
-                                         dev->bus_id);
+               error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
+                                         &dev->kobj, dev->bus_id);
                if (error)
                        goto out_subsys;
        }
@@ -701,13 +706,14 @@ out_device:
        if (dev->parent && device_is_not_partition(dev))
                sysfs_remove_link(&dev->kobj, "device");
 out_busid:
-       if (dev->kobj.parent != &dev->class->subsys.kobj &&
+       if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
            device_is_not_partition(dev))
-               sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+               sysfs_remove_link(&dev->class->p->class_subsys.kobj,
+                                 dev->bus_id);
 #else
        /* link in the class directory pointing to the device */
-       error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
-                                 dev->bus_id);
+       error = sysfs_create_link(&dev->class->p->class_subsys.kobj,
+                                 &dev->kobj, dev->bus_id);
        if (error)
                goto out_subsys;
 
@@ -720,7 +726,7 @@ out_busid:
        return 0;
 
 out_busid:
-       sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+       sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id);
 #endif
 
 out_subsys:
@@ -746,14 +752,15 @@ static void device_remove_class_symlinks(struct device *dev)
                sysfs_remove_link(&dev->kobj, "device");
        }
 
-       if (dev->kobj.parent != &dev->class->subsys.kobj &&
+       if (dev->kobj.parent != &dev->class->p->class_subsys.kobj &&
            device_is_not_partition(dev))
-               sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+               sysfs_remove_link(&dev->class->p->class_subsys.kobj,
+                                 dev->bus_id);
 #else
        if (dev->parent && device_is_not_partition(dev))
                sysfs_remove_link(&dev->kobj, "device");
 
-       sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
+       sysfs_remove_link(&dev->class->p->class_subsys.kobj, dev->bus_id);
 #endif
 
        sysfs_remove_link(&dev->kobj, "subsystem");
@@ -775,6 +782,54 @@ int dev_set_name(struct device *dev, const char *fmt, ...)
 }
 EXPORT_SYMBOL_GPL(dev_set_name);
 
+/**
+ * device_to_dev_kobj - select a /sys/dev/ directory for the device
+ * @dev: device
+ *
+ * By default we select char/ for new entries.  Setting class->dev_obj
+ * to NULL prevents an entry from being created.  class->dev_kobj must
+ * be set (or cleared) before any devices are registered to the class
+ * otherwise device_create_sys_dev_entry() and
+ * device_remove_sys_dev_entry() will disagree about the the presence
+ * of the link.
+ */
+static struct kobject *device_to_dev_kobj(struct device *dev)
+{
+       struct kobject *kobj;
+
+       if (dev->class)
+               kobj = dev->class->dev_kobj;
+       else
+               kobj = sysfs_dev_char_kobj;
+
+       return kobj;
+}
+
+static int device_create_sys_dev_entry(struct device *dev)
+{
+       struct kobject *kobj = device_to_dev_kobj(dev);
+       int error = 0;
+       char devt_str[15];
+
+       if (kobj) {
+               format_dev_t(devt_str, dev->devt);
+               error = sysfs_create_link(kobj, &dev->kobj, devt_str);
+       }
+
+       return error;
+}
+
+static void device_remove_sys_dev_entry(struct device *dev)
+{
+       struct kobject *kobj = device_to_dev_kobj(dev);
+       char devt_str[15];
+
+       if (kobj) {
+               format_dev_t(devt_str, dev->devt);
+               sysfs_remove_link(kobj, devt_str);
+       }
+}
+
 /**
  * device_add - add device to device hierarchy.
  * @dev: device.
@@ -829,6 +884,10 @@ int device_add(struct device *dev)
                error = device_create_file(dev, &devt_attr);
                if (error)
                        goto ueventattrError;
+
+               error = device_create_sys_dev_entry(dev);
+               if (error)
+                       goto devtattrError;
        }
 
        error = device_add_class_symlinks(dev);
@@ -849,15 +908,16 @@ int device_add(struct device *dev)
                klist_add_tail(&dev->knode_parent, &parent->klist_children);
 
        if (dev->class) {
-               down(&dev->class->sem);
+               mutex_lock(&dev->class->p->class_mutex);
                /* tie the class to the device */
-               list_add_tail(&dev->node, &dev->class->devices);
+               list_add_tail(&dev->node, &dev->class->p->class_devices);
 
                /* notify any interfaces that the device is here */
-               list_for_each_entry(class_intf, &dev->class->interfaces, node)
+               list_for_each_entry(class_intf,
+                                   &dev->class->p->class_interfaces, node)
                        if (class_intf->add_dev)
                                class_intf->add_dev(dev, class_intf);
-               up(&dev->class->sem);
+               mutex_unlock(&dev->class->p->class_mutex);
        }
  Done:
        put_device(dev);
@@ -872,6 +932,9 @@ int device_add(struct device *dev)
  AttrsError:
        device_remove_class_symlinks(dev);
  SymlinkError:
+       if (MAJOR(dev->devt))
+               device_remove_sys_dev_entry(dev);
+ devtattrError:
        if (MAJOR(dev->devt))
                device_remove_file(dev, &devt_attr);
  ueventattrError:
@@ -948,19 +1011,22 @@ void device_del(struct device *dev)
        device_pm_remove(dev);
        if (parent)
                klist_del(&dev->knode_parent);
-       if (MAJOR(dev->devt))
+       if (MAJOR(dev->devt)) {
+               device_remove_sys_dev_entry(dev);
                device_remove_file(dev, &devt_attr);
+       }
        if (dev->class) {
                device_remove_class_symlinks(dev);
 
-               down(&dev->class->sem);
+               mutex_lock(&dev->class->p->class_mutex);
                /* notify any interfaces that the device is now gone */
-               list_for_each_entry(class_intf, &dev->class->interfaces, node)
+               list_for_each_entry(class_intf,
+                                   &dev->class->p->class_interfaces, node)
                        if (class_intf->remove_dev)
                                class_intf->remove_dev(dev, class_intf);
                /* remove the device from the class list */
                list_del_init(&dev->node);
-               up(&dev->class->sem);
+               mutex_unlock(&dev->class->p->class_mutex);
        }
        device_remove_file(dev, &uevent_attr);
        device_remove_attrs(dev);
@@ -1074,7 +1140,25 @@ int __init devices_init(void)
        devices_kset = kset_create_and_add("devices", &device_uevent_ops, NULL);
        if (!devices_kset)
                return -ENOMEM;
+       dev_kobj = kobject_create_and_add("dev", NULL);
+       if (!dev_kobj)
+               goto dev_kobj_err;
+       sysfs_dev_block_kobj = kobject_create_and_add("block", dev_kobj);
+       if (!sysfs_dev_block_kobj)
+               goto block_kobj_err;
+       sysfs_dev_char_kobj = kobject_create_and_add("char", dev_kobj);
+       if (!sysfs_dev_char_kobj)
+               goto char_kobj_err;
+
        return 0;
+
+ char_kobj_err:
+       kobject_put(sysfs_dev_block_kobj);
+ block_kobj_err:
+       kobject_put(dev_kobj);
+ dev_kobj_err:
+       kset_unregister(devices_kset);
+       return -ENOMEM;
 }
 
 EXPORT_SYMBOL_GPL(device_for_each_child);
@@ -1157,49 +1241,12 @@ error:
 }
 EXPORT_SYMBOL_GPL(device_create_vargs);
 
-/**
- * device_create_drvdata - creates a device and registers it with sysfs
- * @class: pointer to the struct class that this device should be registered to
- * @parent: pointer to the parent struct device of this new device, if any
- * @devt: the dev_t for the char device to be added
- * @drvdata: the data to be added to the device for callbacks
- * @fmt: string for the device's name
- *
- * This function can be used by char device classes.  A struct device
- * will be created in sysfs, registered to the specified class.
- *
- * A "dev" file will be created, showing the dev_t for the device, if
- * the dev_t is not 0,0.
- * If a pointer to a parent struct device is passed in, the newly created
- * struct device will be a child of that device in sysfs.
- * The pointer to the struct device will be returned from the call.
- * Any further sysfs files that might be required can be created using this
- * pointer.
- *
- * Note: the struct class passed to this function must have previously
- * been created with a call to class_create().
- */
-struct device *device_create_drvdata(struct class *class,
-                                    struct device *parent,
-                                    dev_t devt,
-                                    void *drvdata,
-                                    const char *fmt, ...)
-{
-       va_list vargs;
-       struct device *dev;
-
-       va_start(vargs, fmt);
-       dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
-       va_end(vargs);
-       return dev;
-}
-EXPORT_SYMBOL_GPL(device_create_drvdata);
-
 /**
  * device_create - creates a device and registers it with sysfs
  * @class: pointer to the struct class that this device should be registered to
  * @parent: pointer to the parent struct device of this new device, if any
  * @devt: the dev_t for the char device to be added
+ * @drvdata: the data to be added to the device for callbacks
  * @fmt: string for the device's name
  *
  * This function can be used by char device classes.  A struct device
@@ -1217,13 +1264,13 @@ EXPORT_SYMBOL_GPL(device_create_drvdata);
  * been created with a call to class_create().
  */
 struct device *device_create(struct class *class, struct device *parent,
-                            dev_t devt, const char *fmt, ...)
+                            dev_t devt, void *drvdata, const char *fmt, ...)
 {
        va_list vargs;
        struct device *dev;
 
        va_start(vargs, fmt);
-       dev = device_create_vargs(class, parent, devt, NULL, fmt, vargs);
+       dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
        va_end(vargs);
        return dev;
 }
@@ -1248,7 +1295,7 @@ void device_destroy(struct class *class, dev_t devt)
 {
        struct device *dev;
 
-       dev = class_find_device(class, &devt, __match_devt);
+       dev = class_find_device(class, NULL, &devt, __match_devt);
        if (dev) {
                put_device(dev);
                device_unregister(dev);
@@ -1298,8 +1345,9 @@ int device_rename(struct device *dev, char *new_name)
        if (old_class_name) {
                new_class_name = make_class_name(dev->class->name, &dev->kobj);
                if (new_class_name) {
-                       error = sysfs_create_link(&dev->parent->kobj,
-                                                 &dev->kobj, new_class_name);
+                       error = sysfs_create_link_nowarn(&dev->parent->kobj,
+                                                        &dev->kobj,
+                                                        new_class_name);
                        if (error)
                                goto out;
                        sysfs_remove_link(&dev->parent->kobj, old_class_name);
@@ -1307,11 +1355,12 @@ int device_rename(struct device *dev, char *new_name)
        }
 #else
        if (dev->class) {
-               error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
-                                         dev->bus_id);
+               error = sysfs_create_link_nowarn(&dev->class->p->class_subsys.kobj,
+                                                &dev->kobj, dev->bus_id);
                if (error)
                        goto out;
-               sysfs_remove_link(&dev->class->subsys.kobj, old_device_name);
+               sysfs_remove_link(&dev->class->p->class_subsys.kobj,
+                                 old_device_name);
        }
 #endif
 
@@ -1447,4 +1496,7 @@ void device_shutdown(void)
                        dev->driver->shutdown(dev);
                }
        }
+       kobject_put(sysfs_dev_char_kobj);
+       kobject_put(sysfs_dev_block_kobj);
+       kobject_put(dev_kobj);
 }
index e38dfed41d80b8e6dff45379ee1fdfb8e8d3c750..20537d507909c5cbc3d166e3dee76cac9e8ce73e 100644 (file)
@@ -21,15 +21,16 @@ EXPORT_SYMBOL(cpu_sysdev_class);
 static DEFINE_PER_CPU(struct sys_device *, cpu_sys_devices);
 
 #ifdef CONFIG_HOTPLUG_CPU
-static ssize_t show_online(struct sys_device *dev, char *buf)
+static ssize_t show_online(struct sys_device *dev, struct sysdev_attribute *attr,
+                          char *buf)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
 
        return sprintf(buf, "%u\n", !!cpu_online(cpu->sysdev.id));
 }
 
-static ssize_t __ref store_online(struct sys_device *dev, const char *buf,
-                           size_t count)
+static ssize_t __ref store_online(struct sys_device *dev, struct sysdev_attribute *attr,
+                                const char *buf, size_t count)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
        ssize_t ret;
@@ -80,7 +81,8 @@ static inline void register_cpu_control(struct cpu *cpu)
 #ifdef CONFIG_KEXEC
 #include <linux/kexec.h>
 
-static ssize_t show_crash_notes(struct sys_device *dev, char *buf)
+static ssize_t show_crash_notes(struct sys_device *dev, struct sysdev_attribute *attr,
+                               char *buf)
 {
        struct cpu *cpu = container_of(dev, struct cpu, sysdev);
        ssize_t rc;
index 937e8258981db78be0b81303d63a8e7ebc30d692..4d4e0e7b6e925e656c8346d63671f0179bca880e 100644 (file)
@@ -92,7 +92,8 @@ unregister_memory(struct memory_block *memory, struct mem_section *section)
  * uses.
  */
 
-static ssize_t show_mem_phys_index(struct sys_device *dev, char *buf)
+static ssize_t show_mem_phys_index(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct memory_block *mem =
                container_of(dev, struct memory_block, sysdev);
@@ -102,7 +103,8 @@ static ssize_t show_mem_phys_index(struct sys_device *dev, char *buf)
 /*
  * online, offline, going offline, etc.
  */
-static ssize_t show_mem_state(struct sys_device *dev, char *buf)
+static ssize_t show_mem_state(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        struct memory_block *mem =
                container_of(dev, struct memory_block, sysdev);
@@ -217,7 +219,8 @@ out:
 }
 
 static ssize_t
-store_mem_state(struct sys_device *dev, const char *buf, size_t count)
+store_mem_state(struct sys_device *dev,
+               struct sysdev_attribute *attr, const char *buf, size_t count)
 {
        struct memory_block *mem;
        unsigned int phys_section_nr;
@@ -248,7 +251,8 @@ out:
  * s.t. if I offline all of these sections I can then
  * remove the physical device?
  */
-static ssize_t show_phys_device(struct sys_device *dev, char *buf)
+static ssize_t show_phys_device(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        struct memory_block *mem =
                container_of(dev, struct memory_block, sysdev);
index 0f867a0833387fc7cfa5094450593c94f4905486..5116b78c632586884a19ab8b8329b798bc5cce14 100644 (file)
@@ -36,11 +36,13 @@ static ssize_t node_read_cpumap(struct sys_device *dev, int type, char *buf)
        return len;
 }
 
-static inline ssize_t node_read_cpumask(struct sys_device *dev, char *buf)
+static inline ssize_t node_read_cpumask(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        return node_read_cpumap(dev, 0, buf);
 }
-static inline ssize_t node_read_cpulist(struct sys_device *dev, char *buf)
+static inline ssize_t node_read_cpulist(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        return node_read_cpumap(dev, 1, buf);
 }
@@ -49,7 +51,8 @@ static SYSDEV_ATTR(cpumap,  S_IRUGO, node_read_cpumask, NULL);
 static SYSDEV_ATTR(cpulist, S_IRUGO, node_read_cpulist, NULL);
 
 #define K(x) ((x) << (PAGE_SHIFT - 10))
-static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
+static ssize_t node_read_meminfo(struct sys_device * dev,
+                       struct sysdev_attribute *attr, char * buf)
 {
        int n;
        int nid = dev->id;
@@ -112,7 +115,8 @@ static ssize_t node_read_meminfo(struct sys_device * dev, char * buf)
 #undef K
 static SYSDEV_ATTR(meminfo, S_IRUGO, node_read_meminfo, NULL);
 
-static ssize_t node_read_numastat(struct sys_device * dev, char * buf)
+static ssize_t node_read_numastat(struct sys_device * dev,
+                               struct sysdev_attribute *attr, char * buf)
 {
        return sprintf(buf,
                       "numa_hit %lu\n"
@@ -130,7 +134,8 @@ static ssize_t node_read_numastat(struct sys_device * dev, char * buf)
 }
 static SYSDEV_ATTR(numastat, S_IRUGO, node_read_numastat, NULL);
 
-static ssize_t node_read_distance(struct sys_device * dev, char * buf)
+static ssize_t node_read_distance(struct sys_device * dev,
+                       struct sysdev_attribute *attr, char * buf)
 {
        int nid = dev->id;
        int len = 0;
index 9b1b20b59e0a7b2dcc61bad05f078813e65f92fe..2aa6e8fc4defff41ffaa63745baa3a54029ece80 100644 (file)
@@ -194,7 +194,7 @@ static int show_dev_hash(unsigned int value)
                struct device * dev = to_device(entry);
                unsigned int hash = hash_string(DEVSEED, dev->bus_id, DEVHASH);
                if (hash == value) {
-                       printk("  hash matches device %s\n", dev->bus_id);
+                       dev_info(dev, "hash matches\n");
                        match++;
                }
                entry = entry->prev;
index 358bb0be3c0838b9233bae7b1eab1cc2b05ef1e6..40fc14f035402ec70de718977e309932dce7b576 100644 (file)
@@ -36,7 +36,7 @@ sysdev_show(struct kobject * kobj, struct attribute * attr, char * buffer)
        struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
 
        if (sysdev_attr->show)
-               return sysdev_attr->show(sysdev, buffer);
+               return sysdev_attr->show(sysdev, sysdev_attr, buffer);
        return -EIO;
 }
 
@@ -49,7 +49,7 @@ sysdev_store(struct kobject * kobj, struct attribute * attr,
        struct sysdev_attribute * sysdev_attr = to_sysdev_attr(attr);
 
        if (sysdev_attr->store)
-               return sysdev_attr->store(sysdev, buffer, count);
+               return sysdev_attr->store(sysdev, sysdev_attr, buffer, count);
        return -EIO;
 }
 
@@ -130,8 +130,8 @@ static struct kset *system_kset;
 
 int sysdev_class_register(struct sysdev_class * cls)
 {
-       pr_debug("Registering sysdev class '%s'\n",
-                kobject_name(&cls->kset.kobj));
+       pr_debug("Registering sysdev class '%s'\n", cls->name);
+
        INIT_LIST_HEAD(&cls->drivers);
        memset(&cls->kset.kobj, 0x00, sizeof(struct kobject));
        cls->kset.kobj.parent = &system_kset->kobj;
@@ -241,7 +241,8 @@ int sysdev_register(struct sys_device * sysdev)
        if (!cls)
                return -EINVAL;
 
-       pr_debug("Registering sys device '%s'\n", kobject_name(&sysdev->kobj));
+       pr_debug("Registering sys device of class '%s'\n",
+                kobject_name(&cls->kset.kobj));
 
        /* initialize the kobject to 0, in case it had previously been used */
        memset(&sysdev->kobj, 0x00, sizeof(struct kobject));
@@ -257,6 +258,9 @@ int sysdev_register(struct sys_device * sysdev)
        if (!error) {
                struct sysdev_driver * drv;
 
+               pr_debug("Registering sys device '%s'\n",
+                        kobject_name(&sysdev->kobj));
+
                mutex_lock(&sysdev_drivers_lock);
                /* Generic notification is implicit, because it's that
                 * code that should have called us.
@@ -269,6 +273,7 @@ int sysdev_register(struct sys_device * sysdev)
                }
                mutex_unlock(&sysdev_drivers_lock);
        }
+
        kobject_uevent(&sysdev->kobj, KOBJ_ADD);
        return error;
 }
@@ -474,3 +479,52 @@ int __init system_bus_init(void)
 
 EXPORT_SYMBOL_GPL(sysdev_register);
 EXPORT_SYMBOL_GPL(sysdev_unregister);
+
+#define to_ext_attr(x) container_of(x, struct sysdev_ext_attribute, attr)
+
+ssize_t sysdev_store_ulong(struct sys_device *sysdev,
+                          struct sysdev_attribute *attr,
+                          const char *buf, size_t size)
+{
+       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
+       char *end;
+       unsigned long new = simple_strtoul(buf, &end, 0);
+       if (end == buf)
+               return -EINVAL;
+       *(unsigned long *)(ea->var) = new;
+       return end - buf;
+}
+EXPORT_SYMBOL_GPL(sysdev_store_ulong);
+
+ssize_t sysdev_show_ulong(struct sys_device *sysdev,
+                         struct sysdev_attribute *attr,
+                         char *buf)
+{
+       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
+       return snprintf(buf, PAGE_SIZE, "%lx\n", *(unsigned long *)(ea->var));
+}
+EXPORT_SYMBOL_GPL(sysdev_show_ulong);
+
+ssize_t sysdev_store_int(struct sys_device *sysdev,
+                          struct sysdev_attribute *attr,
+                          const char *buf, size_t size)
+{
+       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
+       char *end;
+       long new = simple_strtol(buf, &end, 0);
+       if (end == buf || new > INT_MAX || new < INT_MIN)
+               return -EINVAL;
+       *(int *)(ea->var) = new;
+       return end - buf;
+}
+EXPORT_SYMBOL_GPL(sysdev_store_int);
+
+ssize_t sysdev_show_int(struct sys_device *sysdev,
+                         struct sysdev_attribute *attr,
+                         char *buf)
+{
+       struct sysdev_ext_attribute *ea = to_ext_attr(attr);
+       return snprintf(buf, PAGE_SIZE, "%d\n", *(int *)(ea->var));
+}
+EXPORT_SYMBOL_GPL(sysdev_show_int);
+
index 3f6d9b0a6abed354ca07527e0294c8042dcc8ae0..199cd97e32e64b2c56338b2d74eb68ab5ce01de3 100644 (file)
@@ -34,7 +34,8 @@
 static SYSDEV_ATTR(_name, 0444, show_##_name, NULL)
 
 #define define_id_show_func(name)                              \
-static ssize_t show_##name(struct sys_device *dev, char *buf)  \
+static ssize_t show_##name(struct sys_device *dev,             \
+               struct sysdev_attribute *attr, char *buf)       \
 {                                                              \
        unsigned int cpu = dev->id;                             \
        return sprintf(buf, "%d\n", topology_##name(cpu));      \
@@ -59,14 +60,17 @@ static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf)
 
 #ifdef arch_provides_topology_pointers
 #define define_siblings_show_map(name)                                 \
-static ssize_t show_##name(struct sys_device *dev, char *buf)  \
+static ssize_t show_##name(struct sys_device *dev,                     \
+                          struct sysdev_attribute *attr, char *buf)    \
 {                                                                      \
        unsigned int cpu = dev->id;                                     \
        return show_cpumap(0, &(topology_##name(cpu)), buf);            \
 }
 
 #define define_siblings_show_list(name)                                        \
-static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \
+static ssize_t show_##name##_list(struct sys_device *dev,              \
+                                 struct sysdev_attribute *attr,        \
+                                 char *buf)                            \
 {                                                                      \
        unsigned int cpu = dev->id;                                     \
        return show_cpumap(1, &(topology_##name(cpu)), buf);            \
@@ -74,7 +78,8 @@ static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \
 
 #else
 #define define_siblings_show_map(name)                                 \
-static ssize_t show_##name(struct sys_device *dev, char *buf)  \
+static ssize_t show_##name(struct sys_device *dev,                     \
+                          struct sysdev_attribute *attr, char *buf)    \
 {                                                                      \
        unsigned int cpu = dev->id;                                     \
        cpumask_t mask = topology_##name(cpu);                          \
@@ -82,7 +87,9 @@ static ssize_t show_##name(struct sys_device *dev, char *buf) \
 }
 
 #define define_siblings_show_list(name)                                        \
-static ssize_t show_##name##_list(struct sys_device *dev, char *buf) \
+static ssize_t show_##name##_list(struct sys_device *dev,              \
+                                 struct sysdev_attribute *attr,        \
+                                 char *buf)                            \
 {                                                                      \
        unsigned int cpu = dev->id;                                     \
        cpumask_t mask = topology_##name(cpu);                          \
index d1de68a3192088b11f20317d5405d05c35cd5071..c04440cd6a32d5bc5031aed5ec4fe50c4d50dd67 100644 (file)
@@ -277,8 +277,9 @@ aoechr_init(void)
                return PTR_ERR(aoe_class);
        }
        for (i = 0; i < ARRAY_SIZE(chardevs); ++i)
-               device_create(aoe_class, NULL,
-                             MKDEV(AOE_MAJOR, chardevs[i].minor), chardevs[i].name);
+               device_create_drvdata(aoe_class, NULL,
+                                     MKDEV(AOE_MAJOR, chardevs[i].minor),
+                                     NULL, chardevs[i].name);
 
        return 0;
 }
index 9d92636350e5f67f1d2ebd7b60466859b4e301f9..d731ca42f8024f48a12214b064ed5ff3d13b8543 100644 (file)
@@ -686,8 +686,9 @@ static int __init pg_init(void)
        for (unit = 0; unit < PG_UNITS; unit++) {
                struct pg *dev = &devices[unit];
                if (dev->present)
-                       device_create(pg_class, NULL, MKDEV(major, unit),
-                                     "pg%u", unit);
+                       device_create_drvdata(pg_class, NULL,
+                                             MKDEV(major, unit), NULL,
+                                             "pg%u", unit);
        }
        err = 0;
        goto out;
index 5c74c3574a5adf77bb9120d77e9f45442cb3debe..673b8b2fd337a1e22b442eba939aa4c90a407b86 100644 (file)
@@ -979,10 +979,12 @@ static int __init pt_init(void)
 
        for (unit = 0; unit < PT_UNITS; unit++)
                if (pt[unit].present) {
-                       device_create(pt_class, NULL, MKDEV(major, unit),
-                                     "pt%d", unit);
-                       device_create(pt_class, NULL, MKDEV(major, unit + 128),
-                                     "pt%dn", unit);
+                       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);
                }
        goto out;
 
index 45bee918c46a821e5a5c4ec3c2a74ad96b8d8e72..158eed4d516188deb82b50b9f60ddbbd502b8302 100644 (file)
@@ -303,7 +303,9 @@ 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(class_pktcdvd, NULL, pd->pkt_dev, "%s", pd->name);
+               pd->dev = device_create_drvdata(class_pktcdvd, NULL,
+                                               pd->pkt_dev, NULL,
+                                               "%s", pd->name);
                if (IS_ERR(pd->dev))
                        pd->dev = NULL;
        }
index b9a30c30e2b8682a85822c764b8b05f3bd3bdb79..33c466a4888f092c15475601b503a473808a20fc 100644 (file)
@@ -500,7 +500,8 @@ static int __init dsp56k_init_driver(void)
                err = PTR_ERR(dsp56k_class);
                goto out_chrdev;
        }
-       device_create(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0), "dsp56k");
+       device_create_drvdata(dsp56k_class, NULL, MKDEV(DSP56K_MAJOR, 0),
+                             NULL, "dsp56k");
 
        printk(banner);
        goto out;
index 5dc74404058f6eb46941a4af8bad71dfe3a5229e..9cb48fcd316c775007e596dc66a6adb0494ddfd9 100644 (file)
@@ -718,12 +718,12 @@ ip2_loadmain(int *iop, int *irqp)
                        }
 
                        if ( NULL != ( pB = i2BoardPtrTable[i] ) ) {
-                               device_create(ip2_class, NULL,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i),
-                                               "ipl%d", i);
-                               device_create(ip2_class, NULL,
-                                               MKDEV(IP2_IPL_MAJOR, 4 * i + 1),
-                                               "stat%d", i);
+                               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);
 
                            for ( box = 0; box < ABS_MAX_BOXES; ++box )
                            {
index c11a40483459f3bd581dd5429f65606b1d882f67..64e1c169e826814c922c6937f738424ba819891b 100644 (file)
@@ -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(ipmi_class, device, dev, "ipmi%d", if_num);
+       device_create_drvdata(ipmi_class, device, dev, NULL, "ipmi%d", if_num);
        list_add(&entry->link, &reg_list);
        mutex_unlock(&reg_list_mutex);
 }
index f9ebcd41d8e5dd765643a10cc76a5b6a88910638..843a2afaf2040f2a641af8ea33a4f10b570e5a04 100644 (file)
@@ -4599,8 +4599,9 @@ static int __init istallion_module_init(void)
 
        istallion_class = class_create(THIS_MODULE, "staliomem");
        for (i = 0; i < 4; i++)
-               device_create(istallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
-                             "staliomem%d", i);
+               device_create_drvdata(istallion_class, NULL,
+                                     MKDEV(STL_SIOMEMMAJOR, i),
+                                     NULL, "staliomem%d", i);
 
        return 0;
 err_deinit:
index 71abb4c33aa249d748826a317be08a3b8a4f7cd9..3f2719b9f77b5fca364477dfa7d096c66be759cb 100644 (file)
@@ -813,7 +813,8 @@ static int lp_register(int nr, struct parport *port)
        if (reset)
                lp_reset(nr);
 
-       device_create(lp_class, port->dev, MKDEV(LP_MAJOR, nr), "lp%d", nr);
+       device_create_drvdata(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");
index b6772d657547a4e25f275f2a1bd4bc29ac3188e4..c2dba82eb5f7fa82bdb874b17f605ab01f80fb1f 100644 (file)
@@ -989,9 +989,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(mem_class, NULL,
-                             MKDEV(MEM_MAJOR, devlist[i].minor),
-                             devlist[i].name);
+               device_create_drvdata(mem_class, NULL,
+                                     MKDEV(MEM_MAJOR, devlist[i].minor),
+                                     NULL, devlist[i].name);
 
        return 0;
 }
index 6e1563c3d30aea0da63650ea8a3a64daaf6727be..999aa779c08a710601fabc93cacb6f52229c53ba 100644 (file)
@@ -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(misc_class, misc->parent, dev,
-                                         "%s", misc->name);
+       misc->this_device = device_create_drvdata(misc_class, misc->parent,
+                                                 dev, NULL, "%s", misc->name);
        if (IS_ERR(misc->this_device)) {
                err = PTR_ERR(misc->this_device);
                goto out;
index e4a4fbd37d7a3062cd8d91faf397cbdf28443186..f070ae7bd91a1d905eab711a6ee8d013ae8f3eeb 100644 (file)
@@ -1896,7 +1896,7 @@ static int cm4000_probe(struct pcmcia_device *link)
                return ret;
        }
 
-       device_create(cmm_class, NULL, MKDEV(major, i), "cmm%d", i);
+       device_create_drvdata(cmm_class, NULL, MKDEV(major, i), NULL, "cmm%d", i);
 
        return 0;
 }
index 6181f8a9b0bd0309cb4670dd0d572af91fc8689f..0b5934bef7a4301049f19c8d82393544742f4a84 100644 (file)
@@ -653,7 +653,8 @@ static int reader_probe(struct pcmcia_device *link)
                return ret;
        }
 
-       device_create(cmx_class, NULL, MKDEV(major, i), "cmx%d", i);
+       device_create_drvdata(cmx_class, NULL, MKDEV(major, i), NULL,
+                             "cmx%d", i);
 
        return 0;
 }
index f6e6acadd9a017d98b562a9c2f2da7178a412161..7af7a7e6b9c2e570ff53eff4152e5f61d6cf7738 100644 (file)
@@ -752,8 +752,9 @@ static const struct file_operations pp_fops = {
 
 static void pp_attach(struct parport *port)
 {
-       device_create(ppdev_class, port->dev, MKDEV(PP_MAJOR, port->number),
-                       "parport%d", port->number);
+       device_create_drvdata(ppdev_class, port->dev,
+                             MKDEV(PP_MAJOR, port->number),
+                             NULL, "parport%d", port->number);
 }
 
 static void pp_detach(struct parport *port)
index 505fcbe884a4aad394ae212396677d258b3d25fb..47b8cf281d4a79766c0717dec1ea4380d2bf9717 100644 (file)
@@ -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(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
-                     "raw%d", rq->raw_minor);
+       device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, rq->raw_minor),
+                             NULL, "raw%d", rq->raw_minor);
 }
 
 /*
@@ -283,7 +283,8 @@ static int __init raw_init(void)
                ret = PTR_ERR(raw_class);
                goto error_region;
        }
-       device_create(raw_class, NULL, MKDEV(RAW_MAJOR, 0), "rawctl");
+       device_create_drvdata(raw_class, NULL, MKDEV(RAW_MAJOR, 0), NULL,
+                             "rawctl");
 
        return 0;
 
index 0b799ac1b04957f501d4c50539f58e7ee28199cd..3ce60df14c0a623f5aff950148f034938988a5f9 100644 (file)
@@ -444,7 +444,8 @@ scdrv_init(void)
                                continue;
                        }
 
-                       device_create(snsc_class, NULL, dev, "%s", devname);
+                       device_create_drvdata(snsc_class, NULL, dev, NULL,
+                                             "%s", devname);
 
                        ia64_sn_irtr_intr_enable(scd->scd_nasid,
                                                 0 /*ignored */ ,
index de5a725c3cc0493ddfcdb19f9074561c584638b4..b976248e10727dd7f8e8610dc02da65efa064828 100644 (file)
@@ -4755,8 +4755,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(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
-                             "staliomem%d", i);
+               device_create_drvdata(stallion_class, NULL, MKDEV(STL_SIOMEMMAJOR, i),
+                                     NULL, "staliomem%d", i);
 
        return 0;
 err_unrtty:
index d94cd8410c539aed537c59ba69a9227b3e4fe0e9..15e597d030026b4b45ee5d6e61d306b379fa5dde 100644 (file)
@@ -3412,7 +3412,7 @@ struct device *tty_register_device(struct tty_driver *driver, unsigned index,
        else
                tty_line_name(driver, index, name);
 
-       return device_create(tty_class, device, dev, name);
+       return device_create_drvdata(tty_class, device, dev, NULL, name);
 }
 
 /**
@@ -3690,20 +3690,22 @@ static int __init tty_init(void)
        if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
                panic("Couldn't register /dev/tty driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), "tty");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
+                             "tty");
 
        cdev_init(&console_cdev, &console_fops);
        if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
                panic("Couldn't register /dev/console driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), "console");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
+                             "console");
 
 #ifdef CONFIG_UNIX98_PTYS
        cdev_init(&ptmx_cdev, &ptmx_fops);
        if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
                panic("Couldn't register /dev/ptmx driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), "ptmx");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
 #endif
 
 #ifdef CONFIG_VT
@@ -3711,7 +3713,7 @@ static int __init tty_init(void)
        if (cdev_add(&vc0_cdev, MKDEV(TTY_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTY_MAJOR, 0), 1, "/dev/vc/0") < 0)
                panic("Couldn't register /dev/tty0 driver\n");
-       device_create(tty_class, NULL, MKDEV(TTY_MAJOR, 0), "tty0");
+       device_create_drvdata(tty_class, NULL, MKDEV(TTY_MAJOR, 0), NULL, "tty0");
 
        vty_init();
 #endif
index eebfad2777d29ac9bfd7134eab259c11c7bd5a79..c2ae52dd53d1a6447affa697afaa53c9f9f9f7f7 100644 (file)
@@ -481,10 +481,10 @@ static struct class *vc_class;
 
 void vcs_make_sysfs(struct tty_struct *tty)
 {
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 1),
-                       "vcs%u", tty->index + 1);
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, tty->index + 129),
-                       "vcsa%u", tty->index + 1);
+       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);
 }
 
 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(vc_class, NULL, MKDEV(VCS_MAJOR, 0), "vcs");
-       device_create(vc_class, NULL, MKDEV(VCS_MAJOR, 128), "vcsa");
+       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 0), NULL, "vcs");
+       device_create_drvdata(vc_class, NULL, MKDEV(VCS_MAJOR, 128), NULL, "vcsa");
        return 0;
 }
index e5da98d8f9cd70f493ecb8c9d7521639f937e779..7a70a40ad639855b4f3880386ef7b34f47d71f46 100644 (file)
@@ -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(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i),
-                       "iseries!vt%d", i);
-       device_create(tape_class, NULL, MKDEV(VIOTAPE_MAJOR, i | 0x80),
-                       "iseries!nvt%d", i);
+       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);
        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,
index 935f1c207a1f0edfe7056fee448e4ff337164229..e32a076d5f1f8f182025341d98d3a89f25a9f4f8 100644 (file)
@@ -3425,9 +3425,10 @@ int register_con_driver(const struct consw *csw, int first, int last)
        if (retval)
                goto err;
 
-       con_driver->dev = device_create(vtconsole_class, NULL,
-                                       MKDEV(0, con_driver->node),
-                                       "vtcon%i", con_driver->node);
+       con_driver->dev = device_create_drvdata(vtconsole_class, NULL,
+                                               MKDEV(0, con_driver->node),
+                                               NULL, "vtcon%i",
+                                               con_driver->node);
 
        if (IS_ERR(con_driver->dev)) {
                printk(KERN_WARNING "Unable to create device for %s; "
@@ -3535,9 +3536,10 @@ static int __init vtconsole_class_init(void)
                struct con_driver *con = &registered_con_driver[i];
 
                if (con->con && !con->dev) {
-                       con->dev = device_create(vtconsole_class, NULL,
-                                                MKDEV(0, con->node),
-                                                "vtcon%i", con->node);
+                       con->dev = device_create_drvdata(vtconsole_class, NULL,
+                                                        MKDEV(0, con->node),
+                                                        NULL, "vtcon%i",
+                                                        con->node);
 
                        if (IS_ERR(con->dev)) {
                                printk(KERN_WARNING "Unable to create "
index 1e1b81e57cdcf7060739a42bd6862d2d5a2caab7..51966ccf4ea3f56c4449f88c93906ab81e136111 100644 (file)
@@ -658,8 +658,9 @@ static int __devinit hwicap_setup(struct device *dev, int id,
                dev_err(dev, "cdev_add() failed\n");
                goto failed3;
        }
-       /*  devfs_mk_cdev(devt, S_IFCHR|S_IRUGO|S_IWUGO, DRIVER_NAME); */
-       device_create(icap_class, dev, devt, "%s%d", DRIVER_NAME, id);
+
+       device_create_drvdata(icap_class, dev, devt, NULL,
+                             "%s%d", DRIVER_NAME, id);
        return 0;               /* success */
 
  failed3:
index e949618b9be0ee3d0e95b48bbac4fd5f93ad21f2..31a0e0b455b6e3c61ffef1ef004351fac0085dcd 100644 (file)
@@ -21,7 +21,8 @@ static int __init cpuidle_sysfs_setup(char *unused)
 }
 __setup("cpuidle_sysfs_switch", cpuidle_sysfs_setup);
 
-static ssize_t show_available_governors(struct sys_device *dev, char *buf)
+static ssize_t show_available_governors(struct sys_device *dev,
+               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t i = 0;
        struct cpuidle_governor *tmp;
@@ -39,7 +40,8 @@ out:
        return i;
 }
 
-static ssize_t show_current_driver(struct sys_device *dev, char *buf)
+static ssize_t show_current_driver(struct sys_device *dev,
+               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t ret;
 
@@ -53,7 +55,8 @@ static ssize_t show_current_driver(struct sys_device *dev, char *buf)
        return ret;
 }
 
-static ssize_t show_current_governor(struct sys_device *dev, char *buf)
+static ssize_t show_current_governor(struct sys_device *dev,
+                       struct sysdev_attribute *attr, char *buf)
 {
        ssize_t ret;
 
@@ -68,6 +71,7 @@ static ssize_t show_current_governor(struct sys_device *dev, char *buf)
 }
 
 static ssize_t store_current_governor(struct sys_device *dev,
+       struct sysdev_attribute *attr,
        const char *buf, size_t count)
 {
        char gov_name[CPUIDLE_NAME_LEN];
index 011328faa5f21c88b1c007eb405129137e709a87..9a70377bfb34e808e954afb266eb5218f8bb7982 100644 (file)
@@ -14,8 +14,9 @@ int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
 {
        struct device *cd;
 
-       cd = device_create(dca_class, dca->cd, MKDEV(0, slot + 1),
-                          "requester%d", slot);
+       cd = device_create_drvdata(dca_class, dca->cd,
+                                  MKDEV(0, slot + 1), NULL,
+                                  "requester%d", slot);
        if (IS_ERR(cd))
                return PTR_ERR(cd);
        return 0;
@@ -46,7 +47,8 @@ idr_try_again:
                return err;
        }
 
-       cd = device_create(dca_class, dev, MKDEV(0, 0), "dca%d", dca->id);
+       cd = device_create_drvdata(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);
index 70abf93fe6b0e823239409613aa28ca1e2045d71..5369ce957c6d5397146cbbcb71c75aed01ebaa57 100644 (file)
@@ -9,7 +9,7 @@ obj-${CONFIG_EISA_VIRTUAL_ROOT} += virtual_root.o
 
 
 # Ugly hack to get DEVICE_NAME_SIZE value...
-DEVICE_NAME_SIZE =$(shell awk '$$1=="\#define" && $$2=="DEVICE_NAME_SIZE" {print $$3-1}' $(srctree)/include/linux/device.h)
+DEVICE_NAME_SIZE = 50
 
 $(obj)/eisa-bus.o: $(obj)/devlist.h
 
index 65dcf0432653b51b1593f94a4ae237584fe3a907..c950bf8606d967b07639ed14e0bfd643136df57d 100644 (file)
@@ -22,7 +22,7 @@
 
 struct eisa_device_info {
        struct eisa_device_id id;
-       char name[DEVICE_NAME_SIZE];
+       char name[50];
 };
 
 #ifdef CONFIG_EISA_NAMES
@@ -63,7 +63,7 @@ static void __init eisa_name_device (struct eisa_device *edev)
                if (!strcmp (edev->id.sig, eisa_table[i].id.sig)) {
                        strlcpy (edev->pretty_name,
                                 eisa_table[i].name,
-                                DEVICE_NAME_SIZE);
+                                sizeof(edev->pretty_name));
                        return;
                }
        }
index 2fde6c63f47dffa2d89c224cd15c1be215d4d20e..0c6b4d4e7e2700ee9135d2729b8c388f7d8c6118 100644 (file)
@@ -322,8 +322,9 @@ int hidraw_connect(struct hid_device *hid)
                goto out;
        }
 
-       dev->dev = device_create(hidraw_class, NULL, MKDEV(hidraw_major, minor),
-                               "%s%d", "hidraw", minor);
+       dev->dev = device_create_drvdata(hidraw_class, NULL,
+                                        MKDEV(hidraw_major, minor), NULL,
+                                        "%s%d", "hidraw", minor);
 
        if (IS_ERR(dev->dev)) {
                spin_lock(&minors_lock);
index 3db28450a3b34504facc27cc8a9611a8e53569cd..7321a88a51128adef8ba40016e03f0648b7e4a97 100644 (file)
@@ -55,7 +55,8 @@ again:
                return ERR_PTR(err);
 
        id = id & MAX_ID_MASK;
-       hwdev = device_create(hwmon_class, dev, MKDEV(0,0), HWMON_ID_FORMAT, id);
+       hwdev = device_create_drvdata(hwmon_class, dev, MKDEV(0, 0), NULL,
+                                     HWMON_ID_FORMAT, id);
 
        if (IS_ERR(hwdev)) {
                spin_lock(&idr_lock);
index 7608df83d6d1e0625a8b0de306a799dac62143d3..7bf38c418086e45aee6f7d6ba47f256eb65e47f6 100644 (file)
@@ -722,7 +722,8 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
 
        INIT_LIST_HEAD(&driver->clients);
        /* Walk the adapters that are already present */
-       class_for_each_device(&i2c_adapter_class, driver, __attach_adapter);
+       class_for_each_device(&i2c_adapter_class, NULL, driver,
+                             __attach_adapter);
 
        mutex_unlock(&core_lock);
        return 0;
@@ -782,7 +783,8 @@ void i2c_del_driver(struct i2c_driver *driver)
 {
        mutex_lock(&core_lock);
 
-       class_for_each_device(&i2c_adapter_class, driver, __detach_adapter);
+       class_for_each_device(&i2c_adapter_class, NULL, driver,
+                             __detach_adapter);
 
        driver_unregister(&driver->driver);
        pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
index 86727fa8858fcf808a1a1373efe0ecc46a2e5678..9d55c6383b2323bd908b782095420196498842aa 100644 (file)
@@ -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(i2c_dev_class, &adap->dev,
-                                    MKDEV(I2C_MAJOR, adap->nr),
-                                    "i2c-%d", adap->nr);
+       i2c_dev->dev = device_create_drvdata(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;
index b711ab96e28751c053c105a05371ba073808d0fe..353dd11b9283ed0ba312ad7e8dc6d8c56dbb28e6 100644 (file)
@@ -2697,10 +2697,12 @@ static int ide_tape_probe(ide_drive_t *drive)
 
        idetape_setup(drive, tape, minor);
 
-       device_create(idetape_sysfs_class, &drive->gendev,
-                     MKDEV(IDETAPE_MAJOR, minor), "%s", tape->name);
-       device_create(idetape_sysfs_class, &drive->gendev,
-                       MKDEV(IDETAPE_MAJOR, minor + 128), "n%s", tape->name);
+       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);
 
        g->fops = &idetape_block_ops;
        ide_register_region(g);
index 9d19aec5820a303145d8b286e2d1ce2e72b4a586..b6eb2cf25914479667439fa51e181fca1e986fbd 100644 (file)
@@ -2296,9 +2296,10 @@ static void dv1394_add_host(struct hpsb_host *host)
 
        ohci = (struct ti_ohci *)host->hostdata;
 
-       device_create(hpsb_protocol_class, NULL, MKDEV(
-               IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_DV1394 * 16 + (id<<2)),
-               "dv1394-%d", id);
+       device_create_drvdata(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);
index 05710c7c12206aa1a9fcca8bad4db2eac3be7697..994a21e5a0aa7e6d929e94b82f0f8f99efe5b72f 100644 (file)
@@ -754,7 +754,8 @@ static void nodemgr_remove_uds(struct node_entry *ne)
         */
        mutex_lock(&nodemgr_serialize_remove_uds);
        for (;;) {
-               dev = class_find_device(&nodemgr_ud_class, ne, __match_ne);
+               dev = class_find_device(&nodemgr_ud_class, NULL, ne,
+                                       __match_ne);
                if (!dev)
                        break;
                ud = container_of(dev, struct unit_directory, unit_dev);
@@ -901,7 +902,8 @@ static struct node_entry *find_entry_by_guid(u64 guid)
        struct device *dev;
        struct node_entry *ne;
 
-       dev = class_find_device(&nodemgr_ne_class, &guid, __match_ne_guid);
+       dev = class_find_device(&nodemgr_ne_class, NULL, &guid,
+                               __match_ne_guid);
        if (!dev)
                return NULL;
        ne = container_of(dev, struct node_entry, node_dev);
@@ -940,7 +942,8 @@ static struct node_entry *find_entry_by_nodeid(struct hpsb_host *host,
        param.host = host;
        param.nodeid = nodeid;
 
-       dev = class_find_device(&nodemgr_ne_class, &param, __match_ne_nodeid);
+       dev = class_find_device(&nodemgr_ne_class, NULL, &param,
+                               __match_ne_nodeid);
        if (!dev)
                return NULL;
        ne = container_of(dev, struct node_entry, node_dev);
@@ -1453,7 +1456,8 @@ static void nodemgr_suspend_ne(struct node_entry *ne)
        ne->in_limbo = 1;
        WARN_ON(device_create_file(&ne->device, &dev_attr_ne_in_limbo));
 
-       class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_suspend);
+       class_for_each_device(&nodemgr_ud_class, NULL, ne,
+                             __nodemgr_driver_suspend);
 }
 
 
@@ -1462,7 +1466,8 @@ static void nodemgr_resume_ne(struct node_entry *ne)
        ne->in_limbo = 0;
        device_remove_file(&ne->device, &dev_attr_ne_in_limbo);
 
-       class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_driver_resume);
+       class_for_each_device(&nodemgr_ud_class, NULL, ne,
+                             __nodemgr_driver_resume);
        HPSB_DEBUG("Node resumed: ID:BUS[" NODE_BUS_FMT "]  GUID[%016Lx]",
                   NODE_BUS_ARGS(ne->host, ne->nodeid), (unsigned long long)ne->guid);
 }
@@ -1498,7 +1503,8 @@ static int __nodemgr_update_pdrv(struct device *dev, void *data)
 
 static void nodemgr_update_pdrv(struct node_entry *ne)
 {
-       class_for_each_device(&nodemgr_ud_class, ne, __nodemgr_update_pdrv);
+       class_for_each_device(&nodemgr_ud_class, NULL, ne,
+                             __nodemgr_update_pdrv);
 }
 
 
@@ -1591,7 +1597,8 @@ static void nodemgr_node_probe(struct host_info *hi, int generation)
         * while probes are time-consuming. (Well, those probes need some
         * improvement...) */
 
-       class_for_each_device(&nodemgr_ne_class, &param, __nodemgr_node_probe);
+       class_for_each_device(&nodemgr_ne_class, NULL, &param,
+                             __nodemgr_node_probe);
 
        /* If we had a bus reset while we were scanning the bus, it is
         * possible that we did not probe all nodes.  In that case, we
@@ -1826,7 +1833,7 @@ int nodemgr_for_each_host(void *data, int (*cb)(struct hpsb_host *, void *))
 
        hip.cb = cb;
        hip.data = data;
-       error = class_for_each_device(&hpsb_host_class, &hip,
+       error = class_for_each_device(&hpsb_host_class, NULL, &hip,
                                      __nodemgr_for_each_host);
 
        return error;
index 96f2847b0405e03ced5c4d3ec5b50a973caf6129..6fa9e4a21840b5f0cad2ce28b3754b293913e8fc 100644 (file)
@@ -3010,10 +3010,10 @@ static int __init init_raw1394(void)
        hpsb_register_highlevel(&raw1394_highlevel);
 
        if (IS_ERR
-           (device_create(
+           (device_create_drvdata(
              hpsb_protocol_class, NULL,
              MKDEV(IEEE1394_MAJOR, IEEE1394_MINOR_BLOCK_RAW1394 * 16),
-             RAW1394_DEVICE_NAME))) {
+             NULL, RAW1394_DEVICE_NAME))) {
                ret = -EFAULT;
                goto out_unreg;
        }
index 069b9f6bf16dae8396d871673c8618eb544967a7..25db6e67fa4ea6d123f9a71df2e9c44616e84c3d 100644 (file)
@@ -1341,9 +1341,9 @@ 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(hpsb_protocol_class, NULL,
-                     MKDEV(IEEE1394_MAJOR, minor),
-                     "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
+       device_create_drvdata(hpsb_protocol_class, NULL,
+                             MKDEV(IEEE1394_MAJOR, minor), NULL,
+                             "%s-%d", VIDEO1394_DRIVER_NAME, ohci->host->id);
 }
 
 
index 55738eead3bf1ce009568b1028be83b0e7b7d283..922d35f4fc08aa07d69355a812577f9534e82567 100644 (file)
@@ -44,6 +44,7 @@
 #include <linux/spinlock.h>
 #include <linux/sysfs.h>
 #include <linux/workqueue.h>
+#include <linux/kdev_t.h>
 
 #include <rdma/ib_cache.h>
 #include <rdma/ib_cm.h>
@@ -162,8 +163,8 @@ struct cm_port {
 
 struct cm_device {
        struct list_head list;
-       struct ib_device *device;
-       struct kobject dev_obj;
+       struct ib_device *ib_device;
+       struct device *device;
        u8 ack_delay;
        struct cm_port *port[0];
 };
@@ -339,7 +340,7 @@ static void cm_init_av_for_response(struct cm_port *port, struct ib_wc *wc,
 {
        av->port = port;
        av->pkey_index = wc->pkey_index;
-       ib_init_ah_from_wc(port->cm_dev->device, port->port_num, wc,
+       ib_init_ah_from_wc(port->cm_dev->ib_device, port->port_num, wc,
                           grh, &av->ah_attr);
 }
 
@@ -353,7 +354,7 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
 
        read_lock_irqsave(&cm.device_lock, flags);
        list_for_each_entry(cm_dev, &cm.device_list, list) {
-               if (!ib_find_cached_gid(cm_dev->device, &path->sgid,
+               if (!ib_find_cached_gid(cm_dev->ib_device, &path->sgid,
                                        &p, NULL)) {
                        port = cm_dev->port[p-1];
                        break;
@@ -364,13 +365,13 @@ static int cm_init_av_by_path(struct ib_sa_path_rec *path, struct cm_av *av)
        if (!port)
                return -EINVAL;
 
-       ret = ib_find_cached_pkey(cm_dev->device, port->port_num,
+       ret = ib_find_cached_pkey(cm_dev->ib_device, port->port_num,
                                  be16_to_cpu(path->pkey), &av->pkey_index);
        if (ret)
                return ret;
 
        av->port = port;
-       ib_init_ah_from_path(cm_dev->device, port->port_num, path,
+       ib_init_ah_from_path(cm_dev->ib_device, port->port_num, path,
                             &av->ah_attr);
        av->timeout = path->packet_life_time + 1;
        return 0;
@@ -1515,7 +1516,7 @@ static int cm_req_handler(struct cm_work *work)
 
        req_msg = (struct cm_req_msg *)work->mad_recv_wc->recv_buf.mad;
 
-       cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
+       cm_id = ib_create_cm_id(work->port->cm_dev->ib_device, NULL, NULL);
        if (IS_ERR(cm_id))
                return PTR_ERR(cm_id);
 
@@ -1550,7 +1551,7 @@ static int cm_req_handler(struct cm_work *work)
        cm_format_paths_from_req(req_msg, &work->path[0], &work->path[1]);
        ret = cm_init_av_by_path(&work->path[0], &cm_id_priv->av);
        if (ret) {
-               ib_get_cached_gid(work->port->cm_dev->device,
+               ib_get_cached_gid(work->port->cm_dev->ib_device,
                                  work->port->port_num, 0, &work->path[0].sgid);
                ib_send_cm_rej(cm_id, IB_CM_REJ_INVALID_GID,
                               &work->path[0].sgid, sizeof work->path[0].sgid,
@@ -2950,7 +2951,7 @@ static int cm_sidr_req_handler(struct cm_work *work)
        struct cm_sidr_req_msg *sidr_req_msg;
        struct ib_wc *wc;
 
-       cm_id = ib_create_cm_id(work->port->cm_dev->device, NULL, NULL);
+       cm_id = ib_create_cm_id(work->port->cm_dev->ib_device, NULL, NULL);
        if (IS_ERR(cm_id))
                return PTR_ERR(cm_id);
        cm_id_priv = container_of(cm_id, struct cm_id_private, id);
@@ -3578,7 +3579,7 @@ static void cm_get_ack_delay(struct cm_device *cm_dev)
 {
        struct ib_device_attr attr;
 
-       if (ib_query_device(cm_dev->device, &attr))
+       if (ib_query_device(cm_dev->ib_device, &attr))
                cm_dev->ack_delay = 0; /* acks will rely on packet life time */
        else
                cm_dev->ack_delay = attr.local_ca_ack_delay;
@@ -3618,18 +3619,6 @@ static struct kobj_type cm_port_obj_type = {
        .release = cm_release_port_obj
 };
 
-static void cm_release_dev_obj(struct kobject *obj)
-{
-       struct cm_device *cm_dev;
-
-       cm_dev = container_of(obj, struct cm_device, dev_obj);
-       kfree(cm_dev);
-}
-
-static struct kobj_type cm_dev_obj_type = {
-       .release = cm_release_dev_obj
-};
-
 struct class cm_class = {
        .name    = "infiniband_cm",
 };
@@ -3640,7 +3629,7 @@ static int cm_create_port_fs(struct cm_port *port)
        int i, ret;
 
        ret = kobject_init_and_add(&port->port_obj, &cm_port_obj_type,
-                                  &port->cm_dev->dev_obj,
+                                  &port->cm_dev->device->kobj,
                                   "%d", port->port_num);
        if (ret) {
                kfree(port);
@@ -3676,7 +3665,7 @@ static void cm_remove_port_fs(struct cm_port *port)
        kobject_put(&port->port_obj);
 }
 
-static void cm_add_one(struct ib_device *device)
+static void cm_add_one(struct ib_device *ib_device)
 {
        struct cm_device *cm_dev;
        struct cm_port *port;
@@ -3691,26 +3680,27 @@ static void cm_add_one(struct ib_device *device)
        int ret;
        u8 i;
 
-       if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
+       if (rdma_node_get_transport(ib_device->node_type) != RDMA_TRANSPORT_IB)
                return;
 
        cm_dev = kzalloc(sizeof(*cm_dev) + sizeof(*port) *
-                        device->phys_port_cnt, GFP_KERNEL);
+                        ib_device->phys_port_cnt, GFP_KERNEL);
        if (!cm_dev)
                return;
 
-       cm_dev->device = device;
+       cm_dev->ib_device = ib_device;
        cm_get_ack_delay(cm_dev);
 
-       ret = kobject_init_and_add(&cm_dev->dev_obj, &cm_dev_obj_type,
-                                  &cm_class.subsys.kobj, "%s", device->name);
-       if (ret) {
+       cm_dev->device = device_create_drvdata(&cm_class, &ib_device->dev,
+                                              MKDEV(0, 0), NULL,
+                                              "%s", ib_device->name);
+       if (!cm_dev->device) {
                kfree(cm_dev);
                return;
        }
 
        set_bit(IB_MGMT_METHOD_SEND, reg_req.method_mask);
-       for (i = 1; i <= device->phys_port_cnt; i++) {
+       for (i = 1; i <= ib_device->phys_port_cnt; i++) {
                port = kzalloc(sizeof *port, GFP_KERNEL);
                if (!port)
                        goto error1;
@@ -3723,7 +3713,7 @@ static void cm_add_one(struct ib_device *device)
                if (ret)
                        goto error1;
 
-               port->mad_agent = ib_register_mad_agent(device, i,
+               port->mad_agent = ib_register_mad_agent(ib_device, i,
                                                        IB_QPT_GSI,
                                                        &reg_req,
                                                        0,
@@ -3733,11 +3723,11 @@ static void cm_add_one(struct ib_device *device)
                if (IS_ERR(port->mad_agent))
                        goto error2;
 
-               ret = ib_modify_port(device, i, 0, &port_modify);
+               ret = ib_modify_port(ib_device, i, 0, &port_modify);
                if (ret)
                        goto error3;
        }
-       ib_set_client_data(device, &cm_client, cm_dev);
+       ib_set_client_data(ib_device, &cm_client, cm_dev);
 
        write_lock_irqsave(&cm.device_lock, flags);
        list_add_tail(&cm_dev->list, &cm.device_list);
@@ -3753,14 +3743,14 @@ error1:
        port_modify.clr_port_cap_mask = IB_PORT_CM_SUP;
        while (--i) {
                port = cm_dev->port[i-1];
-               ib_modify_port(device, port->port_num, 0, &port_modify);
+               ib_modify_port(ib_device, port->port_num, 0, &port_modify);
                ib_unregister_mad_agent(port->mad_agent);
                cm_remove_port_fs(port);
        }
-       kobject_put(&cm_dev->dev_obj);
+       device_unregister(cm_dev->device);
 }
 
-static void cm_remove_one(struct ib_device *device)
+static void cm_remove_one(struct ib_device *ib_device)
 {
        struct cm_device *cm_dev;
        struct cm_port *port;
@@ -3770,7 +3760,7 @@ static void cm_remove_one(struct ib_device *device)
        unsigned long flags;
        int i;
 
-       cm_dev = ib_get_client_data(device, &cm_client);
+       cm_dev = ib_get_client_data(ib_device, &cm_client);
        if (!cm_dev)
                return;
 
@@ -3778,14 +3768,14 @@ static void cm_remove_one(struct ib_device *device)
        list_del(&cm_dev->list);
        write_unlock_irqrestore(&cm.device_lock, flags);
 
-       for (i = 1; i <= device->phys_port_cnt; i++) {
+       for (i = 1; i <= ib_device->phys_port_cnt; i++) {
                port = cm_dev->port[i-1];
-               ib_modify_port(device, port->port_num, 0, &port_modify);
+               ib_modify_port(ib_device, port->port_num, 0, &port_modify);
                ib_unregister_mad_agent(port->mad_agent);
                flush_workqueue(cm.wq);
                cm_remove_port_fs(port);
        }
-       kobject_put(&cm_dev->dev_obj);
+       device_unregister(cm_dev->device);
 }
 
 static int __init ib_cm_init(void)
index 35f301c88b57196d0098e5a7d86ef5adba157d8b..56c0eda3c0772816f09e9b975090707929b826f3 100644 (file)
@@ -2455,7 +2455,7 @@ static int init_cdev(int minor, char *name, const struct file_operations *fops,
                goto err_cdev;
        }
 
-       device = device_create(ipath_class, NULL, dev, name);
+       device = device_create_drvdata(ipath_class, NULL, dev, NULL, name);
 
        if (IS_ERR(device)) {
                ret = PTR_ERR(device);
index 19e005e81feffe2a332198a518a15c853d7782d7..871b0cbca5e4540299047294d02c40a20326345a 100644 (file)
@@ -1553,7 +1553,8 @@ static int __init capi_init(void)
                return PTR_ERR(capi_class);
        }
 
-       device_create(capi_class, NULL, MKDEV(capi_major, 0), "capi");
+       device_create_drvdata(capi_class, NULL, MKDEV(capi_major, 0), NULL,
+                             "capi");
 
 #ifdef CONFIG_ISDN_CAPI_MIDDLEWARE
        if (capinc_tty_init() < 0) {
index e5d446804d323e74880db5ff14130440a120f033..cae52485208aaf022bd57689dcf8a4b30173aa2e 100644 (file)
@@ -862,7 +862,8 @@ adbdev_init(void)
        adb_dev_class = class_create(THIS_MODULE, "adb");
        if (IS_ERR(adb_dev_class))
                return;
-       device_create(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), "adb");
+       device_create_drvdata(adb_dev_class, NULL, MKDEV(ADB_MAJOR, 0), NULL,
+                             "adb");
 
        platform_device_register(&adb_pfdev);
        platform_driver_probe(&adb_pfdrv, adb_dummy_probe);
index 67b8e9453b191a2c701970f4ccbdd4a5207dd1e3..ef2dbfe747141ee3940fa645e700d89d7a173981 100644 (file)
@@ -40,7 +40,7 @@ static struct mca_bus *mca_root_busses[MAX_MCA_BUSSES];
 
 struct mca_device_info {
        short pos_id;           /* the 2 byte pos id for this card */
-       char name[DEVICE_NAME_SIZE];
+       char name[50];
 };
 
 static int mca_bus_match (struct device *dev, struct device_driver *drv)
index e208a60c048ad930ebdade3ff274efdbf039fb1f..e7132770a3bfdd656117890d11ff4ee6c9195302 100644 (file)
@@ -233,9 +233,9 @@ int dvb_register_device(struct dvb_adapter *adap, struct dvb_device **pdvbdev,
 
        mutex_unlock(&dvbdev_register_lock);
 
-       clsdev = device_create(dvb_class, adap->device,
+       clsdev = device_create_drvdata(dvb_class, adap->device,
                               MKDEV(DVB_MAJOR, nums2minor(adap->num, type, id)),
-                              "dvb%d.%s%d", adap->num, dnames[type], id);
+                              NULL, "dvb%d.%s%d", adap->num, dnames[type], id);
        if (IS_ERR(clsdev)) {
                printk(KERN_ERR "%s: failed to create device dvb%d.%s%d (%ld)\n",
                       __func__, adap->num, dnames[type], id, PTR_ERR(clsdev));
index a054668eda16c93e2ad2389402c94a8b358bae27..4e3bfbcdf155d9cadfc2d1ea06c35911cd3c7c11 100644 (file)
@@ -51,7 +51,7 @@ struct jmb38x_ms_host {
        void __iomem            *addr;
        spinlock_t              lock;
        int                     id;
-       char                    host_id[DEVICE_ID_SIZE];
+       char                    host_id[32];
        int                     irq;
        unsigned int            block_pos;
        unsigned long           timeout_jiffies;
@@ -781,7 +781,7 @@ static struct memstick_host *jmb38x_ms_alloc_host(struct jmb38x_ms *jm, int cnt)
 
        spin_lock_init(&host->lock);
        host->id = cnt;
-       snprintf(host->host_id, DEVICE_ID_SIZE, DRIVER_NAME ":slot%d",
+       snprintf(host->host_id, sizeof(host->host_id), DRIVER_NAME ":slot%d",
                 host->id);
        host->irq = jm->pdev->irq;
        host->timeout_jiffies = msecs_to_jiffies(1000);
index 75e599b85b645aba6d4de501f7f6c22e01dfa825..34402c47027e3951ac1d7de9387ec81a61227a2d 100644 (file)
@@ -1670,7 +1670,8 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
        INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
        spin_lock_init(&ioc->fault_reset_work_lock);
 
-       snprintf(ioc->reset_work_q_name, KOBJ_NAME_LEN, "mpt_poll_%d", ioc->id);
+       snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name),
+                "mpt_poll_%d", ioc->id);
        ioc->reset_work_q =
                create_singlethread_workqueue(ioc->reset_work_q_name);
        if (!ioc->reset_work_q) {
index 6adab648dbb91278076d0de0270018892c524ee4..dff048cfa101d78d09a878f1845d3480e88b5388 100644 (file)
@@ -707,12 +707,12 @@ typedef struct _MPT_ADAPTER
        u8                       fc_link_speed[2];
        spinlock_t               fc_rescan_work_lock;
        struct work_struct       fc_rescan_work;
-       char                     fc_rescan_work_q_name[KOBJ_NAME_LEN];
+       char                     fc_rescan_work_q_name[20];
        struct workqueue_struct *fc_rescan_work_q;
        struct scsi_cmnd        **ScsiLookup;
        spinlock_t                scsi_lookup_lock;
 
-       char                     reset_work_q_name[KOBJ_NAME_LEN];
+       char                     reset_work_q_name[20];
        struct workqueue_struct *reset_work_q;
        struct delayed_work      fault_reset_work;
        spinlock_t               fault_reset_work_lock;
index fc31ca6829d8d571d9c9da562c43bd7d2e94f73b..b36cae9ec6db6c81041f8dccd8b3ce59db466f2e 100644 (file)
@@ -1326,8 +1326,8 @@ mptfc_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 
        /* initialize workqueue */
 
-       snprintf(ioc->fc_rescan_work_q_name, KOBJ_NAME_LEN, "mptfc_wq_%d",
-               sh->host_no);
+       snprintf(ioc->fc_rescan_work_q_name, sizeof(ioc->fc_rescan_work_q_name),
+                "mptfc_wq_%d", sh->host_no);
        ioc->fc_rescan_work_q =
                create_singlethread_workqueue(ioc->fc_rescan_work_q_name);
        if (!ioc->fc_rescan_work_q)
index 1921b8dbb2427f94d1403c24e0330c6dbad7d70b..ce67d973d349df0f76ed5a5eccb9836fdc604469 100644 (file)
@@ -420,4 +420,17 @@ config SGI_XP
          this feature will allow for direct communication between SSIs
          based on a network adapter and DMA messaging.
 
+config HP_ILO
+       tristate "Channel interface driver for HP iLO/iLO2 processor"
+       default n
+       help
+         The channel interface driver allows applications to communicate
+         with iLO/iLO2 management processors present on HP ProLiant
+         servers.  Upon loading, the driver creates /dev/hpilo/dXccbN files,
+         which can be used to gather data from the management processor,
+         via read and write system calls.
+
+         To compile this driver as a module, choose M here: the
+         module will be called hpilo.
+
 endif # MISC_DEVICES
index a6dac6a2e7e59c485fcd5a65f9f4ed752768a2af..688fe76135e0eca608a8936edc324d37f91e4dea 100644 (file)
@@ -27,3 +27,4 @@ obj-$(CONFIG_INTEL_MENLOW)    += intel_menlow.o
 obj-$(CONFIG_ENCLOSURE_SERVICES) += enclosure.o
 obj-$(CONFIG_KGDB_TESTS)       += kgdbts.o
 obj-$(CONFIG_SGI_XP)           += sgi-xp/
+obj-$(CONFIG_HP_ILO)           += hpilo.o
diff --git a/drivers/misc/hpilo.c b/drivers/misc/hpilo.c
new file mode 100644 (file)
index 0000000..05e2982
--- /dev/null
@@ -0,0 +1,768 @@
+/*
+ * Driver for HP iLO/iLO2 management processor.
+ *
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *     David Altobelli <david.altobelli@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/file.h>
+#include <linux/cdev.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include "hpilo.h"
+
+static struct class *ilo_class;
+static unsigned int ilo_major;
+static char ilo_hwdev[MAX_ILO_DEV];
+
+static inline int get_entry_id(int entry)
+{
+       return (entry & ENTRY_MASK_DESCRIPTOR) >> ENTRY_BITPOS_DESCRIPTOR;
+}
+
+static inline int get_entry_len(int entry)
+{
+       return ((entry & ENTRY_MASK_QWORDS) >> ENTRY_BITPOS_QWORDS) << 3;
+}
+
+static inline int mk_entry(int id, int len)
+{
+       int qlen = len & 7 ? (len >> 3) + 1 : len >> 3;
+       return id << ENTRY_BITPOS_DESCRIPTOR | qlen << ENTRY_BITPOS_QWORDS;
+}
+
+static inline int desc_mem_sz(int nr_entry)
+{
+       return nr_entry << L2_QENTRY_SZ;
+}
+
+/*
+ * FIFO queues, shared with hardware.
+ *
+ * If a queue has empty slots, an entry is added to the queue tail,
+ * and that entry is marked as occupied.
+ * Entries can be dequeued from the head of the list, when the device
+ * has marked the entry as consumed.
+ *
+ * Returns true on successful queue/dequeue, false on failure.
+ */
+static int fifo_enqueue(struct ilo_hwinfo *hw, char *fifobar, int entry)
+{
+       struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
+       int ret = 0;
+
+       spin_lock(&hw->fifo_lock);
+       if (!(fifo_q->fifobar[(fifo_q->tail + 1) & fifo_q->imask]
+             & ENTRY_MASK_O)) {
+               fifo_q->fifobar[fifo_q->tail & fifo_q->imask] |=
+                               (entry & ENTRY_MASK_NOSTATE) | fifo_q->merge;
+               fifo_q->tail += 1;
+               ret = 1;
+       }
+       spin_unlock(&hw->fifo_lock);
+
+       return ret;
+}
+
+static int fifo_dequeue(struct ilo_hwinfo *hw, char *fifobar, int *entry)
+{
+       struct fifo *fifo_q = FIFOBARTOHANDLE(fifobar);
+       int ret = 0;
+       u64 c;
+
+       spin_lock(&hw->fifo_lock);
+       c = fifo_q->fifobar[fifo_q->head & fifo_q->imask];
+       if (c & ENTRY_MASK_C) {
+               if (entry)
+                       *entry = c & ENTRY_MASK_NOSTATE;
+
+               fifo_q->fifobar[fifo_q->head & fifo_q->imask] =
+                                                       (c | ENTRY_MASK) + 1;
+               fifo_q->head += 1;
+               ret = 1;
+       }
+       spin_unlock(&hw->fifo_lock);
+
+       return ret;
+}
+
+static int ilo_pkt_enqueue(struct ilo_hwinfo *hw, struct ccb *ccb,
+                          int dir, int id, int len)
+{
+       char *fifobar;
+       int entry;
+
+       if (dir == SENDQ)
+               fifobar = ccb->ccb_u1.send_fifobar;
+       else
+               fifobar = ccb->ccb_u3.recv_fifobar;
+
+       entry = mk_entry(id, len);
+       return fifo_enqueue(hw, fifobar, entry);
+}
+
+static int ilo_pkt_dequeue(struct ilo_hwinfo *hw, struct ccb *ccb,
+                          int dir, int *id, int *len, void **pkt)
+{
+       char *fifobar, *desc;
+       int entry = 0, pkt_id = 0;
+       int ret;
+
+       if (dir == SENDQ) {
+               fifobar = ccb->ccb_u1.send_fifobar;
+               desc = ccb->ccb_u2.send_desc;
+       } else {
+               fifobar = ccb->ccb_u3.recv_fifobar;
+               desc = ccb->ccb_u4.recv_desc;
+       }
+
+       ret = fifo_dequeue(hw, fifobar, &entry);
+       if (ret) {
+               pkt_id = get_entry_id(entry);
+               if (id)
+                       *id = pkt_id;
+               if (len)
+                       *len = get_entry_len(entry);
+               if (pkt)
+                       *pkt = (void *)(desc + desc_mem_sz(pkt_id));
+       }
+
+       return ret;
+}
+
+static inline void doorbell_set(struct ccb *ccb)
+{
+       iowrite8(1, ccb->ccb_u5.db_base);
+}
+
+static inline void doorbell_clr(struct ccb *ccb)
+{
+       iowrite8(2, ccb->ccb_u5.db_base);
+}
+static inline int ctrl_set(int l2sz, int idxmask, int desclim)
+{
+       int active = 0, go = 1;
+       return l2sz << CTRL_BITPOS_L2SZ |
+              idxmask << CTRL_BITPOS_FIFOINDEXMASK |
+              desclim << CTRL_BITPOS_DESCLIMIT |
+              active << CTRL_BITPOS_A |
+              go << CTRL_BITPOS_G;
+}
+static void ctrl_setup(struct ccb *ccb, int nr_desc, int l2desc_sz)
+{
+       /* for simplicity, use the same parameters for send and recv ctrls */
+       ccb->send_ctrl = ctrl_set(l2desc_sz, nr_desc-1, nr_desc-1);
+       ccb->recv_ctrl = ctrl_set(l2desc_sz, nr_desc-1, nr_desc-1);
+}
+
+static inline int fifo_sz(int nr_entry)
+{
+       /* size of a fifo is determined by the number of entries it contains */
+       return (nr_entry * sizeof(u64)) + FIFOHANDLESIZE;
+}
+
+static void fifo_setup(void *base_addr, int nr_entry)
+{
+       struct fifo *fifo_q = base_addr;
+       int i;
+
+       /* set up an empty fifo */
+       fifo_q->head = 0;
+       fifo_q->tail = 0;
+       fifo_q->reset = 0;
+       fifo_q->nrents = nr_entry;
+       fifo_q->imask = nr_entry - 1;
+       fifo_q->merge = ENTRY_MASK_O;
+
+       for (i = 0; i < nr_entry; i++)
+               fifo_q->fifobar[i] = 0;
+}
+
+static void ilo_ccb_close(struct pci_dev *pdev, struct ccb_data *data)
+{
+       struct ccb *driver_ccb;
+       struct ccb __iomem *device_ccb;
+       int retries;
+
+       driver_ccb = &data->driver_ccb;
+       device_ccb = data->mapped_ccb;
+
+       /* complicated dance to tell the hw we are stopping */
+       doorbell_clr(driver_ccb);
+       iowrite32(ioread32(&device_ccb->send_ctrl) & ~(1 << CTRL_BITPOS_G),
+                 &device_ccb->send_ctrl);
+       iowrite32(ioread32(&device_ccb->recv_ctrl) & ~(1 << CTRL_BITPOS_G),
+                 &device_ccb->recv_ctrl);
+
+       /* give iLO some time to process stop request */
+       for (retries = 1000; retries > 0; retries--) {
+               doorbell_set(driver_ccb);
+               udelay(1);
+               if (!(ioread32(&device_ccb->send_ctrl) & (1 << CTRL_BITPOS_A))
+                   &&
+                   !(ioread32(&device_ccb->recv_ctrl) & (1 << CTRL_BITPOS_A)))
+                       break;
+       }
+       if (retries == 0)
+               dev_err(&pdev->dev, "Closing, but controller still active\n");
+
+       /* clear the hw ccb */
+       memset_io(device_ccb, 0, sizeof(struct ccb));
+
+       /* free resources used to back send/recv queues */
+       pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
+}
+
+static int ilo_ccb_open(struct ilo_hwinfo *hw, struct ccb_data *data, int slot)
+{
+       char *dma_va, *dma_pa;
+       int pkt_id, pkt_sz, i, error;
+       struct ccb *driver_ccb, *ilo_ccb;
+       struct pci_dev *pdev;
+
+       driver_ccb = &data->driver_ccb;
+       ilo_ccb = &data->ilo_ccb;
+       pdev = hw->ilo_dev;
+
+       data->dma_size = 2 * fifo_sz(NR_QENTRY) +
+                        2 * desc_mem_sz(NR_QENTRY) +
+                        ILO_START_ALIGN + ILO_CACHE_SZ;
+
+       error = -ENOMEM;
+       data->dma_va = pci_alloc_consistent(pdev, data->dma_size,
+                                           &data->dma_pa);
+       if (!data->dma_va)
+               goto out;
+
+       dma_va = (char *)data->dma_va;
+       dma_pa = (char *)data->dma_pa;
+
+       memset(dma_va, 0, data->dma_size);
+
+       dma_va = (char *)roundup((unsigned long)dma_va, ILO_START_ALIGN);
+       dma_pa = (char *)roundup((unsigned long)dma_pa, ILO_START_ALIGN);
+
+       /*
+        * Create two ccb's, one with virt addrs, one with phys addrs.
+        * Copy the phys addr ccb to device shared mem.
+        */
+       ctrl_setup(driver_ccb, NR_QENTRY, L2_QENTRY_SZ);
+       ctrl_setup(ilo_ccb, NR_QENTRY, L2_QENTRY_SZ);
+
+       fifo_setup(dma_va, NR_QENTRY);
+       driver_ccb->ccb_u1.send_fifobar = dma_va + FIFOHANDLESIZE;
+       ilo_ccb->ccb_u1.send_fifobar = dma_pa + FIFOHANDLESIZE;
+       dma_va += fifo_sz(NR_QENTRY);
+       dma_pa += fifo_sz(NR_QENTRY);
+
+       dma_va = (char *)roundup((unsigned long)dma_va, ILO_CACHE_SZ);
+       dma_pa = (char *)roundup((unsigned long)dma_pa, ILO_CACHE_SZ);
+
+       fifo_setup(dma_va, NR_QENTRY);
+       driver_ccb->ccb_u3.recv_fifobar = dma_va + FIFOHANDLESIZE;
+       ilo_ccb->ccb_u3.recv_fifobar = dma_pa + FIFOHANDLESIZE;
+       dma_va += fifo_sz(NR_QENTRY);
+       dma_pa += fifo_sz(NR_QENTRY);
+
+       driver_ccb->ccb_u2.send_desc = dma_va;
+       ilo_ccb->ccb_u2.send_desc = dma_pa;
+       dma_pa += desc_mem_sz(NR_QENTRY);
+       dma_va += desc_mem_sz(NR_QENTRY);
+
+       driver_ccb->ccb_u4.recv_desc = dma_va;
+       ilo_ccb->ccb_u4.recv_desc = dma_pa;
+
+       driver_ccb->channel = slot;
+       ilo_ccb->channel = slot;
+
+       driver_ccb->ccb_u5.db_base = hw->db_vaddr + (slot << L2_DB_SIZE);
+       ilo_ccb->ccb_u5.db_base = NULL; /* hw ccb's doorbell is not used */
+
+       /* copy the ccb with physical addrs to device memory */
+       data->mapped_ccb = (struct ccb __iomem *)
+                               (hw->ram_vaddr + (slot * ILOHW_CCB_SZ));
+       memcpy_toio(data->mapped_ccb, ilo_ccb, sizeof(struct ccb));
+
+       /* put packets on the send and receive queues */
+       pkt_sz = 0;
+       for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++) {
+               ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, pkt_sz);
+               doorbell_set(driver_ccb);
+       }
+
+       pkt_sz = desc_mem_sz(1);
+       for (pkt_id = 0; pkt_id < NR_QENTRY; pkt_id++)
+               ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, pkt_sz);
+
+       doorbell_clr(driver_ccb);
+
+       /* make sure iLO is really handling requests */
+       for (i = 1000; i > 0; i--) {
+               if (ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, NULL, NULL))
+                       break;
+               udelay(1);
+       }
+
+       if (i) {
+               ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, 0);
+               doorbell_set(driver_ccb);
+       } else {
+               dev_err(&pdev->dev, "Open could not dequeue a packet\n");
+               error = -EBUSY;
+               goto free;
+       }
+
+       return 0;
+free:
+       pci_free_consistent(pdev, data->dma_size, data->dma_va, data->dma_pa);
+out:
+       return error;
+}
+
+static inline int is_channel_reset(struct ccb *ccb)
+{
+       /* check for this particular channel needing a reset */
+       return FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset;
+}
+
+static inline void set_channel_reset(struct ccb *ccb)
+{
+       /* set a flag indicating this channel needs a reset */
+       FIFOBARTOHANDLE(ccb->ccb_u1.send_fifobar)->reset = 1;
+}
+
+static inline int is_device_reset(struct ilo_hwinfo *hw)
+{
+       /* check for global reset condition */
+       return ioread32(&hw->mmio_vaddr[DB_OUT]) & (1 << DB_RESET);
+}
+
+static inline void clear_device(struct ilo_hwinfo *hw)
+{
+       /* clear the device (reset bits, pending channel entries) */
+       iowrite32(-1, &hw->mmio_vaddr[DB_OUT]);
+}
+
+static void ilo_locked_reset(struct ilo_hwinfo *hw)
+{
+       int slot;
+
+       /*
+        * Mapped memory is zeroed on ilo reset, so set a per ccb flag
+        * to indicate that this ccb needs to be closed and reopened.
+        */
+       for (slot = 0; slot < MAX_CCB; slot++) {
+               if (!hw->ccb_alloc[slot])
+                       continue;
+               set_channel_reset(&hw->ccb_alloc[slot]->driver_ccb);
+       }
+
+       clear_device(hw);
+}
+
+static void ilo_reset(struct ilo_hwinfo *hw)
+{
+       spin_lock(&hw->alloc_lock);
+
+       /* reset might have been handled after lock was taken */
+       if (is_device_reset(hw))
+               ilo_locked_reset(hw);
+
+       spin_unlock(&hw->alloc_lock);
+}
+
+static ssize_t ilo_read(struct file *fp, char __user *buf,
+                       size_t len, loff_t *off)
+{
+       int err, found, cnt, pkt_id, pkt_len;
+       struct ccb_data *data;
+       struct ccb *driver_ccb;
+       struct ilo_hwinfo *hw;
+       void *pkt;
+
+       data = fp->private_data;
+       driver_ccb = &data->driver_ccb;
+       hw = data->ilo_hw;
+
+       if (is_device_reset(hw) || is_channel_reset(driver_ccb)) {
+               /*
+                * If the device has been reset, applications
+                * need to close and reopen all ccbs.
+                */
+               ilo_reset(hw);
+               return -ENODEV;
+       }
+
+       /*
+        * This function is to be called when data is expected
+        * in the channel, and will return an error if no packet is found
+        * during the loop below.  The sleep/retry logic is to allow
+        * applications to call read() immediately post write(),
+        * and give iLO some time to process the sent packet.
+        */
+       cnt = 20;
+       do {
+               /* look for a received packet */
+               found = ilo_pkt_dequeue(hw, driver_ccb, RECVQ, &pkt_id,
+                                       &pkt_len, &pkt);
+               if (found)
+                       break;
+               cnt--;
+               msleep(100);
+       } while (!found && cnt);
+
+       if (!found)
+               return -EAGAIN;
+
+       /* only copy the length of the received packet */
+       if (pkt_len < len)
+               len = pkt_len;
+
+       err = copy_to_user(buf, pkt, len);
+
+       /* return the received packet to the queue */
+       ilo_pkt_enqueue(hw, driver_ccb, RECVQ, pkt_id, desc_mem_sz(1));
+
+       return err ? -EFAULT : len;
+}
+
+static ssize_t ilo_write(struct file *fp, const char __user *buf,
+                        size_t len, loff_t *off)
+{
+       int err, pkt_id, pkt_len;
+       struct ccb_data *data;
+       struct ccb *driver_ccb;
+       struct ilo_hwinfo *hw;
+       void *pkt;
+
+       data = fp->private_data;
+       driver_ccb = &data->driver_ccb;
+       hw = data->ilo_hw;
+
+       if (is_device_reset(hw) || is_channel_reset(driver_ccb)) {
+               /*
+                * If the device has been reset, applications
+                * need to close and reopen all ccbs.
+                */
+               ilo_reset(hw);
+               return -ENODEV;
+       }
+
+       /* get a packet to send the user command */
+       if (!ilo_pkt_dequeue(hw, driver_ccb, SENDQ, &pkt_id, &pkt_len, &pkt))
+               return -EBUSY;
+
+       /* limit the length to the length of the packet */
+       if (pkt_len < len)
+               len = pkt_len;
+
+       /* on failure, set the len to 0 to return empty packet to the device */
+       err = copy_from_user(pkt, buf, len);
+       if (err)
+               len = 0;
+
+       /* send the packet */
+       ilo_pkt_enqueue(hw, driver_ccb, SENDQ, pkt_id, len);
+       doorbell_set(driver_ccb);
+
+       return err ? -EFAULT : len;
+}
+
+static int ilo_close(struct inode *ip, struct file *fp)
+{
+       int slot;
+       struct ccb_data *data;
+       struct ilo_hwinfo *hw;
+
+       slot = iminor(ip) % MAX_CCB;
+       hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
+
+       spin_lock(&hw->alloc_lock);
+
+       if (is_device_reset(hw))
+               ilo_locked_reset(hw);
+
+       if (hw->ccb_alloc[slot]->ccb_cnt == 1) {
+
+               data = fp->private_data;
+
+               ilo_ccb_close(hw->ilo_dev, data);
+
+               kfree(data);
+               hw->ccb_alloc[slot] = NULL;
+       } else
+               hw->ccb_alloc[slot]->ccb_cnt--;
+
+       spin_unlock(&hw->alloc_lock);
+
+       return 0;
+}
+
+static int ilo_open(struct inode *ip, struct file *fp)
+{
+       int slot, error;
+       struct ccb_data *data;
+       struct ilo_hwinfo *hw;
+
+       slot = iminor(ip) % MAX_CCB;
+       hw = container_of(ip->i_cdev, struct ilo_hwinfo, cdev);
+
+       /* new ccb allocation */
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       spin_lock(&hw->alloc_lock);
+
+       if (is_device_reset(hw))
+               ilo_locked_reset(hw);
+
+       /* each fd private_data holds sw/hw view of ccb */
+       if (hw->ccb_alloc[slot] == NULL) {
+               /* create a channel control block for this minor */
+               error = ilo_ccb_open(hw, data, slot);
+               if (!error) {
+                       hw->ccb_alloc[slot] = data;
+                       hw->ccb_alloc[slot]->ccb_cnt = 1;
+                       hw->ccb_alloc[slot]->ccb_excl = fp->f_flags & O_EXCL;
+                       hw->ccb_alloc[slot]->ilo_hw = hw;
+               } else
+                       kfree(data);
+       } else {
+               kfree(data);
+               if (fp->f_flags & O_EXCL || hw->ccb_alloc[slot]->ccb_excl) {
+                       /*
+                        * The channel exists, and either this open
+                        * or a previous open of this channel wants
+                        * exclusive access.
+                        */
+                       error = -EBUSY;
+               } else {
+                       hw->ccb_alloc[slot]->ccb_cnt++;
+                       error = 0;
+               }
+       }
+       spin_unlock(&hw->alloc_lock);
+
+       if (!error)
+               fp->private_data = hw->ccb_alloc[slot];
+
+       return error;
+}
+
+static const struct file_operations ilo_fops = {
+       .owner          = THIS_MODULE,
+       .read           = ilo_read,
+       .write          = ilo_write,
+       .open           = ilo_open,
+       .release        = ilo_close,
+};
+
+static void ilo_unmap_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
+{
+       pci_iounmap(pdev, hw->db_vaddr);
+       pci_iounmap(pdev, hw->ram_vaddr);
+       pci_iounmap(pdev, hw->mmio_vaddr);
+}
+
+static int __devinit ilo_map_device(struct pci_dev *pdev, struct ilo_hwinfo *hw)
+{
+       int error = -ENOMEM;
+
+       /* map the memory mapped i/o registers */
+       hw->mmio_vaddr = pci_iomap(pdev, 1, 0);
+       if (hw->mmio_vaddr == NULL) {
+               dev_err(&pdev->dev, "Error mapping mmio\n");
+               goto out;
+       }
+
+       /* map the adapter shared memory region */
+       hw->ram_vaddr = pci_iomap(pdev, 2, MAX_CCB * ILOHW_CCB_SZ);
+       if (hw->ram_vaddr == NULL) {
+               dev_err(&pdev->dev, "Error mapping shared mem\n");
+               goto mmio_free;
+       }
+
+       /* map the doorbell aperture */
+       hw->db_vaddr = pci_iomap(pdev, 3, MAX_CCB * ONE_DB_SIZE);
+       if (hw->db_vaddr == NULL) {
+               dev_err(&pdev->dev, "Error mapping doorbell\n");
+               goto ram_free;
+       }
+
+       return 0;
+ram_free:
+       pci_iounmap(pdev, hw->ram_vaddr);
+mmio_free:
+       pci_iounmap(pdev, hw->mmio_vaddr);
+out:
+       return error;
+}
+
+static void ilo_remove(struct pci_dev *pdev)
+{
+       int i, minor;
+       struct ilo_hwinfo *ilo_hw = pci_get_drvdata(pdev);
+
+       clear_device(ilo_hw);
+
+       minor = MINOR(ilo_hw->cdev.dev);
+       for (i = minor; i < minor + MAX_CCB; i++)
+               device_destroy(ilo_class, MKDEV(ilo_major, i));
+
+       cdev_del(&ilo_hw->cdev);
+       ilo_unmap_device(pdev, ilo_hw);
+       pci_release_regions(pdev);
+       pci_disable_device(pdev);
+       kfree(ilo_hw);
+       ilo_hwdev[(minor / MAX_CCB)] = 0;
+}
+
+static int __devinit ilo_probe(struct pci_dev *pdev,
+                              const struct pci_device_id *ent)
+{
+       int devnum, minor, start, error;
+       struct ilo_hwinfo *ilo_hw;
+
+       /* find a free range for device files */
+       for (devnum = 0; devnum < MAX_ILO_DEV; devnum++) {
+               if (ilo_hwdev[devnum] == 0) {
+                       ilo_hwdev[devnum] = 1;
+                       break;
+               }
+       }
+
+       if (devnum == MAX_ILO_DEV) {
+               dev_err(&pdev->dev, "Error finding free device\n");
+               return -ENODEV;
+       }
+
+       /* track global allocations for this device */
+       error = -ENOMEM;
+       ilo_hw = kzalloc(sizeof(*ilo_hw), GFP_KERNEL);
+       if (!ilo_hw)
+               goto out;
+
+       ilo_hw->ilo_dev = pdev;
+       spin_lock_init(&ilo_hw->alloc_lock);
+       spin_lock_init(&ilo_hw->fifo_lock);
+
+       error = pci_enable_device(pdev);
+       if (error)
+               goto free;
+
+       pci_set_master(pdev);
+
+       error = pci_request_regions(pdev, ILO_NAME);
+       if (error)
+               goto disable;
+
+       error = ilo_map_device(pdev, ilo_hw);
+       if (error)
+               goto free_regions;
+
+       pci_set_drvdata(pdev, ilo_hw);
+       clear_device(ilo_hw);
+
+       cdev_init(&ilo_hw->cdev, &ilo_fops);
+       ilo_hw->cdev.owner = THIS_MODULE;
+       start = devnum * MAX_CCB;
+       error = cdev_add(&ilo_hw->cdev, MKDEV(ilo_major, start), MAX_CCB);
+       if (error) {
+               dev_err(&pdev->dev, "Could not add cdev\n");
+               goto unmap;
+       }
+
+       for (minor = 0 ; minor < MAX_CCB; minor++) {
+               struct device *dev;
+               dev = device_create(ilo_class, &pdev->dev,
+                                   MKDEV(ilo_major, minor), NULL,
+                                   "hpilo!d%dccb%d", devnum, minor);
+               if (IS_ERR(dev))
+                       dev_err(&pdev->dev, "Could not create files\n");
+       }
+
+       return 0;
+unmap:
+       ilo_unmap_device(pdev, ilo_hw);
+free_regions:
+       pci_release_regions(pdev);
+disable:
+       pci_disable_device(pdev);
+free:
+       kfree(ilo_hw);
+out:
+       ilo_hwdev[devnum] = 0;
+       return error;
+}
+
+static struct pci_device_id ilo_devices[] = {
+       { PCI_DEVICE(PCI_VENDOR_ID_COMPAQ, 0xB204) },
+       { }
+};
+MODULE_DEVICE_TABLE(pci, ilo_devices);
+
+static struct pci_driver ilo_driver = {
+       .name     = ILO_NAME,
+       .id_table = ilo_devices,
+       .probe    = ilo_probe,
+       .remove   = __devexit_p(ilo_remove),
+};
+
+static int __init ilo_init(void)
+{
+       int error;
+       dev_t dev;
+
+       ilo_class = class_create(THIS_MODULE, "iLO");
+       if (IS_ERR(ilo_class)) {
+               error = PTR_ERR(ilo_class);
+               goto out;
+       }
+
+       error = alloc_chrdev_region(&dev, 0, MAX_OPEN, ILO_NAME);
+       if (error)
+               goto class_destroy;
+
+       ilo_major = MAJOR(dev);
+
+       error = pci_register_driver(&ilo_driver);
+       if (error)
+               goto chr_remove;
+
+       return 0;
+chr_remove:
+       unregister_chrdev_region(dev, MAX_OPEN);
+class_destroy:
+       class_destroy(ilo_class);
+out:
+       return error;
+}
+
+static void __exit ilo_exit(void)
+{
+       pci_unregister_driver(&ilo_driver);
+       unregister_chrdev_region(MKDEV(ilo_major, 0), MAX_OPEN);
+       class_destroy(ilo_class);
+}
+
+MODULE_VERSION("0.05");
+MODULE_ALIAS(ILO_NAME);
+MODULE_DESCRIPTION(ILO_NAME);
+MODULE_AUTHOR("David Altobelli <david.altobelli@hp.com>");
+MODULE_LICENSE("GPL v2");
+
+module_init(ilo_init);
+module_exit(ilo_exit);
diff --git a/drivers/misc/hpilo.h b/drivers/misc/hpilo.h
new file mode 100644 (file)
index 0000000..a281207
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * linux/drivers/char/hpilo.h
+ *
+ * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
+ *     David Altobelli <david.altobelli@hp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef __HPILO_H
+#define __HPILO_H
+
+#define ILO_NAME "hpilo"
+
+/* max number of open channel control blocks per device, hw limited to 32 */
+#define MAX_CCB                8
+/* max number of supported devices */
+#define MAX_ILO_DEV    1
+/* max number of files */
+#define MAX_OPEN       (MAX_CCB * MAX_ILO_DEV)
+
+/*
+ * Per device, used to track global memory allocations.
+ */
+struct ilo_hwinfo {
+       /* mmio registers on device */
+       char __iomem *mmio_vaddr;
+
+       /* doorbell registers on device */
+       char __iomem *db_vaddr;
+
+       /* shared memory on device used for channel control blocks */
+       char __iomem *ram_vaddr;
+
+       /* files corresponding to this device */
+       struct ccb_data *ccb_alloc[MAX_CCB];
+
+       struct pci_dev *ilo_dev;
+
+       spinlock_t alloc_lock;
+       spinlock_t fifo_lock;
+
+       struct cdev cdev;
+};
+
+/* offset from mmio_vaddr */
+#define DB_OUT         0xD4
+/* DB_OUT reset bit */
+#define DB_RESET       26
+
+/*
+ * Channel control block. Used to manage hardware queues.
+ * The format must match hw's version.  The hw ccb is 128 bytes,
+ * but the context area shouldn't be touched by the driver.
+ */
+#define ILOSW_CCB_SZ   64
+#define ILOHW_CCB_SZ   128
+struct ccb {
+       union {
+               char *send_fifobar;
+               u64 padding1;
+       } ccb_u1;
+       union {
+               char *send_desc;
+               u64 padding2;
+       } ccb_u2;
+       u64 send_ctrl;
+
+       union {
+               char *recv_fifobar;
+               u64 padding3;
+       } ccb_u3;
+       union {
+               char *recv_desc;
+               u64 padding4;
+       } ccb_u4;
+       u64 recv_ctrl;
+
+       union {
+               char __iomem *db_base;
+               u64 padding5;
+       } ccb_u5;
+
+       u64 channel;
+
+       /* unused context area (64 bytes) */
+};
+
+/* ccb queue parameters */
+#define SENDQ          1
+#define RECVQ          2
+#define NR_QENTRY      4
+#define L2_QENTRY_SZ   12
+
+/* ccb ctrl bitfields */
+#define CTRL_BITPOS_L2SZ             0
+#define CTRL_BITPOS_FIFOINDEXMASK    4
+#define CTRL_BITPOS_DESCLIMIT        18
+#define CTRL_BITPOS_A                30
+#define CTRL_BITPOS_G                31
+
+/* ccb doorbell macros */
+#define L2_DB_SIZE             14
+#define ONE_DB_SIZE            (1 << L2_DB_SIZE)
+
+/*
+ * Per fd structure used to track the ccb allocated to that dev file.
+ */
+struct ccb_data {
+       /* software version of ccb, using virtual addrs */
+       struct ccb  driver_ccb;
+
+       /* hardware version of ccb, using physical addrs */
+       struct ccb  ilo_ccb;
+
+       /* hardware ccb is written to this shared mapped device memory */
+       struct ccb __iomem *mapped_ccb;
+
+       /* dma'able memory used for send/recv queues */
+       void       *dma_va;
+       dma_addr_t  dma_pa;
+       size_t      dma_size;
+
+       /* pointer to hardware device info */
+       struct ilo_hwinfo *ilo_hw;
+
+       /* usage count, to allow for shared ccb's */
+       int         ccb_cnt;
+
+       /* open wanted exclusive access to this ccb */
+       int         ccb_excl;
+};
+
+/*
+ * FIFO queue structure, shared with hw.
+ */
+#define ILO_START_ALIGN        4096
+#define ILO_CACHE_SZ    128
+struct fifo {
+    u64 nrents;        /* user requested number of fifo entries */
+    u64 imask;  /* mask to extract valid fifo index */
+    u64 merge; /*  O/C bits to merge in during enqueue operation */
+    u64 reset; /* set to non-zero when the target device resets */
+    u8  pad_0[ILO_CACHE_SZ - (sizeof(u64) * 4)];
+
+    u64 head;
+    u8  pad_1[ILO_CACHE_SZ - (sizeof(u64))];
+
+    u64 tail;
+    u8  pad_2[ILO_CACHE_SZ - (sizeof(u64))];
+
+    u64 fifobar[1];
+};
+
+/* convert between struct fifo, and the fifobar, which is saved in the ccb */
+#define FIFOHANDLESIZE (sizeof(struct fifo) - sizeof(u64))
+#define FIFOBARTOHANDLE(_fifo) \
+       ((struct fifo *)(((char *)(_fifo)) - FIFOHANDLESIZE))
+
+/* the number of qwords to consume from the entry descriptor */
+#define ENTRY_BITPOS_QWORDS      0
+/* descriptor index number (within a specified queue) */
+#define ENTRY_BITPOS_DESCRIPTOR  10
+/* state bit, fifo entry consumed by consumer */
+#define ENTRY_BITPOS_C           22
+/* state bit, fifo entry is occupied */
+#define ENTRY_BITPOS_O           23
+
+#define ENTRY_BITS_QWORDS        10
+#define ENTRY_BITS_DESCRIPTOR    12
+#define ENTRY_BITS_C             1
+#define ENTRY_BITS_O             1
+#define ENTRY_BITS_TOTAL       \
+       (ENTRY_BITS_C + ENTRY_BITS_O + \
+        ENTRY_BITS_QWORDS + ENTRY_BITS_DESCRIPTOR)
+
+/* extract various entry fields */
+#define ENTRY_MASK ((1 << ENTRY_BITS_TOTAL) - 1)
+#define ENTRY_MASK_C (((1 << ENTRY_BITS_C) - 1) << ENTRY_BITPOS_C)
+#define ENTRY_MASK_O (((1 << ENTRY_BITS_O) - 1) << ENTRY_BITPOS_O)
+#define ENTRY_MASK_QWORDS \
+       (((1 << ENTRY_BITS_QWORDS) - 1) << ENTRY_BITPOS_QWORDS)
+#define ENTRY_MASK_DESCRIPTOR \
+       (((1 << ENTRY_BITS_DESCRIPTOR) - 1) << ENTRY_BITPOS_DESCRIPTOR)
+
+#define ENTRY_MASK_NOSTATE (ENTRY_MASK >> (ENTRY_BITS_C + ENTRY_BITS_O))
+
+#endif /* __HPILO_H */
index 1861624700905571ca777937ba005f64bcce3a89..4ce3bdc2f959b4081a27a30dc7f8486ee9611057 100644 (file)
@@ -399,8 +399,9 @@ static int __devinit phantom_probe(struct pci_dev *pdev,
                goto err_irq;
        }
 
-       if (IS_ERR(device_create(phantom_class, &pdev->dev, MKDEV(phantom_major,
-                       minor), "phantom%u", minor)))
+       if (IS_ERR(device_create_drvdata(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);
index 519d942e7940c6167672c2d53829530e3e7d9fcc..7b72a1b36115f4b1bf4c581c6d67c1e6f6454566 100644 (file)
@@ -241,6 +241,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
 {
        struct block_device *bdev;
        struct block2mtd_dev *dev;
+       char *name;
 
        if (!devname)
                return NULL;
@@ -279,12 +280,13 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size)
 
        /* Setup the MTD structure */
        /* make the name contain the block device in */
-       dev->mtd.name = kmalloc(sizeof("block2mtd: ") + strlen(devname),
+       name = kmalloc(sizeof("block2mtd: ") + strlen(devname) + 1,
                        GFP_KERNEL);
-       if (!dev->mtd.name)
+       if (!name)
                goto devinit_err;
 
-       sprintf(dev->mtd.name, "block2mtd: %s", devname);
+       sprintf(name, "block2mtd: %s", devname);
+       dev->mtd.name = name;
 
        dev->mtd.size = dev->blkdev->bd_inode->i_size & PAGE_MASK;
        dev->mtd.erasesize = erase_size;
index 129d429cd2da5abc55ea1aa9c97a21041a5c85ff..aef9f4b687c9fdfafc7eb5fddfc6cdb98ea28cc1 100644 (file)
@@ -28,10 +28,13 @@ static void mtd_notify_add(struct mtd_info* mtd)
        if (!mtd)
                return;
 
-       device_create(mtd_class, NULL, MKDEV(MTD_CHAR_MAJOR, mtd->index*2), "mtd%d", mtd->index);
+       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+1), "mtd%dro", mtd->index);
+       device_create_drvdata(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)
index aabad8ce7458c852a496422991c0683c0fe43d26..8db4e6b89482abc37c68c6cedf6396984b4f3a09 100644 (file)
@@ -1010,7 +1010,7 @@ static int __devinit vortex_probe1(struct device *gendev,
        static int printed_version;
        int retval, print_info;
        struct vortex_chip_info * const vci = &vortex_info_tbl[chip_idx];
-       char *print_name = "3c59x";
+       const char *print_name = "3c59x";
        struct pci_dev *pdev = NULL;
        struct eisa_device *edev = NULL;
        DECLARE_MAC_BUF(mac);
index 1e39e78f1778c5228d7e6345005e900a347ccbff..71f7cec309118986cc05f51806d82ebdfa4f3003 100644 (file)
@@ -677,7 +677,7 @@ static void at91ether_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo
 {
        strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
        strlcpy(info->version, DRV_VERSION, sizeof(info->version));
-       strlcpy(info->bus_info, dev->dev.parent->bus_id, sizeof(info->bus_info));
+       strlcpy(info->bus_info, dev_name(dev->dev.parent), sizeof(info->bus_info));
 }
 
 static const struct ethtool_ops at91ether_ethtool_ops = {
index ecd8fc6146e9faa710351eb8765c8538807bcc51..7a14980f3472d133da546174cef0f6365ffb4772 100644 (file)
@@ -848,7 +848,7 @@ static int ep93xx_eth_probe(struct platform_device *pdev)
 
        ep->res = request_mem_region(pdev->resource[0].start,
                        pdev->resource[0].end - pdev->resource[0].start + 1,
-                       pdev->dev.bus_id);
+                       dev_name(&pdev->dev));
        if (ep->res == NULL) {
                dev_err(&pdev->dev, "Could not reserve memory region\n");
                err = -ENOMEM;
index e9d15eccad082cf91f72f8115ae27190a7a8c1b3..5c5f1e470d3c2d05fcc910fb97917cb487bf7533 100644 (file)
@@ -535,7 +535,7 @@ static int __init etherh_addr(char *addr, struct expansion_card *ec)
        
        if (!ecard_readchunk(&cd, ec, 0xf5, 0)) {
                printk(KERN_ERR "%s: unable to read podule description string\n",
-                      ec->dev.bus_id);
+                      dev_name(&ec->dev));
                goto no_addr;
        }
 
@@ -554,7 +554,7 @@ static int __init etherh_addr(char *addr, struct expansion_card *ec)
        }
 
        printk(KERN_ERR "%s: unable to parse MAC address: %s\n",
-              ec->dev.bus_id, cd.d.string);
+              dev_name(&ec->dev), cd.d.string);
 
  no_addr:
        return -ENODEV;
@@ -585,7 +585,7 @@ static void etherh_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *i
 {
        strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
        strlcpy(info->version, DRV_VERSION, sizeof(info->version));
-       strlcpy(info->bus_info, dev->dev.parent->bus_id,
+       strlcpy(info->bus_info, dev_name(dev->dev.parent),
                sizeof(info->bus_info));
 }
 
index 6b1d7a8edf1554aeff5680fd4f467f2444dce498..739b3ab7bccc2d9ea719c6080eb3137bf2ba2dbc 100644 (file)
@@ -866,7 +866,8 @@ static int __init ppp_init(void)
                        err = PTR_ERR(ppp_class);
                        goto out_chrdev;
                }
-               device_create(ppp_class, NULL, MKDEV(PPP_MAJOR, 0), "ppp");
+               device_create_drvdata(ppp_class, NULL, MKDEV(PPP_MAJOR, 0),
+                                     NULL, "ppp");
        }
 
 out:
index 5827324e9d9f94a2abde26a450c1b4be90c941cf..f7d3349dc3ec8ffcc35707287e4a3127176d9fd5 100644 (file)
@@ -397,9 +397,9 @@ static int __init cosa_init(void)
                err = PTR_ERR(cosa_class);
                goto out_chrdev;
        }
-       for (i=0; i<nr_cards; i++) {
-               device_create(cosa_class, NULL, MKDEV(cosa_major, i), "cosa%d", i);
-       }
+       for (i = 0; i < nr_cards; i++)
+               device_create_drvdata(cosa_class, NULL, MKDEV(cosa_major, i),
+                                     NULL, "cosa%d", i);
        err = 0;
        goto out;
        
index eecf7cbf4139aca028fd6c57f49c075717bcf8da..5a58b075dd8d0da2f7ae8ae451ded6ea241c0e06 100644 (file)
@@ -36,7 +36,7 @@
 #define _ACPIPHP_H
 
 #include <linux/acpi.h>
-#include <linux/kobject.h>     /* for KOBJ_NAME_LEN */
+#include <linux/kobject.h>
 #include <linux/mutex.h>
 #include <linux/pci_hotplug.h>
 
@@ -51,7 +51,7 @@
 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
 
 /* name size which is used for entries in pcihpfs */
-#define SLOT_NAME_SIZE KOBJ_NAME_LEN           /* {_SUN} */
+#define SLOT_NAME_SIZE 20              /* {_SUN} */
 
 struct acpiphp_bridge;
 struct acpiphp_slot;
index a4892275659dc02ffb1d12b85d0774a86bda8b08..936bae560fa1f730255bde8a94c9493c953efdfd 100644 (file)
@@ -78,7 +78,7 @@ static void find_main_battery(void)
        main_battery = NULL;
        bp.main = main_battery;
 
-       error = class_for_each_device(power_supply_class, &bp,
+       error = class_for_each_device(power_supply_class, NULL, &bp,
                                      __find_main_battery);
        if (error) {
                main_battery = bp.main;
index af1633eb3b707c9c53c50e578f0ed5859ee69d96..cb1ccb4729210c1a3cfd8901bf7dea5c56117146 100644 (file)
@@ -41,7 +41,7 @@ static void power_supply_changed_work(struct work_struct *work)
 
        dev_dbg(psy->dev, "%s\n", __func__);
 
-       class_for_each_device(power_supply_class, psy,
+       class_for_each_device(power_supply_class, NULL, psy,
                              __power_supply_changed_work);
 
        power_supply_update_leds(psy);
@@ -79,7 +79,7 @@ int power_supply_am_i_supplied(struct power_supply *psy)
 {
        int error;
 
-       error = class_for_each_device(power_supply_class, psy,
+       error = class_for_each_device(power_supply_class, NULL, psy,
                                      __power_supply_am_i_supplied);
 
        dev_dbg(psy->dev, "%s %d\n", __func__, error);
index 58b7336640ff7a1559263798f46e9d7912f09088..d397fa5f3a91ab650f890aef8d1e59fc5d3005b8 100644 (file)
@@ -345,7 +345,7 @@ struct rtc_device *rtc_class_open(char *name)
        struct device *dev;
        struct rtc_device *rtc = NULL;
 
-       dev = class_find_device(rtc_class, name, __rtc_match);
+       dev = class_find_device(rtc_class, NULL, name, __rtc_match);
        if (dev)
                rtc = to_rtc_device(dev);
 
index 81a96e019080bf591ab68e3dee40b593ab2ff9f8..c3dee900a5c8b84608ef868ab73d4d0df0206cf3 100644 (file)
@@ -1168,17 +1168,19 @@ static int raw3270_create_attributes(struct raw3270 *rp)
        if (rc)
                goto out;
 
-       rp->clttydev = device_create(class3270, &rp->cdev->dev,
-                                    MKDEV(IBM_TTY3270_MAJOR, rp->minor),
-                                    "tty%s", rp->cdev->dev.bus_id);
+       rp->clttydev = device_create_drvdata(class3270, &rp->cdev->dev,
+                                            MKDEV(IBM_TTY3270_MAJOR, rp->minor),
+                                            NULL,
+                                            "tty%s", rp->cdev->dev.bus_id);
        if (IS_ERR(rp->clttydev)) {
                rc = PTR_ERR(rp->clttydev);
                goto out_ttydev;
        }
 
-       rp->cltubdev = device_create(class3270, &rp->cdev->dev,
-                                    MKDEV(IBM_FS3270_MAJOR, rp->minor),
-                                    "tub%s", rp->cdev->dev.bus_id);
+       rp->cltubdev = device_create_drvdata(class3270, &rp->cdev->dev,
+                                            MKDEV(IBM_FS3270_MAJOR, rp->minor),
+                                            NULL,
+                                            "tub%s", rp->cdev->dev.bus_id);
        if (!IS_ERR(rp->cltubdev))
                goto out;
 
index 6dfdb7c179819a121e8514db89daf6eb35811f8c..12c2a5aaf31b47e88587957b7f31cb6a24edff7b 100644 (file)
@@ -69,10 +69,9 @@ struct tape_class_device *register_tape_dev(
        if (rc)
                goto fail_with_cdev;
 
-       tcd->class_device = device_create(tape_class, device,
-                                         tcd->char_device->dev,
-                                         "%s", tcd->device_name
-                       );
+       tcd->class_device = device_create_drvdata(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;
index b0ac44b271270e31db9e5b689c7802175f6dc0ec..c1f352b84868c16affd93a7ff7af1f162527eb2b 100644 (file)
@@ -896,8 +896,9 @@ static int ur_set_online(struct ccw_device *cdev)
                goto fail_free_cdev;
        }
 
-       urd->device = device_create(vmur_class, NULL, urd->char_device->dev,
-                                       "%s", node_id);
+       urd->device = device_create_drvdata(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);
index c37d7c2587ff923ad0129a3b145f1a542f150ddf..73a86d09bba8d71dd84641e58dbde5d1c1278d03 100644 (file)
@@ -78,7 +78,7 @@ static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sde
        else
                sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev;
        sdev->ofdev.dev.bus = &sbus_bus_type;
-       sprintf(sdev->ofdev.dev.bus_id, "sbus[%08x]", dp->node);
+       dev_set_name(&sdev->ofdev.dev, "sbus[%08x]", dp->node);
 
        if (of_device_register(&sdev->ofdev) != 0)
                printk(KERN_DEBUG "sbus: device registration error for %s!\n",
@@ -257,11 +257,11 @@ static void __init build_one_sbus(struct device_node *dp, int num_sbus)
        sbus->ofdev.node = dp;
        sbus->ofdev.dev.parent = NULL;
        sbus->ofdev.dev.bus = &sbus_bus_type;
-       sprintf(sbus->ofdev.dev.bus_id, "sbus%d", num_sbus);
+       dev_set_name(&sbus->ofdev.dev, "sbus%d", num_sbus);
 
        if (of_device_register(&sbus->ofdev) != 0)
                printk(KERN_DEBUG "sbus: device registration error for %s!\n",
-                      sbus->ofdev.dev.bus_id);
+                      dev_name(&sbus->ofdev.dev));
 
        dev_dp = dp->child;
        while (dev_dp) {
index 2bc30e32b67a691823568025e802c52cd3f27a7a..1fe0901e81192d91dad44c4773908c1f6492d39a 100644 (file)
@@ -271,8 +271,8 @@ rebuild_sys_tab:
                pHba->initialized = TRUE;
                pHba->state &= ~DPTI_STATE_RESET;
                if (adpt_sysfs_class) {
-                       struct device *dev = device_create(adpt_sysfs_class,
-                               NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit),
+                       struct device *dev = device_create_drvdata(adpt_sysfs_class,
+                               NULL, MKDEV(DPTI_I2O_MAJOR, pHba->unit), NULL,
                                "dpti%d", pHba->unit);
                        if (IS_ERR(dev)) {
                                printk(KERN_WARNING"dpti%d: unable to "
index 35cd892dce04f899336a49c21228fe36984b5155..fed0b02ebc1d35ecba7c19b534956edf939eb7a6 100644 (file)
@@ -232,8 +232,8 @@ int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
        }
 
        if (shost->transportt->create_work_queue) {
-               snprintf(shost->work_q_name, KOBJ_NAME_LEN, "scsi_wq_%d",
-                       shost->host_no);
+               snprintf(shost->work_q_name, sizeof(shost->work_q_name),
+                        "scsi_wq_%d", shost->host_no);
                shost->work_q = create_singlethread_workqueue(
                                        shost->work_q_name);
                if (!shost->work_q) {
@@ -466,7 +466,8 @@ struct Scsi_Host *scsi_host_lookup(unsigned short hostnum)
        struct device *cdev;
        struct Scsi_Host *shost = ERR_PTR(-ENXIO);
 
-       cdev = class_find_device(&shost_class, &hostnum, __scsi_host_match);
+       cdev = class_find_device(&shost_class, NULL, &hostnum,
+                                __scsi_host_match);
        if (cdev) {
                shost = scsi_host_get(class_to_shost(cdev));
                put_device(cdev);
index 5fd64e70029dcd30d4c30c8c9dffd5a0f77648a6..a272b9a2c86945314a8ae4693cc18b2a37dce2cb 100644 (file)
@@ -417,15 +417,16 @@ static int fc_host_setup(struct transport_container *tc, struct device *dev,
        fc_host->next_vport_number = 0;
        fc_host->npiv_vports_inuse = 0;
 
-       snprintf(fc_host->work_q_name, KOBJ_NAME_LEN, "fc_wq_%d",
-               shost->host_no);
+       snprintf(fc_host->work_q_name, sizeof(fc_host->work_q_name),
+                "fc_wq_%d", shost->host_no);
        fc_host->work_q = create_singlethread_workqueue(
                                        fc_host->work_q_name);
        if (!fc_host->work_q)
                return -ENOMEM;
 
-       snprintf(fc_host->devloss_work_q_name, KOBJ_NAME_LEN, "fc_dl_%d",
-               shost->host_no);
+       snprintf(fc_host->devloss_work_q_name,
+                sizeof(fc_host->devloss_work_q_name),
+                "fc_dl_%d", shost->host_no);
        fc_host->devloss_work_q = create_singlethread_workqueue(
                                        fc_host->devloss_work_q_name);
        if (!fc_host->devloss_work_q) {
index 3af7cbcc5c5d7c6f93822a2e7e29f15f17a7df13..043c3921164ff781f3b20e51232ee091d2381622 100644 (file)
@@ -170,7 +170,7 @@ iscsi_create_endpoint(int dd_size)
        int err;
 
        for (id = 1; id < ISCSI_MAX_EPID; id++) {
-               dev = class_find_device(&iscsi_endpoint_class, &id,
+               dev = class_find_device(&iscsi_endpoint_class, NULL, &id,
                                        iscsi_match_epid);
                if (!dev)
                        break;
@@ -222,7 +222,7 @@ struct iscsi_endpoint *iscsi_lookup_endpoint(u64 handle)
        struct iscsi_endpoint *ep;
        struct device *dev;
 
-       dev = class_find_device(&iscsi_endpoint_class, &handle,
+       dev = class_find_device(&iscsi_endpoint_class, NULL, &handle,
                                iscsi_match_epid);
        if (!dev)
                return NULL;
@@ -247,8 +247,8 @@ static int iscsi_setup_host(struct transport_container *tc, struct device *dev,
        atomic_set(&ihost->nr_scans, 0);
        mutex_init(&ihost->mutex);
 
-       snprintf(ihost->scan_workq_name, KOBJ_NAME_LEN, "iscsi_scan_%d",
-               shost->host_no);
+       snprintf(ihost->scan_workq_name, sizeof(ihost->scan_workq_name),
+                "iscsi_scan_%d", shost->host_no);
        ihost->scan_workq = create_singlethread_workqueue(
                                                ihost->scan_workq_name);
        if (!ihost->scan_workq)
index 1ad12afc6ba0ace916c817c571b265dc49cc1398..1771b2456bfaf8f60ab3d0fdfafdd443813b3138 100644 (file)
@@ -502,7 +502,7 @@ struct spi_master *spi_busnum_to_master(u16 bus_num)
        struct device           *dev;
        struct spi_master       *master = NULL;
 
-       dev = class_find_device(&spi_master_class, &bus_num,
+       dev = class_find_device(&spi_master_class, NULL, &bus_num,
                                __spi_master_match);
        if (dev)
                master = container_of(dev, struct spi_master, dev);
index ddbe1a5e970e1b017b46e629100af8848c292427..2833fd772a24feb160f33a07e4bbbcc23a5cbb21 100644 (file)
@@ -576,7 +576,8 @@ static int spidev_probe(struct spi_device *spi)
                struct device *dev;
 
                spidev->devt = MKDEV(SPIDEV_MAJOR, minor);
-               dev = device_create(spidev_class, &spi->dev, spidev->devt,
+               dev = device_create_drvdata(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;
@@ -586,7 +587,6 @@ static int spidev_probe(struct spi_device *spi)
        }
        if (status == 0) {
                set_bit(minor, minors);
-               spi_set_drvdata(spi, spidev);
                list_add(&spidev->device_entry, &device_list);
        }
        mutex_unlock(&device_list_lock);
index a4aaab9c7ddcd3f1a5546175a262ad0b84310a73..2e9079df26b3a2ebd67e633295167389d380ae81 100644 (file)
@@ -15,7 +15,7 @@ if UIO
 
 config UIO_CIF
        tristate "generic Hilscher CIF Card driver"
-       depends on UIO && PCI
+       depends on PCI
        default n
        help
          Driver for Hilscher CIF DeviceNet and Profibus cards.  This
@@ -26,9 +26,15 @@ config UIO_CIF
          To compile this driver as a module, choose M here: the module
          will be called uio_cif.
 
+config UIO_PDRV
+       tristate "Userspace I/O platform driver"
+       help
+         Generic platform driver for Userspace I/O devices.
+
+         If you don't know what to do here, say N.
+
 config UIO_SMX
        tristate "SMX cryptengine UIO interface"
-       depends on UIO
        default n
        help
          Userspace IO interface to the Cryptography engine found on the
index 18c45662431e302fe1b5014b3b9ca8968643f3ba..e00ce0def1a02898d0b197c2c593f8344bb989b7 100644 (file)
@@ -1,3 +1,4 @@
 obj-$(CONFIG_UIO)      += uio.o
 obj-$(CONFIG_UIO_CIF)  += uio_cif.o
+obj-$(CONFIG_UIO_PDRV) += uio_pdrv.o
 obj-$(CONFIG_UIO_SMX)  += uio_smx.o
index 5a7ca2e6094dc4d2ea0f6fb95f2315b11373be13..3a6934bf713134edc3f53b68e25bf913ec3215e4 100644 (file)
@@ -427,6 +427,31 @@ static ssize_t uio_read(struct file *filep, char __user *buf,
        return retval;
 }
 
+static ssize_t uio_write(struct file *filep, const char __user *buf,
+                       size_t count, loff_t *ppos)
+{
+       struct uio_listener *listener = filep->private_data;
+       struct uio_device *idev = listener->dev;
+       ssize_t retval;
+       s32 irq_on;
+
+       if (idev->info->irq == UIO_IRQ_NONE)
+               return -EIO;
+
+       if (count != sizeof(s32))
+               return -EINVAL;
+
+       if (!idev->info->irqcontrol)
+               return -ENOSYS;
+
+       if (copy_from_user(&irq_on, buf, count))
+               return -EFAULT;
+
+       retval = idev->info->irqcontrol(idev->info, irq_on);
+
+       return retval ? retval : sizeof(s32);
+}
+
 static int uio_find_mem_index(struct vm_area_struct *vma)
 {
        int mi;
@@ -546,6 +571,7 @@ static const struct file_operations uio_fops = {
        .open           = uio_open,
        .release        = uio_release,
        .read           = uio_read,
+       .write          = uio_write,
        .mmap           = uio_mmap,
        .poll           = uio_poll,
        .fasync         = uio_fasync,
diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
new file mode 100644 (file)
index 0000000..5d0d2e8
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * drivers/uio/uio_pdrv.c
+ *
+ * Copyright (C) 2008 by Digi International Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ */
+#include <linux/platform_device.h>
+#include <linux/uio_driver.h>
+#include <linux/stringify.h>
+
+#define DRIVER_NAME "uio"
+
+struct uio_platdata {
+       struct uio_info *uioinfo;
+};
+
+static int uio_pdrv_probe(struct platform_device *pdev)
+{
+       struct uio_info *uioinfo = pdev->dev.platform_data;
+       struct uio_platdata *pdata;
+       struct uio_mem *uiomem;
+       int ret = -ENODEV;
+       int i;
+
+       if (!uioinfo || !uioinfo->name || !uioinfo->version) {
+               dev_dbg(&pdev->dev, "%s: err_uioinfo\n", __func__);
+               goto err_uioinfo;
+       }
+
+       pdata = kzalloc(sizeof(*pdata), GFP_KERNEL);
+       if (!pdata) {
+               ret = -ENOMEM;
+               dev_dbg(&pdev->dev, "%s: err_alloc_pdata\n", __func__);
+               goto err_alloc_pdata;
+       }
+
+       pdata->uioinfo = uioinfo;
+
+       uiomem = &uioinfo->mem[0];
+
+       for (i = 0; i < pdev->num_resources; ++i) {
+               struct resource *r = &pdev->resource[i];
+
+               if (r->flags != IORESOURCE_MEM)
+                       continue;
+
+               if (uiomem >= &uioinfo->mem[MAX_UIO_MAPS]) {
+                       dev_warn(&pdev->dev, "device has more than "
+                                       __stringify(MAX_UIO_MAPS)
+                                       " I/O memory resources.\n");
+                       break;
+               }
+
+               uiomem->memtype = UIO_MEM_PHYS;
+               uiomem->addr = r->start;
+               uiomem->size = r->end - r->start + 1;
+               ++uiomem;
+       }
+
+       while (uiomem < &uioinfo->mem[MAX_UIO_MAPS]) {
+               uiomem->size = 0;
+               ++uiomem;
+       }
+
+       pdata->uioinfo->priv = pdata;
+
+       ret = uio_register_device(&pdev->dev, pdata->uioinfo);
+
+       if (ret) {
+               kfree(pdata);
+err_alloc_pdata:
+err_uioinfo:
+               return ret;
+       }
+
+       platform_set_drvdata(pdev, pdata);
+
+       return 0;
+}
+
+static int uio_pdrv_remove(struct platform_device *pdev)
+{
+       struct uio_platdata *pdata = platform_get_drvdata(pdev);
+
+       uio_unregister_device(pdata->uioinfo);
+
+       return 0;
+}
+
+static struct platform_driver uio_pdrv = {
+       .probe = uio_pdrv_probe,
+       .remove = uio_pdrv_remove,
+       .driver = {
+               .name = DRIVER_NAME,
+               .owner = THIS_MODULE,
+       },
+};
+
+static int __init uio_pdrv_init(void)
+{
+       return platform_driver_register(&uio_pdrv);
+}
+
+static void __exit uio_pdrv_exit(void)
+{
+       platform_driver_unregister(&uio_pdrv);
+}
+module_init(uio_pdrv_init);
+module_exit(uio_pdrv_exit);
+
+MODULE_AUTHOR("Uwe Kleine-Koenig");
+MODULE_DESCRIPTION("Userspace I/O platform driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
index 54a350ccd0333870fc4a7c01371f2dd1e7042d78..20290c5b15625c3b4272765ff95eefa3feb07b88 100644 (file)
@@ -1729,9 +1729,9 @@ static int usb_classdev_add(struct usb_device *dev)
 {
        struct device *cldev;
 
-       cldev = device_create(usb_classdev_class, &dev->dev, dev->dev.devt,
-                             "usbdev%d.%d", dev->bus->busnum,
-                             dev->devnum);
+       cldev = device_create_drvdata(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;
@@ -1792,6 +1792,11 @@ int __init usb_devio_init(void)
                usb_classdev_class = NULL;
                goto out;
        }
+       /* devices of this class shadow the major:minor of their parent
+        * device, so clear ->dev_kobj to prevent adding duplicate entries
+        * to /sys/dev
+        */
+       usb_classdev_class->dev_kobj = NULL;
 
        usb_register_notify(&usbdev_nb);
 #endif
index 913fb8667899f29a48333d17e3074d73b4f2ed50..6b1b229e38cd1d28790d5f29e54eebbe3efe2fb8 100644 (file)
@@ -196,8 +196,9 @@ int usb_register_dev(struct usb_interface *intf,
                ++temp;
        else
                temp = name;
-       intf->usb_dev = device_create(usb_class->class, &intf->dev,
-                                     MKDEV(USB_MAJOR, minor), "%s", temp);
+       intf->usb_dev = device_create_drvdata(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;
index 9caaec3ae9a38aff14de8052bdfc285d38540ad9..49cd9e145a9bfbcdba12c76192f93ae3073b716d 100644 (file)
@@ -1360,8 +1360,8 @@ printer_bind(struct usb_gadget *gadget)
 
 
        /* Setup the sysfs files for the printer gadget. */
-       dev->pdev = device_create(usb_gadget_class, NULL, g_printer_devno,
-                       "g_printer");
+       dev->pdev = device_create_drvdata(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;
index 293a46247c3b3bc8e4c731ca45fac0493d526778..6566fc0a322853a50b8f212d6b82df868da9b4d5 100644 (file)
@@ -1162,8 +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(mon_bin_class, ubus? ubus->controller: NULL,
-                       MKDEV(MAJOR(mon_bin_dev0), minor), "usbmon%d", minor);
+       dev = device_create_drvdata(mon_bin_class, ubus? ubus->controller: NULL,
+                                   MKDEV(MAJOR(mon_bin_dev0), minor), NULL,
+                                   "usbmon%d", minor);
        if (IS_ERR(dev))
                return 0;
 
index 24ee96c4e9e9e5c816254444b7f002863363eda7..07b6addbb3c1a2631990db635e238703a891a82c 100644 (file)
@@ -1872,7 +1872,7 @@ static int __devinit aty128_init(struct pci_dev *pdev, const struct pci_device_i
        struct fb_info *info = pci_get_drvdata(pdev);
        struct aty128fb_par *par = info->par;
        struct fb_var_screeninfo var;
-       char video_card[DEVICE_NAME_SIZE];
+       char video_card[50];
        u8 chip_rev;
        u32 dac;
 
index c347e38cd0b084719437e8157477aa220ef9e6f6..ccbfffd128056c57392f02ff59f2dfe318f5b24e 100644 (file)
@@ -289,7 +289,7 @@ struct radeonfb_info {
        struct radeon_regs      state;
        struct radeon_regs      init_state;
 
-       char                    name[DEVICE_NAME_SIZE];
+       char                    name[50];
 
        unsigned long           mmio_base_phys;
        unsigned long           fb_base_phys;
index 97aff8db10bf1e53435ef2a3441b83ab9f5ed774..4be3b46c069be3e33853fc7dd4b83023576eb8f1 100644 (file)
@@ -3586,7 +3586,8 @@ static int __init fb_console_init(void)
 
        acquire_console_sem();
        fb_register_client(&fbcon_event_notifier);
-       fbcon_device = device_create(fb_class, NULL, MKDEV(0, 0), "fbcon");
+       fbcon_device = device_create_drvdata(fb_class, NULL, MKDEV(0, 0),
+                                            NULL, "fbcon");
 
        if (IS_ERR(fbcon_device)) {
                printk(KERN_WARNING "Unable to create device "
index 33ebdb198dafbf5776ff5a5ac4a39c35fecf1464..1cd5071e53621f26a1cfe77b784a9dd8da725799 100644 (file)
@@ -1439,8 +1439,9 @@ register_framebuffer(struct fb_info *fb_info)
                        break;
        fb_info->node = i;
 
-       fb_info->dev = device_create(fb_class, fb_info->device,
-                                    MKDEV(FB_MAJOR, i), "fb%d", i);
+       fb_info->dev = device_create_drvdata(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));
index 591bc29b55f5acf0f8dbe97e360ddd279020e9b2..d4427cb869791cd0f1b910f5371f78aefe42c626 100644 (file)
@@ -610,6 +610,7 @@ static ssize_t show_target_kb(struct sys_device *dev, char *buf)
 }
 
 static ssize_t store_target_kb(struct sys_device *dev,
+                              struct sysdev_attribute *attr,
                               const char *buf,
                               size_t count)
 {
index e3eb3556622b6808c6d15515e18e597a0ddc4f5b..40c36f7352a609a061cabdd1704e8074c0e0ee2e 100644 (file)
@@ -362,8 +362,9 @@ static int init_coda_psdev(void)
                goto out_chrdev;
        }               
        for (i = 0; i < MAX_CODADEVS; i++)
-               device_create(coda_psdev_class, NULL,
-                             MKDEV(CODA_PSDEV_MAJOR,i), "cfs%d", i);
+               device_create_drvdata(coda_psdev_class, NULL,
+                                     MKDEV(CODA_PSDEV_MAJOR, i),
+                                     NULL, "cfs%d", i);
        coda_sysctl_init();
        goto out;
 
index e9602d85c11d0220d5cbccf7817c25b10a6d068e..08e28c9bb4164f5e2f549535959fd816d92521ed 100644 (file)
@@ -309,6 +309,31 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
 }
 EXPORT_SYMBOL_GPL(debugfs_create_symlink);
 
+static void __debugfs_remove(struct dentry *dentry, struct dentry *parent)
+{
+       int ret = 0;
+
+       if (debugfs_positive(dentry)) {
+               if (dentry->d_inode) {
+                       dget(dentry);
+                       switch (dentry->d_inode->i_mode & S_IFMT) {
+                       case S_IFDIR:
+                               ret = simple_rmdir(parent->d_inode, dentry);
+                               break;
+                       case S_IFLNK:
+                               kfree(dentry->d_inode->i_private);
+                               /* fall through */
+                       default:
+                               simple_unlink(parent->d_inode, dentry);
+                               break;
+                       }
+                       if (!ret)
+                               d_delete(dentry);
+                       dput(dentry);
+               }
+       }
+}
+
 /**
  * debugfs_remove - removes a file or directory from the debugfs filesystem
  * @dentry: a pointer to a the dentry of the file or directory to be
@@ -325,7 +350,6 @@ EXPORT_SYMBOL_GPL(debugfs_create_symlink);
 void debugfs_remove(struct dentry *dentry)
 {
        struct dentry *parent;
-       int ret = 0;
        
        if (!dentry)
                return;
@@ -335,29 +359,83 @@ void debugfs_remove(struct dentry *dentry)
                return;
 
        mutex_lock(&parent->d_inode->i_mutex);
-       if (debugfs_positive(dentry)) {
-               if (dentry->d_inode) {
-                       dget(dentry);
-                       switch (dentry->d_inode->i_mode & S_IFMT) {
-                       case S_IFDIR:
-                               ret = simple_rmdir(parent->d_inode, dentry);
-                               break;
-                       case S_IFLNK:
-                               kfree(dentry->d_inode->i_private);
-                               /* fall through */
-                       default:
-                               simple_unlink(parent->d_inode, dentry);
+       __debugfs_remove(dentry, parent);
+       mutex_unlock(&parent->d_inode->i_mutex);
+       simple_release_fs(&debugfs_mount, &debugfs_mount_count);
+}
+EXPORT_SYMBOL_GPL(debugfs_remove);
+
+/**
+ * debugfs_remove_recursive - recursively removes a directory
+ * @dentry: a pointer to a the dentry of the directory to be removed.
+ *
+ * This function recursively removes a directory tree in debugfs that
+ * was previously created with a call to another debugfs function
+ * (like debugfs_create_file() or variants thereof.)
+ *
+ * This function is required to be called in order for the file to be
+ * removed, no automatic cleanup of files will happen when a module is
+ * removed, you are responsible here.
+ */
+void debugfs_remove_recursive(struct dentry *dentry)
+{
+       struct dentry *child;
+       struct dentry *parent;
+
+       if (!dentry)
+               return;
+
+       parent = dentry->d_parent;
+       if (!parent || !parent->d_inode)
+               return;
+
+       parent = dentry;
+       mutex_lock(&parent->d_inode->i_mutex);
+
+       while (1) {
+               /*
+                * When all dentries under "parent" has been removed,
+                * walk up the tree until we reach our starting point.
+                */
+               if (list_empty(&parent->d_subdirs)) {
+                       mutex_unlock(&parent->d_inode->i_mutex);
+                       if (parent == dentry)
                                break;
-                       }
-                       if (!ret)
-                               d_delete(dentry);
-                       dput(dentry);
+                       parent = parent->d_parent;
+                       mutex_lock(&parent->d_inode->i_mutex);
+               }
+               child = list_entry(parent->d_subdirs.next, struct dentry,
+                               d_u.d_child);
+
+               /*
+                * If "child" isn't empty, walk down the tree and
+                * remove all its descendants first.
+                */
+               if (!list_empty(&child->d_subdirs)) {
+                       mutex_unlock(&parent->d_inode->i_mutex);
+                       parent = child;
+                       mutex_lock(&parent->d_inode->i_mutex);
+                       continue;
                }
+               __debugfs_remove(child, parent);
+               if (parent->d_subdirs.next == &child->d_u.d_child) {
+                       /*
+                        * Avoid infinite loop if we fail to remove
+                        * one dentry.
+                        */
+                       mutex_unlock(&parent->d_inode->i_mutex);
+                       break;
+               }
+               simple_release_fs(&debugfs_mount, &debugfs_mount_count);
        }
+
+       parent = dentry->d_parent;
+       mutex_lock(&parent->d_inode->i_mutex);
+       __debugfs_remove(dentry, parent);
        mutex_unlock(&parent->d_inode->i_mutex);
        simple_release_fs(&debugfs_mount, &debugfs_mount_count);
 }
-EXPORT_SYMBOL_GPL(debugfs_remove);
+EXPORT_SYMBOL_GPL(debugfs_remove_recursive);
 
 /**
  * debugfs_rename - rename a file/directory in the debugfs filesystem
index 6149e4b58c887a62cd11e4776650b1880745af2a..efef715135d34e459ce450eb24ca41e4234cf471 100644 (file)
@@ -401,7 +401,7 @@ void register_disk(struct gendisk *disk)
        disk->dev.parent = disk->driverfs_dev;
        disk->dev.devt = MKDEV(disk->major, disk->first_minor);
 
-       strlcpy(disk->dev.bus_id, disk->disk_name, KOBJ_NAME_LEN);
+       strlcpy(disk->dev.bus_id, disk->disk_name, BUS_ID_SIZE);
        /* ewww... some of these buggers have / in the name... */
        s = strchr(disk->dev.bus_id, '/');
        if (s)
index 8c0e4b92574f6ad71a473c9220bcb980e9b5a7c3..c1a7efb310bf3517ab1bf52bb1312a79a517f2d6 100644 (file)
@@ -398,7 +398,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
 }
 
 /**
- *     sysfs_add_one - add sysfs_dirent to parent
+ *     __sysfs_add_one - add sysfs_dirent to parent without warning
  *     @acxt: addrm context to use
  *     @sd: sysfs_dirent to be added
  *
@@ -417,7 +417,7 @@ void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
  *     0 on success, -EEXIST if entry with the given name already
  *     exists.
  */
-int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
 {
        if (sysfs_find_dirent(acxt->parent_sd, sd->s_name))
                return -EEXIST;
@@ -434,6 +434,39 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
        return 0;
 }
 
+/**
+ *     sysfs_add_one - add sysfs_dirent to parent
+ *     @acxt: addrm context to use
+ *     @sd: sysfs_dirent to be added
+ *
+ *     Get @acxt->parent_sd and set sd->s_parent to it and increment
+ *     nlink of parent inode if @sd is a directory and link into the
+ *     children list of the parent.
+ *
+ *     This function should be called between calls to
+ *     sysfs_addrm_start() and sysfs_addrm_finish() and should be
+ *     passed the same @acxt as passed to sysfs_addrm_start().
+ *
+ *     LOCKING:
+ *     Determined by sysfs_addrm_start().
+ *
+ *     RETURNS:
+ *     0 on success, -EEXIST if entry with the given name already
+ *     exists.
+ */
+int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
+{
+       int ret;
+
+       ret = __sysfs_add_one(acxt, sd);
+       if (ret == -EEXIST) {
+               printk(KERN_WARNING "sysfs: duplicate filename '%s' "
+                      "can not be created\n", sd->s_name);
+               WARN_ON(1);
+       }
+       return ret;
+}
+
 /**
  *     sysfs_remove_one - remove sysfs_dirent from parent
  *     @acxt: addrm context to use
index e7735f643cd1b03eab8560479d6f691e387ce218..3f07893ff8968a483f4c5fc45646c80e3535966f 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/kobject.h>
 #include <linux/kallsyms.h>
 #include <linux/slab.h>
+#include <linux/fsnotify.h>
 #include <linux/namei.h>
 #include <linux/poll.h>
 #include <linux/list.h>
@@ -585,9 +586,11 @@ int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode)
 
        newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO);
        newattrs.ia_valid = ATTR_MODE | ATTR_CTIME;
-       rc = notify_change(victim, &newattrs);
+       newattrs.ia_ctime = current_fs_time(inode->i_sb);
+       rc = sysfs_setattr(victim, &newattrs);
 
        if (rc == 0) {
+               fsnotify_change(victim, newattrs.ia_valid);
                mutex_lock(&sysfs_mutex);
                victim_sd->s_mode = newattrs.ia_mode;
                mutex_unlock(&sysfs_mutex);
index 817f5966edcac2c2e36033902f2ac2ce0f89f626..a3ba217fbe74f4313a1dca88a8cc863e14766341 100644 (file)
 
 #include "sysfs.h"
 
-/**
- *     sysfs_create_link - create symlink between two objects.
- *     @kobj:  object whose directory we're creating the link in.
- *     @target:        object we're pointing to.
- *     @name:          name of the symlink.
- */
-int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name)
+static int sysfs_do_create_link(struct kobject *kobj, struct kobject *target,
+                               const char *name, int warn)
 {
        struct sysfs_dirent *parent_sd = NULL;
        struct sysfs_dirent *target_sd = NULL;
@@ -65,7 +60,10 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
        target_sd = NULL;       /* reference is now owned by the symlink */
 
        sysfs_addrm_start(&acxt, parent_sd);
-       error = sysfs_add_one(&acxt, sd);
+       if (warn)
+               error = sysfs_add_one(&acxt, sd);
+       else
+               error = __sysfs_add_one(&acxt, sd);
        sysfs_addrm_finish(&acxt);
 
        if (error)
@@ -79,6 +77,33 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
        return error;
 }
 
+/**
+ *     sysfs_create_link - create symlink between two objects.
+ *     @kobj:  object whose directory we're creating the link in.
+ *     @target:        object we're pointing to.
+ *     @name:          name of the symlink.
+ */
+int sysfs_create_link(struct kobject *kobj, struct kobject *target,
+                     const char *name)
+{
+       return sysfs_do_create_link(kobj, target, name, 1);
+}
+
+/**
+ *     sysfs_create_link_nowarn - create symlink between two objects.
+ *     @kobj:  object whose directory we're creating the link in.
+ *     @target:        object we're pointing to.
+ *     @name:          name of the symlink.
+ *
+ *     This function does the same as sysf_create_link(), but it
+ *     doesn't warn if the link already exists.
+ */
+int sysfs_create_link_nowarn(struct kobject *kobj, struct kobject *target,
+                            const char *name)
+{
+       return sysfs_do_create_link(kobj, target, name, 0);
+}
+
 /**
  *     sysfs_remove_link - remove symlink in object's directory.
  *     @kobj:  object we're acting for.
index ce4e15f8aaebce521b4e8b4469c5923307cedad3..a5db496f71c717ce63073440a3c9a23138b67d47 100644 (file)
@@ -107,6 +107,7 @@ struct sysfs_dirent *sysfs_get_active_two(struct sysfs_dirent *sd);
 void sysfs_put_active_two(struct sysfs_dirent *sd);
 void sysfs_addrm_start(struct sysfs_addrm_cxt *acxt,
                       struct sysfs_dirent *parent_sd);
+int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
 int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
 void sysfs_remove_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd);
 void sysfs_addrm_finish(struct sysfs_addrm_cxt *acxt);
index 32755cdf68db6512daeea31a16e18048167b7212..e1a6c046cea3d8133d3f659a1a85ffbe32844b5b 100644 (file)
@@ -44,6 +44,7 @@ struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
                                      const char *dest);
 
 void debugfs_remove(struct dentry *dentry);
+void debugfs_remove_recursive(struct dentry *dentry);
 
 struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, const char *new_name);
@@ -101,6 +102,9 @@ static inline struct dentry *debugfs_create_symlink(const char *name,
 static inline void debugfs_remove(struct dentry *dentry)
 { }
 
+static inline void debugfs_remove_recursive(struct dentry *dentry)
+{ }
+
 static inline struct dentry *debugfs_rename(struct dentry *old_dir, struct dentry *old_dentry,
                 struct dentry *new_dir, char *new_name)
 {
index f71a78d123aef9d7b3b03276921d10286e1eceed..d24a47f80f9c67587df13a5a8b57282f7dd2e8dd 100644 (file)
@@ -16,6 +16,7 @@
 #include <linux/kobject.h>
 #include <linux/klist.h>
 #include <linux/list.h>
+#include <linux/lockdep.h>
 #include <linux/compiler.h>
 #include <linux/types.h>
 #include <linux/module.h>
 #include <asm/atomic.h>
 #include <asm/device.h>
 
-#define DEVICE_NAME_SIZE       50
-/* DEVICE_NAME_HALF is really less than half to accommodate slop */
-#define DEVICE_NAME_HALF       __stringify(20)
-#define DEVICE_ID_SIZE         32
-#define BUS_ID_SIZE            KOBJ_NAME_LEN
-
+#define BUS_ID_SIZE            20
 
 struct device;
 struct device_driver;
 struct driver_private;
 struct class;
+struct class_private;
 struct bus_type;
 struct bus_type_private;
 
@@ -186,13 +183,9 @@ struct class {
        const char              *name;
        struct module           *owner;
 
-       struct kset             subsys;
-       struct list_head        devices;
-       struct list_head        interfaces;
-       struct kset             class_dirs;
-       struct semaphore        sem; /* locks children, devices, interfaces */
        struct class_attribute          *class_attrs;
        struct device_attribute         *dev_attrs;
+       struct kobject                  *dev_kobj;
 
        int (*dev_uevent)(struct device *dev, struct kobj_uevent_env *env);
 
@@ -203,13 +196,28 @@ struct class {
        int (*resume)(struct device *dev);
 
        struct pm_ops *pm;
+       struct class_private *p;
 };
 
-extern int __must_check class_register(struct class *class);
+extern struct kobject *sysfs_dev_block_kobj;
+extern struct kobject *sysfs_dev_char_kobj;
+extern int __must_check __class_register(struct class *class,
+                                        struct lock_class_key *key);
 extern void class_unregister(struct class *class);
-extern int class_for_each_device(struct class *class, void *data,
+
+/* This is a #define to keep the compiler from merging different
+ * instances of the __key variable */
+#define class_register(class)                  \
+({                                             \
+       static struct lock_class_key __key;     \
+       __class_register(class, &__key);        \
+})
+
+extern int class_for_each_device(struct class *class, struct device *start,
+                                void *data,
                                 int (*fn)(struct device *dev, void *data));
-extern struct device *class_find_device(struct class *class, void *data,
+extern struct device *class_find_device(struct class *class,
+                                       struct device *start, void *data,
                                        int (*match)(struct device *, void *));
 
 struct class_attribute {
@@ -237,9 +245,19 @@ struct class_interface {
 extern int __must_check class_interface_register(struct class_interface *);
 extern void class_interface_unregister(struct class_interface *);
 
-extern struct class *class_create(struct module *owner, const char *name);
+extern struct class * __must_check __class_create(struct module *owner,
+                                                 const char *name,
+                                                 struct lock_class_key *key);
 extern void class_destroy(struct class *cls);
 
+/* This is a #define to keep the compiler from merging different
+ * instances of the __key variable */
+#define class_create(owner, name)              \
+({                                             \
+       static struct lock_class_key __key;     \
+       __class_create(owner, name, &__key);    \
+})
+
 /*
  * The type of device, "struct device" is embedded in. A class
  * or bus can contain devices of different types
@@ -468,14 +486,10 @@ extern struct device *device_create_vargs(struct class *cls,
                                          const char *fmt,
                                          va_list vargs);
 extern struct device *device_create(struct class *cls, struct device *parent,
-                                   dev_t devt, const char *fmt, ...)
-                                   __attribute__((format(printf, 4, 5)));
-extern struct device *device_create_drvdata(struct class *cls,
-                                           struct device *parent,
-                                           dev_t devt,
-                                           void *drvdata,
-                                           const char *fmt, ...)
+                                   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);
 
 /*
index fe806b6f030dfb2d7583751cc33d96f36a8b7d90..e61c0be2a45977fb61e48b0b0eb89f016b7c978d 100644 (file)
@@ -40,7 +40,7 @@ struct eisa_device {
        u64                   dma_mask;
        struct device         dev; /* generic device */
 #ifdef CONFIG_EISA_NAMES
-       char                  pretty_name[DEVICE_NAME_SIZE];
+       char                  pretty_name[50];
 #endif
 };
 
index 39e709f88aa001b73d1f9e7c6a9d33edac619c1f..60f0d418ae3264c8684accf0f44cbab9c2db700e 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/wait.h>
 #include <asm/atomic.h>
 
-#define KOBJ_NAME_LEN                  20
 #define UEVENT_HELPER_PATH_LEN         256
 #define UEVENT_NUM_ENVP                        32      /* number of env pointers */
 #define UEVENT_BUFFER_SIZE             2048    /* buffer for the variables */
@@ -59,12 +58,12 @@ enum kobject_action {
 
 struct kobject {
        const char              *name;
-       struct kref             kref;
        struct list_head        entry;
        struct kobject          *parent;
        struct kset             *kset;
        struct kobj_type        *ktype;
        struct sysfs_dirent     *sd;
+       struct kref             kref;
        unsigned int state_initialized:1;
        unsigned int state_in_sysfs:1;
        unsigned int state_add_uevent_sent:1;
index a9fae032ba8176db0a256aea1160f3c04e78720e..9c1d95491f8b0a7d208257b39f6fd794d713be84 100644 (file)
@@ -189,7 +189,7 @@ typedef union {
 */
 
 struct map_info {
-       char *name;
+       const char *name;
        unsigned long size;
        resource_size_t phys;
 #define NO_XIP (-1UL)
index 245f9098e171cfe2bf5b27860f6be2e0365fa57f..8b5d49133ec616a80fdc7f375b95e9cc244e16cc 100644 (file)
@@ -121,7 +121,7 @@ struct mtd_info {
        u_int32_t oobavail;  // Available OOB bytes per block
 
        // Kernel-only stuff starts here.
-       char *name;
+       const char *name;
        int index;
 
        /* ecc layout structure pointer - read only ! */
index 387e428f1cdf233ab3b54b078ba34b20157b2e37..b9a76c9720844105eccc6fe89dc139dd54c8095e 100644 (file)
@@ -733,7 +733,7 @@ struct spi_board_info {
         * controller_data goes to spi_device.controller_data,
         * irq is copied too
         */
-       char            modalias[KOBJ_NAME_LEN];
+       char            modalias[32];
        const void      *platform_data;
        void            *controller_data;
        int             irq;
index f2767bc6b73517bea32d2e34ed362a8e61b794f1..f395bb3fa2f2065375f25c51ea8221d27a4d3dc6 100644 (file)
@@ -99,8 +99,9 @@ extern void sysdev_unregister(struct sys_device *);
 
 struct sysdev_attribute { 
        struct attribute        attr;
-       ssize_t (*show)(struct sys_device *, char *);
-       ssize_t (*store)(struct sys_device *, const char *, size_t);
+       ssize_t (*show)(struct sys_device *, struct sysdev_attribute *, char *);
+       ssize_t (*store)(struct sys_device *, struct sysdev_attribute *,
+                        const char *, size_t);
 };
 
 
@@ -118,4 +119,38 @@ struct sysdev_attribute {
 extern int sysdev_create_file(struct sys_device *, struct sysdev_attribute *);
 extern void sysdev_remove_file(struct sys_device *, struct sysdev_attribute *);
 
+struct sysdev_ext_attribute {
+       struct sysdev_attribute attr;
+       void *var;
+};
+
+/*
+ * Support for simple variable sysdev attributes.
+ * The pointer to the variable is stored in a sysdev_ext_attribute
+ */
+
+/* Add more types as needed */
+
+extern ssize_t sysdev_show_ulong(struct sys_device *, struct sysdev_attribute *,
+                               char *);
+extern ssize_t sysdev_store_ulong(struct sys_device *,
+                       struct sysdev_attribute *, const char *, size_t);
+extern ssize_t sysdev_show_int(struct sys_device *, struct sysdev_attribute *,
+                               char *);
+extern ssize_t sysdev_store_int(struct sys_device *,
+                       struct sysdev_attribute *, const char *, size_t);
+
+#define _SYSDEV_ULONG_ATTR(_name, _mode, _var)                         \
+       { _SYSDEV_ATTR(_name, _mode, sysdev_show_ulong, sysdev_store_ulong), \
+         &(_var) }
+#define SYSDEV_ULONG_ATTR(_name, _mode, _var)                  \
+       struct sysdev_ext_attribute attr_##_name =              \
+               _SYSDEV_ULONG_ATTR(_name, _mode, _var);
+#define _SYSDEV_INT_ATTR(_name, _mode, _var)                           \
+       { _SYSDEV_ATTR(_name, _mode, sysdev_show_int, sysdev_store_int), \
+         &(_var) }
+#define SYSDEV_INT_ATTR(_name, _mode, _var)                    \
+       struct sysdev_ext_attribute attr_##_name =              \
+               _SYSDEV_INT_ATTR(_name, _mode, _var);
+
 #endif /* _SYSDEV_H_ */
index 7858eac40aa7be8e27f9091806f2b194eabedd61..37fa24152bd810f7d9dd67b685e738179b5bfdf9 100644 (file)
@@ -101,6 +101,9 @@ void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr);
 
 int __must_check sysfs_create_link(struct kobject *kobj, struct kobject *target,
                                   const char *name);
+int __must_check sysfs_create_link_nowarn(struct kobject *kobj,
+                                         struct kobject *target,
+                                         const char *name);
 void sysfs_remove_link(struct kobject *kobj, const char *name);
 
 int __must_check sysfs_create_group(struct kobject *kobj,
@@ -180,6 +183,13 @@ static inline int sysfs_create_link(struct kobject *kobj,
        return 0;
 }
 
+static inline int sysfs_create_link_nowarn(struct kobject *kobj,
+                                          struct kobject *target,
+                                          const char *name)
+{
+       return 0;
+}
+
 static inline void sysfs_remove_link(struct kobject *kobj, const char *name)
 {
 }
index 973386d439da24ffef58636347b3463c5aa038b8..cdf338d94b7f450b42fbb1a12779cdbc7c920248 100644 (file)
@@ -36,7 +36,7 @@ struct uio_mem {
        struct uio_map          *map;
 };
 
-#define MAX_UIO_MAPS   5
+#define MAX_UIO_MAPS   5
 
 struct uio_device;
 
@@ -53,6 +53,7 @@ struct uio_device;
  * @mmap:              mmap operation for this uio device
  * @open:              open operation for this uio device
  * @release:           release operation for this uio device
+ * @irqcontrol:                disable/enable irqs when 0/1 is written to /dev/uioX
  */
 struct uio_info {
        struct uio_device       *uio_dev;
@@ -66,6 +67,7 @@ struct uio_info {
        int (*mmap)(struct uio_info *info, struct vm_area_struct *vma);
        int (*open)(struct uio_info *info, struct inode *inode);
        int (*release)(struct uio_info *info, struct inode *inode);
+       int (*irqcontrol)(struct uio_info *info, s32 irq_on);
 };
 
 extern int __must_check
@@ -80,11 +82,11 @@ static inline int __must_check
 extern void uio_unregister_device(struct uio_info *info);
 extern void uio_event_notify(struct uio_info *info);
 
-/* defines for uio_device->irq */
+/* defines for uio_info->irq */
 #define UIO_IRQ_CUSTOM -1
 #define UIO_IRQ_NONE   -2
 
-/* defines for uio_device->memtype */
+/* defines for uio_mem->memtype */
 #define UIO_MEM_NONE   0
 #define UIO_MEM_PHYS   1
 #define UIO_MEM_LOGICAL        2
index 1834fdfe82a7d7129880e2a0380c2e99b77adfa3..a594bac4a77db2b5f311470cc2e2324d5cf6bedb 100644 (file)
@@ -623,7 +623,7 @@ struct Scsi_Host {
        /*
         * Optional work queue to be utilized by the transport
         */
-       char work_q_name[KOBJ_NAME_LEN];
+       char work_q_name[20];
        struct workqueue_struct *work_q;
 
        /*
index 06f72bab9df0af520039506ece89079d549178aa..878373c32ef7e434bdb6c840ca15b4ec0412d550 100644 (file)
@@ -489,9 +489,9 @@ struct fc_host_attrs {
        u16 npiv_vports_inuse;
 
        /* work queues for rport state manipulation */
-       char work_q_name[KOBJ_NAME_LEN];
+       char work_q_name[20];
        struct workqueue_struct *work_q;
-       char devloss_work_q_name[KOBJ_NAME_LEN];
+       char devloss_work_q_name[20];
        struct workqueue_struct *devloss_work_q;
 };
 
index f5444e033cc92d7c8707d3b3c59b71b9048463cd..8b6c91df4c7a9057c08aa23569838ac7358ddc89 100644 (file)
@@ -198,7 +198,7 @@ struct iscsi_cls_host {
        atomic_t nr_scans;
        struct mutex mutex;
        struct workqueue_struct *scan_workq;
-       char scan_workq_name[KOBJ_NAME_LEN];
+       char scan_workq_name[20];
 };
 
 extern void iscsi_host_for_each_session(struct Scsi_Host *shost,
index 092e4c620af908410a30ef3ee9ece43df72dcb84..a56f629b057a75be4ff0428d265b8c833886dd85 100644 (file)
@@ -297,8 +297,8 @@ static int test_func(void *data)
  *
  * opcode:data
  */
-static ssize_t sysfs_test_command(struct sys_device *dev, const char *buf,
-                                 size_t count)
+static ssize_t sysfs_test_command(struct sys_device *dev, struct sysdev_attribute *attr,
+                                 const char *buf, size_t count)
 {
        struct sched_param schedpar;
        struct test_thread_data *td;
@@ -360,7 +360,8 @@ static ssize_t sysfs_test_command(struct sys_device *dev, const char *buf,
  * @dev:       thread to query
  * @buf:       char buffer to be filled with thread status info
  */
-static ssize_t sysfs_test_status(struct sys_device *dev, char *buf)
+static ssize_t sysfs_test_status(struct sys_device *dev, struct sysdev_attribute *attr,
+                                char *buf)
 {
        struct test_thread_data *td;
        struct task_struct *tsk;
index 99e6d850ecab097e4d1c5cbda1e0419548093681..b1104ea5d2553615899cf820d0a632ed490b0e61 100644 (file)
@@ -7737,11 +7737,13 @@ static ssize_t sched_power_savings_store(const char *buf, size_t count, int smt)
 }
 
 #ifdef CONFIG_SCHED_MC
-static ssize_t sched_mc_power_savings_show(struct sys_device *dev, char *page)
+static ssize_t sched_mc_power_savings_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *page)
 {
        return sprintf(page, "%u\n", sched_mc_power_savings);
 }
 static ssize_t sched_mc_power_savings_store(struct sys_device *dev,
+                                           struct sysdev_attribute *attr,
                                            const char *buf, size_t count)
 {
        return sched_power_savings_store(buf, count, 0);
@@ -7751,11 +7753,13 @@ static SYSDEV_ATTR(sched_mc_power_savings, 0644, sched_mc_power_savings_show,
 #endif
 
 #ifdef CONFIG_SCHED_SMT
-static ssize_t sched_smt_power_savings_show(struct sys_device *dev, char *page)
+static ssize_t sched_smt_power_savings_show(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *page)
 {
        return sprintf(page, "%u\n", sched_smt_power_savings);
 }
 static ssize_t sched_smt_power_savings_store(struct sys_device *dev,
+                                            struct sysdev_attribute *attr,
                                             const char *buf, size_t count)
 {
        return sched_power_savings_store(buf, count, 1);
index dadde5361f32df668877aaa8d5a2e56abb5bb9ff..b1c2da81b050d74fec257f51c42e91e1c07b1d03 100644 (file)
@@ -376,7 +376,8 @@ void clocksource_unregister(struct clocksource *cs)
  * Provides sysfs interface for listing current clocksource.
  */
 static ssize_t
-sysfs_show_current_clocksources(struct sys_device *dev, char *buf)
+sysfs_show_current_clocksources(struct sys_device *dev,
+                               struct sysdev_attribute *attr, char *buf)
 {
        ssize_t count = 0;
 
@@ -397,6 +398,7 @@ sysfs_show_current_clocksources(struct sys_device *dev, char *buf)
  * clocksource selction.
  */
 static ssize_t sysfs_override_clocksource(struct sys_device *dev,
+                                         struct sysdev_attribute *attr,
                                          const char *buf, size_t count)
 {
        struct clocksource *ovr = NULL;
@@ -449,7 +451,9 @@ static ssize_t sysfs_override_clocksource(struct sys_device *dev,
  * Provides sysfs interface for listing registered clocksources
  */
 static ssize_t
-sysfs_show_available_clocksources(struct sys_device *dev, char *buf)
+sysfs_show_available_clocksources(struct sys_device *dev,
+                                 struct sysdev_attribute *attr,
+                                 char *buf)
 {
        struct clocksource *src;
        ssize_t count = 0;
index df27132a56f437eacdf53cde9caf93162d87d1d0..ba106db5a65b2b5fdd7be1821e8bd59af9dd855c 100644 (file)
@@ -74,6 +74,9 @@ config DEBUG_FS
          debugging files into.  Enable this option to be able to read and
          write to these files.
 
+         For detailed documentation on the debugfs API, see
+         Documentation/DocBook/filesystems.
+
          If unsure, say N.
 
 config HEADERS_CHECK
index dcade0543bd2a2395ede8f91bf33438348e54f7e..744401571ed76cbd48717f1aa1970804fc33cd9a 100644 (file)
@@ -216,13 +216,19 @@ static int kobject_add_internal(struct kobject *kobj)
 static int kobject_set_name_vargs(struct kobject *kobj, const char *fmt,
                                  va_list vargs)
 {
-       /* Free the old name, if necessary. */
-       kfree(kobj->name);
+       const char *old_name = kobj->name;
+       char *s;
 
        kobj->name = kvasprintf(GFP_KERNEL, fmt, vargs);
        if (!kobj->name)
                return -ENOMEM;
 
+       /* ewww... some of these buggers have '/' in the name ... */
+       s = strchr(kobj->name, '/');
+       if (s)
+               s[0] = '!';
+
+       kfree(old_name);
        return 0;
 }
 
index 2fa545a631607dc1d0498a7c2bff592ad7d115bb..9f8d599459d11011c0d9b5a7a11030af7c6e2f51 100644 (file)
@@ -245,7 +245,8 @@ int kobject_uevent_env(struct kobject *kobj, enum kobject_action action,
                if (retval)
                        goto exit;
 
-               call_usermodehelper(argv[0], argv, env->envp, UMH_WAIT_EXEC);
+               retval = call_usermodehelper(argv[0], argv,
+                                            env->envp, UMH_WAIT_EXEC);
        }
 
 exit:
index 844ca5f1b2d4d9457dbb24542b4d36e40b586c7c..c85bf8f678dc5f1456788d3ebce5212627211912 100644 (file)
@@ -398,10 +398,6 @@ int hci_register_sysfs(struct hci_dev *hdev)
                if (device_create_file(dev, bt_attrs[i]) < 0)
                        BT_ERR("Failed to create device attribute");
 
-       if (sysfs_create_link(&bt_class->subsys.kobj,
-                               &dev->kobj, kobject_name(&dev->kobj)) < 0)
-               BT_ERR("Failed to create class symlink");
-
        return 0;
 }
 
@@ -409,9 +405,6 @@ void hci_unregister_sysfs(struct hci_dev *hdev)
 {
        BT_DBG("%p name %s type %d", hdev, hdev->name, hdev->type);
 
-       sysfs_remove_link(&bt_class->subsys.kobj,
-                                       kobject_name(&hdev->dev.kobj));
-
        device_del(&hdev->dev);
 }
 
index 9392116e47b009e1ef02f69f85ecff247f5b78b8..e6cf7a43a297f9473b155add043b7bfab56c6938 100644 (file)
@@ -124,7 +124,7 @@ static int fw_setup_class_device(struct class_device *class_dev,
        class_dev->class_id[BUS_ID_SIZE-1] = '\0';
        class_dev->dev = device;
 
-       class_dev->class = &firmware_class,
+       class_dev->class = &firmware_class;
        class_set_devdata(class_dev, fw_priv);
        retval = class_device_register(class_dev);
        if (retval) {
index b0a1b4fe6584a026866233136d69d19bb3f9d468..7395c0bbae18426e119d47bb67e59da293228952 100644 (file)
@@ -211,7 +211,7 @@ static struct foo_obj *create_foo_obj(const char *name)
         */
        retval = kobject_init_and_add(&foo->kobj, &foo_ktype, NULL, "%s", name);
        if (retval) {
-               kfree(foo);
+               kobject_put(&foo->kobj);
                return NULL;
        }
 
index 37d5c363fbcd8f0008044a08414721f9710c7442..1fcaf3284a6a2990128f2589b5856cec3997097c 100644 (file)
@@ -340,11 +340,18 @@ static int do_acpi_entry(const char *filename,
 }
 
 /* looks like: "pnp:dD" */
-static int do_pnp_entry(const char *filename,
-                       struct pnp_device_id *id, char *alias)
+static void do_pnp_device_entry(void *symval, unsigned long size,
+                               struct module *mod)
 {
-       sprintf(alias, "pnp:d%s*", id->id);
-       return 1;
+       const unsigned long id_size = sizeof(struct pnp_device_id);
+       const struct pnp_device_id *id = symval;
+
+       device_id_check(mod->name, "pnp", size, id_size, symval);
+
+       buf_printf(&mod->dev_table_buf,
+                  "MODULE_ALIAS(\"pnp:d%s*\");\n", id->id);
+       buf_printf(&mod->dev_table_buf,
+                  "MODULE_ALIAS(\"acpi*:%s:*\");\n", id->id);
 }
 
 /* looks like: "pnp:dD" for every device of the card */
@@ -388,9 +395,12 @@ static void do_pnp_card_entries(void *symval, unsigned long size,
                        }
 
                        /* add an individual alias for every device entry */
-                       if (!dup)
+                       if (!dup) {
                                buf_printf(&mod->dev_table_buf,
                                           "MODULE_ALIAS(\"pnp:d%s*\");\n", id);
+                               buf_printf(&mod->dev_table_buf,
+                                          "MODULE_ALIAS(\"acpi*:%s:*\");\n", id);
+                       }
                }
        }
 }
@@ -701,9 +711,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
                         sizeof(struct acpi_device_id), "acpi",
                         do_acpi_entry, mod);
        else if (sym_is(symname, "__mod_pnp_device_table"))
-               do_table(symval, sym->st_size,
-                        sizeof(struct pnp_device_id), "pnp",
-                        do_pnp_entry, mod);
+               do_pnp_device_entry(symval, sym->st_size, mod);
        else if (sym_is(symname, "__mod_pnp_card_device_table"))
                do_pnp_card_entries(symval, sym->st_size, mod);
        else if (sym_is(symname, "__mod_pcmcia_device_table"))
index 5c254d498ae094d452bb0c85a143f468eaedde0a..df46bbc25dc2da7dccf2872abbae76837693e3ba 100644 (file)
@@ -548,8 +548,9 @@ int snd_card_register(struct snd_card *card)
        snd_assert(card != NULL, return -EINVAL);
 #ifndef CONFIG_SYSFS_DEPRECATED
        if (!card->card_dev) {
-               card->card_dev = device_create(sound_class, card->dev, 0,
-                                              "card%i", card->number);
+               card->card_dev = device_create_drvdata(sound_class, card->dev,
+                                                      MKDEV(0, 0), NULL,
+                                                      "card%i", card->number);
                if (IS_ERR(card->card_dev))
                        card->card_dev = NULL;
        }
index a9c23b2502ad4399b9316a900462ba80bf6a3ae7..7d89c081a0866bfe9b7ee22696ee286007cb0a2a 100644 (file)
@@ -560,17 +560,19 @@ static int __init oss_init(void)
        sound_dmap_flag = (dmabuf > 0 ? 1 : 0);
 
        for (i = 0; i < ARRAY_SIZE(dev_list); i++) {
-               device_create(sound_class, NULL,
-                             MKDEV(SOUND_MAJOR, dev_list[i].minor),
-                             "%s", dev_list[i].name);
+               device_create_drvdata(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(sound_class, NULL,
-                                     MKDEV(SOUND_MAJOR, dev_list[i].minor + (j*0x10)),
-                                     "%s%d", dev_list[i].name, j);
+                       device_create_drvdata(sound_class, NULL,
+                                             MKDEV(SOUND_MAJOR,
+                                                   dev_list[i].minor + (j*0x10)),
+                                             NULL,
+                                             "%s%d", dev_list[i].name, j);
        }
 
        if (sound_nblocks >= 1024)
index dcfc1d5ce63173e5c636cc344d391889a1236611..1b04259a4328486357059acfd892bb3015285203 100644 (file)
@@ -171,8 +171,9 @@ 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(sound_class, dev, MKDEV(SOUND_MAJOR, s->unit_minor),
-                     s->name+6);
+       device_create_drvdata(sound_class, dev,
+                             MKDEV(SOUND_MAJOR, s->unit_minor),
+                             NULL, s->name+6);
        return r;
 
  fail: