27 Jul, 2011

1 commit

  • This allows us to move duplicated code in
    (atomic_inc_not_zero() for now) to

    Signed-off-by: Arun Sharma
    Reviewed-by: Eric Dumazet
    Cc: Ingo Molnar
    Cc: David Miller
    Cc: Eric Dumazet
    Acked-by: Mike Frysinger
    Signed-off-by: Andrew Morton
    Signed-off-by: Linus Torvalds

    Arun Sharma
     

12 Dec, 2010

1 commit

  • Amend .open handler accordingly and remove the .llseek handler.
    .llseek = NULL means no_llseek (return error) since commit 776c163b1b93.

    The only client that uses this interface is nosy-dump in linux/tools/firewire
    and it knows not to seek in this char dev.

    Signed-off-by: Stefan Richter

    Stefan Richter
     

15 Oct, 2010

1 commit

  • All file_operations should get a .llseek operation so we can make
    nonseekable_open the default for future file operations without a
    .llseek pointer.

    The three cases that we can automatically detect are no_llseek, seq_lseek
    and default_llseek. For cases where we can we can automatically prove that
    the file offset is always ignored, we use noop_llseek, which maintains
    the current behavior of not returning an error from a seek.

    New drivers should normally not use noop_llseek but instead use no_llseek
    and call nonseekable_open at open time. Existing drivers can be converted
    to do the same when the maintainer knows for certain that no user code
    relies on calling seek on the device file.

    The generated code is often incorrectly indented and right now contains
    comments that clarify for each added line why a specific variant was
    chosen. In the version that gets submitted upstream, the comments will
    be gone and I will manually fix the indentation, because there does not
    seem to be a way to do that using coccinelle.

    Some amount of new code is currently sitting in linux-next that should get
    the same modifications, which I will do at the end of the merge window.

    Many thanks to Julia Lawall for helping me learn to write a semantic
    patch that does all this.

    ===== begin semantic patch =====
    // This adds an llseek= method to all file operations,
    // as a preparation for making no_llseek the default.
    //
    // The rules are
    // - use no_llseek explicitly if we do nonseekable_open
    // - use seq_lseek for sequential files
    // - use default_llseek if we know we access f_pos
    // - use noop_llseek if we know we don't access f_pos,
    // but we still want to allow users to call lseek
    //
    @ open1 exists @
    identifier nested_open;
    @@
    nested_open(...)
    {

    }

    @ open exists@
    identifier open_f;
    identifier i, f;
    identifier open1.nested_open;
    @@
    int open_f(struct inode *i, struct file *f)
    {

    }

    @ read disable optional_qualifier exists @
    identifier read_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    expression E;
    identifier func;
    @@
    ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
    {

    }

    @ read_no_fpos disable optional_qualifier exists @
    identifier read_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    @@
    ssize_t read_f(struct file *f, char *p, size_t s, loff_t *off)
    {
    ... when != off
    }

    @ write @
    identifier write_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    expression E;
    identifier func;
    @@
    ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
    {

    }

    @ write_no_fpos @
    identifier write_f;
    identifier f, p, s, off;
    type ssize_t, size_t, loff_t;
    @@
    ssize_t write_f(struct file *f, const char *p, size_t s, loff_t *off)
    {
    ... when != off
    }

    @ fops0 @
    identifier fops;
    @@
    struct file_operations fops = {
    ...
    };

    @ has_llseek depends on fops0 @
    identifier fops0.fops;
    identifier llseek_f;
    @@
    struct file_operations fops = {
    ...
    .llseek = llseek_f,
    ...
    };

    @ has_read depends on fops0 @
    identifier fops0.fops;
    identifier read_f;
    @@
    struct file_operations fops = {
    ...
    .read = read_f,
    ...
    };

    @ has_write depends on fops0 @
    identifier fops0.fops;
    identifier write_f;
    @@
    struct file_operations fops = {
    ...
    .write = write_f,
    ...
    };

    @ has_open depends on fops0 @
    identifier fops0.fops;
    identifier open_f;
    @@
    struct file_operations fops = {
    ...
    .open = open_f,
    ...
    };

    // use no_llseek if we call nonseekable_open
    ////////////////////////////////////////////
    @ nonseekable1 depends on !has_llseek && has_open @
    identifier fops0.fops;
    identifier nso ~= "nonseekable_open";
    @@
    struct file_operations fops = {
    ... .open = nso, ...
    +.llseek = no_llseek, /* nonseekable */
    };

    @ nonseekable2 depends on !has_llseek @
    identifier fops0.fops;
    identifier open.open_f;
    @@
    struct file_operations fops = {
    ... .open = open_f, ...
    +.llseek = no_llseek, /* open uses nonseekable */
    };

    // use seq_lseek for sequential files
    /////////////////////////////////////
    @ seq depends on !has_llseek @
    identifier fops0.fops;
    identifier sr ~= "seq_read";
    @@
    struct file_operations fops = {
    ... .read = sr, ...
    +.llseek = seq_lseek, /* we have seq_read */
    };

    // use default_llseek if there is a readdir
    ///////////////////////////////////////////
    @ fops1 depends on !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier readdir_e;
    @@
    // any other fop is used that changes pos
    struct file_operations fops = {
    ... .readdir = readdir_e, ...
    +.llseek = default_llseek, /* readdir is present */
    };

    // use default_llseek if at least one of read/write touches f_pos
    /////////////////////////////////////////////////////////////////
    @ fops2 depends on !fops1 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read.read_f;
    @@
    // read fops use offset
    struct file_operations fops = {
    ... .read = read_f, ...
    +.llseek = default_llseek, /* read accesses f_pos */
    };

    @ fops3 depends on !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier write.write_f;
    @@
    // write fops use offset
    struct file_operations fops = {
    ... .write = write_f, ...
    + .llseek = default_llseek, /* write accesses f_pos */
    };

    // Use noop_llseek if neither read nor write accesses f_pos
    ///////////////////////////////////////////////////////////

    @ fops4 depends on !fops1 && !fops2 && !fops3 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read_no_fpos.read_f;
    identifier write_no_fpos.write_f;
    @@
    // write fops use offset
    struct file_operations fops = {
    ...
    .write = write_f,
    .read = read_f,
    ...
    +.llseek = noop_llseek, /* read and write both use no f_pos */
    };

    @ depends on has_write && !has_read && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier write_no_fpos.write_f;
    @@
    struct file_operations fops = {
    ... .write = write_f, ...
    +.llseek = noop_llseek, /* write uses no f_pos */
    };

    @ depends on has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    identifier read_no_fpos.read_f;
    @@
    struct file_operations fops = {
    ... .read = read_f, ...
    +.llseek = noop_llseek, /* read uses no f_pos */
    };

    @ depends on !has_read && !has_write && !fops1 && !fops2 && !has_llseek && !nonseekable1 && !nonseekable2 && !seq @
    identifier fops0.fops;
    @@
    struct file_operations fops = {
    ...
    +.llseek = noop_llseek, /* no read or write fn */
    };
    ===== End semantic patch =====

    Signed-off-by: Arnd Bergmann
    Cc: Julia Lawall
    Cc: Christoph Hellwig

    Arnd Bergmann
     

