[GIT PATCH] driver core patches against 2.6.26 - Kernel

This is a discussion on [GIT PATCH] driver core patches against 2.6.26 - Kernel ; This changes vortex_prob1() to handle pci_name() now returning a constant string. Cc: Steffen Klassert Signed-off-by: Greg Kroah-Hartman --- drivers/net/3c59x.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index aabad8c..8db4e6b 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c ...

+ Reply to Thread
Page 3 of 4 FirstFirst 1 2 3 4 LastLast
Results 41 to 60 of 79

Thread: [GIT PATCH] driver core patches against 2.6.26

  1. [PATCH 77/79] 3c59x: handle pci_name() being const

    This changes vortex_prob1() to handle pci_name() now returning a
    constant string.

    Cc: Steffen Klassert
    Signed-off-by: Greg Kroah-Hartman
    ---
    drivers/net/3c59x.c | 2 +-
    1 files changed, 1 insertions(+), 1 deletions(-)

    diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
    index aabad8c..8db4e6b 100644
    --- a/drivers/net/3c59x.c
    +++ b/drivers/net/3c59x.c
    @@ -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);
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  2. [PATCH 69/79] sysfs-rules.txt: reword API stability statement

    From: Nathan Lynch

    The first paragraph of this document implies that user space developers
    shouldn't use sysfs at all, but then it goes on to describe rules that
    developers should follow when accessing sysfs. Not only is this somewhat
    self-contradictory, it has been shown to discourage developers from using
    established sysfs interfaces.

    A note of caution is more appropriate than a blanket "sysfs will never
    be stable" assertion.

    Signed-off-by: Nathan Lynch
    Cc: Stephen Rothwell
    Signed-off-by: Andrew Morton
    Signed-off-by: Greg Kroah-Hartman
    ---
    Documentation/sysfs-rules.txt | 5 ++---
    1 files changed, 2 insertions(+), 3 deletions(-)

    diff --git a/Documentation/sysfs-rules.txt b/Documentation/sysfs-rules.txt
    index 80ef562..6049a2a 100644
    --- a/Documentation/sysfs-rules.txt
    +++ b/Documentation/sysfs-rules.txt
    @@ -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
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  3. [PATCH 74/79] sysdev: Convert the x86 mce tolerant sysdev attribute to generic attribute

    From: Andi Kleen

    Use the new generic int attribute accessors for the x86 mce tolerant
    attribute. Simple example to illustrate the new macros.

    There are much more places all over the tree that could be converted
    like this.

    Signed-off-by: Andi Kleen
    Signed-off-by: Greg Kroah-Hartman
    ---
    arch/x86/kernel/cpu/mcheck/mce_64.c | 4 ++--
    1 files changed, 2 insertions(+), 2 deletions(-)

    diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
    index e6a4d5f..9ab65be 100644
    --- a/arch/x86/kernel/cpu/mcheck/mce_64.c
    +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
    @@ -812,12 +812,12 @@ static ssize_t set_trigger(struct sys_device *s, struct sysdev_attribute *attr,
    }

    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
    };

    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  4. [PATCH 70/79] kobject: Transmit return value of call_usermodehelper() to caller

    From: Wang Chen

    kobject_uevent_env() drops the return value of call_usermodehelper().
    It will make upper caller, such as dm_send_uevents(), to lose error
    information.

    BTW, Previously kobject_uevent_env() transmitted return of
    call_usermodehelper() to callers, but
    commit 5f123fbd80f4f788554636f02bf73e40f914e0d6
    "[PATCH] merge kobject_uevent and kobject_hotplug" removed it.

    Signed-off-by: Wang Chen
    Cc: Kay Sievers
    Signed-off-by: Greg Kroah-Hartman
    ---
    lib/kobject_uevent.c | 3 ++-
    1 files changed, 2 insertions(+), 1 deletions(-)

    diff --git a/lib/kobject_uevent.c b/lib/kobject_uevent.c
    index 2fa545a..9f8d599 100644
    --- a/lib/kobject_uevent.c
    +++ b/lib/kobject_uevent.c
    @@ -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:
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  5. [PATCH 75/79] HP iLO driver

    From: David Altobelli

    A driver for the HP iLO/iLO2 management processor, which allows userspace
    programs to query the management processor. Programs can open a channel
    to the device (/dev/hpilo/dXccbN), and use this to send/receive queries.
    The O_EXCL open flag is used to indicate that a particular channel cannot
    be shared between processes. This driver will replace various packages
    HP has shipped, including hprsm and hp-ilo.

    Signed-off-by: David Altobelli
    Signed-off-by: Greg Kroah-Hartman
    ---
    drivers/misc/Kconfig | 13 +
    drivers/misc/Makefile | 1 +
    drivers/misc/hpilo.c | 768 +++++++++++++++++++++++++++++++++++++++++++++++++
    drivers/misc/hpilo.h | 189 ++++++++++++
    4 files changed, 971 insertions(+), 0 deletions(-)
    create mode 100644 drivers/misc/hpilo.c
    create mode 100644 drivers/misc/hpilo.h

    diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
    index 1921b8d..ce67d97 100644
    --- a/drivers/misc/Kconfig
    +++ b/drivers/misc/Kconfig
    @@ -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
    diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
    index a6dac6a..688fe76 100644
    --- a/drivers/misc/Makefile
    +++ b/drivers/misc/Makefile
    @@ -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
    index 0000000..05e2982
    --- /dev/null
    +++ b/drivers/misc/hpilo.c
    @@ -0,0 +1,768 @@
    +/*
    + * Driver for HP iLO/iLO2 management processor.
    + *
    + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
    + * David Altobelli
    + *
    + * 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
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#include
    +#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 ");
    +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
    index 0000000..a281207
    --- /dev/null
    +++ b/drivers/misc/hpilo.h
    @@ -0,0 +1,189 @@
    +/*
    + * linux/drivers/char/hpilo.h
    + *
    + * Copyright (C) 2008 Hewlett-Packard Development Company, L.P.
    + * David Altobelli
    + *
    + * 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 */
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  6. [PATCH 57/79] UIO: Add write function to allow irq masking

    From: Hans J. Koch

    Sometimes it is necessary to enable/disable the interrupt of a UIO device
    from the userspace part of the driver. With this patch, the UIO kernel driver
    can implement an "irqcontrol()" function that does this. Userspace can write
    an s32 value to /dev/uioX (usually 0 or 1 to turn the irq off or on). The
    UIO core will then call the driver's irqcontrol function.

    Signed-off-by: Hans J. Koch
    Acked-by: Uwe Kleine-König
    Acked-by: Magnus Damm
    Signed-off-by: Greg Kroah-Hartman
    ---
    Documentation/DocBook/uio-howto.tmpl | 40 +++++++++++++++++++++++++++++++++-
    drivers/uio/uio.c | 26 ++++++++++++++++++++++
    include/linux/uio_driver.h | 2 +
    3 files changed, 67 insertions(+), 1 deletions(-)

    diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
    index fdd7f4f..c4d1873 100644
    --- a/Documentation/DocBook/uio-howto.tmpl
    +++ b/Documentation/DocBook/uio-howto.tmpl
    @@ -30,6 +30,12 @@



    + 0.5
    + 2008-05-22
    + hjk
    + Added description of write() function.
    +

    +
    0.4
    2007-11-26
    hjk
    @@ -64,7 +70,7 @@

    Copyright and License

    - Copyright (c) 2006 by Hans-Jürgen Koch.

    + Copyright (c) 2006-2008 by Hans-Jürgen Koch.

    This documentation is Free Software licensed under the terms of the
    GPL version 2.
    @@ -189,6 +195,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.

    +
    + 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.
    +

    +
    + 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 /dev/uioX
    + will call the irqcontrol() 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
    + irqcontrol(), write() will
    + return with -ENOSYS.
    +



    To handle interrupts properly, your custom kernel module can
    @@ -362,6 +392,14 @@ device is actually used.
    open(), you will probably also want a custom
    release() function.

    +
    +
    +int (*irqcontrol)(struct uio_info *info, s32 irq_on)
    +
    : Optional. If you need to be able to enable or disable
    +interrupts from userspace by writing to /dev/uioX,
    +you can implement this function. The parameter irq_on
    +will be 0 to disable interrupts and 1 to enable them.
    +




    diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c
    index 5a7ca2e..3a6934b 100644
    --- a/drivers/uio/uio.c
    +++ b/drivers/uio/uio.c
    @@ -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/include/linux/uio_driver.h b/include/linux/uio_driver.h
    index 973386d..cf65e96 100644
    --- a/include/linux/uio_driver.h
    +++ b/include/linux/uio_driver.h
    @@ -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
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  7. [PATCH 71/79] driver core: Suppress sysfs warnings for device_rename().

    From: Cornelia Huck

    driver core: Suppress sysfs warnings for device_rename().

    Renaming network devices to an already existing name is not
    something we want sysfs to print a scary warning for, since the
    callers can deal with this correctly. So let's introduce
    sysfs_create_link_nowarn() which gets rid of the common warning.

    Signed-off-by: Cornelia Huck
    Signed-off-by: Greg Kroah-Hartman
    ---
    drivers/base/core.c | 9 +++++----
    fs/sysfs/dir.c | 37 +++++++++++++++++++++++++++++++++++--
    fs/sysfs/symlink.c | 41 +++++++++++++++++++++++++++++++++--------
    fs/sysfs/sysfs.h | 1 +
    include/linux/sysfs.h | 10 ++++++++++
    5 files changed, 84 insertions(+), 14 deletions(-)

    diff --git a/drivers/base/core.c b/drivers/base/core.c
    index c05b115..7d5c63c 100644
    --- a/drivers/base/core.c
    +++ b/drivers/base/core.c
    @@ -1345,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);
    @@ -1354,8 +1355,8 @@ int device_rename(struct device *dev, char *new_name)
    }
    #else
    if (dev->class) {
    - error = sysfs_create_link(&dev->class->p->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->p->class_subsys.kobj,
    diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
    index 8c0e4b9..c1a7efb 100644
    --- a/fs/sysfs/dir.c
    +++ b/fs/sysfs/dir.c
    @@ -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;
    @@ -435,6 +435,39 @@ int sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd)
    }

    /**
    + * 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
    * @sd: sysfs_dirent to be removed
    diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c
    index 817f596..a3ba217 100644
    --- a/fs/sysfs/symlink.c
    +++ b/fs/sysfs/symlink.c
    @@ -19,13 +19,8 @@

    #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)
    @@ -80,6 +78,33 @@ int sysfs_create_link(struct kobject * kobj, struct kobject * target, const char
    }

    /**
    + * 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.
    * @name: name of the symlink to remove.
    diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h
    index ce4e15f..a5db496 100644
    --- a/fs/sysfs/sysfs.h
    +++ b/fs/sysfs/sysfs.h
    @@ -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);
    diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
    index 7858eac..37fa241 100644
    --- a/include/linux/sysfs.h
    +++ b/include/linux/sysfs.h
    @@ -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)
    {
    }
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  8. [PATCH 63/79] sysfs: don't call notify_change

    From: Miklos Szeredi

    sysfs_chmod_file() calls notify_change() to change the permission bits
    on a sysfs file. Replace with explicit call to sysfs_setattr() and
    fsnotify_change().

    This is equivalent, except that security_inode_setattr() is not
    called. This function is called by drivers, so the security checks do
    not make any sense.

    Signed-off-by: Miklos Szeredi
    Signed-off-by: Greg Kroah-Hartman
    ---
    fs/sysfs/file.c | 5 ++++-
    1 files changed, 4 insertions(+), 1 deletions(-)

    diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
    index e7735f6..3f07893 100644
    --- a/fs/sysfs/file.c
    +++ b/fs/sysfs/file.c
    @@ -14,6 +14,7 @@
    #include
    #include
    #include
    +#include
    #include
    #include
    #include
    @@ -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);
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  9. [PATCH 76/79] MTD: handle pci_name() being const

    This changes the MTD core to handle pci_name() now returning a constant
    string.

    Cc: David Woodhouse
    Signed-off-by: Greg Kroah-Hartman
    ---
    drivers/mtd/devices/block2mtd.c | 8 +++++---
    include/linux/mtd/map.h | 2 +-
    include/linux/mtd/mtd.h | 2 +-
    3 files changed, 7 insertions(+), 5 deletions(-)

    diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c
    index 519d942..7b72a1b 100644
    --- a/drivers/mtd/devices/block2mtd.c
    +++ b/drivers/mtd/devices/block2mtd.c
    @@ -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;
    diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
    index a9fae03..9c1d954 100644
    --- a/include/linux/mtd/map.h
    +++ b/include/linux/mtd/map.h
    @@ -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)
    diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
    index 245f909..8b5d491 100644
    --- a/include/linux/mtd/mtd.h
    +++ b/include/linux/mtd/mtd.h
    @@ -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 ! */
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  10. [PATCH 64/79] uio-howto.tmpl: use standard copyright/legal markings

    From: Mike Frysinger

    The Userspace I/O HOWTO document uses straight tags and plain text
    to describe copyright/legal information. It should instead use the
    and tags like all other documents in the kernel.

    Signed-off-by: Mike Frysinger
    Acked-by: Hans J. Koch
    Cc: Randy Dunlap
    Signed-off-by: Andrew Morton
    Signed-off-by: Greg Kroah-Hartman
    ---
    Documentation/DocBook/uio-howto.tmpl | 23 ++++++++++++-----------
    1 files changed, 12 insertions(+), 11 deletions(-)

    diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
    index c4d1873..d799a26 100644
    --- a/Documentation/DocBook/uio-howto.tmpl
    +++ b/Documentation/DocBook/uio-howto.tmpl
    @@ -21,6 +21,18 @@



    +
    + 2006-2008
    + Hans-Jürgen Koch.
    +

    +
    +
    +
    +This documentation is Free Software licensed under the terms of the
    +GPL version 2.
    +

    +

    +
    2006-12-11


    @@ -66,17 +78,6 @@

    About this document

    -
    -
    -Copyright and License
    -
    - Copyright (c) 2006-2008 by Hans-Jürgen Koch.

    -
    -This documentation is Free Software licensed under the terms of the
    -GPL version 2.
    -

    -

    -


    Translations
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  11. [PATCH 65/79] uio-howto.tmpl: use unique output names

    From: Mike Frysinger

    The Userspace I/O HOWTO template sets two different sections with the same
    html output name (about.html). This clearly won't work, so change the
    first one to a unique "aboutthis.html" to prevent clobbering.

    Signed-off-by: Mike Frysinger
    Acked-by: Hans J. Koch
    Cc: Randy Dunlap
    Signed-off-by: Andrew Morton
    Signed-off-by: Greg Kroah-Hartman
    ---
    Documentation/DocBook/uio-howto.tmpl | 2 +-
    1 files changed, 1 insertions(+), 1 deletions(-)

    diff --git a/Documentation/DocBook/uio-howto.tmpl b/Documentation/DocBook/uio-howto.tmpl
    index d799a26..df87d1b 100644
    --- a/Documentation/DocBook/uio-howto.tmpl
    +++ b/Documentation/DocBook/uio-howto.tmpl
    @@ -75,7 +75,7 @@ GPL version 2.



    -
    +
    About this document


    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  12. [PATCH 55/79] pnp: add acpi:* modalias entries

    From: Kay Sievers

    Along with the non-modalias conformant "pnp:*" aliases, we add "acpi:*"
    entries to PNP drivers, to allow module autoloading by ACPI PNP device
    entries, which export proper modalias information, without any specific
    userspace modprobe mangling.

    Cc: Adam Belay
    Cc: Thomas Renninger
    Signed-off-by: Kay Sievers
    Signed-off-by: Greg Kroah-Hartman
    ---
    scripts/mod/file2alias.c | 24 ++++++++++++++++--------
    1 files changed, 16 insertions(+), 8 deletions(-)

    diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c
    index 37d5c36..1fcaf32 100644
    --- a/scripts/mod/file2alias.c
    +++ b/scripts/mod/file2alias.c
    @@ -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"))
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  13. [PATCH 79/79] arm: bus_id -> dev_name() and dev_set_name() conversions

    From: Kay Sievers

    Signed-off-by: Kay Sievers
    Signed-off-by: Greg Kroah-Hartman
    ---
    arch/arm/common/locomo.c | 2 +-
    arch/arm/common/sa1111.c | 7 +++----
    arch/arm/common/scoop.c | 2 +-
    arch/arm/kernel/ecard.c | 2 +-
    arch/arm/mach-integrator/impd1.c | 4 +---
    arch/arm/mach-integrator/lm.c | 6 ++++--
    arch/arm/plat-omap/mailbox.c | 2 +-
    drivers/net/arm/at91_ether.c | 2 +-
    drivers/net/arm/ep93xx_eth.c | 2 +-
    drivers/net/arm/etherh.c | 6 +++---
    10 files changed, 17 insertions(+), 18 deletions(-)

    diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
    index d973c98..c3c3a33 100644
    --- a/arch/arm/common/locomo.c
    +++ b/arch/arm/common/locomo.c
    @@ -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;
    diff --git a/arch/arm/common/sa1111.c b/arch/arm/common/sa1111.c
    index 2048ae0..c8e8f0e 100644
    --- a/arch/arm/common/sa1111.c
    +++ b/arch/arm/common/sa1111.c
    @@ -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;
    }
    diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c
    index bc299b0..ae39553 100644
    --- a/arch/arm/common/scoop.c
    +++ b/arch/arm/common/scoop.c
    @@ -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;
    diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
    index 2de425f..f5cfdab 100644
    --- a/arch/arm/kernel/ecard.c
    +++ b/arch/arm/kernel/ecard.c
    @@ -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; \
    diff --git a/arch/arm/mach-integrator/impd1.c b/arch/arm/mach-integrator/impd1.c
    index 619d05e..5a1588c 100644
    --- a/arch/arm/mach-integrator/impd1.c
    +++ b/arch/arm/mach-integrator/impd1.c
    @@ -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;
    diff --git a/arch/arm/mach-integrator/lm.c b/arch/arm/mach-integrator/lm.c
    index 622cdc4..f939c50 100644
    --- a/arch/arm/mach-integrator/lm.c
    +++ b/arch/arm/mach-integrator/lm.c
    @@ -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) {
    diff --git a/arch/arm/plat-omap/mailbox.c b/arch/arm/plat-omap/mailbox.c
    index 848fdca..ff1413e 100644
    --- a/arch/arm/plat-omap/mailbox.c
    +++ b/arch/arm/plat-omap/mailbox.c
    @@ -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, BUS_ID_SIZE);
    + dev_set_name(&mbox->dev, "%s", mbox->name);
    dev_set_drvdata(&mbox->dev, mbox);

    ret = device_register(&mbox->dev);
    diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c
    index 1e39e78..71f7cec 100644
    --- a/drivers/net/arm/at91_ether.c
    +++ b/drivers/net/arm/at91_ether.c
    @@ -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 = {
    diff --git a/drivers/net/arm/ep93xx_eth.c b/drivers/net/arm/ep93xx_eth.c
    index ecd8fc6..7a14980 100644
    --- a/drivers/net/arm/ep93xx_eth.c
    +++ b/drivers/net/arm/ep93xx_eth.c
    @@ -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;
    diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
    index e9d15ec..5c5f1e4 100644
    --- a/drivers/net/arm/etherh.c
    +++ b/drivers/net/arm/etherh.c
    @@ -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));
    }

    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  14. [PATCH 78/79] sparc64: fix up bus_id changes in sparc core code

    This converts all instances of bus_id in the sparc core kernel to use
    either dev_set_name(), or dev_name() depending on the need.

    This is done in anticipation of removing the bus_id field from struct
    driver.

    Cc: Kay Sievers
    Acked-by: David S. Miller
    Signed-off-by: Greg Kroah-Hartman
    ---
    arch/sparc64/kernel/ebus.c | 4 ++--
    arch/sparc64/kernel/of_device.c | 4 ++--
    arch/sparc64/kernel/pci.c | 2 +-
    arch/sparc64/kernel/vio.c | 16 +++++++---------
    drivers/sbus/sbus.c | 6 +++---
    5 files changed, 15 insertions(+), 17 deletions(-)

    diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c
    index c49d038..4d58d7c 100644
    --- a/arch/sparc64/kernel/ebus.c
    +++ b/arch/sparc64/kernel/ebus.c
    @@ -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)
    diff --git a/arch/sparc64/kernel/of_device.c b/arch/sparc64/kernel/of_device.c
    index d569f60..4fd48ab 100644
    --- a/arch/sparc64/kernel/of_device.c
    +++ b/arch/sparc64/kernel/of_device.c
    @@ -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",
    diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c
    index d00a365..5509619 100644
    --- a/arch/sparc64/kernel/pci.c
    +++ b/arch/sparc64/kernel/pci.c
    @@ -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)
    diff --git a/arch/sparc64/kernel/vio.c b/arch/sparc64/kernel/vio.c
    index ecbb8b6..a490077 100644
    --- a/arch/sparc64/kernel/vio.c
    +++ b/arch/sparc64/kernel/vio.c
    @@ -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);
    }
    diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c
    index c37d7c2..73a86d0 100644
    --- a/drivers/sbus/sbus.c
    +++ b/drivers/sbus/sbus.c
    @@ -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) {
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  15. [PATCH 62/79] sysdev: fix debugging statements in registration code.

    From: Ben Dooks

    The systdev_class_register() and sysdev_register() functions have
    pr_debug() statements which are enabled when the user selects the
    driver core debug. Both of these routines do not produce the
    correct output, as they make assumptions about data which has not
    been initialised.

    In sysdev_class_register() the code uses the kobject_name(&cls->kset.kobj)
    at the start of the function, but this is not setup until later in the
    same call. Change this to use cls->name which is passed in from the caller.

    The sysdev_register() function tries to get the name of the sysdev by
    kobject_name(&sysdev->kobj), but that isn't setup until later in the same
    function so change this message to use the name of the sysdev's class and
    add another message once the name is initialised.

    Signed-off-by: Ben Dooks
    Signed-off-by: Greg Kroah-Hartman
    ---
    drivers/base/sys.c | 11 ++++++++---
    1 files changed, 8 insertions(+), 3 deletions(-)

    diff --git a/drivers/base/sys.c b/drivers/base/sys.c
    index 358bb0b..50690d9 100644
    --- a/drivers/base/sys.c
    +++ b/drivers/base/sys.c
    @@ -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;
    }
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  16. [PATCH 59/79] UIO: minor style and comment fixes

    From: Uwe Kleine-König

    Signed-off-by: Uwe Kleine-König
    Signed-off-by: Hans J. Koch
    ---
    include/linux/uio_driver.h | 6 +++---
    1 files changed, 3 insertions(+), 3 deletions(-)

    diff --git a/include/linux/uio_driver.h b/include/linux/uio_driver.h
    index cf65e96..cdf338d 100644
    --- a/include/linux/uio_driver.h
    +++ b/include/linux/uio_driver.h
    @@ -36,7 +36,7 @@ struct uio_mem {
    struct uio_map *map;
    };

    -#define MAX_UIO_MAPS 5
    +#define MAX_UIO_MAPS 5

    struct uio_device;

    @@ -82,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
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  17. [PATCH 73/79] sysdev: Add utility functions for simple int/ulong variable sysdev attributes

    From: Andi Kleen

    This adds a new sysdev_ext_attribute that stores a pointer to the variable
    it manages and some utility functions/macro to easily use them.

    Previously all users wrote custom macros to generate show/store
    functions for each variable, with this it is possible to avoid
    that in many cases.

    Signed-off-by: Andi Kleen
    Signed-off-by: Greg Kroah-Hartman
    ---
    drivers/base/sys.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
    include/linux/sysdev.h | 34 +++++++++++++++++++++++++++++++++
    2 files changed, 83 insertions(+), 0 deletions(-)

    diff --git a/drivers/base/sys.c b/drivers/base/sys.c
    index dc7dace..40fc14f 100644
    --- a/drivers/base/sys.c
    +++ b/drivers/base/sys.c
    @@ -479,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);
    +
    diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
    index 8dcf316..f395bb3 100644
    --- a/include/linux/sysdev.h
    +++ b/include/linux/sysdev.h
    @@ -119,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_ */
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  18. [PATCH 58/79] UIO: add generic UIO platform driver

    From: Uwe Kleine-König

    This patch adds a generic UIO platform driver. It eliminates the need for a
    dedicated kernel module for simple platform devices. Users only need to
    implement their irq handler in platform code and fill a struct uio_info
    there. This helps avoiding code duplication as UIO platform drivers often
    share a lot of common code.

    Signed-off-by: Uwe Kleine-König
    Signed-off-by: Hans J. Koch
    Signed-off-by: Greg Kroah-Hartman
    ---
    drivers/uio/Kconfig | 7 +++
    drivers/uio/Makefile | 1 +
    drivers/uio/uio_pdrv.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++
    3 files changed, 126 insertions(+), 0 deletions(-)
    create mode 100644 drivers/uio/uio_pdrv.c

    diff --git a/drivers/uio/Kconfig b/drivers/uio/Kconfig
    index 78e139c..2e9079d 100644
    --- a/drivers/uio/Kconfig
    +++ b/drivers/uio/Kconfig
    @@ -26,6 +26,13 @@ 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"
    default n
    diff --git a/drivers/uio/Makefile b/drivers/uio/Makefile
    index 18c4566..e00ce0d 100644
    --- a/drivers/uio/Makefile
    +++ b/drivers/uio/Makefile
    @@ -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
    diff --git a/drivers/uio/uio_pdrv.c b/drivers/uio/uio_pdrv.c
    new file mode 100644
    index 0000000..5d0d2e8
    --- /dev/null
    +++ b/drivers/uio/uio_pdrv.c
    @@ -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
    +#include
    +#include
    +
    +#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);
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  19. [PATCH 72/79] sysdev: Pass the attribute to the low level sysdev show/store function

    From: Andi Kleen

    This allow to dynamically generate attributes and share show/store
    functions between attributes. Right now most attributes are generated
    by special macros and lots of duplicated code. With the attribute
    passed it's instead possible to attach some data to the attribute
    and then use that in shared low level functions to do different things.

    I need this for the dynamically generated bank attributes in the x86
    machine check code, but it'll allow some further cleanups.

    I converted all users in tree to the new show/store prototype. It's a single
    huge patch to avoid unbisectable sections.

    Runtime tested: x86-32, x86-64
    Compiled only: ia64, powerpc
    Not compile tested/only grep converted: sh, arm, avr32

    Signed-off-by: Andi Kleen
    Signed-off-by: Greg Kroah-Hartman
    ---
    arch/arm/kernel/time.c | 4 ++-
    arch/avr32/kernel/cpu.c | 38 ++++++++++++++++--------
    arch/ia64/kernel/err_inject.c | 22 +++++++++----
    arch/powerpc/kernel/sysfs.c | 15 +++++++--
    arch/powerpc/platforms/cell/cbe_thermal.c | 45 +++++++++++++++++++---------
    arch/powerpc/platforms/cell/spu_base.c | 3 +-
    arch/s390/kernel/smp.c | 36 +++++++++++++++--------
    arch/s390/kernel/time.c | 35 +++++++++++++++-------
    arch/sh/drivers/dma/dma-sysfs.c | 15 +++++++--
    arch/sparc64/kernel/sysfs.c | 16 +++++++---
    arch/x86/kernel/cpu/mcheck/mce_64.c | 14 ++++++--
    arch/x86/kernel/cpu/mcheck/therm_throt.c | 1 +
    arch/x86/kernel/microcode.c | 10 ++++--
    drivers/base/cpu.c | 10 ++++--
    drivers/base/memory.c | 12 +++++--
    drivers/base/node.c | 15 ++++++---
    drivers/base/sys.c | 4 +-
    drivers/base/topology.c | 17 ++++++++---
    drivers/cpuidle/sysfs.c | 10 ++++--
    drivers/xen/balloon.c | 1 +
    include/linux/sysdev.h | 5 ++-
    kernel/rtmutex-tester.c | 7 ++--
    kernel/sched.c | 8 ++++-
    kernel/time/clocksource.c | 8 ++++-
    24 files changed, 239 insertions(+), 112 deletions(-)

    diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
    index cc5145b..368d171 100644
    --- a/arch/arm/kernel/time.c
    +++ b/arch/arm/kernel/time.c
    @@ -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, " ");

    diff --git a/arch/avr32/kernel/cpu.c b/arch/avr32/kernel/cpu.c
    index b8409ca..e84faff 100644
    --- a/arch/avr32/kernel/cpu.c
    +++ b/arch/avr32/kernel/cpu.c
    @@ -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;
    diff --git a/arch/ia64/kernel/err_inject.c b/arch/ia64/kernel/err_inject.c
    index b642648..c539c68 100644
    --- a/arch/ia64/kernel/err_inject.c
    +++ b/arch/ia64/kernel/err_inject.c
    @@ -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;
    diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
    index c8127f8..aba0ba9 100644
    --- a/arch/powerpc/kernel/sysfs.c
    +++ b/arch/powerpc/kernel/sysfs.c
    @@ -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; \
    diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c
    index 4852bf3..4d4c8c1 100644
    --- a/arch/powerpc/platforms/cell/cbe_thermal.c
    +++ b/arch/powerpc/platforms/cell/cbe_thermal.c
    @@ -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);
    }
    diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
    index 78f905b..a5bdb89 100644
    --- a/arch/powerpc/platforms/cell/spu_base.c
    +++ b/arch/powerpc/platforms/cell/spu_base.c
    @@ -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);

    diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
    index b678103..b795b3e 100644
    --- a/arch/s390/kernel/smp.c
    +++ b/arch/s390/kernel/smp.c
    @@ -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;
    diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
    index f2cede3..ab70d9b 100644
    --- a/arch/s390/kernel/time.c
    +++ b/arch/s390/kernel/time.c
    @@ -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);

    diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
    index 51b57c0..347ee11 100644
    --- a/arch/sh/drivers/dma/dma-sysfs.c
    +++ b/arch/sh/drivers/dma/dma-sysfs.c
    @@ -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); \
    diff --git a/arch/sparc64/kernel/sysfs.c b/arch/sparc64/kernel/sysfs.c
    index e885034..84e5ce1 100644
    --- a/arch/sparc64/kernel/sysfs.c
    +++ b/arch/sparc64/kernel/sysfs.c
    @@ -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); \
    diff --git a/arch/x86/kernel/cpu/mcheck/mce_64.c b/arch/x86/kernel/cpu/mcheck/mce_64.c
    index c4a7ec3..e6a4d5f 100644
    --- a/arch/x86/kernel/cpu/mcheck/mce_64.c
    +++ b/arch/x86/kernel/cpu/mcheck/mce_64.c
    @@ -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;
    diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c
    index 1f4cc48..d5ae224 100644
    --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c
    +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c
    @@ -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; \
    diff --git a/arch/x86/kernel/microcode.c b/arch/x86/kernel/microcode.c
    index 56b9331..fc47906 100644
    --- a/arch/x86/kernel/microcode.c
    +++ b/arch/x86/kernel/microcode.c
    @@ -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;

    diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
    index e38dfed..20537d5 100644
    --- a/drivers/base/cpu.c
    +++ b/drivers/base/cpu.c
    @@ -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

    -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;
    diff --git a/drivers/base/memory.c b/drivers/base/memory.c
    index 937e825..4d4e0e7 100644
    --- a/drivers/base/memory.c
    +++ b/drivers/base/memory.c
    @@ -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);
    diff --git a/drivers/base/node.c b/drivers/base/node.c
    index 0f867a0..5116b78 100644
    --- a/drivers/base/node.c
    +++ b/drivers/base/node.c
    @@ -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;
    diff --git a/drivers/base/sys.c b/drivers/base/sys.c
    index 50690d9..dc7dace 100644
    --- a/drivers/base/sys.c
    +++ b/drivers/base/sys.c
    @@ -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;
    }

    diff --git a/drivers/base/topology.c b/drivers/base/topology.c
    index 3f6d9b0..199cd97 100644
    --- a/drivers/base/topology.c
    +++ b/drivers/base/topology.c
    @@ -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); \
    diff --git a/drivers/cpuidle/sysfs.c b/drivers/cpuidle/sysfs.c
    index e949618..31a0e0b 100644
    --- a/drivers/cpuidle/sysfs.c
    +++ b/drivers/cpuidle/sysfs.c
    @@ -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];
    diff --git a/drivers/xen/balloon.c b/drivers/xen/balloon.c
    index 591bc29..d4427cb 100644
    --- a/drivers/xen/balloon.c
    +++ b/drivers/xen/balloon.c
    @@ -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)
    {
    diff --git a/include/linux/sysdev.h b/include/linux/sysdev.h
    index f2767bc..8dcf316 100644
    --- a/include/linux/sysdev.h
    +++ b/include/linux/sysdev.h
    @@ -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);
    };


    diff --git a/kernel/rtmutex-tester.c b/kernel/rtmutex-tester.c
    index 092e4c6..a56f629 100644
    --- a/kernel/rtmutex-tester.c
    +++ b/kernel/rtmutex-tester.c
    @@ -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;
    diff --git a/kernel/sched.c b/kernel/sched.c
    index 99e6d85..b1104ea 100644
    --- a/kernel/sched.c
    +++ b/kernel/sched.c
    @@ -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);
    diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c
    index dadde53..b1c2da8 100644
    --- a/kernel/time/clocksource.c
    +++ b/kernel/time/clocksource.c
    @@ -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;
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

  20. [PATCH 67/79] HOWTO: change email addresses of James in HOWTO

    From: Tsugikazu Shibata

    Signed-off-by: Tsugikazu Shibata
    Signed-off-by: Greg Kroah-Hartman
    ---
    Documentation/HOWTO | 2 +-
    1 files changed, 1 insertions(+), 1 deletions(-)

    diff --git a/Documentation/HOWTO b/Documentation/HOWTO
    index 619e8ca..c2371c5 100644
    --- a/Documentation/HOWTO
    +++ b/Documentation/HOWTO
    @@ -358,7 +358,7 @@ Here is a list of some of the different kernel trees available:
    - pcmcia, Dominik Brodowski
    git.kernel.org:/pub/scm/linux/kernel/git/brodo/pcmcia-2.6.git

    - - SCSI, James Bottomley
    + - SCSI, James Bottomley
    git.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6.git

    - x86, Ingo Molnar
    --
    1.5.6.3

    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

+ Reply to Thread
Page 3 of 4 FirstFirst 1 2 3 4 LastLast