]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Mar 2008 17:34:21 +0000 (10:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Mar 2008 17:34:21 +0000 (10:34 -0700)
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc:
  [POWERPC] Fix missed hardware breakpoints across multiple threads

201 files changed:
Documentation/hw_random.txt
Documentation/i386/IO-APIC.txt
Documentation/kernel-parameters.txt
Documentation/lguest/lguest.c
Documentation/lguest/lguest.txt
Documentation/nmi_watchdog.txt
MAINTAINERS
Makefile
arch/avr32/kernel/setup.c
arch/avr32/kernel/traps.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/kvm/mmu.c
arch/x86/kvm/vmx.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/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/pci_irq.c
drivers/acpi/processor_idle.c
drivers/acpi/sbshc.c
drivers/acpi/scan.c
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/libata-scsi.c
drivers/ata/pata_it821x.c
drivers/ata/sata_promise.c
drivers/base/core.c
drivers/char/hw_random/Kconfig
drivers/cpuidle/cpuidle.c
drivers/cpuidle/sysfs.c
drivers/i2c/busses/Kconfig
drivers/i2c/busses/i2c-omap.c
drivers/i2c/i2c-core.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/mtd/devices/block2mtd.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/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/usb/rtl8150.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/intel-iommu.c
drivers/pci/pci.c
drivers/pci/setup-bus.c
drivers/pnp/pnpacpi/rsparser.c
drivers/uio/uio.c
drivers/usb/core/message.c
drivers/usb/core/quirks.c
drivers/usb/gadget/inode.c
drivers/usb/host/ehci-pci.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/sierra.c
drivers/usb/storage/isd200.c
drivers/usb/storage/transport.c
drivers/usb/storage/unusual_devs.h
drivers/virtio/virtio_pci.c
fs/anon_inodes.c
fs/file_table.c
fs/hppfs/hppfs_kern.c
fs/hugetlbfs/inode.c
fs/namei.c
fs/open.c
fs/pipe.c
fs/reiserfs/xattr.c
fs/super.c
fs/sysfs/file.c
include/asm-avr32/byteorder.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/cpuidle.h
include/linux/lguest_launcher.h
include/linux/libata.h
include/linux/pci.h
include/linux/sched.h
include/linux/usb/quirks.h
include/linux/usb_usual.h
include/net/neighbour.h
include/net/xfrm.h
kernel/acct.c
kernel/futex.c
kernel/marker.c
kernel/printk.c
kernel/relay.c
kernel/sched.c
kernel/time/clocksource.c
kernel/timer.c
mm/bootmem.c
mm/hugetlb.c
mm/slab.c
mm/slub.c
mm/tiny-shmem.c
mm/vmscan.c
net/8021q/vlan_dev.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/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/Makefile.modpost
scripts/mod/file2alias.c
scripts/mod/modpost.c
scripts/mod/modpost.h
security/smack/smackfs.c
sound/soc/codecs/tlv320aic3x.c

index bb58c36b5845c979dd2f531ee51824a808cbf301..690f52550c80096bb54cd7c7b292399aed63d890 100644 (file)
@@ -1,33 +1,26 @@
-       Hardware driver for Intel/AMD/VIA Random Number Generators (RNG)
-       Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
-       Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
-
 Introduction:
 
-       The hw_random device driver is software that makes use of a
+       The hw_random framework is software that makes use of a
        special hardware feature on your CPU or motherboard,
-       a Random Number Generator (RNG).
+       a Random Number Generator (RNG).  The software has two parts:
+       a core providing the /dev/hw_random character device and its
+       sysfs support, plus a hardware-specific driver that plugs
+       into that core.
 
-       In order to make effective use of this device driver, you
+       To make the most effective use of these mechanisms, you
        should download the support software as well.  Download the
        latest version of the "rng-tools" package from the
        hw_random driver's official Web site:
 
                http://sourceforge.net/projects/gkernel/
 
-About the Intel RNG hardware, from the firmware hub datasheet:
-
-       The Firmware Hub integrates a Random Number Generator (RNG)
-       using thermal noise generated from inherently random quantum
-       mechanical properties of silicon. When not generating new random
-       bits the RNG circuitry will enter a low power state. Intel will
-       provide a binary software driver to give third party software
-       access to our RNG for use as a security feature. At this time,
-       the RNG is only to be used with a system in an OS-present state.
+       Those tools use /dev/hw_random to fill the kernel entropy pool,
+       which is used internally and exported by the /dev/urandom and
+       /dev/random special files.
 
 Theory of operation:
 
-       Character driver.  Using the standard open()
+       CHARACTER DEVICE.  Using the standard open()
        and read() system calls, you can read random data from
        the hardware RNG device.  This data is NOT CHECKED by any
        fitness tests, and could potentially be bogus (if the
@@ -36,9 +29,37 @@ Theory of operation:
        a security-conscious person would run fitness tests on the
        data before assuming it is truly random.
 
-       /dev/hwrandom is char device major 10, minor 183.
+       The rng-tools package uses such tests in "rngd", and lets you
+       run them by hand with a "rngtest" utility.
+
+       /dev/hw_random is char device major 10, minor 183.
+
+       CLASS DEVICE.  There is a /sys/class/misc/hw_random node with
+       two unique attributes, "rng_available" and "rng_current".  The
+       "rng_available" attribute lists the hardware-specific drivers
+       available, while "rng_current" lists the one which is currently
+       connected to /dev/hw_random.  If your system has more than one
+       RNG available, you may change the one used by writing a name from
+       the list in "rng_available" into "rng_current".
+
+==========================================================================
+
+       Hardware driver for Intel/AMD/VIA Random Number Generators (RNG)
+       Copyright 2000,2001 Jeff Garzik <jgarzik@pobox.com>
+       Copyright 2000,2001 Philipp Rumpf <prumpf@mandrakesoft.com>
+
+
+About the Intel RNG hardware, from the firmware hub datasheet:
+
+       The Firmware Hub integrates a Random Number Generator (RNG)
+       using thermal noise generated from inherently random quantum
+       mechanical properties of silicon. When not generating new random
+       bits the RNG circuitry will enter a low power state. Intel will
+       provide a binary software driver to give third party software
+       access to our RNG for use as a security feature. At this time,
+       the RNG is only to be used with a system in an OS-present state.
 
-Driver notes:
+Intel RNG Driver notes:
 
        * FIXME: support poll(2)
 
index f95166645d29ffb1d97ba991355031cc41a40685..30b4c714fbe127cd088f6511fb19af74a41e388f 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 650b0d8aa89b7bde17ca17c1ee54ad37e57f7480..508e2a2c98644ad6c4ee70e59a33191af9af541e 100644 (file)
@@ -1130,6 +1130,10 @@ and is between 256 and 4096 characters. It is defined in the file
        memmap=nn[KMG]$ss[KMG]
                        [KNL,ACPI] Mark specific memory as reserved.
                        Region of memory to be used, from ss to ss+nn.
+                       Example: Exclude memory from 0x18690000-0x1869ffff
+                                memmap=64K$0x18690000
+                                or
+                                memmap=0x10000$0x18690000
 
        meye.*=         [HW] Set MotionEye Camera parameters
                        See Documentation/video4linux/meye.txt.
index bec5a32e4095d705ee16d6bd9a538b4fdaadfe52..4c1fc65a8b3d1c946965db4afc2a2dc08f82c44e 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 722d4e7fbebe479001ee2bd6a8891fc2572bd1e1..29510dc515109ad5dd8a16b5936f1f6086ae417c 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 c025a4561c103381cb14f77880e3d95037061e5c..757c729ee42e717f8908ec148c9221948164ade1 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 73883b8bbd764e8b6732525d18ad3b9600ef8c1f..f1ed75cef6a4a592f3fcef2bcfb1379217793acc 100644 (file)
@@ -2110,7 +2110,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
@@ -2322,6 +2322,8 @@ 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 7a4d34b91e032099d119adae92a0f347dc481901..b08a259e21dc2e32c027c36a033f216f73a50ef9 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 25
-EXTRAVERSION = -rc6
+EXTRAVERSION = -rc7
 NAME = Funky Weasel is Jiggy wit it
 
 # *DOCUMENTATION*
@@ -189,7 +189,7 @@ SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ \
 # Alternatively CROSS_COMPILE can be set in the environment.
 # Default value for CROSS_COMPILE is not to prefix executables
 # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
-
+export KBUILD_BUILDHOST := $(SUBARCH)
 ARCH           ?= $(SUBARCH)
 CROSS_COMPILE  ?=
 
index e66a07a928cd6f7e10cb4798e61a46de75e492b3..2687b730e2d006a638492b303429cbcb767a313a 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 cf6f686d9b0b4c97647316cd93a890930f100990..b835c4c0136882e8320ddde56fe14d98d3f1201c 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 250958d1e3cba242d990df88ad1a623855a1aad4..9d4bd222949345a5b43daa16b72ea63052616782 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 dd5d28e3d79899df97342266e79c1372a9c79707..0097c08dc600e2f432d6a8da965962ab9b3b2bcd 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 6be4d2d2904e3c8f0707e94adcb844cdc19209eb..49eca4b1cf25d41c44a7f165dc97b50e2974136f 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 fbaab3497bfdfa59b45f538e5b473f9bc0959d41..b781d3d54fb8f7ac7c69c358d69abcedb6cab199 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 5ec06c8c7feaa53dd162980c133f274a6637afdf..eb88bd6e674ef7e05a1af6480539e99b860c62cb 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 9a1ba1fe859d96a4e41bccd51342d214a0bea6a4..aaae865e79329aafd093974a2fb1a26c61992a5f 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 d036dbe728647df285833ef7871a90b167cde0d9..6acb4c51cfe4944e3d8c8dae77417515e64514cc 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 fb13775b36823b7f5cdbd707026c9782a0aaf291..94a9d64208eee17126fb2ef996ad07f3ece660fd 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 5a1126b363a499027d1cdb625df2b8757b49664d..59f020d69d4c246c82c2a434eeb15b0d310a8c08 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 47f92a59be18ad41904891f3888974a9df9b08b1..84d39e873e880655d32b4b1ceb05ea32ddc9cf79 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 134d801579f92e5ce10a274e1de080b5702ca113..f952745d0f3d964605e6008f6f567de72a49855e 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 d204f1ab1d4c25a62a5e01a03b3f8fe1ff4e85bf..e5d238970c7ec60e7d52a04495ffb7eb725340c5 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 007f5317c0deda723ba06fea4f46f7e7bb4e0038..96da847023f3c956cecdec5a04fda1fe518be05d 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 466fd6cffac9607a3c481c2cde1f63b85344a0d0..f37078d964073561cda5cbd9a71f9228dcadfc0a 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 3f10fc921b00e1bfb6279f8ccf00986ad7619089..a0f000b293de6ab3c26f2267ee8d7d40c0fe1d6f 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 1e8f41a9951142e536e22312d25e106b1cf1297e..1d43bdfc20c43d37c6b187195556054fd0ae2eeb 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 f2b5a621d27b39e4ece42418719655406b220e17..8a85c93bd62a4678f58be9cdcf8040875b564756 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 103d61a59b196ac5bebd57a9c3369409cba56bfa..3e18db4cefeec9ac73e0220bb1b5ccc44f8999dc 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 c706a3061553d31f69e8904ae23b7b2b335ccfd8..5921e5f0a64027745fa2ac3e5f695ceaca9ddeae 100644 (file)
@@ -76,6 +76,14 @@ static struct dmi_system_id __initdata io_delay_0xed_port_dmi_table[] = {
                        DMI_MATCH(DMI_BOARD_NAME, "30B9")
                }
        },
+       {
+               .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",
index 027fc067b3995153164c799fbe63502baf7706fd..b402c0f3f192213f84595197f067c28043545ea1 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 d5904eef1d319a00eaf71d7efb842d0f87b2fab5..eb92ccbb35026c0d12c26391067df1071536f685 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 a1d7071a51c91c472d4c2926018906dd47e31344..2b3e5d45176bda99d2172a2484076e973d53cfd4 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 7637dc91c79bebac16365bbcff3b480c408584ef..f4f7ecfb898c7628eb220143dd7ad54b60a4ccbd 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 d8172aabc660de7503c43b697fea470d81f7eb9a..e55af12e11b7aeb523ff0296d7e525d2f7a33a6d 100644 (file)
@@ -222,8 +222,7 @@ static int is_io_pte(unsigned long pte)
 
 static int is_rmap_pte(u64 pte)
 {
-       return pte != shadow_trap_nonpresent_pte
-               && pte != shadow_notrap_nonpresent_pte;
+       return is_shadow_present_pte(pte);
 }
 
 static gfn_t pse36_gfn_delta(u32 gpte)
@@ -893,14 +892,25 @@ static void mmu_set_spte(struct kvm_vcpu *vcpu, u64 *shadow_pte,
                         int *ptwrite, gfn_t gfn, struct page *page)
 {
        u64 spte;
-       int was_rmapped = is_rmap_pte(*shadow_pte);
+       int was_rmapped = 0;
        int was_writeble = is_writeble_pte(*shadow_pte);
+       hfn_t host_pfn = (*shadow_pte & PT64_BASE_ADDR_MASK) >> PAGE_SHIFT;
 
        pgprintk("%s: spte %llx access %x write_fault %d"
                 " user_fault %d gfn %lx\n",
                 __FUNCTION__, *shadow_pte, pt_access,
                 write_fault, user_fault, gfn);
 
+       if (is_rmap_pte(*shadow_pte)) {
+               if (host_pfn != page_to_pfn(page)) {
+                       pgprintk("hfn old %lx new %lx\n",
+                                host_pfn, page_to_pfn(page));
+                       rmap_remove(vcpu->kvm, shadow_pte);
+               }
+               else
+                       was_rmapped = 1;
+       }
+
        /*
         * We don't set the accessed bit, since we sometimes want to see
         * whether the guest actually used the pte (in order to detect
@@ -1402,7 +1412,7 @@ static void mmu_guess_page_from_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
        up_read(&current->mm->mmap_sem);
 
        vcpu->arch.update_pte.gfn = gfn;
-       vcpu->arch.update_pte.page = gfn_to_page(vcpu->kvm, gfn);
+       vcpu->arch.update_pte.page = page;
 }
 
 void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa,
index 94ea724638fda63b87ec248c2c3b40783ad93e08..8e1462880d1f1dec6d6162124db057ae5f687868 100644 (file)
@@ -349,8 +349,6 @@ static void update_exception_bitmap(struct kvm_vcpu *vcpu)
 
 static void reload_tss(void)
 {
-#ifndef CONFIG_X86_64
-
        /*
         * VT restores TR but not its size.  Useless.
         */
@@ -361,7 +359,6 @@ static void reload_tss(void)
        descs = (void *)gdt.base;
        descs[GDT_ENTRY_TSS].type = 9; /* available TSS */
        load_TR_desc();
-#endif
 }
 
 static void load_transition_efer(struct vcpu_vmx *vmx)
@@ -1436,7 +1433,7 @@ static int init_rmode_tss(struct kvm *kvm)
        int ret = 0;
        int r;
 
-       down_read(&current->mm->mmap_sem);
+       down_read(&kvm->slots_lock);
        r = kvm_clear_guest_page(kvm, fn, 0, PAGE_SIZE);
        if (r < 0)
                goto out;
@@ -1459,7 +1456,7 @@ static int init_rmode_tss(struct kvm *kvm)
 
        ret = 1;
 out:
-       up_read(&current->mm->mmap_sem);
+       up_read(&kvm->slots_lock);
        return ret;
 }
 
index a104c532ff706cb9845140421371fc208a90605b..3335b4595efd1db2d4b0c8471067c85a75cbe243 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 95b6fbcded63232ffbb614f493741575d4413829..5c7cef34c9e70d31d96fc47e002fd6b6bcd8d590 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 031269163bd670a077733bc1ea3d8a788448044e..247f33d3a4078af864ae842225298d8bc17e2b54 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 dda6024a58629ca2f9cf4bf21b523d4e8972eb4c..a037041817c75edcf070a8dc0acfd1f457297c1c 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 c394ca0720b8d0566f39536b57fc241202c5eb7a..8e25e06ff73088f50a335a9316e1c472b7d1f571 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 fdc667422df9913f2f5d861a3e80fad14eab7f4d..ec08d83898505171ca31b146d4bb0360690ae884 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 4fbafb4bc2f02a93bfcbb64fa732fc08fb0af406..0b3d567e686df15c1b042deb388091ab78a6ae25 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 4afaba0ed72221175854a856d347179b1ab3e979..794895c6dcc99428b2105a9f4062b109b90f5215 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 14e48b5a94ba193c1cb4acc667482e05905d373e..7b79f6be4e7df99dc663d2d4c935a7e35f877a3b 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 8b9ee27805fdd10be4cb19b082131745d1c4a670..de4e6f05840b11a4b89cd91da51aa411648f14de 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 1a43b60c0c62533cf481d50591166d6530b35f32..6b7190449d07950b7cb869e2cca829497bf132af 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 7af414a3c63ee89f3ec0624d256437f9d74a2825..89022a74faeeda9d9ed9b11f431c2e4c4eecb4d7 100644 (file)
@@ -131,8 +131,8 @@ struct prt_quirk {
  */
 static struct prt_quirk prt_quirks[] = {
        { medion_md9580, 0, 0, 9, 'A',
-               "\\_SB_.PCI0.ISA.LNKA",
-               "\\_SB_.PCI0.ISA.LNKB"},
+               "\\_SB_.PCI0.ISA_.LNKA",
+               "\\_SB_.PCI0.ISA_.LNKB"},
        { dell_optiplex, 0, 0, 0xd, 'A',
                "\\_SB_.LNKB",
                "\\_SB_.LNKA"},
index e8e2d88692368f5ea4903485aa7ca6a6b783e493..788da9781f80ffb5311b396cd3557b0786376dcd 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 a2cf3008ce6c03eb40ad564d3063700896a68d03..bcf2c70fca87f498b9a3c5af5e0037248c488b37 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 57570ac47803f4d590da5f8254547119ab10aec3..e6ce262b5d449673932c6c49fa1f41bbc8cb8436 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 17ee6ed985d9198ad356a9b68efebf406a4b11f6..b1eb4e24c86a90a4382be0fd21cbc2765e14ef96 100644 (file)
@@ -433,6 +433,7 @@ static const struct ata_port_info ahci_port_info[] = {
        /* board_ahci_sb600 */
        {
                AHCI_HFLAGS     (AHCI_HFLAG_IGN_SERR_INTERNAL |
+                                AHCI_HFLAG_32BIT_ONLY |
                                 AHCI_HFLAG_SECT255 | AHCI_HFLAG_NO_PMP),
                .flags          = AHCI_FLAG_COMMON,
                .link_flags     = AHCI_LFLAG_COMMON,
@@ -1217,8 +1218,11 @@ static void ahci_dev_config(struct ata_device *dev)
 {
        struct ahci_host_priv *hpriv = dev->link->ap->host->private_data;
 
-       if (hpriv->flags & AHCI_HFLAG_SECT255)
+       if (hpriv->flags & AHCI_HFLAG_SECT255) {
                dev->max_sectors = 255;
+               ata_dev_printk(dev, KERN_INFO,
+                              "SB600 AHCI: limiting to 255 sectors per cmd\n");
+       }
 }
 
 static unsigned int ahci_dev_classify(struct ata_port *ap)
index 4bbe31f98ef8cffadb53a8c2b0962a8ac6f2c1bb..c4248b37ff645c71422d67f1c67802458d020a72 100644 (file)
@@ -1416,12 +1416,12 @@ static int ata_hpa_resize(struct ata_device *dev)
        /* read native max address */
        rc = ata_read_native_max_address(dev, &native_sectors);
        if (rc) {
-               /* If HPA isn't going to be unlocked, skip HPA
-                * resizing from the next try.
+               /* If device aborted the command or HPA isn't going to
+                * be unlocked, skip HPA resizing.
                 */
-               if (!ata_ignore_hpa) {
+               if (rc == -EACCES || !ata_ignore_hpa) {
                        ata_dev_printk(dev, KERN_WARNING, "HPA support seems "
-                                      "broken, will skip HPA handling\n");
+                                      "broken, skipping HPA handling\n");
                        dev->horkage |= ATA_HORKAGE_BROKEN_HPA;
 
                        /* we can continue if device aborted the command */
@@ -2092,24 +2092,34 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
                                     id, sizeof(id[0]) * ATA_ID_WORDS, 0);
        if (err_mask) {
                if (err_mask & AC_ERR_NODEV_HINT) {
-                       DPRINTK("ata%u.%d: NODEV after polling detection\n",
-                               ap->print_id, dev->devno);
+                       ata_dev_printk(dev, KERN_DEBUG,
+                                      "NODEV after polling detection\n");
                        return -ENOENT;
                }
 
-               /* Device or controller might have reported the wrong
-                * device class.  Give a shot at the other IDENTIFY if
-                * the current one is aborted by the device.
-                */
-               if (may_fallback &&
-                   (err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
-                       may_fallback = 0;
+               if ((err_mask == AC_ERR_DEV) && (tf.feature & ATA_ABORTED)) {
+                       /* Device or controller might have reported
+                        * the wrong device class.  Give a shot at the
+                        * other IDENTIFY if the current one is
+                        * aborted by the device.
+                        */
+                       if (may_fallback) {
+                               may_fallback = 0;
 
-                       if (class == ATA_DEV_ATA)
-                               class = ATA_DEV_ATAPI;
-                       else
-                               class = ATA_DEV_ATA;
-                       goto retry;
+                               if (class == ATA_DEV_ATA)
+                                       class = ATA_DEV_ATAPI;
+                               else
+                                       class = ATA_DEV_ATA;
+                               goto retry;
+                       }
+
+                       /* Control reaches here iff the device aborted
+                        * both flavors of IDENTIFYs which happens
+                        * sometimes with phantom devices.
+                        */
+                       ata_dev_printk(dev, KERN_DEBUG,
+                                      "both IDENTIFYs aborted, assuming NODEV\n");
+                       return -ENOENT;
                }
 
                rc = -EIO;
index 8f0e8f2bc628a283c0000b5cab3e43287aa4bb58..15795394b0a88b82a5b54470206ba7fce99e2eae 100644 (file)
@@ -527,6 +527,14 @@ static struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev,
        return qc;
 }
 
+static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc)
+{
+       struct scsi_cmnd *scmd = qc->scsicmd;
+
+       qc->extrabytes = scmd->request->extra_len;
+       qc->nbytes = scsi_bufflen(scmd) + qc->extrabytes;
+}
+
 /**
  *     ata_dump_status - user friendly display of error info
  *     @id: id of the port in question
@@ -2539,7 +2547,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
        }
 
        qc->tf.command = ATA_CMD_PACKET;
-       qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len;
+       ata_qc_set_pc_nbytes(qc);
 
        /* check whether ATAPI DMA is safe */
        if (!using_pio && ata_check_atapi_dma(qc))
@@ -2550,7 +2558,7 @@ static unsigned int atapi_xlat(struct ata_queued_cmd *qc)
         * want to set it properly, and for DMA where it is
         * effectively meaningless.
         */
-       nbytes = min(scmd->request->data_len, (unsigned int)63 * 1024);
+       nbytes = min(ata_qc_raw_nbytes(qc), (unsigned int)63 * 1024);
 
        /* Most ATAPI devices which honor transfer chunk size don't
         * behave according to the spec when odd chunk size which
@@ -2876,7 +2884,7 @@ static unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc)
         * TODO: find out if we need to do more here to
         *       cover scatter/gather case.
         */
-       qc->nbytes = scsi_bufflen(scmd) + scmd->request->extra_len;
+       ata_qc_set_pc_nbytes(qc);
 
        /* request result TF and be quiet about device error */
        qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET;
index 109ddd42c266ba0447b42b801dbee853b9ca16a5..257951d03dbbffbb90520e66c96421dd2f15b148 100644 (file)
@@ -564,7 +564,7 @@ static int it821x_check_atapi_dma(struct ata_queued_cmd *qc)
        struct it821x_dev *itdev = ap->private_data;
 
        /* Only use dma for transfers to/from the media. */
-       if (qc->nbytes < 2048)
+       if (ata_qc_raw_nbytes(qc) < 2048)
                return -EOPNOTSUPP;
 
        /* No ATAPI DMA in smart mode */
index f251a5f569d52403c8fa246848a0f7ff88d63e5b..11c1afea2db298a8d1dc0547ba06282e2d4a73d5 100644 (file)
@@ -46,7 +46,7 @@
 #include "sata_promise.h"
 
 #define DRV_NAME       "sata_promise"
-#define DRV_VERSION    "2.11"
+#define DRV_VERSION    "2.12"
 
 enum {
        PDC_MAX_PORTS           = 4,
@@ -145,7 +145,9 @@ static int pdc_old_sata_check_atapi_dma(struct ata_queued_cmd *qc);
 static void pdc_irq_clear(struct ata_port *ap);
 static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc);
 static void pdc_freeze(struct ata_port *ap);
+static void pdc_sata_freeze(struct ata_port *ap);
 static void pdc_thaw(struct ata_port *ap);
+static void pdc_sata_thaw(struct ata_port *ap);
 static void pdc_pata_error_handler(struct ata_port *ap);
 static void pdc_sata_error_handler(struct ata_port *ap);
 static void pdc_post_internal_cmd(struct ata_queued_cmd *qc);
@@ -180,8 +182,8 @@ static const struct ata_port_operations pdc_sata_ops = {
 
        .qc_prep                = pdc_qc_prep,
        .qc_issue               = pdc_qc_issue_prot,
-       .freeze                 = pdc_freeze,
-       .thaw                   = pdc_thaw,
+       .freeze                 = pdc_sata_freeze,
+       .thaw                   = pdc_sata_thaw,
        .error_handler          = pdc_sata_error_handler,
        .post_internal_cmd      = pdc_post_internal_cmd,
        .cable_detect           = pdc_sata_cable_detect,
@@ -205,8 +207,8 @@ static const struct ata_port_operations pdc_old_sata_ops = {
 
        .qc_prep                = pdc_qc_prep,
        .qc_issue               = pdc_qc_issue_prot,
-       .freeze                 = pdc_freeze,
-       .thaw                   = pdc_thaw,
+       .freeze                 = pdc_sata_freeze,
+       .thaw                   = pdc_sata_thaw,
        .error_handler          = pdc_sata_error_handler,
        .post_internal_cmd      = pdc_post_internal_cmd,
        .cable_detect           = pdc_sata_cable_detect,
@@ -631,6 +633,41 @@ static void pdc_qc_prep(struct ata_queued_cmd *qc)
        }
 }
 
+static int pdc_is_sataii_tx4(unsigned long flags)
+{
+       const unsigned long mask = PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS;
+       return (flags & mask) == mask;
+}
+
+static unsigned int pdc_port_no_to_ata_no(unsigned int port_no,
+                                         int is_sataii_tx4)
+{
+       static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2};
+       return is_sataii_tx4 ? sataii_tx4_port_remap[port_no] : port_no;
+}
+
+static unsigned int pdc_sata_nr_ports(const struct ata_port *ap)
+{
+       return (ap->flags & PDC_FLAG_4_PORTS) ? 4 : 2;
+}
+
+static unsigned int pdc_sata_ata_port_to_ata_no(const struct ata_port *ap)
+{
+       const struct ata_host *host = ap->host;
+       unsigned int nr_ports = pdc_sata_nr_ports(ap);
+       unsigned int i;
+
+       for(i = 0; i < nr_ports && host->ports[i] != ap; ++i)
+               ;
+       BUG_ON(i >= nr_ports);
+       return pdc_port_no_to_ata_no(i, pdc_is_sataii_tx4(ap->flags));
+}
+
+static unsigned int pdc_sata_hotplug_offset(const struct ata_port *ap)
+{
+       return (ap->flags & PDC_FLAG_GEN_II) ? PDC2_SATA_PLUG_CSR : PDC_SATA_PLUG_CSR;
+}
+
 static void pdc_freeze(struct ata_port *ap)
 {
        void __iomem *mmio = ap->ioaddr.cmd_addr;
@@ -643,6 +680,29 @@ static void pdc_freeze(struct ata_port *ap)
        readl(mmio + PDC_CTLSTAT); /* flush */
 }
 
+static void pdc_sata_freeze(struct ata_port *ap)
+{
+       struct ata_host *host = ap->host;
+       void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
+       unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
+       unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
+       u32 hotplug_status;
+
+       /* Disable hotplug events on this port.
+        *
+        * Locking:
+        * 1) hotplug register accesses must be serialised via host->lock
+        * 2) ap->lock == &ap->host->lock
+        * 3) ->freeze() and ->thaw() are called with ap->lock held
+        */
+       hotplug_status = readl(host_mmio + hotplug_offset);
+       hotplug_status |= 0x11 << (ata_no + 16);
+       writel(hotplug_status, host_mmio + hotplug_offset);
+       readl(host_mmio + hotplug_offset); /* flush */
+
+       pdc_freeze(ap);
+}
+
 static void pdc_thaw(struct ata_port *ap)
 {
        void __iomem *mmio = ap->ioaddr.cmd_addr;
@@ -658,6 +718,26 @@ static void pdc_thaw(struct ata_port *ap)
        readl(mmio + PDC_CTLSTAT); /* flush */
 }
 
+static void pdc_sata_thaw(struct ata_port *ap)
+{
+       struct ata_host *host = ap->host;
+       void __iomem *host_mmio = host->iomap[PDC_MMIO_BAR];
+       unsigned int hotplug_offset = pdc_sata_hotplug_offset(ap);
+       unsigned int ata_no = pdc_sata_ata_port_to_ata_no(ap);
+       u32 hotplug_status;
+
+       pdc_thaw(ap);
+
+       /* Enable hotplug events on this port.
+        * Locking: see pdc_sata_freeze().
+        */
+       hotplug_status = readl(host_mmio + hotplug_offset);
+       hotplug_status |= 0x11 << ata_no;
+       hotplug_status &= ~(0x11 << (ata_no + 16));
+       writel(hotplug_status, host_mmio + hotplug_offset);
+       readl(host_mmio + hotplug_offset); /* flush */
+}
+
 static void pdc_common_error_handler(struct ata_port *ap, ata_reset_fn_t hardreset)
 {
        if (!(ap->pflags & ATA_PFLAG_FROZEN))
@@ -765,19 +845,6 @@ static void pdc_irq_clear(struct ata_port *ap)
        readl(mmio + PDC_INT_SEQMASK);
 }
 
-static int pdc_is_sataii_tx4(unsigned long flags)
-{
-       const unsigned long mask = PDC_FLAG_GEN_II | PDC_FLAG_4_PORTS;
-       return (flags & mask) == mask;
-}
-
-static unsigned int pdc_port_no_to_ata_no(unsigned int port_no,
-                                         int is_sataii_tx4)
-{
-       static const unsigned char sataii_tx4_port_remap[4] = { 3, 1, 0, 2};
-       return is_sataii_tx4 ? sataii_tx4_port_remap[port_no] : port_no;
-}
-
 static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
@@ -799,6 +866,8 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
 
        mmio_base = host->iomap[PDC_MMIO_BAR];
 
+       spin_lock(&host->lock);
+
        /* read and clear hotplug flags for all ports */
        if (host->ports[0]->flags & PDC_FLAG_GEN_II)
                hotplug_offset = PDC2_SATA_PLUG_CSR;
@@ -814,11 +883,9 @@ static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
 
        if (mask == 0xffffffff && hotplug_status == 0) {
                VPRINTK("QUICK EXIT 2\n");
-               return IRQ_NONE;
+               goto done_irq;
        }
 
-       spin_lock(&host->lock);
-
        mask &= 0xffff;         /* only 16 tags possible */
        if (mask == 0 && hotplug_status == 0) {
                VPRINTK("QUICK EXIT 3\n");
index 7de543d1d0b4337328f95c502915d99b3a4fa871..24198ad0197654943ae95250b22386358cb22e71 100644 (file)
@@ -19,6 +19,7 @@
 #include <linux/kdev_t.h>
 #include <linux/notifier.h>
 #include <linux/genhd.h>
+#include <linux/kallsyms.h>
 #include <asm/semaphore.h>
 
 #include "base.h"
@@ -68,6 +69,10 @@ static ssize_t dev_attr_show(struct kobject *kobj, struct attribute *attr,
 
        if (dev_attr->show)
                ret = dev_attr->show(dev, dev_attr, buf);
+       if (ret >= (ssize_t)PAGE_SIZE) {
+               print_symbol("dev_attr_show: %s returned bad count\n",
+                               (unsigned long)dev_attr->show);
+       }
        return ret;
 }
 
index 6bbd4fa50f3b87458a56dbc155288f1e21b5a64d..8d6c2089d2a8480bf1829d0b3d24bca959b22a31 100644 (file)
@@ -9,7 +9,14 @@ config HW_RANDOM
          Hardware Random Number Generator Core infrastructure.
 
          To compile this driver as a module, choose M here: the
-         module will be called rng-core.
+         module will be called rng-core.  This provides a device
+         that's usually called /dev/hw_random, and which exposes one
+         of possibly several hardware random number generators.
+
+         These hardware random number generators do not feed directly
+         into the kernel's random number generator.  That is usually
+         handled by the "rngd" daemon.  Documentation/hw_random.txt
+         has more information.
 
          If unsure, say Y.
 
index d73663a52324b89b93a7eb68f2fe0df9d21fbe26..fc555a90bb211b651e20c254751ae08f00fffd1a 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 69102ca05685bdf9f7f48d0926edd160d3428074..e949618b9be0ee3d0e95b48bbac4fd5f93ad21f2 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 476b0bb72d6c680b6636e8cd6e784e039f2a772b..5fa9c3c67e0cd55d18f779552c89f017a9ab644f 100644 (file)
@@ -100,7 +100,7 @@ config I2C_AU1550
 
 config I2C_BLACKFIN_TWI
        tristate "Blackfin TWI I2C support"
-       depends on BF534 || BF536 || BF537 || BF54x
+       depends on BF534 || BF536 || BF537
        help
          This is the TWI I2C device driver for Blackfin 534/536/537/54x.
          This driver can also be built as a module.  If so, the module
index da6639707ea31e32f944d9cccae70e7827c4cb2a..7ba31770d773245102b4ece0dc9393af76791a3b 100644 (file)
@@ -128,6 +128,8 @@ struct omap_i2c_dev {
        size_t                  buf_len;
        struct i2c_adapter      adapter;
        unsigned                rev1:1;
+       unsigned                idle:1;
+       u16                     iestate;        /* Saved interrupt register */
 };
 
 static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
@@ -174,18 +176,30 @@ static void omap_i2c_put_clocks(struct omap_i2c_dev *dev)
        }
 }
 
-static void omap_i2c_enable_clocks(struct omap_i2c_dev *dev)
+static void omap_i2c_unidle(struct omap_i2c_dev *dev)
 {
        if (dev->iclk != NULL)
                clk_enable(dev->iclk);
        clk_enable(dev->fclk);
+       if (dev->iestate)
+               omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, dev->iestate);
+       dev->idle = 0;
 }
 
-static void omap_i2c_disable_clocks(struct omap_i2c_dev *dev)
+static void omap_i2c_idle(struct omap_i2c_dev *dev)
 {
+       u16 iv;
+
+       dev->idle = 1;
+       dev->iestate = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
+       omap_i2c_write_reg(dev, OMAP_I2C_IE_REG, 0);
+       if (dev->rev1)
+               iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);   /* Read clears */
+       else
+               omap_i2c_write_reg(dev, OMAP_I2C_STAT_REG, dev->iestate);
+       clk_disable(dev->fclk);
        if (dev->iclk != NULL)
                clk_disable(dev->iclk);
-       clk_disable(dev->fclk);
 }
 
 static int omap_i2c_init(struct omap_i2c_dev *dev)
@@ -360,7 +374,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
        int i;
        int r;
 
-       omap_i2c_enable_clocks(dev);
+       omap_i2c_unidle(dev);
 
        if ((r = omap_i2c_wait_for_bb(dev)) < 0)
                goto out;
@@ -374,7 +388,7 @@ omap_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
        if (r == 0)
                r = num;
 out:
-       omap_i2c_disable_clocks(dev);
+       omap_i2c_idle(dev);
        return r;
 }
 
@@ -403,6 +417,9 @@ omap_i2c_rev1_isr(int this_irq, void *dev_id)
        struct omap_i2c_dev *dev = dev_id;
        u16 iv, w;
 
+       if (dev->idle)
+               return IRQ_NONE;
+
        iv = omap_i2c_read_reg(dev, OMAP_I2C_IV_REG);
        switch (iv) {
        case 0x00:      /* None */
@@ -457,6 +474,9 @@ omap_i2c_isr(int this_irq, void *dev_id)
        u16 stat, w;
        int count = 0;
 
+       if (dev->idle)
+               return IRQ_NONE;
+
        bits = omap_i2c_read_reg(dev, OMAP_I2C_IE_REG);
        while ((stat = (omap_i2c_read_reg(dev, OMAP_I2C_STAT_REG))) & bits) {
                dev_dbg(dev->dev, "IRQ (ISR = 0x%04x)\n", stat);
@@ -575,7 +595,7 @@ omap_i2c_probe(struct platform_device *pdev)
        if ((r = omap_i2c_get_clocks(dev)) != 0)
                goto err_free_mem;
 
-       omap_i2c_enable_clocks(dev);
+       omap_i2c_unidle(dev);
 
        if (cpu_is_omap15xx())
                dev->rev1 = omap_i2c_read_reg(dev, OMAP_I2C_REV_REG) < 0x20;
@@ -610,7 +630,7 @@ omap_i2c_probe(struct platform_device *pdev)
                goto err_free_irq;
        }
 
-       omap_i2c_disable_clocks(dev);
+       omap_i2c_idle(dev);
 
        return 0;
 
@@ -618,7 +638,7 @@ err_free_irq:
        free_irq(dev->irq, dev);
 err_unuse_clocks:
        omap_i2c_write_reg(dev, OMAP_I2C_CON_REG, 0);
-       omap_i2c_disable_clocks(dev);
+       omap_i2c_idle(dev);
        omap_i2c_put_clocks(dev);
 err_free_mem:
        platform_set_drvdata(pdev, NULL);
index fd84b2a363381a6571a09d883cc3d7fe3cc676fa..8b645c6b2cb50c506b82a21f7af0d3c1fdecccf8 100644 (file)
@@ -489,8 +489,8 @@ EXPORT_SYMBOL(i2c_add_adapter);
  * Context: can sleep
  *
  * This routine is used to declare an I2C adapter when its bus number
- * matters.  Example: for I2C adapters from system-on-chip CPUs, or
- * otherwise built in to the system's mainboard, and where i2c_board_info
+ * matters.  For example, use it for I2C adapters from system-on-chip CPUs,
+ * or otherwise built in to the system's mainboard, and where i2c_board_info
  * is used to properly configure I2C devices.
  *
  * If no devices have pre-been declared for this bus, then be sure to
index 5e8272d296d8ff47e03937e766e24fba4d0db6f8..7d463c26124f38d9fb1545a6098f08b6d6c1d29f 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 c632c08cbbdc949793f322b75186aa77beddf1a4..5eea4356d70348b102ba2b62d9a3196e21bc7690 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 0f2cb4fd7c6980448e01770476e262d6ea708d70..54d66f05fefa0a82af7c96a78432cf2a763d6530 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 32e97c1858e571a2608c678e602755a7f3b7aa38..0414ddf875871729c00742c00cb6bf45a558eac8 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 1b2ec0bf5eb11d9fedfeb65b035e89efe683d013..2bc9bf7e88e5e8f03a62347a346a1fc2cfd2c747 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 2221485b07739a48114f44dc38b4f4249a93360c..564e425d71dd37747735e8ba47ed1b1881a022cb 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;
 }
 
@@ -185,14 +192,13 @@ static int initialize(struct file *file, const unsigned long __user *input)
        lg->mem_base = (void __user *)(long)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 a7f64a9d67e009437b30e5007a208c25863be392..d93500f24fbb22e26ecd0316ed12289ed8b4b686 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 635187812d52b11cf85ed65a3ae88ef6fabf6f7f..5126d5d9ea0e8d8d97fa0eaf47ed22216329328b 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 0af8baaa0d4a602ee9f6925c411dcf14059efda2..3fc15318a80ff50e58cdd1f2195748e0e718faff 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 eeaaa9dce6ef62607ee510e580d647554bca8611..ad1880c67518eead88feb416b72a598fb86a9ba6 100644 (file)
@@ -408,7 +408,6 @@ static int block2mtd_setup2(const char *val)
        if (token[1]) {
                ret = parse_num(&erase_size, token[1]);
                if (ret) {
-                       kfree(name);
                        parse_err("illegal erase size");
                }
        }
index ea2a2b548e3c85f380fef916827df61ce45329e9..25f1337cd02c813e6ed5bfe0fcea21608e94b8ec 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 cb3c6faa7888c55b74771053a4c80660ef317a4a..d16e0e1d2b30fba04d5f6f2d8ae81599480599d7 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 b57bc9467dbe7a22d1c609fffa1ca5154daf9382..3f58c3d0b7106ae02452ff77f1e41c28ae2ded67 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 0942d82f7cbf721f62c364941a13b31373668c5b..0f0675319e9c601ff76880f001b4e07d5ad829ee 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 67ccad69d445f097675c9c724b7a632bca10a4cd..a3c74e20aa538523df633effbeaa46aaa1b0bb27 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 db586870c5f43843cacba508cfc60673f6a2864e..98a6bbd11d4c92232df793d3475082b0db12f63a 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 1fe305ca2cf0b42bb8a5a90e80918924a90ac2f8..b09a53de1c53373c1d469f60a6c1356fb12f63d9 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);
 
