Merge branch 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Apr 2008 18:25:37 +0000 (11:25 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 1 Apr 2008 18:25:37 +0000 (11:25 -0700)
* 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6:
  hwmon: (w83781d) Fix I/O resource conflict with PNP

263 files changed:
Documentation/i386/IO-APIC.txt
Documentation/kernel-parameters.txt
Documentation/lguest/lguest.c
Documentation/lguest/lguest.txt
Documentation/nmi_watchdog.txt
MAINTAINERS
arch/avr32/kernel/setup.c
arch/avr32/kernel/traps.c
arch/powerpc/configs/pasemi_defconfig
arch/powerpc/kernel/process.c
arch/powerpc/oprofile/cell/vma_map.c
arch/powerpc/platforms/pseries/xics.c
arch/sparc64/defconfig
arch/sparc64/kernel/cpu.c
arch/sparc64/kernel/entry.S
arch/sparc64/kernel/entry.h [new file with mode: 0644]
arch/sparc64/kernel/iommu.c
arch/sparc64/kernel/irq.c
arch/sparc64/kernel/ptrace.c
arch/sparc64/kernel/setup.c
arch/sparc64/kernel/signal.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/stacktrace.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/kernel/systbls.h [new file with mode: 0644]
arch/sparc64/kernel/time.c
arch/sparc64/kernel/traps.c
arch/sparc64/mm/init.c
arch/sparc64/mm/tlb.c
arch/um/drivers/net_kern.c
arch/x86/kernel/cpu/cpufreq/speedstep-smi.c
arch/x86/kernel/cpu/mtrr/generic.c
arch/x86/kernel/io_delay.c
arch/x86/kernel/mfgpt_32.c
arch/x86/kernel/ptrace.c
arch/x86/kernel/setup_32.c
arch/x86/kernel/setup_64.c
arch/x86/lguest/boot.c
arch/x86/lguest/i386_head.S
arch/x86/mach-rdc321x/gpio.c
arch/x86/mach-rdc321x/platform.c
arch/x86/mm/discontig_32.c
arch/x86/mm/fault.c
arch/x86/mm/highmem_32.c
arch/x86/mm/hugetlbpage.c
arch/x86/mm/ioremap.c
arch/x86/mm/pageattr.c
arch/x86/xen/enlighten.c
arch/x86/xen/xen-asm.S
drivers/acpi/processor_idle.c
drivers/acpi/sbshc.c
drivers/acpi/scan.c
drivers/acpi/sleep/main.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/pata_sil680.c
drivers/base/driver.c
drivers/char/drm/ati_pcigart.c
drivers/char/drm/drm_scatter.c
drivers/char/drm/drm_vm.c
drivers/char/drm/i915_dma.c
drivers/char/drm/r300_cmdbuf.c
drivers/char/drm/radeon_drm.h
drivers/char/drm/radeon_mem.c
drivers/char/n_tty.c
drivers/char/nozomi.c
drivers/cpuidle/cpuidle.c
drivers/cpuidle/sysfs.c
drivers/crypto/hifn_795x.c
drivers/dma/fsldma.h
drivers/dma/ioat_dca.c
drivers/ide/ide-iops.c
drivers/ide/ide-probe.c
drivers/infiniband/core/addr.c
drivers/infiniband/core/cm.c
drivers/infiniband/core/cma.c
drivers/infiniband/hw/cxgb3/iwch_cm.c
drivers/input/apm-power.c
drivers/input/evdev.c
drivers/input/joydev.c
drivers/input/keyboard/pxa27x_keypad.c
drivers/input/misc/ixp4xx-beeper.c
drivers/input/mousedev.c
drivers/leds/leds-gpio.c
drivers/lguest/Makefile
drivers/lguest/core.c
drivers/lguest/hypercalls.c
drivers/lguest/interrupts_and_traps.c
drivers/lguest/lguest_device.c
drivers/lguest/lguest_user.c
drivers/lguest/page_tables.c
drivers/lguest/x86/core.c
drivers/lguest/x86/switcher_32.S
drivers/md/dm-crypt.c
drivers/md/dm-io.c
drivers/md/dm-raid1.c
drivers/md/dm-snap.c
drivers/md/kcopyd.c
drivers/md/kcopyd.h
drivers/media/common/saa7146_core.c
drivers/media/common/saa7146_fops.c
drivers/media/dvb/dvb-core/dvb_net.c
drivers/media/video/adv7170.c
drivers/media/video/adv7175.c
drivers/media/video/bt819.c
drivers/media/video/bt856.c
drivers/media/video/dpc7146.c
drivers/media/video/mt20xx.c
drivers/media/video/mxb.c
drivers/media/video/pvrusb2/pvrusb2-ctrl.c
drivers/media/video/pvrusb2/pvrusb2-hdw.c
drivers/media/video/pvrusb2/pvrusb2-io.c
drivers/media/video/pvrusb2/pvrusb2-ioread.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/saa7110.c
drivers/media/video/saa7111.c
drivers/media/video/saa7114.c
drivers/media/video/saa7185.c
drivers/media/video/tda9840.c
drivers/media/video/tea6415c.c
drivers/media/video/tea6420.c
drivers/media/video/tvp5150.c
drivers/media/video/zoran_driver.c
drivers/media/video/zr364xx.c
drivers/memstick/host/tifm_ms.c
drivers/mfd/asic3.c
drivers/misc/fujitsu-laptop.c
drivers/misc/ibmasm/module.c
drivers/misc/lkdtm.c
drivers/mtd/maps/physmap.c
drivers/mtd/nand/rtc_from4.c
drivers/net/b44.c
drivers/net/bonding/bond_3ad.c
drivers/net/bonding/bond_alb.c
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/cxgb3/sge.c
drivers/net/dm9000.c
drivers/net/e100.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_main.c
drivers/net/igb/e1000_82575.h
drivers/net/igb/e1000_hw.h
drivers/net/igb/igb_main.c
drivers/net/ixgb/ixgb_main.c
drivers/net/netxen/netxen_nic.h
drivers/net/netxen/netxen_nic_ethtool.c
drivers/net/netxen/netxen_nic_hdr.h
drivers/net/netxen/netxen_nic_hw.c
drivers/net/netxen/netxen_nic_init.c
drivers/net/netxen/netxen_nic_isr.c
drivers/net/netxen/netxen_nic_main.c
drivers/net/netxen/netxen_nic_phan_reg.h
drivers/net/phy/marvell.c
drivers/net/plip.c
drivers/net/s2io.c
drivers/net/skge.c
drivers/net/smc91x.h
drivers/net/tokenring/smctr.c
drivers/net/usb/dm9601.c
drivers/net/usb/rndis_host.c
drivers/net/wireless/arlan-proc.c
drivers/net/wireless/b43/debugfs.c
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/rt2x00/rt73usb.c
drivers/net/wireless/wavelan_cs.h
drivers/pci/quirks.c
drivers/pci/setup-bus.c
drivers/pnp/pnpacpi/rsparser.c
drivers/serial/8250_pci.c
drivers/video/bf54x-lq043fb.c
drivers/video/bfin-t350mcqb-fb.c
drivers/virtio/virtio_pci.c
fs/afs/cell.c
fs/afs/internal.h
fs/afs/mntpt.c
fs/afs/super.c
fs/buffer.c
fs/cifs/cifs_dfs_ref.c
fs/cifs/cifsacl.c
fs/jbd/journal.c
fs/jbd/revoke.c
fs/jbd2/journal.c
fs/jbd2/revoke.c
fs/namespace.c
fs/nfs/super.c
fs/pnode.c
fs/reiserfs/do_balan.c
fs/reiserfs/fix_node.c
fs/reiserfs/lbalance.c
fs/reiserfs/namei.c
fs/smbfs/smbiod.c
include/asm-avr32/byteorder.h
include/asm-frv/system.h
include/asm-sparc64/cpudata.h
include/asm-sparc64/dcu.h
include/asm-sparc64/irq.h
include/asm-sparc64/pgtable.h
include/asm-sparc64/processor.h
include/asm-sparc64/stacktrace.h [new file with mode: 0644]
include/asm-sparc64/timer.h
include/asm-x86/lguest_hcall.h
include/asm-x86/mach-rdc321x/gpio.h
include/asm-x86/mach-rdc321x/rdc321x_defs.h
include/asm-x86/pgtable.h
include/linux/Kbuild
include/linux/bitops.h
include/linux/compat.h
include/linux/cpuidle.h
include/linux/dmaengine.h
include/linux/hardirq.h
include/linux/ide.h
include/linux/input.h
include/linux/lguest_launcher.h
include/linux/libata.h
include/linux/mount.h
include/linux/sched.h
include/net/neighbour.h
include/net/xfrm.h
kernel/audit.c
kernel/cgroup.c
kernel/fork.c
kernel/futex.c
kernel/futex_compat.c
kernel/relay.c
kernel/sched.c
kernel/time/clocksource.c
kernel/timer.c
lib/kobject_uevent.c
mm/hugetlb.c
mm/slab.c
mm/slub.c
mm/sparse-vmemmap.c
net/8021q/vlan_dev.c
net/9p/trans_fd.c
net/ax25/TODO
net/core/dev.c
net/core/neighbour.c
net/ipv4/icmp.c
net/ipv4/xfrm4_mode_beet.c
net/ipv4/xfrm4_mode_tunnel.c
net/ipv4/xfrm4_output.c
net/ipv4/xfrm4_state.c
net/ipv6/ndisc.c
net/ipv6/xfrm6_mode_beet.c
net/ipv6/xfrm6_mode_tunnel.c
net/ipv6/xfrm6_output.c
net/ipv6/xfrm6_state.c
net/irda/irnet/irnet.h
net/key/af_key.c
net/rxrpc/ar-internal.h
net/rxrpc/rxkad.c
net/sunrpc/xprtrdma/svc_rdma_recvfrom.c
net/xfrm/xfrm_input.c
net/xfrm/xfrm_output.c
net/xfrm/xfrm_state.c
net/xfrm/xfrm_user.c
scripts/checkpatch.pl
sound/oss/ac97_codec.c

index f951666..30b4c71 100644 (file)
@@ -70,7 +70,7 @@ Every PCI card emits a PCI IRQ, which can be INTA, INTB, INTC or INTD:
 
 These INTA-D PCI IRQs are always 'local to the card', their real meaning
 depends on which slot they are in. If you look at the daisy chaining diagram,
-a card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ2 of
+a card in slot4, issuing INTA IRQ, it will end up as a signal on PIRQ4 of
 the PCI chipset. Most cards issue INTA, this creates optimal distribution
 between the PIRQ lines. (distributing IRQ sources properly is not a
 necessity, PCI IRQs can be shared at will, but it's a good for performance
index 508e2a2..4cd1a5d 100644 (file)
@@ -170,11 +170,6 @@ and is between 256 and 4096 characters. It is defined in the file
        acpi_irq_isa=   [HW,ACPI] If irq_balance, mark listed IRQs used by ISA
                        Format: <irq>,<irq>...
 
-       acpi_new_pts_ordering [HW,ACPI]
-                       Enforce the ACPI 2.0 ordering of the _PTS control
-                       method wrt putting devices into low power states
-                       default: pre ACPI 2.0 ordering of _PTS
-
        acpi_no_auto_ssdt       [HW,ACPI] Disable automatic loading of SSDT
 
        acpi_os_name=   [HW,ACPI] Tell ACPI BIOS the name of the OS
index bec5a32..4c1fc65 100644 (file)
@@ -1,7 +1,7 @@
 /*P:100 This is the Launcher code, a simple program which lays out the
- * "physical" memory for the new Guest by mapping the kernel image and the
- * virtual devices, then reads repeatedly from /dev/lguest to run the Guest.
-:*/
+ * "physical" memory for the new Guest by mapping the kernel image and
+ * the virtual devices, then opens /dev/lguest to tell the kernel
+ * about the Guest and control it. :*/
 #define _LARGEFILE64_SOURCE
 #define _GNU_SOURCE
 #include <stdio.h>
@@ -43,7 +43,7 @@
 #include "linux/virtio_console.h"
 #include "linux/virtio_ring.h"
 #include "asm-x86/bootparam.h"
-/*L:110 We can ignore the 38 include files we need for this program, but I do
+/*L:110 We can ignore the 39 include files we need for this program, but I do
  * want to draw attention to the use of kernel-style types.
  *
  * As Linus said, "C is a Spartan language, and so should your naming be."  I
@@ -320,7 +320,7 @@ static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr)
                err(1, "Reading program headers");
 
        /* Try all the headers: there are usually only three.  A read-only one,
-        * a read-write one, and a "note" section which isn't loadable. */
+        * a read-write one, and a "note" section which we don't load. */
        for (i = 0; i < ehdr->e_phnum; i++) {
                /* If this isn't a loadable segment, we ignore it */
                if (phdr[i].p_type != PT_LOAD)
@@ -387,7 +387,7 @@ static unsigned long load_kernel(int fd)
        if (memcmp(hdr.e_ident, ELFMAG, SELFMAG) == 0)
                return map_elf(fd, &hdr);
 
-       /* Otherwise we assume it's a bzImage, and try to unpack it */
+       /* Otherwise we assume it's a bzImage, and try to load it. */
        return load_bzimage(fd);
 }
 
@@ -433,12 +433,12 @@ static unsigned long load_initrd(const char *name, unsigned long mem)
        return len;
 }
 
-/* Once we know how much memory we have, we can construct simple linear page
+/* Once we know how much memory we have we can construct simple linear page
  * tables which set virtual == physical which will get the Guest far enough
  * into the boot to create its own.
  *
  * We lay them out of the way, just below the initrd (which is why we need to
- * know its size). */
+ * know its size here). */
 static unsigned long setup_pagetables(unsigned long mem,
                                      unsigned long initrd_size)
 {
@@ -850,7 +850,8 @@ static void handle_console_output(int fd, struct virtqueue *vq)
  *
  * Handling output for network is also simple: we get all the output buffers
  * and write them (ignoring the first element) to this device's file descriptor
- * (stdout). */
+ * (/dev/net/tun).
+ */
 static void handle_net_output(int fd, struct virtqueue *vq)
 {
        unsigned int head, out, in;
@@ -924,7 +925,7 @@ static void enable_fd(int fd, struct virtqueue *vq)
        write(waker_fd, &vq->dev->fd, sizeof(vq->dev->fd));
 }
 
-/* Resetting a device is fairly easy. */
+/* When the Guest asks us to reset a device, it's is fairly easy. */
 static void reset_device(struct device *dev)
 {
        struct virtqueue *vq;
@@ -1003,8 +1004,8 @@ static void handle_input(int fd)
                if (select(devices.max_infd+1, &fds, NULL, NULL, &poll) == 0)
                        break;
 
-               /* Otherwise, call the device(s) which have readable
-                * file descriptors and a method of handling them.  */
+               /* Otherwise, call the device(s) which have readable file
+                * descriptors and a method of handling them.  */
                for (i = devices.dev; i; i = i->next) {
                        if (i->handle_input && FD_ISSET(i->fd, &fds)) {
                                int dev_fd;
@@ -1015,8 +1016,7 @@ static void handle_input(int fd)
                                 * should no longer service it.  Networking and
                                 * console do this when there's no input
                                 * buffers to deliver into.  Console also uses
-                                * it when it discovers that stdin is
-                                * closed. */
+                                * it when it discovers that stdin is closed. */
                                FD_CLR(i->fd, &devices.infds);
                                /* Tell waker to ignore it too, by sending a
                                 * negative fd number (-1, since 0 is a valid
@@ -1033,7 +1033,8 @@ static void handle_input(int fd)
  *
  * All devices need a descriptor so the Guest knows it exists, and a "struct
  * device" so the Launcher can keep track of it.  We have common helper
- * routines to allocate and manage them. */
+ * routines to allocate and manage them.
+ */
 
 /* The layout of the device page is a "struct lguest_device_desc" followed by a
  * number of virtqueue descriptors, then two sets of feature bits, then an
@@ -1078,7 +1079,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
        struct virtqueue **i, *vq = malloc(sizeof(*vq));
        void *p;
 
-       /* First we need some pages for this virtqueue. */
+       /* First we need some memory for this virtqueue. */
        pages = (vring_size(num_descs, getpagesize()) + getpagesize() - 1)
                / getpagesize();
        p = get_pages(pages);
@@ -1122,7 +1123,7 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
 }
 
 /* The first half of the feature bitmask is for us to advertise features.  The
- * second half if for the Guest to accept features. */
+ * second half is for the Guest to accept features. */
 static void add_feature(struct device *dev, unsigned bit)
 {
        u8 *features = get_feature_bits(dev);
@@ -1151,7 +1152,9 @@ static void set_config(struct device *dev, unsigned len, const void *conf)
 }
 
 /* This routine does all the creation and setup of a new device, including
- * calling new_dev_desc() to allocate the descriptor and device memory. */
+ * calling new_dev_desc() to allocate the descriptor and device memory.
+ *
+ * See what I mean about userspace being boring? */
 static struct device *new_device(const char *name, u16 type, int fd,
                                 bool (*handle_input)(int, struct device *))
 {
@@ -1383,7 +1386,6 @@ struct vblk_info
         * Launcher triggers interrupt to Guest. */
        int done_fd;
 };
-/*:*/
 
 /*L:210
  * The Disk
@@ -1493,7 +1495,10 @@ static int io_thread(void *_dev)
        while (read(vblk->workpipe[0], &c, 1) == 1) {
                /* We acknowledge each request immediately to reduce latency,
                 * rather than waiting until we've done them all.  I haven't
-                * measured to see if it makes any difference. */
+                * measured to see if it makes any difference.
+                *
+                * That would be an interesting test, wouldn't it?  You could
+                * also try having more than one I/O thread. */
                while (service_io(dev))
                        write(vblk->done_fd, &c, 1);
        }
@@ -1501,7 +1506,7 @@ static int io_thread(void *_dev)
 }
 
 /* Now we've seen the I/O thread, we return to the Launcher to see what happens
- * when the thread tells us it's completed some I/O. */
+ * when that thread tells us it's completed some I/O. */
 static bool handle_io_finish(int fd, struct device *dev)
 {
        char c;
@@ -1573,11 +1578,12 @@ static void setup_block_file(const char *filename)
         * more work. */
        pipe(vblk->workpipe);
 
-       /* Create stack for thread and run it */
+       /* Create stack for thread and run it.  Since stack grows upwards, we
+        * point the stack pointer to the end of this region. */
        stack = malloc(32768);
        /* SIGCHLD - We dont "wait" for our cloned thread, so prevent it from
         * becoming a zombie. */
-       if (clone(io_thread, stack + 32768,  CLONE_VM | SIGCHLD, dev) == -1)
+       if (clone(io_thread, stack + 32768, CLONE_VM | SIGCHLD, dev) == -1)
                err(1, "Creating clone");
 
        /* We don't need to keep the I/O thread's end of the pipes open. */
@@ -1587,14 +1593,14 @@ static void setup_block_file(const char *filename)
        verbose("device %u: virtblock %llu sectors\n",
                devices.device_num, le64_to_cpu(conf.capacity));
 }
-/* That's the end of device setup. :*/
+/* That's the end of device setup. */
 
-/* Reboot */
+/*L:230 Reboot is pretty easy: clean up and exec() the Launcher afresh. */
 static void __attribute__((noreturn)) restart_guest(void)
 {
        unsigned int i;
 
-       /* Closing pipes causes the waker thread and io_threads to die, and
+       /* Closing pipes causes the Waker thread and io_threads to die, and
         * closing /dev/lguest cleans up the Guest.  Since we don't track all
         * open fds, we simply close everything beyond stderr. */
        for (i = 3; i < FD_SETSIZE; i++)
@@ -1603,7 +1609,7 @@ static void __attribute__((noreturn)) restart_guest(void)
        err(1, "Could not exec %s", main_args[0]);
 }
 
-/*L:220 Finally we reach the core of the Launcher, which runs the Guest, serves
+/*L:220 Finally we reach the core of the Launcher which runs the Guest, serves
  * its input and output, and finally, lays it to rest. */
 static void __attribute__((noreturn)) run_guest(int lguest_fd)
 {
@@ -1644,7 +1650,7 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd)
                        err(1, "Resetting break");
        }
 }
-/*
+/*L:240
  * This is the end of the Launcher.  The good news: we are over halfway
  * through!  The bad news: the most fiendish part of the code still lies ahead
  * of us.
@@ -1691,8 +1697,8 @@ int main(int argc, char *argv[])
         * device receive input from a file descriptor, we keep an fdset
         * (infds) and the maximum fd number (max_infd) with the head of the
         * list.  We also keep a pointer to the last device.  Finally, we keep
-        * the next interrupt number to hand out (1: remember that 0 is used by
-        * the timer). */
+        * the next interrupt number to use for devices (1: remember that 0 is
+        * used by the timer). */
        FD_ZERO(&devices.infds);
        devices.max_infd = -1;
        devices.lastdev = NULL;
@@ -1793,8 +1799,8 @@ int main(int argc, char *argv[])
        lguest_fd = tell_kernel(pgdir, start);
 
        /* We fork off a child process, which wakes the Launcher whenever one
-        * of the input file descriptors needs attention.  Otherwise we would
-        * run the Guest until it tries to output something. */
+        * of the input file descriptors needs attention.  We call this the
+        * Waker, and we'll cover it in a moment. */
        waker_fd = setup_waker(lguest_fd);
 
        /* Finally, run the Guest.  This doesn't return. */
index 722d4e7..29510dc 100644 (file)
@@ -1,6 +1,7 @@
-Rusty's Remarkably Unreliable Guide to Lguest
-       - or, A Young Coder's Illustrated Hypervisor
-http://lguest.ozlabs.org
+      __
+ (___()'`;  Rusty's Remarkably Unreliable Guide to Lguest
+ /,    /`      - or, A Young Coder's Illustrated Hypervisor
+ \\"--\\    http://lguest.ozlabs.org
 
 Lguest is designed to be a minimal hypervisor for the Linux kernel, for
 Linux developers and users to experiment with virtualization with the
@@ -41,12 +42,16 @@ Running Lguest:
          CONFIG_PHYSICAL_ALIGN=0x100000)
 
   "Device Drivers":
+     "Block devices"
+        "Virtio block driver (EXPERIMENTAL)" = M/Y
      "Network device support"
         "Universal TUN/TAP device driver support" = M/Y
-           (CONFIG_TUN=m)
-     "Virtualization"
-        "Linux hypervisor example code" = M/Y
-           (CONFIG_LGUEST=m)
+        "Virtio network driver (EXPERIMENTAL)" = M/Y
+           (CONFIG_VIRTIO_BLK=m, CONFIG_VIRTIO_NET=m and CONFIG_TUN=m)
+
+  "Virtualization"
+     "Linux hypervisor example code" = M/Y
+        (CONFIG_LGUEST=m)
 
 - A tool called "lguest" is available in this directory: type "make"
   to build it.  If you didn't build your kernel in-tree, use "make
index c025a45..757c729 100644 (file)
@@ -23,8 +23,7 @@ kernel debugging options, such as Kernel Stack Meter or Kernel Tracer,
 may implicitly disable the NMI watchdog.]
 
 For x86-64, the needed APIC is always compiled in, and the NMI watchdog is
-always enabled with I/O-APIC mode (nmi_watchdog=1). Currently, local APIC
-mode (nmi_watchdog=2) does not work on x86-64.
+always enabled with I/O-APIC mode (nmi_watchdog=1).
 
 Using local APIC (nmi_watchdog=2) needs the first performance register, so
 you can't use it for other purposes (such as high precision performance
index 73883b8..90dcbbc 100644 (file)
@@ -163,6 +163,12 @@ M: A2232@gmx.net
 L:     linux-m68k@lists.linux-m68k.org
 S:     Maintained
 
+AFS FILESYSTEM & AF_RXRPC SOCKET DOMAIN
+P:     David Howells
+M:     dhowells@redhat.com
+L:     linux-afs@lists.infradead.org
+S:     Supported
+
 AIO
 P:     Benjamin LaHaise
 M:     bcrl@kvack.org
@@ -2110,7 +2116,7 @@ M:        reinette.chatre@intel.com
 L:     linux-wireless@vger.kernel.org
 L:     ipw3945-devel@lists.sourceforge.net
 W:     http://intellinuxwireless.org
-T:     git git://intellinuxwireless.org/repos/iwlwifi
+T:     git git://git.kernel.org/pub/scm/linux/kernel/git/rchatre/iwlwifi-2.6.git
 S:     Supported
 
 IOC3 ETHERNET DRIVER
@@ -2314,14 +2320,14 @@ L:      kexec@lists.infradead.org
 S:     Maintained
 
 KPROBES
-P:     Prasanna S Panchamukhi
-M:     prasanna@in.ibm.com
 P:     Ananth N Mavinakayanahalli
 M:     ananth@in.ibm.com
 P:     Anil S Keshavamurthy
 M:     anil.s.keshavamurthy@intel.com
 P:     David S. Miller
 M:     davem@davemloft.net
+P:     Masami Hiramatsu
+M:     mhiramat@redhat.com
 L:     linux-kernel@vger.kernel.org
 S:     Maintained
 
index e66a07a..2687b73 100644 (file)
@@ -163,6 +163,7 @@ add_reserved_region(resource_size_t start, resource_size_t end,
        new->start = start;
        new->end = end;
        new->name = name;
+       new->sibling = next;
        new->flags = IORESOURCE_MEM;
 
        *pprev = new;
index cf6f686..b835c4c 100644 (file)
@@ -178,6 +178,7 @@ static int do_cop_absent(u32 insn)
        return 0;
 }
 
+#ifdef CONFIG_BUG
 int is_valid_bugaddr(unsigned long pc)
 {
        unsigned short opcode;
@@ -189,6 +190,7 @@ int is_valid_bugaddr(unsigned long pc)
 
        return opcode == AVR32_BUG_OPCODE;
 }
+#endif
 
 asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs)
 {
@@ -197,6 +199,7 @@ asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs)
        void __user *pc;
        long code;
 
+#ifdef CONFIG_BUG
        if (!user_mode(regs) && (ecr == ECR_ILLEGAL_OPCODE)) {
                enum bug_trap_type type;
 
@@ -211,6 +214,7 @@ asmlinkage void do_illegal_opcode(unsigned long ecr, struct pt_regs *regs)
                        die("Kernel BUG", regs, SIGKILL);
                }
        }
+#endif
 
        local_irq_enable();
 
index 797f0df..09f3062 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.24-rc6
-# Tue Jan 15 10:26:10 2008
+# Linux kernel version: 2.6.25-rc6
+# Tue Mar 25 10:25:48 2008
 #
 CONFIG_PPC64=y
 
@@ -27,6 +27,7 @@ CONFIG_GENERIC_TIME=y
 CONFIG_GENERIC_TIME_VSYSCALL=y
 CONFIG_GENERIC_CLOCKEVENTS=y
 CONFIG_GENERIC_HARDIRQS=y
+CONFIG_HAVE_SETUP_PER_CPU_AREA=y
 CONFIG_IRQ_PER_CPU=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
 CONFIG_ARCH_HAS_ILOG2_U32=y
@@ -67,17 +68,19 @@ CONFIG_SYSVIPC_SYSCTL=y
 # CONFIG_POSIX_MQUEUE is not set
 # CONFIG_BSD_PROCESS_ACCT is not set
 # CONFIG_TASKSTATS is not set
-# CONFIG_USER_NS is not set
-# CONFIG_PID_NS is not set
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=17
 # CONFIG_CGROUPS is not set
-CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+# CONFIG_GROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
 # CONFIG_RELAY is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+# CONFIG_IPC_NS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
 CONFIG_BLK_DEV_INITRD=y
 CONFIG_INITRAMFS_SOURCE=""
 # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
@@ -91,11 +94,13 @@ CONFIG_HOTPLUG=y
 CONFIG_PRINTK=y
 CONFIG_BUG=y
 CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
 CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_ANON_INODES=y
 CONFIG_EPOLL=y
 CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
 CONFIG_EVENTFD=y
 CONFIG_SHMEM=y
 CONFIG_VM_EVENT_COUNTERS=y
@@ -103,6 +108,15 @@ CONFIG_SLUB_DEBUG=y
 # CONFIG_SLAB is not set
 CONFIG_SLUB=y
 # CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
 CONFIG_RT_MUTEXES=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
@@ -130,6 +144,7 @@ CONFIG_DEFAULT_AS=y
 # CONFIG_DEFAULT_CFQ is not set
 # CONFIG_DEFAULT_NOOP is not set
 CONFIG_DEFAULT_IOSCHED="anticipatory"
+CONFIG_CLASSIC_RCU=y
 
 #
 # Platform support
@@ -140,8 +155,8 @@ CONFIG_PPC_MULTIPLATFORM=y
 # CONFIG_PPC_86xx is not set
 # CONFIG_PPC_PSERIES is not set
 # CONFIG_PPC_ISERIES is not set
-# CONFIG_PPC_MPC52xx is not set
-# CONFIG_PPC_MPC5200 is not set
+# CONFIG_PPC_MPC512x is not set
+# CONFIG_PPC_MPC5121 is not set
 # CONFIG_PPC_PMAC is not set
 # CONFIG_PPC_MAPLE is not set
 CONFIG_PPC_PASEMI=y
@@ -159,6 +174,7 @@ CONFIG_PPC_PASEMI_MDIO=y
 # CONFIG_PPC_IBM_CELL_BLADE is not set
 # CONFIG_PQ2ADS is not set
 CONFIG_PPC_NATIVE=y
+# CONFIG_IPIC is not set
 CONFIG_MPIC=y
 # CONFIG_MPIC_WEIRD is not set
 # CONFIG_PPC_I8259 is not set
@@ -189,7 +205,6 @@ CONFIG_CPU_FREQ_GOV_ONDEMAND=y
 # CPU Frequency drivers
 #
 CONFIG_PPC_PASEMI_CPUFREQ=y
-# CONFIG_CPM2 is not set
 # CONFIG_FSL_ULI1575 is not set
 
 #
@@ -204,16 +219,20 @@ CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
 # CONFIG_HZ_300 is not set
 CONFIG_HZ_1000=y
 CONFIG_HZ=1000
+# CONFIG_SCHED_HRTICK is not set
 CONFIG_PREEMPT_NONE=y
 # CONFIG_PREEMPT_VOLUNTARY is not set
 # CONFIG_PREEMPT is not set
-# CONFIG_PREEMPT_BKL is not set
 CONFIG_BINFMT_ELF=y
+CONFIG_COMPAT_BINFMT_ELF=y
 # CONFIG_BINFMT_MISC is not set
 CONFIG_FORCE_MAX_ZONEORDER=9
 CONFIG_HUGETLB_PAGE_SIZE_VARIABLE=y
 CONFIG_IOMMU_VMERGE=y
+CONFIG_IOMMU_HELPER=y
 CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
+CONFIG_ARCH_HAS_WALK_MEMORY=y
+CONFIG_ARCH_ENABLE_MEMORY_HOTREMOVE=y
 # CONFIG_KEXEC is not set
 # CONFIG_CRASH_DUMP is not set
 # CONFIG_IRQ_ALL_CPUS is not set
@@ -236,12 +255,12 @@ CONFIG_ZONE_DMA_FLAG=1
 CONFIG_BOUNCE=y
 CONFIG_PPC_HAS_HASH_64K=y
 CONFIG_PPC_64K_PAGES=y
+# CONFIG_PPC_SUBPAGE_PROT is not set
 # CONFIG_SCHED_SMT is not set
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_CMDLINE_BOOL is not set
 # CONFIG_PM is not set
 # CONFIG_SECCOMP is not set
-# CONFIG_WANT_DEVICE_TREE is not set
 CONFIG_ISA_DMA_API=y
 
 #
@@ -290,6 +309,7 @@ CONFIG_XFRM=y
 CONFIG_XFRM_USER=y
 # CONFIG_XFRM_SUB_POLICY is not set
 # CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
 CONFIG_NET_KEY=y
 # CONFIG_NET_KEY_MIGRATE is not set
 CONFIG_INET=y
@@ -346,6 +366,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
 #
 # CONFIG_NET_PKTGEN is not set
 # CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
 # CONFIG_IRDA is not set
 # CONFIG_BT is not set
 # CONFIG_AF_RXRPC is not set
@@ -441,8 +462,10 @@ CONFIG_MTD_NAND=y
 CONFIG_MTD_NAND_IDS=y
 # CONFIG_MTD_NAND_DISKONCHIP is not set
 # CONFIG_MTD_NAND_CAFE is not set
+CONFIG_MTD_NAND_PASEMI=y
 # CONFIG_MTD_NAND_PLATFORM is not set
 # CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_NAND_FSL_ELBC is not set
 # CONFIG_MTD_ONENAND is not set
 
 #
@@ -465,7 +488,7 @@ CONFIG_BLK_DEV_LOOP=y
 CONFIG_BLK_DEV_RAM=y
 CONFIG_BLK_DEV_RAM_COUNT=16
 CONFIG_BLK_DEV_RAM_SIZE=16384
-CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
+# CONFIG_BLK_DEV_XIP is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 CONFIG_MISC_DEVICES=y
@@ -473,11 +496,13 @@ CONFIG_MISC_DEVICES=y
 # CONFIG_EEPROM_93CX6 is not set
 # CONFIG_SGI_IOC4 is not set
 # CONFIG_TIFM_CORE is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
 CONFIG_IDE=y
 CONFIG_BLK_DEV_IDE=y
 
 #
-# Please see Documentation/ide.txt for help/info on IDE drives
+# Please see Documentation/ide/ide.txt for help/info on IDE drives
 #
 # CONFIG_BLK_DEV_IDE_SATA is not set
 CONFIG_BLK_DEV_IDEDISK=y
@@ -485,6 +510,7 @@ CONFIG_IDEDISK_MULTI_MODE=y
 # CONFIG_BLK_DEV_IDECS is not set
 # CONFIG_BLK_DEV_DELKIN is not set
 CONFIG_BLK_DEV_IDECD=y
+CONFIG_BLK_DEV_IDECD_VERBOSE_ERRORS=y
 # CONFIG_BLK_DEV_IDETAPE is not set
 # CONFIG_BLK_DEV_IDEFLOPPY is not set
 CONFIG_BLK_DEV_IDESCSI=y
@@ -500,7 +526,6 @@ CONFIG_IDE_PROC_FS=y
 #
 # PCI IDE chipsets support
 #
-# CONFIG_IDEPCI_PCIBUS_ORDER is not set
 # CONFIG_BLK_DEV_GENERIC is not set
 # CONFIG_BLK_DEV_OPTI621 is not set
 # CONFIG_BLK_DEV_AEC62XX is not set
@@ -528,7 +553,6 @@ CONFIG_IDE_PROC_FS=y
 # CONFIG_BLK_DEV_TRM290 is not set
 # CONFIG_BLK_DEV_VIA82CXXX is not set
 # CONFIG_BLK_DEV_TC86C001 is not set
-# CONFIG_IDE_ARM is not set
 # CONFIG_BLK_DEV_IDEDMA is not set
 CONFIG_IDE_ARCH_OBSOLETE_INIT=y
 # CONFIG_BLK_DEV_HD is not set
@@ -593,6 +617,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
@@ -646,6 +671,7 @@ CONFIG_ATA_GENERIC=y
 # CONFIG_PATA_MPIIX is not set
 # CONFIG_PATA_OLDPIIX is not set
 # CONFIG_PATA_NETCELL is not set
+# CONFIG_PATA_NINJA32 is not set
 # CONFIG_PATA_NS87410 is not set
 # CONFIG_PATA_NS87415 is not set
 # CONFIG_PATA_OPTI is not set
@@ -699,7 +725,6 @@ CONFIG_DUMMY=y
 # CONFIG_EQUALIZER is not set
 # CONFIG_TUN is not set
 # CONFIG_VETH is not set
-# CONFIG_IP1000 is not set
 # CONFIG_ARCNET is not set
 CONFIG_PHYLIB=y
 
@@ -715,6 +740,7 @@ CONFIG_MARVELL_PHY=y
 # CONFIG_SMSC_PHY is not set
 # CONFIG_BROADCOM_PHY is not set
 # CONFIG_ICPLUS_PHY is not set
+# CONFIG_REALTEK_PHY is not set
 # CONFIG_FIXED_PHY is not set
 # CONFIG_MDIO_BITBANG is not set
 CONFIG_NET_ETHERNET=y
@@ -742,6 +768,7 @@ CONFIG_NET_PCI=y
 # CONFIG_NE2K_PCI is not set
 # CONFIG_8139CP is not set
 # CONFIG_8139TOO is not set
+# CONFIG_R6040 is not set
 # CONFIG_SIS900 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_SUNDANCE is not set
@@ -754,6 +781,9 @@ CONFIG_E1000=y
 CONFIG_E1000_NAPI=y
 # CONFIG_E1000_DISABLE_PACKET_SPLIT is not set
 # CONFIG_E1000E is not set
+# CONFIG_E1000E_ENABLED is not set
+# CONFIG_IP1000 is not set
+# CONFIG_IGB is not set
 # CONFIG_NS83820 is not set
 # CONFIG_HAMACHI is not set
 # CONFIG_YELLOWFIN is not set
@@ -779,6 +809,7 @@ CONFIG_NETDEV_10000=y
 CONFIG_PASEMI_MAC=y
 # CONFIG_MLX4_CORE is not set
 # CONFIG_TEHUTI is not set
+# CONFIG_BNX2X is not set
 # CONFIG_TR is not set
 
 #
@@ -802,7 +833,6 @@ CONFIG_PASEMI_MAC=y
 # CONFIG_PPP is not set
 # CONFIG_SLIP is not set
 # CONFIG_NET_FC is not set
-# CONFIG_SHAPER is not set
 # CONFIG_NETCONSOLE is not set
 # CONFIG_NETPOLL is not set
 # CONFIG_NET_POLL_CONTROLLER is not set
@@ -861,6 +891,7 @@ CONFIG_VT_CONSOLE=y
 CONFIG_HW_CONSOLE=y
 # CONFIG_VT_HW_CONSOLE_BINDING is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_NOZOMI is not set
 
 #
 # Serial drivers
@@ -886,8 +917,7 @@ CONFIG_LEGACY_PTY_COUNT=4
 # CONFIG_IPMI_HANDLER is not set
 CONFIG_HW_RANDOM=y
 CONFIG_HW_RANDOM_PASEMI=y
-CONFIG_GEN_RTC=y
-CONFIG_GEN_RTC_X=y
+# CONFIG_GEN_RTC is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
 
@@ -897,6 +927,7 @@ CONFIG_GEN_RTC_X=y
 # CONFIG_SYNCLINK_CS is not set
 # CONFIG_CARDMAN_4000 is not set
 # CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
 CONFIG_RAW_DRIVER=y
 CONFIG_MAX_RAW_DEVS=256
 # CONFIG_HANGCHECK_TIMER is not set
@@ -944,13 +975,12 @@ CONFIG_I2C_PASEMI=y
 #
 # Miscellaneous I2C Chip support
 #
-# CONFIG_SENSORS_DS1337 is not set
-# CONFIG_SENSORS_DS1374 is not set
 # CONFIG_DS1682 is not set
 CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
-# CONFIG_SENSORS_PCA9539 is not set
+# CONFIG_PCF8575 is not set
 # CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_TPS65010 is not set
 # CONFIG_SENSORS_MAX6875 is not set
 # CONFIG_SENSORS_TSL2550 is not set
 # CONFIG_I2C_DEBUG_CORE is not set
@@ -975,6 +1005,7 @@ CONFIG_HWMON_VID=y
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
@@ -1004,6 +1035,7 @@ CONFIG_SENSORS_LM90=y
 # CONFIG_SENSORS_SMSC47M1 is not set
 # CONFIG_SENSORS_SMSC47M192 is not set
 # CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
 # CONFIG_SENSORS_THMC50 is not set
 # CONFIG_SENSORS_VIA686A is not set
 # CONFIG_SENSORS_VT1211 is not set
@@ -1013,9 +1045,11 @@ CONFIG_SENSORS_LM90=y
 # CONFIG_SENSORS_W83792D is not set
 # CONFIG_SENSORS_W83793 is not set
 # CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
 # CONFIG_SENSORS_W83627HF is not set
 # CONFIG_SENSORS_W83627EHF is not set
 # CONFIG_HWMON_DEBUG_CHIP is not set
+# CONFIG_THERMAL is not set
 # CONFIG_WATCHDOG is not set
 
 #
@@ -1183,6 +1217,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_BT87X is not set
 # CONFIG_SND_CA0106 is not set
 # CONFIG_SND_CMIPCI is not set
+# CONFIG_SND_OXYGEN is not set
 # CONFIG_SND_CS4281 is not set
 # CONFIG_SND_CS46XX is not set
 # CONFIG_SND_CS5530 is not set
@@ -1208,6 +1243,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_HDA_INTEL is not set
 # CONFIG_SND_HDSP is not set
 # CONFIG_SND_HDSPM is not set
+# CONFIG_SND_HIFIER is not set
 # CONFIG_SND_ICE1712 is not set
 # CONFIG_SND_ICE1724 is not set
 # CONFIG_SND_INTEL8X0 is not set
@@ -1225,6 +1261,7 @@ CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_TRIDENT is not set
 # CONFIG_SND_VIA82XX is not set
 # CONFIG_SND_VIA82XX_MODEM is not set
+# CONFIG_SND_VIRTUOSO is not set
 # CONFIG_SND_VX222 is not set
 # CONFIG_SND_YMFPCI is not set
 
@@ -1259,6 +1296,10 @@ CONFIG_SND_USB_USX2Y=y
 #
 
 #
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
 # Open Sound System
 #
 # CONFIG_SOUND_PRIME is not set
@@ -1280,6 +1321,7 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
 
 #
 # Miscellaneous USB options
@@ -1293,17 +1335,14 @@ CONFIG_USB_DEVICEFS=y
 # USB Host Controller Drivers
 #
 CONFIG_USB_EHCI_HCD=y
-# CONFIG_USB_EHCI_SPLIT_ISO is not set
 # CONFIG_USB_EHCI_ROOT_HUB_TT is not set
 # CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_EHCI_HCD_PPC_OF=y
 # CONFIG_USB_ISP116X_HCD is not set
 CONFIG_USB_OHCI_HCD=y
-CONFIG_USB_OHCI_HCD_PPC_OF=y
-CONFIG_USB_OHCI_HCD_PPC_OF_BE=y
-# CONFIG_USB_OHCI_HCD_PPC_OF_LE is not set
-CONFIG_USB_OHCI_HCD_PCI=y
-CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
-CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
+# CONFIG_USB_OHCI_HCD_PPC_OF is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_DESC is not set
+# CONFIG_USB_OHCI_BIG_ENDIAN_MMIO is not set
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 CONFIG_USB_UHCI_HCD=y
 CONFIG_USB_SL811_HCD=y
@@ -1348,10 +1387,6 @@ CONFIG_USB_LIBUSUAL=y
 #
 # USB port drivers
 #
-
-#
-# USB Serial Converter support
-#
 # CONFIG_USB_SERIAL is not set
 
 #
@@ -1377,16 +1412,9 @@ CONFIG_USB_LIBUSUAL=y
 # CONFIG_USB_TRANCEVIBRATOR is not set
 # CONFIG_USB_IOWARRIOR is not set
 # CONFIG_USB_TEST is not set
-
-#
-# USB DSL modem support
-#
-
-#
-# USB Gadget Support
-#
 # CONFIG_USB_GADGET is not set
 # CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
 # CONFIG_NEW_LEDS is not set
 # CONFIG_INFINIBAND is not set
 CONFIG_EDAC=y
@@ -1425,6 +1453,7 @@ CONFIG_RTC_DRV_DS1307=y
 # CONFIG_RTC_DRV_PCF8563 is not set
 # CONFIG_RTC_DRV_PCF8583 is not set
 # CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
 
 #
 # SPI RTC drivers
@@ -1434,9 +1463,10 @@ CONFIG_RTC_DRV_DS1307=y
 # Platform RTC drivers
 #
 # CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
 # CONFIG_RTC_DRV_DS1553 is not set
-# CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
 # CONFIG_RTC_DRV_M48T86 is not set
 # CONFIG_RTC_DRV_M48T59 is not set
 # CONFIG_RTC_DRV_V3020 is not set
@@ -1444,6 +1474,7 @@ CONFIG_RTC_DRV_DS1307=y
 #
 # on-CPU RTC drivers
 #
+# CONFIG_DMADEVICES is not set
 
 #
 # Userspace I/O
@@ -1471,12 +1502,10 @@ CONFIG_FS_POSIX_ACL=y
 # CONFIG_XFS_FS is not set
 # CONFIG_GFS2_FS is not set
 # CONFIG_OCFS2_FS is not set
-# CONFIG_MINIX_FS is not set
-# CONFIG_ROMFS_FS is not set
+CONFIG_DNOTIFY=y
 CONFIG_INOTIFY=y
 CONFIG_INOTIFY_USER=y
 # CONFIG_QUOTA is not set
-CONFIG_DNOTIFY=y
 CONFIG_AUTOFS_FS=y
 CONFIG_AUTOFS4_FS=y
 # CONFIG_FUSE_FS is not set
@@ -1536,8 +1565,10 @@ CONFIG_JFFS2_RTIME=y
 # CONFIG_JFFS2_RUBIN is not set
 # CONFIG_CRAMFS is not set
 # CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
 # CONFIG_HPFS_FS is not set
 # CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
 # CONFIG_SYSV_FS is not set
 # CONFIG_UFS_FS is not set
 CONFIG_NETWORK_FILESYSTEMS=y
@@ -1629,7 +1660,6 @@ CONFIG_NLS_ISO8859_1=y
 # CONFIG_NLS_KOI8_U is not set
 # CONFIG_NLS_UTF8 is not set
 # CONFIG_DLM is not set
-# CONFIG_UCC_SLOW is not set
 
 #
 # Library routines
@@ -1647,11 +1677,6 @@ CONFIG_PLIST=y
 CONFIG_HAS_IOMEM=y
 CONFIG_HAS_IOPORT=y
 CONFIG_HAS_DMA=y
-CONFIG_INSTRUMENTATION=y
-CONFIG_PROFILING=y
-CONFIG_OPROFILE=y
-# CONFIG_KPROBES is not set
-# CONFIG_MARKERS is not set
 
 #
 # Kernel hacking
@@ -1670,6 +1695,7 @@ CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 # CONFIG_TIMER_STATS is not set
 # CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
 # CONFIG_DEBUG_RT_MUTEXES is not set
 # CONFIG_RT_MUTEX_TESTER is not set
 # CONFIG_DEBUG_SPINLOCK is not set
@@ -1682,9 +1708,9 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_VM is not set
 # CONFIG_DEBUG_LIST is not set
 # CONFIG_DEBUG_SG is not set
-# CONFIG_FORCED_INLINING is not set
 # CONFIG_BOOT_PRINTK_DELAY is not set
 # CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
 # CONFIG_FAULT_INJECTION is not set
 # CONFIG_SAMPLES is not set
 # CONFIG_DEBUG_STACKOVERFLOW is not set
@@ -1710,7 +1736,9 @@ CONFIG_ASYNC_MEMCPY=y
 CONFIG_ASYNC_XOR=y
 CONFIG_CRYPTO=y
 CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
 CONFIG_CRYPTO_BLKCIPHER=y
+# CONFIG_CRYPTO_SEQIV is not set
 CONFIG_CRYPTO_HASH=y
 CONFIG_CRYPTO_MANAGER=y
 CONFIG_CRYPTO_HMAC=y
@@ -1729,6 +1757,9 @@ CONFIG_CRYPTO_CBC=y
 # CONFIG_CRYPTO_PCBC is not set
 # CONFIG_CRYPTO_LRW is not set
 # CONFIG_CRYPTO_XTS is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_CCM is not set
 # CONFIG_CRYPTO_CRYPTD is not set
 CONFIG_CRYPTO_DES=y
 # CONFIG_CRYPTO_FCRYPT is not set
@@ -1743,11 +1774,14 @@ CONFIG_CRYPTO_AES=y
 # CONFIG_CRYPTO_KHAZAD is not set
 # CONFIG_CRYPTO_ANUBIS is not set
 # CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SALSA20 is not set
 # CONFIG_CRYPTO_DEFLATE is not set
 # CONFIG_CRYPTO_MICHAEL_MIC is not set
 # CONFIG_CRYPTO_CRC32C is not set
 # CONFIG_CRYPTO_CAMELLIA is not set
 # CONFIG_CRYPTO_TEST is not set
-# CONFIG_CRYPTO_AUTHENC is not set
+CONFIG_CRYPTO_AUTHENC=y
+# CONFIG_CRYPTO_LZO is not set
 CONFIG_CRYPTO_HW=y
+# CONFIG_CRYPTO_DEV_HIFN_795X is not set
 # CONFIG_PPC_CLOCK is not set
index 59311ec..4ec6055 100644 (file)
@@ -241,8 +241,12 @@ void discard_lazy_cpu_state(void)
 }
 #endif /* CONFIG_SMP */
 
+static DEFINE_PER_CPU(unsigned long, current_dabr);
+
 int set_dabr(unsigned long dabr)
 {
+       __get_cpu_var(current_dabr) = dabr;
+
 #ifdef CONFIG_PPC_MERGE                /* XXX for now */
        if (ppc_md.set_dabr)
                return ppc_md.set_dabr(dabr);
@@ -259,8 +263,6 @@ int set_dabr(unsigned long dabr)
 DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
 #endif
 
-static DEFINE_PER_CPU(unsigned long, current_dabr);
-
 struct task_struct *__switch_to(struct task_struct *prev,
        struct task_struct *new)
 {
@@ -325,10 +327,8 @@ struct task_struct *__switch_to(struct task_struct *prev,
 
 #endif /* CONFIG_SMP */
 
-       if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr)) {
+       if (unlikely(__get_cpu_var(current_dabr) != new->thread.dabr))
                set_dabr(new->thread.dabr);
-               __get_cpu_var(current_dabr) = new->thread.dabr;
-       }
 
        new_thread = &new->thread;
        old_thread = &current->thread;
index 76ec1d1..9a93217 100644 (file)
@@ -92,7 +92,7 @@ vma_map_add(struct vma_to_fileoffset_map *map, unsigned int vma,
  * A pointer to the first vma_map in the generated list
  * of vma_maps is returned.  */
 struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
-                                            unsigned long spu_elf_start)
+                                            unsigned long __spu_elf_start)
 {
        static const unsigned char expected[EI_PAD] = {
                [EI_MAG0] = ELFMAG0,
@@ -107,9 +107,11 @@ struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
 
        int grd_val;
        struct vma_to_fileoffset_map *map = NULL;
+       void __user *spu_elf_start = (void __user *)__spu_elf_start;
        struct spu_overlay_info ovly;
        unsigned int overlay_tbl_offset = -1;
-       unsigned long phdr_start, shdr_start;
+       Elf32_Phdr __user *phdr_start;
+       Elf32_Shdr __user *shdr_start;
        Elf32_Ehdr ehdr;
        Elf32_Phdr phdr;
        Elf32_Shdr shdr, shdr_str;
@@ -121,12 +123,12 @@ struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
        unsigned int ovly_buf_table_sym = 0;
        unsigned int ovly_table_end_sym = 0;
        unsigned int ovly_buf_table_end_sym = 0;
-       unsigned long ovly_table;
+       struct spu_overlay_info __user *ovly_table;
        unsigned int n_ovlys;
 
        /* Get and validate ELF header.  */
 
-       if (copy_from_user(&ehdr, (void *) spu_elf_start, sizeof (ehdr)))
+       if (copy_from_user(&ehdr, spu_elf_start, sizeof (ehdr)))
                goto fail;
 
        if (memcmp(ehdr.e_ident, expected, EI_PAD) != 0) {
@@ -152,9 +154,7 @@ struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
 
        /* Traverse program headers.  */
        for (i = 0; i < ehdr.e_phnum; i++) {
-               if (copy_from_user(&phdr,
-                                  (void *) (phdr_start + i * sizeof(phdr)),
-                                  sizeof(phdr)))
+               if (copy_from_user(&phdr, phdr_start + i, sizeof(phdr)))
                        goto fail;
 
                if (phdr.p_type != PT_LOAD)
@@ -171,9 +171,7 @@ struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
        pr_debug("SPU_PROF: Created non-overlay maps\n");
        /* Traverse section table and search for overlay-related symbols.  */
        for (i = 0; i < ehdr.e_shnum; i++) {
-               if (copy_from_user(&shdr,
-                                  (void *) (shdr_start + i * sizeof(shdr)),
-                                  sizeof(shdr)))
+               if (copy_from_user(&shdr, shdr_start + i, sizeof(shdr)))
                        goto fail;
 
                if (shdr.sh_type != SHT_SYMTAB)
@@ -182,8 +180,7 @@ struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
                        continue;
 
                if (copy_from_user(&shdr_str,
-                                  (void *) (shdr_start + shdr.sh_link *
-                                            sizeof(shdr)),
+                                  shdr_start + shdr.sh_link,
                                   sizeof(shdr)))
                        goto fail;
 
@@ -191,15 +188,15 @@ struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
                        goto fail;;
 
                for (j = 0; j < shdr.sh_size / sizeof (sym); j++) {
-                       if (copy_from_user(&sym, (void *) (spu_elf_start +
-                                                      shdr.sh_offset + j *
-                                                          sizeof (sym)),
+                       if (copy_from_user(&sym, spu_elf_start +
+                                                shdr.sh_offset +
+                                                j * sizeof (sym),
                                           sizeof (sym)))
                                goto fail;
 
-                       if (copy_from_user(name, (void *)
-                                          (spu_elf_start + shdr_str.sh_offset +
-                                           sym.st_name),
+                       if (copy_from_user(name, 
+                                          spu_elf_start + shdr_str.sh_offset +
+                                          sym.st_name,
                                           20))
                                goto fail;
 
@@ -245,9 +242,7 @@ struct vma_to_fileoffset_map *create_vma_map(const struct spu *aSpu,
 
        /* Traverse overlay table.  */
        for (i = 0; i < n_ovlys; i++) {
-               if (copy_from_user(&ovly, (void *)
-                                  (ovly_table + i * sizeof (ovly)),
-                                  sizeof (ovly)))
+               if (copy_from_user(&ovly, ovly_table + i, sizeof (ovly)))
                        goto fail;
 
                /* The ovly.vma/size/offset arguments are analogous to the same
index ca52b58..a977f20 100644 (file)
@@ -763,7 +763,7 @@ void xics_request_IPIs(void)
 }
 #endif /* CONFIG_SMP */
 
-void xics_teardown_cpu()
+void xics_teardown_cpu(void)
 {
        int cpu = smp_processor_id();
 
index 250958d..9d4bd22 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25-rc1
-# Sun Feb 17 22:44:12 2008
+# Linux kernel version: 2.6.25-rc3
+# Wed Mar 26 04:33:35 2008
 #
 CONFIG_SPARC=y
 CONFIG_SPARC64=y
@@ -55,9 +55,11 @@ CONFIG_POSIX_MQUEUE=y
 # CONFIG_IKCONFIG is not set
 CONFIG_LOG_BUF_SHIFT=18
 # CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
 CONFIG_FAIR_GROUP_SCHED=y
-CONFIG_FAIR_USER_SCHED=y
-# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_RT_GROUP_SCHED=y
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
 CONFIG_SYSFS_DEPRECATED=y
 CONFIG_RELAY=y
 CONFIG_NAMESPACES=y
@@ -482,6 +484,7 @@ CONFIG_SCSI_LOWLEVEL=y
 # CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_MVSAS is not set
 # CONFIG_SCSI_STEX is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
@@ -810,6 +813,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ADM1031 is not set
 # CONFIG_SENSORS_ADM9240 is not set
 # CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
 # CONFIG_SENSORS_I5K_AMB is not set
index dd5d28e..0097c08 100644 (file)
@@ -15,6 +15,8 @@
 #include <asm/spitfire.h>
 #include <asm/oplib.h>
 
+#include "entry.h"
+
 DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
 
 struct cpu_iu_info {
@@ -65,8 +67,6 @@ static struct cpu_iu_info linux_sparc_chips[] = {
 char *sparc_cpu_type;
 char *sparc_fpu_type;
 
-unsigned int fsr_storage;
-
 static void __init sun4v_cpu_probe(void)
 {
        switch (sun4v_chip_type) {
@@ -94,8 +94,10 @@ void __init cpu_probe(void)
        unsigned long ver, fpu_vers, manuf, impl, fprs;
        int i;
        
-       if (tlb_type == hypervisor)
-               return sun4v_cpu_probe();
+       if (tlb_type == hypervisor) {
+               sun4v_cpu_probe();
+               return;
+       }
 
        fprs = fprs_read();
        fprs_write(FPRS_FEF);
index 6be4d2d..49eca4b 100644 (file)
@@ -1705,6 +1705,36 @@ __flushw_user:
 2:     retl
         nop
 
+       /* Flush %fp and %i7 to the stack for all register
+        * windows active inside of the cpu.  This allows
+        * show_stack_trace() to avoid using an expensive
+        * 'flushw'.
+        */
+       .globl          stack_trace_flush
+       .type           stack_trace_flush,#function
+stack_trace_flush:
+       rdpr            %pstate, %o0
+       wrpr            %o0, PSTATE_IE, %pstate
+
+       rdpr            %cwp, %g1
+       rdpr            %canrestore, %g2
+       sub             %g1, 1, %g3
+
+1:     brz,pn          %g2, 2f
+        sub            %g2, 1, %g2
+       wrpr            %g3, %cwp
+       stx             %fp, [%sp + STACK_BIAS + RW_V9_I6]
+       stx             %i7, [%sp + STACK_BIAS + RW_V9_I7]
+       ba,pt           %xcc, 1b
+        sub            %g3, 1, %g3
+
+2:     wrpr            %g1, %cwp
+       wrpr            %o0, %pstate
+
+       retl
+        nop
+       .size           stack_trace_flush,.-stack_trace_flush
+
 #ifdef CONFIG_SMP
        .globl          hard_smp_processor_id
 hard_smp_processor_id:
diff --git a/arch/sparc64/kernel/entry.h b/arch/sparc64/kernel/entry.h
new file mode 100644 (file)
index 0000000..4a91e9c
--- /dev/null
@@ -0,0 +1,196 @@
+#ifndef _ENTRY_H
+#define _ENTRY_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+
+extern char *sparc_cpu_type;
+extern char *sparc_fpu_type;
+
+extern void __init per_cpu_patch(void);
+extern void __init sun4v_patch(void);
+extern void __init boot_cpu_id_too_large(int cpu);
+extern unsigned int dcache_parity_tl1_occurred;
+extern unsigned int icache_parity_tl1_occurred;
+
+extern asmlinkage void update_perfctrs(void);
+extern asmlinkage void sparc_breakpoint(struct pt_regs *regs);
+extern void timer_interrupt(int irq, struct pt_regs *regs);
+
+extern void do_notify_resume(struct pt_regs *regs,
+                            unsigned long orig_i0,
+                            int restart_syscall,
+                            unsigned long thread_info_flags);
+
+extern asmlinkage void syscall_trace(struct pt_regs *regs,
+                                    int syscall_exit_p);
+
+extern void bad_trap_tl1(struct pt_regs *regs, long lvl);
+
+extern void do_fpe_common(struct pt_regs *regs);
+extern void do_fpieee(struct pt_regs *regs);
+extern void do_fpother(struct pt_regs *regs);
+extern void do_tof(struct pt_regs *regs);
+extern void do_div0(struct pt_regs *regs);
+extern void do_illegal_instruction(struct pt_regs *regs);
+extern void mem_address_unaligned(struct pt_regs *regs,
+                                 unsigned long sfar,
+                                 unsigned long sfsr);
+extern void sun4v_do_mna(struct pt_regs *regs,
+                        unsigned long addr,
+                        unsigned long type_ctx);
+extern void do_privop(struct pt_regs *regs);
+extern void do_privact(struct pt_regs *regs);
+extern void do_cee(struct pt_regs *regs);
+extern void do_cee_tl1(struct pt_regs *regs);
+extern void do_dae_tl1(struct pt_regs *regs);
+extern void do_iae_tl1(struct pt_regs *regs);
+extern void do_div0_tl1(struct pt_regs *regs);
+extern void do_fpdis_tl1(struct pt_regs *regs);
+extern void do_fpieee_tl1(struct pt_regs *regs);
+extern void do_fpother_tl1(struct pt_regs *regs);
+extern void do_ill_tl1(struct pt_regs *regs);
+extern void do_irq_tl1(struct pt_regs *regs);
+extern void do_lddfmna_tl1(struct pt_regs *regs);
+extern void do_stdfmna_tl1(struct pt_regs *regs);
+extern void do_paw(struct pt_regs *regs);
+extern void do_paw_tl1(struct pt_regs *regs);
+extern void do_vaw(struct pt_regs *regs);
+extern void do_vaw_tl1(struct pt_regs *regs);
+extern void do_tof_tl1(struct pt_regs *regs);
+extern void do_getpsr(struct pt_regs *regs);
+
+extern void spitfire_insn_access_exception(struct pt_regs *regs,
+                                          unsigned long sfsr,
+                                          unsigned long sfar);
+extern void spitfire_insn_access_exception_tl1(struct pt_regs *regs,
+                                              unsigned long sfsr,
+                                              unsigned long sfar);
+extern void spitfire_data_access_exception(struct pt_regs *regs,
+                                          unsigned long sfsr,
+                                          unsigned long sfar);
+extern void spitfire_data_access_exception_tl1(struct pt_regs *regs,
+                                              unsigned long sfsr,
+                                              unsigned long sfar);
+extern void spitfire_access_error(struct pt_regs *regs,
+                                 unsigned long status_encoded,
+                                 unsigned long afar);
+
+extern void cheetah_fecc_handler(struct pt_regs *regs,
+                                unsigned long afsr,
+                                unsigned long afar);
+extern void cheetah_cee_handler(struct pt_regs *regs,
+                               unsigned long afsr,
+                               unsigned long afar);
+extern void cheetah_deferred_handler(struct pt_regs *regs,
+                                    unsigned long afsr,
+                                    unsigned long afar);
+extern void cheetah_plus_parity_error(int type, struct pt_regs *regs);
+
+extern void sun4v_insn_access_exception(struct pt_regs *regs,
+                                       unsigned long addr,
+                                       unsigned long type_ctx);
+extern void sun4v_insn_access_exception_tl1(struct pt_regs *regs,
+                                           unsigned long addr,
+                                           unsigned long type_ctx);
+extern void sun4v_data_access_exception(struct pt_regs *regs,
+                                       unsigned long addr,
+                                       unsigned long type_ctx);
+extern void sun4v_data_access_exception_tl1(struct pt_regs *regs,
+                                           unsigned long addr,
+                                           unsigned long type_ctx);
+extern void sun4v_resum_error(struct pt_regs *regs,
+                             unsigned long offset);
+extern void sun4v_resum_overflow(struct pt_regs *regs);
+extern void sun4v_nonresum_error(struct pt_regs *regs,
+                                unsigned long offset);
+extern void sun4v_nonresum_overflow(struct pt_regs *regs);
+
+extern unsigned long sun4v_err_itlb_vaddr;
+extern unsigned long sun4v_err_itlb_ctx;
+extern unsigned long sun4v_err_itlb_pte;
+extern unsigned long sun4v_err_itlb_error;
+
+extern void sun4v_itlb_error_report(struct pt_regs *regs, int tl);
+
+extern unsigned long sun4v_err_dtlb_vaddr;
+extern unsigned long sun4v_err_dtlb_ctx;
+extern unsigned long sun4v_err_dtlb_pte;
+extern unsigned long sun4v_err_dtlb_error;
+
+extern void sun4v_dtlb_error_report(struct pt_regs *regs, int tl);
+extern void hypervisor_tlbop_error(unsigned long err,
+                                  unsigned long op);
+extern void hypervisor_tlbop_error_xcall(unsigned long err,
+                                        unsigned long op);
+
+/* WARNING: The error trap handlers in assembly know the precise
+ *         layout of the following structure.
+ *
+ * C-level handlers in traps.c use this information to log the
+ * error and then determine how to recover (if possible).
+ */
+struct cheetah_err_info {
+/*0x00*/u64 afsr;
+/*0x08*/u64 afar;
+
+       /* D-cache state */
+/*0x10*/u64 dcache_data[4];    /* The actual data      */
+/*0x30*/u64 dcache_index;      /* D-cache index        */
+/*0x38*/u64 dcache_tag;                /* D-cache tag/valid    */
+/*0x40*/u64 dcache_utag;       /* D-cache microtag     */
+/*0x48*/u64 dcache_stag;       /* D-cache snooptag     */
+
+       /* I-cache state */
+/*0x50*/u64 icache_data[8];    /* The actual insns + predecode */
+/*0x90*/u64 icache_index;      /* I-cache index        */
+/*0x98*/u64 icache_tag;                /* I-cache phys tag     */
+/*0xa0*/u64 icache_utag;       /* I-cache microtag     */
+/*0xa8*/u64 icache_stag;       /* I-cache snooptag     */
+/*0xb0*/u64 icache_upper;      /* I-cache upper-tag    */
+/*0xb8*/u64 icache_lower;      /* I-cache lower-tag    */
+
+       /* E-cache state */
+/*0xc0*/u64 ecache_data[4];    /* 32 bytes from staging registers */
+/*0xe0*/u64 ecache_index;      /* E-cache index        */
+/*0xe8*/u64 ecache_tag;                /* E-cache tag/state    */
+
+/*0xf0*/u64 __pad[32 - 30];
+};
+#define CHAFSR_INVALID         ((u64)-1L)
+
+/* This is allocated at boot time based upon the largest hardware
+ * cpu ID in the system.  We allocate two entries per cpu, one for
+ * TL==0 logging and one for TL >= 1 logging.
+ */
+extern struct cheetah_err_info *cheetah_error_log;
+
+/* UPA nodes send interrupt packet to UltraSparc with first data reg
+ * value low 5 (7 on Starfire) bits holding the IRQ identifier being
+ * delivered.  We must translate this into a non-vector IRQ so we can
+ * set the softint on this cpu.
+ *
+ * To make processing these packets efficient and race free we use
+ * an array of irq buckets below.  The interrupt vector handler in
+ * entry.S feeds incoming packets into per-cpu pil-indexed lists.
+ *
+ * If you make changes to ino_bucket, please update hand coded assembler
+ * of the vectored interrupt trap handler(s) in entry.S and sun4v_ivec.S
+ */
+struct ino_bucket {
+/*0x00*/unsigned long __irq_chain_pa;
+
+       /* Virtual interrupt number assigned to this INO.  */
+/*0x08*/unsigned int __virt_irq;
+/*0x0c*/unsigned int __pad;
+};
+
+extern struct ino_bucket *ivector_table;
+extern unsigned long ivector_table_pa;
+
+extern void handler_irq(int irq, struct pt_regs *regs);
+extern void init_irqwork_curcpu(void);
+extern void __cpuinit sun4v_register_mondo_queues(int this_cpu);
+
+#endif /* _ENTRY_H */
index fbaab34..b781d3d 100644 (file)
@@ -626,7 +626,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
 iommu_map_failed:
        for_each_sg(sglist, s, nelems, i) {
                if (s->dma_length != 0) {
-                       unsigned long vaddr, npages, entry, i;
+                       unsigned long vaddr, npages, entry, j;
                        iopte_t *base;
 
                        vaddr = s->dma_address & IO_PAGE_MASK;
@@ -637,8 +637,8 @@ iommu_map_failed:
                                >> IO_PAGE_SHIFT;
                        base = iommu->page_table + entry;
 
-                       for (i = 0; i < npages; i++)
-                               iopte_make_dummy(iommu, base + i);
+                       for (j = 0; j < npages; j++)
+                               iopte_make_dummy(iommu, base + j);
 
                        s->dma_address = DMA_ERROR_CODE;
                        s->dma_length = 0;
@@ -803,7 +803,7 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
        spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
-const struct dma_ops sun4u_dma_ops = {
+static const struct dma_ops sun4u_dma_ops = {
        .alloc_coherent         = dma_4u_alloc_coherent,
        .free_coherent          = dma_4u_free_coherent,
        .map_single             = dma_4u_map_single,
index 5ec06c8..eb88bd6 100644 (file)
 #include <asm/hypervisor.h>
 #include <asm/cacheflush.h>
 
-/* UPA nodes send interrupt packet to UltraSparc with first data reg
- * value low 5 (7 on Starfire) bits holding the IRQ identifier being
- * delivered.  We must translate this into a non-vector IRQ so we can
- * set the softint on this cpu.
- *
- * To make processing these packets efficient and race free we use
- * an array of irq buckets below.  The interrupt vector handler in
- * entry.S feeds incoming packets into per-cpu pil-indexed lists.
- *
- * If you make changes to ino_bucket, please update hand coded assembler
- * of the vectored interrupt trap handler(s) in entry.S and sun4v_ivec.S
- */
-struct ino_bucket {
-/*0x00*/unsigned long __irq_chain_pa;
-
-       /* Virtual interrupt number assigned to this INO.  */
-/*0x08*/unsigned int __virt_irq;
-/*0x0c*/unsigned int __pad;
-};
+#include "entry.h"
 
 #define NUM_IVECS      (IMAP_INR + 1)
+
 struct ino_bucket *ivector_table;
 unsigned long ivector_table_pa;
 
index 9a1ba1f..aaae865 100644 (file)
@@ -35,6 +35,9 @@
 #include <asm/spitfire.h>
 #include <asm/page.h>
 #include <asm/cpudata.h>
+#include <asm/cacheflush.h>
+
+#include "entry.h"
 
 /* #define ALLOW_INIT_TRACING */
 
@@ -67,6 +70,8 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
        if (tlb_type == hypervisor)
                return;
 
+       preempt_disable();
+
 #ifdef DCACHE_ALIASING_POSSIBLE
        /* If bit 13 of the kernel address we used to access the
         * user page is the same as the virtual address that page
@@ -105,6 +110,8 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
                for (; start < end; start += icache_line_size)
                        flushi(start);
        }
+
+       preempt_enable();
 }
 
 enum sparc_regset {
@@ -382,6 +389,7 @@ static const struct user_regset_view user_sparc64_view = {
        .regsets = sparc64_regsets, .n = ARRAY_SIZE(sparc64_regsets)
 };
 
+#ifdef CONFIG_COMPAT
 static int genregs32_get(struct task_struct *target,
                         const struct user_regset *regset,
                         unsigned int pos, unsigned int count,
@@ -676,14 +684,18 @@ static const struct user_regset_view user_sparc32_view = {
        .name = "sparc", .e_machine = EM_SPARC,
        .regsets = sparc32_regsets, .n = ARRAY_SIZE(sparc32_regsets)
 };
+#endif /* CONFIG_COMPAT */
 
 const struct user_regset_view *task_user_regset_view(struct task_struct *task)
 {
+#ifdef CONFIG_COMPAT
        if (test_tsk_thread_flag(task, TIF_32BIT))
                return &user_sparc32_view;
+#endif
        return &user_sparc64_view;
 }
 
+#ifdef CONFIG_COMPAT
 struct compat_fps {
        unsigned int regs[32];
        unsigned int fsr;
@@ -798,6 +810,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
 
        return ret;
 }
+#endif /* CONFIG_COMPAT */
 
 struct fps {
        unsigned int regs[64];
@@ -807,11 +820,14 @@ struct fps {
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
        const struct user_regset_view *view = task_user_regset_view(child);
-       struct pt_regs __user *pregs = (struct pt_regs __user *) addr;
        unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
-       struct fps __user *fps = (struct fps __user *) addr;
+       struct pt_regs __user *pregs;
+       struct fps __user *fps;
        int ret;
 
+       pregs = (struct pt_regs __user *) (unsigned long) addr;
+       fps = (struct fps __user *) (unsigned long) addr;
+
        switch (request) {
        case PTRACE_PEEKUSR:
                ret = (addr != 0) ? -EIO : 0;
index d036dbe..6acb4c5 100644 (file)
@@ -51,6 +51,8 @@
 #include <net/ipconfig.h>
 #endif
 
+#include "entry.h"
+
 /* Used to synchronize accesses to NatSemi SUPER I/O chip configure
  * operations in asm/ns87303.h
  */
@@ -335,9 +337,6 @@ void __init setup_arch(char **cmdline_p)
 
 /* BUFFER is PAGE_SIZE bytes long. */
 
-extern char *sparc_cpu_type;
-extern char *sparc_fpu_type;
-
 extern void smp_info(struct seq_file *);
 extern void smp_bogo(struct seq_file *);
 extern void mmu_info(struct seq_file *);
index fb13775..94a9d64 100644 (file)
@@ -32,6 +32,9 @@
 #include <asm/siginfo.h>
 #include <asm/visasm.h>
 
+#include "entry.h"
+#include "systbls.h"
+
 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
 
 /* {set, get}context() needed for 64-bit SparcLinux userland. */
index 5a1126b..59f020d 100644 (file)
@@ -1,6 +1,6 @@
 /* smp.c: Sparc64 SMP support.
  *
- * Copyright (C) 1997, 2007 David S. Miller (davem@davemloft.net)
+ * Copyright (C) 1997, 2007, 2008 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/module.h>
@@ -30,6 +30,7 @@
 #include <asm/cpudata.h>
 #include <asm/hvtramp.h>
 #include <asm/io.h>
+#include <asm/timer.h>
 
 #include <asm/irq.h>
 #include <asm/irq_regs.h>
index 47f92a5..84d39e8 100644 (file)
@@ -2,13 +2,15 @@
 #include <linux/stacktrace.h>
 #include <linux/thread_info.h>
 #include <asm/ptrace.h>
+#include <asm/stacktrace.h>
 
 void save_stack_trace(struct stack_trace *trace)
 {
        unsigned long ksp, fp, thread_base;
        struct thread_info *tp = task_thread_info(current);
 
-       flushw_all();
+       stack_trace_flush();
+
        __asm__ __volatile__(
                "mov    %%fp, %0"
                : "=r" (ksp)
index 134d801..f952745 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: sys_sparc.c,v 1.57 2002/02/09 19:49:30 davem Exp $
- * linux/arch/sparc64/kernel/sys_sparc.c
+/* linux/arch/sparc64/kernel/sys_sparc.c
  *
  * This file contains various random system calls that
  * have a non-standard calling sequence on the Linux/sparc
@@ -30,6 +29,9 @@
 #include <asm/perfctr.h>
 #include <asm/unistd.h>
 
+#include "entry.h"
+#include "systbls.h"
+
 /* #define DEBUG_UNIMP_SYSCALL */
 
 asmlinkage unsigned long sys_getpagesize(void)
@@ -445,7 +447,8 @@ asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second,
                        goto out;
                case SEMTIMEDOP:
                        err = sys_semtimedop(first, ptr, (unsigned)second,
-                               (const struct timespec __user *) fifth);
+                               (const struct timespec __user *)
+                                            (unsigned long) fifth);
                        goto out;
                case SEMGET:
                        err = sys_semget(first, (int)second, (int)third);
@@ -788,7 +791,7 @@ asmlinkage long sys_utrap_install(utrap_entry_t type,
        } else {
                if ((utrap_handler_t)current_thread_info()->utraps[type] != new_p &&
                    current_thread_info()->utraps[0] > 1) {
-                       long *p = current_thread_info()->utraps;
+                       unsigned long *p = current_thread_info()->utraps;
 
                        current_thread_info()->utraps =
                                kmalloc((UT_TRAP_INSTRUCTION_31+1)*sizeof(long),
@@ -816,7 +819,8 @@ asmlinkage long sys_utrap_install(utrap_entry_t type,
        return 0;
 }
 
-long sparc_memory_ordering(unsigned long model, struct pt_regs *regs)
+asmlinkage long sparc_memory_ordering(unsigned long model,
+                                     struct pt_regs *regs)
 {
        if (model >= 3)
                return -EINVAL;
diff --git a/arch/sparc64/kernel/systbls.h b/arch/sparc64/kernel/systbls.h
new file mode 100644 (file)
index 0000000..8a0d20a
--- /dev/null
@@ -0,0 +1,53 @@
+#ifndef _SYSTBLS_H
+#define _SYSTBLS_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/utsname.h>
+#include <asm/utrap.h>
+#include <asm/signal.h>
+
+extern asmlinkage unsigned long sys_getpagesize(void);
+extern asmlinkage unsigned long sparc_brk(unsigned long brk);
+extern asmlinkage long sparc_pipe(struct pt_regs *regs);
+extern asmlinkage long sys_ipc(unsigned int call, int first,
+                              unsigned long second,
+                              unsigned long third,
+                              void __user *ptr, long fifth);
+extern asmlinkage long sparc64_newuname(struct new_utsname __user *name);
+extern asmlinkage long sparc64_personality(unsigned long personality);
+extern asmlinkage unsigned long sys_mmap(unsigned long addr, unsigned long len,
+                                        unsigned long prot, unsigned long flags,
+                                        unsigned long fd, unsigned long off);
+extern asmlinkage long sys64_munmap(unsigned long addr, size_t len);
+extern asmlinkage unsigned long sys64_mremap(unsigned long addr,
+                                            unsigned long old_len,
+                                            unsigned long new_len,
+                                            unsigned long flags,
+                                            unsigned long new_addr);
+extern asmlinkage unsigned long c_sys_nis_syscall(struct pt_regs *regs);
+extern asmlinkage long sys_getdomainname(char __user *name, int len);
+extern asmlinkage long solaris_syscall(struct pt_regs *regs);
+extern asmlinkage long sunos_syscall(struct pt_regs *regs);
+extern asmlinkage long sys_utrap_install(utrap_entry_t type,
+                                        utrap_handler_t new_p,
+                                        utrap_handler_t new_d,
+                                        utrap_handler_t __user *old_p,
+                                        utrap_handler_t __user *old_d);
+extern asmlinkage long sparc_memory_ordering(unsigned long model,
+                                            struct pt_regs *regs);
+extern asmlinkage long sys_rt_sigaction(int sig,
+                                       const struct sigaction __user *act,
+                                       struct sigaction __user *oact,
+                                       void __user *restorer,
+                                       size_t sigsetsize);
+extern asmlinkage long sys_perfctr(int opcode, unsigned long arg0,
+                                  unsigned long arg1, unsigned long arg2);
+
+extern asmlinkage void sparc64_set_context(struct pt_regs *regs);
+extern asmlinkage void sparc64_get_context(struct pt_regs *regs);
+extern asmlinkage long sys_sigpause(unsigned int set);
+extern asmlinkage long sys_sigsuspend(old_sigset_t set);
+extern void do_rt_sigreturn(struct pt_regs *regs);
+
+#endif /* _SYSTBLS_H */
index d204f1a..e5d2389 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: time.c,v 1.42 2002/01/23 14:33:55 davem Exp $
- * time.c: UltraSparc timer and TOD clock support.
+/* time.c: UltraSparc timer and TOD clock support.
  *
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1997, 2008 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1998 Eddie C. Dost   (ecd@skynet.be)
  *
  * Based largely on code which is:
@@ -48,6 +47,8 @@
 #include <asm/uaccess.h>
 #include <asm/irq_regs.h>
 
+#include "entry.h"
+
 DEFINE_SPINLOCK(mostek_lock);
 DEFINE_SPINLOCK(rtc_lock);
 void __iomem *mstk48t02_regs = NULL;
@@ -508,6 +509,37 @@ static int __init has_low_battery(void)
        return (data1 == data2);        /* Was the write blocked? */
 }
 
+static void __init mostek_set_system_time(void __iomem *mregs)
+{
+       unsigned int year, mon, day, hour, min, sec;
+       u8 tmp;
+
+       spin_lock_irq(&mostek_lock);
+
+       /* Traditional Mostek chip. */
+       tmp = mostek_read(mregs + MOSTEK_CREG);
+       tmp |= MSTK_CREG_READ;
+       mostek_write(mregs + MOSTEK_CREG, tmp);
+
+       sec = MSTK_REG_SEC(mregs);
+       min = MSTK_REG_MIN(mregs);
+       hour = MSTK_REG_HOUR(mregs);
+       day = MSTK_REG_DOM(mregs);
+       mon = MSTK_REG_MONTH(mregs);
+       year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
+
+       xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+       xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
+       set_normalized_timespec(&wall_to_monotonic,
+                               -xtime.tv_sec, -xtime.tv_nsec);
+
+       tmp = mostek_read(mregs + MOSTEK_CREG);
+       tmp &= ~MSTK_CREG_READ;
+       mostek_write(mregs + MOSTEK_CREG, tmp);
+
+       spin_unlock_irq(&mostek_lock);
+}
+
 /* Probe for the real time clock chip. */
 static void __init set_system_time(void)
 {
@@ -520,7 +552,6 @@ static void __init set_system_time(void)
        unsigned long dregs = 0UL;
        void __iomem *bregs = 0UL;
 #endif
-       u8 tmp;
 
        if (!mregs && !dregs && !bregs) {
                prom_printf("Something wrong, clock regs not mapped yet.\n");
@@ -528,20 +559,11 @@ static void __init set_system_time(void)
        }               
 
        if (mregs) {
-               spin_lock_irq(&mostek_lock);
-
-               /* Traditional Mostek chip. */
-               tmp = mostek_read(mregs + MOSTEK_CREG);
-               tmp |= MSTK_CREG_READ;
-               mostek_write(mregs + MOSTEK_CREG, tmp);
+               mostek_set_system_time(mregs);
+               return;
+       }
 
-               sec = MSTK_REG_SEC(mregs);
-               min = MSTK_REG_MIN(mregs);
-               hour = MSTK_REG_HOUR(mregs);
-               day = MSTK_REG_DOM(mregs);
-               mon = MSTK_REG_MONTH(mregs);
-               year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
-       } else if (bregs) {
+       if (bregs) {
                unsigned char val = readb(bregs + 0x0e);
                unsigned int century;
 
@@ -596,14 +618,6 @@ static void __init set_system_time(void)
        xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
        set_normalized_timespec(&wall_to_monotonic,
                                -xtime.tv_sec, -xtime.tv_nsec);
-
-       if (mregs) {
-               tmp = mostek_read(mregs + MOSTEK_CREG);
-               tmp &= ~MSTK_CREG_READ;
-               mostek_write(mregs + MOSTEK_CREG, tmp);
-
-               spin_unlock_irq(&mostek_lock);
-       }
 }
 
 /* davem suggests we keep this within the 4M locked kernel image */
@@ -1027,7 +1041,7 @@ void __init time_init(void)
        setup_clockevent_multiplier(clock);
 
        sparc64_clockevent.max_delta_ns =
-               clockevent_delta2ns(0x7fffffffffffffff, &sparc64_clockevent);
+               clockevent_delta2ns(0x7fffffffffffffffUL, &sparc64_clockevent);
        sparc64_clockevent.min_delta_ns =
                clockevent_delta2ns(0xF, &sparc64_clockevent);
 
index 007f531..96da847 100644 (file)
@@ -42,6 +42,7 @@
 #endif
 #include <asm/prom.h>
 
+#include "entry.h"
 
 /* When an irrecoverable trap occurs at tl > 0, the trap entry
  * code logs the trap state registers at every level in the trap
@@ -77,11 +78,6 @@ static void dump_tl1_traplog(struct tl1_traplog *p)
        }
 }
 
-void do_call_debug(struct pt_regs *regs) 
-{ 
-       notify_die(DIE_CALL, "debug call", regs, 0, 255, SIGINT); 
-}
-
 void bad_trap(struct pt_regs *regs, long lvl)
 {
        char buffer[32];
@@ -550,41 +546,6 @@ static unsigned long ecache_flush_physbase;
 static unsigned long ecache_flush_linesize;
 static unsigned long ecache_flush_size;
 
-/* WARNING: The error trap handlers in assembly know the precise
- *         layout of the following structure.
- *
- * C-level handlers below use this information to log the error
- * and then determine how to recover (if possible).
- */
-struct cheetah_err_info {
-/*0x00*/u64 afsr;
-/*0x08*/u64 afar;
-
-       /* D-cache state */
-/*0x10*/u64 dcache_data[4];    /* The actual data      */
-/*0x30*/u64 dcache_index;      /* D-cache index        */
-/*0x38*/u64 dcache_tag;                /* D-cache tag/valid    */
-/*0x40*/u64 dcache_utag;       /* D-cache microtag     */
-/*0x48*/u64 dcache_stag;       /* D-cache snooptag     */
-
-       /* I-cache state */
-/*0x50*/u64 icache_data[8];    /* The actual insns + predecode */
-/*0x90*/u64 icache_index;      /* I-cache index        */
-/*0x98*/u64 icache_tag;                /* I-cache phys tag     */
-/*0xa0*/u64 icache_utag;       /* I-cache microtag     */
-/*0xa8*/u64 icache_stag;       /* I-cache snooptag     */
-/*0xb0*/u64 icache_upper;      /* I-cache upper-tag    */
-/*0xb8*/u64 icache_lower;      /* I-cache lower-tag    */
-
-       /* E-cache state */
-/*0xc0*/u64 ecache_data[4];    /* 32 bytes from staging registers */
-/*0xe0*/u64 ecache_index;      /* E-cache index        */
-/*0xe8*/u64 ecache_tag;                /* E-cache tag/state    */
-
-/*0xf0*/u64 __pad[32 - 30];
-};
-#define CHAFSR_INVALID         ((u64)-1L)
-
 /* This table is ordered in priority of errors and matches the
  * AFAR overwrite policy as well.
  */
@@ -758,10 +719,6 @@ static struct afsr_error_table __jalapeno_error_table[] = {
 static struct afsr_error_table *cheetah_error_table;
 static unsigned long cheetah_afsr_errors;
 
-/* This is allocated at boot time based upon the largest hardware
- * cpu ID in the system.  We allocate two entries per cpu, one for
- * TL==0 logging and one for TL >= 1 logging.
- */
 struct cheetah_err_info *cheetah_error_log;
 
 static inline struct cheetah_err_info *cheetah_get_error_log(unsigned long afsr)
@@ -2102,7 +2059,7 @@ void do_div0(struct pt_regs *regs)
        force_sig_info(SIGFPE, &info, current);
 }
 
-void instruction_dump (unsigned int *pc)
+static void instruction_dump(unsigned int *pc)
 {
        int i;
 
@@ -2115,7 +2072,7 @@ void instruction_dump (unsigned int *pc)
        printk("\n");
 }
 
-static void user_instruction_dump (unsigned int __user *pc)
+static void user_instruction_dump(unsigned int __user *pc)
 {
        int i;
        unsigned int buf[9];
index 466fd6c..f37078d 100644 (file)
@@ -46,6 +46,7 @@
 #include <asm/prom.h>
 #include <asm/sstate.h>
 #include <asm/mdesc.h>
+#include <asm/cpudata.h>
 
 #define MAX_PHYS_ADDRESS       (1UL << 42UL)
 #define KPTE_BITMAP_CHUNK_SZ   (256UL * 1024UL * 1024UL)
@@ -1273,10 +1274,6 @@ void __cpuinit sun4v_ktsb_register(void)
 
 /* paging_init() sets up the page tables */
 
-extern void cheetah_ecache_flush_init(void);
-extern void sun4v_patch_tlb_handlers(void);
-
-extern void cpu_probe(void);
 extern void central_probe(void);
 
 static unsigned long last_valid_pfn;
index 3f10fc9..a0f000b 100644 (file)
@@ -23,10 +23,11 @@ DEFINE_PER_CPU(struct mmu_gather, mmu_gathers) = { 0, };
 
 void flush_tlb_pending(void)
 {
-       struct mmu_gather *mp = &__get_cpu_var(mmu_gathers);
+       struct mmu_gather *mp;
 
        preempt_disable();
 
+       mp = &__get_cpu_var(mmu_gathers);
        if (mp->tlb_nr) {
                flush_tsb_user(mp);
 
index 1e8f41a..1d43bdf 100644 (file)
@@ -256,11 +256,7 @@ static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
 
 static void uml_net_set_multicast_list(struct net_device *dev)
 {
-       if (dev->flags & IFF_PROMISC)
-               return;
-       else if (dev->mc_count)
-               dev->flags |= IFF_ALLMULTI;
-       else dev->flags &= ~IFF_ALLMULTI;
+       return;
 }
 
 static void uml_net_tx_timeout(struct net_device *dev)
index f2b5a62..8a85c93 100644 (file)
@@ -63,7 +63,7 @@ static struct cpufreq_frequency_table speedstep_freqs[] = {
  */
 static int speedstep_smi_ownership (void)
 {
-       u32 command, result, magic;
+       u32 command, result, magic, dummy;
        u32 function = GET_SPEEDSTEP_OWNER;
        unsigned char magic_data[] = "Copyright (c) 1999 Intel Corporation";
 
@@ -73,8 +73,11 @@ static int speedstep_smi_ownership (void)
        dprintk("trying to obtain ownership with command %x at port %x\n", command, smi_port);
 
        __asm__ __volatile__(
+               "push %%ebp\n"
                "out %%al, (%%dx)\n"
-               : "=D" (result)
+               "pop %%ebp\n"
+               : "=D" (result), "=a" (dummy), "=b" (dummy), "=c" (dummy), "=d" (dummy),
+                       "=S" (dummy)
                : "a" (command), "b" (function), "c" (0), "d" (smi_port),
                        "D" (0), "S" (magic)
                : "memory"
@@ -96,7 +99,7 @@ static int speedstep_smi_ownership (void)
  */
 static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
 {
-       u32 command, result = 0, edi, high_mhz, low_mhz;
+       u32 command, result = 0, edi, high_mhz, low_mhz, dummy;
        u32 state=0;
        u32 function = GET_SPEEDSTEP_FREQS;
 
@@ -109,10 +112,12 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
 
        dprintk("trying to determine frequencies with command %x at port %x\n", command, smi_port);
 
-       __asm__ __volatile__("movl $0, %%edi\n"
+       __asm__ __volatile__(
+               "push %%ebp\n"
                "out %%al, (%%dx)\n"
-               : "=a" (result), "=b" (high_mhz), "=c" (low_mhz), "=d" (state), "=D" (edi)
-               : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0)
+               "pop %%ebp"
+               : "=a" (result), "=b" (high_mhz), "=c" (low_mhz), "=d" (state), "=D" (edi), "=S" (dummy)
+               : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0), "D" (0)
        );
 
        dprintk("result %x, low_freq %u, high_freq %u\n", result, low_mhz, high_mhz);
@@ -135,16 +140,18 @@ static int speedstep_smi_get_freqs (unsigned int *low, unsigned int *high)
 static int speedstep_get_state (void)
 {
        u32 function=GET_SPEEDSTEP_STATE;
-       u32 result, state, edi, command;
+       u32 result, state, edi, command, dummy;
 
        command = (smi_sig & 0xffffff00) | (smi_cmd & 0xff);
 
        dprintk("trying to determine current setting with command %x at port %x\n", command, smi_port);
 
-       __asm__ __volatile__("movl $0, %%edi\n"
+       __asm__ __volatile__(
+               "push %%ebp\n"
                "out %%al, (%%dx)\n"
-               : "=a" (result), "=b" (state), "=D" (edi)
-               : "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0)
+               "pop %%ebp\n"
+               : "=a" (result), "=b" (state), "=D" (edi), "=c" (dummy), "=d" (dummy), "=S" (dummy)
+               : "a" (command), "b" (function), "c" (0), "d" (smi_port), "S" (0), "D" (0)
        );
 
        dprintk("state is %x, result is %x\n", state, result);
@@ -160,7 +167,7 @@ static int speedstep_get_state (void)
  */
 static void speedstep_set_state (unsigned int state)
 {
-       unsigned int result = 0, command, new_state;
+       unsigned int result = 0, command, new_state, dummy;
        unsigned long flags;
        unsigned int function=SET_SPEEDSTEP_STATE;
        unsigned int retry = 0;
@@ -182,10 +189,12 @@ static void speedstep_set_state (unsigned int state)
                }
                retry++;
                __asm__ __volatile__(
-                       "movl $0, %%edi\n"
+                       "push %%ebp\n"
                        "out %%al, (%%dx)\n"
-                       : "=b" (new_state), "=D" (result)
-                       : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0)
+                       "pop %%ebp"
+                       : "=b" (new_state), "=D" (result), "=c" (dummy), "=a" (dummy),
+                               "=d" (dummy), "=S" (dummy)
+                       : "a" (command), "b" (function), "c" (state), "d" (smi_port), "S" (0), "D" (0)
                        );
        } while ((new_state != state) && (retry <= SMI_TRIES));
 
@@ -195,7 +204,7 @@ static void speedstep_set_state (unsigned int state)
        if (new_state == state) {
                dprintk("change to %u MHz succeeded after %u tries with result %u\n", (speedstep_freqs[new_state].frequency / 1000), retry, result);
        } else {
-               printk(KERN_ERR "cpufreq: change failed with new_state %u and result %u\n", new_state, result);
+               printk(KERN_ERR "cpufreq: change to state %u failed with new_state %u and result %u\n", state, new_state, result);
        }
 
        return;
index 103d61a..3e18db4 100644 (file)
@@ -176,12 +176,13 @@ static inline void k8_enable_fixed_iorrs(void)
 }
 
 /**
- * Checks and updates an fixed-range MTRR if it differs from the value it
- * should have. If K8 extentions are wanted, update the K8 SYSCFG MSR also.
- * see AMD publication no. 24593, chapter 7.8.1, page 233 for more information
- * \param msr MSR address of the MTTR which should be checked and updated
- * \param changed pointer which indicates whether the MTRR needed to be changed
- * \param msrwords pointer to the MSR values which the MSR should have
+ * set_fixed_range - checks & updates a fixed-range MTRR if it differs from the value it should have
+ * @msr: MSR address of the MTTR which should be checked and updated
+ * @changed: pointer which indicates whether the MTRR needed to be changed
+ * @msrwords: pointer to the MSR values which the MSR should have
+ *
+ * If K8 extentions are wanted, update the K8 SYSCFG MSR also.
+ * See AMD publication no. 24593, chapter 7.8.1, page 233 for more information.
  */
 static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords)
 {
@@ -199,12 +200,15 @@ static void set_fixed_range(int msr, bool *changed, unsigned int *msrwords)
        }
 }
 
+/**
+ * generic_get_free_region - Get a free MTRR.
+ * @base: The starting (base) address of the region.
+ * @size: The size (in bytes) of the region.
+ * @replace_reg: mtrr index to be replaced; set to invalid value if none.
+ *
+ * Returns: The index of the region on success, else negative on error.
+ */
 int generic_get_free_region(unsigned long base, unsigned long size, int replace_reg)
-/*  [SUMMARY] Get a free MTRR.
-    <base> The starting (base) address of the region.
-    <size> The size (in bytes) of the region.
-    [RETURNS] The index of the region on success, else -1 on error.
-*/
 {
        int i, max;
        mtrr_type ltype;
@@ -249,8 +253,8 @@ static void generic_get_mtrr(unsigned int reg, unsigned long *base,
 }
 
 /**
- * Checks and updates the fixed-range MTRRs if they differ from the saved set
- * \param frs pointer to fixed-range MTRR values, saved by get_fixed_ranges()
+ * set_fixed_ranges - checks & updates the fixed-range MTRRs if they differ from the saved set
+ * @frs: pointer to fixed-range MTRR values, saved by get_fixed_ranges()
  */
 static int set_fixed_ranges(mtrr_type * frs)
 {
@@ -294,13 +298,13 @@ static bool set_mtrr_var_ranges(unsigned int index, struct mtrr_var_range *vr)
 
 static u32 deftype_lo, deftype_hi;
 
+/**
+ * set_mtrr_state - Set the MTRR state for this CPU.
+ *
+ * NOTE: The CPU must already be in a safe state for MTRR changes.
+ * RETURNS: 0 if no changes made, else a mask indicating what was changed.
+ */
 static unsigned long set_mtrr_state(void)
-/*  [SUMMARY] Set the MTRR state for this CPU.
-    <state> The MTRR state information to read.
-    <ctxt> Some relevant CPU context.
-    [NOTE] The CPU must already be in a safe state for MTRR changes.
-    [RETURNS] 0 if no changes made, else a mask indication what was changed.
-*/
 {
        unsigned int i;
        unsigned long change_mask = 0;
index c706a30..5921e5f 100644 (file)
@@ -78,6 +78,14 @@ static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
        },
        {
                .callback       = dmi_io_delay_0xed_port,
+               .ident          = "HP Pavilion dv6000",
+               .matches        = {
+                       DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
+                       DMI_MATCH(DMI_BOARD_NAME, "30B8")
+               }
+       },
+       {
+               .callback       = dmi_io_delay_0xed_port,
                .ident          = "HP Pavilion tx1000",
                .matches        = {
                        DMI_MATCH(DMI_BOARD_VENDOR, "Quanta"),
index 027fc06..b402c0f 100644 (file)
@@ -30,6 +30,7 @@
 
 #include <linux/kernel.h>
 #include <linux/interrupt.h>
+#include <linux/module.h>
 #include <asm/geode.h>
 
 static struct mfgpt_timer_t {
index d5904ee..eb92ccb 100644 (file)
@@ -600,21 +600,6 @@ static int ptrace_bts_read_record(struct task_struct *child,
        return sizeof(ret);
 }
 
-static int ptrace_bts_write_record(struct task_struct *child,
-                                  const struct bts_struct *in)
-{
-       int retval;
-
-       if (!child->thread.ds_area_msr)
-               return -ENXIO;
-
-       retval = ds_write_bts((void *)child->thread.ds_area_msr, in);
-       if (retval)
-               return retval;
-
-       return sizeof(*in);
-}
-
 static int ptrace_bts_clear(struct task_struct *child)
 {
        if (!child->thread.ds_area_msr)
@@ -657,75 +642,6 @@ static int ptrace_bts_drain(struct task_struct *child,
        return end;
 }
 
-static int ptrace_bts_realloc(struct task_struct *child,
-                             int size, int reduce_size)
-{
-       unsigned long rlim, vm;
-       int ret, old_size;
-
-       if (size < 0)
-               return -EINVAL;
-
-       old_size = ds_get_bts_size((void *)child->thread.ds_area_msr);
-       if (old_size < 0)
-               return old_size;
-
-       ret = ds_free((void **)&child->thread.ds_area_msr);
-       if (ret < 0)
-               goto out;
-
-       size >>= PAGE_SHIFT;
-       old_size >>= PAGE_SHIFT;
-
-       current->mm->total_vm  -= old_size;
-       current->mm->locked_vm -= old_size;
-
-       if (size == 0)
-               goto out;
-
-       rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
-       vm = current->mm->total_vm  + size;
-       if (rlim < vm) {
-               ret = -ENOMEM;
-
-               if (!reduce_size)
-                       goto out;
-
-               size = rlim - current->mm->total_vm;
-               if (size <= 0)
-                       goto out;
-       }
-
-       rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
-       vm = current->mm->locked_vm  + size;
-       if (rlim < vm) {
-               ret = -ENOMEM;
-
-               if (!reduce_size)
-                       goto out;
-
-               size = rlim - current->mm->locked_vm;
-               if (size <= 0)
-                       goto out;
-       }
-
-       ret = ds_allocate((void **)&child->thread.ds_area_msr,
-                         size << PAGE_SHIFT);
-       if (ret < 0)
-               goto out;
-
-       current->mm->total_vm  += size;
-       current->mm->locked_vm += size;
-
-out:
-       if (child->thread.ds_area_msr)
-               set_tsk_thread_flag(child, TIF_DS_AREA_MSR);
-       else
-               clear_tsk_thread_flag(child, TIF_DS_AREA_MSR);
-
-       return ret;
-}
-
 static int ptrace_bts_config(struct task_struct *child,
                             long cfg_size,
                             const struct ptrace_bts_config __user *ucfg)
@@ -828,6 +744,91 @@ static int ptrace_bts_status(struct task_struct *child,
        return sizeof(cfg);
 }
 
+
+static int ptrace_bts_write_record(struct task_struct *child,
+                                  const struct bts_struct *in)
+{
+       int retval;
+
+       if (!child->thread.ds_area_msr)
+               return -ENXIO;
+
+       retval = ds_write_bts((void *)child->thread.ds_area_msr, in);
+       if (retval)
+               return retval;
+
+       return sizeof(*in);
+}
+
+static int ptrace_bts_realloc(struct task_struct *child,
+                             int size, int reduce_size)
+{
+       unsigned long rlim, vm;
+       int ret, old_size;
+
+       if (size < 0)
+               return -EINVAL;
+
+       old_size = ds_get_bts_size((void *)child->thread.ds_area_msr);
+       if (old_size < 0)
+               return old_size;
+
+       ret = ds_free((void **)&child->thread.ds_area_msr);
+       if (ret < 0)
+               goto out;
+
+       size >>= PAGE_SHIFT;
+       old_size >>= PAGE_SHIFT;
+
+       current->mm->total_vm  -= old_size;
+       current->mm->locked_vm -= old_size;
+
+       if (size == 0)
+               goto out;
+
+       rlim = current->signal->rlim[RLIMIT_AS].rlim_cur >> PAGE_SHIFT;
+       vm = current->mm->total_vm  + size;
+       if (rlim < vm) {
+               ret = -ENOMEM;
+
+               if (!reduce_size)
+                       goto out;
+
+               size = rlim - current->mm->total_vm;
+               if (size <= 0)
+                       goto out;
+       }
+
+       rlim = current->signal->rlim[RLIMIT_MEMLOCK].rlim_cur >> PAGE_SHIFT;
+       vm = current->mm->locked_vm  + size;
+       if (rlim < vm) {
+               ret = -ENOMEM;
+
+               if (!reduce_size)
+                       goto out;
+
+               size = rlim - current->mm->locked_vm;
+               if (size <= 0)
+                       goto out;
+       }
+
+       ret = ds_allocate((void **)&child->thread.ds_area_msr,
+                         size << PAGE_SHIFT);
+       if (ret < 0)
+               goto out;
+
+       current->mm->total_vm  += size;
+       current->mm->locked_vm += size;
+
+out:
+       if (child->thread.ds_area_msr)
+               set_tsk_thread_flag(child, TIF_DS_AREA_MSR);
+       else
+               clear_tsk_thread_flag(child, TIF_DS_AREA_MSR);
+
+       return ret;
+}
+
 void ptrace_bts_take_timestamp(struct task_struct *tsk,
                               enum bts_qualifier qualifier)
 {
index a1d7071..2b3e5d4 100644 (file)
@@ -406,8 +406,6 @@ static unsigned long __init setup_memory(void)
         */
        min_low_pfn = PFN_UP(init_pg_tables_end);
 
-       find_max_pfn();
-
        max_low_pfn = find_max_low_pfn();
 
 #ifdef CONFIG_HIGHMEM
@@ -764,12 +762,13 @@ void __init setup_arch(char **cmdline_p)
        if (efi_enabled)
                efi_init();
 
-       max_low_pfn = setup_memory();
-
        /* update e820 for memory not covered by WB MTRRs */
+       find_max_pfn();
        mtrr_bp_init();
        if (mtrr_trim_uncached_memory(max_pfn))
-               max_low_pfn = setup_memory();
+               find_max_pfn();
+
+       max_low_pfn = setup_memory();
 
 #ifdef CONFIG_VMI
        /*
index 7637dc9..f4f7ecf 100644 (file)
@@ -801,7 +801,7 @@ static void __cpuinit srat_detect_node(void)
        /* Don't do the funky fallback heuristics the AMD version employs
           for now. */
        node = apicid_to_node[apicid];
-       if (node == NUMA_NO_NODE)
+       if (node == NUMA_NO_NODE || !node_online(node))
                node = first_node(node_online_map);
        numa_set_node(cpu, node);
 
index a104c53..3335b45 100644 (file)
  * (such as the example in Documentation/lguest/lguest.c) is called the
  * Launcher.
  *
- * Secondly, we only run specially modified Guests, not normal kernels.  When
- * you set CONFIG_LGUEST to 'y' or 'm', this automatically sets
- * CONFIG_LGUEST_GUEST=y, which compiles this file into the kernel so it knows
- * how to be a Guest.  This means that you can use the same kernel you boot
- * normally (ie. as a Host) as a Guest.
+ * Secondly, we only run specially modified Guests, not normal kernels: setting
+ * CONFIG_LGUEST_GUEST to "y" compiles this file into the kernel so it knows
+ * how to be a Guest at boot time.  This means that you can use the same kernel
+ * you boot normally (ie. as a Host) as a Guest.
  *
  * These Guests know that they cannot do privileged operations, such as disable
  * interrupts, and that they have to ask the Host to do such things explicitly.
  * This file consists of all the replacements for such low-level native
  * hardware operations: these special Guest versions call the Host.
  *
- * So how does the kernel know it's a Guest?  The Guest starts at a special
- * entry point marked with a magic string, which sets up a few things then
- * calls here.  We replace the native functions various "paravirt" structures
- * with our Guest versions, then boot like normal. :*/
+ * So how does the kernel know it's a Guest?  We'll see that later, but let's
+ * just say that we end up here where we replace the native functions various
+ * "paravirt" structures with our Guest versions, then boot like normal. :*/
 
 /*
  * Copyright (C) 2006, Rusty Russell <rusty@rustcorp.com.au> IBM Corporation.
@@ -134,7 +132,7 @@ static void async_hcall(unsigned long call, unsigned long arg1,
  * lguest_leave_lazy_mode().
  *
  * So, when we're in lazy mode, we call async_hcall() to store the call for
- * future processing. */
+ * future processing: */
 static void lazy_hcall(unsigned long call,
                       unsigned long arg1,
                       unsigned long arg2,
@@ -147,7 +145,7 @@ static void lazy_hcall(unsigned long call,
 }
 
 /* When lazy mode is turned off reset the per-cpu lazy mode variable and then
- * issue a hypercall to flush any stored calls. */
+ * issue the do-nothing hypercall to flush any stored calls. */
 static void lguest_leave_lazy_mode(void)
 {
        paravirt_leave_lazy(paravirt_get_lazy_mode());
@@ -164,7 +162,7 @@ static void lguest_leave_lazy_mode(void)
  *
  * So instead we keep an "irq_enabled" field inside our "struct lguest_data",
  * which the Guest can update with a single instruction.  The Host knows to
- * check there when it wants to deliver an interrupt.
+ * check there before it tries to deliver an interrupt.
  */
 
 /* save_flags() is expected to return the processor state (ie. "flags").  The
@@ -196,10 +194,15 @@ static void irq_enable(void)
 /*M:003 Note that we don't check for outstanding interrupts when we re-enable
  * them (or when we unmask an interrupt).  This seems to work for the moment,
  * since interrupts are rare and we'll just get the interrupt on the next timer
- * tick, but when we turn on CONFIG_NO_HZ, we should revisit this.  One way
+ * tick, but now we can run with CONFIG_NO_HZ, we should revisit this.  One way
  * would be to put the "irq_enabled" field in a page by itself, and have the
  * Host write-protect it when an interrupt comes in when irqs are disabled.
- * There will then be a page fault as soon as interrupts are re-enabled. :*/
+ * There will then be a page fault as soon as interrupts are re-enabled.
+ *
+ * A better method is to implement soft interrupt disable generally for x86:
+ * instead of disabling interrupts, we set a flag.  If an interrupt does come
+ * in, we then disable them for real.  This is uncommon, so we could simply use
+ * a hypercall for interrupt control and not worry about efficiency. :*/
 
 /*G:034
  * The Interrupt Descriptor Table (IDT).
@@ -212,6 +215,10 @@ static void irq_enable(void)
 static void lguest_write_idt_entry(gate_desc *dt,
                                   int entrynum, const gate_desc *g)
 {
+       /* The gate_desc structure is 8 bytes long: we hand it to the Host in
+        * two 32-bit chunks.  The whole 32-bit kernel used to hand descriptors
+        * around like this; typesafety wasn't a big concern in Linux's early
+        * years. */
        u32 *desc = (u32 *)g;
        /* Keep the local copy up to date. */
        native_write_idt_entry(dt, entrynum, g);
@@ -243,7 +250,8 @@ static void lguest_load_idt(const struct desc_ptr *desc)
  *
  * This is the opposite of the IDT code where we have a LOAD_IDT_ENTRY
  * hypercall and use that repeatedly to load a new IDT.  I don't think it
- * really matters, but wouldn't it be nice if they were the same?
+ * really matters, but wouldn't it be nice if they were the same?  Wouldn't
+ * it be even better if you were the one to send the patch to fix it?
  */
 static void lguest_load_gdt(const struct desc_ptr *desc)
 {
@@ -298,9 +306,9 @@ static void lguest_load_tr_desc(void)
 
 /* The "cpuid" instruction is a way of querying both the CPU identity
  * (manufacturer, model, etc) and its features.  It was introduced before the
- * Pentium in 1993 and keeps getting extended by both Intel and AMD.  As you
- * might imagine, after a decade and a half this treatment, it is now a giant
- * ball of hair.  Its entry in the current Intel manual runs to 28 pages.
+ * Pentium in 1993 and keeps getting extended by both Intel, AMD and others.
+ * As you might imagine, after a decade and a half this treatment, it is now a
+ * giant ball of hair.  Its entry in the current Intel manual runs to 28 pages.
  *
  * This instruction even it has its own Wikipedia entry.  The Wikipedia entry
  * has been translated into 4 languages.  I am not making this up!
@@ -594,17 +602,17 @@ static unsigned long lguest_get_wallclock(void)
        return lguest_data.time.tv_sec;
 }
 
-/* The TSC is a Time Stamp Counter.  The Host tells us what speed it runs at,
- * or 0 if it's unusable as a reliable clock source.  This matches what we want
- * here: if we return 0 from this function, the x86 TSC clock will not register
- * itself. */
+/* The TSC is an Intel thing called the Time Stamp Counter.  The Host tells us
+ * what speed it runs at, or 0 if it's unusable as a reliable clock source.
+ * This matches what we want here: if we return 0 from this function, the x86
+ * TSC clock will give up and not register itself. */
 static unsigned long lguest_cpu_khz(void)
 {
        return lguest_data.tsc_khz;
 }
 
-/* If we can't use the TSC, the kernel falls back to our "lguest_clock", where
- * we read the time value given to us by the Host. */
+/* If we can't use the TSC, the kernel falls back to our lower-priority
+ * "lguest_clock", where we read the time value given to us by the Host. */
 static cycle_t lguest_clock_read(void)
 {
        unsigned long sec, nsec;
@@ -648,12 +656,16 @@ static struct clocksource lguest_clock = {
 static int lguest_clockevent_set_next_event(unsigned long delta,
                                            struct clock_event_device *evt)
 {
+       /* FIXME: I don't think this can ever happen, but James tells me he had
+        * to put this code in.  Maybe we should remove it now.  Anyone? */
        if (delta < LG_CLOCK_MIN_DELTA) {
                if (printk_ratelimit())
                        printk(KERN_DEBUG "%s: small delta %lu ns\n",
                               __FUNCTION__, delta);
                return -ETIME;
        }
+
+       /* Please wake us this far in the future. */
        hcall(LHCALL_SET_CLOCKEVENT, delta, 0, 0);
        return 0;
 }
@@ -738,7 +750,7 @@ static void lguest_time_init(void)
  * will not tolerate us trying to use that), the stack pointer, and the number
  * of pages in the stack. */
 static void lguest_load_sp0(struct tss_struct *tss,
-                                    struct thread_struct *thread)
+                           struct thread_struct *thread)
 {
        lazy_hcall(LHCALL_SET_STACK, __KERNEL_DS|0x1, thread->sp0,
                   THREAD_SIZE/PAGE_SIZE);
@@ -786,9 +798,8 @@ static void lguest_safe_halt(void)
        hcall(LHCALL_HALT, 0, 0, 0);
 }
 
-/* Perhaps CRASH isn't the best name for this hypercall, but we use it to get a
- * message out when we're crashing as well as elegant termination like powering
- * off.
+/* The SHUTDOWN hypercall takes a string to describe what's happening, and
+ * an argument which says whether this to restart (reboot) the Guest or not.
  *
  * Note that the Host always prefers that the Guest speak in physical addresses
  * rather than virtual addresses, so we use __pa() here. */
@@ -816,8 +827,9 @@ static struct notifier_block paniced = {
 /* Setting up memory is fairly easy. */
 static __init char *lguest_memory_setup(void)
 {
-       /* We do this here and not earlier because lockcheck barfs if we do it
-        * before start_kernel() */
+       /* We do this here and not earlier because lockcheck used to barf if we
+        * did it before start_kernel().  I think we fixed that, so it'd be
+        * nice to move it back to lguest_init.  Patch welcome... */
        atomic_notifier_chain_register(&panic_notifier_list, &paniced);
 
        /* The Linux bootloader header contains an "e820" memory map: the
@@ -850,12 +862,19 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
        return len;
 }
 
+/* Rebooting also tells the Host we're finished, but the RESTART flag tells the
+ * Launcher to reboot us. */
+static void lguest_restart(char *reason)
+{
+       hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0);
+}
+
 /*G:050
  * Patching (Powerfully Placating Performance Pedants)
  *
- * We have already seen that pv_ops structures let us replace simple
- * native instructions with calls to the appropriate back end all throughout
- * the kernel.  This allows the same kernel to run as a Guest and as a native
+ * We have already seen that pv_ops structures let us replace simple native
+ * instructions with calls to the appropriate back end all throughout the
+ * kernel.  This allows the same kernel to run as a Guest and as a native
  * kernel, but it's slow because of all the indirect branches.
  *
  * Remember that David Wheeler quote about "Any problem in computer science can
@@ -908,14 +927,9 @@ static unsigned lguest_patch(u8 type, u16 clobber, void *ibuf,
        return insn_len;
 }
 
-static void lguest_restart(char *reason)
-{
-       hcall(LHCALL_SHUTDOWN, __pa(reason), LGUEST_SHUTDOWN_RESTART, 0);
-}
-
-/*G:030 Once we get to lguest_init(), we know we're a Guest.  The pv_ops
- * structures in the kernel provide points for (almost) every routine we have
- * to override to avoid privileged instructions. */
+/*G:030 Once we get to lguest_init(), we know we're a Guest.  The various
+ * pv_ops structures in the kernel provide points for (almost) every routine we
+ * have to override to avoid privileged instructions. */
 __init void lguest_init(void)
 {
        /* We're under lguest, paravirt is enabled, and we're running at
@@ -1003,9 +1017,9 @@ __init void lguest_init(void)
         * the normal data segment to get through booting. */
        asm volatile ("mov %0, %%fs" : : "r" (__KERNEL_DS) : "memory");
 
-       /* The Host uses the top of the Guest's virtual address space for the
-        * Host<->Guest Switcher, and it tells us how big that is in
-        * lguest_data.reserve_mem, set up on the LGUEST_INIT hypercall. */
+       /* The Host<->Guest Switcher lives at the top of our address space, and
+        * the Host told us how big it is when we made LGUEST_INIT hypercall:
+        * it put the answer in lguest_data.reserve_mem  */
        reserve_top_address(lguest_data.reserve_mem);
 
        /* If we don't initialize the lock dependency checker now, it crashes
@@ -1027,6 +1041,7 @@ __init void lguest_init(void)
        /* Math is always hard! */
        new_cpu_data.hard_math = 1;
 
+       /* We don't have features.  We have puppies!  Puppies! */
 #ifdef CONFIG_X86_MCE
        mce_disabled = 1;
 #endif
@@ -1044,10 +1059,11 @@ __init void lguest_init(void)
        virtio_cons_early_init(early_put_chars);
 
        /* Last of all, we set the power management poweroff hook to point to
-        * the Guest routine to power off. */
+        * the Guest routine to power off, and the reboot hook to our restart
+        * routine. */
        pm_power_off = lguest_power_off;
-
        machine_ops.restart = lguest_restart;
+
        /* Now we're set up, call start_kernel() in init/main.c and we proceed
         * to boot as normal.  It never returns. */
        start_kernel();
index 95b6fbc..5c7cef3 100644 (file)
@@ -5,13 +5,20 @@
 #include <asm/thread_info.h>
 #include <asm/processor-flags.h>
 
-/*G:020 This is where we begin: head.S notes that the boot header's platform
- * type field is "1" (lguest), so calls us here.
+/*G:020 Our story starts with the kernel booting into startup_32 in
+ * arch/x86/kernel/head_32.S.  It expects a boot header, which is created by
+ * the bootloader (the Launcher in our case).
+ *
+ * The startup_32 function does very little: it clears the uninitialized global
+ * C variables which we expect to be zero (ie. BSS) and then copies the boot
+ * header and kernel command line somewhere safe.  Finally it checks the
+ * 'hardware_subarch' field.  This was introduced in 2.6.24 for lguest and Xen:
+ * if it's set to '1' (lguest's assigned number), then it calls us here.
  *
  * WARNING: be very careful here!  We're running at addresses equal to physical
  * addesses (around 0), not above PAGE_OFFSET as most code expectes
  * (eg. 0xC0000000).  Jumps are relative, so they're OK, but we can't touch any
- * data.
+ * data without remembering to subtract __PAGE_OFFSET!
  *
  * The .section line puts this code in .init.text so it will be discarded after
  * boot. */
@@ -24,7 +31,7 @@ ENTRY(lguest_entry)
        int $LGUEST_TRAP_ENTRY
 
        /* The Host put the toplevel pagetable in lguest_data.pgdir.  The movsl
-        * instruction uses %esi implicitly as the source for the copy we'
+        * instruction uses %esi implicitly as the source for the copy we're
         * about to do. */
        movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi
 
index 0312691..247f33d 100644 (file)
 /*
- *  Copyright (C) 2007, OpenWrt.org, Florian Fainelli <florian@openwrt.org>
- *     RDC321x architecture specific GPIO support
+ *  GPIO support for RDC SoC R3210/R8610
+ *
+ *  Copyright (C) 2007, Florian Fainelli <florian@openwrt.org>
+ *  Copyright (C) 2008, Volker Weiss <dev@tintuc.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  *
- *  This program is free software; you can redistribute  it and/or modify it
- *  under  the terms of  the GNU General  Public License as published by the
- *  Free Software Foundation;  either version 2 of the  License, or (at your
- *  option) any later version.
  */
 
-#include <linux/autoconf.h>
-#include <linux/init.h>
+
+#include <linux/spinlock.h>
 #include <linux/io.h>
 #include <linux/types.h>
 #include <linux/module.h>
-#include <linux/delay.h>
 
+#include <asm/gpio.h>
 #include <asm/mach-rdc321x/rdc321x_defs.h>
 
-static inline int rdc_gpio_is_valid(unsigned gpio)
+
+/* spin lock to protect our private copy of GPIO data register plus
+   the access to PCI conf registers. */
+static DEFINE_SPINLOCK(gpio_lock);
+
+/* copy of GPIO data registers */
+static u32 gpio_data_reg1;
+static u32 gpio_data_reg2;
+
+static u32 gpio_request_data[2];
+
+
+static inline void rdc321x_conf_write(unsigned addr, u32 value)
 {
-       return (gpio <= RDC_MAX_GPIO);
+       outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR);
+       outl(value, RDC3210_CFGREG_DATA);
 }
 
-static unsigned int rdc_gpio_read(unsigned gpio)
+static inline void rdc321x_conf_or(unsigned addr, u32 value)
 {
-       unsigned int val;
-
-       val = 0x80000000 | (7 << 11) | ((gpio&0x20?0x84:0x48));
-       outl(val, RDC3210_CFGREG_ADDR);
-       udelay(10);
-       val = inl(RDC3210_CFGREG_DATA);
-       val |= (0x1 << (gpio & 0x1F));
-       outl(val, RDC3210_CFGREG_DATA);
-       udelay(10);
-       val = 0x80000000 | (7 << 11) | ((gpio&0x20?0x88:0x4C));
-       outl(val, RDC3210_CFGREG_ADDR);
-       udelay(10);
-       val = inl(RDC3210_CFGREG_DATA);
-
-       return val;
+       outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR);
+       value |= inl(RDC3210_CFGREG_DATA);
+       outl(value, RDC3210_CFGREG_DATA);
 }
 
-static void rdc_gpio_write(unsigned int val)
+static inline u32 rdc321x_conf_read(unsigned addr)
 {
-       if (val) {
-               outl(val, RDC3210_CFGREG_DATA);
-               udelay(10);
-       }
+       outl((1 << 31) | (7 << 11) | addr, RDC3210_CFGREG_ADDR);
+
+       return inl(RDC3210_CFGREG_DATA);
 }
 
-int rdc_gpio_get_value(unsigned gpio)
+/* configure pin as GPIO */
+static void rdc321x_configure_gpio(unsigned gpio)
+{
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+       rdc321x_conf_or(gpio < 32
+               ? RDC321X_GPIO_CTRL_REG1 : RDC321X_GPIO_CTRL_REG2,
+               1 << (gpio & 0x1f));
+       spin_unlock_irqrestore(&gpio_lock, flags);
+}
+
+/* initially setup the 2 copies of the gpio data registers.
+   This function must be called by the platform setup code. */
+void __init rdc321x_gpio_setup()
+{
+       /* this might not be, what others (BIOS, bootloader, etc.)
+          wrote to these registers before, but it's a good guess. Still
+          better than just using 0xffffffff. */
+
+       gpio_data_reg1 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG1);
+       gpio_data_reg2 = rdc321x_conf_read(RDC321X_GPIO_DATA_REG2);
+}
+
+/* determine, if gpio number is valid */
+static inline int rdc321x_is_gpio(unsigned gpio)
+{
+       return gpio <= RDC321X_MAX_GPIO;
+}
+
+/* request GPIO */
+int rdc_gpio_request(unsigned gpio, const char *label)
 {
-       if (rdc_gpio_is_valid(gpio))
-               return (int)rdc_gpio_read(gpio);
-       else
+       unsigned long flags;
+
+       if (!rdc321x_is_gpio(gpio))
                return -EINVAL;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+       if (gpio_request_data[(gpio & 0x20) ? 1 : 0] & (1 << (gpio & 0x1f)))
+               goto inuse;
+       gpio_request_data[(gpio & 0x20) ? 1 : 0] |= (1 << (gpio & 0x1f));
+       spin_unlock_irqrestore(&gpio_lock, flags);
+
+       return 0;
+inuse:
+       spin_unlock_irqrestore(&gpio_lock, flags);
+       return -EINVAL;
 }
-EXPORT_SYMBOL(rdc_gpio_get_value);
+EXPORT_SYMBOL(rdc_gpio_request);
 
-void rdc_gpio_set_value(unsigned gpio, int value)
+/* release previously-claimed GPIO */
+void rdc_gpio_free(unsigned gpio)
 {
-       unsigned int val;
+       unsigned long flags;
 
-       if (!rdc_gpio_is_valid(gpio))
+       if (!rdc321x_is_gpio(gpio))
                return;
 
-       val = rdc_gpio_read(gpio);
+       spin_lock_irqsave(&gpio_lock, flags);
+       gpio_request_data[(gpio & 0x20) ? 1 : 0] &= ~(1 << (gpio & 0x1f));
+       spin_unlock_irqrestore(&gpio_lock, flags);
+}
+EXPORT_SYMBOL(rdc_gpio_free);
+
+/* read GPIO pin */
+int rdc_gpio_get_value(unsigned gpio)
+{
+       u32 reg;
+       unsigned long flags;
+
+       spin_lock_irqsave(&gpio_lock, flags);
+       reg = rdc321x_conf_read(gpio < 32
+               ? RDC321X_GPIO_DATA_REG1 : RDC321X_GPIO_DATA_REG2);
+       spin_unlock_irqrestore(&gpio_lock, flags);
 
-       if (value)
-               val &= ~(0x1 << (gpio & 0x1F));
-       else
-               val |= (0x1 << (gpio & 0x1F));
+       return (1 << (gpio & 0x1f)) & reg ? 1 : 0;
+}
+EXPORT_SYMBOL(rdc_gpio_get_value);
 
-       rdc_gpio_write(val);
+/* set GPIO pin to value */
+void rdc_gpio_set_value(unsigned gpio, int value)
+{
+       unsigned long flags;
+       u32 reg;
+
+       reg = 1 << (gpio & 0x1f);
+       if (gpio < 32) {
+               spin_lock_irqsave(&gpio_lock, flags);
+               if (value)
+                       gpio_data_reg1 |= reg;
+               else
+                       gpio_data_reg1 &= ~reg;
+               rdc321x_conf_write(RDC321X_GPIO_DATA_REG1, gpio_data_reg1);
+               spin_unlock_irqrestore(&gpio_lock, flags);
+       } else {
+               spin_lock_irqsave(&gpio_lock, flags);
+               if (value)
+                       gpio_data_reg2 |= reg;
+               else
+                       gpio_data_reg2 &= ~reg;
+               rdc321x_conf_write(RDC321X_GPIO_DATA_REG2, gpio_data_reg2);
+               spin_unlock_irqrestore(&gpio_lock, flags);
+       }
 }
 EXPORT_SYMBOL(rdc_gpio_set_value);
 
+/* configure GPIO pin as input */
 int rdc_gpio_direction_input(unsigned gpio)
 {
+       if (!rdc321x_is_gpio(gpio))
+               return -EINVAL;
+
+       rdc321x_configure_gpio(gpio);
+
        return 0;
 }
 EXPORT_SYMBOL(rdc_gpio_direction_input);
 
+/* configure GPIO pin as output and set value */
 int rdc_gpio_direction_output(unsigned gpio, int value)
 {
+       if (!rdc321x_is_gpio(gpio))
+               return -EINVAL;
+
+       gpio_set_value(gpio, value);
+       rdc321x_configure_gpio(gpio);
+
        return 0;
 }
 EXPORT_SYMBOL(rdc_gpio_direction_output);
-
-
index dda6024..a037041 100644 (file)
@@ -62,6 +62,8 @@ static struct platform_device *rdc321x_devs[] = {
 
 static int __init rdc_board_setup(void)
 {
+       rdc321x_gpio_setup();
+
        return platform_add_devices(rdc321x_devs, ARRAY_SIZE(rdc321x_devs));
 }
 
index c394ca0..8e25e06 100644 (file)
@@ -324,7 +324,6 @@ unsigned long __init setup_memory(void)
         * this space and use it to adjust the boundary between ZONE_NORMAL
         * and ZONE_HIGHMEM.
         */
-       find_max_pfn();
        get_memcfg_numa();
 
        kva_pages = calculate_numa_remap_pages();
index fdc6674..ec08d83 100644 (file)
@@ -91,12 +91,10 @@ static int is_prefetch(struct pt_regs *regs, unsigned long addr,
        int prefetch = 0;
        unsigned char *max_instr;
 
-#ifdef CONFIG_X86_32
-       if (!(__supported_pte_mask & _PAGE_NX))
-               return 0;
-#endif
-
-       /* If it was a exec fault on NX page, ignore */
+       /*
+        * If it was a exec (instruction fetch) fault on NX page, then
+        * do not ignore the fault:
+        */
        if (error_code & PF_INSTR)
                return 0;
 
index 3d936f2..9cf33d3 100644 (file)
@@ -73,15 +73,15 @@ void *kmap_atomic_prot(struct page *page, enum km_type type, pgprot_t prot)
 {
        enum fixed_addresses idx;
        unsigned long vaddr;
-       /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
-
-       debug_kmap_atomic_prot(type);
 
+       /* even !CONFIG_PREEMPT needs this, for in_atomic in do_page_fault */
        pagefault_disable();
 
        if (!PageHighMem(page))
                return page_address(page);
 
+       debug_kmap_atomic_prot(type);
+
        idx = type + KM_TYPE_NR*smp_processor_id();
        vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
        BUG_ON(!pte_none(*(kmap_pte-idx)));
index 4fbafb4..0b3d567 100644 (file)
@@ -178,7 +178,7 @@ follow_huge_addr(struct mm_struct *mm, unsigned long address, int write)
 
        page = &pte_page(*pte)[vpfn % (HPAGE_SIZE/PAGE_SIZE)];
 
-       WARN_ON(!PageCompound(page));
+       WARN_ON(!PageHead(page));
 
        return page;
 }
index 4afaba0..794895c 100644 (file)
@@ -137,7 +137,11 @@ static void __iomem *__ioremap(resource_size_t phys_addr, unsigned long size,
        switch (mode) {
        case IOR_MODE_UNCACHED:
        default:
-               prot = PAGE_KERNEL_NOCACHE;
+               /*
+                * FIXME: we will use UC MINUS for now, as video fb drivers
+                * depend on it. Upcoming ioremap_wc() will fix this behavior.
+                */
+               prot = PAGE_KERNEL_UC_MINUS;
                break;
        case IOR_MODE_CACHED:
                prot = PAGE_KERNEL;
index 14e48b5..7b79f6b 100644 (file)
@@ -771,7 +771,7 @@ static inline int change_page_attr_clear(unsigned long addr, int numpages,
 int set_memory_uc(unsigned long addr, int numpages)
 {
        return change_page_attr_set(addr, numpages,
-                                   __pgprot(_PAGE_PCD | _PAGE_PWT));
+                                   __pgprot(_PAGE_PCD));
 }
 EXPORT_SYMBOL(set_memory_uc);
 
index 8b9ee27..de4e6f0 100644 (file)
@@ -95,7 +95,7 @@ struct shared_info *HYPERVISOR_shared_info = (void *)&dummy_shared_info;
  *
  * 0: not available, 1: available
  */
-static int have_vcpu_info_placement = 0;
+static int have_vcpu_info_placement = 1;
 
 static void __init xen_vcpu_setup(int cpu)
 {
@@ -103,6 +103,7 @@ static void __init xen_vcpu_setup(int cpu)
        int err;
        struct vcpu_info *vcpup;
 
+       BUG_ON(HYPERVISOR_shared_info == &dummy_shared_info);
        per_cpu(xen_vcpu, cpu) = &HYPERVISOR_shared_info->vcpu_info[cpu];
 
        if (!have_vcpu_info_placement)
@@ -805,33 +806,43 @@ static __init void xen_pagetable_setup_start(pgd_t *base)
                          PFN_DOWN(__pa(xen_start_info->pt_base)));
 }
 
-static __init void xen_pagetable_setup_done(pgd_t *base)
+static __init void setup_shared_info(void)
 {
-       /* This will work as long as patching hasn't happened yet
-          (which it hasn't) */
-       pv_mmu_ops.alloc_pt = xen_alloc_pt;
-       pv_mmu_ops.alloc_pd = xen_alloc_pd;
-       pv_mmu_ops.release_pt = xen_release_pt;
-       pv_mmu_ops.release_pd = xen_release_pt;
-       pv_mmu_ops.set_pte = xen_set_pte;
-
        if (!xen_feature(XENFEAT_auto_translated_physmap)) {
+               unsigned long addr = fix_to_virt(FIX_PARAVIRT_BOOTMAP);
+
                /*
                 * Create a mapping for the shared info page.
                 * Should be set_fixmap(), but shared_info is a machine
                 * address with no corresponding pseudo-phys address.
                 */
-               set_pte_mfn(fix_to_virt(FIX_PARAVIRT_BOOTMAP),
+               set_pte_mfn(addr,
                            PFN_DOWN(xen_start_info->shared_info),
                            PAGE_KERNEL);
 
-               HYPERVISOR_shared_info =
-                       (struct shared_info *)fix_to_virt(FIX_PARAVIRT_BOOTMAP);
-
+               HYPERVISOR_shared_info = (struct shared_info *)addr;
        } else
                HYPERVISOR_shared_info =
                        (struct shared_info *)__va(xen_start_info->shared_info);
 
+#ifndef CONFIG_SMP
+       /* In UP this is as good a place as any to set up shared info */
+       xen_setup_vcpu_info_placement();
+#endif
+}
+
+static __init void xen_pagetable_setup_done(pgd_t *base)
+{
+       /* This will work as long as patching hasn't happened yet
+          (which it hasn't) */
+       pv_mmu_ops.alloc_pt = xen_alloc_pt;
+       pv_mmu_ops.alloc_pd = xen_alloc_pd;
+       pv_mmu_ops.release_pt = xen_release_pt;
+       pv_mmu_ops.release_pd = xen_release_pt;
+       pv_mmu_ops.set_pte = xen_set_pte;
+
+       setup_shared_info();
+
        /* Actually pin the pagetable down, but we can't set PG_pinned
           yet because the page structures don't exist yet. */
        {
@@ -1182,15 +1193,9 @@ asmlinkage void __init xen_start_kernel(void)
        x86_write_percpu(xen_cr3, __pa(pgd));
        x86_write_percpu(xen_current_cr3, __pa(pgd));
 
-#ifdef CONFIG_SMP
        /* Don't do the full vcpu_info placement stuff until we have a
-          possible map. */
+          possible map and a non-dummy shared_info. */
        per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];
-#else
-       /* May as well do it now, since there's no good time to call
-          it later on UP. */
-       xen_setup_vcpu_info_placement();
-#endif
 
        pv_info.kernel_rpl = 1;
        if (xen_feature(XENFEAT_supervisor_mode_kernel))
index 1a43b60..6b71904 100644 (file)
        events, then enter the hypervisor to get them handled.
  */
 ENTRY(xen_irq_enable_direct)
-       /* Clear mask and test pending */
-       andw $0x00ff, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_pending
+       /* Unmask events */
+       movb $0, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_mask
+
        /* Preempt here doesn't matter because that will deal with
           any pending interrupts.  The pending check may end up being
           run on the wrong CPU, but that doesn't hurt. */
+
+       /* Test for pending */
+       testb $0xff, PER_CPU_VAR(xen_vcpu_info)+XEN_vcpu_info_pending
        jz 1f
+
 2:     call check_events
 1:
 ENDPATCH(xen_irq_enable_direct)
index e8e2d88..788da97 100644 (file)
@@ -1487,7 +1487,6 @@ static int acpi_idle_enter_simple(struct cpuidle_device *dev,
                return 0;
        }
 
-       acpi_unlazy_tlb(smp_processor_id());
        /*
         * Must be done before busmaster disable as we might need to
         * access HPET !
@@ -1577,6 +1576,8 @@ static int acpi_idle_enter_bm(struct cpuidle_device *dev,
                return 0;
        }
 
+       acpi_unlazy_tlb(smp_processor_id());
+
        /* Tell the scheduler that we are going deep-idle: */
        sched_clock_idle_sleep_event();
        /*
@@ -1692,7 +1693,9 @@ static int acpi_processor_setup_cpuidle(struct acpi_processor *pr)
                switch (cx->type) {
                        case ACPI_STATE_C1:
                        state->flags |= CPUIDLE_FLAG_SHALLOW;
-                       state->flags |= CPUIDLE_FLAG_TIME_VALID;
+                       if (cx->entry_method == ACPI_CSTATE_FFH)
+                               state->flags |= CPUIDLE_FLAG_TIME_VALID;
+
                        state->enter = acpi_idle_enter_c1;
                        dev->safe_state = state;
                        break;
index a2cf300..bcf2c70 100644 (file)
@@ -130,7 +130,6 @@ static int acpi_smbus_transaction(struct acpi_smb_hc *hc, u8 protocol,
                goto end;
        }
        smb_hc_write(hc, ACPI_SMB_COMMAND, command);
-       smb_hc_write(hc, ACPI_SMB_COMMAND, command);
        if (!(protocol & 0x01)) {
                smb_hc_write(hc, ACPI_SMB_BLOCK_COUNT, length);
                for (i = 0; i < length; ++i)
index 57570ac..e6ce262 100644 (file)
@@ -39,20 +39,26 @@ static int create_modalias(struct acpi_device *acpi_dev, char *modalias,
                           int size)
 {
        int len;
+       int count;
 
-       if (!acpi_dev->flags.hardware_id)
+       if (!acpi_dev->flags.hardware_id && !acpi_dev->flags.compatible_ids)
                return -ENODEV;
 
-       len = snprintf(modalias, size, "acpi:%s:",
-                      acpi_dev->pnp.hardware_id);
-       if (len < 0 || len >= size)
-               return -EINVAL;
+       len = snprintf(modalias, size, "acpi:");
        size -= len;
 
+       if (acpi_dev->flags.hardware_id) {
+               count = snprintf(&modalias[len], size, "%s:",
+                                acpi_dev->pnp.hardware_id);
+               if (count < 0 || count >= size)
+                       return -EINVAL;
+               len += count;
+               size -= count;
+       }
+
        if (acpi_dev->flags.compatible_ids) {
                struct acpi_compatible_id_list *cid_list;
                int i;
-               int count;
 
                cid_list = acpi_dev->pnp.cid_list;
                for (i = 0; i < cid_list->count; i++) {
index d2f71a5..71183ee 100644 (file)
@@ -26,21 +26,6 @@ u8 sleep_states[ACPI_S_STATE_COUNT];
 
 #ifdef CONFIG_PM_SLEEP
 static u32 acpi_target_sleep_state = ACPI_STATE_S0;
-static bool acpi_sleep_finish_wake_up;
-
-/*
- * ACPI 2.0 and later want us to execute _PTS after suspending devices, so we
- * allow the user to request that behavior by using the 'acpi_new_pts_ordering'
- * kernel command line option that causes the following variable to be set.
- */
-static bool new_pts_ordering;
-
-static int __init acpi_new_pts_ordering(char *str)
-{
-       new_pts_ordering = true;
-       return 1;
-}
-__setup("acpi_new_pts_ordering", acpi_new_pts_ordering);
 #endif
 
 static int acpi_sleep_prepare(u32 acpi_state)
@@ -91,14 +76,6 @@ static int acpi_pm_begin(suspend_state_t pm_state)
 
        if (sleep_states[acpi_state]) {
                acpi_target_sleep_state = acpi_state;
-               if (new_pts_ordering)
-                       return 0;
-
-               error = acpi_sleep_prepare(acpi_state);
-               if (error)
-                       acpi_target_sleep_state = ACPI_STATE_S0;
-               else
-                       acpi_sleep_finish_wake_up = true;
        } else {
                printk(KERN_ERR "ACPI does not support this state: %d\n",
                        pm_state);
@@ -116,14 +93,11 @@ static int acpi_pm_begin(suspend_state_t pm_state)
 
 static int acpi_pm_prepare(void)
 {
-       if (new_pts_ordering) {
-               int error = acpi_sleep_prepare(acpi_target_sleep_state);
+       int error = acpi_sleep_prepare(acpi_target_sleep_state);
 
-               if (error) {
-                       acpi_target_sleep_state = ACPI_STATE_S0;
-                       return error;
-               }
-               acpi_sleep_finish_wake_up = true;
+       if (error) {
+               acpi_target_sleep_state = ACPI_STATE_S0;
+               return error;
        }
 
        return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT;
@@ -212,7 +186,6 @@ static void acpi_pm_finish(void)
        acpi_set_firmware_waking_vector((acpi_physical_address) 0);
 
        acpi_target_sleep_state = ACPI_STATE_S0;
-       acpi_sleep_finish_wake_up = false;
 
 #ifdef CONFIG_X86
        if (init_8259A_after_S1) {
@@ -229,11 +202,10 @@ static void acpi_pm_finish(void)
 static void acpi_pm_end(void)
 {
        /*
-        * This is necessary in case acpi_pm_finish() is not called directly
-        * during a failing transition to a sleep state.
+        * This is necessary in case acpi_pm_finish() is not called during a
+        * failing transition to a sleep state.
         */
-       if (acpi_sleep_finish_wake_up)
-               acpi_pm_finish();
+       acpi_target_sleep_state = ACPI_STATE_S0;
 }
 
 static int acpi_pm_state_valid(suspend_state_t pm_state)
@@ -285,31 +257,18 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
 #ifdef CONFIG_HIBERNATION
 static int acpi_hibernation_begin(void)
 {
-       int error;
-
        acpi_target_sleep_state = ACPI_STATE_S4;
-       if (new_pts_ordering)
-               return 0;
 
-       error = acpi_sleep_prepare(ACPI_STATE_S4);
-       if (error)
-               acpi_target_sleep_state = ACPI_STATE_S0;
-       else
-               acpi_sleep_finish_wake_up = true;
-
-       return error;
+       return 0;
 }
 
 static int acpi_hibernation_prepare(void)
 {
-       if (new_pts_ordering) {
-               int error = acpi_sleep_prepare(ACPI_STATE_S4);
+       int error = acpi_sleep_prepare(ACPI_STATE_S4);
 
-               if (error) {
-                       acpi_target_sleep_state = ACPI_STATE_S0;
-                       return error;
-               }
-               acpi_sleep_finish_wake_up = true;
+       if (error) {
+               acpi_target_sleep_state = ACPI_STATE_S0;
+               return error;
        }
 
        return ACPI_SUCCESS(acpi_hw_disable_all_gpes()) ? 0 : -EFAULT;
@@ -353,17 +312,15 @@ static void acpi_hibernation_finish(void)
        acpi_set_firmware_waking_vector((acpi_physical_address) 0);
 
        acpi_target_sleep_state = ACPI_STATE_S0;
-       acpi_sleep_finish_wake_up = false;
 }
 
 static void acpi_hibernation_end(void)
 {
        /*
         * This is necessary in case acpi_hibernation_finish() is not called
-        * directly during a failing transition to the sleep state.
+        * during a failing transition to the sleep state.
         */
-       if (acpi_sleep_finish_wake_up)
-               acpi_hibernation_finish();
+       acpi_target_sleep_state = ACPI_STATE_S0;
 }
 
 static int acpi_hibernation_pre_restore(void)
index c4248b3..4851988 100644 (file)
@@ -972,7 +972,7 @@ static void ata_dev_disable_pm(struct ata_device *dev)
 void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy)
 {
        ap->pm_policy = policy;
-       ap->link.eh_info.action |= ATA_EHI_LPM;
+       ap->link.eh_info.action |= ATA_EH_LPM;
        ap->link.eh_info.flags |= ATA_EHI_NO_AUTOPSY;
        ata_port_schedule_eh(ap);
 }
index 681252f..a583032 100644 (file)
@@ -2748,7 +2748,7 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
                        ehc->i.flags &= ~ATA_EHI_SETMODE;
                }
 
-               if (ehc->i.action & ATA_EHI_LPM)
+               if (ehc->i.action & ATA_EH_LPM)
                        ata_link_for_each_dev(dev, link)
                                ata_dev_enable_pm(dev, ap->pm_policy);
 
index 503245a..3988e44 100644 (file)
@@ -269,7 +269,11 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
        dev_dbg(&pdev->dev, "sil680: BA5_EN = %d clock = %02X\n",
                tmpbyte & 1, tmpbyte & 0x30);
 
-       *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
+       *try_mmio = 0;
+#ifdef CONFIG_PPC
+       if (machine_is(cell))
+               *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
+#endif
 
        switch(tmpbyte & 0x30) {
                case 0x00:
index bf31a01..9a6537f 100644 (file)
@@ -133,6 +133,7 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj,
 {
        va_list args;
        char *name;
+       int ret;
 
        va_start(args, fmt);
        name = kvasprintf(GFP_KERNEL, fmt, args);
@@ -141,7 +142,9 @@ int driver_add_kobj(struct device_driver *drv, struct kobject *kobj,
        if (!name)
                return -ENOMEM;
 
-       return kobject_add(kobj, &drv->p->kobj, "%s", name);
+       ret = kobject_add(kobj, &drv->p->kobj, "%s", name);
+       kfree(name);
+       return ret;
 }
 EXPORT_SYMBOL_GPL(driver_add_kobj);
 
index e5a0e97..141f4df 100644 (file)
@@ -122,8 +122,9 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
        } else {
                address = gart_info->addr;
                bus_address = gart_info->bus_addr;
-               DRM_DEBUG("PCI: Gart Table: VRAM %08X mapped at %08lX\n",
-                         bus_address, (unsigned long)address);
+               DRM_DEBUG("PCI: Gart Table: VRAM %08LX mapped at %08lX\n",
+                         (unsigned long long)bus_address,
+                         (unsigned long)address);
        }
 
        pci_gart = (u32 *) address;
@@ -167,6 +168,12 @@ int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *ga
                }
        }
 
+       if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
+               dma_sync_single_for_device(&dev->pdev->dev,
+                                          bus_address,
+                                          max_pages * sizeof(u32),
+                                          PCI_DMA_TODEVICE);
+
        ret = 1;
 
 #if defined(__i386__) || defined(__x86_64__)
index 26d8f67..b2b0f3d 100644 (file)
 
 #define DEBUG_SCATTER 0
 
+static inline void *drm_vmalloc_dma(unsigned long size)
+{
+#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE)
+       return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL | _PAGE_NO_CACHE);
+#else
+       return vmalloc_32(size);
+#endif
+}
+
 void drm_sg_cleanup(struct drm_sg_mem * entry)
 {
        struct page *page;
@@ -104,7 +113,7 @@ int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request)
        }
        memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr));
 
-       entry->virtual = vmalloc_32(pages << PAGE_SHIFT);
+       entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT);
        if (!entry->virtual) {
                drm_free(entry->busaddr,
                         entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
index 3d65c4d..945df72 100644 (file)
@@ -54,13 +54,24 @@ static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
        pgprot_val(tmp) |= _PAGE_NO_CACHE;
        if (map_type == _DRM_REGISTERS)
                pgprot_val(tmp) |= _PAGE_GUARDED;
-#endif
-#if defined(__ia64__)
+#elif defined(__ia64__)
        if (efi_range_is_wc(vma->vm_start, vma->vm_end -
                                    vma->vm_start))
                tmp = pgprot_writecombine(tmp);
        else
                tmp = pgprot_noncached(tmp);
+#elif defined(__sparc__)
+       tmp = pgprot_noncached(tmp);
+#endif
+       return tmp;
+}
+
+static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma)
+{
+       pgprot_t tmp = vm_get_page_prot(vma->vm_flags);
+
+#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE)
+       tmp |= _PAGE_NO_CACHE;
 #endif
        return tmp;
 }
@@ -603,9 +614,6 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
                offset = dev->driver->get_reg_ofs(dev);
                vma->vm_flags |= VM_IO; /* not in core dump */
                vma->vm_page_prot = drm_io_prot(map->type, vma);
-#ifdef __sparc__
-               vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-#endif
                if (io_remap_pfn_range(vma, vma->vm_start,
                                       (map->offset + offset) >> PAGE_SHIFT,
                                       vma->vm_end - vma->vm_start,
@@ -624,6 +632,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
                    page_to_pfn(virt_to_page(map->handle)),
                    vma->vm_end - vma->vm_start, vma->vm_page_prot))
                        return -EAGAIN;
+               vma->vm_page_prot = drm_dma_prot(map->type, vma);
        /* fall through to _DRM_SHM */
        case _DRM_SHM:
                vma->vm_ops = &drm_vm_shm_ops;
@@ -631,6 +640,7 @@ static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
                /* Don't let this area swap.  Change when
                   DRM_KERNEL advisory is supported. */
                vma->vm_flags |= VM_RESERVED;
+               vma->vm_page_prot = drm_dma_prot(map->type, vma);
                break;
        case _DRM_SCATTER_GATHER:
                vma->vm_ops = &drm_vm_sg_ops;
index e9d6663..a043bb1 100644 (file)
@@ -804,6 +804,9 @@ void i915_driver_lastclose(struct drm_device * dev)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
 
+       if (!dev_priv)
+               return;
+
        if (dev_priv->agp_heap)
                i915_mem_takedown(&(dev_priv->agp_heap));
 
index 0f4afc4..f535812 100644 (file)
@@ -729,6 +729,47 @@ static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
        buf->used = 0;
 }
 
+static void r300_cmd_wait(drm_radeon_private_t * dev_priv,
+                         drm_r300_cmd_header_t header)
+{
+       u32 wait_until;
+       RING_LOCALS;
+
+       if (!header.wait.flags)
+               return;
+
+       wait_until = 0;
+
+       switch(header.wait.flags) {
+       case R300_WAIT_2D:
+               wait_until = RADEON_WAIT_2D_IDLE;
+               break;
+       case R300_WAIT_3D:
+               wait_until = RADEON_WAIT_3D_IDLE;
+               break;
+       case R300_NEW_WAIT_2D_3D:
+               wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_3D_IDLE;
+               break;
+       case R300_NEW_WAIT_2D_2D_CLEAN:
+               wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
+               break;
+       case R300_NEW_WAIT_3D_3D_CLEAN:
+               wait_until = RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
+               break;
+       case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN:
+               wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
+               wait_until |= RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
+               break;
+       default:
+               return;
+       }
+
+       BEGIN_RING(2);
+       OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
+       OUT_RING(wait_until);
+       ADVANCE_RING();
+}
+
 static int r300_scratch(drm_radeon_private_t *dev_priv,
                        drm_radeon_kcmd_buffer_t *cmdbuf,
                        drm_r300_cmd_header_t header)
@@ -909,19 +950,8 @@ int r300_do_cp_cmdbuf(struct drm_device *dev,
                        break;
 
                case R300_CMD_WAIT:
-                       /* simple enough, we can do it here */
                        DRM_DEBUG("R300_CMD_WAIT\n");
-                       if (header.wait.flags == 0)
-                               break;  /* nothing to do */
-
-                       {
-                               RING_LOCALS;
-
-                               BEGIN_RING(2);
-                               OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
-                               OUT_RING((header.wait.flags & 0xf) << 14);
-                               ADVANCE_RING();
-                       }
+                       r300_cmd_wait(dev_priv, header);
                        break;
 
                case R300_CMD_SCRATCH:
index 71e5b21..aab82e1 100644 (file)
@@ -225,8 +225,20 @@ typedef union {
 #define R300_CMD_WAIT                  7
 #      define R300_WAIT_2D             0x1
 #      define R300_WAIT_3D             0x2
+/* these two defines are DOING IT WRONG - however
+ * we have userspace which relies on using these.
+ * The wait interface is backwards compat new 
+ * code should use the NEW_WAIT defines below
+ * THESE ARE NOT BIT FIELDS
+ */
 #      define R300_WAIT_2D_CLEAN       0x3
 #      define R300_WAIT_3D_CLEAN       0x4
+
+#      define R300_NEW_WAIT_2D_3D      0x3
+#      define R300_NEW_WAIT_2D_2D_CLEAN        0x4
+#      define R300_NEW_WAIT_3D_3D_CLEAN        0x6
+#      define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN    0x8
+
 #define R300_CMD_SCRATCH               8
 
 typedef union {
index 78b34fa..4af5286 100644 (file)
@@ -88,7 +88,7 @@ static struct mem_block *alloc_block(struct mem_block *heap, int size,
 
        list_for_each(p, heap) {
                int start = (p->start + mask) & ~mask;
-               if (p->file_priv == 0 && start + size <= p->start + p->size)
+               if (p->file_priv == NULL && start + size <= p->start + p->size)
                        return split_block(p, start, size, file_priv);
        }
 
@@ -113,7 +113,7 @@ static void free_block(struct mem_block *p)
        /* Assumes a single contiguous range.  Needs a special file_priv in
         * 'heap' to stop it being subsumed.
         */
-       if (p->next->file_priv == 0) {
+       if (p->next->file_priv == NULL) {
                struct mem_block *q = p->next;
                p->size += q->size;
                p->next = q->next;
@@ -121,7 +121,7 @@ static void free_block(struct mem_block *p)
                drm_free(q, sizeof(*q), DRM_MEM_BUFS);
        }
 
-       if (p->prev->file_priv == 0) {
+       if (p->prev->file_priv == NULL) {
                struct mem_block *q = p->prev;
                q->size += p->size;
                q->next = p->next;
@@ -174,7 +174,7 @@ void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap)
         * 'heap' to stop it being subsumed.
         */
        list_for_each(p, heap) {
-               while (p->file_priv == 0 && p->next->file_priv == 0) {
+               while (p->file_priv == NULL && p->next->file_priv == NULL) {
                        struct mem_block *q = p->next;
                        p->size += q->size;
                        p->next = q->next;
index 46b2a1c..0c09409 100644 (file)
@@ -1183,7 +1183,7 @@ static int copy_from_read_buf(struct tty_struct *tty,
        return retval;
 }
 
-extern ssize_t redirected_tty_write(struct file *, const char *,
+extern ssize_t redirected_tty_write(struct file *, const char __user *,
                                                        size_t, loff_t *);
 
 /**
index 6d0dc5f..6a6843a 100644 (file)
@@ -438,7 +438,7 @@ static void read_mem32(u32 *buf, const void __iomem *mem_addr_start,
                        u32 size_bytes)
 {
        u32 i = 0;
-       const u32 *ptr = (__force u32 *) mem_addr_start;
+       const u32 __iomem *ptr = mem_addr_start;
        u16 *buf16;
 
        if (unlikely(!ptr || !buf))
@@ -448,11 +448,11 @@ static void read_mem32(u32 *buf, const void __iomem *mem_addr_start,
        switch (size_bytes) {
        case 2: /* 2 bytes */
                buf16 = (u16 *) buf;
-               *buf16 = __le16_to_cpu(readw((void __iomem *)ptr));
+               *buf16 = __le16_to_cpu(readw(ptr));
                goto out;
                break;
        case 4: /* 4 bytes */
-               *(buf) = __le32_to_cpu(readl((void __iomem *)ptr));
+               *(buf) = __le32_to_cpu(readl(ptr));
                goto out;
                break;
        }
@@ -461,11 +461,11 @@ static void read_mem32(u32 *buf, const void __iomem *mem_addr_start,
                if (size_bytes - i == 2) {
                        /* Handle 2 bytes in the end */
                        buf16 = (u16 *) buf;
-                       *(buf16) = __le16_to_cpu(readw((void __iomem *)ptr));
+                       *(buf16) = __le16_to_cpu(readw(ptr));
                        i += 2;
                } else {
                        /* Read 4 bytes */
-                       *(buf) = __le32_to_cpu(readl((void __iomem *)ptr));
+                       *(buf) = __le32_to_cpu(readl(ptr));
                        i += 4;
                }
                buf++;
@@ -484,7 +484,7 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
                        u32 size_bytes)
 {
        u32 i = 0;
-       u32 *ptr = (__force u32 *) mem_addr_start;
+       u32 __iomem *ptr = mem_addr_start;
        const u16 *buf16;
 
        if (unlikely(!ptr || !buf))
@@ -494,7 +494,7 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
        switch (size_bytes) {
        case 2: /* 2 bytes */
                buf16 = (const u16 *)buf;
-               writew(__cpu_to_le16(*buf16), (void __iomem *)ptr);
+               writew(__cpu_to_le16(*buf16), ptr);
                return 2;
                break;
        case 1: /*
@@ -502,7 +502,7 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
                 * so falling through..
                 */
        case 4: /* 4 bytes */
-               writel(__cpu_to_le32(*buf), (void __iomem *)ptr);
+               writel(__cpu_to_le32(*buf), ptr);
                return 4;
                break;
        }
@@ -511,11 +511,11 @@ static u32 write_mem32(void __iomem *mem_addr_start, const u32 *buf,
                if (size_bytes - i == 2) {
                        /* 2 bytes */
                        buf16 = (const u16 *)buf;
-                       writew(__cpu_to_le16(*buf16), (void __iomem *)ptr);
+                       writew(__cpu_to_le16(*buf16), ptr);
                        i += 2;
                } else {
                        /* 4 bytes */
-                       writel(__cpu_to_le32(*buf), (void __iomem *)ptr);
+                       writel(__cpu_to_le32(*buf), ptr);
                        i += 4;
                }
                buf++;
index d73663a..fc555a9 100644 (file)
@@ -67,7 +67,7 @@ static void cpuidle_idle_call(void)
        /* enter the state and update stats */
        dev->last_residency = target_state->enter(dev, target_state);
        dev->last_state = target_state;
-       target_state->time += dev->last_residency;
+       target_state->time += (unsigned long long)dev->last_residency;
        target_state->usage++;
 
        /* give the governor an opportunity to reflect on the outcome */
@@ -224,7 +224,7 @@ static void poll_idle_init(struct cpuidle_device *dev)
        state->exit_latency = 0;
        state->target_residency = 0;
        state->power_usage = -1;
-       state->flags = CPUIDLE_FLAG_POLL | CPUIDLE_FLAG_TIME_VALID;
+       state->flags = CPUIDLE_FLAG_POLL;
        state->enter = poll_idle;
 }
 #else
index 69102ca..e949618 100644 (file)
@@ -218,6 +218,12 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
        return sprintf(buf, "%u\n", state->_name);\
 }
 
+#define define_show_state_ull_function(_name) \
+static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
+{ \
+       return sprintf(buf, "%llu\n", state->_name);\
+}
+
 #define define_show_state_str_function(_name) \
 static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
 { \
@@ -228,8 +234,8 @@ static ssize_t show_state_##_name(struct cpuidle_state *state, char *buf) \
 
 define_show_state_function(exit_latency)
 define_show_state_function(power_usage)
-define_show_state_function(usage)
-define_show_state_function(time)
+define_show_state_ull_function(usage)
+define_show_state_ull_function(time)
 define_show_state_str_function(name)
 define_show_state_str_function(desc)
 
index 3110bf7..81f3f95 100644 (file)
@@ -392,8 +392,8 @@ static atomic_t hifn_dev_number;
 
 struct hifn_desc
 {
-       volatile u32            l;
-       volatile u32            p;
+       volatile __le32         l;
+       volatile __le32         p;
 };
 
 struct hifn_dma {
@@ -481,10 +481,10 @@ struct hifn_device
 
 struct hifn_base_command
 {
-       volatile u16            masks;
-       volatile u16            session_num;
-       volatile u16            total_source_count;
-       volatile u16            total_dest_count;
+       volatile __le16         masks;
+       volatile __le16         session_num;
+       volatile __le16         total_source_count;
+       volatile __le16         total_dest_count;
 };
 
 #define        HIFN_BASE_CMD_COMP              0x0100  /* enable compression engine */
@@ -504,10 +504,10 @@ struct hifn_base_command
  */
 struct hifn_crypt_command
 {
-       volatile u16            masks;
-       volatile u16            header_skip;
-       volatile u16            source_count;
-       volatile u16            reserved;
+       volatile __le16                 masks;
+       volatile __le16                 header_skip;
+       volatile __le16                 source_count;
+       volatile __le16                 reserved;
 };
 
 #define        HIFN_CRYPT_CMD_ALG_MASK         0x0003          /* algorithm: */
@@ -670,7 +670,7 @@ static inline u32 hifn_read_0(struct hifn_device *dev, u32 reg)
 {
        u32 ret;
 
-       ret = readl((char *)(dev->bar[0]) + reg);
+       ret = readl(dev->bar[0] + reg);
 
        return ret;
 }
@@ -679,19 +679,19 @@ static inline u32 hifn_read_1(struct hifn_device *dev, u32 reg)
 {
        u32 ret;
 
-       ret = readl((char *)(dev->bar[1]) + reg);
+       ret = readl(dev->bar[1] + reg);
 
        return ret;
 }
 
 static inline void hifn_write_0(struct hifn_device *dev, u32 reg, u32 val)
 {
-       writel(val, (char *)(dev->bar[0]) + reg);
+       writel(val, dev->bar[0] + reg);
 }
 
 static inline void hifn_write_1(struct hifn_device *dev, u32 reg, u32 val)
 {
-       writel(val, (char *)(dev->bar[1]) + reg);
+       writel(val, dev->bar[1] + reg);
 }
 
 static void hifn_wait_puc(struct hifn_device *dev)
index fddd6ae..6faf07b 100644 (file)
 #define FSL_DMA_DGSR_EOSI      0x02
 #define FSL_DMA_DGSR_EOLSI     0x01
 
+typedef u64 __bitwise v64;
+typedef u32 __bitwise v32;
+
 struct fsl_dma_ld_hw {
-       u64 __bitwise   src_addr;
-       u64 __bitwise   dst_addr;
-       u64 __bitwise   next_ln_addr;
-       u32 __bitwise   count;
-       u32 __bitwise   reserve;
+       v64 src_addr;
+       v64 dst_addr;
+       v64 next_ln_addr;
+       v32 count;
+       v32 reserve;
 } __attribute__((aligned(32)));
 
 struct fsl_desc_sw {
@@ -92,13 +95,13 @@ struct fsl_desc_sw {
 } __attribute__((aligned(32)));
 
 struct fsl_dma_chan_regs {
-       u32 __bitwise   mr;     /* 0x00 - Mode Register */
-       u32 __bitwise   sr;     /* 0x04 - Status Register */
-       u64 __bitwise   cdar;   /* 0x08 - Current descriptor address register */
-       u64 __bitwise   sar;    /* 0x10 - Source Address Register */
-       u64 __bitwise   dar;    /* 0x18 - Destination Address Register */
-       u32 __bitwise   bcr;    /* 0x20 - Byte Count Register */
-       u64 __bitwise   ndar;   /* 0x24 - Next Descriptor Address Register */
+       u32 mr; /* 0x00 - Mode Register */
+       u32 sr; /* 0x04 - Status Register */
+       u64 cdar;       /* 0x08 - Current descriptor address register */
+       u64 sar;        /* 0x10 - Source Address Register */
+       u64 dar;        /* 0x18 - Destination Address Register */
+       u32 bcr;        /* 0x20 - Byte Count Register */
+       u64 ndar;       /* 0x24 - Next Descriptor Address Register */
 };
 
 struct fsl_dma_chan;
@@ -151,25 +154,27 @@ struct fsl_dma_chan {
 #ifndef __powerpc64__
 static u64 in_be64(const u64 __iomem *addr)
 {
-       return ((u64)in_be32((u32 *)addr) << 32) | (in_be32((u32 *)addr + 1));
+       return ((u64)in_be32((u32 __iomem *)addr) << 32) |
+               (in_be32((u32 __iomem *)addr + 1));
 }
 
 static void out_be64(u64 __iomem *addr, u64 val)
 {
-       out_be32((u32 *)addr, val >> 32);
-       out_be32((u32 *)addr + 1, (u32)val);
+       out_be32((u32 __iomem *)addr, val >> 32);
+       out_be32((u32 __iomem *)addr + 1, (u32)val);
 }
 
 /* There is no asm instructions for 64 bits reverse loads and stores */
 static u64 in_le64(const u64 __iomem *addr)
 {
-       return ((u64)in_le32((u32 *)addr + 1) << 32) | (in_le32((u32 *)addr));
+       return ((u64)in_le32((u32 __iomem *)addr + 1) << 32) |
+               (in_le32((u32 __iomem *)addr));
 }
 
 static void out_le64(u64 __iomem *addr, u64 val)
 {
-       out_le32((u32 *)addr + 1, val >> 32);
-       out_le32((u32 *)addr, (u32)val);
+       out_le32((u32 __iomem *)addr + 1, val >> 32);
+       out_le32((u32 __iomem *)addr, (u32)val);
 }
 #endif
 
@@ -182,9 +187,11 @@ static void out_le64(u64 __iomem *addr, u64 val)
 
 #define DMA_TO_CPU(fsl_chan, d, width)                                 \
                (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ?           \
-                       be##width##_to_cpu(d) : le##width##_to_cpu(d))
+                       be##width##_to_cpu((__force __be##width)(v##width)d) : \
+                       le##width##_to_cpu((__force __le##width)(v##width)d))
 #define CPU_TO_DMA(fsl_chan, c, width)                                 \
                (((fsl_chan)->feature & FSL_DMA_BIG_ENDIAN) ?           \
-                       cpu_to_be##width(c) : cpu_to_le##width(c))
+                       (__force v##width)cpu_to_be##width(c) :         \
+                       (__force v##width)cpu_to_le##width(c))
 
 #endif /* __DMA_FSLDMA_H */
index 0fa8a98..9e92276 100644 (file)
@@ -98,7 +98,7 @@ struct ioat_dca_slot {
 
 struct ioat_dca_priv {
        void __iomem            *iobase;
-       void                    *dca_base;
+       void __iomem            *dca_base;
        int                      max_requesters;
        int                      requester_count;
        u8                       tag_map[IOAT_TAG_MAP_LEN];
@@ -338,7 +338,7 @@ static struct dca_ops ioat2_dca_ops = {
        .get_tag                = ioat2_dca_get_tag,
 };
 
-static int ioat2_dca_count_dca_slots(void *iobase, u16 dca_offset)
+static int ioat2_dca_count_dca_slots(void __iomem *iobase, u16 dca_offset)
 {
        int slots = 0;
        u32 req;
index c419266..01b9220 100644 (file)
@@ -595,6 +595,7 @@ u8 eighty_ninty_three (ide_drive_t *drive)
 
        /*
         * FIXME:
+        * - change master/slave IDENTIFY order
         * - force bit13 (80c cable present) check also for !ivb devices
         *   (unless the slave device is pre-ATA3)
         */
index 194ecb0..47a1149 100644 (file)
@@ -774,9 +774,10 @@ static int ide_probe_port(ide_hwif_t *hwif)
                printk(KERN_DEBUG "%s: Wait for ready failed before probe !\n", hwif->name);
 
        /*
-        * Need to probe slave device first to make it release PDIAG-.
+        * Second drive should only exist if first drive was found,
+        * but a lot of cdrom drives are configured as single slaves.
         */
-       for (unit = MAX_DRIVES - 1; unit >= 0; unit--) {
+       for (unit = 0; unit < MAX_DRIVES; ++unit) {
                ide_drive_t *drive = &hwif->drives[unit];
                drive->dn = (hwif->channel ? 2 : 0) + unit;
                (void) probe_for_drive(drive);
index a58ad8a..781ea59 100644 (file)
@@ -154,7 +154,7 @@ static void addr_send_arp(struct sockaddr_in *dst_in)
 {
        struct rtable *rt;
        struct flowi fl;
-       u32 dst_ip = dst_in->sin_addr.s_addr;
+       __be32 dst_ip = dst_in->sin_addr.s_addr;
 
        memset(&fl, 0, sizeof fl);
        fl.nl_u.ip4_u.daddr = dst_ip;
@@ -169,8 +169,8 @@ static int addr_resolve_remote(struct sockaddr_in *src_in,
                               struct sockaddr_in *dst_in,
                               struct rdma_dev_addr *addr)
 {
-       u32 src_ip = src_in->sin_addr.s_addr;
-       u32 dst_ip = dst_in->sin_addr.s_addr;
+       __be32 src_ip = src_in->sin_addr.s_addr;
+       __be32 dst_ip = dst_in->sin_addr.s_addr;
        struct flowi fl;
        struct rtable *rt;
        struct neighbour *neigh;
@@ -257,7 +257,7 @@ static int addr_resolve_local(struct sockaddr_in *src_in,
                              struct rdma_dev_addr *addr)
 {
        struct net_device *dev;
-       u32 src_ip = src_in->sin_addr.s_addr;
+       __be32 src_ip = src_in->sin_addr.s_addr;
        __be32 dst_ip = dst_in->sin_addr.s_addr;
        int ret;
 
index 4df4051..faa7ce3 100644 (file)
@@ -393,7 +393,7 @@ static int cm_alloc_id(struct cm_id_private *cm_id_priv)
                spin_unlock_irqrestore(&cm.lock, flags);
        } while( (ret == -EAGAIN) && idr_pre_get(&cm.local_id_table, GFP_KERNEL) );
 
-       cm_id_priv->id.local_id = (__force __be32) (id ^ cm.random_id_operand);
+       cm_id_priv->id.local_id = (__force __be32)id ^ cm.random_id_operand;
        return ret;
 }
 
index 34507da..d81c156 100644 (file)
@@ -168,15 +168,15 @@ struct cma_work {
 union cma_ip_addr {
        struct in6_addr ip6;
        struct {
-               __u32 pad[3];
-               __u32 addr;
+               __be32 pad[3];
+               __be32 addr;
        } ip4;
 };
 
 struct cma_hdr {
        u8 cma_version;
        u8 ip_version;  /* IP version: 7:4 */
-       __u16 port;
+       __be16 port;
        union cma_ip_addr src_addr;
        union cma_ip_addr dst_addr;
 };
@@ -186,8 +186,8 @@ struct sdp_hh {
        u8 sdp_version; /* Major version: 7:4 */
        u8 ip_version;  /* IP version: 7:4 */
        u8 sdp_specific1[10];
-       __u16 port;
-       __u16 sdp_specific2;
+       __be16 port;
+       __be16 sdp_specific2;
        union cma_ip_addr src_addr;
        union cma_ip_addr dst_addr;
 };
@@ -663,7 +663,7 @@ static inline int cma_any_port(struct sockaddr *addr)
 }
 
 static int cma_get_net_info(void *hdr, enum rdma_port_space ps,
-                           u8 *ip_ver, __u16 *port,
+                           u8 *ip_ver, __be16 *port,
                            union cma_ip_addr **src, union cma_ip_addr **dst)
 {
        switch (ps) {
@@ -695,7 +695,7 @@ static int cma_get_net_info(void *hdr, enum rdma_port_space ps,
 
 static void cma_save_net_info(struct rdma_addr *addr,
                              struct rdma_addr *listen_addr,
-                             u8 ip_ver, __u16 port,
+                             u8 ip_ver, __be16 port,
                              union cma_ip_addr *src, union cma_ip_addr *dst)
 {
        struct sockaddr_in *listen4, *ip4;
@@ -996,7 +996,7 @@ static struct rdma_id_private *cma_new_conn_id(struct rdma_cm_id *listen_id,
        struct rdma_cm_id *id;
        struct rdma_route *rt;
        union cma_ip_addr *src, *dst;
-       __u16 port;
+       __be16 port;
        u8 ip_ver;
 
        if (cma_get_net_info(ib_event->private_data, listen_id->ps,
@@ -1043,7 +1043,7 @@ static struct rdma_id_private *cma_new_udp_id(struct rdma_cm_id *listen_id,
        struct rdma_id_private *id_priv;
        struct rdma_cm_id *id;
        union cma_ip_addr *src, *dst;
-       __u16 port;
+       __be16 port;
        u8 ip_ver;
        int ret;
 
@@ -1165,7 +1165,7 @@ static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr,
 {
        struct cma_hdr *cma_data, *cma_mask;
        struct sdp_hh *sdp_data, *sdp_mask;
-       __u32 ip4_addr;
+       __be32 ip4_addr;
        struct in6_addr ip6_addr;
 
        memset(compare, 0, sizeof *compare);
@@ -1181,12 +1181,12 @@ static void cma_set_compare_data(enum rdma_port_space ps, struct sockaddr *addr,
                        sdp_set_ip_ver(sdp_data, 4);
                        sdp_set_ip_ver(sdp_mask, 0xF);
                        sdp_data->dst_addr.ip4.addr = ip4_addr;
-                       sdp_mask->dst_addr.ip4.addr = ~0;
+                       sdp_mask->dst_addr.ip4.addr = htonl(~0);
                } else {
                        cma_set_ip_ver(cma_data, 4);
                        cma_set_ip_ver(cma_mask, 0xF);
                        cma_data->dst_addr.ip4.addr = ip4_addr;
-                       cma_mask->dst_addr.ip4.addr = ~0;
+                       cma_mask->dst_addr.ip4.addr = htonl(~0);
                }
                break;
        case AF_INET6:
index 320f2b6..99f2f2a 100644 (file)
@@ -1745,7 +1745,7 @@ int iwch_accept_cr(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param)
 
        /* bind QP to EP and move to RTS */
        attrs.mpa_attr = ep->mpa_attr;
-       attrs.max_ird = ep->ord;
+       attrs.max_ird = ep->ird;
        attrs.max_ord = ep->ord;
        attrs.llp_stream_handle = ep;
        attrs.next_state = IWCH_QP_STATE_RTS;
index c36d110..7d61a96 100644 (file)
@@ -63,8 +63,6 @@ static int apmpower_connect(struct input_handler *handler,
        handle->handler = handler;
        handle->name = "apm-power";
 
-       handler->private = handle;
-
        error = input_register_handle(handle);
        if (error) {
                printk(KERN_ERR
@@ -87,11 +85,10 @@ static int apmpower_connect(struct input_handler *handler,
        return 0;
 }
 
-static void apmpower_disconnect(struct input_handle *handler)
+static void apmpower_disconnect(struct input_handle *handle)
 {
-       struct input_handle *handle = handler->private;
-
        input_close_device(handle);
+       input_unregister_handle(handle);
        kfree(handle);
 }
 
index 0727b0a..b32984b 100644 (file)
@@ -124,6 +124,7 @@ static void evdev_free(struct device *dev)
 {
        struct evdev *evdev = container_of(dev, struct evdev, dev);
 
+       input_put_device(evdev->handle.dev);
        kfree(evdev);
 }
 
@@ -893,7 +894,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
        evdev->exist = 1;
        evdev->minor = minor;
 
-       evdev->handle.dev = dev;
+       evdev->handle.dev = input_get_device(dev);
        evdev->handle.name = evdev->name;
        evdev->handle.handler = handler;
        evdev->handle.private = evdev;
index 22b2789..65d7077 100644 (file)
@@ -171,6 +171,7 @@ static void joydev_free(struct device *dev)
 {
        struct joydev *joydev = container_of(dev, struct joydev, dev);
 
+       input_put_device(joydev->handle.dev);
        kfree(joydev);
 }
 
@@ -750,7 +751,7 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev,
        joydev->minor = minor;
 
        joydev->exist = 1;
-       joydev->handle.dev = dev;
+       joydev->handle.dev = input_get_device(dev);
        joydev->handle.name = joydev->name;
        joydev->handle.handler = handler;
        joydev->handle.private = joydev;
index 6224c2f..4e651c1 100644 (file)
@@ -50,9 +50,9 @@
 #define KPKDI           0x0048
 
 /* bit definitions */
-#define KPC_MKRN(n)    ((((n) & 0x7) - 1) << 26) /* matrix key row number */
-#define KPC_MKCN(n)    ((((n) & 0x7) - 1) << 23) /* matrix key column number */
-#define KPC_DKN(n)     ((((n) & 0x7) - 1) << 6)  /* direct key number */
+#define KPC_MKRN(n)    ((((n) - 1) & 0x7) << 26) /* matrix key row number */
+#define KPC_MKCN(n)    ((((n) - 1) & 0x7) << 23) /* matrix key column number */
+#define KPC_DKN(n)     ((((n) - 1) & 0x7) << 6)  /* direct key number */
 
 #define KPC_AS          (0x1 << 30)  /* Automatic Scan bit */
 #define KPC_ASACT       (0x1 << 29)  /* Automatic Scan on Activity */
index d2ade74..798d84c 100644 (file)
@@ -25,6 +25,7 @@
 MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("ixp4xx beeper driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ixp4xx-beeper");
 
 static DEFINE_SPINLOCK(beep_lock);
 
index bbbe5e8..b989748 100644 (file)
@@ -414,6 +414,7 @@ static void mousedev_free(struct device *dev)
 {
        struct mousedev *mousedev = container_of(dev, struct mousedev, dev);
 
+       input_put_device(mousedev->handle.dev);
        kfree(mousedev);
 }
 
@@ -865,7 +866,7 @@ static struct mousedev *mousedev_create(struct input_dev *dev,
 
        mousedev->minor = minor;
        mousedev->exist = 1;
-       mousedev->handle.dev = dev;
+       mousedev->handle.dev = input_get_device(dev);
        mousedev->handle.name = mousedev->name;
        mousedev->handle.handler = handler;
        mousedev->handle.private = mousedev;
index 6c0a9c4..4c0b058 100644 (file)
@@ -49,13 +49,13 @@ static void gpio_led_set(struct led_classdev *led_cdev,
        if (led_dat->active_low)
                level = !level;
 
-       /* setting GPIOs with I2C/etc requires a preemptible task context */
+       /* Setting GPIOs with I2C/etc requires a task context, and we don't
+        * seem to have a reliable way to know if we're already in one; so
+        * let's just assume the worst.
+        */
        if (led_dat->can_sleep) {
-               if (preempt_count()) {
-                       led_dat->new_level = level;
-                       schedule_work(&led_dat->work);
-               } else
-                       gpio_set_value_cansleep(led_dat->gpio, level);
+               led_dat->new_level = level;
+               schedule_work(&led_dat->work);
        } else
                gpio_set_value(led_dat->gpio, level);
 }
@@ -79,6 +79,10 @@ static int gpio_led_probe(struct platform_device *pdev)
                cur_led = &pdata->leds[i];
                led_dat = &leds_data[i];
 
+               ret = gpio_request(cur_led->gpio, cur_led->name);
+               if (ret < 0)
+                       goto err;
+
                led_dat->cdev.name = cur_led->name;
                led_dat->cdev.default_trigger = cur_led->default_trigger;
                led_dat->gpio = cur_led->gpio;
@@ -87,10 +91,6 @@ static int gpio_led_probe(struct platform_device *pdev)
                led_dat->cdev.brightness_set = gpio_led_set;
                led_dat->cdev.brightness = LED_OFF;
 
-               ret = gpio_request(led_dat->gpio, led_dat->cdev.name);
-               if (ret < 0)
-                       goto err;
-
                gpio_direction_output(led_dat->gpio, led_dat->active_low);
 
                INIT_WORK(&led_dat->work, gpio_led_work);
index 5e8272d..7d463c2 100644 (file)
@@ -19,3 +19,11 @@ Beer:
        @for f in Preparation Guest Drivers Launcher Host Switcher Mastery; do echo "{==- $$f -==}"; make -s $$f; done; echo "{==-==}"
 Preparation Preparation! Guest Drivers Launcher Host Switcher Mastery:
        @sh ../../Documentation/lguest/extract $(PREFIX) `find ../../* -name '*.[chS]' -wholename '*lguest*'`
+Puppy:
+       @clear
+       @printf "      __  \n (___()'\`;\n /,    /\`\n \\\\\\\"--\\\\\\   \n"
+       @sleep 2; clear; printf "\n\n   Sit!\n\n"; sleep 1; clear
+       @printf "    __    \n   ()'\`;  \n   /\\|\` \n  /  |  \n(/_)_|_   \n"
+       @sleep 2; clear; printf "\n\n  Stand!\n\n"; sleep 1; clear
+       @printf "    __    \n   ()'\`;  \n   /\\|\` \n  /._.= \n /| /     \n(_\_)_    \n"
+       @sleep 2; clear; printf "\n\n  Good puppy!\n\n"; sleep 1; clear
index c632c08..5eea435 100644 (file)
@@ -1,8 +1,6 @@
 /*P:400 This contains run_guest() which actually calls into the Host<->Guest
  * Switcher and analyzes the return, such as determining if the Guest wants the
- * Host to do something.  This file also contains useful helper routines, and a
- * couple of non-obvious setup and teardown pieces which were implemented after
- * days of debugging pain. :*/
+ * Host to do something.  This file also contains useful helper routines. :*/
 #include <linux/module.h>
 #include <linux/stringify.h>
 #include <linux/stddef.h>
@@ -49,8 +47,8 @@ static __init int map_switcher(void)
         * easy.
         */
 
-       /* We allocate an array of "struct page"s.  map_vm_area() wants the
-        * pages in this form, rather than just an array of pointers. */
+       /* We allocate an array of struct page pointers.  map_vm_area() wants
+        * this, rather than just an array of pages. */
        switcher_page = kmalloc(sizeof(switcher_page[0])*TOTAL_SWITCHER_PAGES,
                                GFP_KERNEL);
        if (!switcher_page) {
@@ -172,7 +170,7 @@ void __lgread(struct lg_cpu *cpu, void *b, unsigned long addr, unsigned bytes)
        }
 }
 
-/* This is the write (copy into guest) version. */
+/* This is the write (copy into Guest) version. */
 void __lgwrite(struct lg_cpu *cpu, unsigned long addr, const void *b,
               unsigned bytes)
 {
@@ -209,9 +207,9 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
                if (cpu->break_out)
                        return -EAGAIN;
 
-               /* Check if there are any interrupts which can be delivered
-                * now: if so, this sets up the hander to be executed when we
-                * next run the Guest. */
+               /* Check if there are any interrupts which can be delivered now:
+                * if so, this sets up the hander to be executed when we next
+                * run the Guest. */
                maybe_do_interrupt(cpu);
 
                /* All long-lived kernel loops need to check with this horrible
@@ -246,8 +244,10 @@ int run_guest(struct lg_cpu *cpu, unsigned long __user *user)
                lguest_arch_handle_trap(cpu);
        }
 
+       /* Special case: Guest is 'dead' but wants a reboot. */
        if (cpu->lg->dead == ERR_PTR(-ERESTART))
                return -ERESTART;
+
        /* The Guest is dead => "No such file or directory" */
        return -ENOENT;
 }
index 0f2cb4f..54d66f0 100644 (file)
@@ -29,7 +29,7 @@
 #include "lg.h"
 
 /*H:120 This is the core hypercall routine: where the Guest gets what it wants.
- * Or gets killed.  Or, in the case of LHCALL_CRASH, both. */
+ * Or gets killed.  Or, in the case of LHCALL_SHUTDOWN, both. */
 static void do_hcall(struct lg_cpu *cpu, struct hcall_args *args)
 {
        switch (args->arg0) {
@@ -190,6 +190,13 @@ static void initialize(struct lg_cpu *cpu)
         * pagetable. */
        guest_pagetable_clear_all(cpu);
 }
+/*:*/
+
+/*M:013 If a Guest reads from a page (so creates a mapping) that it has never
+ * written to, and then the Launcher writes to it (ie. the output of a virtual
+ * device), the Guest will still see the old page.  In practice, this never
+ * happens: why would the Guest read a page which it has never written to?  But
+ * a similar scenario might one day bite us, so it's worth mentioning. :*/
 
 /*H:100
  * Hypercalls
@@ -227,7 +234,7 @@ void do_hypercalls(struct lg_cpu *cpu)
                 * However, if we are signalled or the Guest sends I/O to the
                 * Launcher, the run_guest() loop will exit without running the
                 * Guest.  When it comes back it would try to re-run the
-                * hypercall. */
+                * hypercall.  Finding that bug sucked. */
                cpu->hcall = NULL;
        }
 }
index 32e97c1..0414ddf 100644 (file)
@@ -144,7 +144,6 @@ void maybe_do_interrupt(struct lg_cpu *cpu)
        if (copy_from_user(&blk, cpu->lg->lguest_data->blocked_interrupts,
                           sizeof(blk)))
                return;
-
        bitmap_andnot(blk, cpu->irqs_pending, blk, LGUEST_IRQS);
 
        /* Find the first interrupt. */
@@ -237,9 +236,9 @@ void free_interrupts(void)
                clear_bit(syscall_vector, used_vectors);
 }
 
-/*H:220 Now we've got the routines to deliver interrupts, delivering traps
- * like page fault is easy.  The only trick is that Intel decided that some
- * traps should have error codes: */
+/*H:220 Now we've got the routines to deliver interrupts, delivering traps like
+ * page fault is easy.  The only trick is that Intel decided that some traps
+ * should have error codes: */
 static int has_err(unsigned int trap)
 {
        return (trap == 8 || (trap >= 10 && trap <= 14) || trap == 17);
index 1b2ec0b..2bc9bf7 100644 (file)
@@ -1,10 +1,10 @@
 /*P:050 Lguest guests use a very simple method to describe devices.  It's a
- * series of device descriptors contained just above the top of normal
+ * series of device descriptors contained just above the top of normal Guest
  * memory.
  *
  * We use the standard "virtio" device infrastructure, which provides us with a
  * console, a network and a block driver.  Each one expects some configuration
- * information and a "virtqueue" mechanism to send and receive data. :*/
+ * information and a "virtqueue" or two to send and receive data. :*/
 #include <linux/init.h>
 #include <linux/bootmem.h>
 #include <linux/lguest_launcher.h>
@@ -53,7 +53,7 @@ struct lguest_device {
  * Device configurations
  *
  * The configuration information for a device consists of one or more
- * virtqueues, a feature bitmaks, and some configuration bytes.  The
+ * virtqueues, a feature bitmap, and some configuration bytes.  The
  * configuration bytes don't really matter to us: the Launcher sets them up, and
  * the driver will look at them during setup.
  *
@@ -179,7 +179,7 @@ struct lguest_vq_info
 };
 
 /* When the virtio_ring code wants to prod the Host, it calls us here and we
- * make a hypercall.  We hand the page number of the virtqueue so the Host
+ * make a hypercall.  We hand the physical address of the virtqueue so the Host
  * knows which virtqueue we're talking about. */
 static void lg_notify(struct virtqueue *vq)
 {
@@ -199,7 +199,8 @@ static void lg_notify(struct virtqueue *vq)
  * allocate its own pages and tell the Host where they are, but for lguest it's
  * simpler for the Host to simply tell us where the pages are.
  *
- * So we provide devices with a "find virtqueue and set it up" function. */
+ * So we provide drivers with a "find the Nth virtqueue and set it up"
+ * function. */
 static struct virtqueue *lg_find_vq(struct virtio_device *vdev,
                                    unsigned index,
                                    void (*callback)(struct virtqueue *vq))
index 2221485..645e6e0 100644 (file)
@@ -73,7 +73,7 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
        if (current != cpu->tsk)
                return -EPERM;
 
-       /* If the guest is already dead, we indicate why */
+       /* If the Guest is already dead, we indicate why */
        if (lg->dead) {
                size_t len;
 
@@ -88,7 +88,7 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
                return len;
        }
 
-       /* If we returned from read() last time because the Guest notified,
+       /* If we returned from read() last time because the Guest sent I/O,
         * clear the flag. */
        if (cpu->pending_notify)
                cpu->pending_notify = 0;
@@ -97,14 +97,20 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
        return run_guest(cpu, (unsigned long __user *)user);
 }
 
+/*L:025 This actually initializes a CPU.  For the moment, a Guest is only
+ * uniprocessor, so "id" is always 0. */
 static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip)
 {
+       /* We have a limited number the number of CPUs in the lguest struct. */
        if (id >= NR_CPUS)
                return -EINVAL;
 
+       /* Set up this CPU's id, and pointer back to the lguest struct. */
        cpu->id = id;
        cpu->lg = container_of((cpu - id), struct lguest, cpus[0]);
        cpu->lg->nr_cpus++;
+
+       /* Each CPU has a timer it can set. */
        init_clockdev(cpu);
 
        /* We need a complete page for the Guest registers: they are accessible
@@ -120,11 +126,11 @@ static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip)
         * address. */
        lguest_arch_setup_regs(cpu, start_ip);
 
-       /* Initialize the queue for the waker to wait on */
+       /* Initialize the queue for the Waker to wait on */
        init_waitqueue_head(&cpu->break_wq);
 
        /* We keep a pointer to the Launcher task (ie. current task) for when
-        * other Guests want to wake this one (inter-Guest I/O). */
+        * other Guests want to wake this one (eg. console input). */
        cpu->tsk = current;
 
        /* We need to keep a pointer to the Launcher's memory map, because if
@@ -136,6 +142,7 @@ static int lg_cpu_start(struct lg_cpu *cpu, unsigned id, unsigned long start_ip)
         * when the same Guest runs on the same CPU twice. */
        cpu->last_pages = NULL;
 
+       /* No error == success. */
        return 0;
 }
 
@@ -182,17 +189,16 @@ static int initialize(struct file *file, const unsigned long __user *input)
        }
 
        /* Populate the easy fields of our "struct lguest" */
-       lg->mem_base = (void __user *)(long)args[0];
+       lg->mem_base = (void __user *)args[0];
        lg->pfn_limit = args[1];
 
-       /* This is the first cpu */
+       /* This is the first cpu (cpu 0) and it will start booting at args[3] */
        err = lg_cpu_start(&lg->cpus[0], 0, args[3]);
        if (err)
                goto release_guest;
 
        /* Initialize the Guest's shadow page tables, using the toplevel
-        * address the Launcher gave us.  This allocates memory, so can
-        * fail. */
+        * address the Launcher gave us.  This allocates memory, so can fail. */
        err = init_guest_pagetable(lg, args[2]);
        if (err)
                goto free_regs;
@@ -218,11 +224,16 @@ unlock:
 /*L:010 The first operation the Launcher does must be a write.  All writes
  * start with an unsigned long number: for the first write this must be
  * LHREQ_INITIALIZE to set up the Guest.  After that the Launcher can use
- * writes of other values to send interrupts. */
+ * writes of other values to send interrupts.
+ *
+ * Note that we overload the "offset" in the /dev/lguest file to indicate what
+ * CPU number we're dealing with.  Currently this is always 0, since we only
+ * support uniprocessor Guests, but you can see the beginnings of SMP support
+ * here. */
 static ssize_t write(struct file *file, const char __user *in,
                     size_t size, loff_t *off)
 {
-       /* Once the guest is initialized, we hold the "struct lguest" in the
+       /* Once the Guest is initialized, we hold the "struct lguest" in the
         * file private data. */
        struct lguest *lg = file->private_data;
        const unsigned long __user *input = (const unsigned long __user *)in;
@@ -230,6 +241,7 @@ static ssize_t write(struct file *file, const char __user *in,
        struct lg_cpu *uninitialized_var(cpu);
        unsigned int cpu_id = *off;
 
+       /* The first value tells us what this request is. */
        if (get_user(req, input) != 0)
                return -EFAULT;
        input++;
index a7f64a9..d93500f 100644 (file)
@@ -2,8 +2,8 @@
  * previous encounters.  It's functional, and as neat as it can be in the
  * circumstances, but be wary, for these things are subtle and break easily.
  * The Guest provides a virtual to physical mapping, but we can neither trust
- * it nor use it: we verify and convert it here to point the hardware to the
- * actual Guest pages when running the Guest. :*/
+ * it nor use it: we verify and convert it here then point the CPU to the
+ * converted Guest pages when running the Guest. :*/
 
 /* Copyright (C) Rusty Russell IBM Corporation 2006.
  * GPL v2 and any later version */
@@ -106,6 +106,11 @@ static unsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr)
        BUG_ON(!(pgd_flags(gpgd) & _PAGE_PRESENT));
        return gpage + ((vaddr>>PAGE_SHIFT) % PTRS_PER_PTE) * sizeof(pte_t);
 }
+/*:*/
+
+/*M:014 get_pfn is slow; it takes the mmap sem and calls get_user_pages.  We
+ * could probably try to grab batches of pages here as an optimization
+ * (ie. pre-faulting). :*/
 
 /*H:350 This routine takes a page number given by the Guest and converts it to
  * an actual, physical page number.  It can fail for several reasons: the
@@ -113,8 +118,8 @@ static unsigned long gpte_addr(pgd_t gpgd, unsigned long vaddr)
  * and the page is read-only, or the write flag was set and the page was
  * shared so had to be copied, but we ran out of memory.
  *
- * This holds a reference to the page, so release_pte() is careful to
- * put that back. */
+ * This holds a reference to the page, so release_pte() is careful to put that
+ * back. */
 static unsigned long get_pfn(unsigned long virtpfn, int write)
 {
        struct page *page;
@@ -532,13 +537,13 @@ static void do_set_pte(struct lg_cpu *cpu, int idx,
  * all processes.  So when the page table above that address changes, we update
  * all the page tables, not just the current one.  This is rare.
  *
- * The benefit is that when we have to track a new page table, we can copy keep
- * all the kernel mappings.  This speeds up context switch immensely. */
+ * The benefit is that when we have to track a new page table, we can keep all
+ * the kernel mappings.  This speeds up context switch immensely. */
 void guest_set_pte(struct lg_cpu *cpu,
                   unsigned long gpgdir, unsigned long vaddr, pte_t gpte)
 {
-       /* Kernel mappings must be changed on all top levels.  Slow, but
-        * doesn't happen often. */
+       /* Kernel mappings must be changed on all top levels.  Slow, but doesn't
+        * happen often. */
        if (vaddr >= cpu->lg->kernel_address) {
                unsigned int i;
                for (i = 0; i < ARRAY_SIZE(cpu->lg->pgdirs); i++)
@@ -704,12 +709,11 @@ static __init void populate_switcher_pte_page(unsigned int cpu,
 /* We've made it through the page table code.  Perhaps our tired brains are
  * still processing the details, or perhaps we're simply glad it's over.
  *
- * If nothing else, note that all this complexity in juggling shadow page
- * tables in sync with the Guest's page tables is for one reason: for most
- * Guests this page table dance determines how bad performance will be.  This
- * is why Xen uses exotic direct Guest pagetable manipulation, and why both
- * Intel and AMD have implemented shadow page table support directly into
- * hardware.
+ * If nothing else, note that all this complexity in juggling shadow page tables
+ * in sync with the Guest's page tables is for one reason: for most Guests this
+ * page table dance determines how bad performance will be.  This is why Xen
+ * uses exotic direct Guest pagetable manipulation, and why both Intel and AMD
+ * have implemented shadow page table support directly into hardware.
  *
  * There is just one file remaining in the Host. */
 
index 6351878..5126d5d 100644 (file)
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
+/*P:450 This file contains the x86-specific lguest code.  It used to be all
+ * mixed in with drivers/lguest/core.c but several foolhardy code slashers
+ * wrestled most of the dependencies out to here in preparation for porting
+ * lguest to other architectures (see what I mean by foolhardy?).
+ *
+ * This also contains a couple of non-obvious setup and teardown pieces which
+ * were implemented after days of debugging pain. :*/
 #include <linux/kernel.h>
 #include <linux/start_kernel.h>
 #include <linux/string.h>
@@ -157,6 +164,8 @@ static void run_guest_once(struct lg_cpu *cpu, struct lguest_pages *pages)
  * also simplify copy_in_guest_info().  Note that we'd still need to restore
  * things when we exit to Launcher userspace, but that's fairly easy.
  *
+ * We could also try using this hooks for PGE, but that might be too expensive.
+ *
  * The hooks were designed for KVM, but we can also put them to good use. :*/
 
 /*H:040 This is the i386-specific code to setup and run the Guest.  Interrupts
@@ -182,7 +191,7 @@ void lguest_arch_run_guest(struct lg_cpu *cpu)
         * was doing. */
        run_guest_once(cpu, lguest_pages(raw_smp_processor_id()));
 
-       /* Note that the "regs" pointer contains two extra entries which are
+       /* Note that the "regs" structure contains two extra entries which are
         * not really registers: a trap number which says what interrupt or
         * trap made the switcher code come back, and an error code which some
         * traps set.  */
@@ -293,11 +302,10 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
                break;
        case 14: /* We've intercepted a Page Fault. */
                /* The Guest accessed a virtual address that wasn't mapped.
-                * This happens a lot: we don't actually set up most of the
-                * page tables for the Guest at all when we start: as it runs
-                * it asks for more and more, and we set them up as
-                * required. In this case, we don't even tell the Guest that
-                * the fault happened.
+                * This happens a lot: we don't actually set up most of the page
+                * tables for the Guest at all when we start: as it runs it asks
+                * for more and more, and we set them up as required. In this
+                * case, we don't even tell the Guest that the fault happened.
                 *
                 * The errcode tells whether this was a read or a write, and
                 * whether kernel or userspace code. */
@@ -342,7 +350,7 @@ void lguest_arch_handle_trap(struct lg_cpu *cpu)
        if (!deliver_trap(cpu, cpu->regs->trapnum))
                /* If the Guest doesn't have a handler (either it hasn't
                 * registered any yet, or it's one of the faults we don't let
-                * it handle), it dies with a cryptic error message. */
+                * it handle), it dies with this cryptic error message. */
                kill_guest(cpu, "unhandled trap %li at %#lx (%#lx)",
                           cpu->regs->trapnum, cpu->regs->eip,
                           cpu->regs->trapnum == 14 ? cpu->arch.last_pagefault
@@ -375,8 +383,8 @@ void __init lguest_arch_host_init(void)
         * The only exception is the interrupt handlers in switcher.S: their
         * addresses are placed in a table (default_idt_entries), so we need to
         * update the table with the new addresses.  switcher_offset() is a
-        * convenience function which returns the distance between the builtin
-        * switcher code and the high-mapped copy we just made. */
+        * convenience function which returns the distance between the
+        * compiled-in switcher code and the high-mapped copy we just made. */
        for (i = 0; i < IDT_ENTRIES; i++)
                default_idt_entries[i] += switcher_offset();
 
@@ -416,7 +424,7 @@ void __init lguest_arch_host_init(void)
                state->guest_gdt_desc.address = (long)&state->guest_gdt;
 
                /* We know where we want the stack to be when the Guest enters
-                * the switcher: in pages->regs.  The stack grows upwards, so
+                * the Switcher: in pages->regs.  The stack grows upwards, so
                 * we start it at the end of that structure. */
                state->guest_tss.sp0 = (long)(&pages->regs + 1);
                /* And this is the GDT entry to use for the stack: we keep a
@@ -513,8 +521,8 @@ int lguest_arch_init_hypercalls(struct lg_cpu *cpu)
 {
        u32 tsc_speed;
 
-       /* The pointer to the Guest's "struct lguest_data" is the only
-        * argument.  We check that address now. */
+       /* The pointer to the Guest's "struct lguest_data" is the only argument.
+        * We check that address now. */
        if (!lguest_address_ok(cpu->lg, cpu->hcall->arg1,
                               sizeof(*cpu->lg->lguest_data)))
                return -EFAULT;
@@ -546,6 +554,7 @@ int lguest_arch_init_hypercalls(struct lg_cpu *cpu)
 
        return 0;
 }
+/*:*/
 
 /*L:030 lguest_arch_setup_regs()
  *
index 0af8baa..3fc1531 100644 (file)
@@ -1,6 +1,6 @@
-/*P:900 This is the Switcher: code which sits at 0xFFC00000 to do the low-level
- * Guest<->Host switch.  It is as simple as it can be made, but it's naturally
- * very specific to x86.
+/*P:900 This is the Switcher: code which sits at 0xFFC00000 astride both the
+ * Host and Guest to do the low-level Guest<->Host switch.  It is as simple as
+ * it can be made, but it's naturally very specific to x86.
  *
  * You have now completed Preparation.  If this has whet your appetite; if you
  * are feeling invigorated and refreshed then the next, more challenging stage
@@ -189,7 +189,7 @@ ENTRY(switch_to_guest)
        // Interrupts are turned back on: we are Guest.
        iret
 
-// We treat two paths to switch back to the Host
+// We tread two paths to switch back to the Host
 // Yet both must save Guest state and restore Host
 // So we put the routine in a macro.
 #define SWITCH_TO_HOST                                                 \
index b04f98d..835def1 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2003 Christophe Saout <christophe@saout.de>
  * Copyright (C) 2004 Clemens Fruhwirth <clemens@endorphin.org>
- * Copyright (C) 2006-2007 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2006-2008 Red Hat, Inc. All rights reserved.
  *
  * This file is released under the GPL.
  */
@@ -93,6 +93,8 @@ struct crypt_config {
 
        struct workqueue_struct *io_queue;
        struct workqueue_struct *crypt_queue;
+       wait_queue_head_t writeq;
+
        /*
         * crypto related data
         */
@@ -331,14 +333,7 @@ static void crypt_convert_init(struct crypt_config *cc,
        ctx->idx_out = bio_out ? bio_out->bi_idx : 0;
        ctx->sector = sector + cc->iv_offset;
        init_completion(&ctx->restart);
-       /*
-        * Crypto operation can be asynchronous,
-        * ctx->pending is increased after request submission.
-        * We need to ensure that we don't call the crypt finish
-        * operation before pending got incremented
-        * (dependent on crypt submission return code).
-        */
-       atomic_set(&ctx->pending, 2);
+       atomic_set(&ctx->pending, 1);
 }
 
 static int crypt_convert_block(struct crypt_config *cc,
@@ -411,43 +406,42 @@ static void crypt_alloc_req(struct crypt_config *cc,
 static int crypt_convert(struct crypt_config *cc,
                         struct convert_context *ctx)
 {
-       int r = 0;
+       int r;
 
        while(ctx->idx_in < ctx->bio_in->bi_vcnt &&
              ctx->idx_out < ctx->bio_out->bi_vcnt) {
 
                crypt_alloc_req(cc, ctx);
 
+               atomic_inc(&ctx->pending);
+
                r = crypt_convert_block(cc, ctx, cc->req);
 
                switch (r) {
+               /* async */
                case -EBUSY:
                        wait_for_completion(&ctx->restart);
                        INIT_COMPLETION(ctx->restart);
                        /* fall through*/
                case -EINPROGRESS:
-                       atomic_inc(&ctx->pending);
                        cc->req = NULL;
-                       r = 0;
-                       /* fall through*/
+                       ctx->sector++;
+                       continue;
+
+               /* sync */
                case 0:
+                       atomic_dec(&ctx->pending);
                        ctx->sector++;
                        continue;
-               }
 
-               break;
+               /* error */
+               default:
+                       atomic_dec(&ctx->pending);
+                       return r;
+               }
        }
 
-       /*
-        * If there are pending crypto operation run async
-        * code. Otherwise process return code synchronously.
-        * The step of 2 ensures that async finish doesn't
-        * call crypto finish too early.
-        */
-       if (atomic_sub_return(2, &ctx->pending))
-               return -EINPROGRESS;
-
-       return r;
+       return 0;
 }
 
 static void dm_crypt_bio_destructor(struct bio *bio)
@@ -624,8 +618,10 @@ static void kcryptd_io_read(struct dm_crypt_io *io)
 static void kcryptd_io_write(struct dm_crypt_io *io)
 {
        struct bio *clone = io->ctx.bio_out;
+       struct crypt_config *cc = io->target->private;
 
        generic_make_request(clone);
+       wake_up(&cc->writeq);
 }
 
 static void kcryptd_io(struct work_struct *work)
@@ -698,7 +694,8 @@ static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io)
 
                r = crypt_convert(cc, &io->ctx);
 
-               if (r != -EINPROGRESS) {
+               if (atomic_dec_and_test(&io->ctx.pending)) {
+                       /* processed, no running async crypto  */
                        kcryptd_crypt_write_io_submit(io, r, 0);
                        if (unlikely(r < 0))
                                return;
@@ -706,8 +703,12 @@ static void kcryptd_crypt_write_convert_loop(struct dm_crypt_io *io)
                        atomic_inc(&io->pending);
 
                /* out of memory -> run queues */
-               if (unlikely(remaining))
+               if (unlikely(remaining)) {
+                       /* wait for async crypto then reinitialize pending */
+                       wait_event(cc->writeq, !atomic_read(&io->ctx.pending));
+                       atomic_set(&io->ctx.pending, 1);
                        congestion_wait(WRITE, HZ/100);
+               }
        }
 }
 
@@ -746,7 +747,7 @@ static void kcryptd_crypt_read_convert(struct dm_crypt_io *io)
 
        r = crypt_convert(cc, &io->ctx);
 
-       if (r != -EINPROGRESS)
+       if (atomic_dec_and_test(&io->ctx.pending))
                kcryptd_crypt_read_done(io, r);
 
        crypt_dec_pending(io);
@@ -1047,6 +1048,7 @@ static int crypt_ctr(struct dm_target *ti, unsigned int argc, char **argv)
                goto bad_crypt_queue;
        }
 
+       init_waitqueue_head(&cc->writeq);
        ti->private = cc;
        return 0;
 
index b8e342f..8f25f62 100644 (file)
@@ -114,7 +114,7 @@ static void dec_count(struct io *io, unsigned int region, int error)
                        wake_up_process(io->sleeper);
 
                else {
-                       int r = io->error;
+                       unsigned long r = io->error;
                        io_notify_fn fn = io->callback;
                        void *context = io->context;
 
index 5160587..762cb08 100644 (file)
@@ -753,7 +753,7 @@ out:
  * are in the no-sync state.  We have to recover these by
  * recopying from the default mirror to all the others.
  *---------------------------------------------------------------*/
-static void recovery_complete(int read_err, unsigned int write_err,
+static void recovery_complete(int read_err, unsigned long write_err,
                              void *context)
 {
        struct region *reg = (struct region *)context;
@@ -767,7 +767,7 @@ static void recovery_complete(int read_err, unsigned int write_err,
        }
 
        if (write_err) {
-               DMERR_LIMIT("Write error during recovery (error = 0x%x)",
+               DMERR_LIMIT("Write error during recovery (error = 0x%lx)",
                            write_err);
                /*
                 * Bits correspond to devices (excluding default mirror).
index ae24eab..4dc8a43 100644 (file)
@@ -804,7 +804,7 @@ static void commit_callback(void *context, int success)
  * Called when the copy I/O has finished.  kcopyd actually runs
  * this code so don't block.
  */
-static void copy_callback(int read_err, unsigned int write_err, void *context)
+static void copy_callback(int read_err, unsigned long write_err, void *context)
 {
        struct dm_snap_pending_exception *pe = context;
        struct dm_snapshot *s = pe->snap;
index f3831f3..e76b52a 100644 (file)
@@ -169,7 +169,7 @@ struct kcopyd_job {
         * Error state of the job.
         */
        int read_err;
-       unsigned int write_err;
+       unsigned long write_err;
 
        /*
         * Either READ or WRITE
@@ -293,7 +293,7 @@ static int run_complete_job(struct kcopyd_job *job)
 {
        void *context = job->context;
        int read_err = job->read_err;
-       unsigned int write_err = job->write_err;
+       unsigned long write_err = job->write_err;
        kcopyd_notify_fn fn = job->fn;
        struct kcopyd_client *kc = job->kc;
 
@@ -396,7 +396,7 @@ static int process_jobs(struct list_head *jobs, int (*fn) (struct kcopyd_job *))
                if (r < 0) {
                        /* error this rogue job */
                        if (job->rw == WRITE)
-                               job->write_err = (unsigned int) -1;
+                               job->write_err = (unsigned long) -1L;
                        else
                                job->read_err = 1;
                        push(&_complete_jobs, job);
@@ -448,8 +448,8 @@ static void dispatch_job(struct kcopyd_job *job)
 }
 
 #define SUB_JOB_SIZE 128
-static void segment_complete(int read_err,
-                            unsigned int write_err, void *context)
+static void segment_complete(int read_err, unsigned long write_err,
+                            void *context)
 {
        /* FIXME: tidy this function */
        sector_t progress = 0;
index 4621ea0..4845f2a 100644 (file)
@@ -32,8 +32,8 @@ void kcopyd_client_destroy(struct kcopyd_client *kc);
  * read_err is a boolean,
  * write_err is a bitset, with 1 bit for each destination region
  */
-typedef void (*kcopyd_notify_fn)(int read_err,
-                                unsigned int write_err, void *context);
+typedef void (*kcopyd_notify_fn)(int read_err, unsigned long write_err,
+                                void *context);
 
 int kcopyd_copy(struct kcopyd_client *kc, struct io_region *from,
                unsigned int num_dests, struct io_region *dests,
index 168a8d3..7707b8c 100644 (file)
@@ -306,25 +306,22 @@ static irqreturn_t interrupt_hw(int irq, void *dev_id)
                return IRQ_NONE;
        }
 
-       if( 0 != (dev->ext)) {
-               if( 0 != (dev->ext->irq_mask & isr )) {
-                       if( 0 != dev->ext->irq_func ) {
+       if (dev->ext) {
+               if (dev->ext->irq_mask & isr) {
+                       if (dev->ext->irq_func)
                                dev->ext->irq_func(dev, &isr);
-                       }
                        isr &= ~dev->ext->irq_mask;
                }
        }
        if (0 != (isr & (MASK_27))) {
                DEB_INT(("irq: RPS0 (0x%08x).\n",isr));
-               if( 0 != dev->vv_data && 0 != dev->vv_callback) {
+               if (dev->vv_data && dev->vv_callback)
                        dev->vv_callback(dev,isr);
-               }
                isr &= ~MASK_27;
        }
        if (0 != (isr & (MASK_28))) {
-               if( 0 != dev->vv_data && 0 != dev->vv_callback) {
+               if (dev->vv_data && dev->vv_callback)
                        dev->vv_callback(dev,isr);
-               }
                isr &= ~MASK_28;
        }
        if (0 != (isr & (MASK_16|MASK_17))) {
index f0703d8..171afe7 100644 (file)
@@ -272,7 +272,7 @@ static int fops_open(struct inode *inode, struct file *file)
 
        result = 0;
 out:
-       if( fh != 0 && result != 0 ) {
+       if (fh && result != 0) {
                kfree(fh);
                file->private_data = NULL;
        }
index ed3f826..4c8b62e 100644 (file)
@@ -784,8 +784,8 @@ static int dvb_net_ts_callback(const u8 *buffer1, size_t buffer1_len,
 {
        struct net_device *dev = feed->priv;
 
-       if (buffer2 != 0)
-               printk(KERN_WARNING "buffer2 not 0: %p.\n", buffer2);
+       if (buffer2)
+               printk(KERN_WARNING "buffer2 not NULL: %p.\n", buffer2);
        if (buffer1_len > 32768)
                printk(KERN_WARNING "length > 32k: %zu.\n", buffer1_len);
        /* printk("TS callback: %u bytes, %u TS cells @ %p.\n",
index cbab53f..fea2e72 100644 (file)
@@ -408,7 +408,7 @@ adv7170_detect_client (struct i2c_adapter *adapter,
                return 0;
 
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == 0)
+       if (!client)
                return -ENOMEM;
        client->addr = address;
        client->adapter = adapter;
index 0d0c554..10d4d89 100644 (file)
@@ -426,7 +426,7 @@ adv7175_detect_client (struct i2c_adapter *adapter,
                return 0;
 
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == 0)
+       if (!client)
                return -ENOMEM;
        client->addr = address;
        client->adapter = adapter;
index 12d1b92..e663cc0 100644 (file)
@@ -524,7 +524,7 @@ bt819_detect_client (struct i2c_adapter *adapter,
                return 0;
 
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == 0)
+       if (!client)
                return -ENOMEM;
        client->addr = address;
        client->adapter = adapter;
index e1028a7..7dee2e3 100644 (file)
@@ -311,7 +311,7 @@ bt856_detect_client (struct i2c_adapter *adapter,
                return 0;
 
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == 0)
+       if (!client)
                return -ENOMEM;
        client->addr = address;
        client->adapter = adapter;
index 566e479..9ceb6b2 100644 (file)
@@ -131,7 +131,7 @@ static int dpc_probe(struct saa7146_dev* dev)
        device_for_each_child(&dpc->i2c_adapter.dev, dpc, dpc_check_clients);
 
        /* check if all devices are present */
-       if( 0 == dpc->saa7111a ) {
+       if (!dpc->saa7111a) {
                DEB_D(("dpc_v4l2.o: dpc_attach failed for this device.\n"));
                i2c_del_adapter(&dpc->i2c_adapter);
                kfree(dpc);
index 58bab65..74fd6a0 100644 (file)
@@ -647,7 +647,7 @@ struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
        default:
                tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
                           name);
-               return 0;
+               return NULL;
        }
 
        strlcpy(fe->ops.tuner_ops.info.name, name,
index add6d0d..cb5a510 100644 (file)
@@ -221,9 +221,8 @@ static int mxb_probe(struct saa7146_dev* dev)
        device_for_each_child(&mxb->i2c_adapter.dev, mxb, mxb_check_clients);
 
        /* check if all devices are present */
-       if(    0 == mxb->tea6420_1      || 0 == mxb->tea6420_2  || 0 == mxb->tea6415c
-           || 0 == mxb->tda9840        || 0 == mxb->saa7111a   || 0 == mxb->tuner ) {
-
+       if (!mxb->tea6420_1 || !mxb->tea6420_2 || !mxb->tea6415c ||
+           !mxb->tda9840 || !mxb->saa7111a || !mxb->tuner) {
                printk("mxb: did not find all i2c devices. aborting\n");
                i2c_del_adapter(&mxb->i2c_adapter);
                kfree(mxb);
index 46f156f..5a3e8d2 100644 (file)
@@ -60,7 +60,7 @@ int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
        int ret = 0;
        if (!cptr) return -EINVAL;
        LOCK_TAKE(cptr->hdw->big_lock); do {
-               if (cptr->info->set_value != 0) {
+               if (cptr->info->set_value) {
                        if (cptr->info->type == pvr2_ctl_bitmask) {
                                mask &= cptr->info->def.type_bitmask.valid_bits;
                        } else if (cptr->info->type == pvr2_ctl_int) {
@@ -265,7 +265,7 @@ unsigned int pvr2_ctrl_get_v4lflags(struct pvr2_ctrl *cptr)
 int pvr2_ctrl_is_writable(struct pvr2_ctrl *cptr)
 {
        if (!cptr) return 0;
-       return cptr->info->set_value != 0;
+       return cptr->info->set_value != NULL;
 }
 
 
index 41ae980..d6955fa 100644 (file)
@@ -2291,7 +2291,7 @@ static int pvr2_hdw_commit_setup(struct pvr2_hdw *hdw)
 
        for (idx = 0; idx < hdw->control_cnt; idx++) {
                cptr = hdw->controls + idx;
-               if (cptr->info->is_dirty == 0) continue;
+               if (!cptr->info->is_dirty) continue;
                if (!cptr->info->is_dirty(cptr)) continue;
                commit_flag = !0;
 
@@ -2646,7 +2646,7 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
        u16 address;
        unsigned int pipe;
        LOCK_TAKE(hdw->big_lock); do {
-               if ((hdw->fw_buffer == 0) == !enable_flag) break;
+               if ((hdw->fw_buffer == NULL) == !enable_flag) break;
 
                if (!enable_flag) {
                        pvr2_trace(PVR2_TRACE_FIRMWARE,
@@ -2715,7 +2715,7 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw,
 /* Return true if we're in a mode for retrieval CPU firmware */
 int pvr2_hdw_cpufw_get_enabled(struct pvr2_hdw *hdw)
 {
-       return hdw->fw_buffer != 0;
+       return hdw->fw_buffer != NULL;
 }
 
 
index ce3c898..a9889ff 100644 (file)
@@ -563,7 +563,7 @@ void pvr2_stream_kill(struct pvr2_stream *sp)
        struct pvr2_buffer *bp;
        mutex_lock(&sp->mutex); do {
                pvr2_stream_internal_flush(sp);
-               while ((bp = pvr2_stream_get_ready_buffer(sp)) != 0) {
+               while ((bp = pvr2_stream_get_ready_buffer(sp)) != NULL) {
                        pvr2_buffer_set_idle(bp);
                }
                if (sp->buffer_total_count != sp->buffer_target_count) {
index f782418..c572212 100644 (file)
@@ -165,7 +165,7 @@ static int pvr2_ioread_start(struct pvr2_ioread *cp)
        if (!(cp->stream)) return 0;
        pvr2_trace(PVR2_TRACE_START_STOP,
                   "/*---TRACE_READ---*/ pvr2_ioread_start id=%p",cp);
-       while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != 0) {
+       while ((bp = pvr2_stream_get_idle_buffer(cp->stream)) != NULL) {
                stat = pvr2_buffer_queue(bp);
                if (stat < 0) {
                        pvr2_trace(PVR2_TRACE_DATA_FLOW,
index f991d72..e0a453a 100644 (file)
@@ -915,7 +915,7 @@ static void pwc_iso_stop(struct pwc_device *pdev)
                struct urb *urb;
 
                urb = pdev->sbuf[i].urb;
-               if (urb != 0) {
+               if (urb) {
                        PWC_DEBUG_MEMORY("Unlinking URB %p\n", urb);
                        usb_kill_urb(urb);
                }
@@ -931,7 +931,7 @@ static void pwc_iso_free(struct pwc_device *pdev)
                struct urb *urb;
 
                urb = pdev->sbuf[i].urb;
-               if (urb != 0) {
+               if (urb) {
                        PWC_DEBUG_MEMORY("Freeing URB\n");
                        usb_free_urb(urb);
                        pdev->sbuf[i].urb = NULL;
@@ -1759,8 +1759,7 @@ static int usb_pwc_probe(struct usb_interface *intf, const struct usb_device_id
 
        /* Allocate video_device structure */
        pdev->vdev = video_device_alloc();
-       if (pdev->vdev == 0)
-       {
+       if (!pdev->vdev) {
                PWC_ERROR("Err, cannot allocate video_device struture. Failing probe.");
                kfree(pdev);
                return -ENOMEM;
index 061134a..1df2602 100644 (file)
@@ -488,7 +488,7 @@ saa7110_detect_client (struct i2c_adapter *adapter,
                return 0;
 
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == 0)
+       if (!client)
                return -ENOMEM;
        client->addr = address;
        client->adapter = adapter;
@@ -496,7 +496,7 @@ saa7110_detect_client (struct i2c_adapter *adapter,
        strlcpy(I2C_NAME(client), "saa7110", sizeof(I2C_NAME(client)));
 
        decoder = kzalloc(sizeof(struct saa7110), GFP_KERNEL);
-       if (decoder == 0) {
+       if (!decoder) {
                kfree(client);
                return -ENOMEM;
        }
index 7ae2d64..a0772c5 100644 (file)
@@ -502,7 +502,7 @@ saa7111_detect_client (struct i2c_adapter *adapter,
                return 0;
 
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == 0)
+       if (!client)
                return -ENOMEM;
        client->addr = address;
        client->adapter = adapter;
index 677df51..bf91a4f 100644 (file)
@@ -841,7 +841,7 @@ saa7114_detect_client (struct i2c_adapter *adapter,
                return 0;
 
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == 0)
+       if (!client)
                return -ENOMEM;
        client->addr = address;
        client->adapter = adapter;
index 66cc92c..41f7044 100644 (file)
@@ -403,7 +403,7 @@ saa7185_detect_client (struct i2c_adapter *adapter,
                return 0;
 
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (client == 0)
+       if (!client)
                return -ENOMEM;
        client->addr = address;
        client->adapter = adapter;
index ef494fe..bdca5d2 100644 (file)
@@ -172,7 +172,7 @@ static int detect(struct i2c_adapter *adapter, int address, int kind)
 
        /* allocate memory for client structure */
        client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (0 == client) {
+       if (!client) {
                printk("not enough kernel memory\n");
                return -ENOMEM;
        }
index 523df0b..df2fad9 100644 (file)
@@ -64,7 +64,7 @@ static int detect(struct i2c_adapter *adapter, int address, int kind)
 
        /* allocate memory for client structure */
        client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (0 == client) {
+       if (!client) {
                return -ENOMEM;
        }
 
index ca05cd6..4ff6c63 100644 (file)
@@ -101,7 +101,7 @@ static int tea6420_detect(struct i2c_adapter *adapter, int address, int kind)
 
        /* allocate memory for client structure */
        client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (0 == client) {
+       if (!client) {
                return -ENOMEM;
        }
 
index d28318c..b6e24e7 100644 (file)
@@ -1072,12 +1072,12 @@ static int tvp5150_detect_client(struct i2c_adapter *adapter,
                return 0;
 
        c = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
-       if (c == 0)
+       if (!c)
                return -ENOMEM;
        memcpy(c, &client_template, sizeof(struct i2c_client));
 
        core = kzalloc(sizeof(struct tvp5150), GFP_KERNEL);
-       if (core == 0) {
+       if (!core) {
                kfree(c);
                return -ENOMEM;
        }
index dd3d7d2..fea4946 100644 (file)
@@ -339,7 +339,7 @@ v4l_fbuffer_alloc (struct file *file)
                        /* Use kmalloc */
 
                        mem = kmalloc(fh->v4l_buffers.buffer_size, GFP_KERNEL);
-                       if (mem == 0) {
+                       if (!mem) {
                                dprintk(1,
                                        KERN_ERR
                                        "%s: v4l_fbuffer_alloc() - kmalloc for V4L buf %d failed\n",
index 1b44784..04949c8 100644 (file)
@@ -390,7 +390,7 @@ static int read_frame(struct zr364xx_camera *cam, int framenum)
 }
 
 
-static ssize_t zr364xx_read(struct file *file, char *buf, size_t cnt,
+static ssize_t zr364xx_read(struct file *file, char __user *buf, size_t cnt,
                            loff_t * ppos)
 {
        unsigned long count = cnt;
index eb150df..8577de4 100644 (file)
@@ -182,7 +182,7 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
        struct tifm_dev *sock = host->dev;
        unsigned int length;
        unsigned int off;
-       unsigned int t_size, p_off, p_cnt;
+       unsigned int t_size, p_cnt;
        unsigned char *buf;
        struct page *pg;
        unsigned long flags = 0;
@@ -198,6 +198,8 @@ static unsigned int tifm_ms_transfer_data(struct tifm_ms *host)
                host->block_pos);
 
        while (length) {
+               unsigned int uninitialized_var(p_off);
+
                if (host->req->long_data) {
                        pg = nth_page(sg_page(&host->req->sg),
                                      off >> PAGE_SHIFT);
index 63fb1ff..f6f2d96 100644 (file)
 static inline void asic3_write_register(struct asic3 *asic,
                                 unsigned int reg, u32 value)
 {
-       iowrite16(value, (unsigned long)asic->mapping +
+       iowrite16(value, asic->mapping +
                  (reg >> asic->bus_shift));
 }
 
 static inline u32 asic3_read_register(struct asic3 *asic,
                               unsigned int reg)
 {
-       return ioread16((unsigned long)asic->mapping +
+       return ioread16(asic->mapping +
                        (reg >> asic->bus_shift));
 }
 
index 1cfd7f3..e2e7c05 100644 (file)
@@ -231,7 +231,7 @@ static int acpi_fujitsu_remove(struct acpi_device *device, int type)
 
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
-       fujitsu->acpi_handle = 0;
+       fujitsu->acpi_handle = NULL;
 
        return 0;
 }
index 4f9d4a9..b5f6add 100644 (file)
@@ -106,7 +106,7 @@ static int __devinit ibmasm_init_one(struct pci_dev *pdev, const struct pci_devi
        sp->irq = pdev->irq;
        sp->base_address = ioremap(pci_resource_start(pdev, 0),
                                        pci_resource_len(pdev, 0));
-       if (sp->base_address == 0) {
+       if (!sp->base_address) {
                dev_err(sp->dev, "Failed to ioremap pci memory\n");
                result =  -ENODEV;
                goto error_ioremap;
index c884730..1bfe5d1 100644 (file)
@@ -197,7 +197,7 @@ static int lkdtm_parse_commandline(void)
 {
        int i;
 
-       if (cpoint_name == INVALID || cpoint_type == NONE ||
+       if (cpoint_name == NULL || cpoint_type == NULL ||
                                        cpoint_count < 1 || recur_count < 1)
                return -EINVAL;
 
index f00e04e..bc4649a 100644 (file)
@@ -202,9 +202,8 @@ static int physmap_flash_suspend(struct platform_device *dev, pm_message_t state
        int ret = 0;
        int i;
 
-       if (info)
-               for (i = 0; i < MAX_RESOURCES; i++)
-                       ret |= info->mtd[i]->suspend(info->mtd[i]);
+       for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++)
+               ret |= info->mtd[i]->suspend(info->mtd[i]);
 
        return ret;
 }
@@ -214,9 +213,9 @@ static int physmap_flash_resume(struct platform_device *dev)
        struct physmap_flash_info *info = platform_get_drvdata(dev);
        int i;
 
-       if (info)
-               for (i = 0; i < MAX_RESOURCES; i++)
-                       info->mtd[i]->resume(info->mtd[i]);
+       for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++)
+               info->mtd[i]->resume(info->mtd[i]);
+
        return 0;
 }
 
@@ -225,8 +224,8 @@ static void physmap_flash_shutdown(struct platform_device *dev)
        struct physmap_flash_info *info = platform_get_drvdata(dev);
        int i;
 
-       for (i = 0; i < MAX_RESOURCES; i++)
-               if (info && info->mtd[i]->suspend(info->mtd[i]) == 0)
+       for (i = 0; i < MAX_RESOURCES && info->mtd[i]; i++)
+               if (info->mtd[i]->suspend(info->mtd[i]) == 0)
                        info->mtd[i]->resume(info->mtd[i]);
 }
 #else
index 9189ec8..0f6ac25 100644 (file)
@@ -460,7 +460,7 @@ static int rtc_from4_errstat(struct mtd_info *mtd, struct nand_chip *this,
                        er_stat |= 1 << 1;
                kfree(buf);
        }
-
+out:
        rtn = status;
        if (er_stat == 0) {     /* if ECC is available   */
                rtn = (status & ~NAND_STATUS_FAIL);     /*   clear the error bit */
index ea2a2b5..25f1337 100644 (file)
@@ -2082,6 +2082,11 @@ static int __devinit b44_get_invariants(struct b44 *bp)
                addr = sdev->bus->sprom.et0mac;
                bp->phy_addr = sdev->bus->sprom.et0phyaddr;
        }
+       /* Some ROMs have buggy PHY addresses with the high
+        * bits set (sign extension?). Truncate them to a
+        * valid PHY address. */
+       bp->phy_addr &= 0x1F;
+
        memcpy(bp->dev->dev_addr, addr, 6);
 
        if (!is_valid_ether_addr(&bp->dev->dev_addr[0])){
index cb3c6fa..d16e0e1 100644 (file)
@@ -310,7 +310,7 @@ static inline int __check_agg_selection_timer(struct port *port)
  */
 static inline void __get_rx_machine_lock(struct port *port)
 {
-       spin_lock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
+       spin_lock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
 }
 
 /**
@@ -320,7 +320,7 @@ static inline void __get_rx_machine_lock(struct port *port)
  */
 static inline void __release_rx_machine_lock(struct port *port)
 {
-       spin_unlock(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
+       spin_unlock_bh(&(SLAVE_AD_INFO(port->slave).rx_machine_lock));
 }
 
 /**
index b57bc94..3f58c3d 100644 (file)
@@ -678,12 +678,8 @@ static struct slave *rlb_choose_channel(struct sk_buff *skb, struct bonding *bon
                }
 
                if (!list_empty(&bond->vlan_list)) {
-                       unsigned short vlan_id;
-                       int res = vlan_get_tag(skb, &vlan_id);
-                       if (!res) {
+                       if (!vlan_get_tag(skb, &client_info->vlan_id))
                                client_info->tag = 1;
-                               client_info->vlan_id = vlan_id;
-                       }
                }
 
                if (!client_info->assigned) {
index 0942d82..0f06753 100644 (file)
@@ -383,7 +383,7 @@ struct vlan_entry *bond_next_vlan(struct bonding *bond, struct vlan_entry *curr)
  */
 int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_device *slave_dev)
 {
-       unsigned short vlan_id;
+       unsigned short uninitialized_var(vlan_id);
 
        if (!list_empty(&bond->vlan_list) &&
            !(slave_dev->features & NETIF_F_HW_VLAN_TX) &&
@@ -4528,8 +4528,7 @@ static void bond_free_all(void)
                netif_tx_unlock_bh(bond_dev);
                /* Release the bonded slaves */
                bond_release_all(bond_dev);
-               bond_deinit(bond_dev);
-               unregister_netdevice(bond_dev);
+               bond_destroy(bond);
        }
 
 #ifdef CONFIG_PROC_FS
index 67ccad6..a3c74e2 100644 (file)
@@ -22,8 +22,8 @@
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION    "3.2.4"
-#define DRV_RELDATE    "January 28, 2008"
+#define DRV_VERSION    "3.2.5"
+#define DRV_RELDATE    "March 21, 2008"
 #define DRV_NAME       "bonding"
 #define DRV_DESCRIPTION        "Ethernet Channel Bonding Driver"
 
index db58687..98a6bbd 100644 (file)
@@ -557,9 +557,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
 
        for (i = 0; i < SGE_RXQ_PER_SET; ++i)
                if (q->fl[i].desc) {
-                       spin_lock(&adapter->sge.reg_lock);
+                       spin_lock_irq(&adapter->sge.reg_lock);
                        t3_sge_disable_fl(adapter, q->fl[i].cntxt_id);
-                       spin_unlock(&adapter->sge.reg_lock);
+                       spin_unlock_irq(&adapter->sge.reg_lock);
                        free_rx_bufs(pdev, &q->fl[i]);
                        kfree(q->fl[i].sdesc);
                        dma_free_coherent(&pdev->dev,
@@ -570,9 +570,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
 
        for (i = 0; i < SGE_TXQ_PER_SET; ++i)
                if (q->txq[i].desc) {
-                       spin_lock(&adapter->sge.reg_lock);
+                       spin_lock_irq(&adapter->sge.reg_lock);
                        t3_sge_enable_ecntxt(adapter, q->txq[i].cntxt_id, 0);
-                       spin_unlock(&adapter->sge.reg_lock);
+                       spin_unlock_irq(&adapter->sge.reg_lock);
                        if (q->txq[i].sdesc) {
                                free_tx_desc(adapter, &q->txq[i],
                                             q->txq[i].in_use);
@@ -586,9 +586,9 @@ static void t3_free_qset(struct adapter *adapter, struct sge_qset *q)
                }
 
        if (q->rspq.desc) {
-               spin_lock(&adapter->sge.reg_lock);
+               spin_lock_irq(&adapter->sge.reg_lock);
                t3_sge_disable_rspcntxt(adapter, q->rspq.cntxt_id);
-               spin_unlock(&adapter->sge.reg_lock);
+               spin_unlock_irq(&adapter->sge.reg_lock);
                dma_free_coherent(&pdev->dev,
                                  q->rspq.size * sizeof(struct rsp_desc),
                                  q->rspq.desc, q->rspq.phys_addr);
@@ -2667,7 +2667,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
                (16 * 1024) - SKB_DATA_ALIGN(sizeof(struct skb_shared_info)) :
                MAX_FRAME_SIZE + 2 + sizeof(struct cpl_rx_pkt);
 
-       spin_lock(&adapter->sge.reg_lock);
+       spin_lock_irq(&adapter->sge.reg_lock);
 
        /* FL threshold comparison uses < */
        ret = t3_sge_init_rspcntxt(adapter, q->rspq.cntxt_id, irq_vec_idx,
@@ -2711,7 +2711,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
                        goto err_unlock;
        }
 
-       spin_unlock(&adapter->sge.reg_lock);
+       spin_unlock_irq(&adapter->sge.reg_lock);
 
        q->adap = adapter;
        q->netdev = dev;
@@ -2728,7 +2728,7 @@ int t3_sge_alloc_qset(struct adapter *adapter, unsigned int id, int nports,
        return 0;
 
       err_unlock:
-       spin_unlock(&adapter->sge.reg_lock);
+       spin_unlock_irq(&adapter->sge.reg_lock);
       err:
        t3_free_qset(adapter, q);
        return ret;
index 1fe305c..d63cc93 100644 (file)
@@ -798,8 +798,6 @@ dm9000_init_dm9000(struct net_device *dev)
        /* Set address filter table */
        dm9000_hash_table(dev);
 
-       /* Activate DM9000 */
-       iow(db, DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
        /* Enable TX/RX interrupt mask */
        iow(db, DM9000_IMR, IMR_PAR | IMR_PTM | IMR_PRM);
 
@@ -970,7 +968,7 @@ dm9000_interrupt(int irq, void *dev_id)
 struct dm9000_rxhdr {
        u8      RxPktReady;
        u8      RxStatus;
-       u16     RxLen;
+       __le16  RxLen;
 } __attribute__((__packed__));
 
 /*
@@ -1197,6 +1195,7 @@ dm9000_hash_table(struct net_device *dev)
        int i, oft;
        u32 hash_val;
        u16 hash_table[4];
+       u8 rcr = RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN;
        unsigned long flags;
 
        dm9000_dbg(db, 1, "entering %s\n", __func__);
@@ -1213,6 +1212,12 @@ dm9000_hash_table(struct net_device *dev)
        /* broadcast address */
        hash_table[3] = 0x8000;
 
+       if (dev->flags & IFF_PROMISC)
+               rcr |= RCR_PRMSC;
+
+       if (dev->flags & IFF_ALLMULTI)
+               rcr |= RCR_ALL;
+
        /* the multicast address in Hash Table : 64 bits */
        for (i = 0; i < mc_cnt; i++, mcptr = mcptr->next) {
                hash_val = ether_crc_le(6, mcptr->dmi_addr) & 0x3f;
@@ -1225,6 +1230,7 @@ dm9000_hash_table(struct net_device *dev)
                iow(db, oft++, hash_table[i] >> 8);
        }
 
+       iow(db, DM9000_RCR, rcr);
        spin_unlock_irqrestore(&db->lock, flags);
 }
 
index cdf3090..2d139ec 100644 (file)
@@ -960,7 +960,7 @@ static void e100_get_defaults(struct nic *nic)
 
        /* Template for a freshly allocated RFD */
        nic->blank_rfd.command = 0;
-       nic->blank_rfd.rbd = 0xFFFFFFFF;
+       nic->blank_rfd.rbd = cpu_to_le32(0xFFFFFFFF);
        nic->blank_rfd.size = cpu_to_le16(VLAN_ETH_FRAME_LEN);
 
        /* MII setup */
index 7c4ead3..93b7fb2 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "ehea"
-#define DRV_VERSION    "EHEA_0087"
+#define DRV_VERSION    "EHEA_0089"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
index 21af674..07c742d 100644 (file)
@@ -3108,7 +3108,7 @@ struct ehea_port *ehea_setup_single_port(struct ehea_adapter *adapter,
        dev->vlan_rx_add_vid = ehea_vlan_rx_add_vid;
        dev->vlan_rx_kill_vid = ehea_vlan_rx_kill_vid;
        dev->features = NETIF_F_SG | NETIF_F_FRAGLIST | NETIF_F_TSO
-                     | NETIF_F_HIGHDMA | NETIF_F_HW_CSUM | NETIF_F_HW_VLAN_TX
+                     | NETIF_F_HIGHDMA | NETIF_F_IP_CSUM | NETIF_F_HW_VLAN_TX
                      | NETIF_F_HW_VLAN_RX | NETIF_F_HW_VLAN_FILTER
                      | NETIF_F_LLTX;
        dev->tx_timeout = &ehea_tx_watchdog;
index 6604d96..76ea846 100644 (file)
 /* Receive Descriptor - Advanced */
 union e1000_adv_rx_desc {
        struct {
-               u64 pkt_addr;             /* Packet buffer address */
-               u64 hdr_addr;             /* Header buffer address */
+               __le64 pkt_addr;             /* Packet buffer address */
+               __le64 hdr_addr;             /* Header buffer address */
        } read;
        struct {
                struct {
                        struct {
-                               u16 pkt_info;   /* RSS type, Packet type */
-                               u16 hdr_info;   /* Split Header,
-                                                * header buffer length */
+                               __le16 pkt_info;   /* RSS type, Packet type */
+                               __le16 hdr_info;   /* Split Header,
+                                                   * header buffer length */
                        } lo_dword;
                        union {
-                               u32 rss;          /* RSS Hash */
+                               __le32 rss;          /* RSS Hash */
                                struct {
-                                       u16 ip_id;    /* IP id */
-                                       u16 csum;     /* Packet Checksum */
+                                       __le16 ip_id;    /* IP id */
+                                       __le16 csum;     /* Packet Checksum */
                                } csum_ip;
                        } hi_dword;
                } lower;
                struct {
-                       u32 status_error;     /* ext status/error */
-                       u16 length;           /* Packet length */
-                       u16 vlan;             /* VLAN tag */
+                       __le32 status_error;     /* ext status/error */
+                       __le16 length;           /* Packet length */
+                       __le16 vlan;             /* VLAN tag */
                } upper;
        } wb;  /* writeback */
 };
@@ -97,14 +97,14 @@ union e1000_adv_rx_desc {
 /* Transmit Descriptor - Advanced */
 union e1000_adv_tx_desc {
        struct {
-               u64 buffer_addr;    /* Address of descriptor's data buf */
-               u32 cmd_type_len;
-               u32 olinfo_status;
+               __le64 buffer_addr;    /* Address of descriptor's data buf */
+               __le32 cmd_type_len;
+               __le32 olinfo_status;
        } read;
        struct {
-               u64 rsvd;       /* Reserved */
-               u32 nxtseq_seed;
-               u32 status;
+               __le64 rsvd;       /* Reserved */
+               __le32 nxtseq_seed;
+               __le32 status;
        } wb;
 };
 
@@ -119,10 +119,10 @@ union e1000_adv_tx_desc {
 
 /* Context descriptors */
 struct e1000_adv_tx_context_desc {
-       u32 vlan_macip_lens;
-       u32 seqnum_seed;
-       u32 type_tucmd_mlhl;
-       u32 mss_l4len_idx;
+       __le32 vlan_macip_lens;
+       __le32 seqnum_seed;
+       __le32 type_tucmd_mlhl;
+       __le32 mss_l4len_idx;
 };
 
 #define E1000_ADVTXD_MACLEN_SHIFT    9  /* Adv ctxt desc mac len shift */
index 161fb68..7b2c70a 100644 (file)
@@ -143,35 +143,35 @@ enum e1000_fc_type {
 
 /* Receive Descriptor */
 struct e1000_rx_desc {
-       u64 buffer_addr; /* Address of the descriptor's data buffer */
-       u16 length;      /* Length of data DMAed into data buffer */
-       u16 csum;        /* Packet checksum */
+       __le64 buffer_addr; /* Address of the descriptor's data buffer */
+       __le16 length;      /* Length of data DMAed into data buffer */
+       __le16 csum;        /* Packet checksum */
        u8  status;      /* Descriptor status */
        u8  errors;      /* Descriptor Errors */
-       u16 special;
+       __le16 special;
 };
 
 /* Receive Descriptor - Extended */
 union e1000_rx_desc_extended {
        struct {
-               u64 buffer_addr;
-               u64 reserved;
+               __le64 buffer_addr;
+               __le64 reserved;
        } read;
        struct {
                struct {
-                       u32 mrq;              /* Multiple Rx Queues */
+                       __le32 mrq;              /* Multiple Rx Queues */
                        union {
-                               u32 rss;            /* RSS Hash */
+                               __le32 rss;            /* RSS Hash */
                                struct {
-                                       u16 ip_id;  /* IP id */
-                                       u16 csum;   /* Packet Checksum */
+                                       __le16 ip_id;  /* IP id */
+                                       __le16 csum;   /* Packet Checksum */
                                } csum_ip;
                        } hi_dword;
                } lower;
                struct {
-                       u32 status_error;     /* ext status/error */
-                       u16 length;
-                       u16 vlan;             /* VLAN tag */
+                       __le32 status_error;     /* ext status/error */
+                       __le16 length;
+                       __le16 vlan;             /* VLAN tag */
                } upper;
        } wb;  /* writeback */
 };
@@ -181,49 +181,49 @@ union e1000_rx_desc_extended {
 union e1000_rx_desc_packet_split {
        struct {
                /* one buffer for protocol header(s), three data buffers */
-               u64 buffer_addr[MAX_PS_BUFFERS];
+               __le64 buffer_addr[MAX_PS_BUFFERS];
        } read;
        struct {
                struct {
-                       u32 mrq;              /* Multiple Rx Queues */
+                       __le32 mrq;              /* Multiple Rx Queues */
                        union {
-                               u32 rss;              /* RSS Hash */
+                               __le32 rss;              /* RSS Hash */
                                struct {
-                                       u16 ip_id;    /* IP id */
-                                       u16 csum;     /* Packet Checksum */
+                                       __le16 ip_id;    /* IP id */
+                                       __le16 csum;     /* Packet Checksum */
                                } csum_ip;
                        } hi_dword;
                } lower;
                struct {
-                       u32 status_error;     /* ext status/error */
-                       u16 length0;          /* length of buffer 0 */
-                       u16 vlan;             /* VLAN tag */
+                       __le32 status_error;     /* ext status/error */
+                       __le16 length0;          /* length of buffer 0 */
+                       __le16 vlan;             /* VLAN tag */
                } middle;
                struct {
-                       u16 header_status;
-                       u16 length[3];        /* length of buffers 1-3 */
+                       __le16 header_status;
+                       __le16 length[3];        /* length of buffers 1-3 */
                } upper;
-               u64 reserved;
+               __le64 reserved;
        } wb; /* writeback */
 };
 
 /* Transmit Descriptor */
 struct e1000_tx_desc {
-       u64 buffer_addr;      /* Address of the descriptor's data buffer */
+       __le64 buffer_addr;      /* Address of the descriptor's data buffer */
        union {
-               u32 data;
+               __le32 data;
                struct {
-                       u16 length;    /* Data buffer length */
+                       __le16 length;    /* Data buffer length */
                        u8 cso;        /* Checksum offset */
                        u8 cmd;        /* Descriptor control */
                } flags;
        } lower;
        union {
-               u32 data;
+               __le32 data;
                struct {
                        u8 status;     /* Descriptor status */
                        u8 css;        /* Checksum start */
-                       u16 special;
+                       __le16 special;
                } fields;
        } upper;
 };
@@ -231,49 +231,49 @@ struct e1000_tx_desc {
 /* Offload Context Descriptor */
 struct e1000_context_desc {
        union {
-               u32 ip_config;
+               __le32 ip_config;
                struct {
                        u8 ipcss;      /* IP checksum start */
                        u8 ipcso;      /* IP checksum offset */
-                       u16 ipcse;     /* IP checksum end */
+                       __le16 ipcse;     /* IP checksum end */
                } ip_fields;
        } lower_setup;
        union {
-               u32 tcp_config;
+               __le32 tcp_config;
                struct {
                        u8 tucss;      /* TCP checksum start */
                        u8 tucso;      /* TCP checksum offset */
-                       u16 tucse;     /* TCP checksum end */
+                       __le16 tucse;     /* TCP checksum end */
                } tcp_fields;
        } upper_setup;
-       u32 cmd_and_length;
+       __le32 cmd_and_length;
        union {
-               u32 data;
+               __le32 data;
                struct {
                        u8 status;     /* Descriptor status */
                        u8 hdr_len;    /* Header length */
-                       u16 mss;       /* Maximum segment size */
+                       __le16 mss;       /* Maximum segment size */
                } fields;
        } tcp_seg_setup;
 };
 
 /* Offload data descriptor */
 struct e1000_data_desc {
-       u64 buffer_addr;   /* Address of the descriptor's buffer address */
+       __le64 buffer_addr;   /* Address of the descriptor's buffer address */
        union {
-               u32 data;
+               __le32 data;
                struct {
-                       u16 length;    /* Data buffer length */
+                       __le16 length;    /* Data buffer length */
                        u8 typ_len_ext;
                        u8 cmd;
                } flags;
        } lower;
        union {
-               u32 data;
+               __le32 data;
                struct {
                        u8 status;     /* Descriptor status */
                        u8 popts;      /* Packet Options */
-                       u16 special;
+                       __le16 special;
                } fields;
        } upper;
 };
index 928ce82..aaee02e 100644 (file)
@@ -3254,6 +3254,13 @@ quit_polling:
 
        return 1;
 }
+
+static inline u32 get_head(struct igb_ring *tx_ring)
+{
+       void *end = (struct e1000_tx_desc *)tx_ring->desc + tx_ring->count;
+       return le32_to_cpu(*(volatile __le32 *)end);
+}
+
 /**
  * igb_clean_tx_irq - Reclaim resources after transmit completes
  * @adapter: board private structure
@@ -3275,9 +3282,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter,
        unsigned int total_bytes = 0, total_packets = 0;
 
        rmb();
-       head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc
-                                + tx_ring->count);
-       head = le32_to_cpu(head);
+       head = get_head(tx_ring);
        i = tx_ring->next_to_clean;
        while (1) {
                while (i != head) {
@@ -3312,9 +3317,7 @@ static bool igb_clean_tx_irq(struct igb_adapter *adapter,
                }
                oldhead = head;
                rmb();
-               head = *(volatile u32 *)((struct e1000_tx_desc *)tx_ring->desc
-                                        + tx_ring->count);
-               head = le32_to_cpu(head);
+               head = get_head(tx_ring);
                if (head == oldhead)
                        goto done_cleaning;
        }  /* while (1) */
@@ -3388,7 +3391,7 @@ done_cleaning:
  * @vlan: descriptor vlan field as written by hardware (no le/be conversion)
  * @skb: pointer to sk_buff to be indicated to stack
  **/
-static void igb_receive_skb(struct igb_adapter *adapter, u8 status, u16 vlan,
+static void igb_receive_skb(struct igb_adapter *adapter, u8 status, __le16 vlan,
                            struct sk_buff *skb)
 {
        if (adapter->vlgrp && (status & E1000_RXD_STAT_VP))
@@ -3452,8 +3455,8 @@ static bool igb_clean_rx_irq_adv(struct igb_adapter *adapter,
                 * that case, it fills the header buffer and spills the rest
                 * into the page.
                 */
-               hlen = le16_to_cpu((rx_desc->wb.lower.lo_dword.hdr_info &
-                 E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT);
+               hlen = (le16_to_cpu(rx_desc->wb.lower.lo_dword.hdr_info) &
+                 E1000_RXDADV_HDRBUFLEN_MASK) >> E1000_RXDADV_HDRBUFLEN_SHIFT;
                if (hlen > adapter->rx_ps_hdr_size)
                        hlen = adapter->rx_ps_hdr_size;
 
index 269e6f8..6738b4d 100644 (file)
@@ -2088,14 +2088,12 @@ ixgb_alloc_rx_buffers(struct ixgb_adapter *adapter)
        struct ixgb_buffer *buffer_info;
        struct sk_buff *skb;
        unsigned int i;
-       int num_group_tail_writes;
        long cleancount;
 
        i = rx_ring->next_to_use;
        buffer_info = &rx_ring->buffer_info[i];
        cleancount = IXGB_DESC_UNUSED(rx_ring);
 
-       num_group_tail_writes = IXGB_RX_BUFFER_WRITE;
 
        /* leave three descriptors unused */
        while(--cleancount > 2) {
index 2bc5eaa..7f20a03 100644 (file)
@@ -85,7 +85,7 @@
        (sizeof(struct netxen_cmd_buffer) * adapter->max_tx_desc_count)
 #define RCV_BUFFSIZE   \
        (sizeof(struct netxen_rx_buffer) * rcv_desc->max_rx_desc_count)
-#define find_diff_among(a,b,range) ((a)<=(b)?((b)-(a)):((b)+(range)-(a)))
+#define find_diff_among(a,b,range) ((a)<(b)?((b)-(a)):((b)+(range)-(a)))
 
 #define NETXEN_NETDEV_STATUS           0x1
 #define NETXEN_RCV_PRODUCER_OFFSET     0
@@ -204,7 +204,7 @@ enum {
                        ? RCV_DESC_LRO :        \
                        (RCV_DESC_NORMAL)))
 
-#define MAX_CMD_DESCRIPTORS            1024
+#define MAX_CMD_DESCRIPTORS            4096
 #define MAX_RCV_DESCRIPTORS            16384
 #define MAX_CMD_DESCRIPTORS_HOST       (MAX_CMD_DESCRIPTORS / 4)
 #define MAX_RCV_DESCRIPTORS_1G         (MAX_RCV_DESCRIPTORS / 4)
@@ -818,15 +818,8 @@ struct netxen_adapter_stats {
        u64  badskblen;
        u64  nocmddescriptor;
        u64  polled;
-       u64  uphappy;
-       u64  updropped;
-       u64  uplcong;
-       u64  uphcong;
-       u64  upmcong;
-       u64  updunno;
-       u64  skbfreed;
+       u64  rxdropped;
        u64  txdropped;
-       u64  txnullskb;
        u64  csummed;
        u64  no_rcv;
        u64  rxbytes;
@@ -842,7 +835,6 @@ struct netxen_rcv_desc_ctx {
        u32 flags;
        u32 producer;
        u32 rcv_pending;        /* Num of bufs posted in phantom */
-       u32 rcv_free;           /* Num of bufs in free list */
        dma_addr_t phys_addr;
        struct pci_dev *phys_pdev;
        struct rcv_desc *desc_head;     /* address of rx ring in Phantom */
@@ -889,8 +881,6 @@ struct netxen_adapter {
        int mtu;
        int portnum;
 
-       spinlock_t tx_lock;
-       spinlock_t lock;
        struct work_struct watchdog_task;
        struct timer_list watchdog_timer;
        struct work_struct  tx_timeout_task;
@@ -899,16 +889,12 @@ struct netxen_adapter {
 
        u32 cmd_producer;
        __le32 *cmd_consumer;
-
        u32 last_cmd_consumer;
+
        u32 max_tx_desc_count;
        u32 max_rx_desc_count;
        u32 max_jumbo_rx_desc_count;
        u32 max_lro_rx_desc_count;
-       /* Num of instances active on cmd buffer ring */
-       u32 proc_cmd_buf_counter;
-
-       u32 num_threads, total_threads; /*Use to keep track of xmit threads */
 
        u32 flags;
        u32 irq;
@@ -942,6 +928,7 @@ struct netxen_adapter {
        struct pci_dev *ctx_desc_pdev;
        dma_addr_t ctx_desc_phys_addr;
        int intr_scheme;
+       int msi_mode;
        int (*enable_phy_interrupts) (struct netxen_adapter *);
        int (*disable_phy_interrupts) (struct netxen_adapter *);
        void (*handle_phy_intr) (struct netxen_adapter *);
@@ -1075,12 +1062,10 @@ void netxen_tso_check(struct netxen_adapter *adapter,
                      struct cmd_desc_type0 *desc, struct sk_buff *skb);
 int netxen_nic_hw_resources(struct netxen_adapter *adapter);
 void netxen_nic_clear_stats(struct netxen_adapter *adapter);
-int netxen_nic_rx_has_work(struct netxen_adapter *adapter);
-int netxen_nic_tx_has_work(struct netxen_adapter *adapter);
 void netxen_watchdog_task(struct work_struct *work);
 void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx,
                            u32 ringid);
-int netxen_process_cmd_ring(unsigned long data);
+int netxen_process_cmd_ring(struct netxen_adapter *adapter);
 u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctx, int max);
 void netxen_nic_set_multi(struct net_device *netdev);
 int netxen_nic_change_mtu(struct net_device *netdev, int new_mtu);
index 7a876f4..6e98d83 100644 (file)
@@ -64,15 +64,7 @@ static const struct netxen_nic_stats netxen_nic_gstrings_stats[] = {
        {"bad_skb_len", NETXEN_NIC_STAT(stats.badskblen)},
        {"no_cmd_desc", NETXEN_NIC_STAT(stats.nocmddescriptor)},
        {"polled", NETXEN_NIC_STAT(stats.polled)},
-       {"uphappy", NETXEN_NIC_STAT(stats.uphappy)},
-       {"updropped", NETXEN_NIC_STAT(stats.updropped)},
-       {"uplcong", NETXEN_NIC_STAT(stats.uplcong)},
-       {"uphcong", NETXEN_NIC_STAT(stats.uphcong)},
-       {"upmcong", NETXEN_NIC_STAT(stats.upmcong)},
-       {"updunno", NETXEN_NIC_STAT(stats.updunno)},
-       {"skb_freed", NETXEN_NIC_STAT(stats.skbfreed)},
        {"tx_dropped", NETXEN_NIC_STAT(stats.txdropped)},
-       {"tx_null_skb", NETXEN_NIC_STAT(stats.txnullskb)},
        {"csummed", NETXEN_NIC_STAT(stats.csummed)},
        {"no_rcv", NETXEN_NIC_STAT(stats.no_rcv)},
        {"rx_bytes", NETXEN_NIC_STAT(stats.rxbytes)},
index d72f8f8..160f605 100644 (file)
@@ -456,6 +456,12 @@ enum {
 #define ISR_INT_MASK_SLOW      (NETXEN_PCIX_PS_REG(PCIX_INT_MASK))
 #define ISR_INT_TARGET_STATUS  (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS))
 #define ISR_INT_TARGET_MASK    (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK))
+#define ISR_INT_TARGET_STATUS_F1   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F1))
+#define ISR_INT_TARGET_MASK_F1     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F1))
+#define ISR_INT_TARGET_STATUS_F2   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F2))
+#define ISR_INT_TARGET_MASK_F2     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F2))
+#define ISR_INT_TARGET_STATUS_F3   (NETXEN_PCIX_PS_REG(PCIX_TARGET_STATUS_F3))
+#define ISR_INT_TARGET_MASK_F3     (NETXEN_PCIX_PS_REG(PCIX_TARGET_MASK_F3))
 
 #define NETXEN_PCI_MAPSIZE     128
 #define NETXEN_PCI_DDR_NET     (0x00000000UL)
@@ -662,6 +668,12 @@ enum {
 
 #define PCIX_TARGET_STATUS     (0x10118)
 #define PCIX_TARGET_MASK       (0x10128)
+#define PCIX_TARGET_STATUS_F1 (0x10160)
+#define PCIX_TARGET_MASK_F1   (0x10170)
+#define PCIX_TARGET_STATUS_F2 (0x10164)
+#define PCIX_TARGET_MASK_F2   (0x10174)
+#define PCIX_TARGET_STATUS_F3 (0x10168)
+#define PCIX_TARGET_MASK_F3   (0x10178)
 
 #define PCIX_MSI_F0            (0x13000)
 #define PCIX_MSI_F1            (0x13004)
index 0135570..05748ca 100644 (file)
@@ -398,6 +398,8 @@ int netxen_nic_hw_resources(struct netxen_adapter *adapter)
                NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_FW));
        printk(KERN_NOTICE "%s: FW capabilities:0x%x\n", netxen_nic_driver_name,
                        adapter->intr_scheme);
+       adapter->msi_mode = readl(
+               NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_FW));
        DPRINTK(INFO, "Receive Peg ready too. starting stuff\n");
 
        addr = netxen_alloc(adapter->ahw.pdev,
index 9e38bcb..45fa33e 100644 (file)
@@ -145,6 +145,8 @@ int netxen_init_firmware(struct netxen_adapter *adapter)
        /* Window 1 call */
        writel(INTR_SCHEME_PERPORT,
               NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_CAPABILITIES_HOST));
+       writel(MSI_MODE_MULTIFUNC,
+              NETXEN_CRB_NORMALIZE(adapter, CRB_NIC_MSI_MODE_HOST));
        writel(MPORT_MULTI_FUNCTION_MODE,
               NETXEN_CRB_NORMALIZE(adapter, CRB_MPORT_MODE));
        writel(PHAN_INITIALIZE_ACK,
@@ -183,7 +185,6 @@ void netxen_initialize_adapter_sw(struct netxen_adapter *adapter)
                for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
                        struct netxen_rx_buffer *rx_buf;
                        rcv_desc = &adapter->recv_ctx[ctxid].rcv_desc[ring];
-                       rcv_desc->rcv_free = rcv_desc->max_rx_desc_count;
                        rcv_desc->begin_alloc = 0;
                        rx_buf = rcv_desc->rx_buf_arr;
                        num_rx_bufs = rcv_desc->max_rx_desc_count;
@@ -974,28 +975,6 @@ int netxen_phantom_init(struct netxen_adapter *adapter, int pegtune_val)
        return 0;
 }
 
-int netxen_nic_rx_has_work(struct netxen_adapter *adapter)
-{
-       int ctx;
-
-       for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
-               struct netxen_recv_context *recv_ctx =
-                   &(adapter->recv_ctx[ctx]);
-               u32 consumer;
-               struct status_desc *desc_head;
-               struct status_desc *desc;
-
-               consumer = recv_ctx->status_rx_consumer;
-               desc_head = recv_ctx->rcv_status_desc_head;
-               desc = &desc_head[consumer];
-
-               if (netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)
-                       return 1;
-       }
-
-       return 0;
-}
-
 static int netxen_nic_check_temp(struct netxen_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
@@ -1038,7 +1017,6 @@ static int netxen_nic_check_temp(struct netxen_adapter *adapter)
 
 void netxen_watchdog_task(struct work_struct *work)
 {
-       struct net_device *netdev;
        struct netxen_adapter *adapter =
                container_of(work, struct netxen_adapter, watchdog_task);
 
@@ -1048,20 +1026,6 @@ void netxen_watchdog_task(struct work_struct *work)
        if (adapter->handle_phy_intr)
                adapter->handle_phy_intr(adapter);
 
-       netdev = adapter->netdev;
-       if ((netif_running(netdev)) && !netif_carrier_ok(netdev) &&
-                       netxen_nic_link_ok(adapter) ) {
-               printk(KERN_INFO "%s %s (port %d), Link is up\n",
-                              netxen_nic_driver_name, netdev->name, adapter->portnum);
-               netif_carrier_on(netdev);
-               netif_wake_queue(netdev);
-       } else if(!(netif_running(netdev)) && netif_carrier_ok(netdev)) {
-               printk(KERN_ERR "%s %s Link is Down\n",
-                               netxen_nic_driver_name, netdev->name);
-               netif_carrier_off(netdev);
-               netif_stop_queue(netdev);
-       }
-
        mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
 }
 
@@ -1125,7 +1089,7 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
        skb = (struct sk_buff *)buffer->skb;
 
        if (likely(adapter->rx_csum &&
-                               netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) {
+                       netxen_get_sts_status(sts_data) == STATUS_CKSUM_OK)) {
                adapter->stats.csummed++;
                skb->ip_summed = CHECKSUM_UNNECESSARY;
        } else
@@ -1142,40 +1106,8 @@ static void netxen_process_rcv(struct netxen_adapter *adapter, int ctxid,
        skb->protocol = eth_type_trans(skb, netdev);
 
        ret = netif_receive_skb(skb);
-
-       /*
-        * RH: Do we need these stats on a regular basis. Can we get it from
-        * Linux stats.
-        */
-       switch (ret) {
-       case NET_RX_SUCCESS:
-               adapter->stats.uphappy++;
-               break;
-
-       case NET_RX_CN_LOW:
-               adapter->stats.uplcong++;
-               break;
-
-       case NET_RX_CN_MOD:
-               adapter->stats.upmcong++;
-               break;
-
-       case NET_RX_CN_HIGH:
-               adapter->stats.uphcong++;
-               break;
-
-       case NET_RX_DROP:
-               adapter->stats.updropped++;
-               break;
-
-       default:
-               adapter->stats.updunno++;
-               break;
-       }
-
        netdev->last_rx = jiffies;
 
-       rcv_desc->rcv_free++;
        rcv_desc->rcv_pending--;
 
        /*
@@ -1200,13 +1132,6 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
        u32 producer = 0;
        int count = 0, ring;
 
-       DPRINTK(INFO, "procesing receive\n");
-       /*
-        * we assume in this case that there is only one port and that is
-        * port #1...changes need to be done in firmware to indicate port
-        * number as part of the descriptor. This way we will be able to get
-        * the netdev which is associated with that device.
-        */
        while (count < max) {
                desc = &desc_head[consumer];
                if (!(netxen_get_sts_owner(desc) & STATUS_OWNER_HOST)) {
@@ -1219,11 +1144,8 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
                consumer = (consumer + 1) & (adapter->max_rx_desc_count - 1);
                count++;
        }
-       if (count) {
-               for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++) {
-                       netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
-               }
-       }
+       for (ring = 0; ring < NUM_RCV_DESC_RINGS; ring++)
+               netxen_post_rx_buffers_nodb(adapter, ctxid, ring);
 
        /* update the consumer index in phantom */
        if (count) {
@@ -1233,108 +1155,60 @@ u32 netxen_process_rcv_ring(struct netxen_adapter *adapter, int ctxid, int max)
                /* Window = 1 */
                writel(consumer,
                       NETXEN_CRB_NORMALIZE(adapter,
-                                           recv_crb_registers[adapter->portnum].
+                                   recv_crb_registers[adapter->portnum].
                                            crb_rcv_status_consumer));
-               wmb();
        }
 
        return count;
 }
 
 /* Process Command status ring */
-int netxen_process_cmd_ring(unsigned long data)
+int netxen_process_cmd_ring(struct netxen_adapter *adapter)
 {
-       u32 last_consumer;
-       u32 consumer;
-       struct netxen_adapter *adapter = (struct netxen_adapter *)data;
-       int count1 = 0;
-       int count2 = 0;
+       u32 last_consumer, consumer;
+       int count = 0, i;
        struct netxen_cmd_buffer *buffer;
-       struct pci_dev *pdev;
+       struct pci_dev *pdev = adapter->pdev;
+       struct net_device *netdev = adapter->netdev;
        struct netxen_skb_frag *frag;
-       u32 i;
-       int done;
+       int done = 0;
 
-       spin_lock(&adapter->tx_lock);
        last_consumer = adapter->last_cmd_consumer;
-       DPRINTK(INFO, "procesing xmit complete\n");
-       /* we assume in this case that there is only one port and that is
-        * port #1...changes need to be done in firmware to indicate port
-        * number as part of the descriptor. This way we will be able to get
-        * the netdev which is associated with that device.
-        */
-
        consumer = le32_to_cpu(*(adapter->cmd_consumer));
-       if (last_consumer == consumer) {        /* Ring is empty    */
-               DPRINTK(INFO, "last_consumer %d == consumer %d\n",
-                       last_consumer, consumer);
-               spin_unlock(&adapter->tx_lock);
-               return 1;
-       }
-
-       adapter->proc_cmd_buf_counter++;
-       /*
-        * Not needed - does not seem to be used anywhere.
-        * adapter->cmd_consumer = consumer;
-        */
-       spin_unlock(&adapter->tx_lock);
 
-       while ((last_consumer != consumer) && (count1 < MAX_STATUS_HANDLE)) {
+       while (last_consumer != consumer) {
                buffer = &adapter->cmd_buf_arr[last_consumer];
-               pdev = adapter->pdev;
                if (buffer->skb) {
                        frag = &buffer->frag_array[0];
                        pci_unmap_single(pdev, frag->dma, frag->length,
                                         PCI_DMA_TODEVICE);
                        frag->dma = 0ULL;
                        for (i = 1; i < buffer->frag_count; i++) {
-                               DPRINTK(INFO, "getting fragment no %d\n", i);
                                frag++; /* Get the next frag */
                                pci_unmap_page(pdev, frag->dma, frag->length,
                                               PCI_DMA_TODEVICE);
                                frag->dma = 0ULL;
                        }
 
-                       adapter->stats.skbfreed++;
+                       adapter->stats.xmitfinished++;
                        dev_kfree_skb_any(buffer->skb);
                        buffer->skb = NULL;
-               } else if (adapter->proc_cmd_buf_counter == 1) {
-                       adapter->stats.txnullskb++;
-               }
-               if (unlikely(netif_queue_stopped(adapter->netdev)
-                            && netif_carrier_ok(adapter->netdev))
-                   && ((jiffies - adapter->netdev->trans_start) >
-                       adapter->netdev->watchdog_timeo)) {
-                       SCHEDULE_WORK(&adapter->tx_timeout_task);
                }
 
                last_consumer = get_next_index(last_consumer,
                                               adapter->max_tx_desc_count);
-               count1++;
+               if (++count >= MAX_STATUS_HANDLE)
+                       break;
        }
 
-       count2 = 0;
-       spin_lock(&adapter->tx_lock);
-       if ((--adapter->proc_cmd_buf_counter) == 0) {
+       if (count) {
                adapter->last_cmd_consumer = last_consumer;
-               while ((adapter->last_cmd_consumer != consumer)
-                      && (count2 < MAX_STATUS_HANDLE)) {
-                       buffer =
-                           &adapter->cmd_buf_arr[adapter->last_cmd_consumer];
-                       count2++;
-                       if (buffer->skb)
-                               break;
-                       else
-                               adapter->last_cmd_consumer =
-                                   get_next_index(adapter->last_cmd_consumer,
-                                                  adapter->max_tx_desc_count);
-               }
-       }
-       if (count1 || count2) {
-               if (netif_queue_stopped(adapter->netdev)
-                   && (adapter->flags & NETXEN_NETDEV_STATUS)) {
-                       netif_wake_queue(adapter->netdev);
-                       adapter->flags &= ~NETXEN_NETDEV_STATUS;
+               smp_mb();
+               if (netif_queue_stopped(netdev) && netif_running(netdev)) {
+                       netif_tx_lock(netdev);
+                       netif_wake_queue(netdev);
+                       smp_mb();
+                       netif_tx_unlock(netdev);
                }
        }
        /*
@@ -1350,16 +1224,9 @@ int netxen_process_cmd_ring(unsigned long data)
         * There is still a possible race condition and the host could miss an
         * interrupt. The card has to take care of this.
         */
-       if (adapter->last_cmd_consumer == consumer &&
-           (((adapter->cmd_producer + 1) %
-             adapter->max_tx_desc_count) == adapter->last_cmd_consumer)) {
-               consumer = le32_to_cpu(*(adapter->cmd_consumer));
-       }
-       done = (adapter->last_cmd_consumer == consumer);
+       consumer = le32_to_cpu(*(adapter->cmd_consumer));
+       done = (last_consumer == consumer);
 
-       spin_unlock(&adapter->tx_lock);
-       DPRINTK(INFO, "last consumer is %d in %s\n", last_consumer,
-               __FUNCTION__);
        return (done);
 }
 
@@ -1433,8 +1300,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
                rcv_desc->begin_alloc = index;
                rcv_desc->rcv_pending += count;
                rcv_desc->producer = producer;
-               if (rcv_desc->rcv_free >= 32) {
-                       rcv_desc->rcv_free = 0;
                        /* Window = 1 */
                        writel((producer - 1) &
                               (rcv_desc->max_rx_desc_count - 1),
@@ -1458,8 +1323,6 @@ void netxen_post_rx_buffers(struct netxen_adapter *adapter, u32 ctx, u32 ringid)
                        writel(msg,
                               DB_NORMALIZE(adapter,
                                            NETXEN_RCV_PRODUCER_OFFSET));
-                       wmb();
-               }
        }
 }
 
@@ -1523,8 +1386,6 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
                rcv_desc->begin_alloc = index;
                rcv_desc->rcv_pending += count;
                rcv_desc->producer = producer;
-               if (rcv_desc->rcv_free >= 32) {
-                       rcv_desc->rcv_free = 0;
                        /* Window = 1 */
                        writel((producer - 1) &
                               (rcv_desc->max_rx_desc_count - 1),
@@ -1534,21 +1395,9 @@ static void netxen_post_rx_buffers_nodb(struct netxen_adapter *adapter,
                                                    rcv_desc_crb[ringid].
                                                    crb_rcv_producer_offset));
                        wmb();
-               }
        }
 }
 
-int netxen_nic_tx_has_work(struct netxen_adapter *adapter)
-{
-       if (find_diff_among(adapter->last_cmd_consumer,
-                           adapter->cmd_producer,
-                           adapter->max_tx_desc_count) > 0)
-               return 1;
-
-       return 0;
-}
-
-
 void netxen_nic_clear_stats(struct netxen_adapter *adapter)
 {
        memset(&adapter->stats, 0, sizeof(adapter->stats));
index 48a404a..c81313b 100644 (file)
@@ -59,7 +59,7 @@ struct net_device_stats *netxen_nic_get_stats(struct net_device *netdev)
        /* packet transmit problems */
        stats->tx_errors = adapter->stats.nocmddescriptor;
        /* no space in linux buffers    */
-       stats->rx_dropped = adapter->stats.updropped;
+       stats->rx_dropped = adapter->stats.rxdropped;
        /* no space available in linux  */
        stats->tx_dropped = adapter->stats.txdropped;
 
@@ -193,14 +193,14 @@ int netxen_nic_link_ok(struct netxen_adapter *adapter)
 void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
 {
        struct net_device *netdev = adapter->netdev;
-       u32 val, val1;
+       u32 val;
 
        /* WINDOW = 1 */
        val = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_XG_STATE));
        val >>= (physical_port[adapter->portnum] * 8);
-       val1 = val & 0xff;
+       val &= 0xff;
 
-       if (adapter->ahw.xg_linkup == 1 && val1 != XG_LINK_UP) {
+       if (adapter->ahw.xg_linkup == 1 && val != XG_LINK_UP) {
                printk(KERN_INFO "%s: %s NIC Link is down\n",
                       netxen_nic_driver_name, netdev->name);
                adapter->ahw.xg_linkup = 0;
@@ -208,16 +208,7 @@ void netxen_nic_xgbe_handle_phy_intr(struct netxen_adapter *adapter)
                        netif_carrier_off(netdev);
                        netif_stop_queue(netdev);
                }
-               /* read twice to clear sticky bits */
-               /* WINDOW = 0 */
-               netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1);
-               netxen_nic_read_w0(adapter, NETXEN_NIU_XG_STATUS, &val1);
-
-               if ((val & 0xffb) != 0xffb) {
-                       printk(KERN_INFO "%s ISR: Sync/Align BAD: 0x%08x\n",
-                              netxen_nic_driver_name, val1);
-               }
-       } else if (adapter->ahw.xg_linkup == 0 && val1 == XG_LINK_UP) {
+       } else if (adapter->ahw.xg_linkup == 0 && val == XG_LINK_UP) {
                printk(KERN_INFO "%s: %s NIC Link is up\n",
                       netxen_nic_driver_name, netdev->name);
                adapter->ahw.xg_linkup = 1;
index 9737eae..a8fb439 100644 (file)
@@ -63,12 +63,12 @@ static int netxen_nic_xmit_frame(struct sk_buff *, struct net_device *);
 static void netxen_tx_timeout(struct net_device *netdev);
 static void netxen_tx_timeout_task(struct work_struct *work);
 static void netxen_watchdog(unsigned long);
-static int netxen_handle_int(struct netxen_adapter *, struct net_device *);
 static int netxen_nic_poll(struct napi_struct *napi, int budget);
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void netxen_nic_poll_controller(struct net_device *netdev);
 #endif
 static irqreturn_t netxen_intr(int irq, void *data);
+static irqreturn_t netxen_msi_intr(int irq, void *data);
 
 int physical_port[] = {0, 1, 2, 3};
 
@@ -149,33 +149,30 @@ static void netxen_nic_update_cmd_consumer(struct netxen_adapter *adapter,
 
 #define        ADAPTER_LIST_SIZE 12
 
+static uint32_t msi_tgt_status[4] = {
+       ISR_INT_TARGET_STATUS, ISR_INT_TARGET_STATUS_F1,
+       ISR_INT_TARGET_STATUS_F2, ISR_INT_TARGET_STATUS_F3
+};
+
+static uint32_t sw_int_mask[4] = {
+       CRB_SW_INT_MASK_0, CRB_SW_INT_MASK_1,
+       CRB_SW_INT_MASK_2, CRB_SW_INT_MASK_3
+};
+
 static void netxen_nic_disable_int(struct netxen_adapter *adapter)
 {
-       uint32_t        mask = 0x7ff;
+       u32 mask = 0x7ff;
        int retries = 32;
+       int port = adapter->portnum;
+       int pci_fn = adapter->ahw.pci_func;
 
-       DPRINTK(1, INFO, "Entered ISR Disable \n");
-
-       switch (adapter->portnum) {
-       case 0:
-               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
-               break;
-       case 1:
-               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
-               break;
-       case 2:
-               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
-               break;
-       case 3:
-               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
-               break;
-       }
+       if (adapter->msi_mode != MSI_MODE_MULTIFUNC)
+               writel(0x0, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port]));
 
        if (adapter->intr_scheme != -1 &&
            adapter->intr_scheme != INTR_SCHEME_PERPORT)
                writel(mask,PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
 
-       /* Window = 0 or 1 */
        if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
                do {
                        writel(0xffffffff,
@@ -190,14 +187,18 @@ static void netxen_nic_disable_int(struct netxen_adapter *adapter)
                        printk(KERN_NOTICE "%s: Failed to disable interrupt completely\n",
                                        netxen_nic_driver_name);
                }
+       } else {
+               if (adapter->msi_mode == MSI_MODE_MULTIFUNC) {
+                       writel(0xffffffff, PCI_OFFSET_SECOND_RANGE(adapter,
+                                               msi_tgt_status[pci_fn]));
+               }
        }
-
-       DPRINTK(1, INFO, "Done with Disable Int\n");
 }
 
 static void netxen_nic_enable_int(struct netxen_adapter *adapter)
 {
        u32 mask;
+       int port = adapter->portnum;
 
        DPRINTK(1, INFO, "Entered ISR Enable \n");
 
@@ -218,20 +219,7 @@ static void netxen_nic_enable_int(struct netxen_adapter *adapter)
                writel(mask, PCI_OFFSET_SECOND_RANGE(adapter, ISR_INT_MASK));
        }
 
-       switch (adapter->portnum) {
-       case 0:
-               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_0));
-               break;
-       case 1:
-               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_1));
-               break;
-       case 2:
-               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_2));
-               break;
-       case 3:
-               writel(0x1, NETXEN_CRB_NORMALIZE(adapter, CRB_SW_INT_MASK_3));
-               break;
-       }
+       writel(0x1, NETXEN_CRB_NORMALIZE(adapter, sw_int_mask[port]));
 
        if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
                mask = 0xbff;
@@ -328,7 +316,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        adapter->ahw.pdev = pdev;
        adapter->ahw.pci_func  = pci_func_id;
-       spin_lock_init(&adapter->tx_lock);
 
        /* remap phys address */
        mem_base = pci_resource_start(pdev, 0); /* 0 is for BAR 0 */
@@ -401,6 +388,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
 
        /* this will be read from FW later */
        adapter->intr_scheme = -1;
+       adapter->msi_mode = -1;
 
        /* This will be reset for mezz cards  */
        adapter->portnum = pci_func_id;
@@ -415,7 +403,7 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        netdev->set_mac_address    = netxen_nic_set_mac;
        netdev->change_mtu         = netxen_nic_change_mtu;
        netdev->tx_timeout         = netxen_tx_timeout;
-       netdev->watchdog_timeo     = HZ;
+       netdev->watchdog_timeo     = 2*HZ;
 
        netxen_nic_change_mtu(netdev, netdev->mtu);
 
@@ -543,7 +531,6 @@ netxen_nic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
        adapter->watchdog_timer.data = (unsigned long)adapter;
        INIT_WORK(&adapter->watchdog_task, netxen_watchdog_task);
        adapter->ahw.pdev = pdev;
-       adapter->proc_cmd_buf_counter = 0;
        adapter->ahw.revision_id = pdev->revision;
 
        /* make sure Window == 1 */
@@ -833,6 +820,8 @@ static int netxen_nic_open(struct net_device *netdev)
        struct netxen_adapter *adapter = (struct netxen_adapter *)netdev->priv;
        int err = 0;
        int ctx, ring;
+       irq_handler_t handler;
+       unsigned long flags = IRQF_SAMPLE_RANDOM;
 
        if (adapter->is_up != NETXEN_ADAPTER_UP_MAGIC) {
                err = netxen_init_firmware(adapter);
@@ -856,9 +845,14 @@ static int netxen_nic_open(struct net_device *netdev)
                                netxen_post_rx_buffers(adapter, ctx, ring);
                }
                adapter->irq = adapter->ahw.pdev->irq;
-               err = request_irq(adapter->ahw.pdev->irq, netxen_intr,
-                                 IRQF_SHARED|IRQF_SAMPLE_RANDOM, netdev->name,
-                                 adapter);
+               if (adapter->flags & NETXEN_NIC_MSI_ENABLED)
+                       handler = netxen_msi_intr;
+               else {
+                       flags |= IRQF_SHARED;
+                       handler = netxen_intr;
+               }
+               err = request_irq(adapter->irq, handler,
+                                 flags, netdev->name, adapter);
                if (err) {
                        printk(KERN_ERR "request_irq failed with: %d\n", err);
                        netxen_free_hw_resources(adapter);
@@ -867,21 +861,12 @@ static int netxen_nic_open(struct net_device *netdev)
 
                adapter->is_up = NETXEN_ADAPTER_UP_MAGIC;
        }
-       if (!adapter->driver_mismatch)
-               mod_timer(&adapter->watchdog_timer, jiffies);
-
-       napi_enable(&adapter->napi);
-
-       netxen_nic_enable_int(adapter);
-
        /* Done here again so that even if phantom sw overwrote it,
         * we set it */
        if (adapter->init_port
            && adapter->init_port(adapter, adapter->portnum) != 0) {
-           del_timer_sync(&adapter->watchdog_timer);
                printk(KERN_ERR "%s: Failed to initialize port %d\n",
                                netxen_nic_driver_name, adapter->portnum);
-               napi_disable(&adapter->napi);
                return -EIO;
        }
        if (adapter->macaddr_set)
@@ -894,6 +879,12 @@ static int netxen_nic_open(struct net_device *netdev)
                adapter->set_mtu(adapter, netdev->mtu);
 
        if (!adapter->driver_mismatch)
+               mod_timer(&adapter->watchdog_timer, jiffies);
+
+       napi_enable(&adapter->napi);
+       netxen_nic_enable_int(adapter);
+
+       if (!adapter->driver_mismatch)
                netif_start_queue(netdev);
 
        return 0;
@@ -958,41 +949,17 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
        struct netxen_skb_frag *buffrag;
        unsigned int i;
 
-       u32 producer = 0;
+       u32 producer, consumer;
        u32 saved_producer = 0;
        struct cmd_desc_type0 *hwdesc;
        int k;
        struct netxen_cmd_buffer *pbuf = NULL;
-       static int dropped_packet = 0;
        int frag_count;
-       u32 local_producer = 0;
-       u32 max_tx_desc_count = 0;
-       u32 last_cmd_consumer = 0;
        int no_of_desc;
+       u32 num_txd = adapter->max_tx_desc_count;
 
-       adapter->stats.xmitcalled++;
        frag_count = skb_shinfo(skb)->nr_frags + 1;
 
-       if (unlikely(skb->len <= 0)) {
-               dev_kfree_skb_any(skb);
-               adapter->stats.badskblen++;
-               return NETDEV_TX_OK;
-       }
-
-       if (frag_count > MAX_BUFFERS_PER_CMD) {
-               printk("%s: %s netxen_nic_xmit_frame: frag_count (%d) "
-                      "too large, can handle only %d frags\n",
-                      netxen_nic_driver_name, netdev->name,
-                      frag_count, MAX_BUFFERS_PER_CMD);
-               adapter->stats.txdropped++;
-               if ((++dropped_packet & 0xff) == 0xff)
-                       printk("%s: %s droppped packets = %d\n",
-                              netxen_nic_driver_name, netdev->name,
-                              dropped_packet);
-
-               return NETDEV_TX_OK;
-       }
-
        /* There 4 fragments per descriptor */
        no_of_desc = (frag_count + 3) >> 2;
        if (netdev->features & NETIF_F_TSO) {
@@ -1007,27 +974,16 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                }
        }
 
-       spin_lock_bh(&adapter->tx_lock);
-       if (adapter->total_threads >= MAX_XMIT_PRODUCERS) {
-               goto out_requeue;
-       }
-       local_producer = adapter->cmd_producer;
-       k = adapter->cmd_producer;
-       max_tx_desc_count = adapter->max_tx_desc_count;
-       last_cmd_consumer = adapter->last_cmd_consumer;
-       if ((k + no_of_desc) >=
-           ((last_cmd_consumer <= k) ? last_cmd_consumer + max_tx_desc_count :
-            last_cmd_consumer)) {
-               goto out_requeue;
+       producer = adapter->cmd_producer;
+       smp_mb();
+       consumer = adapter->last_cmd_consumer;
+       if ((no_of_desc+2) > find_diff_among(producer, consumer, num_txd)) {
+               netif_stop_queue(netdev);
+               smp_mb();
+               return NETDEV_TX_BUSY;
        }
-       k = get_index_range(k, max_tx_desc_count, no_of_desc);
-       adapter->cmd_producer = k;
-       adapter->total_threads++;
-       adapter->num_threads++;
 
-       spin_unlock_bh(&adapter->tx_lock);
        /* Copy the descriptors into the hardware    */
-       producer = local_producer;
        saved_producer = producer;
        hwdesc = &hw->cmd_desc_head[producer];
        memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
@@ -1067,8 +1023,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                /* move to next desc. if there is a need */
                if ((i & 0x3) == 0) {
                        k = 0;
-                       producer = get_next_index(producer,
-                                                 adapter->max_tx_desc_count);
+                       producer = get_next_index(producer, num_txd);
                        hwdesc = &hw->cmd_desc_head[producer];
                        memset(hwdesc, 0, sizeof(struct cmd_desc_type0));
                        pbuf = &adapter->cmd_buf_arr[producer];
@@ -1086,7 +1041,6 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                buffrag->dma = temp_dma;
                buffrag->length = temp_len;
 
-               DPRINTK(INFO, "for loop. i=%d k=%d\n", i, k);
                switch (k) {
                case 0:
                        hwdesc->buffer1_length = cpu_to_le16(temp_len);
@@ -1107,7 +1061,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                }
                frag++;
        }
-       producer = get_next_index(producer, adapter->max_tx_desc_count);
+       producer = get_next_index(producer, num_txd);
 
        /* might change opcode to TX_TCP_LSO */
        netxen_tso_check(adapter, &hw->cmd_desc_head[saved_producer], skb);
@@ -1134,7 +1088,7 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                /* copy the first 64 bytes */
                memcpy(((void *)hwdesc) + 2,
                       (void *)(skb->data), first_hdr_len);
-               producer = get_next_index(producer, max_tx_desc_count);
+               producer = get_next_index(producer, num_txd);
 
                if (more_hdr) {
                        hwdesc = &hw->cmd_desc_head[producer];
@@ -1147,35 +1101,19 @@ static int netxen_nic_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
                                                         hwdesc,
                                                         (hdr_len -
                                                          first_hdr_len));
-                       producer = get_next_index(producer, max_tx_desc_count);
+                       producer = get_next_index(producer, num_txd);
                }
        }
 
-       spin_lock_bh(&adapter->tx_lock);
+       adapter->cmd_producer = producer;
        adapter->stats.txbytes += skb->len;
 
-       /* Code to update the adapter considering how many producer threads
-          are currently working */
-       if ((--adapter->num_threads) == 0) {
-               /* This is the last thread */
-               u32 crb_producer = adapter->cmd_producer;
-               netxen_nic_update_cmd_producer(adapter, crb_producer);
-               wmb();
-               adapter->total_threads = 0;
-       }
+       netxen_nic_update_cmd_producer(adapter, adapter->cmd_producer);
 
-       adapter->stats.xmitfinished++;
+       adapter->stats.xmitcalled++;
        netdev->trans_start = jiffies;
 
-       spin_unlock_bh(&adapter->tx_lock);
        return NETDEV_TX_OK;
-
-out_requeue:
-       netif_stop_queue(netdev);
-       adapter->flags |= NETXEN_NETDEV_STATUS;
-
-       spin_unlock_bh(&adapter->tx_lock);
-       return NETDEV_TX_BUSY;
 }
 
 static void netxen_watchdog(unsigned long v)
@@ -1200,87 +1138,60 @@ static void netxen_tx_timeout_task(struct work_struct *work)
        printk(KERN_ERR "%s %s: transmit timeout, resetting.\n",
               netxen_nic_driver_name, adapter->netdev->name);
 
-       netxen_nic_close(adapter->netdev);
-       netxen_nic_open(adapter->netdev);
+       netxen_nic_disable_int(adapter);
+       napi_disable(&adapter->napi);
+
        adapter->netdev->trans_start = jiffies;
+
+       napi_enable(&adapter->napi);
+       netxen_nic_enable_int(adapter);
        netif_wake_queue(adapter->netdev);
 }
 
-static int
-netxen_handle_int(struct netxen_adapter *adapter, struct net_device *netdev)
+static inline void
+netxen_handle_int(struct netxen_adapter *adapter)
 {
-       u32 ret = 0;
-
-       DPRINTK(INFO, "Entered handle ISR\n");
-       adapter->stats.ints++;
-
        netxen_nic_disable_int(adapter);
-
-       if (netxen_nic_rx_has_work(adapter) || netxen_nic_tx_has_work(adapter)) {
-               if (netif_rx_schedule_prep(netdev, &adapter->napi)) {
-                       /*
-                        * Interrupts are already disabled.
-                        */
-                       __netif_rx_schedule(netdev, &adapter->napi);
-               } else {
-                       static unsigned int intcount = 0;
-                       if ((++intcount & 0xfff) == 0xfff)
-                               DPRINTK(KERN_ERR
-                                      "%s: %s interrupt %d while in poll\n",
-                                      netxen_nic_driver_name, netdev->name,
-                                      intcount);
-               }
-               ret = 1;
-       }
-
-       if (ret == 0) {
-               netxen_nic_enable_int(adapter);
-       }
-
-       return ret;
+       napi_schedule(&adapter->napi);
 }
 
-/*
- * netxen_intr - Interrupt Handler
- * @irq: interrupt number
- * data points to adapter stucture (which may be handling more than 1 port
- */
 irqreturn_t netxen_intr(int irq, void *data)
 {
        struct netxen_adapter *adapter = data;
-       struct net_device *netdev = adapter->netdev;
        u32 our_int = 0;
 
-       if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
-               our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
-               /* not our interrupt */
-               if ((our_int & (0x80 << adapter->portnum)) == 0)
-                       return IRQ_NONE;
-       }
+       our_int = readl(NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
+       /* not our interrupt */
+       if ((our_int & (0x80 << adapter->portnum)) == 0)
+               return IRQ_NONE;
 
        if (adapter->intr_scheme == INTR_SCHEME_PERPORT) {
                /* claim interrupt */
-               if (!(adapter->flags & NETXEN_NIC_MSI_ENABLED)) {
-                       writel(our_int & ~((u32)(0x80 << adapter->portnum)),
+               writel(our_int & ~((u32)(0x80 << adapter->portnum)),
                        NETXEN_CRB_NORMALIZE(adapter, CRB_INT_VECTOR));
-               }
        }
 
-       if (netif_running(netdev))
-               netxen_handle_int(adapter, netdev);
+       netxen_handle_int(adapter);
 
        return IRQ_HANDLED;
 }
 
+irqreturn_t netxen_msi_intr(int irq, void *data)
+{
+       struct netxen_adapter *adapter = data;
+
+       netxen_handle_int(adapter);
+       return IRQ_HANDLED;
+}
+
 static int netxen_nic_poll(struct napi_struct *napi, int budget)
 {
        struct netxen_adapter *adapter = container_of(napi, struct netxen_adapter, napi);
-       struct net_device *netdev = adapter->netdev;
-       int done = 1;
+       int tx_complete;
        int ctx;
        int work_done;
 
-       DPRINTK(INFO, "polling for %d descriptors\n", *budget);
+       tx_complete = netxen_process_cmd_ring(adapter);
 
        work_done = 0;
        for (ctx = 0; ctx < MAX_RCV_CTX; ++ctx) {
@@ -1300,16 +1211,8 @@ static int netxen_nic_poll(struct napi_struct *napi, int budget)
                                                     budget / MAX_RCV_CTX);
        }
 
-       if (work_done >= budget)
-               done = 0;
-
-       if (netxen_process_cmd_ring((unsigned long)adapter) == 0)
-               done = 0;
-
-       DPRINTK(INFO, "new work_done: %d work_to_do: %d\n",
-               work_done, work_to_do);
-       if (done) {
-               netif_rx_complete(netdev, napi);
+       if ((work_done < budget) && tx_complete) {
+               netif_rx_complete(adapter->netdev, &adapter->napi);
                netxen_nic_enable_int(adapter);
        }
 
index ffa3b72..a566b50 100644 (file)
  */
 #define CRB_NIC_CAPABILITIES_HOST      NETXEN_NIC_REG(0x1a8)
 #define CRB_NIC_CAPABILITIES_FW                NETXEN_NIC_REG(0x1dc)
+#define CRB_NIC_MSI_MODE_HOST          NETXEN_NIC_REG(0x270)
+#define CRB_NIC_MSI_MODE_FW                    NETXEN_NIC_REG(0x274)
 
 #define INTR_SCHEME_PERPORT            0x1
+#define MSI_MODE_MULTIFUNC             0x1
 
 /* used for ethtool tests */
 #define CRB_SCRATCHPAD_TEST        NETXEN_NIC_REG(0x280)
index f057407..3353991 100644 (file)
 #define MII_M1111_RX_DELAY             0x80
 #define MII_M1111_TX_DELAY             0x2
 #define MII_M1111_PHY_EXT_SR           0x1b
-#define MII_M1111_HWCFG_MODE_MASK      0xf
-#define MII_M1111_HWCFG_MODE_RGMII     0xb
+
+#define MII_M1111_HWCFG_MODE_MASK              0xf
+#define MII_M1111_HWCFG_MODE_COPPER_RGMII      0xb
+#define MII_M1111_HWCFG_MODE_FIBER_RGMII       0x3
 #define MII_M1111_HWCFG_MODE_SGMII_NO_CLK      0x4
+#define MII_M1111_HWCFG_FIBER_COPPER_AUTO      0x8000
+#define MII_M1111_HWCFG_FIBER_COPPER_RES       0x2000
+
+#define MII_M1111_COPPER               0
+#define MII_M1111_FIBER                        1
+
+#define MII_M1011_PHY_STATUS           0x11
+#define MII_M1011_PHY_STATUS_1000      0x8000
+#define MII_M1011_PHY_STATUS_100       0x4000
+#define MII_M1011_PHY_STATUS_SPD_MASK  0xc000
+#define MII_M1011_PHY_STATUS_FULLDUPLEX        0x2000
+#define MII_M1011_PHY_STATUS_RESOLVED  0x0800
+#define MII_M1011_PHY_STATUS_LINK      0x0400
+
 
 MODULE_DESCRIPTION("Marvell PHY driver");
 MODULE_AUTHOR("Andy Fleming");
@@ -141,12 +157,22 @@ static int marvell_config_aneg(struct phy_device *phydev)
 static int m88e1111_config_init(struct phy_device *phydev)
 {
        int err;
+       int temp;
+       int mode;
+
+       /* Enable Fiber/Copper auto selection */
+       temp = phy_read(phydev, MII_M1111_PHY_EXT_SR);
+       temp |= MII_M1111_HWCFG_FIBER_COPPER_AUTO;
+       phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
+
+       temp = phy_read(phydev, MII_BMCR);
+       temp |= BMCR_RESET;
+       phy_write(phydev, MII_BMCR, temp);
 
        if ((phydev->interface == PHY_INTERFACE_MODE_RGMII) ||
            (phydev->interface == PHY_INTERFACE_MODE_RGMII_ID) ||
            (phydev->interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
            (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID)) {
-               int temp;
 
                temp = phy_read(phydev, MII_M1111_PHY_EXT_CR);
                if (temp < 0)
@@ -171,7 +197,13 @@ static int m88e1111_config_init(struct phy_device *phydev)
                        return temp;
 
                temp &= ~(MII_M1111_HWCFG_MODE_MASK);
-               temp |= MII_M1111_HWCFG_MODE_RGMII;
+
+               mode = phy_read(phydev, MII_M1111_PHY_EXT_CR);
+
+               if (mode & MII_M1111_HWCFG_FIBER_COPPER_RES)
+                       temp |= MII_M1111_HWCFG_MODE_FIBER_RGMII;
+               else
+                       temp |= MII_M1111_HWCFG_MODE_COPPER_RGMII;
 
                err = phy_write(phydev, MII_M1111_PHY_EXT_SR, temp);
                if (err < 0)
@@ -262,6 +294,93 @@ static int m88e1145_config_init(struct phy_device *phydev)
        return 0;
 }
 
+/* marvell_read_status
+ *
+ * Generic status code does not detect Fiber correctly!
+ * Description:
+ *   Check the link, then figure out the current state
+ *   by comparing what we advertise with what the link partner
+ *   advertises.  Start by checking the gigabit possibilities,
+ *   then move on to 10/100.
+ */
+static int marvell_read_status(struct phy_device *phydev)
+{
+       int adv;
+       int err;
+       int lpa;
+       int status = 0;
+
+       /* Update the link, but return if there
+        * was an error */
+       err = genphy_update_link(phydev);
+       if (err)
+               return err;
+
+       if (AUTONEG_ENABLE == phydev->autoneg) {
+               status = phy_read(phydev, MII_M1011_PHY_STATUS);
+               if (status < 0)
+                       return status;
+
+               lpa = phy_read(phydev, MII_LPA);
+               if (lpa < 0)
+                       return lpa;
+
+               adv = phy_read(phydev, MII_ADVERTISE);
+               if (adv < 0)
+                       return adv;
+
+               lpa &= adv;
+
+               if (status & MII_M1011_PHY_STATUS_FULLDUPLEX)
+                       phydev->duplex = DUPLEX_FULL;
+               else
+                       phydev->duplex = DUPLEX_HALF;
+
+               status = status & MII_M1011_PHY_STATUS_SPD_MASK;
+               phydev->pause = phydev->asym_pause = 0;
+
+               switch (status) {
+               case MII_M1011_PHY_STATUS_1000:
+                       phydev->speed = SPEED_1000;
+                       break;
+
+               case MII_M1011_PHY_STATUS_100:
+                       phydev->speed = SPEED_100;
+                       break;
+
+               default:
+                       phydev->speed = SPEED_10;
+                       break;
+               }
+
+               if (phydev->duplex == DUPLEX_FULL) {
+                       phydev->pause = lpa & LPA_PAUSE_CAP ? 1 : 0;
+                       phydev->asym_pause = lpa & LPA_PAUSE_ASYM ? 1 : 0;
+               }
+       } else {
+               int bmcr = phy_read(phydev, MII_BMCR);
+
+               if (bmcr < 0)
+                       return bmcr;
+
+               if (bmcr & BMCR_FULLDPLX)
+                       phydev->duplex = DUPLEX_FULL;
+               else
+                       phydev->duplex = DUPLEX_HALF;
+
+               if (bmcr & BMCR_SPEED1000)
+                       phydev->speed = SPEED_1000;
+               else if (bmcr & BMCR_SPEED100)
+                       phydev->speed = SPEED_100;
+               else
+                       phydev->speed = SPEED_10;
+
+               phydev->pause = phydev->asym_pause = 0;
+       }
+
+       return 0;
+}
+
 static struct phy_driver marvell_drivers[] = {
        {
                .phy_id = 0x01410c60,
@@ -296,7 +415,7 @@ static struct phy_driver marvell_drivers[] = {
                .flags = PHY_HAS_INTERRUPT,
                .config_init = &m88e1111_config_init,
                .config_aneg = &marvell_config_aneg,
-               .read_status = &genphy_read_status,
+               .read_status = &marvell_read_status,
                .ack_interrupt = &marvell_ack_interrupt,
                .config_intr = &marvell_config_intr,
                .driver = { .owner = THIS_MODULE },
index fee3d7b..1e96542 100644 (file)
@@ -903,17 +903,18 @@ plip_interrupt(void *dev_id)
        struct net_local *nl;
        struct plip_local *rcv;
        unsigned char c0;
+       unsigned long flags;
 
        nl = netdev_priv(dev);
        rcv = &nl->rcv_data;
 
-       spin_lock_irq (&nl->lock);
+       spin_lock_irqsave (&nl->lock, flags);
 
        c0 = read_status(dev);
        if ((c0 & 0xf8) != 0xc0) {
                if ((dev->irq != -1) && (net_debug > 1))
                        printk(KERN_DEBUG "%s: spurious interrupt\n", dev->name);
-               spin_unlock_irq (&nl->lock);
+               spin_unlock_irqrestore (&nl->lock, flags);
                return;
        }
 
@@ -942,7 +943,7 @@ plip_interrupt(void *dev_id)
                break;
        }
 
-       spin_unlock_irq(&nl->lock);
+       spin_unlock_irqrestore(&nl->lock, flags);
 }
 
 static int
index c72787a..3c915b8 100644 (file)
@@ -4172,6 +4172,9 @@ static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
        dev->trans_start = jiffies;
        spin_unlock_irqrestore(&fifo->tx_lock, flags);
 
+       if (sp->config.intr_type == MSI_X)
+               tx_intr_handler(fifo);
+
        return 0;
 pci_map_failed:
        stats->pci_map_fail_cnt++;
index 186eb8e..2e26dce 100644 (file)
@@ -3199,12 +3199,14 @@ static int skge_poll(struct napi_struct *napi, int to_do)
        skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_START);
 
        if (work_done < to_do) {
-               spin_lock_irq(&hw->hw_lock);
+               unsigned long flags;
+
+               spin_lock_irqsave(&hw->hw_lock, flags);
                __netif_rx_complete(dev, napi);
                hw->intr_mask |= napimask[skge->port];
                skge_write32(hw, B0_IMSK, hw->intr_mask);
                skge_read32(hw, B0_IMSK);
-               spin_unlock_irq(&hw->hw_lock);
+               spin_unlock_irqrestore(&hw->hw_lock, flags);
        }
 
        return work_done;
index 51d4134..98a832a 100644 (file)
 #define SMC_insw(a, r, p, l)   insw ((unsigned long *)((a) + (r)), p, l)
 # endif
 /* check if the mac in reg is valid */
-#define SMC_GET_MAC_ADDR(addr)                                 \
+#define SMC_GET_MAC_ADDR(lp, addr)                             \
        do {                                                    \
                unsigned int __v;                               \
-               __v = SMC_inw(ioaddr, ADDR0_REG);               \
+               __v = SMC_inw(ioaddr, ADDR0_REG(lp));           \
                addr[0] = __v; addr[1] = __v >> 8;              \
-               __v = SMC_inw(ioaddr, ADDR1_REG);               \
+               __v = SMC_inw(ioaddr, ADDR1_REG(lp));           \
                addr[2] = __v; addr[3] = __v >> 8;              \
-               __v = SMC_inw(ioaddr, ADDR2_REG);               \
+               __v = SMC_inw(ioaddr, ADDR2_REG(lp));           \
                addr[4] = __v; addr[5] = __v >> 8;              \
                if (*(u32 *)(&addr[0]) == 0xFFFFFFFF) {         \
                        random_ether_addr(addr);                \
index 8909050..5f1c507 100644 (file)
@@ -3413,7 +3413,7 @@ static int smctr_make_tx_status_code(struct net_device *dev,
         tsv->svi = TRANSMIT_STATUS_CODE;
         tsv->svl = S_TRANSMIT_STATUS_CODE;
 
-        tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) || IBM_PASS_SOURCE_ADDR);
+       tsv->svv[0] = ((tx_fstatus & 0x0100 >> 6) | IBM_PASS_SOURCE_ADDR);
 
         /* Stripped frame status of Transmitted Frame */
         tsv->svv[1] = tx_fstatus & 0xff;
index 4b131a6..0343b00 100644 (file)
@@ -341,7 +341,7 @@ static void dm9601_set_multicast(struct net_device *net)
        /* We use the 20 byte dev->data for our 8 byte filter buffer
         * to avoid allocating memory that is tricky to free later */
        u8 *hashes = (u8 *) & dev->data;
-       u8 rx_ctl = 0x01;
+       u8 rx_ctl = 0x31;
 
        memset(hashes, 0x00, DM_MCAST_SIZE);
        hashes[DM_MCAST_SIZE - 1] |= 0x80;      /* broadcast address */
@@ -562,6 +562,10 @@ static const struct usb_device_id products[] = {
         USB_DEVICE(0x0a46, 0x8515),    /* ADMtek ADM8515 USB NIC */
         .driver_info = (unsigned long)&dm9601_info,
         },
+       {
+       USB_DEVICE(0x0a47, 0x9601),     /* Hirose USB-100 */
+       .driver_info = (unsigned long)&dm9601_info,
+        },
        {},                     // END
 };
 
index 727547a..369c731 100644 (file)
@@ -283,7 +283,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
                struct rndis_set_c      *set_c;
                struct rndis_halt       *halt;
        } u;
-       u32                     tmp, *phym;
+       u32                     tmp, phym_unspec, *phym;
        int                     reply_len;
        unsigned char           *bp;
 
@@ -363,12 +363,15 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags)
                goto halt_fail_and_release;
 
        /* Check physical medium */
+       phym = NULL;
        reply_len = sizeof *phym;
        retval = rndis_query(dev, intf, u.buf, OID_GEN_PHYSICAL_MEDIUM,
                        0, (void **) &phym, &reply_len);
-       if (retval != 0)
+       if (retval != 0 || !phym) {
                /* OID is optional so don't fail here. */
-               *phym = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED;
+               phym_unspec = RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED;
+               phym = &phym_unspec;
+       }
        if ((flags & FLAG_RNDIS_PHYM_WIRELESS) &&
                        *phym != RNDIS_PHYSICAL_MEDIUM_WIRELESS_LAN) {
                if (netif_msg_probe(dev))
index c6e70db..2ab1d59 100644 (file)
@@ -1202,13 +1202,6 @@ static ctl_table arlan_table[MAX_ARLANS + 1] =
        { .ctl_name = 0 }
 };
 #endif
-#else
-
-static ctl_table arlan_table[MAX_ARLANS + 1] =
-{
-       { .ctl_name = 0 }
-};
-#endif
 
 
 // static int mmtu = 1234;
@@ -1233,7 +1226,6 @@ static ctl_table arlan_root_table[] =
 //};
 
 
-#ifdef CONFIG_PROC_FS
 static struct ctl_table_header *arlan_device_sysctl_header;
 
 int __init init_arlan_proc(void)
index e38ed0f..7fca2eb 100644 (file)
@@ -618,6 +618,7 @@ void b43_debugfs_remove_device(struct b43_wldev *dev)
        kfree(e);
 }
 
+/* Called with IRQs disabled. */
 void b43_debugfs_log_txstat(struct b43_wldev *dev,
                            const struct b43_txstatus *status)
 {
@@ -629,8 +630,7 @@ void b43_debugfs_log_txstat(struct b43_wldev *dev,
        if (!e)
                return;
        log = &e->txstatlog;
-       B43_WARN_ON(!irqs_disabled());
-       spin_lock(&log->lock);
+       spin_lock(&log->lock); /* IRQs are already disabled. */
        i = log->end + 1;
        if (i == B43_NR_LOGGED_TXSTATUS)
                i = 0;
index 3dfb28a..cfbc1a2 100644 (file)
@@ -560,7 +560,7 @@ static int b43_dmacontroller_tx_reset(struct b43_wldev *dev, u16 mmio_base,
 /* Check if a DMA mapping address is invalid. */
 static bool b43_dma_mapping_error(struct b43_dmaring *ring,
                                  dma_addr_t addr,
-                                 size_t buffersize)
+                                 size_t buffersize, bool dma_to_device)
 {
        if (unlikely(dma_mapping_error(addr)))
                return 1;
@@ -568,11 +568,11 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
        switch (ring->type) {
        case B43_DMA_30BIT:
                if ((u64)addr + buffersize > (1ULL << 30))
-                       return 1;
+                       goto address_error;
                break;
        case B43_DMA_32BIT:
                if ((u64)addr + buffersize > (1ULL << 32))
-                       return 1;
+                       goto address_error;
                break;
        case B43_DMA_64BIT:
                /* Currently we can't have addresses beyond
@@ -582,6 +582,12 @@ static bool b43_dma_mapping_error(struct b43_dmaring *ring,
 
        /* The address is OK. */
        return 0;
+
+address_error:
+       /* We can't support this address. Unmap it again. */
+       unmap_descbuffer(ring, addr, buffersize, dma_to_device);
+
+       return 1;
 }
 
 static int setup_rx_descbuffer(struct b43_dmaring *ring,
@@ -599,7 +605,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
        if (unlikely(!skb))
                return -ENOMEM;
        dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
-       if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) {
+       if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
                /* ugh. try to realloc in zone_dma */
                gfp_flags |= GFP_DMA;
 
@@ -612,7 +618,7 @@ static int setup_rx_descbuffer(struct b43_dmaring *ring,
                                         ring->rx_buffersize, 0);
        }
 
-       if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) {
+       if (b43_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
                dev_kfree_skb_any(skb);
                return -EIO;
        }
@@ -852,7 +858,8 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                                          b43_txhdr_size(dev),
                                          DMA_TO_DEVICE);
 
-               if (b43_dma_mapping_error(ring, dma_test, b43_txhdr_size(dev))) {
+               if (b43_dma_mapping_error(ring, dma_test,
+                                         b43_txhdr_size(dev), 1)) {
                        /* ugh realloc */
                        kfree(ring->txhdr_cache);
                        ring->txhdr_cache = kcalloc(nr_slots,
@@ -867,7 +874,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                                                  DMA_TO_DEVICE);
 
                        if (b43_dma_mapping_error(ring, dma_test,
-                                                 b43_txhdr_size(dev)))
+                                                 b43_txhdr_size(dev), 1))
                                goto err_kfree_txhdr_cache;
                }
 
@@ -1189,7 +1196,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
 
        meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
                                           hdrsize, 1);
-       if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize)) {
+       if (b43_dma_mapping_error(ring, meta_hdr->dmaaddr, hdrsize, 1)) {
                ring->current_slot = old_top_slot;
                ring->used_slots = old_used_slots;
                return -EIO;
@@ -1208,7 +1215,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
 
        meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
        /* create a bounce buffer in zone_dma on mapping failure. */
-       if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) {
+       if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
                bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
                if (!bounce_skb) {
                        ring->current_slot = old_top_slot;
@@ -1222,7 +1229,7 @@ static int dma_tx_fragment(struct b43_dmaring *ring,
                skb = bounce_skb;
                meta->skb = skb;
                meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
-               if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len)) {
+               if (b43_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
                        ring->current_slot = old_top_slot;
                        ring->used_slots = old_used_slots;
                        err = -EIO;
@@ -1337,6 +1344,7 @@ out_unlock:
        return err;
 }
 
+/* Called with IRQs disabled. */
 void b43_dma_handle_txstatus(struct b43_wldev *dev,
                             const struct b43_txstatus *status)
 {
@@ -1349,8 +1357,8 @@ void b43_dma_handle_txstatus(struct b43_wldev *dev,
        ring = parse_cookie(dev, status->cookie, &slot);
        if (unlikely(!ring))
                return;
-       B43_WARN_ON(!irqs_disabled());
-       spin_lock(&ring->lock);
+
+       spin_lock(&ring->lock); /* IRQs are already disabled. */
 
        B43_WARN_ON(!ring->tx);
        ops = ring->ops;
index 51dfce1..c73a75b 100644 (file)
@@ -2049,7 +2049,6 @@ void b43_mac_enable(struct b43_wldev *dev)
 {
        dev->mac_suspended--;
        B43_WARN_ON(dev->mac_suspended < 0);
-       B43_WARN_ON(irqs_disabled());
        if (dev->mac_suspended == 0) {
                b43_write32(dev, B43_MMIO_MACCTL,
                            b43_read32(dev, B43_MMIO_MACCTL)
@@ -2075,7 +2074,6 @@ void b43_mac_suspend(struct b43_wldev *dev)
        u32 tmp;
 
        might_sleep();
-       B43_WARN_ON(irqs_disabled());
        B43_WARN_ON(dev->mac_suspended < 0);
 
        if (dev->mac_suspended == 0) {
index d1af938..b79a35a 100644 (file)
@@ -20,7 +20,7 @@ config IWL4965
          runs.
 
          If you want to compile the driver as a module ( = code which can be
-         inserted in and remvoed from the running kernel whenever you want),
+         inserted in and removed from the running kernel whenever you want),
          say M here and read <file:Documentation/kbuild/modules.txt>.  The
          module will be called iwl4965.ko.
 
@@ -101,7 +101,7 @@ config IWL3945
          runs.
 
          If you want to compile the driver as a module ( = code which can be
-         inserted in and remvoed from the running kernel whenever you want),
+         inserted in and removed from the running kernel whenever you want),
          say M here and read <file:Documentation/kbuild/modules.txt>.  The
          module will be called iwl3945.ko.
 
index 40b71bc..cbaeaf1 100644 (file)
@@ -6206,11 +6206,11 @@ static void iwl3945_alive_start(struct iwl3945_priv *priv)
 
        /* At this point, the NIC is initialized and operational */
        priv->notif_missed_beacons = 0;
-       set_bit(STATUS_READY, &priv->status);
 
        iwl3945_reg_txpower_periodic(priv);
 
        IWL_DEBUG_INFO("ALIVE processing complete.\n");
+       set_bit(STATUS_READY, &priv->status);
        wake_up_interruptible(&priv->wait_command_queue);
 
        if (priv->error_recovering)
@@ -8706,7 +8706,7 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        return err;
 }
 
-static void iwl3945_pci_remove(struct pci_dev *pdev)
+static void __devexit iwl3945_pci_remove(struct pci_dev *pdev)
 {
        struct iwl3945_priv *priv = pci_get_drvdata(pdev);
        struct list_head *p, *q;
index a23d479..60ec29e 100644 (file)
@@ -6628,11 +6628,11 @@ static void iwl4965_alive_start(struct iwl4965_priv *priv)
 
        /* At this point, the NIC is initialized and operational */
        priv->notif_missed_beacons = 0;
-       set_bit(STATUS_READY, &priv->status);
 
        iwl4965_rf_kill_ct_config(priv);
 
        IWL_DEBUG_INFO("ALIVE processing complete.\n");
+       set_bit(STATUS_READY, &priv->status);
        wake_up_interruptible(&priv->wait_command_queue);
 
        if (priv->error_recovering)
@@ -9282,7 +9282,7 @@ static int iwl4965_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
        return err;
 }
 
-static void iwl4965_pci_remove(struct pci_dev *pdev)
+static void __devexit iwl4965_pci_remove(struct pci_dev *pdev)
 {
        struct iwl4965_priv *priv = pci_get_drvdata(pdev);
        struct list_head *p, *q;
index 8103d41..3909cf4 100644 (file)
@@ -2095,6 +2095,8 @@ static struct usb_device_id rt73usb_device_table[] = {
        { USB_DEVICE(0x1371, 0x9032), USB_DEVICE_DATA(&rt73usb_ops) },
        /* Conceptronic */
        { USB_DEVICE(0x14b2, 0x3c22), USB_DEVICE_DATA(&rt73usb_ops) },
+       /* Corega */
+       { USB_DEVICE(0x07aa, 0x002e), USB_DEVICE_DATA(&rt73usb_ops) },
        /* D-Link */
        { USB_DEVICE(0x07d1, 0x3c03), USB_DEVICE_DATA(&rt73usb_ops) },
        { USB_DEVICE(0x07d1, 0x3c04), USB_DEVICE_DATA(&rt73usb_ops) },
index fabc63e..2e4bfe4 100644 (file)
@@ -309,7 +309,7 @@ struct mmw_t
 #define        MMW_EXT_ANT_INTERNAL    0x00    /* Internal antenna */
 #define        MMW_EXT_ANT_EXTERNAL    0x03    /* External antenna */
 #define        MMW_EXT_ANT_IQ_TEST     0x1C    /* IQ test pattern (set to 0) */
-};
+} __attribute__((packed));
 
 /* Size for structure checking (if padding is correct) */
 #define        MMW_SIZE        37
index e9a333d..e887aa4 100644 (file)
@@ -951,6 +951,12 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,      PCI_DEVICE_ID_INTEL_82375,      quirk_e
  * accesses to the SMBus registers, with potentially bad effects. Thus you
  * should be very careful when adding new entries: if SMM is accessing the
  * Intel SMBus, this is a very good reason to leave it hidden.
+ *
+ * Likewise, many recent laptops use ACPI for thermal management. If the
+ * ACPI DSDT code accesses the SMBus, then Linux should not access it
+ * natively, and keeping the SMBus hidden is the right thing to do. If you
+ * are about to add an entry in the table below, please first disassemble
+ * the DSDT and double-check that there is no code accessing the SMBus.
  */
 static int asus_hides_smbus;
 
@@ -1028,11 +1034,6 @@ static void __init asus_hides_smbus_hostbridge(struct pci_dev *dev)
                        case 0x12bf: /* HP xw4100 */
                                asus_hides_smbus = 1;
                        }
-               else if (dev->device == PCI_DEVICE_ID_INTEL_82915GM_HB)
-                       switch (dev->subsystem_device) {
-                       case 0x099c: /* HP Compaq nx6110 */
-                               asus_hides_smbus = 1;
-                       }
        } else if (unlikely(dev->subsystem_vendor == PCI_VENDOR_ID_SAMSUNG)) {
                if (dev->device ==  PCI_DEVICE_ID_INTEL_82855PM_HB)
                        switch(dev->subsystem_device) {
index 125e7b7..f7cb8e0 100644 (file)
@@ -486,12 +486,7 @@ void __ref pci_bus_size_bridges(struct pci_bus *bus)
                break;
 
        case PCI_CLASS_BRIDGE_PCI:
-               /* don't size subtractive decoding (transparent)
-                * PCI-to-PCI bridges */
-               if (bus->self->transparent)
-                       break;
                pci_bridge_check_ranges(bus);
-               /* fall through */
        default:
                pbus_size_io(bus);
                /* If the bridge supports prefetchable range, size it
index 6aa231e..2dcd196 100644 (file)
@@ -85,7 +85,7 @@ static void pnpacpi_parse_allocated_irqresource(struct pnp_resource_table *res,
               i < PNP_MAX_IRQ)
                i++;
        if (i >= PNP_MAX_IRQ && !warned) {
-               printk(KERN_ERR "pnpacpi: exceeded the max number of IRQ "
+               printk(KERN_WARNING "pnpacpi: exceeded the max number of IRQ "
                                "resources: %d \n", PNP_MAX_IRQ);
                warned = 1;
                return;
@@ -187,7 +187,7 @@ static void pnpacpi_parse_allocated_dmaresource(struct pnp_resource_table *res,
                res->dma_resource[i].start = dma;
                res->dma_resource[i].end = dma;
        } else if (!warned) {
-               printk(KERN_ERR "pnpacpi: exceeded the max number of DMA "
+               printk(KERN_WARNING "pnpacpi: exceeded the max number of DMA "
                                "resources: %d \n", PNP_MAX_DMA);
                warned = 1;
        }
@@ -213,7 +213,7 @@ static void pnpacpi_parse_allocated_ioresource(struct pnp_resource_table *res,
                res->port_resource[i].start = io;
                res->port_resource[i].end = io + len - 1;
        } else if (!warned) {
-               printk(KERN_ERR "pnpacpi: exceeded the max number of IO "
+               printk(KERN_WARNING "pnpacpi: exceeded the max number of IO "
                                "resources: %d \n", PNP_MAX_PORT);
                warned = 1;
        }
@@ -241,7 +241,7 @@ static void pnpacpi_parse_allocated_memresource(struct pnp_resource_table *res,
                res->mem_resource[i].start = mem;
                res->mem_resource[i].end = mem + len - 1;
        } else if (!warned) {
-               printk(KERN_ERR "pnpacpi: exceeded the max number of mem "
+               printk(KERN_WARNING "pnpacpi: exceeded the max number of mem "
                                "resources: %d\n", PNP_MAX_MEM);
                warned = 1;
        }
index a8bec49..f97224c 100644 (file)
@@ -1214,13 +1214,6 @@ static struct pciserial_board pci_boards[] __devinitdata = {
                .base_baud      = 115200,
                .uart_offset    = 8,
        },
-       [pbn_b0_8_115200] = {
-               .flags          = FL_BASE0,
-               .num_ports      = 8,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-
        [pbn_b0_1_921600] = {
                .flags          = FL_BASE0,
                .num_ports      = 1,
index 986a550..eefba3d 100644 (file)
@@ -384,7 +384,7 @@ static int bfin_bf54x_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
         *   Other flags can be set, and are documented in
         *   include/linux/mm.h
         */
-       vma->vm_flags |= VM_MAYSHARE;
+       vma->vm_flags |=  VM_MAYSHARE | VM_SHARED;
 
        return 0;
 }
index a2bb2de..135d6dd 100644 (file)
@@ -91,6 +91,7 @@ struct bfin_t350mcqbfb_info {
        int lq043_open_cnt;
        int irq;
        spinlock_t lock;        /* lock */
+       u32 pseudo_pal[16];
 };
 
 static int nocursor;
@@ -182,13 +183,13 @@ static void bfin_t350mcqb_config_dma(struct bfin_t350mcqbfb_info *fbi)
 
 }
 
-static int bfin_t350mcqb_request_ports(int action)
-{
-       u16 ppi0_req_8[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
+static u16 ppi0_req_8[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2,
                            P_PPI0_D0, P_PPI0_D1, P_PPI0_D2,
                            P_PPI0_D3, P_PPI0_D4, P_PPI0_D5,
                            P_PPI0_D6, P_PPI0_D7, 0};
 
+static int bfin_t350mcqb_request_ports(int action)
+{
        if (action) {
                if (peripheral_request_list(ppi0_req_8, DRIVER_NAME)) {
                        printk(KERN_ERR "Requesting Peripherals faild\n");
@@ -301,7 +302,7 @@ static int bfin_t350mcqb_fb_mmap(struct fb_info *info, struct vm_area_struct *vm
         *   Other flags can be set, and are documented in
         *   include/linux/mm.h
         */
-       vma->vm_flags |= VM_MAYSHARE;
+       vma->vm_flags |= VM_MAYSHARE | VM_SHARED;
 
        return 0;
 }
@@ -520,16 +521,7 @@ static int __init bfin_t350mcqb_probe(struct platform_device *pdev)
 
        fbinfo->fbops = &bfin_t350mcqb_fb_ops;
 
-       fbinfo->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
-       if (!fbinfo->pseudo_palette) {
-               printk(KERN_ERR DRIVER_NAME
-                      "Fail to allocate pseudo_palette\n");
-
-               ret = -ENOMEM;
-               goto out4;
-       }
-
-       memset(fbinfo->pseudo_palette, 0, sizeof(u32) * 16);
+       fbinfo->pseudo_palette = &info->pseudo_pal;
 
        if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0)
            < 0) {
@@ -537,7 +529,7 @@ static int __init bfin_t350mcqb_probe(struct platform_device *pdev)
                       "Fail to allocate colormap (%d entries)\n",
                       BFIN_LCD_NBR_PALETTE_ENTRIES);
                ret = -EFAULT;
-               goto out5;
+               goto out4;
        }
 
        if (bfin_t350mcqb_request_ports(1)) {
@@ -552,11 +544,11 @@ static int __init bfin_t350mcqb_probe(struct platform_device *pdev)
                goto out7;
        }
 
-       if (request_irq(info->irq, (void *)bfin_t350mcqb_irq_error, IRQF_DISABLED,
-                       "PPI ERROR", info) < 0) {
+       ret = request_irq(info->irq, bfin_t350mcqb_irq_error, IRQF_DISABLED,
+                       "PPI ERROR", info);
+       if (ret < 0) {
                printk(KERN_ERR DRIVER_NAME
                       ": unable to request PPI ERROR IRQ\n");
-               ret = -EFAULT;
                goto out7;
        }
 
@@ -584,8 +576,6 @@ out7:
        bfin_t350mcqb_request_ports(0);
 out6:
        fb_dealloc_cmap(&fbinfo->cmap);
-out5:
-       kfree(fbinfo->pseudo_palette);
 out4:
        dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
                          info->dma_handle);
@@ -605,6 +595,8 @@ static int bfin_t350mcqb_remove(struct platform_device *pdev)
        struct fb_info *fbinfo = platform_get_drvdata(pdev);
        struct bfin_t350mcqbfb_info *info = fbinfo->par;
 
+       unregister_framebuffer(fbinfo);
+
        free_dma(CH_PPI);
        free_irq(info->irq, info);
 
@@ -612,7 +604,6 @@ static int bfin_t350mcqb_remove(struct platform_device *pdev)
                dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
                                  info->dma_handle);
 
-       kfree(fbinfo->pseudo_palette);
        fb_dealloc_cmap(&fbinfo->cmap);
 
 #ifndef NO_BL_SUPPORT
@@ -620,10 +611,11 @@ static int bfin_t350mcqb_remove(struct platform_device *pdev)
        backlight_device_unregister(bl_dev);
 #endif
 
-       unregister_framebuffer(fbinfo);
-
        bfin_t350mcqb_request_ports(0);
 
+       platform_set_drvdata(pdev, NULL);
+       framebuffer_release(fbinfo);
+
        printk(KERN_INFO DRIVER_NAME ": Unregister LCD driver.\n");
 
        return 0;
index 59a8f73..c0df924 100644 (file)
@@ -37,7 +37,7 @@ struct virtio_pci_device
        struct pci_dev *pci_dev;
 
        /* the IO mapping for the PCI config space */
-       void *ioaddr;
+       void __iomem *ioaddr;
 
        /* a list of queues so we can dispatch IRQs */
        spinlock_t lock;
@@ -111,7 +111,7 @@ static void vp_get(struct virtio_device *vdev, unsigned offset,
                   void *buf, unsigned len)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
-       void *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset;
+       void __iomem *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset;
        u8 *ptr = buf;
        int i;
 
@@ -125,7 +125,7 @@ static void vp_set(struct virtio_device *vdev, unsigned offset,
                   const void *buf, unsigned len)
 {
        struct virtio_pci_device *vp_dev = to_vp_device(vdev);
-       void *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset;
+       void __iomem *ioaddr = vp_dev->ioaddr + VIRTIO_PCI_CONFIG + offset;
        const u8 *ptr = buf;
        int i;
 
@@ -388,6 +388,7 @@ static void __devexit virtio_pci_remove(struct pci_dev *pci_dev)
 {
        struct virtio_pci_device *vp_dev = pci_get_drvdata(pci_dev);
 
+       unregister_virtio_device(&vp_dev->vdev);
        free_irq(pci_dev->irq, vp_dev);
        pci_set_drvdata(pci_dev, NULL);
        pci_iounmap(pci_dev, vp_dev->ioaddr);
index 970d38f..788865d 100644 (file)
@@ -127,14 +127,20 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist)
 
        _enter("%s,%s", name, vllist);
 
+       down_write(&afs_cells_sem);
+       read_lock(&afs_cells_lock);
+       list_for_each_entry(cell, &afs_cells, link) {
+               if (strcasecmp(cell->name, name) == 0)
+                       goto duplicate_name;
+       }
+       read_unlock(&afs_cells_lock);
+
        cell = afs_cell_alloc(name, vllist);
        if (IS_ERR(cell)) {
                _leave(" = %ld", PTR_ERR(cell));
                return cell;
        }
 
-       down_write(&afs_cells_sem);
-
        /* add a proc directory for this cell */
        ret = afs_proc_cell_setup(cell);
        if (ret < 0)
@@ -167,6 +173,11 @@ error:
        kfree(cell);
        _leave(" = %d", ret);
        return ERR_PTR(ret);
+
+duplicate_name:
+       read_unlock(&afs_cells_lock);
+       up_write(&afs_cells_sem);
+       return ERR_PTR(-EEXIST);
 }
 
 /*
index 5ca3625..9ba16ed 100644 (file)
@@ -573,7 +573,6 @@ extern const struct file_operations afs_mntpt_file_operations;
 
 extern int afs_mntpt_check_symlink(struct afs_vnode *, struct key *);
 extern void afs_mntpt_kill_timer(void);
-extern void afs_umount_begin(struct vfsmount *, int);
 
 /*
  * proc.c
index a3510b8..2f55039 100644 (file)
@@ -283,11 +283,3 @@ void afs_mntpt_kill_timer(void)
        cancel_delayed_work(&afs_mntpt_expiry_timer);
        flush_scheduled_work();
 }
-
-/*
- * begin unmount by attempting to remove all automounted mountpoints we added
- */
-void afs_umount_begin(struct vfsmount *vfsmnt, int flags)
-{
-       shrink_submounts(vfsmnt, &afs_vfsmounts);
-}
index 36bbce4..4b572b8 100644 (file)
@@ -50,7 +50,6 @@ static const struct super_operations afs_super_ops = {
        .write_inode    = afs_write_inode,
        .destroy_inode  = afs_destroy_inode,
        .clear_inode    = afs_clear_inode,
-       .umount_begin   = afs_umount_begin,
        .put_super      = afs_put_super,
        .show_options   = generic_show_options,
 };
index 7ba5838..9819632 100644 (file)
@@ -2564,14 +2564,13 @@ int nobh_write_end(struct file *file, struct address_space *mapping,
        struct inode *inode = page->mapping->host;
        struct buffer_head *head = fsdata;
        struct buffer_head *bh;
+       BUG_ON(fsdata != NULL && page_has_buffers(page));
 
-       if (!PageMappedToDisk(page)) {
-               if (unlikely(copied < len) && !page_has_buffers(page))
-                       attach_nobh_buffers(page, head);
-               if (page_has_buffers(page))
-                       return generic_write_end(file, mapping, pos, len,
-                                               copied, page, fsdata);
-       }
+       if (unlikely(copied < len) && !page_has_buffers(page))
+               attach_nobh_buffers(page, head);
+       if (page_has_buffers(page))
+               return generic_write_end(file, mapping, pos, len,
+                                       copied, page, fsdata);
 
        SetPageUptodate(page);
        set_page_dirty(page);
index a1a95b0..56c9240 100644 (file)
@@ -33,7 +33,6 @@ void dfs_shrink_umount_helper(struct vfsmount *vfsmnt)
 {
        mark_mounts_for_expiry(&cifs_dfs_automount_list);
        mark_mounts_for_expiry(&cifs_dfs_automount_list);
-       shrink_submounts(vfsmnt, &cifs_dfs_automount_list);
 }
 
 /**
index 1f5a428..1cb5b0a 100644 (file)
@@ -261,7 +261,7 @@ static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
        return;
 }
 
-static __le16 fill_ace_for_sid(struct cifs_ace *pntace,
+static __u16 fill_ace_for_sid(struct cifs_ace *pntace,
                        const struct cifs_sid *psid, __u64 nmode, umode_t bits)
 {
        int i;
@@ -411,7 +411,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl,
 static int set_chmod_dacl(struct cifs_acl *pndacl, struct cifs_sid *pownersid,
                        struct cifs_sid *pgrpsid, __u64 nmode)
 {
-       __le16 size = 0;
+       u16 size = 0;
        struct cifs_acl *pnndacl;
 
        pnndacl = (struct cifs_acl *)((char *)pndacl + sizeof(struct cifs_acl));
index 9816293..0e081d5 100644 (file)
@@ -1620,14 +1620,14 @@ static int journal_init_journal_head_cache(void)
 {
        int retval;
 
-       J_ASSERT(journal_head_cache == 0);
+       J_ASSERT(journal_head_cache == NULL);
        journal_head_cache = kmem_cache_create("journal_head",
                                sizeof(struct journal_head),
                                0,              /* offset */
                                SLAB_TEMPORARY, /* flags */
                                NULL);          /* ctor */
        retval = 0;
-       if (journal_head_cache == 0) {
+       if (!journal_head_cache) {
                retval = -ENOMEM;
                printk(KERN_EMERG "JBD: no memory for journal_head cache\n");
        }
index ad2eacf..d5f8eee 100644 (file)
@@ -173,13 +173,13 @@ int __init journal_init_revoke_caches(void)
                                           0,
                                           SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
                                           NULL);
-       if (revoke_record_cache == 0)
+       if (!revoke_record_cache)
                return -ENOMEM;
 
        revoke_table_cache = kmem_cache_create("revoke_table",
                                           sizeof(struct jbd_revoke_table_s),
                                           0, SLAB_TEMPORARY, NULL);
-       if (revoke_table_cache == 0) {
+       if (!revoke_table_cache) {
                kmem_cache_destroy(revoke_record_cache);
                revoke_record_cache = NULL;
                return -ENOMEM;
index 96ba846..954cff0 100644 (file)
@@ -219,7 +219,7 @@ static int jbd2_journal_start_thread(journal_t *journal)
        if (IS_ERR(t))
                return PTR_ERR(t);
 
-       wait_event(journal->j_wait_done_commit, journal->j_task != 0);
+       wait_event(journal->j_wait_done_commit, journal->j_task != NULL);
        return 0;
 }
 
@@ -231,7 +231,7 @@ static void journal_kill_thread(journal_t *journal)
        while (journal->j_task) {
                wake_up(&journal->j_wait_commit);
                spin_unlock(&journal->j_state_lock);
-               wait_event(journal->j_wait_done_commit, journal->j_task == 0);
+               wait_event(journal->j_wait_done_commit, journal->j_task == NULL);
                spin_lock(&journal->j_state_lock);
        }
        spin_unlock(&journal->j_state_lock);
@@ -1969,14 +1969,14 @@ static int journal_init_jbd2_journal_head_cache(void)
 {
        int retval;
 
-       J_ASSERT(jbd2_journal_head_cache == 0);
+       J_ASSERT(jbd2_journal_head_cache == NULL);
        jbd2_journal_head_cache = kmem_cache_create("jbd2_journal_head",
                                sizeof(struct journal_head),
                                0,              /* offset */
                                SLAB_TEMPORARY, /* flags */
                                NULL);          /* ctor */
        retval = 0;
-       if (jbd2_journal_head_cache == 0) {
+       if (!jbd2_journal_head_cache) {
                retval = -ENOMEM;
                printk(KERN_EMERG "JBD: no memory for journal_head cache\n");
        }
@@ -2002,14 +2002,14 @@ static struct journal_head *journal_alloc_journal_head(void)
        atomic_inc(&nr_journal_heads);
 #endif
        ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS);
-       if (ret == 0) {
+       if (!ret) {
                jbd_debug(1, "out of memory for journal_head\n");
                if (time_after(jiffies, last_warning + 5*HZ)) {
                        printk(KERN_NOTICE "ENOMEM in %s, retrying.\n",
                               __FUNCTION__);
                        last_warning = jiffies;
                }
-               while (ret == 0) {
+               while (!ret) {
                        yield();
                        ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS);
                }
index df36f42..2e1453a 100644 (file)
@@ -174,13 +174,13 @@ int __init jbd2_journal_init_revoke_caches(void)
                                           0,
                                           SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
                                           NULL);
-       if (jbd2_revoke_record_cache == 0)
+       if (!jbd2_revoke_record_cache)
                return -ENOMEM;
 
        jbd2_revoke_table_cache = kmem_cache_create("jbd2_revoke_table",
                                           sizeof(struct jbd2_revoke_table_s),
                                           0, SLAB_TEMPORARY, NULL);
-       if (jbd2_revoke_table_cache == 0) {
+       if (!jbd2_revoke_table_cache) {
                kmem_cache_destroy(jbd2_revoke_record_cache);
                jbd2_revoke_record_cache = NULL;
                return -ENOMEM;
index 7953c96..94f026e 100644 (file)
@@ -155,15 +155,15 @@ static void __touch_mnt_namespace(struct mnt_namespace *ns)
        }
 }
 
-static void detach_mnt(struct vfsmount *mnt, struct nameidata *old_nd)
+static void detach_mnt(struct vfsmount *mnt, struct path *old_path)
 {
-       old_nd->path.dentry = mnt->mnt_mountpoint;
-       old_nd->path.mnt = mnt->mnt_parent;
+       old_path->dentry = mnt->mnt_mountpoint;
+       old_path->mnt = mnt->mnt_parent;
        mnt->mnt_parent = mnt;
        mnt->mnt_mountpoint = mnt->mnt_root;
        list_del_init(&mnt->mnt_child);
        list_del_init(&mnt->mnt_hash);
-       old_nd->path.dentry->d_mounted--;
+       old_path->dentry->d_mounted--;
 }
 
 void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
@@ -174,12 +174,12 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry,
        dentry->d_mounted++;
 }
 
-static void attach_mnt(struct vfsmount *mnt, struct nameidata *nd)
+static void attach_mnt(struct vfsmount *mnt, struct path *path)
 {
-       mnt_set_mountpoint(nd->path.mnt, nd->path.dentry, mnt);
+       mnt_set_mountpoint(path->mnt, path->dentry, mnt);
        list_add_tail(&mnt->mnt_hash, mount_hashtable +
-                       hash(nd->path.mnt, nd->path.dentry));
-       list_add_tail(&mnt->mnt_child, &nd->path.mnt->mnt_mounts);
+                       hash(path->mnt, path->dentry));
+       list_add_tail(&mnt->mnt_child, &path->mnt->mnt_mounts);
 }
 
 /*
@@ -262,10 +262,8 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
                /* stick the duplicate mount on the same expiry list
                 * as the original if that was on one */
                if (flag & CL_EXPIRE) {
-                       spin_lock(&vfsmount_lock);
                        if (!list_empty(&old->mnt_expire))
                                list_add(&mnt->mnt_expire, &old->mnt_expire);
-                       spin_unlock(&vfsmount_lock);
                }
        }
        return mnt;
@@ -548,6 +546,7 @@ void release_mounts(struct list_head *head)
                        m = mnt->mnt_parent;
                        mnt->mnt_mountpoint = mnt->mnt_root;
                        mnt->mnt_parent = mnt;
+                       m->mnt_ghosts--;
                        spin_unlock(&vfsmount_lock);
                        dput(dentry);
                        mntput(m);
@@ -572,12 +571,16 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)
                __touch_mnt_namespace(p->mnt_ns);
                p->mnt_ns = NULL;
                list_del_init(&p->mnt_child);
-               if (p->mnt_parent != p)
+               if (p->mnt_parent != p) {
+                       p->mnt_parent->mnt_ghosts++;
                        p->mnt_mountpoint->d_mounted--;
+               }
                change_mnt_propagation(p, MS_PRIVATE);
        }
 }
 
+static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts);
+
 static int do_umount(struct vfsmount *mnt, int flags)
 {
        struct super_block *sb = mnt->mnt_sb;
@@ -650,6 +653,9 @@ static int do_umount(struct vfsmount *mnt, int flags)
        spin_lock(&vfsmount_lock);
        event++;
 
+       if (!(flags & MNT_DETACH))
+               shrink_submounts(mnt, &umount_list);
+
        retval = -EBUSY;
        if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) {
                if (!list_empty(&mnt->mnt_list))
@@ -744,7 +750,7 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
                                        int flag)
 {
        struct vfsmount *res, *p, *q, *r, *s;
-       struct nameidata nd;
+       struct path path;
 
        if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
                return NULL;
@@ -769,14 +775,14 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry,
                                q = q->mnt_parent;
                        }
                        p = s;
-                       nd.path.mnt = q;
-                       nd.path.dentry = p->mnt_mountpoint;
+                       path.mnt = q;
+                       path.dentry = p->mnt_mountpoint;
                        q = clone_mnt(p, p->mnt_root, flag);
                        if (!q)
                                goto Enomem;
                        spin_lock(&vfsmount_lock);
                        list_add_tail(&q->mnt_list, &res->mnt_list);
-                       attach_mnt(q, &nd);
+                       attach_mnt(q, &path);
                        spin_unlock(&vfsmount_lock);
                }
        }
@@ -876,11 +882,11 @@ void drop_collected_mounts(struct vfsmount *mnt)
  * in allocations.
  */
 static int attach_recursive_mnt(struct vfsmount *source_mnt,
-                       struct nameidata *nd, struct nameidata *parent_nd)
+                       struct path *path, struct path *parent_path)
 {
        LIST_HEAD(tree_list);
-       struct vfsmount *dest_mnt = nd->path.mnt;
-       struct dentry *dest_dentry = nd->path.dentry;
+       struct vfsmount *dest_mnt = path->mnt;
+       struct dentry *dest_dentry = path->dentry;
        struct vfsmount *child, *p;
 
        if (propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list))
@@ -892,9 +898,9 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt,
        }
 
        spin_lock(&vfsmount_lock);
-       if (parent_nd) {
-               detach_mnt(source_mnt, parent_nd);
-               attach_mnt(source_mnt, nd);
+       if (parent_path) {
+               detach_mnt(source_mnt, parent_path);
+               attach_mnt(source_mnt, path);
                touch_mnt_namespace(current->nsproxy->mnt_ns);
        } else {
                mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt);
@@ -930,7 +936,7 @@ static int graft_tree(struct vfsmount *mnt, struct nameidata *nd)
 
        err = -ENOENT;
        if (IS_ROOT(nd->path.dentry) || !d_unhashed(nd->path.dentry))
-               err = attach_recursive_mnt(mnt, nd, NULL);
+               err = attach_recursive_mnt(mnt, &nd->path, NULL);
 out_unlock:
        mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
        if (!err)
@@ -1059,7 +1065,8 @@ static inline int tree_contains_unbindable(struct vfsmount *mnt)
  */
 static noinline int do_move_mount(struct nameidata *nd, char *old_name)
 {
-       struct nameidata old_nd, parent_nd;
+       struct nameidata old_nd;
+       struct path parent_path;
        struct vfsmount *p;
        int err = 0;
        if (!capable(CAP_SYS_ADMIN))
@@ -1114,21 +1121,19 @@ static noinline int do_move_mount(struct nameidata *nd, char *old_name)
                if (p == old_nd.path.mnt)
                        goto out1;
 
-       err = attach_recursive_mnt(old_nd.path.mnt, nd, &parent_nd);
+       err = attach_recursive_mnt(old_nd.path.mnt, &nd->path, &parent_path);
        if (err)
                goto out1;
 
-       spin_lock(&vfsmount_lock);
        /* if the mount is moved, it should no longer be expire
         * automatically */
        list_del_init(&old_nd.path.mnt->mnt_expire);
-       spin_unlock(&vfsmount_lock);
 out1:
        mutex_unlock(&nd->path.dentry->d_inode->i_mutex);
 out:
        up_write(&namespace_sem);
        if (!err)
-               path_put(&parent_nd.path);
+               path_put(&parent_path);
        path_put(&old_nd.path);
        return err;
 }
@@ -1189,12 +1194,9 @@ int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
        if ((err = graft_tree(newmnt, nd)))
                goto unlock;
 
-       if (fslist) {
-               /* add to the specified expiration list */
-               spin_lock(&vfsmount_lock);
+       if (fslist) /* add to the specified expiration list */
                list_add_tail(&newmnt->mnt_expire, fslist);
-               spin_unlock(&vfsmount_lock);
-       }
+
        up_write(&namespace_sem);
        return 0;
 
@@ -1206,75 +1208,6 @@ unlock:
 
 EXPORT_SYMBOL_GPL(do_add_mount);
 
-static void expire_mount(struct vfsmount *mnt, struct list_head *mounts,
-                               struct list_head *umounts)
-{
-       spin_lock(&vfsmount_lock);
-
-       /*
-        * Check if mount is still attached, if not, let whoever holds it deal
-        * with the sucker
-        */
-       if (mnt->mnt_parent == mnt) {
-               spin_unlock(&vfsmount_lock);
-               return;
-       }
-
-       /*
-        * Check that it is still dead: the count should now be 2 - as
-        * contributed by the vfsmount parent and the mntget above
-        */
-       if (!propagate_mount_busy(mnt, 2)) {
-               /* delete from the namespace */
-               touch_mnt_namespace(mnt->mnt_ns);
-               list_del_init(&mnt->mnt_list);
-               mnt->mnt_ns = NULL;
-               umount_tree(mnt, 1, umounts);
-               spin_unlock(&vfsmount_lock);
-       } else {
-               /*
-                * Someone brought it back to life whilst we didn't have any
-                * locks held so return it to the expiration list
-                */
-               list_add_tail(&mnt->mnt_expire, mounts);
-               spin_unlock(&vfsmount_lock);
-       }
-}
-
-/*
- * go through the vfsmounts we've just consigned to the graveyard to
- * - check that they're still dead
- * - delete the vfsmount from the appropriate namespace under lock
- * - dispose of the corpse
- */
-static void expire_mount_list(struct list_head *graveyard, struct list_head *mounts)
-{
-       struct mnt_namespace *ns;
-       struct vfsmount *mnt;
-
-       while (!list_empty(graveyard)) {
-               LIST_HEAD(umounts);
-               mnt = list_first_entry(graveyard, struct vfsmount, mnt_expire);
-               list_del_init(&mnt->mnt_expire);
-
-               /* don't do anything if the namespace is dead - all the
-                * vfsmounts from it are going away anyway */
-               ns = mnt->mnt_ns;
-               if (!ns || !ns->root)
-                       continue;
-               get_mnt_ns(ns);
-
-               spin_unlock(&vfsmount_lock);
-               down_write(&namespace_sem);
-               expire_mount(mnt, mounts, &umounts);
-               up_write(&namespace_sem);
-               release_mounts(&umounts);
-               mntput(mnt);
-               put_mnt_ns(ns);
-               spin_lock(&vfsmount_lock);
-       }
-}
-
 /*
  * process a list of expirable mountpoints with the intent of discarding any
  * mountpoints that aren't in use and haven't been touched since last we came
@@ -1284,10 +1217,12 @@ void mark_mounts_for_expiry(struct list_head *mounts)
 {
        struct vfsmount *mnt, *next;
        LIST_HEAD(graveyard);
+       LIST_HEAD(umounts);
 
        if (list_empty(mounts))
                return;
 
+       down_write(&namespace_sem);
        spin_lock(&vfsmount_lock);
 
        /* extract from the expiration list every vfsmount that matches the
@@ -1298,16 +1233,19 @@ void mark_mounts_for_expiry(struct list_head *mounts)
         */
        list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
                if (!xchg(&mnt->mnt_expiry_mark, 1) ||
-                   atomic_read(&mnt->mnt_count) != 1)
+                       propagate_mount_busy(mnt, 1))
                        continue;
-
-               mntget(mnt);
                list_move(&mnt->mnt_expire, &graveyard);
        }
-
-       expire_mount_list(&graveyard, mounts);
-
+       while (!list_empty(&graveyard)) {
+               mnt = list_first_entry(&graveyard, struct vfsmount, mnt_expire);
+               touch_mnt_namespace(mnt->mnt_ns);
+               umount_tree(mnt, 1, &umounts);
+       }
        spin_unlock(&vfsmount_lock);
+       up_write(&namespace_sem);
+
+       release_mounts(&umounts);
 }
 
 EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);
@@ -1343,7 +1281,6 @@ resume:
                }
 
                if (!propagate_mount_busy(mnt, 1)) {
-                       mntget(mnt);
                        list_move_tail(&mnt->mnt_expire, graveyard);
                        found++;
                }
@@ -1363,22 +1300,22 @@ resume:
  * process a list of expirable mountpoints with the intent of discarding any
  * submounts of a specific parent mountpoint
  */
-void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts)
+static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts)
 {
        LIST_HEAD(graveyard);
-       int found;
-
-       spin_lock(&vfsmount_lock);
+       struct vfsmount *m;
 
        /* extract submounts of 'mountpoint' from the expiration list */
-       while ((found = select_submounts(mountpoint, &graveyard)) != 0)
-               expire_mount_list(&graveyard, mounts);
-
-       spin_unlock(&vfsmount_lock);
+       while (select_submounts(mnt, &graveyard)) {
+               while (!list_empty(&graveyard)) {
+                       m = list_first_entry(&graveyard, struct vfsmount,
+                                               mnt_expire);
+                       touch_mnt_namespace(mnt->mnt_ns);
+                       umount_tree(mnt, 1, umounts);
+               }
+       }
 }
 
-EXPORT_SYMBOL_GPL(shrink_submounts);
-
 /*
  * Some copy_from_user() implementations do not return the exact number of
  * bytes remaining to copy on a fault.  But copy_mount_options() requires that.
@@ -1683,7 +1620,7 @@ void set_fs_pwd(struct fs_struct *fs, struct path *path)
                path_put(&old_pwd);
 }
 
-static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
+static void chroot_fs_refs(struct path *old_root, struct path *new_root)
 {
        struct task_struct *g, *p;
        struct fs_struct *fs;
@@ -1695,12 +1632,12 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
                if (fs) {
                        atomic_inc(&fs->count);
                        task_unlock(p);
-                       if (fs->root.dentry == old_nd->path.dentry
-                           && fs->root.mnt == old_nd->path.mnt)
-                               set_fs_root(fs, &new_nd->path);
-                       if (fs->pwd.dentry == old_nd->path.dentry
-                           && fs->pwd.mnt == old_nd->path.mnt)
-                               set_fs_pwd(fs, &new_nd->path);
+                       if (fs->root.dentry == old_root->dentry
+                           && fs->root.mnt == old_root->mnt)
+                               set_fs_root(fs, new_root);
+                       if (fs->pwd.dentry == old_root->dentry
+                           && fs->pwd.mnt == old_root->mnt)
+                               set_fs_pwd(fs, new_root);
                        put_fs_struct(fs);
                } else
                        task_unlock(p);
@@ -1737,7 +1674,8 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
                               const char __user * put_old)
 {
        struct vfsmount *tmp;
-       struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd;
+       struct nameidata new_nd, old_nd, user_nd;
+       struct path parent_path, root_parent;
        int error;
 
        if (!capable(CAP_SYS_ADMIN))
@@ -1811,19 +1749,19 @@ asmlinkage long sys_pivot_root(const char __user * new_root,
                        goto out3;
        } else if (!is_subdir(old_nd.path.dentry, new_nd.path.dentry))
                goto out3;
-       detach_mnt(new_nd.path.mnt, &parent_nd);
+       detach_mnt(new_nd.path.mnt, &parent_path);
        detach_mnt(user_nd.path.mnt, &root_parent);
        /* mount old root on put_old */
-       attach_mnt(user_nd.path.mnt, &old_nd);
+       attach_mnt(user_nd.path.mnt, &old_nd.path);
        /* mount new_root on / */
        attach_mnt(new_nd.path.mnt, &root_parent);
        touch_mnt_namespace(current->nsproxy->mnt_ns);
        spin_unlock(&vfsmount_lock);
-       chroot_fs_refs(&user_nd, &new_nd);
+       chroot_fs_refs(&user_nd.path, &new_nd.path);
        security_sb_post_pivotroot(&user_nd, &new_nd);
        error = 0;
-       path_put(&root_parent.path);
-       path_put(&parent_nd.path);
+       path_put(&root_parent);
+       path_put(&parent_path);
 out2:
        mutex_unlock(&old_nd.path.dentry->d_inode->i_mutex);
        up_write(&namespace_sem);
index dd4dfcd..f921902 100644 (file)
@@ -589,8 +589,6 @@ static void nfs_umount_begin(struct vfsmount *vfsmnt, int flags)
        struct nfs_server *server = NFS_SB(vfsmnt->mnt_sb);
        struct rpc_clnt *rpc;
 
-       shrink_submounts(vfsmnt, &nfs_automount_list);
-
        if (!(flags & MNT_FORCE))
                return;
        /* -EIO all pending I/O */
index 05ba692..1d8f544 100644 (file)
@@ -225,7 +225,7 @@ out:
  */
 static inline int do_refcount_check(struct vfsmount *mnt, int count)
 {
-       int mycount = atomic_read(&mnt->mnt_count);
+       int mycount = atomic_read(&mnt->mnt_count) - mnt->mnt_ghosts;
        return (mycount > count);
 }
 
index f85c5cf..7ee4208 100644 (file)
@@ -283,7 +283,7 @@ static int balance_leaf(struct tree_balance *tb, struct item_head *ih,      /* item h
                return balance_leaf_when_delete(tb, flag);
 
        zeros_num = 0;
-       if (flag == M_INSERT && body == 0)
+       if (flag == M_INSERT && !body)
                zeros_num = ih_item_len(ih);
 
        pos_in_item = tb->tb_path->pos_in_item;
@@ -1728,7 +1728,7 @@ struct buffer_head *get_FEB(struct tree_balance *tb)
        struct buffer_info bi;
 
        for (i = 0; i < MAX_FEB_SIZE; i++)
-               if (tb->FEB[i] != 0)
+               if (tb->FEB[i] != NULL)
                        break;
 
        if (i == MAX_FEB_SIZE)
@@ -1827,7 +1827,7 @@ int get_left_neighbor_position(struct tree_balance *tb, int h)
 {
        int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1);
 
-       RFALSE(PATH_H_PPARENT(tb->tb_path, h) == 0 || tb->FL[h] == 0,
+       RFALSE(PATH_H_PPARENT(tb->tb_path, h) == NULL || tb->FL[h] == NULL,
               "vs-12325: FL[%d](%p) or F[%d](%p) does not exist",
               h, tb->FL[h], h, PATH_H_PPARENT(tb->tb_path, h));
 
@@ -1841,7 +1841,7 @@ int get_right_neighbor_position(struct tree_balance *tb, int h)
 {
        int Sh_position = PATH_H_POSITION(tb->tb_path, h + 1);
 
-       RFALSE(PATH_H_PPARENT(tb->tb_path, h) == 0 || tb->FR[h] == 0,
+       RFALSE(PATH_H_PPARENT(tb->tb_path, h) == NULL || tb->FR[h] == NULL,
               "vs-12330: F[%d](%p) or FR[%d](%p) does not exist",
               h, PATH_H_PPARENT(tb->tb_path, h), h, tb->FR[h]);
 
index 0ee35c6..07d05e0 100644 (file)
@@ -153,7 +153,7 @@ static void create_virtual_node(struct tree_balance *tb, int h)
        if (vn->vn_mode == M_INSERT) {
                struct virtual_item *vi = vn->vn_vi + vn->vn_affected_item_num;
 
-               RFALSE(vn->vn_ins_ih == 0,
+               RFALSE(vn->vn_ins_ih == NULL,
                       "vs-8040: item header of inserted item is not specified");
                vi->vi_item_len = tb->insert_size[0];
                vi->vi_ih = vn->vn_ins_ih;
@@ -857,7 +857,8 @@ static int get_lfree(struct tree_balance *tb, int h)
        struct buffer_head *l, *f;
        int order;
 
-       if ((f = PATH_H_PPARENT(tb->tb_path, h)) == 0 || (l = tb->FL[h]) == 0)
+       if ((f = PATH_H_PPARENT(tb->tb_path, h)) == NULL ||
+           (l = tb->FL[h]) == NULL)
                return 0;
 
        if (f == l)
@@ -878,7 +879,8 @@ static int get_rfree(struct tree_balance *tb, int h)
        struct buffer_head *r, *f;
        int order;
 
-       if ((f = PATH_H_PPARENT(tb->tb_path, h)) == 0 || (r = tb->FR[h]) == 0)
+       if ((f = PATH_H_PPARENT(tb->tb_path, h)) == NULL ||
+           (r = tb->FR[h]) == NULL)
                return 0;
 
        if (f == r)
index 281f806..6de060a 100644 (file)
@@ -626,7 +626,7 @@ static void leaf_define_dest_src_infos(int shift_mode, struct tree_balance *tb,
                               "vs-10250: leaf_define_dest_src_infos: shift type is unknown (%d)",
                               shift_mode);
        }
-       RFALSE(src_bi->bi_bh == 0 || dest_bi->bi_bh == 0,
+       RFALSE(!src_bi->bi_bh || !dest_bi->bi_bh,
               "vs-10260: mode==%d, source (%p) or dest (%p) buffer is initialized incorrectly",
               shift_mode, src_bi->bi_bh, dest_bi->bi_bh);
 }
index b378eea..8867533 100644 (file)
@@ -452,7 +452,7 @@ static int reiserfs_add_entry(struct reiserfs_transaction_handle *th,
        buflen = DEH_SIZE + ROUND_UP(namelen);
        if (buflen > sizeof(small_buf)) {
                buffer = kmalloc(buflen, GFP_NOFS);
-               if (buffer == 0)
+               if (!buffer)
                        return -ENOMEM;
        } else
                buffer = small_buf;
index fae8e85..6bd9b69 100644 (file)
@@ -206,7 +206,7 @@ int smbiod_retry(struct smb_sb_info *server)
 
        smb_close_socket(server);
 
-       if (pid == 0) {
+       if (!pid) {
                /* FIXME: this is fatal, umount? */
                printk(KERN_ERR "smb_retry: no connection process\n");
                server->state = CONN_RETRIED;
index 402ff41..d77b48b 100644 (file)
@@ -12,8 +12,14 @@ extern unsigned long __builtin_bswap_32(unsigned long x);
 extern unsigned short __builtin_bswap_16(unsigned short x);
 #endif
 
+/*
+ * avr32-linux-gcc versions earlier than 4.2 improperly sign-extends
+ * the result.
+ */
+#if !(__GNUC__ == 4 && __GNUC_MINOR__ < 2)
 #define __arch__swab32(x) __builtin_bswap_32(x)
 #define __arch__swab16(x) __builtin_bswap_16(x)
+#endif
 
 #if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
 # define __BYTEORDER_HAS_U64__
index b400cea..2c57f47 100644 (file)
@@ -234,7 +234,7 @@ extern void free_initmem(void);
                break;                                                          \
                                                                                \
        default:                                                                \
-               __xg_orig = 0;                                                  \
+               __xg_orig = (__typeof__(__xg_orig))0;                           \
                asm volatile("break");                                          \
                break;                                                          \
        }                                                                       \
@@ -259,7 +259,7 @@ extern uint32_t __cmpxchg_32(uint32_t *v, uint32_t test, uint32_t new);
                                         (__force uint32_t)__xg_test,           \
                                         (__force uint32_t)__xg_new); break;    \
        default:                                                                \
-               __xg_orig = 0;                                                  \
+               __xg_orig = (__typeof__(__xg_orig))0;                           \
                asm volatile("break");                                          \
                break;                                                          \
        }                                                                       \
index 5424214..532975e 100644 (file)
@@ -86,6 +86,8 @@ extern struct trap_per_cpu trap_block[NR_CPUS];
 extern void init_cur_cpu_trap(struct thread_info *);
 extern void setup_tba(void);
 extern int ncpus_probed;
+extern void __init cpu_probe(void);
+extern const struct seq_operations cpuinfo_op;
 
 extern unsigned long real_hard_smp_processor_id(void);
 
index ecbed2a..0f704e1 100644 (file)
@@ -1,26 +1,27 @@
-/* $Id: dcu.h,v 1.2 2001/03/01 23:23:33 davem Exp $ */
 #ifndef _SPARC64_DCU_H
 #define _SPARC64_DCU_H
 
+#include <linux/const.h>
+
 /* UltraSparc-III Data Cache Unit Control Register */
-#define DCU_CP         0x0002000000000000 /* Physical Cache Enable w/o mmu*/
-#define DCU_CV         0x0001000000000000 /* Virtual Cache Enable      w/o mmu */
-#define DCU_ME         0x0000800000000000 /* NC-store Merging Enable   */
-#define DCU_RE         0x0000400000000000 /* RAW bypass Enable         */
-#define DCU_PE         0x0000200000000000 /* PCache Enable             */
-#define DCU_HPE                0x0000100000000000 /* HW prefetch Enable                */
-#define DCU_SPE                0x0000080000000000 /* SW prefetch Enable                */
-#define DCU_SL         0x0000040000000000 /* Secondary load steering Enab      */
-#define DCU_WE         0x0000020000000000 /* WCache enable             */
-#define DCU_PM         0x000001fe00000000 /* PA Watchpoint Byte Mask   */
-#define DCU_VM         0x00000001fe000000 /* VA Watchpoint Byte Mask   */
-#define DCU_PR         0x0000000001000000 /* PA Watchpoint Read Enable */
-#define DCU_PW         0x0000000000800000 /* PA Watchpoint Write Enable        */
-#define DCU_VR         0x0000000000400000 /* VA Watchpoint Read Enable */
-#define DCU_VW         0x0000000000200000 /* VA Watchpoint Write Enable        */
-#define DCU_DM         0x0000000000000008 /* DMMU Enable                       */
-#define DCU_IM         0x0000000000000004 /* IMMU Enable                       */
-#define DCU_DC         0x0000000000000002 /* Data Cache Enable         */
-#define DCU_IC         0x0000000000000001 /* Instruction Cache Enable  */
+#define DCU_CP _AC(0x0002000000000000,UL) /* Phys Cache Enable w/o mmu */
+#define DCU_CV _AC(0x0001000000000000,UL) /* Virt Cache Enable w/o mmu */
+#define DCU_ME _AC(0x0000800000000000,UL) /* NC-store Merging Enable   */
+#define DCU_RE _AC(0x0000400000000000,UL) /* RAW bypass Enable         */
+#define DCU_PE _AC(0x0000200000000000,UL) /* PCache Enable             */
+#define DCU_HPE        _AC(0x0000100000000000,UL) /* HW prefetch Enable        */
+#define DCU_SPE        _AC(0x0000080000000000,UL) /* SW prefetch Enable        */
+#define DCU_SL _AC(0x0000040000000000,UL) /* Secondary ld-steering Enab*/
+#define DCU_WE _AC(0x0000020000000000,UL) /* WCache enable             */
+#define DCU_PM _AC(0x000001fe00000000,UL) /* PA Watchpoint Byte Mask   */
+#define DCU_VM _AC(0x00000001fe000000,UL) /* VA Watchpoint Byte Mask   */
+#define DCU_PR _AC(0x0000000001000000,UL) /* PA Watchpoint Read Enable */
+#define DCU_PW _AC(0x0000000000800000,UL) /* PA Watchpoint Write Enable*/
+#define DCU_VR _AC(0x0000000000400000,UL) /* VA Watchpoint Read Enable */
+#define DCU_VW _AC(0x0000000000200000,UL) /* VA Watchpoint Write Enable*/
+#define DCU_DM _AC(0x0000000000000008,UL) /* DMMU Enable               */
+#define DCU_IM _AC(0x0000000000000004,UL) /* IMMU Enable               */
+#define DCU_DC _AC(0x0000000000000002,UL) /* Data Cache Enable         */
+#define DCU_IC _AC(0x0000000000000001,UL) /* Instruction Cache Enable  */
 
 #endif /* _SPARC64_DCU_H */
index 30cb76b..0bb9bf5 100644 (file)
@@ -64,6 +64,7 @@ extern unsigned char virt_irq_alloc(unsigned int dev_handle,
 extern void virt_irq_free(unsigned int virt_irq);
 #endif
 
+extern void __init init_IRQ(void);
 extern void fixup_irqs(void);
 
 static inline void set_softint(unsigned long bits)
index 3167ccf..549e452 100644 (file)
@@ -23,9 +23,9 @@
 #include <asm/page.h>
 #include <asm/processor.h>
 
-/* The kernel image occupies 0x4000000 to 0x1000000 (4MB --> 32MB).
- * The page copy blockops can use 0x2000000 to 0x4000000.
- * The TSB is mapped in the 0x4000000 to 0x6000000 range.
+/* The kernel image occupies 0x4000000 to 0x6000000 (4MB --> 96MB).
+ * The page copy blockops can use 0x6000000 to 0x8000000.
+ * The TSB is mapped in the 0x8000000 to 0xa000000 range.
  * The PROM resides in an area spanning 0xf0000000 to 0x100000000.
  * The vmalloc area spans 0x100000000 to 0x200000000.
  * Since modules need to be in the lowest 32-bits of the address space,
@@ -33,8 +33,8 @@
  * There is a single static kernel PMD which maps from 0x0 to address
  * 0x400000000.
  */
-#define        TLBTEMP_BASE            _AC(0x0000000002000000,UL)
-#define        TSBMAP_BASE             _AC(0x0000000004000000,UL)
+#define        TLBTEMP_BASE            _AC(0x0000000006000000,UL)
+#define        TSBMAP_BASE             _AC(0x0000000008000000,UL)
 #define MODULES_VADDR          _AC(0x0000000010000000,UL)
 #define MODULES_LEN            _AC(0x00000000e0000000,UL)
 #define MODULES_END            _AC(0x00000000f0000000,UL)
@@ -761,6 +761,8 @@ extern unsigned long get_fb_unmapped_area(struct file *filp, unsigned long,
 extern void pgtable_cache_init(void);
 extern void sun4v_register_fault_status(void);
 extern void sun4v_ktsb_register(void);
+extern void __init cheetah_ecache_flush_init(void);
+extern void sun4v_patch_tlb_handlers(void);
 
 extern unsigned long cmdline_memory_size;
 
index 8da484c..885b6a1 100644 (file)
@@ -37,6 +37,9 @@
 #endif
 
 #define TASK_SIZE      ((unsigned long)-VPTE_SIZE)
+#define TASK_SIZE_OF(tsk) \
+       (test_tsk_thread_flag(tsk,TIF_32BIT) ? \
+        (1UL << 32UL) : TASK_SIZE)
 #ifdef __KERNEL__
 
 #define STACK_TOP32    ((1UL << 32UL) - PAGE_SIZE)
diff --git a/include/asm-sparc64/stacktrace.h b/include/asm-sparc64/stacktrace.h
new file mode 100644 (file)
index 0000000..6cee39a
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _SPARC64_STACKTRACE_H
+#define _SPARC64_STACKTRACE_H
+
+extern void stack_trace_flush(void);
+
+#endif /* _SPARC64_STACKTRACE_H */
index ccbd694..5b779fd 100644 (file)
@@ -1,14 +1,13 @@
-/* $Id: timer.h,v 1.3 2000/05/09 17:40:15 davem Exp $
- * timer.h: System timer definitions for sun5.
+/* timer.h: System timer definitions for sun5.
  *
- * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1997, 2008 David S. Miller (davem@davemloft.net)
  */
 
 #ifndef _SPARC64_TIMER_H
 #define _SPARC64_TIMER_H
 
 #include <linux/types.h>
-
+#include <linux/init.h>
 
 struct sparc64_tick_ops {
        unsigned long (*get_tick)(void);
@@ -25,5 +24,7 @@ struct sparc64_tick_ops {
 extern struct sparc64_tick_ops *tick_ops;
 
 extern unsigned long sparc64_get_clock_tick(unsigned int cpu);
+extern void __devinit setup_sparc64_timer(void);
+extern void __init time_init(void);
 
 #endif /* _SPARC64_TIMER_H */
index 758b9a5..f239e70 100644 (file)
@@ -27,7 +27,7 @@
 #ifndef __ASSEMBLY__
 #include <asm/hw_irq.h>
 
-/*G:031 First, how does our Guest contact the Host to ask for privileged
+/*G:031 But first, how does our Guest contact the Host to ask for privileged
  * operations?  There are two ways: the direct way is to make a "hypercall",
  * to make requests of the Host Itself.
  *
index db31b92..acce0b7 100644 (file)
@@ -5,19 +5,20 @@ extern int rdc_gpio_get_value(unsigned gpio);
 extern void rdc_gpio_set_value(unsigned gpio, int value);
 extern int rdc_gpio_direction_input(unsigned gpio);
 extern int rdc_gpio_direction_output(unsigned gpio, int value);
-
+extern int rdc_gpio_request(unsigned gpio, const char *label);
+extern void rdc_gpio_free(unsigned gpio);
+extern void __init rdc321x_gpio_setup(void);
 
 /* Wrappers for the arch-neutral GPIO API */
 
 static inline int gpio_request(unsigned gpio, const char *label)
 {
-       /* Not yet implemented */
-       return 0;
+       return rdc_gpio_request(gpio, label);
 }
 
 static inline void gpio_free(unsigned gpio)
 {
-       /* Not yet implemented */
+       rdc_gpio_free(gpio);
 }
 
 static inline int gpio_direction_input(unsigned gpio)
index 838ba8f..c8e9c8b 100644 (file)
@@ -3,4 +3,10 @@
 /* General purpose configuration and data registers */
 #define RDC3210_CFGREG_ADDR     0x0CF8
 #define RDC3210_CFGREG_DATA     0x0CFC
-#define RDC_MAX_GPIO           0x3A
+
+#define RDC321X_GPIO_CTRL_REG1 0x48
+#define RDC321X_GPIO_CTRL_REG2 0x84
+#define RDC321X_GPIO_DATA_REG1 0x4c
+#define RDC321X_GPIO_DATA_REG2 0x88
+
+#define RDC321X_MAX_GPIO       58
index 174b877..9cf472a 100644 (file)
@@ -85,6 +85,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
 #define __PAGE_KERNEL_RX               (__PAGE_KERNEL_EXEC & ~_PAGE_RW)
 #define __PAGE_KERNEL_EXEC_NOCACHE     (__PAGE_KERNEL_EXEC | _PAGE_PCD | _PAGE_PWT)
 #define __PAGE_KERNEL_NOCACHE          (__PAGE_KERNEL | _PAGE_PCD | _PAGE_PWT)
+#define __PAGE_KERNEL_UC_MINUS         (__PAGE_KERNEL | _PAGE_PCD)
 #define __PAGE_KERNEL_VSYSCALL         (__PAGE_KERNEL_RX | _PAGE_USER)
 #define __PAGE_KERNEL_VSYSCALL_NOCACHE (__PAGE_KERNEL_VSYSCALL | _PAGE_PCD | _PAGE_PWT)
 #define __PAGE_KERNEL_LARGE            (__PAGE_KERNEL | _PAGE_PSE)
@@ -101,6 +102,7 @@ extern pteval_t __PAGE_KERNEL, __PAGE_KERNEL_EXEC;
 #define PAGE_KERNEL_EXEC               MAKE_GLOBAL(__PAGE_KERNEL_EXEC)
 #define PAGE_KERNEL_RX                 MAKE_GLOBAL(__PAGE_KERNEL_RX)
 #define PAGE_KERNEL_NOCACHE            MAKE_GLOBAL(__PAGE_KERNEL_NOCACHE)
+#define PAGE_KERNEL_UC_MINUS           MAKE_GLOBAL(__PAGE_KERNEL_UC_MINUS)
 #define PAGE_KERNEL_EXEC_NOCACHE       MAKE_GLOBAL(__PAGE_KERNEL_EXEC_NOCACHE)
 #define PAGE_KERNEL_LARGE              MAKE_GLOBAL(__PAGE_KERNEL_LARGE)
 #define PAGE_KERNEL_LARGE_EXEC         MAKE_GLOBAL(__PAGE_KERNEL_LARGE_EXEC)
index 4108b38..4a446a1 100644 (file)
@@ -195,7 +195,6 @@ unifdef-y += ethtool.h
 unifdef-y += eventpoll.h
 unifdef-y += signalfd.h
 unifdef-y += ext2_fs.h
-unifdef-y += ext3_fs.h
 unifdef-y += fb.h
 unifdef-y += fcntl.h
 unifdef-y += filter.h
@@ -248,7 +247,6 @@ unifdef-y += isdn.h
 unifdef-y += isdnif.h
 unifdef-y += isdn_divertif.h
 unifdef-y += isdn_ppp.h
-unifdef-y += jbd.h
 unifdef-y += joystick.h
 unifdef-y += kdev_t.h
 unifdef-y += kd.h
index 69c1edb..40d5473 100644 (file)
@@ -65,6 +65,46 @@ static inline __u32 ror32(__u32 word, unsigned int shift)
        return (word >> shift) | (word << (32 - shift));
 }
 
+/**
+ * rol16 - rotate a 16-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u16 rol16(__u16 word, unsigned int shift)
+{
+       return (word << shift) | (word >> (16 - shift));
+}
+
+/**
+ * ror16 - rotate a 16-bit value right
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u16 ror16(__u16 word, unsigned int shift)
+{
+       return (word >> shift) | (word << (16 - shift));
+}
+
+/**
+ * rol8 - rotate an 8-bit value left
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u8 rol8(__u8 word, unsigned int shift)
+{
+       return (word << shift) | (word >> (8 - shift));
+}
+
+/**
+ * ror8 - rotate an 8-bit value right
+ * @word: value to rotate
+ * @shift: bits to roll
+ */
+static inline __u8 ror8(__u8 word, unsigned int shift)
+{
+       return (word >> shift) | (word << (8 - shift));
+}
+
 static inline unsigned fls_long(unsigned long l)
 {
        if (sizeof(l) == 4)
index a671dbf..8fa7857 100644 (file)
@@ -192,8 +192,8 @@ asmlinkage long compat_sys_select(int n, compat_ulong_t __user *inp,
                struct compat_timeval __user *tvp);
 
 asmlinkage long compat_sys_wait4(compat_pid_t pid,
-                                compat_uint_t *stat_addr, int options,
-                                struct compat_rusage *ru);
+                                compat_uint_t __user *stat_addr, int options,
+                                struct compat_rusage __user *ru);
 
 #define BITS_PER_COMPAT_LONG    (8*sizeof(compat_long_t))
 
index 6b72a45..51e6b1e 100644 (file)
@@ -38,8 +38,8 @@ struct cpuidle_state {
        unsigned int    power_usage; /* in mW */
        unsigned int    target_residency; /* in US */
 
-       unsigned int    usage;
-       unsigned int    time; /* in US */
+       unsigned long long      usage;
+       unsigned long long      time; /* in US */
 
        int (*enter)    (struct cpuidle_device *dev,
                         struct cpuidle_state *state);
index 261e43a..34d4406 100644 (file)
@@ -423,7 +423,7 @@ void dma_async_device_unregister(struct dma_device *device);
 /* --- Helper iov-locking functions --- */
 
 struct dma_page_list {
-       char *base_address;
+       char __user *base_address;
        int nr_pages;
        struct page **pages;
 };
index 4982998..897f723 100644 (file)
 #define in_softirq()           (softirq_count())
 #define in_interrupt()         (irq_count())
 
+/*
+ * Are we running in atomic context?  WARNING: this macro cannot
+ * always detect atomic context; in particular, it cannot know about
+ * held spinlocks in non-preemptible kernels.  Thus it should not be
+ * used in the general case to determine whether sleeping is possible.
+ * Do not use in_atomic() in driver code.
+ */
 #define in_atomic()            ((preempt_count() & ~PREEMPT_ACTIVE) != 0)
 
 #ifdef CONFIG_PREEMPT
index a3b69c1..bc26b2f 100644 (file)
@@ -26,7 +26,7 @@
 #include <asm/semaphore.h>
 #include <asm/mutex.h>
 
-#if defined(CRIS) || defined(FRV)
+#if defined(CONFIG_CRIS) || defined(CONFIG_FRV)
 # define SUPPORT_VLB_SYNC 0
 #else
 # define SUPPORT_VLB_SYNC 1
index 1bdc39a..cae2c35 100644 (file)
@@ -1227,12 +1227,13 @@ void input_free_device(struct input_dev *dev);
 
 static inline struct input_dev *input_get_device(struct input_dev *dev)
 {
-       return to_input_dev(get_device(&dev->dev));
+       return dev ? to_input_dev(get_device(&dev->dev)) : NULL;
 }
 
 static inline void input_put_device(struct input_dev *dev)
 {
-       put_device(&dev->dev);
+       if (dev)
+               put_device(&dev->dev);
 }
 
 static inline void *input_get_drvdata(struct input_dev *dev)
index 589be3e..e7217dc 100644 (file)
  * a new device, we simply need to write a new virtio driver and create support
  * for it in the Launcher: this code won't need to change.
  *
+ * Virtio devices are also used by kvm, so we can simply reuse their optimized
+ * device drivers.  And one day when everyone uses virtio, my plan will be
+ * complete.  Bwahahahah!
+ *
  * Devices are described by a simplified ID, a status byte, and some "config"
  * bytes which describe this device's configuration.  This is placed by the
  * Launcher just above the top of physical memory:
@@ -26,7 +30,7 @@ struct lguest_device_desc {
        /* The number of virtqueues (first in config array) */
        __u8 num_vq;
        /* The number of bytes of feature bits.  Multiply by 2: one for host
-        * features and one for guest acknowledgements. */
+        * features and one for Guest acknowledgements. */
        __u8 feature_len;
        /* The number of bytes of the config array after virtqueues. */
        __u8 config_len;
index 269cdba..b064bfe 100644 (file)
@@ -295,6 +295,7 @@ enum {
        ATA_EH_SOFTRESET        = (1 << 1),
        ATA_EH_HARDRESET        = (1 << 2),
        ATA_EH_ENABLE_LINK      = (1 << 3),
+       ATA_EH_LPM              = (1 << 4),  /* link power management action */
 
        ATA_EH_RESET_MASK       = ATA_EH_SOFTRESET | ATA_EH_HARDRESET,
        ATA_EH_PERDEV_MASK      = ATA_EH_REVALIDATE,
@@ -304,7 +305,6 @@ enum {
        ATA_EHI_RESUME_LINK     = (1 << 1),  /* resume link (reset modifier) */
        ATA_EHI_NO_AUTOPSY      = (1 << 2),  /* no autopsy */
        ATA_EHI_QUIET           = (1 << 3),  /* be quiet */
-       ATA_EHI_LPM             = (1 << 4),  /* link power management action */
 
        ATA_EHI_DID_SOFTRESET   = (1 << 16), /* already soft-reset this port */
        ATA_EHI_DID_HARDRESET   = (1 << 17), /* already soft-reset this port */
index 6d3047d..5ee2df2 100644 (file)
@@ -61,6 +61,7 @@ struct vfsmount {
        atomic_t mnt_count;
        int mnt_expiry_mark;            /* true if marked for expiry */
        int mnt_pinned;
+       int mnt_ghosts;
 };
 
 static inline struct vfsmount *mntget(struct vfsmount *mnt)
@@ -98,7 +99,6 @@ extern int do_add_mount(struct vfsmount *newmnt, struct nameidata *nd,
                        int mnt_flags, struct list_head *fslist);
 
 extern void mark_mounts_for_expiry(struct list_head *mounts);
-extern void shrink_submounts(struct vfsmount *mountpoint, struct list_head *mounts);
 
 extern spinlock_t vfsmount_lock;
 extern dev_t name_to_dev_t(char *name);
index fed07d0..6a1e7af 100644 (file)
@@ -1541,6 +1541,12 @@ static inline void idle_task_exit(void) {}
 
 extern void sched_idle_next(void);
 
+#if defined(CONFIG_NO_HZ) && defined(CONFIG_SMP)
+extern void wake_up_idle_cpu(int cpu);
+#else
+static inline void wake_up_idle_cpu(int cpu) { }
+#endif
+
 #ifdef CONFIG_SCHED_DEBUG
 extern unsigned int sysctl_sched_latency;
 extern unsigned int sysctl_sched_min_granularity;
index ebbfb50..64a5f01 100644 (file)
@@ -218,6 +218,10 @@ extern unsigned long               neigh_rand_reach_time(unsigned long base);
 extern void                    pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
                                               struct sk_buff *skb);
 extern struct pneigh_entry     *pneigh_lookup(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev, int creat);
+extern struct pneigh_entry     *__pneigh_lookup(struct neigh_table *tbl,
+                                                struct net *net,
+                                                const void *key,
+                                                struct net_device *dev);
 extern int                     pneigh_delete(struct neigh_table *tbl, struct net *net, const void *key, struct net_device *dev);
 
 extern void neigh_app_ns(struct neighbour *n);
index 619c53b..0d255ae 100644 (file)
@@ -204,6 +204,7 @@ struct xfrm_state
         * transformer. */
        const struct xfrm_type  *type;
        struct xfrm_mode        *inner_mode;
+       struct xfrm_mode        *inner_mode_iaf;
        struct xfrm_mode        *outer_mode;
 
        /* Security context */
@@ -387,6 +388,27 @@ enum {
 extern int xfrm_register_mode(struct xfrm_mode *mode, int family);
 extern int xfrm_unregister_mode(struct xfrm_mode *mode, int family);
 
+static inline int xfrm_af2proto(unsigned int family)
+{
+       switch(family) {
+       case AF_INET:
+               return IPPROTO_IPIP;
+       case AF_INET6:
+               return IPPROTO_IPV6;
+       default:
+               return 0;
+       }
+}
+
+static inline struct xfrm_mode *xfrm_ip2inner_mode(struct xfrm_state *x, int ipproto)
+{
+       if ((ipproto == IPPROTO_IPIP && x->props.family == AF_INET) ||
+           (ipproto == IPPROTO_IPV6 && x->props.family == AF_INET6))
+               return x->inner_mode;
+       else
+               return x->inner_mode_iaf;
+}
+
 struct xfrm_tmpl
 {
 /* id in template is interpreted as:
@@ -530,6 +552,9 @@ struct xfrm_mode_skb_cb {
        __be16 id;
        __be16 frag_off;
 
+       /* IP header length (excluding options or extension headers). */
+       u8 ihl;
+
        /* TOS for IPv4, class for IPv6. */
        u8 tos;
 
@@ -539,6 +564,9 @@ struct xfrm_mode_skb_cb {
        /* Protocol for IPv4, NH for IPv6. */
        u8 protocol;
 
+       /* Option length for IPv4, zero for IPv6. */
+       u8 optlen;
+
        /* Used by IPv6 only, zero for IPv4. */
        u8 flow_lbl[3];
 };
@@ -1253,6 +1281,7 @@ extern int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi,
 extern int xfrm_input_resume(struct sk_buff *skb, int nexthdr);
 extern int xfrm_output_resume(struct sk_buff *skb, int err);
 extern int xfrm_output(struct sk_buff *skb);
+extern int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm4_extract_header(struct sk_buff *skb);
 extern int xfrm4_extract_input(struct xfrm_state *x, struct sk_buff *skb);
 extern int xfrm4_rcv_encap(struct sk_buff *skb, int nexthdr, __be32 spi,
index be55cb5..b782b04 100644 (file)
@@ -1269,8 +1269,8 @@ static void audit_log_n_string(struct audit_buffer *ab, size_t slen,
 
 /**
  * audit_string_contains_control - does a string need to be logged in hex
- * @string - string to be checked
- * @len - max length of the string to check
+ * @string: string to be checked
+ * @len: max length of the string to check
  */
 int audit_string_contains_control(const char *string, size_t len)
 {
@@ -1285,7 +1285,7 @@ int audit_string_contains_control(const char *string, size_t len)
 /**
  * audit_log_n_untrustedstring - log a string that may contain random characters
  * @ab: audit_buffer
- * @len: lenth of string (not including trailing null)
+ * @len: length of string (not including trailing null)
  * @string: string to be logged
  *
  * This code will escape a string that is passed to it if the string
index e9c2fb0..53d86b4 100644 (file)
@@ -2082,7 +2082,7 @@ static int cgroup_tasks_open(struct inode *unused, struct file *file)
 
                kfree(pidarray);
        } else {
-               ctr->buf = 0;
+               ctr->buf = NULL;
                ctr->bufsz = 0;
        }
        file->private_data = ctr;
@@ -2614,7 +2614,7 @@ static int proc_cgroupstats_show(struct seq_file *m, void *v)
 
 static int cgroupstats_open(struct inode *inode, struct file *file)
 {
-       return single_open(file, proc_cgroupstats_show, 0);
+       return single_open(file, proc_cgroupstats_show, NULL);
 }
 
 static struct file_operations proc_cgroupstats_operations = {
index dd249c3..9c042f9 100644 (file)
@@ -394,7 +394,6 @@ void __mmdrop(struct mm_struct *mm)
 {
        BUG_ON(mm == &init_mm);
        mm_free_pgd(mm);
-       mm_free_cgroup(mm);
        destroy_context(mm);
        free_mm(mm);
 }
@@ -416,6 +415,7 @@ void mmput(struct mm_struct *mm)
                        spin_unlock(&mmlist_lock);
                }
                put_swap_token(mm);
+               mm_free_cgroup(mm);
                mmdrop(mm);
        }
 }
index 06968cd..e43945e 100644 (file)
@@ -281,7 +281,7 @@ static int get_futex_key(u32 __user *uaddr, struct rw_semaphore *fshared,
  */
 static void get_futex_key_refs(union futex_key *key)
 {
-       if (key->both.ptr == 0)
+       if (key->both.ptr == NULL)
                return;
        switch (key->both.offset & (FUT_OFF_INODE|FUT_OFF_MMSHARED)) {
                case FUT_OFF_INODE:
@@ -2158,7 +2158,7 @@ static struct file_system_type futex_fs_type = {
        .kill_sb        = kill_anon_super,
 };
 
-static int __init init(void)
+static int __init futex_init(void)
 {
        u32 curval;
        int i;
@@ -2194,4 +2194,4 @@ static int __init init(void)
 
        return 0;
 }
-__initcall(init);
+__initcall(futex_init);
index ff90f04..04ac3a9 100644 (file)
@@ -30,7 +30,7 @@ fetch_robust_entry(compat_uptr_t *uentry, struct robust_list __user **entry,
        return 0;
 }
 
-static void __user *futex_uaddr(struct robust_list *entry,
+static void __user *futex_uaddr(struct robust_list __user *entry,
                                compat_long_t futex_offset)
 {
        compat_uptr_t base = ptr_to_compat(entry);
index 4c035a8..d6204a4 100644 (file)
@@ -736,7 +736,7 @@ static int relay_file_open(struct inode *inode, struct file *filp)
        kref_get(&buf->kref);
        filp->private_data = buf;
 
-       return 0;
+       return nonseekable_open(inode, filp);
 }
 
 /**
@@ -1056,6 +1056,10 @@ static struct pipe_buf_operations relay_pipe_buf_ops = {
        .get = generic_pipe_buf_get,
 };
 
+static void relay_page_release(struct splice_pipe_desc *spd, unsigned int i)
+{
+}
+
 /*
  *     subbuf_splice_actor - splice up to one subbuf's worth of data
  */
@@ -1083,6 +1087,7 @@ static int subbuf_splice_actor(struct file *in,
                .partial = partial,
                .flags = flags,
                .ops = &relay_pipe_buf_ops,
+               .spd_release = relay_page_release,
        };
 
        if (rbuf->subbufs_produced == rbuf->subbufs_consumed)
index 28c73f0..8dcdec6 100644 (file)
@@ -1052,6 +1052,49 @@ static void resched_cpu(int cpu)
        resched_task(cpu_curr(cpu));
        spin_unlock_irqrestore(&rq->lock, flags);
 }
+
+#ifdef CONFIG_NO_HZ
+/*
+ * When add_timer_on() enqueues a timer into the timer wheel of an
+ * idle CPU then this timer might expire before the next timer event
+ * which is scheduled to wake up that CPU. In case of a completely
+ * idle system the next event might even be infinite time into the
+ * future. wake_up_idle_cpu() ensures that the CPU is woken up and
+ * leaves the inner idle loop so the newly added timer is taken into
+ * account when the CPU goes back to idle and evaluates the timer
+ * wheel for the next timer event.
+ */
+void wake_up_idle_cpu(int cpu)
+{
+       struct rq *rq = cpu_rq(cpu);
+
+       if (cpu == smp_processor_id())
+               return;
+
+       /*
+        * This is safe, as this function is called with the timer
+        * wheel base lock of (cpu) held. When the CPU is on the way
+        * to idle and has not yet set rq->curr to idle then it will
+        * be serialized on the timer wheel base lock and take the new
+        * timer into account automatically.
+        */
+       if (rq->curr != rq->idle)
+               return;
+
+       /*
+        * We can set TIF_RESCHED on the idle task of the other CPU
+        * lockless. The worst case is that the other CPU runs the
+        * idle task through an additional NOOP schedule()
+        */
+       set_tsk_thread_flag(rq->idle, TIF_NEED_RESCHED);
+
+       /* NEED_RESCHED must be visible before we test polling */
+       smp_mb();
+       if (!tsk_is_polling(rq->idle))
+               smp_send_reschedule(cpu);
+}
+#endif
+
 #else
 static void __resched_task(struct task_struct *p, int tif_bit)
 {
index 278534b..7f60097 100644 (file)
@@ -174,7 +174,7 @@ static void clocksource_check_watchdog(struct clocksource *cs)
                        if (watchdog)
                                del_timer(&watchdog_timer);
                        watchdog = cs;
-                       init_timer_deferrable(&watchdog_timer);
+                       init_timer(&watchdog_timer);
                        watchdog_timer.function = clocksource_watchdog;
 
                        /* Reset watchdog cycles */
index 99b00a2..b024106 100644 (file)
@@ -451,10 +451,18 @@ void add_timer_on(struct timer_list *timer, int cpu)
        spin_lock_irqsave(&base->lock, flags);
        timer_set_base(timer, base);
        internal_add_timer(base, timer);
+       /*
+        * Check whether the other CPU is idle and needs to be
+        * triggered to reevaluate the timer wheel when nohz is
+        * active. We are protected against the other CPU fiddling
+        * with the timer by holding the timer base lock. This also
+        * makes sure that a CPU on the way to idle can not evaluate
+        * the timer wheel.
+        */
+       wake_up_idle_cpu(cpu);
        spin_unlock_irqrestore(&base->lock, flags);
 }
 
-
 /**
  * mod_timer - modify a timer's timeout
  * @timer: the timer to be modified
index 5a402e2..5b6d7f6 100644 (file)
@@ -55,7 +55,7 @@ int kobject_action_type(const char *buf, size_t count,
        enum kobject_action action;
        int ret = -EINVAL;
 
-       if (count && buf[count-1] == '\n')
+       if (count && (buf[count-1] == '\n' || buf[count-1] == '\0'))
                count--;
 
        if (!count)
index 74c1b6b..51c9e2c 100644 (file)
@@ -401,12 +401,20 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages)
        struct page *page;
        unsigned long nr_pages;
 
+       /*
+        * We want to release as many surplus pages as possible, spread
+        * evenly across all nodes. Iterate across all nodes until we
+        * can no longer free unreserved surplus pages. This occurs when
+        * the nodes with surplus pages have no free pages.
+        */
+       unsigned long remaining_iterations = num_online_nodes();
+
        /* Uncommit the reservation */
        resv_huge_pages -= unused_resv_pages;
 
        nr_pages = min(unused_resv_pages, surplus_huge_pages);
 
-       while (nr_pages) {
+       while (remaining_iterations-- && nr_pages) {
                nid = next_node(nid, node_online_map);
                if (nid == MAX_NUMNODES)
                        nid = first_node(node_online_map);
@@ -424,6 +432,7 @@ static void return_unused_surplus_pages(unsigned long unused_resv_pages)
                        surplus_huge_pages--;
                        surplus_huge_pages_node[nid]--;
                        nr_pages--;
+                       remaining_iterations = num_online_nodes();
                }
        }
 }
@@ -671,9 +680,11 @@ int hugetlb_report_node_meminfo(int nid, char *buf)
 {
        return sprintf(buf,
                "Node %d HugePages_Total: %5u\n"
-               "Node %d HugePages_Free:  %5u\n",
+               "Node %d HugePages_Free:  %5u\n"
+               "Node %d HugePages_Surp:  %5u\n",
                nid, nr_huge_pages_node[nid],
-               nid, free_huge_pages_node[nid]);
+               nid, free_huge_pages_node[nid],
+               nid, surplus_huge_pages_node[nid]);
 }
 
 /* Return the number pages of memory we physically have, in PAGE_SIZE units. */
index bb4070e..04b308c 100644 (file)
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1481,7 +1481,7 @@ void __init kmem_cache_init(void)
        list_add(&cache_cache.next, &cache_chain);
        cache_cache.colour_off = cache_line_size();
        cache_cache.array[smp_processor_id()] = &initarray_cache.cache;
-       cache_cache.nodelists[node] = &initkmem_list3[CACHE_CACHE];
+       cache_cache.nodelists[node] = &initkmem_list3[CACHE_CACHE + node];
 
        /*
         * struct kmem_cache size depends on nr_node_ids, which
@@ -1602,7 +1602,7 @@ void __init kmem_cache_init(void)
                int nid;
 
                for_each_online_node(nid) {
-                       init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], nid);
+                       init_list(&cache_cache, &initkmem_list3[CACHE_CACHE + nid], nid);
 
                        init_list(malloc_sizes[INDEX_AC].cs_cachep,
                                  &initkmem_list3[SIZE_AC + nid], nid);
index ca71d5b..84ed734 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -1470,6 +1470,9 @@ static void *__slab_alloc(struct kmem_cache *s,
        void **object;
        struct page *new;
 
+       /* We handle __GFP_ZERO in the caller */
+       gfpflags &= ~__GFP_ZERO;
+
        if (!c->page)
                goto new_slab;
 
@@ -2685,6 +2688,7 @@ void kfree(const void *x)
 }
 EXPORT_SYMBOL(kfree);
 
+#if defined(SLUB_DEBUG) || defined(CONFIG_SLABINFO)
 static unsigned long count_partial(struct kmem_cache_node *n)
 {
        unsigned long flags;
@@ -2697,6 +2701,7 @@ static unsigned long count_partial(struct kmem_cache_node *n)
        spin_unlock_irqrestore(&n->list_lock, flags);
        return x;
 }
+#endif
 
 /*
  * kmem_cache_shrink removes empty slabs from the partial lists and sorts
index cd75b21..99c4f36 100644 (file)
@@ -76,7 +76,7 @@ pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node)
                pte_t entry;
                void *p = vmemmap_alloc_block(PAGE_SIZE, node);
                if (!p)
-                       return 0;
+                       return NULL;
                entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
                set_pte_at(&init_mm, addr, pte, entry);
        }
@@ -89,7 +89,7 @@ pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
        if (pmd_none(*pmd)) {
                void *p = vmemmap_alloc_block(PAGE_SIZE, node);
                if (!p)
-                       return 0;
+                       return NULL;
                pmd_populate_kernel(&init_mm, pmd, p);
        }
        return pmd;
@@ -101,7 +101,7 @@ pud_t * __meminit vmemmap_pud_populate(pgd_t *pgd, unsigned long addr, int node)
        if (pud_none(*pud)) {
                void *p = vmemmap_alloc_block(PAGE_SIZE, node);
                if (!p)
-                       return 0;
+                       return NULL;
                pud_populate(&init_mm, pud, p);
        }
        return pud;
@@ -113,7 +113,7 @@ pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node)
        if (pgd_none(*pgd)) {
                void *p = vmemmap_alloc_block(PAGE_SIZE, node);
                if (!p)
-                       return 0;
+                       return NULL;
                pgd_populate(&init_mm, pgd, p);
        }
        return pgd;
index 8fbcefe..480ea90 100644 (file)
@@ -660,7 +660,7 @@ static int vlan_dev_init(struct net_device *dev)
        int subclass = 0;
 
        /* IFF_BROADCAST|IFF_MULTICAST; ??? */
-       dev->flags  = real_dev->flags & ~IFF_UP;
+       dev->flags  = real_dev->flags & ~(IFF_UP | IFF_PROMISC | IFF_ALLMULTI);
        dev->iflink = real_dev->ifindex;
        dev->state  = (real_dev->state & ((1<<__LINK_STATE_NOCARRIER) |
                                          (1<<__LINK_STATE_DORMANT))) |
index 4e8d4e7..f624dff 100644 (file)
@@ -1520,7 +1520,7 @@ static int __init p9_trans_fd_init(void)
        v9fs_register_trans(&p9_unix_trans);
        v9fs_register_trans(&p9_fd_trans);
 
-       return 1;
+       return 0;
 }
 
 module_init(p9_trans_fd_init);
index 4089c49..69fb4e3 100644 (file)
@@ -9,10 +9,6 @@ being used.
 Routes to a device being taken down might be deleted by ax25_rt_device_down
 but added by somebody else before the device has been deleted fully.
 
-Massive amounts of lock_kernel / unlock_kernel are just a temporary solution to
-get around the removal of SOCKOPS_WRAP.  A serious locking strategy has to be
-implemented.
-
 The ax25_rt_find_route synopsys is pervert but I somehow had to deal with
 the race caused by the static variable in it's previous implementation.
 
index fcdf03c..460e7f9 100644 (file)
@@ -3329,7 +3329,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
                        return -EOPNOTSUPP;
 
                case SIOCADDMULTI:
-                       if (!dev->set_multicast_list ||
+                       if ((!dev->set_multicast_list && !dev->set_rx_mode) ||
                            ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
                                return -EINVAL;
                        if (!netif_device_present(dev))
@@ -3338,7 +3338,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
                                          dev->addr_len, 1);
 
                case SIOCDELMULTI:
-                       if (!dev->set_multicast_list ||
+                       if ((!dev->set_multicast_list && !dev->set_rx_mode) ||
                            ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
                                return -EINVAL;
                        if (!netif_device_present(dev))
index d9a02b2..19b8e00 100644 (file)
@@ -466,6 +466,28 @@ out_neigh_release:
        goto out;
 }
 
+struct pneigh_entry *__pneigh_lookup(struct neigh_table *tbl,
+               struct net *net, const void *pkey, struct net_device *dev)
+{
+       struct pneigh_entry *n;
+       int key_len = tbl->key_len;
+       u32 hash_val = *(u32 *)(pkey + key_len - 4);
+
+       hash_val ^= (hash_val >> 16);
+       hash_val ^= hash_val >> 8;
+       hash_val ^= hash_val >> 4;
+       hash_val &= PNEIGH_HASHMASK;
+
+       for (n = tbl->phash_buckets[hash_val]; n; n = n->next) {
+               if (!memcmp(n->key, pkey, key_len) &&
+                   (n->net == net) &&
+                   (n->dev == dev || !n->dev))
+                       break;
+       }
+
+       return n;
+}
+
 struct pneigh_entry * pneigh_lookup(struct neigh_table *tbl,
                                    struct net *net, const void *pkey,
                                    struct net_device *dev, int creat)
@@ -2803,6 +2825,7 @@ EXPORT_SYMBOL(neigh_table_init_no_netlink);
 EXPORT_SYMBOL(neigh_update);
 EXPORT_SYMBOL(pneigh_enqueue);
 EXPORT_SYMBOL(pneigh_lookup);
+EXPORT_SYMBOL_GPL(__pneigh_lookup);
 
 #ifdef CONFIG_ARPD
 EXPORT_SYMBOL(neigh_app_ns);
index a13c074..a944e80 100644 (file)
@@ -591,7 +591,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                }
 
                if (xfrm_decode_session_reverse(skb_in, &fl, AF_INET))
-                       goto out_unlock;
+                       goto ende;
 
                if (inet_addr_type(net, fl.fl4_src) == RTN_LOCAL)
                        err = __ip_route_output_key(net, &rt2, &fl);
@@ -601,7 +601,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
 
                        fl2.fl4_dst = fl.fl4_src;
                        if (ip_route_output_key(net, &rt2, &fl2))
-                               goto out_unlock;
+                               goto ende;
 
                        /* Ugh! */
                        odst = skb_in->dst;
@@ -614,7 +614,7 @@ void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info)
                }
 
                if (err)
-                       goto out_unlock;
+                       goto ende;
 
                err = xfrm_lookup((struct dst_entry **)&rt2, &fl, NULL,
                                  XFRM_LOOKUP_ICMP);
index b47030b..9c798ab 100644 (file)
@@ -39,13 +39,11 @@ static void xfrm4_beet_make_header(struct sk_buff *skb)
 static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        struct ip_beet_phdr *ph;
-       struct iphdr *iph, *top_iph;
+       struct iphdr *top_iph;
        int hdrlen, optlen;
 
-       iph = ip_hdr(skb);
-
        hdrlen = 0;
-       optlen = iph->ihl * 4 - sizeof(*iph);
+       optlen = XFRM_MODE_SKB_CB(skb)->optlen;
        if (unlikely(optlen))
                hdrlen += IPV4_BEET_PHMAXLEN - (optlen & 4);
 
@@ -53,11 +51,12 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
                                    hdrlen);
        skb->mac_header = skb->network_header +
                          offsetof(struct iphdr, protocol);
-       skb->transport_header = skb->network_header + sizeof(*iph);
+       skb->transport_header = skb->network_header + sizeof(*top_iph);
 
        xfrm4_beet_make_header(skb);
 
-       ph = (struct ip_beet_phdr *)__skb_pull(skb, sizeof(*iph) - hdrlen);
+       ph = (struct ip_beet_phdr *)
+               __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl - hdrlen);
 
        top_iph = ip_hdr(skb);
 
index 8dee617..584e6d7 100644 (file)
@@ -41,7 +41,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
        top_iph->ihl = 5;
        top_iph->version = 4;
 
-       top_iph->protocol = x->inner_mode->afinfo->proto;
+       top_iph->protocol = xfrm_af2proto(skb->dst->ops->family);
 
        /* DS disclosed */
        top_iph->tos = INET_ECN_encapsulate(XFRM_MODE_SKB_CB(skb)->tos,
index d5a58a8..8c3180a 100644 (file)
@@ -56,7 +56,7 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        int err;
 
-       err = x->inner_mode->afinfo->extract_output(x, skb);
+       err = xfrm_inner_extract_output(x, skb);
        if (err)
                return err;
 
index fdeebe6..07735ed 100644 (file)
@@ -52,10 +52,12 @@ int xfrm4_extract_header(struct sk_buff *skb)
 {
        struct iphdr *iph = ip_hdr(skb);
 
+       XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph);
        XFRM_MODE_SKB_CB(skb)->id = iph->id;
        XFRM_MODE_SKB_CB(skb)->frag_off = iph->frag_off;
        XFRM_MODE_SKB_CB(skb)->tos = iph->tos;
        XFRM_MODE_SKB_CB(skb)->ttl = iph->ttl;
+       XFRM_MODE_SKB_CB(skb)->optlen = iph->ihl * 4 - sizeof(*iph);
        memset(XFRM_MODE_SKB_CB(skb)->flow_lbl, 0,
               sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
 
index 51557c2..452a2ac 100644 (file)
@@ -676,6 +676,20 @@ static void ndisc_solicit(struct neighbour *neigh, struct sk_buff *skb)
        }
 }
 
+static struct pneigh_entry *pndisc_check_router(struct net_device *dev,
+               struct in6_addr *addr, int *is_router)
+{
+       struct pneigh_entry *n;
+
+       read_lock_bh(&nd_tbl.lock);
+       n = __pneigh_lookup(&nd_tbl, &init_net, addr, dev);
+       if (n != NULL)
+               *is_router = (n->flags & NTF_ROUTER);
+       read_unlock_bh(&nd_tbl.lock);
+
+       return n;
+}
+
 static void ndisc_recv_ns(struct sk_buff *skb)
 {
        struct nd_msg *msg = (struct nd_msg *)skb_transport_header(skb);
@@ -692,7 +706,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
        struct pneigh_entry *pneigh = NULL;
        int dad = ipv6_addr_any(saddr);
        int inc;
-       int is_router;
+       int is_router = 0;
 
        if (ipv6_addr_is_multicast(&msg->target)) {
                ND_PRINTK2(KERN_WARNING
@@ -790,8 +804,8 @@ static void ndisc_recv_ns(struct sk_buff *skb)
                if (ipv6_chk_acast_addr(dev, &msg->target) ||
                    (idev->cnf.forwarding &&
                     (ipv6_devconf.proxy_ndp || idev->cnf.proxy_ndp) &&
-                    (pneigh = pneigh_lookup(&nd_tbl, &init_net,
-                                            &msg->target, dev, 0)) != NULL)) {
+                    (pneigh = pndisc_check_router(dev, &msg->target,
+                                                 &is_router)) != NULL)) {
                        if (!(NEIGH_CB(skb)->flags & LOCALLY_ENQUEUED) &&
                            skb->pkt_type != PACKET_HOST &&
                            inc != 0 &&
@@ -812,7 +826,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
                        goto out;
        }
 
-       is_router = !!(pneigh ? pneigh->flags & NTF_ROUTER : idev->cnf.forwarding);
+       is_router = !!(pneigh ? is_router : idev->cnf.forwarding);
 
        if (dad) {
                struct in6_addr maddr;
index 0527d11..d6ce400 100644 (file)
@@ -45,6 +45,7 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
        skb->mac_header = skb->network_header +
                          offsetof(struct ipv6hdr, nexthdr);
        skb->transport_header = skb->network_header + sizeof(*top_iph);
+       __skb_pull(skb, XFRM_MODE_SKB_CB(skb)->ihl);
 
        xfrm6_beet_make_header(skb);
 
index 0c742fa..e20529b 100644 (file)
@@ -45,7 +45,7 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
 
        memcpy(top_iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
               sizeof(top_iph->flow_lbl));
-       top_iph->nexthdr = x->inner_mode->afinfo->proto;
+       top_iph->nexthdr = xfrm_af2proto(skb->dst->ops->family);
 
        dsfield = XFRM_MODE_SKB_CB(skb)->tos;
        dsfield = INET_ECN_encapsulate(dsfield, dsfield);
index 79ccfb0..0af823c 100644 (file)
@@ -62,7 +62,7 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
 {
        int err;
 
-       err = x->inner_mode->afinfo->extract_output(x, skb);
+       err = xfrm_inner_extract_output(x, skb);
        if (err)
                return err;
 
index dc817e0..ff1e1db 100644 (file)
@@ -174,10 +174,12 @@ int xfrm6_extract_header(struct sk_buff *skb)
 {
        struct ipv6hdr *iph = ipv6_hdr(skb);
 
+       XFRM_MODE_SKB_CB(skb)->ihl = sizeof(*iph);
        XFRM_MODE_SKB_CB(skb)->id = 0;
        XFRM_MODE_SKB_CB(skb)->frag_off = htons(IP_DF);
        XFRM_MODE_SKB_CB(skb)->tos = ipv6_get_dsfield(iph);
        XFRM_MODE_SKB_CB(skb)->ttl = iph->hop_limit;
+       XFRM_MODE_SKB_CB(skb)->optlen = 0;
        memcpy(XFRM_MODE_SKB_CB(skb)->flow_lbl, iph->flow_lbl,
               sizeof(XFRM_MODE_SKB_CB(skb)->flow_lbl));
 
index bc2e15c..7873c39 100644 (file)
@@ -405,7 +405,7 @@ typedef struct irnet_socket
   /* "pppd" interact directly with us on a /dev/ file */
   struct file *                file;           /* File descriptor of this instance */
   /* TTY stuff - to keep "pppd" happy */
-  struct termios       termios;        /* Various tty flags */
+  struct ktermios      termios;        /* Various tty flags */
   /* Stuff for the control channel */
   int                  event_index;    /* Last read in the event log */
 
index 8b5f486..e9ef9af 100644 (file)
@@ -1219,7 +1219,7 @@ static struct xfrm_state * pfkey_msg2xfrm_state(struct sadb_msg *hdr,
                x->sel.prefixlen_s = addr->sadb_address_prefixlen;
        }
 
-       if (!x->sel.family)
+       if (x->props.mode == XFRM_MODE_TRANSPORT)
                x->sel.family = x->props.family;
 
        if (ext_hdrs[SADB_X_EXT_NAT_T_TYPE-1]) {
index 1aaa2e8..126ca77 100644 (file)
@@ -23,7 +23,7 @@
 struct rxrpc_crypt {
        union {
                u8      x[FCRYPT_BSIZE];
-               u32     n[2];
+               __be32  n[2];
        };
 } __attribute__((aligned(8)));
 
index f48434a..d1c296f 100644 (file)
@@ -261,6 +261,7 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
                __be32 x[2];
        } tmpbuf __attribute__((aligned(8))); /* must all be in same page */
        __be32 x;
+       u32 y;
        int ret;
 
        sp = rxrpc_skb(skb);
@@ -292,11 +293,11 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
        sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf));
        crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
-       x = ntohl(tmpbuf.x[1]);
-       x = (x >> 16) & 0xffff;
-       if (x == 0)
-               x = 1; /* zero checksums are not permitted */
-       sp->hdr.cksum = htons(x);
+       y = ntohl(tmpbuf.x[1]);
+       y = (y >> 16) & 0xffff;
+       if (y == 0)
+               y = 1; /* zero checksums are not permitted */
+       sp->hdr.cksum = htons(y);
 
        switch (call->conn->security_level) {
        case RXRPC_SECURITY_PLAIN:
@@ -314,7 +315,7 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
                break;
        }
 
-       _leave(" = %d [set %hx]", ret, x);
+       _leave(" = %d [set %hx]", ret, y);
        return ret;
 }
 
@@ -492,6 +493,7 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
                __be32 x[2];
        } tmpbuf __attribute__((aligned(8))); /* must all be in same page */
        __be32 x;
+       u16 y;
        __be16 cksum;
        int ret;
 
@@ -526,12 +528,12 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
        sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf));
        crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
-       x = ntohl(tmpbuf.x[1]);
-       x = (x >> 16) & 0xffff;
-       if (x == 0)
-               x = 1; /* zero checksums are not permitted */
+       y = ntohl(tmpbuf.x[1]);
+       y = (y >> 16) & 0xffff;
+       if (y == 0)
+               y = 1; /* zero checksums are not permitted */
 
-       cksum = htons(x);
+       cksum = htons(y);
        if (sp->hdr.cksum != cksum) {
                *_abort_code = RXKADSEALEDINCON;
                _leave(" = -EPROTO [csum failed]");
@@ -1001,7 +1003,8 @@ static int rxkad_verify_response(struct rxrpc_connection *conn,
        struct rxrpc_crypt session_key;
        time_t expiry;
        void *ticket;
-       u32 abort_code, version, kvno, ticket_len, csum, level;
+       u32 abort_code, version, kvno, ticket_len, level;
+       __be32 csum;
        int ret;
 
        _enter("{%d,%x}", conn->debug_id, key_serial(conn->server_key));
index 9712716..c22d6b6 100644 (file)
@@ -322,15 +322,6 @@ next_sge:
                ctxt->direction = DMA_FROM_DEVICE;
                clear_bit(RDMACTXT_F_READ_DONE, &ctxt->flags);
                clear_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
-               if ((ch+1)->rc_discrim == 0) {
-                       /*
-                        * Checked in sq_cq_reap to see if we need to
-                        * be enqueued
-                        */
-                       set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
-                       ctxt->next = hdr_ctxt;
-                       hdr_ctxt->next = head;
-               }
 
                /* Prepare READ WR */
                memset(&read_wr, 0, sizeof read_wr);
@@ -348,7 +339,17 @@ next_sge:
                rdma_set_ctxt_sge(ctxt, &sge[ch_sge_ary[ch_no].start],
                                  &sgl_offset,
                                  read_wr.num_sge);
-
+               if (((ch+1)->rc_discrim == 0) &&
+                   (read_wr.num_sge == ch_sge_ary[ch_no].count)) {
+                       /*
+                        * Mark the last RDMA_READ with a bit to
+                        * indicate all RPC data has been fetched from
+                        * the client and the RPC needs to be enqueued.
+                        */
+                       set_bit(RDMACTXT_F_LAST_CTXT, &ctxt->flags);
+                       ctxt->next = hdr_ctxt;
+                       hdr_ctxt->next = head;
+               }
                /* Post the read */
                err = svc_rdma_send(xprt, &read_wr);
                if (err) {
index 62188c6..7527940 100644 (file)
@@ -84,14 +84,21 @@ int xfrm_parse_spi(struct sk_buff *skb, u8 nexthdr, __be32 *spi, __be32 *seq)
 
 int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb)
 {
+       struct xfrm_mode *inner_mode = x->inner_mode;
        int err;
 
        err = x->outer_mode->afinfo->extract_input(x, skb);
        if (err)
                return err;
 
-       skb->protocol = x->inner_mode->afinfo->eth_proto;
-       return x->inner_mode->input2(x, skb);
+       if (x->sel.family == AF_UNSPEC) {
+               inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
+               if (inner_mode == NULL)
+                       return -EAFNOSUPPORT;
+       }
+
+       skb->protocol = inner_mode->afinfo->eth_proto;
+       return inner_mode->input2(x, skb);
 }
 EXPORT_SYMBOL(xfrm_prepare_input);
 
@@ -101,6 +108,7 @@ int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, int encap_type)
        __be32 seq;
        struct xfrm_state *x;
        xfrm_address_t *daddr;
+       struct xfrm_mode *inner_mode;
        unsigned int family;
        int decaps = 0;
        int async = 0;
@@ -207,7 +215,15 @@ resume:
 
                XFRM_MODE_SKB_CB(skb)->protocol = nexthdr;
 
-               if (x->inner_mode->input(x, skb)) {
+               inner_mode = x->inner_mode;
+
+               if (x->sel.family == AF_UNSPEC) {
+                       inner_mode = xfrm_ip2inner_mode(x, XFRM_MODE_SKB_CB(skb)->protocol);
+                       if (inner_mode == NULL)
+                               goto drop;
+               }
+
+               if (inner_mode->input(x, skb)) {
                        XFRM_INC_STATS(LINUX_MIB_XFRMINSTATEMODEERROR);
                        goto drop;
                }
index 569d377..2519129 100644 (file)
@@ -124,7 +124,7 @@ int xfrm_output_resume(struct sk_buff *skb, int err)
                if (!x)
                        return dst_output(skb);
 
-               err = nf_hook(x->inner_mode->afinfo->family,
+               err = nf_hook(skb->dst->ops->family,
                              NF_INET_POST_ROUTING, skb,
                              NULL, skb->dst->dev, xfrm_output2);
                if (unlikely(err != 1))
@@ -193,4 +193,20 @@ int xfrm_output(struct sk_buff *skb)
 
        return xfrm_output2(skb);
 }
+
+int xfrm_inner_extract_output(struct xfrm_state *x, struct sk_buff *skb)
+{
+       struct xfrm_mode *inner_mode;
+       if (x->sel.family == AF_UNSPEC)
+               inner_mode = xfrm_ip2inner_mode(x,
+                               xfrm_af2proto(skb->dst->ops->family));
+       else
+               inner_mode = x->inner_mode;
+
+       if (inner_mode == NULL)
+               return -EAFNOSUPPORT;
+       return inner_mode->afinfo->extract_output(x, skb);
+}
+
 EXPORT_SYMBOL_GPL(xfrm_output);
+EXPORT_SYMBOL_GPL(xfrm_inner_extract_output);
index 7ba65e8..58f1f93 100644 (file)
@@ -388,6 +388,8 @@ static void xfrm_state_gc_destroy(struct xfrm_state *x)
        kfree(x->coaddr);
        if (x->inner_mode)
                xfrm_put_mode(x->inner_mode);
+       if (x->inner_mode_iaf)
+               xfrm_put_mode(x->inner_mode_iaf);
        if (x->outer_mode)
                xfrm_put_mode(x->outer_mode);
        if (x->type) {
@@ -523,6 +525,8 @@ struct xfrm_state *xfrm_state_alloc(void)
                x->lft.hard_packet_limit = XFRM_INF;
                x->replay_maxage = 0;
                x->replay_maxdiff = 0;
+               x->inner_mode = NULL;
+               x->inner_mode_iaf = NULL;
                spin_lock_init(&x->lock);
        }
        return x;
@@ -796,7 +800,7 @@ xfrm_state_find(xfrm_address_t *daddr, xfrm_address_t *saddr,
                              selector.
                         */
                        if (x->km.state == XFRM_STATE_VALID) {
-                               if (!xfrm_selector_match(&x->sel, fl, x->sel.family) ||
+                               if ((x->sel.family && !xfrm_selector_match(&x->sel, fl, x->sel.family)) ||
                                    !security_xfrm_state_pol_flow_match(x, pol, fl))
                                        continue;
                                if (!best ||
@@ -1944,6 +1948,7 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu)
 int xfrm_init_state(struct xfrm_state *x)
 {
        struct xfrm_state_afinfo *afinfo;
+       struct xfrm_mode *inner_mode;
        int family = x->props.family;
        int err;
 
@@ -1962,13 +1967,48 @@ int xfrm_init_state(struct xfrm_state *x)
                goto error;
 
        err = -EPROTONOSUPPORT;
-       x->inner_mode = xfrm_get_mode(x->props.mode, x->sel.family);
-       if (x->inner_mode == NULL)
-               goto error;
 
-       if (!(x->inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
-           family != x->sel.family)
-               goto error;
+       if (x->sel.family != AF_UNSPEC) {
+               inner_mode = xfrm_get_mode(x->props.mode, x->sel.family);
+               if (inner_mode == NULL)
+                       goto error;
+
+               if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL) &&
+                   family != x->sel.family) {
+                       xfrm_put_mode(inner_mode);
+                       goto error;
+               }
+
+               x->inner_mode = inner_mode;
+       } else {
+               struct xfrm_mode *inner_mode_iaf;
+
+               inner_mode = xfrm_get_mode(x->props.mode, AF_INET);
+               if (inner_mode == NULL)
+                       goto error;
+
+               if (!(inner_mode->flags & XFRM_MODE_FLAG_TUNNEL)) {
+                       xfrm_put_mode(inner_mode);
+                       goto error;
+               }
+
+               inner_mode_iaf = xfrm_get_mode(x->props.mode, AF_INET6);
+               if (inner_mode_iaf == NULL)
+                       goto error;
+
+               if (!(inner_mode_iaf->flags & XFRM_MODE_FLAG_TUNNEL)) {
+                       xfrm_put_mode(inner_mode_iaf);
+                       goto error;
+               }
+
+               if (x->props.family == AF_INET) {
+                       x->inner_mode = inner_mode;
+                       x->inner_mode_iaf = inner_mode_iaf;
+               } else {
+                       x->inner_mode = inner_mode_iaf;
+                       x->inner_mode_iaf = inner_mode;
+               }
+       }
 
        x->type = xfrm_get_type(x->id.proto, family);
        if (x->type == NULL)
index f971ca5..5d96f27 100644 (file)
@@ -288,12 +288,9 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
        memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr));
        x->props.flags = p->flags;
 
-       /*
-        * Set inner address family if the KM left it as zero.
-        * See comment in validate_tmpl.
-        */
-       if (!x->sel.family)
+       if (x->props.mode == XFRM_MODE_TRANSPORT)
                x->sel.family = p->family;
+
 }
 
 /*
index 2a7cef9..58a9494 100755 (executable)
@@ -9,7 +9,7 @@ use strict;
 my $P = $0;
 $P =~ s@.*/@@g;
 
-my $V = '0.15';
+my $V = '0.16';
 
 use Getopt::Long qw(:config no_auto_abbrev);
 
@@ -18,6 +18,7 @@ my $tree = 1;
 my $chk_signoff = 1;
 my $chk_patch = 1;
 my $tst_type = 0;
+my $tst_only;
 my $emacs = 0;
 my $terse = 0;
 my $file = 0;
@@ -44,6 +45,7 @@ GetOptions(
 
        'debug=s'       => \%debug,
        'test-type!'    => \$tst_type,
+       'test-only=s'   => \$tst_only,
 ) or exit;
 
 my $exit = 0;
@@ -263,17 +265,7 @@ sub expand_tabs {
        return $res;
 }
 sub copy_spacing {
-       my ($str) = @_;
-
-       my $res = '';
-       for my $c (split(//, $str)) {
-               if ($c eq "\t") {
-                       $res .= $c;
-               } else {
-                       $res .= ' ';
-               }
-       }
-
+       (my $res = shift) =~ tr/\t/ /c;
        return $res;
 }
 
@@ -290,53 +282,76 @@ sub line_stats {
        return (length($line), length($white));
 }
 
+my $sanitise_quote = '';
+
+sub sanitise_line_reset {
+       my ($in_comment) = @_;
+
+       if ($in_comment) {
+               $sanitise_quote = '*/';
+       } else {
+               $sanitise_quote = '';
+       }
+}
 sub sanitise_line {
        my ($line) = @_;
 
        my $res = '';
        my $l = '';
 
-       my $quote = '';
        my $qlen = 0;
+       my $off = 0;
+       my $c;
 
-       foreach my $c (split(//, $line)) {
-               # The second backslash of a pair is not a "quote".
-               if ($l eq "\\" && $c eq "\\") {
-                       $c = 'X';
-               }
-               if ($l ne "\\" && ($c eq "'" || $c eq '"')) {
-                       if ($quote eq '') {
-                               $quote = $c;
-                               $res .= $c;
-                               $l = $c;
-                               $qlen = 0;
-                               next;
-                       } elsif ($quote eq $c) {
-                               $quote = '';
-                       }
+       # Always copy over the diff marker.
+       $res = substr($line, 0, 1);
+
+       for ($off = 1; $off < length($line); $off++) {
+               $c = substr($line, $off, 1);
+
+               # Comments we are wacking completly including the begin
+               # and end, all to $;.
+               if ($sanitise_quote eq '' && substr($line, $off, 2) eq '/*') {
+                       $sanitise_quote = '*/';
+
+                       substr($res, $off, 2, "$;$;");
+                       $off++;
+                       next;
                }
-               if ($quote eq "'" && $qlen > 1) {
-                       $quote = '';
+               if (substr($line, $off, 2) eq $sanitise_quote) {
+                       $sanitise_quote = '';
+                       substr($res, $off, 2, "$;$;");
+                       $off++;
+                       next;
                }
-               if ($quote && $c ne "\t") {
-                       $res .= "X";
-                       $qlen++;
-               } else {
-                       $res .= $c;
+
+               # A \ in a string means ignore the next character.
+               if (($sanitise_quote eq "'" || $sanitise_quote eq '"') &&
+                   $c eq "\\") {
+                       substr($res, $off, 2, 'XX');
+                       $off++;
+                       next;
                }
+               # Regular quotes.
+               if ($c eq "'" || $c eq '"') {
+                       if ($sanitise_quote eq '') {
+                               $sanitise_quote = $c;
 
-               $l = $c;
-       }
+                               substr($res, $off, 1, $c);
+                               next;
+                       } elsif ($sanitise_quote eq $c) {
+                               $sanitise_quote = '';
+                       }
+               }
 
-       # Clear out the comments.
-       while ($res =~ m@(/\*.*?\*/)@g) {
-               substr($res, $-[1], $+[1] - $-[1]) = $; x ($+[1] - $-[1]);
-       }
-       if ($res =~ m@(/\*.*)@) {
-               substr($res, $-[1], $+[1] - $-[1]) = $; x ($+[1] - $-[1]);
-       }
-       if ($res =~ m@^.(.*\*/)@) {
-               substr($res, $-[1], $+[1] - $-[1]) = $; x ($+[1] - $-[1]);
+               #print "SQ:$sanitise_quote\n";
+               if ($off != 0 && $sanitise_quote eq '*/' && $c ne "\t") {
+                       substr($res, $off, 1, $;);
+               } elsif ($off != 0 && $sanitise_quote && $c ne "\t") {
+                       substr($res, $off, 1, 'X');
+               } else {
+                       substr($res, $off, 1, $c);
+               }
        }
 
        # The pathname on a #include may be surrounded by '<' and '>'.
@@ -359,6 +374,7 @@ sub ctx_statement_block {
        my $blk = '';
        my $soff = $off;
        my $coff = $off - 1;
+       my $coff_set = 0;
 
        my $loff = 0;
 
@@ -370,7 +386,7 @@ sub ctx_statement_block {
 
        my $remainder;
        while (1) {
-               #warn "CSB: blk<$blk>\n";
+               #warn "CSB: blk<$blk> remain<$remain>\n";
                # If we are about to drop off the end, pull in more
                # context.
                if ($off >= $len) {
@@ -393,7 +409,7 @@ sub ctx_statement_block {
                $c = substr($blk, $off, 1);
                $remainder = substr($blk, $off);
 
-               #warn "CSB: c<$c> type<$type> level<$level>\n";
+               #warn "CSB: c<$c> type<$type> level<$level> remainder<$remainder> coff_set<$coff_set>\n";
                # Statement ends at the ';' or a close '}' at the
                # outermost level.
                if ($level == 0 && $c eq ';') {
@@ -401,10 +417,14 @@ sub ctx_statement_block {
                }
 
                # An else is really a conditional as long as its not else if
-               if ($level == 0 && (!defined($p) || $p =~ /(?:\s|\})/) &&
-                               $remainder =~ /(else)(?:\s|{)/ &&
-                               $remainder !~ /else\s+if\b/) {
-                       $coff = $off + length($1);
+               if ($level == 0 && $coff_set == 0 &&
+                               (!defined($p) || $p =~ /(?:\s|\}|\+)/) &&
+                               $remainder =~ /^(else)(?:\s|{)/ &&
+                               $remainder !~ /^else\s+if\b/) {
+                       $coff = $off + length($1) - 1;
+                       $coff_set = 1;
+                       #warn "CSB: mark coff<$coff> soff<$soff> 1<$1>\n";
+                       #warn "[" . substr($blk, $soff, $coff - $soff + 1) . "]\n";
                }
 
                if (($type eq '' || $type eq '(') && $c eq '(') {
@@ -417,6 +437,8 @@ sub ctx_statement_block {
 
                        if ($level == 0 && $coff < $soff) {
                                $coff = $off;
+                               $coff_set = 1;
+                               #warn "CSB: mark coff<$coff>\n";
                        }
                }
                if (($type eq '' || $type eq '{') && $c eq '{') {
@@ -444,7 +466,7 @@ sub ctx_statement_block {
        #warn "STATEMENT<$statement>\n";
        #warn "CONDITION<$condition>\n";
 
-       #print "off<$off> loff<$loff>\n";
+       #print "coff<$coff> soff<$off> loff<$loff>\n";
 
        return ($statement, $condition,
                        $line, $remain + 1, $off - $loff + 1, $level);
@@ -502,7 +524,7 @@ sub ctx_statement_full {
        # Grab the first conditional/block pair.
        ($statement, $condition, $linenr, $remain, $off, $level) =
                                ctx_statement_block($linenr, $remain, $off);
-       #print "F: c<$condition> s<$statement>\n";
+       #print "F: c<$condition> s<$statement> remain<$remain>\n";
        push(@chunks, [ $condition, $statement ]);
        if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:if|else|do)\b/s)) {
                return ($level, $linenr, @chunks);
@@ -514,7 +536,7 @@ sub ctx_statement_full {
                ($statement, $condition, $linenr, $remain, $off, $level) =
                                ctx_statement_block($linenr, $remain, $off);
                #print "C: c<$condition> s<$statement> remain<$remain>\n";
-               last if (!($remain > 0 && $condition =~ /^\s*(?:\n[+-])?\s*(?:else|do)\b/s));
+               last if (!($remain > 0 && $condition =~ /^(?:\s*\n[+-])*\s*(?:else|do)\b/s));
                #print "C: push\n";
                push(@chunks, [ $condition, $statement ]);
        }
@@ -668,6 +690,7 @@ sub annotate_values {
        print "$stream\n" if ($dbg_values > 1);
 
        while (length($cur)) {
+               @av_paren_type = ('E') if ($#av_paren_type < 0);
                print " <" . join('', @av_paren_type) .
                                        "> <$type> " if ($dbg_values > 1);
                if ($cur =~ /^(\s+)/o) {
@@ -804,28 +827,34 @@ sub possible {
 my $prefix = '';
 
 sub report {
+       if (defined $tst_only && $_[0] !~ /\Q$tst_only\E/) {
+               return 0;
+       }
        my $line = $prefix . $_[0];
 
        $line = (split('\n', $line))[0] . "\n" if ($terse);
 
        push(our @report, $line);
+
+       return 1;
 }
 sub report_dump {
        our @report;
 }
 sub ERROR {
-       report("ERROR: $_[0]\n");
-       our $clean = 0;
-       our $cnt_error++;
+       if (report("ERROR: $_[0]\n")) {
+               our $clean = 0;
+               our $cnt_error++;
+       }
 }
 sub WARN {
-       report("WARNING: $_[0]\n");
-       our $clean = 0;
-       our $cnt_warn++;
+       if (report("WARNING: $_[0]\n")) {
+               our $clean = 0;
+               our $cnt_warn++;
+       }
 }
 sub CHK {
-       if ($check) {
-               report("CHECK: $_[0]\n");
+       if ($check && report("CHECK: $_[0]\n")) {
                our $clean = 0;
                our $cnt_chk++;
        }
@@ -867,30 +896,76 @@ sub process {
        my $prev_values = 'E';
 
        # suppression flags
-       my $suppress_ifbraces = 0;
+       my %suppress_ifbraces;
 
        # Pre-scan the patch sanitizing the lines.
        # Pre-scan the patch looking for any __setup documentation.
        #
        my @setup_docs = ();
        my $setup_docs = 0;
+
+       sanitise_line_reset();
        my $line;
        foreach my $rawline (@rawlines) {
-               # Standardise the strings and chars within the input to
-               # simplify matching.
-               $line = sanitise_line($rawline);
-               push(@lines, $line);
-
-               ##print "==>$rawline\n";
-               ##print "-->$line\n";
+               $linenr++;
+               $line = $rawline;
 
-               if ($line=~/^\+\+\+\s+(\S+)/) {
+               if ($rawline=~/^\+\+\+\s+(\S+)/) {
                        $setup_docs = 0;
                        if ($1 =~ m@Documentation/kernel-parameters.txt$@) {
                                $setup_docs = 1;
                        }
-                       next;
+                       #next;
+               }
+               if ($rawline=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
+                       $realline=$1-1;
+                       if (defined $2) {
+                               $realcnt=$3+1;
+                       } else {
+                               $realcnt=1+1;
+                       }
+
+                       # Guestimate if this is a continuing comment.  Run
+                       # the context looking for a comment "edge".  If this
+                       # edge is a close comment then we must be in a comment
+                       # at context start.
+                       my $edge;
+                       for (my $ln = $linenr; $ln < ($linenr + $realcnt); $ln++) {
+                               next if ($line =~ /^-/);
+                               ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@);
+                               last if (defined $edge);
+                       }
+                       if (defined $edge && $edge eq '*/') {
+                               $in_comment = 1;
+                       }
+
+                       # Guestimate if this is a continuing comment.  If this
+                       # is the start of a diff block and this line starts
+                       # ' *' then it is very likely a comment.
+                       if (!defined $edge &&
+                           $rawlines[$linenr] =~ m@^.\s* \*(?:\s|$)@)
+                       {
+                               $in_comment = 1;
+                       }
+
+                       ##print "COMMENT:$in_comment edge<$edge> $rawline\n";
+                       sanitise_line_reset($in_comment);
+
+               } elsif ($realcnt) {
+                       # Standardise the strings and chars within the input to
+                       # simplify matching.
+                       $line = sanitise_line($rawline);
                }
+               push(@lines, $line);
+
+               if ($realcnt > 1) {
+                       $realcnt-- if ($line =~ /^(?:\+| |$)/);
+               } else {
+                       $realcnt = 0;
+               }
+
+               #print "==>$rawline\n";
+               #print "-->$line\n";
 
                if ($setup_docs && $line =~ /^\+/) {
                        push(@setup_docs, $line);
@@ -899,23 +974,17 @@ sub process {
 
        $prefix = '';
 
+       $realcnt = 0;
+       $linenr = 0;
        foreach my $line (@lines) {
                $linenr++;
 
                my $rawline = $rawlines[$linenr - 1];
 
-#extract the filename as it passes
-               if ($line=~/^\+\+\+\s+(\S+)/) {
-                       $realfile=$1;
-                       $realfile =~ s@^[^/]*/@@;
-                       $in_comment = 0;
-                       next;
-               }
 #extract the line range in the file after the patch is applied
                if ($line=~/^\@\@ -\d+(?:,\d+)? \+(\d+)(,(\d+))? \@\@/) {
                        $is_patch = 1;
                        $first_line = $linenr + 1;
-                       $in_comment = 0;
                        $realline=$1-1;
                        if (defined $2) {
                                $realcnt=$3+1;
@@ -925,50 +994,16 @@ sub process {
                        annotate_reset();
                        $prev_values = 'E';
 
-                       $suppress_ifbraces = $linenr - 1;
+                       %suppress_ifbraces = ();
                        next;
-               }
 
 # track the line number as we move through the hunk, note that
 # new versions of GNU diff omit the leading space on completely
 # blank context lines so we need to count that too.
-               if ($line =~ /^( |\+|$)/) {
+               } elsif ($line =~ /^( |\+|$)/) {
                        $realline++;
                        $realcnt-- if ($realcnt != 0);
 
-                       # Guestimate if this is a continuing comment.  Run
-                       # the context looking for a comment "edge".  If this
-                       # edge is a close comment then we must be in a comment
-                       # at context start.
-                       if ($linenr == $first_line) {
-                               my $edge;
-                               for (my $ln = $first_line; $ln < ($linenr + $realcnt); $ln++) {
-                                       ($edge) = ($rawlines[$ln - 1] =~ m@(/\*|\*/)@);
-                                       last if (defined $edge);
-                               }
-                               if (defined $edge && $edge eq '*/') {
-                                       $in_comment = 1;
-                               }
-                       }
-
-                       # Guestimate if this is a continuing comment.  If this
-                       # is the start of a diff block and this line starts
-                       # ' *' then it is very likely a comment.
-                       if ($linenr == $first_line and $rawline =~ m@^.\s* \*(?:\s|$)@) {
-                               $in_comment = 1;
-                       }
-
-                       # Find the last comment edge on _this_ line.
-                       $comment_edge = 0;
-                       while (($rawline =~ m@(/\*|\*/)@g)) {
-                               if ($1 eq '/*') {
-                                       $in_comment = 1;
-                               } else {
-                                       $in_comment = 0;
-                               }
-                               $comment_edge = 1;
-                       }
-
                        # Measure the line length and indent.
                        ($length, $indent) = line_stats($rawline);
 
@@ -977,23 +1012,36 @@ sub process {
                        ($previndent, $stashindent) = ($stashindent, $indent);
                        ($prevrawline, $stashrawline) = ($stashrawline, $rawline);
 
-                       #warn "ic<$in_comment> ce<$comment_edge> line<$line>\n";
+                       #warn "line<$line>\n";
 
                } elsif ($realcnt == 1) {
                        $realcnt--;
                }
 
 #make up the handle for any error we report on this line
+               $prefix = "$filename:$realline: " if ($emacs && $file);
+               $prefix = "$filename:$linenr: " if ($emacs && !$file);
+
                $here = "#$linenr: " if (!$file);
                $here = "#$realline: " if ($file);
+
+               # extract the filename as it passes
+               if ($line=~/^\+\+\+\s+(\S+)/) {
+                       $realfile = $1;
+                       $realfile =~ s@^[^/]*/@@;
+
+                       if ($realfile =~ m@include/asm/@) {
+                               ERROR("do not modify files in include/asm, change architecture specific files in include/asm-<architecture>\n" . "$here$rawline\n");
+                       }
+                       next;
+               }
+
                $here .= "FILE: $realfile:$realline:" if ($realcnt != 0);
 
                my $hereline = "$here\n$rawline\n";
                my $herecurr = "$here\n$rawline\n";
                my $hereprev = "$here\n$prevrawline\n$rawline\n";
 
-               $prefix = "$filename:$realline: " if ($emacs && $file);
-               $prefix = "$filename:$linenr: " if ($emacs && !$file);
                $cnt_lines++ if ($realcnt != 0);
 
 #check the patch for a signoff:
@@ -1005,7 +1053,7 @@ sub process {
                                        $herecurr);
                        }
                        if ($line =~ /^\s*signed-off-by:\S/i) {
-                               WARN("need space after Signed-off-by:\n" .
+                               WARN("space required after Signed-off-by:\n" .
                                        $herecurr);
                        }
                }
@@ -1072,11 +1120,6 @@ sub process {
                        WARN("CVS style keyword markers, these will _not_ be updated\n". $herecurr);
                }
 
-# The rest of our checks refer specifically to C style
-# only apply those _outside_ comments.  Only skip
-# lines in the middle of comments.
-               next if (!$comment_edge && $in_comment);
-
 # Check for potential 'bare' types
                if ($realcnt) {
                        my ($s, $c) = ctx_statement_block($linenr, $realcnt, 0);
@@ -1110,7 +1153,7 @@ sub process {
                                my ($name_len) = length($1);
 
                                my $ctx = $s;
-                               substr($ctx, 0, $name_len + 1) = '';
+                               substr($ctx, 0, $name_len + 1, '');
                                $ctx =~ s/\)[^\)]*$//;
 
                                for my $arg (split(/\s*,\s*/, $ctx)) {
@@ -1151,27 +1194,33 @@ sub process {
 
 # if/while/etc brace do not go on next line, unless defining a do while loop,
 # or if that brace on the next line is for something else
-               if ($line =~ /\b(?:(if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) {
+               if ($line =~ /(.*)\b((?:if|while|for|switch)\s*\(|do\b|else\b)/ && $line !~ /^.#/) {
+                       my $pre_ctx = "$1$2";
+
                        my ($level, @ctx) = ctx_statement_level($linenr, $realcnt, 0);
                        my $ctx_ln = $linenr + $#ctx + 1;
                        my $ctx_cnt = $realcnt - $#ctx - 1;
                        my $ctx = join("\n", @ctx);
 
+                       ##warn "realcnt<$realcnt> ctx_cnt<$ctx_cnt>\n";
+
                        # Skip over any removed lines in the context following statement.
-                       while ($ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^-/) {
+                       while (defined($lines[$ctx_ln - 1]) && $lines[$ctx_ln - 1] =~ /^-/) {
                                $ctx_ln++;
-                               $ctx_cnt--;
                        }
-                       ##warn "line<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>";
+                       ##warn "pre<$pre_ctx>\nline<$line>\nctx<$ctx>\nnext<$lines[$ctx_ln - 1]>\n";
 
-                       if ($ctx !~ /{\s*/ && $ctx_cnt > 0 && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
-                               ERROR("That open brace { should be on the previous line\n" .
+                       if ($ctx !~ /{\s*/ && defined($lines[$ctx_ln -1]) && $lines[$ctx_ln - 1] =~ /^\+\s*{/) {
+                               ERROR("that open brace { should be on the previous line\n" .
                                        "$here\n$ctx\n$lines[$ctx_ln - 1]");
                        }
-                       if ($level == 0 && $ctx =~ /\)\s*\;\s*$/ && defined $lines[$ctx_ln - 1]) {
+                       if ($level == 0 && $pre_ctx !~ /}\s*while\s*\($/ &&
+                           $ctx =~ /\)\s*\;\s*$/ &&
+                           defined $lines[$ctx_ln - 1])
+                       {
                                my ($nlength, $nindent) = line_stats($lines[$ctx_ln - 1]);
                                if ($nindent > $indent) {
-                                       WARN("Trailing semicolon indicates no statements, indent implies otherwise\n" .
+                                       WARN("trailing semicolon indicates no statements, indent implies otherwise\n" .
                                                "$here\n$ctx\n$lines[$ctx_ln - 1]");
                                }
                        }
@@ -1200,7 +1249,7 @@ sub process {
 # check for initialisation to aggregates open brace on the next line
                if ($prevline =~ /$Declare\s*$Ident\s*=\s*$/ &&
                    $line =~ /^.\s*{/) {
-                       ERROR("That open brace { should be on the previous line\n" . $hereprev);
+                       ERROR("that open brace { should be on the previous line\n" . $hereprev);
                }
 
 #
@@ -1325,22 +1374,31 @@ sub process {
 # check for spaces between functions and their parentheses.
                while ($line =~ /($Ident)\s+\(/g) {
                        my $name = $1;
-                       my $ctx = substr($line, 0, $-[1]);
+                       my $ctx_before = substr($line, 0, $-[1]);
+                       my $ctx = "$ctx_before$name";
 
                        # Ignore those directives where spaces _are_ permitted.
-                       if ($name =~ /^(?:if|for|while|switch|return|volatile|__volatile__|__attribute__|format|__extension__|Copyright|case|__asm__)$/) {
+                       if ($name =~ /^(?:
+                               if|for|while|switch|return|case|
+                               volatile|__volatile__|
+                               __attribute__|format|__extension__|
+                               asm|__asm__)$/x)
+                       {
 
                        # cpp #define statements have non-optional spaces, ie
                        # if there is a space between the name and the open
                        # parenthesis it is simply not a parameter group.
-                       } elsif ($ctx =~ /^.\#\s*define\s*$/) {
+                       } elsif ($ctx_before =~ /^.\#\s*define\s*$/) {
+
+                       # cpp #elif statement condition may start with a (
+                       } elsif ($ctx =~ /^.\#\s*elif\s*$/) {
 
                        # If this whole things ends with a type its most
                        # likely a typedef for a function.
-                       } elsif ("$ctx$name" =~ /$Type$/) {
+                       } elsif ($ctx =~ /$Type$/) {
 
                        } else {
-                               WARN("no space between function name and open parenthesis '('\n" . $herecurr);
+                               WARN("space prohibited between function name and open parenthesis '('\n" . $herecurr);
                        }
                }
 # Check operator spacing.
@@ -1359,13 +1417,21 @@ sub process {
                        for (my $n = 0; $n < $#elements; $n += 2) {
                                $off += length($elements[$n]);
 
+                               # Pick up the preceeding and succeeding characters.
+                               my $ca = substr($opline, 0, $off);
+                               my $cc = '';
+                               if (length($opline) >= ($off + length($elements[$n + 1]))) {
+                                       $cc = substr($opline, $off + length($elements[$n + 1]));
+                               }
+                               my $cb = "$ca$;$cc";
+
                                my $a = '';
                                $a = 'V' if ($elements[$n] ne '');
                                $a = 'W' if ($elements[$n] =~ /\s$/);
                                $a = 'C' if ($elements[$n] =~ /$;$/);
                                $a = 'B' if ($elements[$n] =~ /(\[|\()$/);
                                $a = 'O' if ($elements[$n] eq '');
-                               $a = 'E' if ($elements[$n] eq '' && $n == 0);
+                               $a = 'E' if ($ca =~ /^\s*$/);
 
                                my $op = $elements[$n + 1];
 
@@ -1381,14 +1447,6 @@ sub process {
                                        $c = 'E';
                                }
 
-                               # Pick up the preceeding and succeeding characters.
-                               my $ca = substr($opline, 0, $off);
-                               my $cc = '';
-                               if (length($opline) >= ($off + length($elements[$n + 1]))) {
-                                       $cc = substr($opline, $off + length($elements[$n + 1]));
-                               }
-                               my $cb = "$ca$;$cc";
-
                                my $ctx = "${a}x${c}";
 
                                my $at = "(ctx:$ctx)";
@@ -1424,7 +1482,7 @@ sub process {
                                } elsif ($op eq ';') {
                                        if ($ctx !~ /.x[WEBC]/ &&
                                            $cc !~ /^\\/ && $cc !~ /^;/) {
-                                               ERROR("need space after that '$op' $at\n" . $hereptr);
+                                               ERROR("space required after that '$op' $at\n" . $hereptr);
                                        }
 
                                # // is a comment
@@ -1433,13 +1491,13 @@ sub process {
                                # -> should have no spaces
                                } elsif ($op eq '->') {
                                        if ($ctx =~ /Wx.|.xW/) {
-                                               ERROR("no spaces around that '$op' $at\n" . $hereptr);
+                                               ERROR("spaces prohibited around that '$op' $at\n" . $hereptr);
                                        }
 
                                # , must have a space on the right.
                                } elsif ($op eq ',') {
                                        if ($ctx !~ /.x[WEC]/ && $cc !~ /^}/) {
-                                               ERROR("need space after that '$op' $at\n" . $hereptr);
+                                               ERROR("space required after that '$op' $at\n" . $hereptr);
                                        }
 
                                # '*' as part of a type definition -- reported already.
@@ -1452,21 +1510,26 @@ sub process {
                                } elsif ($op eq '!' || $op eq '~' ||
                                         ($is_unary && ($op eq '*' || $op eq '-' || $op eq '&'))) {
                                        if ($ctx !~ /[WEBC]x./ && $ca !~ /(?:\)|!|~|\*|-|\&|\||\+\+|\-\-|\{)$/) {
-                                               ERROR("need space before that '$op' $at\n" . $hereptr);
+                                               ERROR("space required before that '$op' $at\n" . $hereptr);
                                        }
                                        if ($ctx =~ /.xW/) {
-                                               ERROR("no space after that '$op' $at\n" . $hereptr);
+                                               ERROR("space prohibited after that '$op' $at\n" . $hereptr);
                                        }
 
                                # unary ++ and unary -- are allowed no space on one side.
                                } elsif ($op eq '++' or $op eq '--') {
-                                       if ($ctx !~ /[WOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
-                                               ERROR("need space one side of that '$op' $at\n" . $hereptr);
+                                       if ($ctx !~ /[WEOBC]x[^W]/ && $ctx !~ /[^W]x[WOBEC]/) {
+                                               ERROR("space required one side of that '$op' $at\n" . $hereptr);
+                                       }
+                                       if ($ctx =~ /Wx[BE]/ ||
+                                           ($ctx =~ /Wx./ && $cc =~ /^;/)) {
+                                               ERROR("space prohibited before that '$op' $at\n" . $hereptr);
                                        }
-                                       if ($ctx =~ /WxB/ || ($ctx =~ /Wx./ && $cc =~ /^;/)) {
-                                               ERROR("no space before that '$op' $at\n" . $hereptr);
+                                       if ($ctx =~ /ExW/) {
+                                               ERROR("space prohibited after that '$op' $at\n" . $hereptr);
                                        }
 
+
                                # << and >> may either have or not have spaces both sides
                                } elsif ($op eq '<<' or $op eq '>>' or
                                         $op eq '&' or $op eq '^' or $op eq '|' or
@@ -1474,7 +1537,7 @@ sub process {
                                         $op eq '*' or $op eq '/' or
                                         $op eq '%')
                                {
-                                       if ($ctx !~ /VxV|WxW|VxE|WxE|VxO|Cx.|.xC/) {
+                                       if ($ctx =~ /Wx[^WCE]|[^WCE]xW/) {
                                                ERROR("need consistent spacing around '$op' $at\n" .
                                                        $hereptr);
                                        }
@@ -1484,7 +1547,7 @@ sub process {
                                        # Ignore email addresses <foo@bar>
                                        if (!($op eq '<' && $cb =~ /$;\S+\@\S+>/) &&
                                            !($op eq '>' && $cb =~ /<\S+\@\S+$;/)) {
-                                               ERROR("need spaces around that '$op' $at\n" . $hereptr);
+                                               ERROR("spaces required around that '$op' $at\n" . $hereptr);
                                        }
                                }
                                $off += length($elements[$n + 1]);
@@ -1514,31 +1577,31 @@ sub process {
 #need space before brace following if, while, etc
                if (($line =~ /\(.*\){/ && $line !~ /\($Type\){/) ||
                    $line =~ /do{/) {
-                       ERROR("need a space before the open brace '{'\n" . $herecurr);
+                       ERROR("space required before the open brace '{'\n" . $herecurr);
                }
 
 # closing brace should have a space following it when it has anything
 # on the line
                if ($line =~ /}(?!(?:,|;|\)))\S/) {
-                       ERROR("need a space after that close brace '}'\n" . $herecurr);
+                       ERROR("space required after that close brace '}'\n" . $herecurr);
                }
 
 # check spacing on square brackets
                if ($line =~ /\[\s/ && $line !~ /\[\s*$/) {
-                       ERROR("no space after that open square bracket '['\n" . $herecurr);
+                       ERROR("space prohibited after that open square bracket '['\n" . $herecurr);
                }
                if ($line =~ /\s\]/) {
-                       ERROR("no space before that close square bracket ']'\n" . $herecurr);
+                       ERROR("space prohibited before that close square bracket ']'\n" . $herecurr);
                }
 
 # check spacing on paretheses
                if ($line =~ /\(\s/ && $line !~ /\(\s*(?:\\)?$/ &&
                    $line !~ /for\s*\(\s+;/) {
-                       ERROR("no space after that open parenthesis '('\n" . $herecurr);
+                       ERROR("space prohibited after that open parenthesis '('\n" . $herecurr);
                }
                if ($line =~ /(\s+)\)/ && $line !~ /^.\s*\)/ &&
                    $line !~ /for\s*\(.*;\s+\)/) {
-                       ERROR("no space before that close parenthesis ')'\n" . $herecurr);
+                       ERROR("space prohibited before that close parenthesis ')'\n" . $herecurr);
                }
 
 #goto labels aren't indented, allow a single space however
@@ -1549,7 +1612,7 @@ sub process {
 
 # Need a space before open parenthesis after if, while etc
                if ($line=~/\b(if|while|for|switch)\(/) {
-                       ERROR("need a space before the open parenthesis '('\n" . $herecurr);
+                       ERROR("space required before the open parenthesis '('\n" . $herecurr);
                }
 
 # Check for illegal assignment in if conditional.
@@ -1562,10 +1625,12 @@ sub process {
 
                        # Find out what is on the end of the line after the
                        # conditional.
-                       substr($s, 0, length($c)) = '';
+                       substr($s, 0, length($c), '');
                        $s =~ s/\n.*//g;
                        $s =~ s/$;//g;  # Remove any comments
-                       if (length($c) && $s !~ /^\s*({|;|)\s*\\*\s*$/) {
+                       if (length($c) && $s !~ /^\s*({|;|)\s*\\*\s*$/ &&
+                           $c !~ /^.\#\s*if/)
+                       {
                                ERROR("trailing statements should be on next line\n" . $herecurr);
                        }
                }
@@ -1607,7 +1672,7 @@ sub process {
 
                        # Find out what is on the end of the line after the
                        # conditional.
-                       substr($s, 0, length($c)) = '';
+                       substr($s, 0, length($c), '');
                        $s =~ s/\n.*//g;
 
                        if ($s =~ /^\s*;/) {
@@ -1631,7 +1696,7 @@ sub process {
                if ($tree && $rawline =~ m{^.\#\s*include\s*\<asm\/(.*)\.h\>}) {
                        my $checkfile = "$root/include/linux/$1.h";
                        if (-f $checkfile && $1 ne 'irq.h') {
-                               CHK("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
+                               WARN("Use #include <linux/$1.h> instead of <asm/$1.h>\n" .
                                        $herecurr);
                        }
                }
@@ -1692,15 +1757,24 @@ sub process {
                        if ($#chunks > 0 && $level == 0) {
                                my $allowed = 0;
                                my $seen = 0;
-                               my $herectx = $here . "\n";;
+                               my $herectx = $here . "\n";
                                my $ln = $linenr - 1;
                                for my $chunk (@chunks) {
                                        my ($cond, $block) = @{$chunk};
 
-                                       $herectx .= "$rawlines[$ln]\n[...]\n";
+                                       # If the condition carries leading newlines, then count those as offsets.
+                                       my ($whitespace) = ($cond =~ /^((?:\s*\n[+-])*\s*)/s);
+                                       my $offset = statement_rawlines($whitespace) - 1;
+
+                                       #print "COND<$cond> whitespace<$whitespace> offset<$offset>\n";
+
+                                       # We have looked at and allowed this specific line.
+                                       $suppress_ifbraces{$ln + $offset} = 1;
+
+                                       $herectx .= "$rawlines[$ln + $offset]\n[...]\n";
                                        $ln += statement_rawlines($block) - 1;
 
-                                       substr($block, 0, length($cond)) = '';
+                                       substr($block, 0, length($cond), '');
 
                                        $seen++ if ($block =~ /^\s*{/);
 
@@ -1721,16 +1795,10 @@ sub process {
                                if ($seen && !$allowed) {
                                        WARN("braces {} are not necessary for any arm of this statement\n" . $herectx);
                                }
-                               # Either way we have looked over this whole
-                               # statement and said what needs to be said.
-                               $suppress_ifbraces = $endln;
                        }
                }
-               if ($linenr > $suppress_ifbraces &&
+               if (!defined $suppress_ifbraces{$linenr - 1} &&
                                        $line =~ /\b(if|while|for|else)\b/) {
-                       my ($level, $endln, @chunks) =
-                               ctx_statement_full($linenr, $realcnt, $-[0]);
-
                        my $allowed = 0;
 
                        # Check the pre-context.
@@ -1738,10 +1806,15 @@ sub process {
                                #print "APW: ALLOWED: pre<$1>\n";
                                $allowed = 1;
                        }
+
+                       my ($level, $endln, @chunks) =
+                               ctx_statement_full($linenr, $realcnt, $-[0]);
+
                        # Check the condition.
                        my ($cond, $block) = @{$chunks[0]};
+                       #print "CHECKING<$linenr> cond<$cond> block<$block>\n";
                        if (defined $cond) {
-                               substr($block, 0, length($cond)) = '';
+                               substr($block, 0, length($cond), '');
                        }
                        if (statement_lines($cond) > 1) {
                                #print "APW: ALLOWED: cond<$cond>\n";
@@ -1759,7 +1832,7 @@ sub process {
                        if (defined $chunks[1]) {
                                my ($cond, $block) = @{$chunks[1]};
                                if (defined $cond) {
-                                       substr($block, 0, length($cond)) = '';
+                                       substr($block, 0, length($cond), '');
                                }
                                if ($block =~ /^\s*\{/) {
                                        #print "APW: ALLOWED: chunk-1 block<$block>\n";
@@ -1882,6 +1955,28 @@ sub process {
                if ($line =~ /__FUNCTION__/) {
                        WARN("__func__ should be used instead of gcc specific __FUNCTION__\n"  . $herecurr);
                }
+
+# check for semaphores used as mutexes
+               if ($line =~ /\b(DECLARE_MUTEX|init_MUTEX)\s*\(/) {
+                       WARN("mutexes are preferred for single holder semaphores\n" . $herecurr);
+               }
+# check for semaphores used as mutexes
+               if ($line =~ /\binit_MUTEX_LOCKED\s*\(/) {
+                       WARN("consider using a completion\n" . $herecurr);
+               }
+# recommend strict_strto* over simple_strto*
+               if ($line =~ /\bsimple_(strto.*?)\s*\(/) {
+                       WARN("consider using strict_$1 in preference to simple_$1\n" . $herecurr);
+               }
+
+# use of NR_CPUS is usually wrong
+# ignore definitions of NR_CPUS and usage to define arrays as likely right
+               if ($line =~ /\bNR_CPUS\b/ &&
+                   $line !~ /^.#\s*define\s+NR_CPUS\s+/ &&
+                   $line !~ /^.\s*$Declare\s.*\[[^\]]*NR_CPUS[^\]]*\]/)
+               {
+                       WARN("usage of NR_CPUS is often wrong - consider using cpu_possible(), num_possible_cpus(), for_each_possible_cpu(), etc\n" . $herecurr);
+               }
        }
 
        # If we have no input at all, then there is nothing to report on
index 87a6726..b63839e 100644 (file)
@@ -1202,3 +1202,5 @@ static int pt101_init(struct ac97_codec * codec)
 
 EXPORT_SYMBOL(ac97_probe_codec);
 
+MODULE_LICENSE("GPL");
+