27 Jul, 2010

12 commits

  • Replace home-grown printk wrapper macros by ones from kernel.h and
    device.h.

    Also raise the log level in set_phy_reg() from debug to error because
    these are really error conditions. Could even be WARN_ON. Lower the
    log level in the device probe and driver shutdown from notice to info.

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • 1.) The DMA programs (struct pcl) are PCI-endian = little endian data
    (except for the 3rd quadlet in a PCL which the controller does not
    touch). Annotate them as such.

    Fix all accesses of the PCL to work with big endian CPUs also. Not
    actually tested, I only have a little endian PC to test with. This
    includes replacement of a bitfield struct pcl_status by open-coded
    shift and mask operations.

    2.) The two __attribute__ ((packed)) at struct pcl are not really
    required since it consists of u32/__le32 only, i.e. there will be no
    padding with or without the attribute.

    3.) The received IEEE 1394 data are byteswapped by the controller from
    IEEE 1394 endian = big endian to PCI endian = little endian because the
    PCL_BIGENDIAN control bit is set. Therefore annotate the DMA buffer as
    a __le32 array.

    Fix the one access of the DMA buffer (the check of the transaction code
    of link packets) to work with big endian CPUs. Also fix the two
    accesses of the client bounce buffer (the reading of packet length).

    4.) Add a comment to the userspace ABI header that all of the data gets
    out as little endian data, except for the timestamp which is CPU endian.
    (We could make it little endian too, but why? Vice versa, an ioctl
    could be added to dump packet data in big endian byte order...)

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • Signed-off-by: Stefan Richter

    Stefan Richter
     
  • Fix race between nosy_open() and remove_card() by replacing the
    unprotected array of card pointers by a mutex-protected list of cards.

    Make card instances reference-counted and let each client hold a
    reference.

    Notify clients about card removal via POLLHUP in poll()'s events
    bitmap; also let read() fail with errno=ENODEV if the card was removed
    and everything in the buffer was read.

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • and add a missing pci_disable_device() to device shutdown.

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • Untested, I don't have a PCILynx CardBus card.

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • nosy_start/stop_snoop() and nosy_add/remove_client() are simple enough
    to be inlined into their callers.

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • nosy_start/stop_snoop() are always only called by the ioctl method, i.e.
    with IRQs enabled. packet_handler() and bus_reset_handler() are always
    only called by the IRQ handler. Hence neither one needs to track IRQ
    flags.

    To underline the call context of packet_handler() and
    bus_reset_handler(), rename these functions to *_irq_handler().

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • nosy_stop_snoop() would blow up the second time it was called without
    nosy_start_snoop() in between.

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • The required serialization of NOSY_IOC_START and NOSY_IOC_STOP is
    already provided by the client_list_lock.

    NOSY_IOC_FILTER does not really require serialization since accesses
    to tcode_mask are atomic on any sane CPU architecture. Nevertheless,
    make it explicit that we want this to be atomic by means of
    client_list_lock (which also surrounds the other tcode_mask access in
    the IRQ handler). While we are at it, change the type of tcode_mask to
    u32 for consistency with the user API.

    NOSY_IOC_GET_STATS does not require serialization against itself. But
    there is a bug here regarding concurrent updates of the two counters
    by the IRQ handler. Fix it by taking the client_list_lock in this ioctl
    too.

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • Extend copyright note to 2007, c.f. Kristian's git log.

    Includes:
    - replace some by
    - add required indirectly included
    - order alphabetically

    Coding style related changes:
    - change to utf8
    - normalize whitespace
    - normalize comment style
    - remove usages of __FUNCTION__
    - remove an unnecessary cast from void *

    Const and static declarations:
    - driver_name is not const in pci_driver.name, drop const qualifier
    - driver_name can be taken from KBUILD_MODNAME
    - the global variable minors[] can and should be static
    - constify struct file_operations instance

    Data types:
    - Remove unused struct member struct packet.code. struct packet is
    only used for driver-internal bookkeeping; it does not appear on the
    wire or in DMA programs or the userspace ABI. Hence the unused
    member .code can be removed without worries.

    Preprocessor macros:
    - unroll a preprocessor macro that containd a return
    - use list_for_each_entry

    Printk:
    - add missing terminating \n in some format strings

    Signed-off-by: Stefan Richter

    Stefan Richter
     
  • This adds the traffic sniffer driver for Texas Instruments PCILynx/
    PCILynx2 based cards. The use cases for nosy are analysis of
    nonstandard protocols and as an aid in development of drivers,
    applications, or firmwares.

    Author of the driver is Kristian Høgsberg. Known contributers are
    Jody McIntyre and Jonathan Woithe.

    Nosy programs PCILynx chips to operate in promiscuous mode, which is a
    feature that is not found in OHCI-1394 controllers. Hence, only special
    hardware as mentioned in the Kconfig help text is suitable for nosy.

    This is only the kernelspace part of nosy. There is a userspace
    interface to it, called nosy-dump, proposed to be added into the tools/
    subdirectory of the kernel sources in a subsequent change. Kernelspace
    and userspave component of nosy communicate via a 'misc' character
    device file called /dev/nosy with a simple ioctl() and read() based
    protocol, as described by nosy-user.h.

    The files added here are taken from
    git://anongit.freedesktop.org/~krh/nosy commit ee29be97 (2009-11-10)
    with the following changes by Stefan Richter:
    - Kconfig and Makefile hunks are written from scratch.
    - Commented out version printk in nosy.c.
    - Included missing , reported by Stephen Rothwell.

    "git shortlog nosy{-user.h,.c,.h}" from nosy's git repository:

    Jonathan Woithe (2):
    Nosy updates for recent kernels
    Fix uninitialised memory (needed for 2.6.31 kernel)

    Kristian Høgsberg (5):
    Pull over nosy from mercurial repo.
    Use a misc device instead.
    Add simple AV/C decoder.
    Don't break down on big payloads.
    Set parent device for misc device.

    As a low-level IEEE 1394 driver, its files are placed into
    drivers/firewire/ although nosy is not part of the firewire driver
    stack.

    I am aware of the following literature from Texas Instruments about
    PCILynx programming:
    SCPA020A - PCILynx 1394 to PCI Bus Interface TSB12LV21BPGF
    Functional Specification
    SLLA023 - Initialization and Asynchronous Programming of the
    TSB12LV21A 1394 Device

    Signed-off-by: Stefan Richter
    Acked-by: Kristian Høgsberg

    Stefan Richter