@@ -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 cdf3090a1885fbe6ebfdc537c313af036aaf4b76..2d139ec7977768e78112dd52513dcae57d5b5698 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 7c4ead35cfa23824227ce4dd1449dee671628b5c..93b7fb2469604d55c338c0ba0bf7da4f9cd520e4 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 21af674b764e402e4d0f6ceed6d6df54278d0f15..07c742dd3f0947131507f8e2a1c6251f4e2300c9 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 6604d96bd567618fffff1d01098ad3660e0cf543..76ea846663db9f5a22919b5c427a6cae6a383832 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 161fb68764af2aa27f2853f80f7a1953ba14fcd1..7b2c70a3b8cca8d93c7d832856beba80538d7442 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 928ce8287e6932027fdffdc316962a64f6be73e1..aaee02e9e3f03c4bc0da116942964996fe061fda 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 269e6f805f472bc7232a55cad0518a16884fdbb0..6738b4d097fe6fc4e50058c8a42811e6b7f4a2d4 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 2bc5eaae141fd083a19e4d80c08add20d2d2ee5b..7f20a03623a08472ad450e0f73ee60ec92288010 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 7a876f4b8db24f27a9ad67f20a809a3b7b8584a0..6e98d830eefb48a4542dc8cb077f2d4df029882f 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 d72f8f8fcb50b58f1ffce626dd6da44a6de31216..160f605e58db1fb9508f5bc44e9a83c8372e0b8f 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 01355701bf8ecb9701d2f2d4b46186b774d1bf82..05748ca6f216831543574dda76d0778883365865 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 9e38bcb3fba9ac7fe1d25f28015cbd231d4a936e..45fa33e0cb9062764dc542d3c9fd428dfa6cc17f 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 48a404aa66ceebc859a3851167f556fd4ca54f26..c81313b717bdd1352d7913a014ab90656a87496f 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 9737eae5ef111f265345e1747d008cad953fb7db..a8fb439a4d03395a024772bda25db0fa7deab718 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)
@@ -893,6 +878,12 @@ static int netxen_nic_open(struct net_device *netdev)
        if (adapter->set_mtu)
                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);
 
@@ -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 ffa3b7215ce8eb3dd909da585b4f93b89c50a1a7..a566b50f36f5dac6b3f20b320e479ad75f15712f 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 f0574073a2a34a02beb226cd27401ae5191895a3..33539917e9b8008d6890e872e9d4ab7550b06d6d 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 c72787adeba33bbe31dbbc52d9559551226c1d81..3c915b82e19982455b7b8dd0bdfd704c14ea9e98 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 186eb8ebfda643e2155579f5d36ad7fc518fb4b6..2e26dced13a1ed3bb124e8432382cb13b3555af7 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 51d4134b37b196307bf98480fd786e64d983e897..98a832a7553988664a0a33c923920d04f4bad73b 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 8909050b8ea7e57cda3efce74c181082bf09d3d9..5f1c5072b96f093ee8fa2161eaaf4ba04b6693e1 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 4b131a6c6b70bfcd7d169f9110c7b7fb2c343341..0343b00cf1fd153064a860770d182fcf67b5cabc 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 727547a289920dd59b7ca2ec3045c031cd75c856..369c731114b3c67ffa8f1e5f9760aad22caa7817 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 7e1f00131f91160833e023f416ae2834afeb52cf..df56a518691c6c9fb5664c2f972082ac84fdf693 100644 (file)
@@ -376,7 +376,7 @@ static int alloc_all_urbs(rtl8150_t * dev)
                return 0;
        }
        dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
-       if (!dev->intr_urb) {
+       if (!dev->ctrl_urb) {
                usb_free_urb(dev->rx_urb);
                usb_free_urb(dev->tx_urb);
                usb_free_urb(dev->intr_urb);
index c6e70dbc5de824a9ab63286c82d76ed6480a40ff..2ab1d59870f4e1114daca7a1212e43a61026bf68 100644 (file)
@@ -1197,13 +1197,6 @@ static ctl_table arlan_table[] =
 
 #else
 
-static ctl_table arlan_table[MAX_ARLANS + 1] =
-{
-       { .ctl_name = 0 }
-};
-#endif
-#else
-
 static ctl_table arlan_table[MAX_ARLANS + 1] =
 {
        { .ctl_name = 0 }
@@ -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 e38ed0fe72e9c3978bdf1499d6c299c07e84854d..7fca2ebc747f09b11e017bca3834b4eb73c7fd3f 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 3dfb28a34be9f8259c75bf5490a703cd88303a02..cfbc1a26f6016d7a59510132254168351b3218c8 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 51dfce16178a7ca2276f91ec551635ffc3e7205d..c73a75b24cd684dee52ac9cc40a3337d2d2f3cd1 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 d1af938b9aa661f5e90e998aa9abe43c323bf7e0..b79a35a40ab66b174417b7f5256d8dfda171ed14 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 40b71bc2c4a4c3eea35c5896d4293e20b4f5034d..cbaeaf18649480dd0d426daa08b1f882c4b10fde 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 a23d4798653b716a3bad6e455797df70f90ab801..60ec29eab85aa3f82b29189811d45a0bbefc6486 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 8103d41a1543d04461611fada2d53d684d873962..3909cf42f472412fccc771e7ae58cfa41ee8a9db 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 fabc63ee153c7c8de715dc51f212055f35de8efa..2e4bfe4147c6549a32e4c746f9edc3da2a16e081 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 977d29b322957066e1e6ecb26a37cb322b187237..4cb949f0ebd9746e8e0c5d29a6c5fba034bbf370 100644 (file)
@@ -1097,6 +1097,8 @@ static void iommu_free_domain(struct dmar_domain *domain)
 }
 
 static struct iova_domain reserved_iova_list;
+static struct lock_class_key reserved_alloc_key;
+static struct lock_class_key reserved_rbtree_key;
 
 static void dmar_init_reserved_ranges(void)
 {
@@ -1107,6 +1109,11 @@ static void dmar_init_reserved_ranges(void)
 
        init_iova_domain(&reserved_iova_list, DMA_32BIT_PFN);
 
+       lockdep_set_class(&reserved_iova_list.iova_alloc_lock,
+               &reserved_alloc_key);
+       lockdep_set_class(&reserved_iova_list.iova_rbtree_lock,
+               &reserved_rbtree_key);
+
        /* IOAPIC ranges shouldn't be accessed by DMA */
        iova = reserve_iova(&reserved_iova_list, IOVA_PFN(IOAPIC_RANGE_START),
                IOVA_PFN(IOAPIC_RANGE_END));
index 183fddaa38b74e5854e386c18266b81814eaa5b9..a4445b7210bf7057e0322c5ba49d943ce1cbd056 100644 (file)
@@ -314,24 +314,6 @@ int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
 }
 EXPORT_SYMBOL_GPL(pci_find_ht_capability);
 
-void pcie_wait_pending_transaction(struct pci_dev *dev)
-{
-       int pos;
-       u16 reg16;
-
-       pos = pci_find_capability(dev, PCI_CAP_ID_EXP);
-       if (!pos)
-               return;
-       while (1) {
-               pci_read_config_word(dev, pos + PCI_EXP_DEVSTA, &reg16);
-               if (!(reg16 & PCI_EXP_DEVSTA_TRPND))
-                       break;
-               cpu_relax();
-       }
-
-}
-EXPORT_SYMBOL_GPL(pcie_wait_pending_transaction);
-
 /**
  * pci_find_parent_resource - return resource region of parent bus of given region
  * @dev: PCI device structure contains resources to be searched
@@ -936,9 +918,6 @@ pci_disable_device(struct pci_dev *dev)
        if (atomic_sub_return(1, &dev->enable_cnt) != 0)
                return;
 
-       /* Wait for all transactions are finished before disabling the device */
-       pcie_wait_pending_transaction(dev);
-
        pci_read_config_word(dev, PCI_COMMAND, &pci_command);
        if (pci_command & PCI_COMMAND_MASTER) {
                pci_command &= ~PCI_COMMAND_MASTER;
index 125e7b7f34ffd13462e551b31c79cd03ab0d3572..f7cb8e0758b48a5b7c49e0099d0c3cbc60ae23d8 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 6aa231ef642d3e366b13984a56e524851d9251fa..2dcd1960aca844c5cc98e5796b11dec81cde6dbf 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 e8a01f264540e1cb9675eb821e0f3769c7a9667c..11759080ca547058809b516aaacbc8f979ff77d5 100644 (file)
@@ -470,6 +470,8 @@ static int uio_mmap_physical(struct vm_area_struct *vma)
 
        vma->vm_flags |= VM_IO | VM_RESERVED;
 
+       vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+
        return remap_pfn_range(vma,
                               vma->vm_start,
                               idev->info->mem[mi].addr >> PAGE_SHIFT,
index fefb92296e8f5a921edf849a30caf808cf904793..c311f67b7f0824dba591b50d4b21f943827349b0 100644 (file)
@@ -1206,7 +1206,10 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)
                return -EINVAL;
        }
 
-       ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
+       if (dev->quirks & USB_QUIRK_NO_SET_INTF)
+               ret = -EPIPE;
+       else
+               ret = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),
                                   USB_REQ_SET_INTERFACE, USB_RECIP_INTERFACE,
                                   alternate, interface, NULL, 0, 5000);
 
index d9d1eb19f2a134ecde7a5f5bad21cb195da0bdb1..dfc5418ea10c0a11654cb59d392bb535be0aad0b 100644 (file)
@@ -50,6 +50,9 @@ static const struct usb_device_id usb_quirk_list[] = {
        /* M-Systems Flash Disk Pioneers */
        { USB_DEVICE(0x08ec, 0x1000), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* X-Rite/Gretag-Macbeth Eye-One Pro display colorimeter */
+       { USB_DEVICE(0x0971, 0x2000), .driver_info = USB_QUIRK_NO_SET_INTF },
+
        /* Action Semiconductor flash disk */
        { USB_DEVICE(0x10d6, 0x2200), .driver_info =
                        USB_QUIRK_STRING_FETCH_255 },
index 805602a687cbc7bfd2b225d5e247a6f4f8c19cc5..0a6feafc8d2847ef39ab4ed3c74cac750e8b931c 100644 (file)
@@ -1458,7 +1458,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
        /* currently one config, two speeds */
        case USB_REQ_SET_CONFIGURATION:
                if (ctrl->bRequestType != 0)
-                       break;
+                       goto unrecognized;
                if (0 == (u8) w_value) {
                        value = 0;
                        dev->current_config = 0;
@@ -1505,7 +1505,7 @@ gadgetfs_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
        /* PXA automagically handles this request too */
        case USB_REQ_GET_CONFIGURATION:
                if (ctrl->bRequestType != 0x80)
-                       break;
+                       goto unrecognized;
                *(u8 *)req->buf = dev->current_config;
                value = min (w_length, (u16) 1);
                break;
index 3ba01664f82154b00bef518eea7c3e809566f63b..72ccd56e36dd46665712ea26d5944312f8a10635 100644 (file)
@@ -152,6 +152,20 @@ static int ehci_pci_setup(struct usb_hcd *hcd)
                        break;
                }
                break;
+       case PCI_VENDOR_ID_VIA:
+               if (pdev->device == 0x3104 && (pdev->revision & 0xf0) == 0x60) {
+                       u8 tmp;
+
+                       /* The VT6212 defaults to a 1 usec EHCI sleep time which
+                        * hogs the PCI bus *badly*. Setting bit 5 of 0x4B makes
+                        * that sleep time use the conventional 10 usec.
+                        */
+                       pci_read_config_byte(pdev, 0x4b, &tmp);
+                       if (tmp & 0x20)
+                               break;
+                       pci_write_config_byte(pdev, 0x4b, tmp | 0x20);
+               }
+               break;
        }
 
        ehci_reset(ehci);
index ae3ec1a64008b65e2b10f4a95152ea74e6c23729..2af778555bdc85496e3a3f02c9d8f3f977cda72f 100644 (file)
@@ -55,6 +55,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_DCU11) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
+       { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_ALDIGA) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID) },
        { USB_DEVICE(IODATA_VENDOR_ID, IODATA_PRODUCT_ID_RSAQ5) },
        { USB_DEVICE(ATEN_VENDOR_ID, ATEN_PRODUCT_ID) },
index 237a41f6638ac239b9c3dc980230cf4c615537f5..10cf872e5ecbf1c86e1f52d0895e1913e8c89e9f 100644 (file)
@@ -13,6 +13,7 @@
 #define PL2303_PRODUCT_ID_DCU11                0x1234
 #define PL2303_PRODUCT_ID_PHAROS       0xaaa0
 #define PL2303_PRODUCT_ID_RSAQ3                0xaaa2
+#define PL2303_PRODUCT_ID_ALDIGA       0x0611
 
 #define ATEN_VENDOR_ID         0x0557
 #define ATEN_VENDOR_ID2                0x0547
index e3d44ae8d4482c1c1753e286e1c26a0878ad995a..ed678811e6a6d0ed54e3f6db2c9c1b343bcdba69 100644 (file)
@@ -14,7 +14,7 @@
   Whom based his on the Keyspan driver by Hugh Blemings <hugh@blemings.org>
 */
 
-#define DRIVER_VERSION "v.1.2.7"
+#define DRIVER_VERSION "v.1.2.8"
 #define DRIVER_AUTHOR "Kevin Lloyd <linux@sierrawireless.com>"
 #define DRIVER_DESC "USB Driver for Sierra Wireless USB modems"
 
@@ -163,6 +163,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x1199, 0x6803) }, /* Sierra Wireless MC8765 */
        { USB_DEVICE(0x1199, 0x6812) }, /* Sierra Wireless MC8775 & AC 875U */
        { USB_DEVICE(0x1199, 0x6813) }, /* Sierra Wireless MC8775 (Thinkpad internal) */
+       { USB_DEVICE(0x1199, 0x6815) }, /* Sierra Wireless MC8775 */
        { USB_DEVICE(0x1199, 0x6820) }, /* Sierra Wireless AirCard 875 */
        { USB_DEVICE(0x1199, 0x6832) }, /* Sierra Wireless MC8780*/
        { USB_DEVICE(0x1199, 0x6833) }, /* Sierra Wireless MC8781*/
@@ -196,9 +197,9 @@ struct sierra_port_private {
        spinlock_t lock;        /* lock the structure */
        int outstanding_urbs;   /* number of out urbs in flight */
 
-       /* Input endpoints and buffer for this port */
+       /* Input endpoints and buffers for this port */
        struct urb *in_urbs[N_IN_URB];
-       char in_buffer[N_IN_URB][IN_BUFLEN];
+       char *in_buffer[N_IN_URB];
 
        /* Settings for the port */
        int rts_state;  /* Handshaking pins (outputs) */
@@ -638,6 +639,15 @@ static int sierra_startup(struct usb_serial *serial)
                        return -ENOMEM;
                }
                spin_lock_init(&portdata->lock);
+               for (j = 0; j < N_IN_URB; j++) {
+                       portdata->in_buffer[j] = kmalloc(IN_BUFLEN, GFP_KERNEL);
+                       if (!portdata->in_buffer[j]) {
+                               for (--j; j >= 0; j--)
+                                       kfree(portdata->in_buffer[j]);
+                               kfree(portdata);
+                               return -ENOMEM;
+                       }
+               }
 
                usb_set_serial_port_data(port, portdata);
 
@@ -681,7 +691,7 @@ static void sierra_shutdown(struct usb_serial *serial)
                for (j = 0; j < N_IN_URB; j++) {
                        usb_kill_urb(portdata->in_urbs[j]);
                        usb_free_urb(portdata->in_urbs[j]);
-                       portdata->in_urbs[j] = NULL;
+                       kfree(portdata->in_buffer[j]);
                }
                kfree(portdata);
                usb_set_serial_port_data(port, NULL);
index 9d3f28b92cbeaa8411d8953e6128ffe4f01af64c..971d13dd5e65a55e9256c932d63bc6b0a0caa1e4 100644 (file)
@@ -1230,6 +1230,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
            
                        /* Free driver structure */         
                        us->extra_destructor(info);
+                       kfree(info);
                        us->extra = NULL;
                        us->extra_destructor = NULL;
                }
index 5780ed15f1ad19d6b3d1a17f74bd37b4bfe0bfab..bdd4334bed5a71c7615455cedbb755925cec1436 100644 (file)
@@ -1009,7 +1009,8 @@ int usb_stor_Bulk_transport(struct scsi_cmnd *srb, struct us_data *us)
        US_DEBUGP("Bulk Status S 0x%x T 0x%x R %u Stat 0x%x\n",
                        le32_to_cpu(bcs->Signature), bcs->Tag, 
                        residue, bcs->Status);
-       if (bcs->Tag != us->tag || bcs->Status > US_BULK_STAT_PHASE) {
+       if (!(bcs->Tag == us->tag || (us->flags & US_FL_BULK_IGNORE_TAG)) ||
+               bcs->Status > US_BULK_STAT_PHASE) {
                US_DEBUGP("Bulk logical error\n");
                return USB_STOR_TRANSPORT_ERROR;
        }
index 99679a8cfa0268d3d3e557eb91a45da2bf034dcd..e5219a56947cb9ee20d0483d143dd7771bd28450 100644 (file)
@@ -1589,6 +1589,17 @@ UNUSUAL_DEV(  0x22b8, 0x4810, 0x0001, 0x0001,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_FIX_CAPACITY),
 
+/*
+ * Patch by Constantin Baranov <const@tltsu.ru>
+ * Report by Andreas Koenecke.
+ * Motorola ROKR Z6.
+ */
+UNUSUAL_DEV(  0x22b8, 0x6426, 0x0101, 0x0101,
+               "Motorola",
+               "MSnc.",
+               US_SC_DEVICE, US_PR_DEVICE, NULL,
+               US_FL_FIX_INQUIRY | US_FL_FIX_CAPACITY | US_FL_BULK_IGNORE_TAG),
+
 /* Reported by Radovan Garabik <garabik@kassiopeia.juls.savba.sk> */
 UNUSUAL_DEV(  0x2735, 0x100b, 0x0000, 0x9999,
                "MPIO",
index 59a8f73dec730421c3dcff6b52c0c9de59798b43..6c8ecde6aad188a17b44030e1769ac2310564605 100644 (file)
@@ -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 23321889d9b09d89075272ee419d4e00b496f1d8..f42be069e085b2d212b8cc633d61f418be6801f5 100644 (file)
@@ -81,13 +81,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
 
        if (IS_ERR(anon_inode_inode))
                return -ENODEV;
-       file = get_empty_filp();
-       if (!file)
-               return -ENFILE;
 
        error = get_unused_fd();
        if (error < 0)
-               goto err_put_filp;
+               return error;
        fd = error;
 
        /*
@@ -114,14 +111,15 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
        dentry->d_flags &= ~DCACHE_UNHASHED;
        d_instantiate(dentry, anon_inode_inode);
 
-       file->f_path.mnt = mntget(anon_inode_mnt);
-       file->f_path.dentry = dentry;
+       error = -ENFILE;
+       file = alloc_file(anon_inode_mnt, dentry,
+                         FMODE_READ | FMODE_WRITE, fops);
+       if (!file)
+               goto err_dput;
        file->f_mapping = anon_inode_inode->i_mapping;
 
        file->f_pos = 0;
        file->f_flags = O_RDWR;
-       file->f_op = fops;
-       file->f_mode = FMODE_READ | FMODE_WRITE;
        file->f_version = 0;
        file->private_data = priv;
 
@@ -132,10 +130,10 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
        *pfile = file;
        return 0;
 
+err_dput:
+       dput(dentry);
 err_put_unused_fd:
        put_unused_fd(fd);
-err_put_filp:
-       put_filp(file);
        return error;
 }
 EXPORT_SYMBOL_GPL(anon_inode_getfd);
index 6d27befe2d48ff5fbb13a45c5cd86618777bbbd9..986ff4ed0a7cbf56d258b290635c32203284c565 100644 (file)
@@ -83,6 +83,12 @@ int proc_nr_files(ctl_table *table, int write, struct file *filp,
 /* Find an unused file structure and return a pointer to it.
  * Returns NULL, if there are no more free file structures or
  * we run out of memory.
+ *
+ * Be very careful using this.  You are responsible for
+ * getting write access to any mount that you might assign
+ * to this filp, if it is opened for write.  If this is not
+ * done, you will imbalance int the mount's writer count
+ * and a warning at __fput() time.
  */
 struct file *get_empty_filp(void)
 {
index a1e1f0f61aa5b750971cc81f7369541ed95c0ad0..8601d8ef3b550d1c803c3a5bb7cd37f831717fd2 100644 (file)
@@ -1,23 +1,24 @@
 /*
- * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
+ * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  * Licensed under the GPL
  */
 
-#include <linux/fs.h>
+#include <linux/ctype.h>
+#include <linux/dcache.h>
 #include <linux/file.h>
-#include <linux/module.h>
+#include <linux/fs.h>
 #include <linux/init.h>
-#include <linux/slab.h>
-#include <linux/list.h>
 #include <linux/kernel.h>
-#include <linux/ctype.h>
-#include <linux/dcache.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mount.h>
+#include <linux/slab.h>
 #include <linux/statfs.h>
+#include <linux/types.h>
 #include <asm/uaccess.h>
-#include <asm/fcntl.h>
 #include "os.h"
 
-static int init_inode(struct inode *inode, struct dentry *dentry);
+static struct inode *get_inode(struct super_block *, struct dentry *);
 
 struct hppfs_data {
        struct list_head list;
@@ -51,14 +52,14 @@ static int is_pid(struct dentry *dentry)
        int i;
 
        sb = dentry->d_sb;
-       if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
-               return(0);
+       if ((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
+               return 0;
 
-       for(i = 0; i < dentry->d_name.len; i++){
-               if(!isdigit(dentry->d_name.name[i]))
-                       return(0);
+       for (i = 0; i < dentry->d_name.len; i++) {
+               if (!isdigit(dentry->d_name.name[i]))
+                       return 0;
        }
-       return(1);
+       return 1;
 }
 
 static char *dentry_name(struct dentry *dentry, int extra)
@@ -70,8 +71,8 @@ static char *dentry_name(struct dentry *dentry, int extra)
 
        len = 0;
        parent = dentry;
-       while(parent->d_parent != parent){
-               if(is_pid(parent))
+       while (parent->d_parent != parent) {
+               if (is_pid(parent))
                        len += strlen("pid") + 1;
                else len += parent->d_name.len + 1;
                parent = parent->d_parent;
@@ -80,12 +81,13 @@ static char *dentry_name(struct dentry *dentry, int extra)
        root = "proc";
        len += strlen(root);
        name = kmalloc(len + extra + 1, GFP_KERNEL);
-       if(name == NULL) return(NULL);
+       if (name == NULL)
+               return NULL;
 
        name[len] = '\0';
        parent = dentry;
-       while(parent->d_parent != parent){
-               if(is_pid(parent)){
+       while (parent->d_parent != parent) {
+               if (is_pid(parent)) {
                        seg_name = "pid";
                        seg_len = strlen("pid");
                }
@@ -100,27 +102,25 @@ static char *dentry_name(struct dentry *dentry, int extra)
                parent = parent->d_parent;
        }
        strncpy(name, root, strlen(root));
-       return(name);
+       return name;
 }
 
-struct dentry_operations hppfs_dentry_ops = {
-};
-
 static int file_removed(struct dentry *dentry, const char *file)
 {
        char *host_file;
        int extra, fd;
 
        extra = 0;
-       if(file != NULL) extra += strlen(file) + 1;
+       if (file != NULL)
+               extra += strlen(file) + 1;
 
        host_file = dentry_name(dentry, extra + strlen("/remove"));
-       if(host_file == NULL){
-               printk("file_removed : allocation failed\n");
-               return(-ENOMEM);
+       if (host_file == NULL) {
+               printk(KERN_ERR "file_removed : allocation failed\n");
+               return -ENOMEM;
        }
 
-       if(file != NULL){
+       if (file != NULL) {
                strcat(host_file, "/");
                strcat(host_file, file);
        }
@@ -128,45 +128,11 @@ static int file_removed(struct dentry *dentry, const char *file)
 
        fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
        kfree(host_file);
-       if(fd > 0){
+       if (fd > 0) {
                os_close_file(fd);
-               return(1);
-       }
-       return(0);
-}
-
-static void hppfs_read_inode(struct inode *ino)
-{
-       struct inode *proc_ino;
-
-       if(HPPFS_I(ino)->proc_dentry == NULL)
-               return;
-
-       proc_ino = HPPFS_I(ino)->proc_dentry->d_inode;
-       ino->i_uid = proc_ino->i_uid;
-       ino->i_gid = proc_ino->i_gid;
-       ino->i_atime = proc_ino->i_atime;
-       ino->i_mtime = proc_ino->i_mtime;
-       ino->i_ctime = proc_ino->i_ctime;
-       ino->i_ino = proc_ino->i_ino;
-       ino->i_mode = proc_ino->i_mode;
-       ino->i_nlink = proc_ino->i_nlink;
-       ino->i_size = proc_ino->i_size;
-       ino->i_blocks = proc_ino->i_blocks;
-}
-
-static struct inode *hppfs_iget(struct super_block *sb)
-{
-       struct inode *inode;
-
-       inode = iget_locked(sb, 0);
-       if (!inode)
-               return ERR_PTR(-ENOMEM);
-       if (inode->i_state & I_NEW) {
-               hppfs_read_inode(inode);
-               unlock_new_inode(inode);
+               return 1;
        }
-       return inode;
+       return 0;
 }
 
 static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
@@ -177,55 +143,45 @@ static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
        int err, deleted;
 
        deleted = file_removed(dentry, NULL);
-       if(deleted < 0)
-               return(ERR_PTR(deleted));
-       else if(deleted)
-               return(ERR_PTR(-ENOENT));
+       if (deleted < 0)
+               return ERR_PTR(deleted);
+       else if (deleted)
+               return ERR_PTR(-ENOENT);
 
        err = -ENOMEM;
        parent = HPPFS_I(ino)->proc_dentry;
        mutex_lock(&parent->d_inode->i_mutex);
        proc_dentry = d_lookup(parent, &dentry->d_name);
-       if(proc_dentry == NULL){
+       if (proc_dentry == NULL) {
                proc_dentry = d_alloc(parent, &dentry->d_name);
-               if(proc_dentry == NULL){
+               if (proc_dentry == NULL) {
                        mutex_unlock(&parent->d_inode->i_mutex);
                        goto out;
                }
                new = (*parent->d_inode->i_op->lookup)(parent->d_inode,
                                                       proc_dentry, NULL);
-               if(new){
+               if (new) {
                        dput(proc_dentry);
                        proc_dentry = new;
                }
        }
        mutex_unlock(&parent->d_inode->i_mutex);
 
-       if(IS_ERR(proc_dentry))
-               return(proc_dentry);
+       if (IS_ERR(proc_dentry))
+               return proc_dentry;
 
-       inode = hppfs_iget(ino->i_sb);
-       if (IS_ERR(inode)) {
-               err = PTR_ERR(inode);
+       err = -ENOMEM;
+       inode = get_inode(ino->i_sb, proc_dentry);
+       if (!inode)
                goto out_dput;
-       }
-
-       err = init_inode(inode, proc_dentry);
-       if(err)
-               goto out_put;
-
-       hppfs_read_inode(inode);
 
        d_add(dentry, inode);
-       dentry->d_op = &hppfs_dentry_ops;
-       return(NULL);
+       return NULL;
 
- out_put:
-       iput(inode);
  out_dput:
        dput(proc_dentry);
  out:
-       return(ERR_PTR(err));
+       return ERR_PTR(err);
 }
 
 static const struct inode_operations hppfs_file_iops = {
@@ -239,15 +195,16 @@ static ssize_t read_proc(struct file *file, char __user *buf, ssize_t count,
 
        read = file->f_path.dentry->d_inode->i_fop->read;
 
-       if(!is_user)
+       if (!is_user)
                set_fs(KERNEL_DS);
 
        n = (*read)(file, buf, count, &file->f_pos);
 
-       if(!is_user)
+       if (!is_user)
                set_fs(USER_DS);
 
-       if(ppos) *ppos = file->f_pos;
+       if (ppos)
+               *ppos = file->f_pos;
        return n;
 }
 
@@ -259,24 +216,23 @@ static ssize_t hppfs_read_file(int fd, char __user *buf, ssize_t count)
 
        n = -ENOMEM;
        new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
-       if(new_buf == NULL){
-               printk("hppfs_read_file : kmalloc failed\n");
+       if (new_buf == NULL) {
+               printk(KERN_ERR "hppfs_read_file : kmalloc failed\n");
                goto out;
        }
        n = 0;
-       while(count > 0){
+       while (count > 0) {
                cur = min_t(ssize_t, count, PAGE_SIZE);
                err = os_read_file(fd, new_buf, cur);
-               if(err < 0){
-                       printk("hppfs_read : read failed, errno = %d\n",
-                              err);
+               if (err < 0) {
+                       printk(KERN_ERR "hppfs_read : read failed, "
+                              "errno = %d\n", err);
                        n = err;
                        goto out_free;
-               }
-               else if(err == 0)
+               } else if (err == 0)
                        break;
 
-               if(copy_to_user(buf, new_buf, err)){
+               if (copy_to_user(buf, new_buf, err)) {
                        n = -EFAULT;
                        goto out_free;
                }
@@ -297,35 +253,36 @@ static ssize_t hppfs_read(struct file *file, char __user *buf, size_t count,
        loff_t off;
        int err;
 
-       if(hppfs->contents != NULL){
-               if(*ppos >= hppfs->len) return(0);
+       if (hppfs->contents != NULL) {
+               if (*ppos >= hppfs->len)
+                       return 0;
 
                data = hppfs->contents;
                off = *ppos;
-               while(off >= sizeof(data->contents)){
+               while (off >= sizeof(data->contents)) {
                        data = list_entry(data->list.next, struct hppfs_data,
                                          list);
                        off -= sizeof(data->contents);
                }
 
-               if(off + count > hppfs->len)
+               if (off + count > hppfs->len)
                        count = hppfs->len - off;
                copy_to_user(buf, &data->contents[off], count);
                *ppos += count;
-       }
-       else if(hppfs->host_fd != -1){
+       } else if (hppfs->host_fd != -1) {
                err = os_seek_file(hppfs->host_fd, *ppos);
-               if(err){
-                       printk("hppfs_read : seek failed, errno = %d\n", err);
-                       return(err);
+               if (err) {
+                       printk(KERN_ERR "hppfs_read : seek failed, "
+                              "errno = %d\n", err);
+                       return err;
                }
                count = hppfs_read_file(hppfs->host_fd, buf, count);
-               if(count > 0)
+               if (count > 0)
                        *ppos += count;
        }
        else count = read_proc(hppfs->proc_file, buf, count, ppos, 1);
 
-       return(count);
+       return count;
 }
 
 static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len,
@@ -342,7 +299,7 @@ static ssize_t hppfs_write(struct file *file, const char __user *buf, size_t len
        err = (*write)(proc_file, buf, len, &proc_file->f_pos);
        file->f_pos = proc_file->f_pos;
 
-       return(err);
+       return err;
 }
 
 static int open_host_sock(char *host_file, int *filter_out)
@@ -354,13 +311,13 @@ static int open_host_sock(char *host_file, int *filter_out)
        strcpy(end, "/rw");
        *filter_out = 1;
        fd = os_connect_socket(host_file);
-       if(fd > 0)
-               return(fd);
+       if (fd > 0)
+               return fd;
 
        strcpy(end, "/r");
        *filter_out = 0;
        fd = os_connect_socket(host_file);
-       return(fd);
+       return fd;
 }
 
 static void free_contents(struct hppfs_data *head)
@@ -368,9 +325,10 @@ static void free_contents(struct hppfs_data *head)
        struct hppfs_data *data;
        struct list_head *ele, *next;
 
-       if(head == NULL) return;
+       if (head == NULL)
+               return;
 
-       list_for_each_safe(ele, next, &head->list){
+       list_for_each_safe(ele, next, &head->list) {
                data = list_entry(ele, struct hppfs_data, list);
                kfree(data);
        }
@@ -387,8 +345,8 @@ static struct hppfs_data *hppfs_get_data(int fd, int filter,
 
        err = -ENOMEM;
        data = kmalloc(sizeof(*data), GFP_KERNEL);
-       if(data == NULL){
-               printk("hppfs_get_data : head allocation failed\n");
+       if (data == NULL) {
+               printk(KERN_ERR "hppfs_get_data : head allocation failed\n");
                goto failed;
        }
 
@@ -397,36 +355,36 @@ static struct hppfs_data *hppfs_get_data(int fd, int filter,
        head = data;
        *size_out = 0;
 
-       if(filter){
-               while((n = read_proc(proc_file, data->contents,
+       if (filter) {
+               while ((n = read_proc(proc_file, data->contents,
                                     sizeof(data->contents), NULL, 0)) > 0)
                        os_write_file(fd, data->contents, n);
                err = os_shutdown_socket(fd, 0, 1);
-               if(err){
-                       printk("hppfs_get_data : failed to shut down "
+               if (err) {
+                       printk(KERN_ERR "hppfs_get_data : failed to shut down "
                               "socket\n");
                        goto failed_free;
                }
        }
-       while(1){
+       while (1) {
                n = os_read_file(fd, data->contents, sizeof(data->contents));
-               if(n < 0){
+               if (n < 0) {
                        err = n;
-                       printk("hppfs_get_data : read failed, errno = %d\n",
-                              err);
+                       printk(KERN_ERR "hppfs_get_data : read failed, "
+                              "errno = %d\n", err);
                        goto failed_free;
-               }
-               else if(n == 0)
+               } else if (n == 0)
                        break;
 
                *size_out += n;
 
-               if(n < sizeof(data->contents))
+               if (n < sizeof(data->contents))
                        break;
 
                new = kmalloc(sizeof(*data), GFP_KERNEL);
-               if(new == 0){
-                       printk("hppfs_get_data : data allocation failed\n");
+               if (new == 0) {
+                       printk(KERN_ERR "hppfs_get_data : data allocation "
+                              "failed\n");
                        err = -ENOMEM;
                        goto failed_free;
                }
@@ -435,12 +393,12 @@ static struct hppfs_data *hppfs_get_data(int fd, int filter,
                list_add(&new->list, &data->list);
                data = new;
        }
-       return(head);
+       return head;
 
  failed_free:
        free_contents(head);
  failed:
-       return(ERR_PTR(err));
+       return ERR_PTR(err);
 }
 
 static struct hppfs_private *hppfs_data(void)
@@ -448,77 +406,79 @@ static struct hppfs_private *hppfs_data(void)
        struct hppfs_private *data;
 
        data = kmalloc(sizeof(*data), GFP_KERNEL);
-       if(data == NULL)
-               return(data);
+       if (data == NULL)
+               return data;
 
        *data = ((struct hppfs_private ) { .host_fd             = -1,
                                           .len                 = -1,
                                           .contents            = NULL } );
-       return(data);
+       return data;
 }
 
 static int file_mode(int fmode)
 {
-       if(fmode == (FMODE_READ | FMODE_WRITE))
-               return(O_RDWR);
-       if(fmode == FMODE_READ)
-               return(O_RDONLY);
-       if(fmode == FMODE_WRITE)
-               return(O_WRONLY);
-       return(0);
+       if (fmode == (FMODE_READ | FMODE_WRITE))
+               return O_RDWR;
+       if (fmode == FMODE_READ)
+               return O_RDONLY;
+       if (fmode == FMODE_WRITE)
+               return O_WRONLY;
+       return 0;
 }
 
 static int hppfs_open(struct inode *inode, struct file *file)
 {
        struct hppfs_private *data;
        struct dentry *proc_dentry;
+       struct vfsmount *proc_mnt;
        char *host_file;
        int err, fd, type, filter;
 
        err = -ENOMEM;
        data = hppfs_data();
-       if(data == NULL)
+       if (data == NULL)
                goto out;
 
        host_file = dentry_name(file->f_path.dentry, strlen("/rw"));
-       if(host_file == NULL)
+       if (host_file == NULL)
                goto out_free2;
 
        proc_dentry = HPPFS_I(inode)->proc_dentry;
+       proc_mnt = inode->i_sb->s_fs_info;
 
        /* XXX This isn't closed anywhere */
-       data->proc_file = dentry_open(dget(proc_dentry), NULL,
+       data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
                                      file_mode(file->f_mode));
        err = PTR_ERR(data->proc_file);
-       if(IS_ERR(data->proc_file))
+       if (IS_ERR(data->proc_file))
                goto out_free1;
 
        type = os_file_type(host_file);
-       if(type == OS_TYPE_FILE){
+       if (type == OS_TYPE_FILE) {
                fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
-               if(fd >= 0)
+               if (fd >= 0)
                        data->host_fd = fd;
-               else printk("hppfs_open : failed to open '%s', errno = %d\n",
-                           host_file, -fd);
+               else
+                       printk(KERN_ERR "hppfs_open : failed to open '%s', "
+                              "errno = %d\n", host_file, -fd);
 
                data->contents = NULL;
-       }
-       else if(type == OS_TYPE_DIR){
+       } else if (type == OS_TYPE_DIR) {
                fd = open_host_sock(host_file, &filter);
-               if(fd > 0){
+               if (fd > 0) {
                        data->contents = hppfs_get_data(fd, filter,
                                                        data->proc_file,
                                                        file, &data->len);
-                       if(!IS_ERR(data->contents))
+                       if (!IS_ERR(data->contents))
                                data->host_fd = fd;
-               }
-               else printk("hppfs_open : failed to open a socket in "
-                           "'%s', errno = %d\n", host_file, -fd);
+               } else
+                       printk(KERN_ERR "hppfs_open : failed to open a socket "
+                              "in '%s', errno = %d\n", host_file, -fd);
        }
        kfree(host_file);
 
        file->private_data = data;
-       return(0);
+       return 0;
 
  out_free1:
        kfree(host_file);
@@ -526,34 +486,36 @@ static int hppfs_open(struct inode *inode, struct file *file)
        free_contents(data->contents);
        kfree(data);
  out:
-       return(err);
+       return err;
 }
 
 static int hppfs_dir_open(struct inode *inode, struct file *file)
 {
        struct hppfs_private *data;
        struct dentry *proc_dentry;
+       struct vfsmount *proc_mnt;
        int err;
 
        err = -ENOMEM;
        data = hppfs_data();
-       if(data == NULL)
+       if (data == NULL)
                goto out;
 
        proc_dentry = HPPFS_I(inode)->proc_dentry;
-       data->proc_file = dentry_open(dget(proc_dentry), NULL,
+       proc_mnt = inode->i_sb->s_fs_info;
+       data->proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt),
                                      file_mode(file->f_mode));
        err = PTR_ERR(data->proc_file);
-       if(IS_ERR(data->proc_file))
+       if (IS_ERR(data->proc_file))
                goto out_free;
 
        file->private_data = data;
-       return(0);
+       return 0;
 
  out_free:
        kfree(data);
  out:
-       return(err);
+       return err;
 }
 
 static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
@@ -564,13 +526,13 @@ static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
        loff_t ret;
 
        llseek = proc_file->f_path.dentry->d_inode->i_fop->llseek;
-       if(llseek != NULL){
+       if (llseek != NULL) {
                ret = (*llseek)(proc_file, off, where);
-               if(ret < 0)
-                       return(ret);
+               if (ret < 0)
+                       return ret;
        }
 
-       return(default_llseek(file, off, where));
+       return default_llseek(file, off, where);
 }
 
 static const struct file_operations hppfs_file_fops = {
@@ -592,11 +554,11 @@ static int hppfs_filldir(void *d, const char *name, int size,
 {
        struct hppfs_dirent *dirent = d;
 
-       if(file_removed(dirent->dentry, name))
-               return(0);
+       if (file_removed(dirent->dentry, name))
+               return 0;
 
-       return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
-                                 inode, type));
+       return (*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
+                                 inode, type);
 }
 
 static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
@@ -607,7 +569,8 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
        struct hppfs_dirent dirent = ((struct hppfs_dirent)
                                      { .vfs_dirent     = ent,
                                        .filldir        = filldir,
-                                       .dentry         = file->f_path.dentry } );
+                                       .dentry         = file->f_path.dentry
+                                     });
        int err;
 
        readdir = proc_file->f_path.dentry->d_inode->i_fop->readdir;
@@ -616,12 +579,12 @@ static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
        err = (*readdir)(proc_file, &dirent, hppfs_filldir);
        file->f_pos = proc_file->f_pos;
 
-       return(err);
+       return err;
 }
 
 static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
 {
-       return(0);
+       return 0;
 }
 
 static const struct file_operations hppfs_dir_fops = {
@@ -639,7 +602,7 @@ static int hppfs_statfs(struct dentry *dentry, struct kstatfs *sf)
        sf->f_files = 0;
        sf->f_ffree = 0;
        sf->f_type = HPPFS_SUPER_MAGIC;
-       return(0);
+       return 0;
 }
 
 static struct inode *hppfs_alloc_inode(struct super_block *sb)
@@ -647,12 +610,12 @@ static struct inode *hppfs_alloc_inode(struct super_block *sb)
        struct hppfs_inode_info *hi;
 
        hi = kmalloc(sizeof(*hi), GFP_KERNEL);
-       if(hi == NULL)
-               return(NULL);
+       if (!hi)
+               return NULL;
 
-       *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
+       hi->proc_dentry = NULL;
        inode_init_once(&hi->vfs_inode);
-       return(&hi->vfs_inode);
+       return &hi->vfs_inode;
 }
 
 void hppfs_delete_inode(struct inode *ino)
@@ -665,21 +628,31 @@ static void hppfs_destroy_inode(struct inode *inode)
        kfree(HPPFS_I(inode));
 }
 
+static void hppfs_put_super(struct super_block *sb)
+{
+       mntput(sb->s_fs_info);
+}
+
 static const struct super_operations hppfs_sbops = {
        .alloc_inode    = hppfs_alloc_inode,
        .destroy_inode  = hppfs_destroy_inode,
        .delete_inode   = hppfs_delete_inode,
        .statfs         = hppfs_statfs,
+       .put_super      = hppfs_put_super,
 };
 
-static int hppfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
+static int hppfs_readlink(struct dentry *dentry, char __user *buffer,
+                         int buflen)
 {
        struct file *proc_file;
        struct dentry *proc_dentry;
+       struct vfsmount *proc_mnt;
        int ret;
 
        proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
-       proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY);
+       proc_mnt = dentry->d_sb->s_fs_info;
+
+       proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
        if (IS_ERR(proc_file))
                return PTR_ERR(proc_file);
 
@@ -694,10 +667,13 @@ static void* hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
 {
        struct file *proc_file;
        struct dentry *proc_dentry;
+       struct vfsmount *proc_mnt;
        void *ret;
 
        proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
-       proc_file = dentry_open(dget(proc_dentry), NULL, O_RDONLY);
+       proc_mnt = dentry->d_sb->s_fs_info;
+
+       proc_file = dentry_open(dget(proc_dentry), mntget(proc_mnt), O_RDONLY);
        if (IS_ERR(proc_file))
                return proc_file;
 
@@ -717,70 +693,72 @@ static const struct inode_operations hppfs_link_iops = {
        .follow_link    = hppfs_follow_link,
 };
 
-static int init_inode(struct inode *inode, struct dentry *dentry)
+static struct inode *get_inode(struct super_block *sb, struct dentry *dentry)
 {
-       if(S_ISDIR(dentry->d_inode->i_mode)){
+       struct inode *proc_ino = dentry->d_inode;
+       struct inode *inode = new_inode(sb);
+
+       if (!inode)
+               return ERR_PTR(-ENOMEM);
+
+       if (S_ISDIR(dentry->d_inode->i_mode)) {
                inode->i_op = &hppfs_dir_iops;
                inode->i_fop = &hppfs_dir_fops;
-       }
-       else if(S_ISLNK(dentry->d_inode->i_mode)){
+       } else if (S_ISLNK(dentry->d_inode->i_mode)) {
                inode->i_op = &hppfs_link_iops;
                inode->i_fop = &hppfs_file_fops;
-       }
-       else {
+       } else {
                inode->i_op = &hppfs_file_iops;
                inode->i_fop = &hppfs_file_fops;
        }
 
        HPPFS_I(inode)->proc_dentry = dentry;
 
-       return(0);
+       inode->i_uid = proc_ino->i_uid;
+       inode->i_gid = proc_ino->i_gid;
+       inode->i_atime = proc_ino->i_atime;
+       inode->i_mtime = proc_ino->i_mtime;
+       inode->i_ctime = proc_ino->i_ctime;
+       inode->i_ino = proc_ino->i_ino;
+       inode->i_mode = proc_ino->i_mode;
+       inode->i_nlink = proc_ino->i_nlink;
+       inode->i_size = proc_ino->i_size;
+       inode->i_blocks = proc_ino->i_blocks;
+
+       return 0;
 }
 
 static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
 {
        struct inode *root_inode;
-       struct file_system_type *procfs;
-       struct super_block *proc_sb;
-       int err;
+       struct vfsmount *proc_mnt;
+       int err = -ENOENT;
 
-       err = -ENOENT;
-       procfs = get_fs_type("proc");
-       if(procfs == NULL)
+       proc_mnt = do_kern_mount("proc", 0, "proc", NULL);
+       if (IS_ERR(proc_mnt))
                goto out;
 
-       if(list_empty(&procfs->fs_supers))
-               goto out;
-
-       proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
-                            s_instances);
-
        sb->s_blocksize = 1024;
        sb->s_blocksize_bits = 10;
        sb->s_magic = HPPFS_SUPER_MAGIC;
        sb->s_op = &hppfs_sbops;
-
-       root_inode = hppfs_iget(sb);
-       if (IS_ERR(root_inode)) {
-               err = PTR_ERR(root_inode);
-               goto out;
-       }
-
-       err = init_inode(root_inode, proc_sb->s_root);
-       if(err)
-               goto out_put;
+       sb->s_fs_info = proc_mnt;
 
        err = -ENOMEM;
-       sb->s_root = d_alloc_root(root_inode);
-       if(sb->s_root == NULL)
-               goto out_put;
+       root_inode = get_inode(sb, proc_mnt->mnt_sb->s_root);
+       if (!root_inode)
+               goto out_mntput;
 
-       hppfs_read_inode(root_inode);
+       sb->s_root = d_alloc_root(root_inode);
+       if (!sb->s_root)
+               goto out_iput;
 
-       return(0);
+       return 0;
 
- out_put:
+ out_iput:
        iput(root_inode);
+ out_mntput:
+       mntput(proc_mnt);
  out:
        return(err);
 }
@@ -802,7 +780,7 @@ static struct file_system_type hppfs_type = {
 
 static int __init init_hppfs(void)
 {
-       return(register_filesystem(&hppfs_type));
+       return register_filesystem(&hppfs_type);
 }
 
 static void __exit exit_hppfs(void)
@@ -813,14 +791,3 @@ static void __exit exit_hppfs(void)
 module_init(init_hppfs)
 module_exit(exit_hppfs)
 MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-file-style: "linux"
- * End:
- */
index eee9487ae47fb78a12ffd92a4adaa6e185fbe085..6846785fe9043b48279bc04c44328d0264e48197 100644 (file)
@@ -954,7 +954,7 @@ struct file *hugetlb_file_setup(const char *name, size_t size)
                        FMODE_WRITE | FMODE_READ,
                        &hugetlbfs_file_operations);
        if (!file)
-               goto out_inode;
+               goto out_dentry; /* inode is already attached */
 
        return file;
 
index 6b7a0eef409076abca4a3383bd1c177595aff2ec..8cf9bb9c2fc0b0133d85f0f6ff0f3e35a9fb8e07 100644 (file)
  * any extra contention...
  */
 
-static int link_path_walk(const char *name, struct nameidata *nd);
+static int __link_path_walk(const char *name, struct nameidata *nd);
 
 /* In order to reduce some races, while at the same time doing additional
  * checking and hopefully speeding things up, we copy filenames to the
@@ -563,6 +563,37 @@ walk_init_root(const char *name, struct nameidata *nd)
        return 1;
 }
 
+/*
+ * Wrapper to retry pathname resolution whenever the underlying
+ * file system returns an ESTALE.
+ *
+ * Retry the whole path once, forcing real lookup requests
+ * instead of relying on the dcache.
+ */
+static __always_inline int link_path_walk(const char *name, struct nameidata *nd)
+{
+       struct path save = nd->path;
+       int result;
+
+       /* make sure the stuff we saved doesn't go away */
+       dget(save.dentry);
+       mntget(save.mnt);
+
+       result = __link_path_walk(name, nd);
+       if (result == -ESTALE) {
+               /* nd->path had been dropped */
+               nd->path = save;
+               dget(nd->path.dentry);
+               mntget(nd->path.mnt);
+               nd->flags |= LOOKUP_REVAL;
+               result = __link_path_walk(name, nd);
+       }
+
+       path_put(&save);
+
+       return result;
+}
+
 static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
 {
        int res = 0;
@@ -1020,36 +1051,6 @@ return_err:
        return err;
 }
 
-/*
- * Wrapper to retry pathname resolution whenever the underlying
- * file system returns an ESTALE.
- *
- * Retry the whole path once, forcing real lookup requests
- * instead of relying on the dcache.
- */
-static int link_path_walk(const char *name, struct nameidata *nd)
-{
-       struct nameidata save = *nd;
-       int result;
-
-       /* make sure the stuff we saved doesn't go away */
-       dget(save.path.dentry);
-       mntget(save.path.mnt);
-
-       result = __link_path_walk(name, nd);
-       if (result == -ESTALE) {
-               *nd = save;
-               dget(nd->path.dentry);
-               mntget(nd->path.mnt);
-               nd->flags |= LOOKUP_REVAL;
-               result = __link_path_walk(name, nd);
-       }
-
-       path_put(&save.path);
-
-       return result;
-}
-
 static int path_walk(const char *name, struct nameidata *nd)
 {
        current->total_link_count = 0;
index 54198538b67e7a285fadcc4a8eb905cfe32f4864..a4b12022edaa27cb8cd3ea865d14f1368d507660 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -903,6 +903,18 @@ struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags)
        int error;
        struct file *f;
 
+       /*
+        * We must always pass in a valid mount pointer.   Historically
+        * callers got away with not passing it, but we must enforce this at
+        * the earliest possible point now to avoid strange problems deep in the
+        * filesystem stack.
+        */
+       if (!mnt) {
+               printk(KERN_WARNING "%s called with NULL vfsmount\n", __func__);
+               dump_stack();
+               return ERR_PTR(-EINVAL);
+       }
+
        error = -ENFILE;
        f = get_empty_filp();
        if (f == NULL) {
index 3c185b6527bca9eb650ca21c455c29767e23c7ab..8be381bbcb54ad4108ea3bf453b19afd702314b5 100644 (file)
--- a/fs/pipe.c
+++ b/fs/pipe.c
@@ -957,13 +957,10 @@ struct file *create_write_pipe(void)
        struct dentry *dentry;
        struct qstr name = { .name = "" };
 
-       f = get_empty_filp();
-       if (!f)
-               return ERR_PTR(-ENFILE);
        err = -ENFILE;
        inode = get_pipe_inode();
        if (!inode)
-               goto err_file;
+               goto err;
 
        err = -ENOMEM;
        dentry = d_alloc(pipe_mnt->mnt_sb->s_root, &name);
@@ -978,22 +975,24 @@ struct file *create_write_pipe(void)
         */
        dentry->d_flags &= ~DCACHE_UNHASHED;
        d_instantiate(dentry, inode);
-       f->f_path.mnt = mntget(pipe_mnt);
-       f->f_path.dentry = dentry;
+
+       err = -ENFILE;
+       f = alloc_file(pipe_mnt, dentry, FMODE_WRITE, &write_pipe_fops);
+       if (!f)
+               goto err_dentry;
        f->f_mapping = inode->i_mapping;
 
        f->f_flags = O_WRONLY;
-       f->f_op = &write_pipe_fops;
-       f->f_mode = FMODE_WRITE;
        f->f_version = 0;
 
        return f;
 
+ err_dentry:
+       dput(dentry);
  err_inode:
        free_pipe_info(inode);
        iput(inode);
- err_file:
-       put_filp(f);
+ err:
        return ERR_PTR(err);
 }
 
index eba037b3338fe8c2c480318d38441d3de65aab51..344b9b96cc56ecd10f0612300e844948b0892d90 100644 (file)
@@ -191,28 +191,11 @@ static struct dentry *get_xa_file_dentry(const struct inode *inode,
        dput(xadir);
        if (err)
                xafile = ERR_PTR(err);
-       return xafile;
-}
-
-/* Opens a file pointer to the attribute associated with inode */
-static struct file *open_xa_file(const struct inode *inode, const char *name,
-                                int flags)
-{
-       struct dentry *xafile;
-       struct file *fp;
-
-       xafile = get_xa_file_dentry(inode, name, flags);
-       if (IS_ERR(xafile))
-               return ERR_PTR(PTR_ERR(xafile));
        else if (!xafile->d_inode) {
                dput(xafile);
-               return ERR_PTR(-ENODATA);
+               xafile = ERR_PTR(-ENODATA);
        }
-
-       fp = dentry_open(xafile, NULL, O_RDWR);
-       /* dentry_open dputs the dentry if it fails */
-
-       return fp;
+       return xafile;
 }
 
 /*
@@ -228,9 +211,8 @@ static struct file *open_xa_file(const struct inode *inode, const char *name,
  * we're called with i_mutex held, so there are no worries about the directory
  * changing underneath us.
  */
-static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)
+static int __xattr_readdir(struct inode *inode, void *dirent, filldir_t filldir)
 {
-       struct inode *inode = filp->f_path.dentry->d_inode;
        struct cpu_key pos_key; /* key of current position in the directory (key of directory entry) */
        INITIALIZE_PATH(path_to_entry);
        struct buffer_head *bh;
@@ -374,23 +356,16 @@ static int __xattr_readdir(struct file *filp, void *dirent, filldir_t filldir)
  *
  */
 static
-int xattr_readdir(struct file *file, filldir_t filler, void *buf)
+int xattr_readdir(struct inode *inode, filldir_t filler, void *buf)
 {
-       struct inode *inode = file->f_path.dentry->d_inode;
-       int res = -ENOTDIR;
-       if (!file->f_op || !file->f_op->readdir)
-               goto out;
+       int res = -ENOENT;
        mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR);
-//        down(&inode->i_zombie);
-       res = -ENOENT;
        if (!IS_DEADDIR(inode)) {
                lock_kernel();
-               res = __xattr_readdir(file, buf, filler);
+               res = __xattr_readdir(inode, buf, filler);
                unlock_kernel();
        }
-//        up(&inode->i_zombie);
        mutex_unlock(&inode->i_mutex);
-      out:
        return res;
 }
 
@@ -442,7 +417,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
                   size_t buffer_size, int flags)
 {
        int err = 0;
-       struct file *fp;
+       struct dentry *dentry;
        struct page *page;
        char *data;
        struct address_space *mapping;
@@ -460,18 +435,18 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
                xahash = xattr_hash(buffer, buffer_size);
 
       open_file:
-       fp = open_xa_file(inode, name, flags);
-       if (IS_ERR(fp)) {
-               err = PTR_ERR(fp);
+       dentry = get_xa_file_dentry(inode, name, flags);
+       if (IS_ERR(dentry)) {
+               err = PTR_ERR(dentry);
                goto out;
        }
 
-       xinode = fp->f_path.dentry->d_inode;
+       xinode = dentry->d_inode;
        REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
 
        /* we need to copy it off.. */
        if (xinode->i_nlink > 1) {
-               fput(fp);
+               dput(dentry);
                err = reiserfs_xattr_del(inode, name);
                if (err < 0)
                        goto out;
@@ -485,7 +460,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
        newattrs.ia_size = buffer_size;
        newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
        mutex_lock_nested(&xinode->i_mutex, I_MUTEX_XATTR);
-       err = notify_change(fp->f_path.dentry, &newattrs);
+       err = notify_change(dentry, &newattrs);
        if (err)
                goto out_filp;
 
@@ -518,15 +493,14 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
                        rxh->h_hash = cpu_to_le32(xahash);
                }
 
-               err = reiserfs_prepare_write(fp, page, page_offset,
+               err = reiserfs_prepare_write(NULL, page, page_offset,
                                            page_offset + chunk + skip);
                if (!err) {
                        if (buffer)
                                memcpy(data + skip, buffer + buffer_pos, chunk);
-                       err =
-                           reiserfs_commit_write(fp, page, page_offset,
-                                                 page_offset + chunk +
-                                                 skip);
+                       err = reiserfs_commit_write(NULL, page, page_offset,
+                                                   page_offset + chunk +
+                                                   skip);
                }
                unlock_page(page);
                reiserfs_put_page(page);
@@ -548,7 +522,7 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
 
       out_filp:
        mutex_unlock(&xinode->i_mutex);
-       fput(fp);
+       dput(dentry);
 
       out:
        return err;
@@ -562,7 +536,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,
                   size_t buffer_size)
 {
        ssize_t err = 0;
-       struct file *fp;
+       struct dentry *dentry;
        size_t isize;
        size_t file_pos = 0;
        size_t buffer_pos = 0;
@@ -578,13 +552,13 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,
        if (get_inode_sd_version(inode) == STAT_DATA_V1)
                return -EOPNOTSUPP;
 
-       fp = open_xa_file(inode, name, FL_READONLY);
-       if (IS_ERR(fp)) {
-               err = PTR_ERR(fp);
+       dentry = get_xa_file_dentry(inode, name, FL_READONLY);
+       if (IS_ERR(dentry)) {
+               err = PTR_ERR(dentry);
                goto out;
        }
 
-       xinode = fp->f_path.dentry->d_inode;
+       xinode = dentry->d_inode;
        isize = xinode->i_size;
        REISERFS_I(inode)->i_flags |= i_has_xattr_dir;
 
@@ -652,7 +626,7 @@ reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,
        }
 
       out_dput:
-       fput(fp);
+       dput(dentry);
 
       out:
        return err;
@@ -742,7 +716,6 @@ reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
 /* This is called w/ inode->i_mutex downed */
 int reiserfs_delete_xattrs(struct inode *inode)
 {
-       struct file *fp;
        struct dentry *dir, *root;
        int err = 0;
 
@@ -763,15 +736,8 @@ int reiserfs_delete_xattrs(struct inode *inode)
                return 0;
        }
 
-       fp = dentry_open(dir, NULL, O_RDWR);
-       if (IS_ERR(fp)) {
-               err = PTR_ERR(fp);
-               /* dentry_open dputs the dentry if it fails */
-               goto out;
-       }
-
        lock_kernel();
-       err = xattr_readdir(fp, reiserfs_delete_xattrs_filler, dir);
+       err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir);
        if (err) {
                unlock_kernel();
                goto out_dir;
@@ -791,7 +757,7 @@ int reiserfs_delete_xattrs(struct inode *inode)
        unlock_kernel();
 
       out_dir:
-       fput(fp);
+       dput(dir);
 
       out:
        if (!err)
@@ -833,7 +799,6 @@ reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
 
 int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
 {
-       struct file *fp;
        struct dentry *dir;
        int err = 0;
        struct reiserfs_chown_buf buf;
@@ -857,13 +822,6 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
                goto out;
        }
 
-       fp = dentry_open(dir, NULL, O_RDWR);
-       if (IS_ERR(fp)) {
-               err = PTR_ERR(fp);
-               /* dentry_open dputs the dentry if it fails */
-               goto out;
-       }
-
        lock_kernel();
 
        attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
@@ -871,7 +829,7 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
        buf.attrs = attrs;
        buf.inode = inode;
 
-       err = xattr_readdir(fp, reiserfs_chown_xattrs_filler, &buf);
+       err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf);
        if (err) {
                unlock_kernel();
                goto out_dir;
@@ -881,7 +839,7 @@ int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
        unlock_kernel();
 
       out_dir:
-       fput(fp);
+       dput(dir);
 
       out:
        attrs->ia_valid = ia_valid;
@@ -1029,7 +987,6 @@ reiserfs_listxattr_filler(void *buf, const char *name, int namelen,
  */
 ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
 {
-       struct file *fp;
        struct dentry *dir;
        int err = 0;
        struct reiserfs_listxattr_buf buf;
@@ -1052,13 +1009,6 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
                goto out;
        }
 
-       fp = dentry_open(dir, NULL, O_RDWR);
-       if (IS_ERR(fp)) {
-               err = PTR_ERR(fp);
-               /* dentry_open dputs the dentry if it fails */
-               goto out;
-       }
-
        buf.r_buf = buffer;
        buf.r_size = buffer ? size : 0;
        buf.r_pos = 0;
@@ -1066,7 +1016,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
 
        REISERFS_I(dentry->d_inode)->i_flags |= i_has_xattr_dir;
 
-       err = xattr_readdir(fp, reiserfs_listxattr_filler, &buf);
+       err = xattr_readdir(dir->d_inode, reiserfs_listxattr_filler, &buf);
        if (err)
                goto out_dir;
 
@@ -1076,7 +1026,7 @@ ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
                err = buf.r_pos;
 
       out_dir:
-       fput(fp);
+       dput(dir);
 
       out:
        reiserfs_read_unlock_xattr_i(dentry->d_inode);
index d0a941a4e62007034a2367a5fbff27bc5571e851..09008dbd264e731411c6da60def6648888cc6b52 100644 (file)
@@ -945,6 +945,7 @@ do_kern_mount(const char *fstype, int flags, const char *name, void *data)
        put_filesystem(type);
        return mnt;
 }
+EXPORT_SYMBOL_GPL(do_kern_mount);
 
 struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
 {
index a271c87c4472d530bee00c35da17a06606dfc97c..baa663e69388aeb623aeb667f86ff12540b741e8 100644 (file)
@@ -12,6 +12,7 @@
 
 #include <linux/module.h>
 #include <linux/kobject.h>
+#include <linux/kallsyms.h>
 #include <linux/namei.h>
 #include <linux/poll.h>
 #include <linux/list.h>
@@ -86,7 +87,12 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer
         * The code works fine with PAGE_SIZE return but it's likely to
         * indicate truncated result or overflow in normal use cases.
         */
-       BUG_ON(count >= (ssize_t)PAGE_SIZE);
+       if (count >= (ssize_t)PAGE_SIZE) {
+               print_symbol("fill_read_buffer: %s returned bad count\n",
+                       (unsigned long)ops->show);
+               /* Try to struggle along */
+               count = PAGE_SIZE - 1;
+       }
        if (count >= 0) {
                buffer->needs_read_fill = 0;
                buffer->count = count;
index 402ff4125cdc25d570bf9f769045f6d17aa62b61..d77b48ba73387ba57ac932e5a6676d43b1c6a584 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 542421460a125f1edb80b5c136638be721aa1ff6..532975ecfe10c1b6720f48bf177632901f8cdb94 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 ecbed2ae548f4c8233acfc532d7e6de6d0a57800..0f704e106a1b97e07a8d4ea3d5ee8d27a9f9b945 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 30cb76b47be1a76f86385967e522df3662ae4ec4..0bb9bf531745e8caf587135f3cf3063f31d24a4c 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 3167ccff64f85977636559834937f971512044fd..549e45266b688ec2c2db083fb5581edad9cfbe3e 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 8da484c19822cc1d08d59d4fc635e06329ef2675..885b6a1dcae4d0b75df49cdc82df8e2035aa45a0 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 ccbd69448866f72cbc6daf331dc0953c8e09f575..5b779fd1f78828d123ea047164852b547263eeba 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 758b9a5d4539e583dd29efced39701e7ae1b64d0..f239e7069cabf3bfb9ea6bc92637c95fdec6bb04 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 db31b929b99084873bf3949f3a7c748fd66da870..acce0b7d397bb2465ee89beb6e8a7d817bccbc7a 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 838ba8f64fd3c6213c4af68dc4b225932c44306b..c8e9c8bed3d0783ec990effb2e0cdca2bcca2b0e 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 174b87738714fe634d135c8738df8a6f5ba8a0c5..9cf472aeb9ce5841185ac52131dc311123c9b6f6 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 6b72a458408639becc0f60508d30406093329fe3..51e6b1e520e6feeaefaf71d692be486a128d1d22 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 589be3e1f3ac5a7859587ff4b662e0f6c3167314..e7217dc58f398fb7e6d11897faf2e7ac3d0dbfae 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 a05f600136426c74455f2739169be4fec4c9497f..269cdba095789b94993b2b23d74fa1495c019e96 100644 (file)
@@ -463,6 +463,7 @@ struct ata_queued_cmd {
        unsigned int            sect_size;
 
        unsigned int            nbytes;
+       unsigned int            extrabytes;
        unsigned int            curbytes;
 
        struct scatterlist      *cursg;
@@ -1336,6 +1337,11 @@ static inline struct ata_queued_cmd *ata_qc_from_tag(struct ata_port *ap,
        return NULL;
 }
 
+static inline unsigned int ata_qc_raw_nbytes(struct ata_queued_cmd *qc)
+{
+       return qc->nbytes - min(qc->extrabytes, qc->nbytes);
+}
+
 static inline void ata_tf_init(struct ata_device *dev, struct ata_taskfile *tf)
 {
        memset(tf, 0, sizeof(*tf));
@@ -1354,7 +1360,7 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
        qc->flags = 0;
        qc->cursg = NULL;
        qc->cursg_ofs = 0;
-       qc->nbytes = qc->curbytes = 0;
+       qc->nbytes = qc->extrabytes = qc->curbytes = 0;
        qc->n_elem = 0;
        qc->err_mask = 0;
        qc->sect_size = ATA_SECT_SIZE;
index b7e4b633c69b002d85bda6c7baa6da8341b48d35..ea760e519c46398a4d93de42d585383627587478 100644 (file)
@@ -513,7 +513,6 @@ int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap);
 int pci_find_ext_capability(struct pci_dev *dev, int cap);
 int pci_find_ht_capability(struct pci_dev *dev, int ht_cap);
 int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap);
-void pcie_wait_pending_transaction(struct pci_dev *dev);
 struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
 
 struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
@@ -884,9 +883,6 @@ static inline int pci_find_ext_capability(struct pci_dev *dev, int cap)
        return 0;
 }
 
-static inline void pcie_wait_pending_transaction(struct pci_dev *dev)
-{ }
-
 /* Power management related routines */
 static inline int pci_save_state(struct pci_dev *dev)
 {
index fed07d03364e869df06d7f1405d23d75850fe2b7..6a1e7afb099bc981f91a23ac9698e7244bab4aa0 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 2692ec9389ca2047120f2b175b34076b88c0c049..1f999ec8d08c520c431d626e3bf5372e890c51a3 100644 (file)
@@ -9,3 +9,6 @@
 
 /* device can't resume correctly so reset it instead */
 #define USB_QUIRK_RESET_RESUME         0x00000002
+
+/* device can't handle Set-Interface requests */
+#define USB_QUIRK_NO_SET_INTF          0x00000004
index cee0623b3c7be52b17b2a47b5208b3528f13cf18..0a40dfa44c9f9a640524f03cecd2ef5261b1f78d 100644 (file)
@@ -50,7 +50,9 @@
        US_FLAG(CAPACITY_HEURISTICS,    0x00001000)             \
                /* sometimes sizes is too big */                \
        US_FLAG(MAX_SECTORS_MIN,0x00002000)                     \
-               /* Sets max_sectors to arch min */
+               /* Sets max_sectors to arch min */              \
+       US_FLAG(BULK_IGNORE_TAG,0x00004000)                     \
+               /* Ignore tag mismatch in bulk operations */
 
 
 #define US_FLAG(name, value)   US_FL_##name = value ,
index ebbfb509822e068a992c49ef7b2de6c5f92a617f..64a5f0120b528356de0bf5c2b9ddacb0c29330cd 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 619c53bc3cd20a7149374d729c2936163e37b727..0d255ae008b6f5510474954da780af5eaf079365 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 521dfa53cb999657ce8971494f1f573d88d55df7..91e1cfd734d286f922597108e54065ef691d31b2 100644 (file)
@@ -58,6 +58,7 @@
 #include <asm/uaccess.h>
 #include <asm/div64.h>
 #include <linux/blkdev.h> /* sector_div */
+#include <linux/pid_namespace.h>
 
 /*
  * These constants control the amount of freespace that suspend and
@@ -74,7 +75,7 @@ int acct_parm[3] = {4, 2, 30};
 /*
  * External references and all of the globals.
  */
-static void do_acct_process(struct file *);
+static void do_acct_process(struct pid_namespace *ns, struct file *);
 
 /*
  * This structure is used so that all the data protected by lock
@@ -86,6 +87,7 @@ struct acct_glbs {
        volatile int            active;
        volatile int            needcheck;
        struct file             *file;
+       struct pid_namespace    *ns;
        struct timer_list       timer;
 };
 
@@ -175,9 +177,11 @@ out:
 static void acct_file_reopen(struct file *file)
 {
        struct file *old_acct = NULL;
+       struct pid_namespace *old_ns = NULL;
 
        if (acct_globals.file) {
                old_acct = acct_globals.file;
+               old_ns = acct_globals.ns;
                del_timer(&acct_globals.timer);
                acct_globals.active = 0;
                acct_globals.needcheck = 0;
@@ -185,6 +189,7 @@ static void acct_file_reopen(struct file *file)
        }
        if (file) {
                acct_globals.file = file;
+               acct_globals.ns = get_pid_ns(task_active_pid_ns(current));
                acct_globals.needcheck = 0;
                acct_globals.active = 1;
                /* It's been deleted if it was used before so this is safe */
@@ -196,8 +201,9 @@ static void acct_file_reopen(struct file *file)
        if (old_acct) {
                mnt_unpin(old_acct->f_path.mnt);
                spin_unlock(&acct_globals.lock);
-               do_acct_process(old_acct);
+               do_acct_process(old_ns, old_acct);
                filp_close(old_acct, NULL);
+               put_pid_ns(old_ns);
                spin_lock(&acct_globals.lock);
        }
 }
@@ -419,7 +425,7 @@ static u32 encode_float(u64 value)
 /*
  *  do_acct_process does all actual work. Caller holds the reference to file.
  */
-static void do_acct_process(struct file *file)
+static void do_acct_process(struct pid_namespace *ns, struct file *file)
 {
        struct pacct_struct *pacct = &current->signal->pacct;
        acct_t ac;
@@ -481,8 +487,10 @@ static void do_acct_process(struct file *file)
        ac.ac_gid16 = current->gid;
 #endif
 #if ACCT_VERSION==3
-       ac.ac_pid = current->tgid;
-       ac.ac_ppid = current->real_parent->tgid;
+       ac.ac_pid = task_tgid_nr_ns(current, ns);
+       rcu_read_lock();
+       ac.ac_ppid = task_tgid_nr_ns(rcu_dereference(current->real_parent), ns);
+       rcu_read_unlock();
 #endif
 
        spin_lock_irq(&current->sighand->siglock);
@@ -578,6 +586,7 @@ void acct_collect(long exitcode, int group_dead)
 void acct_process(void)
 {
        struct file *file = NULL;
+       struct pid_namespace *ns;
 
        /*
         * accelerate the common fastpath:
@@ -592,8 +601,10 @@ void acct_process(void)
                return;
        }
        get_file(file);
+       ns = get_pid_ns(acct_globals.ns);
        spin_unlock(&acct_globals.lock);
 
-       do_acct_process(file);
+       do_acct_process(ns, file);
        fput(file);
+       put_pid_ns(ns);
 }
index 06968cd792005753688d094fc768152f2aaf3205..87a6428cb5b67363a23252628c6a03d8b2a789c8 100644 (file)
@@ -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 48a4ea5afffde0b758a627fb63046f8a65976ff5..041c33e3e95cc96283faf10e44ddc01c169098a9 100644 (file)
@@ -104,18 +104,18 @@ void marker_probe_cb(const struct marker *mdata, void *call_private,
        char ptype;
 
        /*
-        * disabling preemption to make sure the teardown of the callbacks can
-        * be done correctly when they are in modules and they insure RCU read
-        * coherency.
+        * preempt_disable does two things : disabling preemption to make sure
+        * the teardown of the callbacks can be done correctly when they are in
+        * modules and they insure RCU read coherency.
         */
        preempt_disable();
-       ptype = ACCESS_ONCE(mdata->ptype);
+       ptype = mdata->ptype;
        if (likely(!ptype)) {
                marker_probe_func *func;
                /* Must read the ptype before ptr. They are not data dependant,
                 * so we put an explicit smp_rmb() here. */
                smp_rmb();
-               func = ACCESS_ONCE(mdata->single.func);
+               func = mdata->single.func;
                /* Must read the ptr before private data. They are not data
                 * dependant, so we put an explicit smp_rmb() here. */
                smp_rmb();
@@ -133,7 +133,7 @@ void marker_probe_cb(const struct marker *mdata, void *call_private,
                 * in the fast path, so put the explicit barrier here.
                 */
                smp_read_barrier_depends();
-               multi = ACCESS_ONCE(mdata->multi);
+               multi = mdata->multi;
                for (i = 0; multi[i].func; i++) {
                        va_start(args, fmt);
                        multi[i].func(multi[i].probe_private, call_private, fmt,
@@ -161,13 +161,13 @@ void marker_probe_cb_noarg(const struct marker *mdata,
        char ptype;
 
        preempt_disable();
-       ptype = ACCESS_ONCE(mdata->ptype);
+       ptype = mdata->ptype;
        if (likely(!ptype)) {
                marker_probe_func *func;
                /* Must read the ptype before ptr. They are not data dependant,
                 * so we put an explicit smp_rmb() here. */
                smp_rmb();
-               func = ACCESS_ONCE(mdata->single.func);
+               func = mdata->single.func;
                /* Must read the ptr before private data. They are not data
                 * dependant, so we put an explicit smp_rmb() here. */
                smp_rmb();
@@ -183,7 +183,7 @@ void marker_probe_cb_noarg(const struct marker *mdata,
                 * in the fast path, so put the explicit barrier here.
                 */
                smp_read_barrier_depends();
-               multi = ACCESS_ONCE(mdata->multi);
+               multi = mdata->multi;
                for (i = 0; multi[i].func; i++)
                        multi[i].func(multi[i].probe_private, call_private, fmt,
                                &args);
@@ -551,9 +551,9 @@ static int set_marker(struct marker_entry **entry, struct marker *elem,
 
 /*
  * Disable a marker and its probe callback.
- * Note: only after a synchronize_sched() issued after setting elem->call to the
- * empty function insures that the original callback is not used anymore. This
- * insured by preemption disabling around the call site.
+ * Note: only waiting an RCU period after setting elem->call to the empty
+ * function insures that the original callback is not used anymore. This insured
+ * by preempt_disable around the call site.
  */
 static void disable_marker(struct marker *elem)
 {
@@ -565,8 +565,8 @@ static void disable_marker(struct marker *elem)
        elem->ptype = 0;        /* single probe */
        /*
         * Leave the private data and id there, because removal is racy and
-        * should be done only after a synchronize_sched(). These are never used
-        * until the next initialization anyway.
+        * should be done only after an RCU period. These are never used until
+        * the next initialization anyway.
         */
 }
 
@@ -601,9 +601,6 @@ void marker_update_probe_range(struct marker *begin,
 
 /*
  * Update probes, removing the faulty probes.
- * Issues a synchronize_sched() when no reference to the module passed
- * as parameter is found in the probes so the probe module can be
- * safely unloaded from now on.
  *
  * Internal callback only changed before the first probe is connected to it.
  * Single probe private data can only be changed on 0 -> 1 and 2 -> 1
index 9adc2a473e6e0f59bbc41350422d415e8f17a7ec..c46a20a19a153f06e938d469bf760ee893b63114 100644 (file)
@@ -616,6 +616,40 @@ asmlinkage int printk(const char *fmt, ...)
 /* cpu currently holding logbuf_lock */
 static volatile unsigned int printk_cpu = UINT_MAX;
 
+/*
+ * Can we actually use the console at this time on this cpu?
+ *
+ * Console drivers may assume that per-cpu resources have
+ * been allocated. So unless they're explicitly marked as
+ * being able to cope (CON_ANYTIME) don't call them until
+ * this CPU is officially up.
+ */
+static inline int can_use_console(unsigned int cpu)
+{
+       return cpu_online(cpu) || have_callable_console();
+}
+
+/*
+ * Try to get console ownership to actually show the kernel
+ * messages from a 'printk'. Return true (and with the
+ * console_semaphore held, and 'console_locked' set) if it
+ * is successful, false otherwise.
+ *
+ * This gets called with the 'logbuf_lock' spinlock held and
+ * interrupts disabled. It should return with 'lockbuf_lock'
+ * released but interrupts still disabled.
+ */
+static int acquire_console_semaphore_for_printk(unsigned int cpu)
+{
+       int retval = 0;
+
+       if (can_use_console(cpu))
+               retval = !try_acquire_console_sem();
+       printk_cpu = UINT_MAX;
+       spin_unlock(&logbuf_lock);
+       return retval;
+}
+
 const char printk_recursion_bug_msg [] =
                        KERN_CRIT "BUG: recent printk recursion!\n";
 static int printk_recursion_bug;
@@ -725,43 +759,22 @@ asmlinkage int vprintk(const char *fmt, va_list args)
                        log_level_unknown = 1;
        }
 
-       if (!down_trylock(&console_sem)) {
-               /*
-                * We own the drivers.  We can drop the spinlock and
-                * let release_console_sem() print the text, maybe ...
-                */
-               console_locked = 1;
-               printk_cpu = UINT_MAX;
-               spin_unlock(&logbuf_lock);
+       /*
+        * Try to acquire and then immediately release the
+        * console semaphore. The release will do all the
+        * actual magic (print out buffers, wake up klogd,
+        * etc). 
+        *
+        * The acquire_console_semaphore_for_printk() function
+        * will release 'logbuf_lock' regardless of whether it
+        * actually gets the semaphore or not.
+        */
+       if (acquire_console_semaphore_for_printk(this_cpu))
+               release_console_sem();
 
-               /*
-                * Console drivers may assume that per-cpu resources have
-                * been allocated. So unless they're explicitly marked as
-                * being able to cope (CON_ANYTIME) don't call them until
-                * this CPU is officially up.
-                */
-               if (cpu_online(smp_processor_id()) || have_callable_console()) {
-                       console_may_schedule = 0;
-                       release_console_sem();
-               } else {
-                       /* Release by hand to avoid flushing the buffer. */
-                       console_locked = 0;
-                       up(&console_sem);
-               }
-               lockdep_on();
-               raw_local_irq_restore(flags);
-       } else {
-               /*
-                * Someone else owns the drivers.  We drop the spinlock, which
-                * allows the semaphore holder to proceed and to call the
-                * console drivers with the output which we just produced.
-                */
-               printk_cpu = UINT_MAX;
-               spin_unlock(&logbuf_lock);
-               lockdep_on();
+       lockdep_on();
 out_restore_irqs:
-               raw_local_irq_restore(flags);
-       }
+       raw_local_irq_restore(flags);
 
        preempt_enable();
        return printed_len;
index 4c035a8a248c2bfabea85bfd616c9562fcf4f440..d6204a4858183c754d5d401ad230c11f60a546c1 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 28c73f07efb2f7506f70be5ceb7a44c134770afa..8dcdec6fe0fe0983f4a90e8d51e501871974d383 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 278534bbca956a93de37352767b91cc72aa87dcd..7f60097d443a6258b2044a37b5d23f0d4656aaca 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 99b00a25f88b3efc4c0558c78ece429d3d3300c3..b024106daa70163646b31a031085b4d732b4f096 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 f6ff4337b4242e911ab4e4faadb160b76a445b50..2ccea700968f7ecaaa265023e79e52d540a82871 100644 (file)
@@ -125,6 +125,7 @@ static int __init reserve_bootmem_core(bootmem_data_t *bdata,
        BUG_ON(!size);
        BUG_ON(PFN_DOWN(addr) >= bdata->node_low_pfn);
        BUG_ON(PFN_UP(addr + size) > bdata->node_low_pfn);
+       BUG_ON(addr < bdata->node_boot_start);
 
        sidx = PFN_DOWN(addr - bdata->node_boot_start);
        eidx = PFN_UP(addr + size - bdata->node_boot_start);
@@ -156,21 +157,31 @@ static void __init free_bootmem_core(bootmem_data_t *bdata, unsigned long addr,
        unsigned long sidx, eidx;
        unsigned long i;
 
+       BUG_ON(!size);
+
+       /* out range */
+       if (addr + size < bdata->node_boot_start ||
+               PFN_DOWN(addr) > bdata->node_low_pfn)
+               return;
        /*
         * round down end of usable mem, partially free pages are
         * considered reserved.
         */
-       BUG_ON(!size);
-       BUG_ON(PFN_DOWN(addr + size) > bdata->node_low_pfn);
 
-       if (addr < bdata->last_success)
+       if (addr >= bdata->node_boot_start && addr < bdata->last_success)
                bdata->last_success = addr;
 
        /*
-        * Round up the beginning of the address.
+        * Round up to index to the range.
         */
-       sidx = PFN_UP(addr) - PFN_DOWN(bdata->node_boot_start);
+       if (PFN_UP(addr) > PFN_DOWN(bdata->node_boot_start))
+               sidx = PFN_UP(addr) - PFN_DOWN(bdata->node_boot_start);
+       else
+               sidx = 0;
+
        eidx = PFN_DOWN(addr + size - bdata->node_boot_start);
+       if (eidx > bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start))
+               eidx = bdata->node_low_pfn - PFN_DOWN(bdata->node_boot_start);
 
        for (i = sidx; i < eidx; i++) {
                if (unlikely(!test_and_clear_bit(i, bdata->node_bootmem_map)))
@@ -421,7 +432,9 @@ int __init reserve_bootmem(unsigned long addr, unsigned long size,
 
 void __init free_bootmem(unsigned long addr, unsigned long size)
 {
-       free_bootmem_core(NODE_DATA(0)->bdata, addr, size);
+       bootmem_data_t *bdata;
+       list_for_each_entry(bdata, &bdata_list, list)
+               free_bootmem_core(bdata, addr, size);
 }
 
 unsigned long __init free_all_bootmem(void)
index 74c1b6b0b37b82dce75e06533c989ab73001afeb..51c9e2c0164068681b299b37f48840af59d5c79d 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 bb4070e1079fb7e863386f84f5fd138163a9a6ba..04b308c3bc547f72762521fa5a45170713546e41 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 ca71d5b81e4a436b43bb183728650887eef4f0e9..84ed734b96b3ee83861b7499edd55d7aa479e61a 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 f0f55875dd6acc34d3c9ee05298cd43dcea02650..ae532f50194319ce83b813a88b6a25aa5a4e85e5 100644 (file)
@@ -88,6 +88,8 @@ struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags)
 
 close_file:
        put_filp(file);
+       return ERR_PTR(error);
+
 put_dentry:
        dput(dentry);
 put_memory:
index 45711585684ec74c01f7b93ae28a8d8b4f62bfb9..4046434046e68b0a45864c019a095fab088420ee 100644 (file)
@@ -70,13 +70,6 @@ struct scan_control {
 
        int order;
 
-       /*
-        * Pages that have (or should have) IO pending.  If we run into
-        * a lot of these, we're better off waiting a little for IO to
-        * finish rather than scanning more pages in the VM.
-        */
-       int nr_io_pages;
-
        /* Which cgroup do we reclaim from */
        struct mem_cgroup *mem_cgroup;
 
@@ -512,10 +505,8 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                         */
                        if (sync_writeback == PAGEOUT_IO_SYNC && may_enter_fs)
                                wait_on_page_writeback(page);
-                       else {
-                               sc->nr_io_pages++;
+                       else
                                goto keep_locked;
-                       }
                }
 
                referenced = page_referenced(page, 1, sc->mem_cgroup);
@@ -554,10 +545,8 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                if (PageDirty(page)) {
                        if (sc->order <= PAGE_ALLOC_COSTLY_ORDER && referenced)
                                goto keep_locked;
-                       if (!may_enter_fs) {
-                               sc->nr_io_pages++;
+                       if (!may_enter_fs)
                                goto keep_locked;
-                       }
                        if (!sc->may_writepage)
                                goto keep_locked;
 
@@ -568,10 +557,8 @@ static unsigned long shrink_page_list(struct list_head *page_list,
                        case PAGE_ACTIVATE:
                                goto activate_locked;
                        case PAGE_SUCCESS:
-                               if (PageWriteback(page) || PageDirty(page)) {
-                                       sc->nr_io_pages++;
+                               if (PageWriteback(page) || PageDirty(page))
                                        goto keep;
-                               }
                                /*
                                 * A synchronous write - probably a ramdisk.  Go
                                 * ahead and try to reclaim the page.
@@ -1344,7 +1331,6 @@ static unsigned long do_try_to_free_pages(struct zone **zones, gfp_t gfp_mask,
 
        for (priority = DEF_PRIORITY; priority >= 0; priority--) {
                sc->nr_scanned = 0;
-               sc->nr_io_pages = 0;
                if (!priority)
                        disable_swap_token();
                nr_reclaimed += shrink_zones(priority, zones, sc);
@@ -1379,8 +1365,7 @@ static unsigned long do_try_to_free_pages(struct zone **zones, gfp_t gfp_mask,
                }
 
                /* Take a nap, wait for some writeback to complete */
-               if (sc->nr_scanned && priority < DEF_PRIORITY - 2 &&
-                               sc->nr_io_pages > sc->swap_cluster_max)
+               if (sc->nr_scanned && priority < DEF_PRIORITY - 2)
                        congestion_wait(WRITE, HZ/10);
        }
        /* top priority shrink_caches still had more to do? don't OOM, then */
@@ -1514,7 +1499,6 @@ loop_again:
                if (!priority)
                        disable_swap_token();
 
-               sc.nr_io_pages = 0;
                all_zones_ok = 1;
 
                /*
@@ -1607,8 +1591,7 @@ loop_again:
                 * OK, kswapd is getting into trouble.  Take a nap, then take
                 * another pass across the zones.
                 */
-               if (total_scanned && priority < DEF_PRIORITY - 2 &&
-                                       sc.nr_io_pages > sc.swap_cluster_max)
+               if (total_scanned && priority < DEF_PRIORITY - 2)
                        congestion_wait(WRITE, HZ/10);
 
                /*
index 8fbcefe10c9fde2ff66a2a78fcced415bc5238cf..480ea90e7dcd870c210d9d27b93684f2e7ddd836 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 4089c49e45cc3a90f9e099df809ef5dd66505b16..69fb4e368d922fe57ab543983416d2532fca1cad 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 fcdf03cf3b3f8b0f62af03ce208b658d11a5834d..460e7f99ce3e3c2e3d252dd31ff251ce49841d0a 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 d9a02b2cc28940d1dde4f5f7ee6064f9581b046b..19b8e003f15084821aee62374a74038514800d80 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 a13c074dac091e21fb1bb3cb1c77715ded13a5c2..a944e8053e28ff84f4989bcaa0ec2395cd348ac4 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 b47030ba162bc97df715d11fc779f59df1db16e5..9c798abce736c5afdb78aaccb3d26f1ce08ad307 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 8dee617ee900662ddac773b7350fe0cc23745692..584e6d74e3a9f0cf1b72fe0c797dc8033332eed0 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 d5a58a8180210a0ffdef8fce568426f448d223a8..8c3180adddbf12e2955a9c7a47ccd374b35b790c 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 fdeebe68a379781853e4a0ea6f4197195af8cb89..07735ed280d720f32ac7269c5099c1e840d866d7 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 51557c27a0cdfc8e5d65337bf12ae0a4cf041da7..452a2ac4eec8ca58d4083b05dc4756224bb7f95c 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 0527d11c1ae37a304964cd5c85baf4d99e3b6fbe..d6ce400f585f69675a17bd96ae4036492dcf1efb 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 0c742faaa30bb84cb309962208f9591b64fc5767..e20529b4c82532acb318758403979a232db4b0d4 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 79ccfb080733d77e52831ce5dd832302856fc5be..0af823cf7f1fb7561b481a814ed99ede1941ddba 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 dc817e035e2338cb60fa78ec2e0cf9319eef986d..ff1e1db8e236009910ed6d9258eef5f961b8fb08 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 bc2e15ce7004e59650a4ad4a3980ace5b101ff1f..7873c392ab4c8e484d7375ae0deba6f1d8bc1d0a 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 8b5f486ac80f298fe6034a2a8b576c3c2ad9ea83..e9ef9af4a53bf5d118882db91a171f9d618f4262 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 971271602dd07e5ae97b0e42b42f02cc2b9f4eb9..c22d6b6f2db43d2d8475c742ac66edd047161f86 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 62188c6a06ddc2d933f0ad88819f3d4f10479638..75279402ccf46f085f249cd65eda2a9e69db40a2 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 569d377932c4b5457b2512f712ac140d00b05704..2519129c6d213f85bceebc165e2c27744f2fd3b6 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 7ba65e82941c4f7794f6ada15a418d60606dbba4..58f1f9347b54515e0bdfe534940adf3263d40755 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 f971ca5645f8283991f29e06fe2bdc888b66a499..5d96f2728dc60f48a337c2c1ff9839ba99184736 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 cfc004e04417e5126a75d53cc3ce3d04c8924c9b..2d20640854b7412bd46156f568a9a29443b6c0aa 100644 (file)
@@ -58,6 +58,9 @@ modules   := $(patsubst %.o,%.ko, $(wildcard $(__modules:.ko=.o)))
 # Stop after building .o files if NOFINAL is set. Makes compile tests quicker
 _modpost: $(if $(KBUILD_MODPOST_NOFINAL), $(modules:.ko:.o),$(modules))
 
+ifneq ($(KBUILD_BUILDHOST),$(ARCH))
+        cross_build := 1
+endif
 
 # Step 2), invoke modpost
 #  Includes step 3,4
@@ -70,7 +73,8 @@ modpost = scripts/mod/modpost                    \
  $(if $(CONFIG_DEBUG_SECTION_MISMATCH),,-S)      \
  $(if $(CONFIG_MARKERS),-K $(kernelmarkersfile)) \
  $(if $(CONFIG_MARKERS),-M $(markersfile))      \
- $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w)
+ $(if $(KBUILD_EXTMOD)$(KBUILD_MODPOST_WARN),-w) \
+ $(if $(cross_build),-c)
 
 quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
       cmd_modpost = $(modpost) -s
index 9ddf944cce290b7d38fc2982b852bc93d4c50001..348d8687b7c9cad167c6d631ce9e5f1c2038bdf0 100644 (file)
@@ -51,11 +51,13 @@ do {                                                            \
                 sprintf(str + strlen(str), "*");                \
 } while(0)
 
+unsigned int cross_build = 0;
 /**
  * Check that sizeof(device_id type) are consistent with size of section
  * in .o file. If in-consistent then userspace and kernel does not agree
  * on actual size which is a bug.
  * Also verify that the final entry in the table is all zeros.
+ * Ignore both checks if build host differ from target host and size differs.
  **/
 static void device_id_check(const char *modname, const char *device_id,
                            unsigned long size, unsigned long id_size,
@@ -64,6 +66,8 @@ static void device_id_check(const char *modname, const char *device_id,
        int i;
 
        if (size % id_size || size < id_size) {
+               if (cross_build != 0)
+                       return;
                fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo "
                      "of the size of section __mod_%s_device_table=%lu.\n"
                      "Fix definition of struct %s_device_id "
index 695b5d657cf59cc89ba1a4989d7052085e942abf..110cf243fa4e56d3749781c7b4703bf4c62ae9b7 100644 (file)
@@ -2026,7 +2026,7 @@ int main(int argc, char **argv)
        int opt;
        int err;
 
-       while ((opt = getopt(argc, argv, "i:I:msSo:awM:K:")) != -1) {
+       while ((opt = getopt(argc, argv, "i:I:cmsSo:awM:K:")) != -1) {
                switch (opt) {
                case 'i':
                        kernel_read = optarg;
@@ -2035,6 +2035,9 @@ int main(int argc, char **argv)
                        module_read = optarg;
                        external_module = 1;
                        break;
+               case 'c':
+                       cross_build = 1;
+                       break;
                case 'm':
                        modversions = 1;
                        break;
index 565c5872407e19e2cfd8c16a63a19be0fd358f47..09f58e33d227bf3fecb88d555f33cd52fc4375a7 100644 (file)
@@ -135,6 +135,7 @@ struct elf_info {
 };
 
 /* file2alias.c */
+extern unsigned int cross_build;
 void handle_moddevtable(struct module *mod, struct elf_info *info,
                        Elf_Sym *sym, const char *symname);
 void add_moddevtable(struct buffer *buf, struct module *mod);
index afe7c9b0732ac6c16ae6677bbfe1ca0ca5ecf799..cfae8afcc262d9fd9e18e3b79f45b5a3f4598bd8 100644 (file)
@@ -73,11 +73,6 @@ struct smk_list_entry *smack_list;
 
 #define        SEQ_READ_FINISHED       1
 
-/*
- * Disable concurrent writing open() operations
- */
-static struct semaphore smack_write_sem;
-
 /*
  * Values for parsing cipso rules
  * SMK_DIGITLEN: Length of a digit field in a rule.
@@ -168,32 +163,7 @@ static struct seq_operations load_seq_ops = {
  */
 static int smk_open_load(struct inode *inode, struct file *file)
 {
-       if ((file->f_flags & O_ACCMODE) == O_RDONLY)
-               return seq_open(file, &load_seq_ops);
-
-       if (down_interruptible(&smack_write_sem))
-               return -ERESTARTSYS;
-
-       return 0;
-}
-
-/**
- * smk_release_load - release() for /smack/load
- * @inode: inode structure representing file
- * @file: "load" file pointer
- *
- * For a reading session, use the seq_file release
- * implementation.
- * Otherwise, we are at the end of a writing session so
- * clean everything up.
- */
-static int smk_release_load(struct inode *inode, struct file *file)
-{
-       if ((file->f_flags & O_ACCMODE) == O_RDONLY)
-               return seq_release(inode, file);
-
-       up(&smack_write_sem);
-       return 0;
+       return seq_open(file, &load_seq_ops);
 }
 
 /**
@@ -341,7 +311,7 @@ static const struct file_operations smk_load_ops = {
        .read           = seq_read,
        .llseek         = seq_lseek,
        .write          = smk_write_load,
-       .release        = smk_release_load,
+       .release        = seq_release,
 };
 
 /**
@@ -1011,7 +981,6 @@ static int __init init_smk_fs(void)
                }
        }
 
-       sema_init(&smack_write_sem, 1);
        smk_cipso_doi();
        smk_unlbl_ambient(NULL);
 
index 569ecaca0e8b9caf7723d9a393367ab6853242c9..889a897d41ac3ed49a5baea9674fdf4d04fbb14b 100644 (file)
@@ -1187,10 +1187,8 @@ static struct i2c_driver aic3x_i2c_driver = {
                .name = "aic3x I2C Codec",
                .owner = THIS_MODULE,
        },
-       .id = I2C_DRIVERID_I2CDEV,
        .attach_adapter = aic3x_i2c_attach,
        .detach_client = aic3x_i2c_detach,
-       .command = NULL,
 };
 
 static struct i2c_client client_template = {