Pull documentation into release branch
authorLen Brown <len.brown@intel.com>
Mon, 29 Oct 2007 21:31:01 +0000 (17:31 -0400)
committerLen Brown <len.brown@intel.com>
Mon, 29 Oct 2007 21:31:01 +0000 (17:31 -0400)
397 files changed:
Documentation/kernel-parameters.txt
Documentation/lguest/lguest.c
Documentation/networking/00-INDEX
Documentation/networking/ip-sysctl.txt
Documentation/networking/net-modules.txt [deleted file]
Documentation/networking/tc-actions-env-rules.txt [new file with mode: 0644]
Documentation/scsi/link_power_management_policy.txt [new file with mode: 0644]
MAINTAINERS
Makefile
arch/blackfin/kernel/dma-mapping.c
arch/frv/mb93090-mb00/pci-dma.c
arch/i386/.gitignore [deleted file]
arch/m68k/kernel/dma.c
arch/sparc/kernel/pcic.c
arch/sparc/kernel/process.c
arch/sparc/kernel/time.c
arch/sparc/mm/btfixup.c
arch/sparc/mm/io-unit.c
arch/sparc/mm/sun4c.c
arch/sparc64/kernel/binfmt_elf32.c
arch/sparc64/kernel/central.c
arch/sparc64/kernel/iommu_common.c
arch/sparc64/kernel/ldc.c
arch/sparc64/kernel/semaphore.c
arch/sparc64/kernel/smp.c
arch/sparc64/kernel/sys_sparc.c
arch/sparc64/kernel/traps.c
arch/sparc64/mm/init.c
arch/sparc64/prom/console.c
arch/sparc64/prom/tree.c
arch/um/Kconfig.i386
arch/um/Makefile-i386
arch/um/Makefile-x86_64
arch/um/drivers/ubd_kern.c
arch/um/kernel/mem.c
arch/um/sys-i386/ptrace.c
arch/um/sys-x86_64/ptrace.c
arch/x86/Kconfig.cpu [moved from arch/i386/Kconfig.cpu with 100% similarity]
arch/x86/Kconfig.debug [moved from arch/i386/Kconfig.debug with 65% similarity]
arch/x86/Kconfig.i386 [moved from arch/i386/Kconfig with 99% similarity]
arch/x86/Kconfig.x86_64 [moved from arch/x86_64/Kconfig with 99% similarity]
arch/x86/Makefile [new file with mode: 0644]
arch/x86/Makefile_32 [moved from arch/i386/Makefile with 98% similarity]
arch/x86/Makefile_32.cpu [moved from arch/i386/Makefile.cpu with 100% similarity]
arch/x86/Makefile_64 [moved from arch/x86_64/Makefile with 99% similarity]
arch/x86/boot/boot.h
arch/x86/boot/compressed/head_32.S
arch/x86/boot/compressed/head_64.S
arch/x86/boot/header.S
arch/x86/boot/video-bios.c
arch/x86/boot/video-vesa.c
arch/x86/boot/video.c
arch/x86/configs/i386_defconfig [moved from arch/i386/defconfig with 100% similarity]
arch/x86/configs/x86_64_defconfig [moved from arch/x86_64/defconfig with 100% similarity]
arch/x86/kernel/acpi/processor.c
arch/x86/kernel/asm-offsets_64.c
arch/x86/kernel/crash.c
arch/x86/kernel/early-quirks.c
arch/x86/kernel/machine_kexec_64.c
arch/x86/kernel/pci-gart_64.c
arch/x86/kernel/smp_32.c
arch/x86/lguest/boot.c
arch/x86/lguest/i386_head.S
arch/x86/mach-voyager/voyager_smp.c
arch/x86/mm/fault_32.c
arch/x86/mm/init_64.c
arch/x86_64/.gitignore [deleted file]
arch/x86_64/Kconfig.debug [deleted file]
block/cfq-iosched.c
block/compat_ioctl.c
block/ll_rw_blk.c
crypto/hmac.c
crypto/tcrypt.c
drivers/acpi/Kconfig
drivers/acpi/battery.c
drivers/acpi/bus.c
drivers/acpi/button.c
drivers/acpi/ec.c
drivers/acpi/fan.c
drivers/acpi/power.c
drivers/acpi/sleep/main.c
drivers/acpi/sleep/proc.c
drivers/ata/ahci.c
drivers/ata/libata-core.c
drivers/ata/libata-eh.c
drivers/ata/libata-scsi.c
drivers/ata/libata.h
drivers/ata/pata_acpi.c
drivers/ata/pata_icside.c
drivers/ata/pata_ns87415.c
drivers/ata/pata_optidma.c
drivers/ata/pata_pcmcia.c
drivers/ata/pata_pdc2027x.c
drivers/ata/pata_pdc202xx_old.c
drivers/ata/pata_scc.c
drivers/ata/pata_via.c
drivers/ata/pata_winbond.c
drivers/ata/pdc_adma.c
drivers/ata/sata_inic162x.c
drivers/ata/sata_mv.c
drivers/ata/sata_nv.c
drivers/ata/sata_promise.c
drivers/ata/sata_qstor.c
drivers/ata/sata_sil.c
drivers/ata/sata_sil24.c
drivers/ata/sata_sis.c
drivers/ata/sata_svw.c
drivers/ata/sata_sx4.c
drivers/ata/sata_uli.c
drivers/ata/sata_via.c
drivers/ata/sata_vsc.c
drivers/block/cciss.c
drivers/block/cciss_scsi.c
drivers/block/cciss_scsi.h
drivers/block/cryptoloop.c
drivers/block/sunvdc.c
drivers/block/ub.c
drivers/block/virtio_blk.c
drivers/cdrom/viocd.c
drivers/char/mem.c
drivers/cpuidle/cpuidle.c
drivers/cpuidle/governor.c
drivers/crypto/padlock-sha.c
drivers/ide/arm/icside.c
drivers/ide/ide-iops.c
drivers/ide/pci/cy82c693.c
drivers/ide/pci/generic.c
drivers/ide/pci/hpt366.c
drivers/ide/pci/sc1200.c
drivers/ieee1394/dma.c
drivers/infiniband/core/umem.c
drivers/infiniband/hw/mthca/mthca_memfree.c
drivers/isdn/capi/capidrv.c
drivers/isdn/sc/shmem.c
drivers/lguest/core.c
drivers/lguest/hypercalls.c
drivers/lguest/interrupts_and_traps.c
drivers/lguest/lg.h
drivers/lguest/lguest_device.c
drivers/lguest/lguest_user.c
drivers/lguest/page_tables.c
drivers/lguest/segments.c
drivers/lguest/x86/core.c
drivers/lguest/x86/switcher_32.S
drivers/md/dm-crypt.c
drivers/md/raid6algos.c
drivers/md/raid6mmx.c
drivers/md/raid6sse1.c
drivers/md/raid6sse2.c
drivers/md/raid6x86.h
drivers/media/common/saa7146_core.c
drivers/media/video/ivtv/ivtv-udma.c
drivers/media/video/videobuf-dma-sg.c
drivers/message/i2o/i2o_block.c
drivers/misc/fujitsu-laptop.c
drivers/mmc/core/mmc_ops.c
drivers/mmc/core/sd_ops.c
drivers/mmc/host/au1xmmc.c
drivers/mmc/host/imxmmc.c
drivers/mmc/host/mmc_spi.c
drivers/mmc/host/mmci.c
drivers/mmc/host/pxamci.c
drivers/mmc/host/sdhci.c
drivers/mmc/host/wbsd.c
drivers/net/Kconfig
drivers/net/Makefile
drivers/net/bonding/bond_main.c
drivers/net/bonding/bonding.h
drivers/net/cpmac.c
drivers/net/e1000e/e1000.h
drivers/net/e1000e/netdev.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_main.c
drivers/net/fec_mpc52xx.c [new file with mode: 0644]
drivers/net/fec_mpc52xx.h [new file with mode: 0644]
drivers/net/fec_mpc52xx_phy.c [new file with mode: 0644]
drivers/net/forcedeth.c
drivers/net/ipg.c
drivers/net/ipg.h
drivers/net/irda/au1k_ir.c
drivers/net/loopback.c
drivers/net/mlx4/icm.c
drivers/net/natsemi.c
drivers/net/pcmcia/3c574_cs.c
drivers/net/pcmcia/3c589_cs.c
drivers/net/pcmcia/axnet_cs.c
drivers/net/pcmcia/fmvj18x_cs.c
drivers/net/pcmcia/pcnet_cs.c
drivers/net/pcmcia/smc91c92_cs.c
drivers/net/pcmcia/xirc2ps_cs.c
drivers/net/ppp_mppe.c
drivers/net/r8169.c
drivers/net/rrunner.c
drivers/net/ucc_geth.c
drivers/net/usb/rndis_host.c
drivers/net/wireless/b43/main.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/ipw2100.c
drivers/net/wireless/ipw2200.c
drivers/net/wireless/iwlwifi/iwl-4965.c
drivers/net/wireless/iwlwifi/iwl3945-base.c
drivers/net/wireless/iwlwifi/iwl4965-base.c
drivers/net/wireless/rt2x00/rt2x00lib.h
drivers/net/wireless/rtl8187_dev.c
drivers/pci/intel-iommu.c
drivers/pci/intel-iommu.h
drivers/s390/scsi/zfcp_aux.c
drivers/s390/scsi/zfcp_def.h
drivers/s390/scsi/zfcp_erp.c
drivers/scsi/aacraid/commctrl.c
drivers/scsi/aacraid/comminit.c
drivers/scsi/aacraid/dpcsup.c
drivers/scsi/arcmsr/arcmsr.h
drivers/scsi/arcmsr/arcmsr_attr.c
drivers/scsi/arcmsr/arcmsr_hba.c
drivers/scsi/atari_NCR5380.c
drivers/scsi/ipr.c
drivers/scsi/iscsi_tcp.c
drivers/scsi/osst.c
drivers/scsi/sg.c
drivers/scsi/st.c
drivers/scsi/sun3x_esp.c
drivers/serial/serial_core.c
drivers/serial/serial_cs.c
drivers/spi/spidev.c
drivers/usb/core/message.c
drivers/usb/core/urb.c
drivers/usb/gadget/amd5536udc.c
drivers/usb/host/Kconfig
drivers/usb/host/ohci-hcd.c
drivers/usb/host/uhci-q.c
drivers/usb/misc/cytherm.c
drivers/usb/misc/emi26.c
drivers/usb/misc/emi62.c
drivers/usb/misc/ftdi-elan.c
drivers/usb/misc/idmouse.c
drivers/usb/misc/iowarrior.c
drivers/usb/misc/legousbtower.c
drivers/usb/misc/rio500.c
drivers/usb/misc/usblcd.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/ch341.c
drivers/usb/serial/console.c
drivers/usb/serial/cp2101.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/empeg.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/generic.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/ir-usb.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/option.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/pl2303.h
drivers/usb/serial/sierra.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/whiteheat.c
drivers/usb/storage/Kconfig
drivers/usb/storage/isd200.c
drivers/video/cirrusfb.c
fs/ecryptfs/crypto.c
fs/jffs2/acl.c
fs/mbcache.c
fs/proc/proc_net.c
fs/proc/proc_sysctl.c
include/acpi/acpi_bus.h
include/asm-avr32/dma-mapping.h
include/asm-frv/scatterlist.h
include/asm-sparc/atomic.h
include/asm-sparc/dma.h
include/asm-sparc/floppy.h
include/asm-sparc/ide.h
include/asm-sparc/posix_types.h
include/asm-sparc/system.h
include/asm-sparc64/atomic.h
include/asm-sparc64/backoff.h
include/asm-sparc64/byteorder.h
include/asm-sparc64/fpumacro.h
include/asm-sparc64/io.h
include/asm-sparc64/irq.h
include/asm-sparc64/mostek.h
include/asm-sparc64/ns87303.h
include/asm-sparc64/parport.h
include/asm-sparc64/posix_types.h
include/asm-sparc64/sbus.h
include/asm-sparc64/spitfire.h
include/asm-sparc64/system.h
include/asm-sparc64/upa.h
include/asm-sparc64/visasm.h
include/asm-um/unistd.h
include/asm-x86/bitops_32.h
include/asm-x86/bitops_64.h
include/asm-x86/lguest_hcall.h
include/asm-x86/smp_32.h
include/asm-xtensa/dma-mapping.h
include/linux/ata.h
include/linux/blkdev.h
include/linux/bootmem.h
include/linux/compiler.h
include/linux/completion.h
include/linux/dccp.h
include/linux/eventpoll.h
include/linux/lguest.h
include/linux/lguest_launcher.h
include/linux/libata.h
include/linux/mv643xx_eth.h
include/linux/netdevice.h
include/linux/pci_ids.h
include/linux/scatterlist.h
include/linux/sched.h
include/linux/skbuff.h
include/linux/sunrpc/rpc_rdma.h
include/linux/types.h
include/net/inet_hashtables.h
include/net/inet_sock.h
include/net/irda/ircomm_tty.h
include/net/net_namespace.h
include/net/sch_generic.h
include/net/sctp/auth.h
include/net/sctp/sctp.h
include/net/tcp.h
include/net/xfrm.h
init/Kconfig
kernel/hrtimer.c
kernel/profile.c
kernel/sched.c
kernel/sched_fair.c
kernel/sched_idletask.c
kernel/sched_rt.c
kernel/signal.c
kernel/time/tick-sched.c
kernel/time/timer_list.c
kernel/user.c
lib/Kconfig.debug
mm/filemap.c
mm/nommu.c
mm/slub.c
mm/sparse.c
net/9p/mux.c
net/core/dev.c
net/core/dev_mcast.c
net/core/flow.c
net/core/net-sysfs.c
net/core/net-sysfs.h [new file with mode: 0644]
net/core/rtnetlink.c
net/core/skbuff.c
net/core/sock.c
net/core/sysctl_net_core.c
net/dccp/ccids/ccid2.c
net/dccp/ccids/ccid3.c
net/dccp/input.c
net/dccp/ipv4.c
net/dccp/ipv6.c
net/dccp/options.c
net/dccp/proto.c
net/ethernet/eth.c
net/ieee80211/ieee80211_crypt_tkip.c
net/ieee80211/ieee80211_crypt_wep.c
net/ipv4/cipso_ipv4.c
net/ipv4/esp4.c
net/ipv4/fib_frontend.c
net/ipv4/icmp.c
net/ipv4/ip_gre.c
net/ipv4/ip_output.c
net/ipv4/ipip.c
net/ipv4/ipvs/ip_vs_xmit.c
net/ipv4/proc.c
net/ipv4/tcp_input.c
net/ipv4/tcp_ipv4.c
net/ipv4/udp.c
net/ipv6/esp6.c
net/ipv6/ip6_output.c
net/ipv6/ip6_tunnel.c
net/ipv6/sit.c
net/ipv6/tcp_ipv6.c
net/irda/ircomm/ircomm_tty.c
net/mac80211/ieee80211_sta.c
net/netlabel/netlabel_domainhash.c
net/netlabel/netlabel_mgmt.c
net/netlabel/netlabel_unlabeled.c
net/netlink/af_netlink.c
net/rxrpc/rxkad.c
net/sched/act_mirred.c
net/sched/sch_prio.c
net/sctp/auth.c
net/sctp/crc32c.c
net/sctp/sm_make_chunk.c
net/sctp/ulpqueue.c
net/sunrpc/auth_gss/gss_krb5_crypto.c
net/sunrpc/auth_gss/gss_spkm3_seal.c
net/sunrpc/xdr.c
net/sunrpc/xprtrdma/rpc_rdma.c
net/xfrm/xfrm_algo.c
scripts/kconfig/Makefile
sound/pci/hda/patch_realtek.c

index a13d69b..33121d6 100644 (file)
@@ -586,11 +586,6 @@ and is between 256 and 4096 characters. It is defined in the file
 
        eata=           [HW,SCSI]
 
-       ec_intr=        [HW,ACPI] ACPI Embedded Controller interrupt mode
-                       Format: <int>
-                       0: polling mode
-                       non-0: interrupt mode (default)
-
        edd=            [EDD]
                        Format: {"of[f]" | "sk[ipmbr]"}
                        See comment in arch/i386/boot/edd.S
@@ -1444,7 +1439,8 @@ and is between 256 and 4096 characters. It is defined in the file
                        Param: "schedule" - profile schedule points.
                        Param: <number> - step/bucket size as a power of 2 for
                                statistical time based profiling.
-                       Param: "sleep" - profile D-state sleeping (millisecs)
+                       Param: "sleep" - profile D-state sleeping (millisecs).
+                               Requires CONFIG_SCHEDSTATS
                        Param: "kvm" - profile VM exits.
 
        processor.max_cstate=   [HW,ACPI]
index 5bdc37f..f266839 100644 (file)
 #include <zlib.h>
 #include <assert.h>
 #include <sched.h>
-/*L:110 We can ignore the 30 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
- * like these abbreviations and the header we need uses them, so we define them
- * here.
- */
-typedef unsigned long long u64;
-typedef uint32_t u32;
-typedef uint16_t u16;
-typedef uint8_t u8;
 #include "linux/lguest_launcher.h"
-#include "linux/pci_ids.h"
 #include "linux/virtio_config.h"
 #include "linux/virtio_net.h"
 #include "linux/virtio_blk.h"
 #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
+ * 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
+ * like these abbreviations, so we define them here.  Note that u64 is always
+ * unsigned long long, which works on all Linux systems: this means that we can
+ * use %llu in printf for any u64. */
+typedef unsigned long long u64;
+typedef uint32_t u32;
+typedef uint16_t u16;
+typedef uint8_t u8;
 /*:*/
 
 #define PAGE_PRESENT 0x7       /* Present, RW, Execute */
@@ -361,8 +360,8 @@ static unsigned long load_bzimage(int fd)
 }
 
 /*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels
- * come wrapped up in the self-decompressing "bzImage" format.  With some funky
- * coding, we can load those, too. */
+ * come wrapped up in the self-decompressing "bzImage" format.  With a little
+ * work, we can load those, too. */
 static unsigned long load_kernel(int fd)
 {
        Elf32_Ehdr hdr;
@@ -465,6 +464,7 @@ static unsigned long setup_pagetables(unsigned long mem,
         * to know where it is. */
        return to_guest_phys(pgdir);
 }
+/*:*/
 
 /* Simple routine to roll all the commandline arguments together with spaces
  * between them. */
@@ -481,9 +481,9 @@ static void concat(char *dst, char *args[])
        dst[len] = '\0';
 }
 
-/* This is where we actually tell the kernel to initialize the Guest.  We saw
- * the arguments it expects when we looked at initialize() in lguest_user.c:
- * the base of guest "physical" memory, the top physical page to allow, the
+/*L:185 This is where we actually tell the kernel to initialize the Guest.  We
+ * saw the arguments it expects when we looked at initialize() in lguest_user.c:
+ * the base of Guest "physical" memory, the top physical page to allow, the
  * top level pagetable and the entry point for the Guest. */
 static int tell_kernel(unsigned long pgdir, unsigned long start)
 {
@@ -513,13 +513,14 @@ static void add_device_fd(int fd)
 /*L:200
  * The Waker.
  *
- * With a console and network devices, we can have lots of input which we need
- * to process.  We could try to tell the kernel what file descriptors to watch,
- * but handing a file descriptor mask through to the kernel is fairly icky.
+ * With console, block and network devices, we can have lots of input which we
+ * need to process.  We could try to tell the kernel what file descriptors to
+ * watch, but handing a file descriptor mask through to the kernel is fairly
+ * icky.
  *
  * Instead, we fork off a process which watches the file descriptors and writes
- * the LHREQ_BREAK command to the /dev/lguest filedescriptor to tell the Host
- * loop to stop running the Guest.  This causes it to return from the
+ * the LHREQ_BREAK command to the /dev/lguest file descriptor to tell the Host
+ * stop running the Guest.  This causes the Launcher to return from the
  * /dev/lguest read with -EAGAIN, where it will write to /dev/lguest to reset
  * the LHREQ_BREAK and wake us up again.
  *
@@ -545,7 +546,9 @@ static void wake_parent(int pipefd, int lguest_fd)
                        if (read(pipefd, &fd, sizeof(fd)) == 0)
                                exit(0);
                        /* Otherwise it's telling us to change what file
-                        * descriptors we're to listen to. */
+                        * descriptors we're to listen to.  Positive means
+                        * listen to a new one, negative means stop
+                        * listening. */
                        if (fd >= 0)
                                FD_SET(fd, &devices.infds);
                        else
@@ -560,7 +563,7 @@ static int setup_waker(int lguest_fd)
 {
        int pipefd[2], child;
 
-       /* We create a pipe to talk to the waker, and also so it knows when the
+       /* We create a pipe to talk to the Waker, and also so it knows when the
         * Launcher dies (and closes pipe). */
        pipe(pipefd);
        child = fork();
@@ -568,7 +571,8 @@ static int setup_waker(int lguest_fd)
                err(1, "forking");
 
        if (child == 0) {
-               /* Close the "writing" end of our copy of the pipe */
+               /* We are the Waker: close the "writing" end of our copy of the
+                * pipe and start waiting for input. */
                close(pipefd[1]);
                wake_parent(pipefd[0], lguest_fd);
        }
@@ -579,12 +583,12 @@ static int setup_waker(int lguest_fd)
        return pipefd[1];
 }
 
-/*L:210
+/*
  * Device Handling.
  *
- * When the Guest sends DMA to us, it sends us an array of addresses and sizes.
+ * When the Guest gives us a buffer, it sends an array of addresses and sizes.
  * We need to make sure it's not trying to reach into the Launcher itself, so
- * we have a convenient routine which check it and exits with an error message
+ * we have a convenient routine which checks it and exits with an error message
  * if something funny is going on:
  */
 static void *_check_pointer(unsigned long addr, unsigned int size,
@@ -601,7 +605,9 @@ static void *_check_pointer(unsigned long addr, unsigned int size,
 /* A macro which transparently hands the line number to the real function. */
 #define check_pointer(addr,size) _check_pointer(addr, size, __LINE__)
 
-/* This function returns the next descriptor in the chain, or vq->vring.num. */
+/* Each buffer in the virtqueues is actually a chain of descriptors.  This
+ * function returns the next descriptor in the chain, or vq->vring.num if we're
+ * at the end. */
 static unsigned next_desc(struct virtqueue *vq, unsigned int i)
 {
        unsigned int next;
@@ -680,13 +686,14 @@ static unsigned get_vq_desc(struct virtqueue *vq,
        return head;
 }
 
-/* Once we've used one of their buffers, we tell them about it.  We'll then
+/* After we've used one of their buffers, we tell them about it.  We'll then
  * want to send them an interrupt, using trigger_irq(). */
 static void add_used(struct virtqueue *vq, unsigned int head, int len)
 {
        struct vring_used_elem *used;
 
-       /* Get a pointer to the next entry in the used ring. */
+       /* The virtqueue contains a ring of used buffers.  Get a pointer to the
+        * next entry in that used ring. */
        used = &vq->vring.used->ring[vq->vring.used->idx % vq->vring.num];
        used->id = head;
        used->len = len;
@@ -700,6 +707,7 @@ static void trigger_irq(int fd, struct virtqueue *vq)
 {
        unsigned long buf[] = { LHREQ_IRQ, vq->config.irq };
 
+       /* If they don't want an interrupt, don't send one. */
        if (vq->vring.avail->flags & VRING_AVAIL_F_NO_INTERRUPT)
                return;
 
@@ -716,8 +724,11 @@ static void add_used_and_trigger(int fd, struct virtqueue *vq,
        trigger_irq(fd, vq);
 }
 
-/* Here is the input terminal setting we save, and the routine to restore them
- * on exit so the user can see what they type next. */
+/*
+ * The Console
+ *
+ * Here is the input terminal setting we save, and the routine to restore them
+ * on exit so the user gets their terminal back. */
 static struct termios orig_term;
 static void restore_term(void)
 {
@@ -818,7 +829,10 @@ static void handle_console_output(int fd, struct virtqueue *vq)
        }
 }
 
-/* Handling output for network is also simple: we get all the output buffers
+/*
+ * The Network
+ *
+ * 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). */
 static void handle_net_output(int fd, struct virtqueue *vq)
@@ -831,8 +845,9 @@ static void handle_net_output(int fd, struct virtqueue *vq)
        while ((head = get_vq_desc(vq, iov, &out, &in)) != vq->vring.num) {
                if (in)
                        errx(1, "Input buffers in output queue?");
-               /* Check header, but otherwise ignore it (we said we supported
-                * no features). */
+               /* Check header, but otherwise ignore it (we told the Guest we
+                * supported no features, so it shouldn't have anything
+                * interesting). */
                (void)convert(&iov[0], struct virtio_net_hdr);
                len = writev(vq->dev->fd, iov+1, out-1);
                add_used_and_trigger(fd, vq, head, len);
@@ -883,7 +898,8 @@ static bool handle_tun_input(int fd, struct device *dev)
        return true;
 }
 
-/* This callback ensures we try again, in case we stopped console or net
+/*L:215 This is the callback attached to the network and console input
+ * virtqueues: it ensures we try again, in case we stopped console or net
  * delivery because Guest didn't have any buffers. */
 static void enable_fd(int fd, struct virtqueue *vq)
 {
@@ -919,7 +935,7 @@ static void handle_output(int fd, unsigned long addr)
              strnlen(from_guest_phys(addr), guest_limit - addr));
 }
 
-/* This is called when the waker wakes us up: check for incoming file
+/* This is called when the Waker wakes us up: check for incoming file
  * descriptors. */
 static void handle_input(int fd)
 {
@@ -986,8 +1002,7 @@ static struct lguest_device_desc *new_dev_desc(u16 type)
 }
 
 /* Each device descriptor is followed by some configuration information.
- * The first byte is a "status" byte for the Guest to report what's happening.
- * After that are fields: u8 type, u8 len, [... len bytes...].
+ * Each configuration field looks like: u8 type, u8 len, [... len bytes...].
  *
  * This routine adds a new field to an existing device's descriptor.  It only
  * works for the last device, but that's OK because that's how we use it. */
@@ -1044,14 +1059,17 @@ static void add_virtqueue(struct device *dev, unsigned int num_descs,
        /* Link virtqueue back to device. */
        vq->dev = dev;
 
-       /* Set up handler. */
+       /* Set the routine to call when the Guest does something to this
+        * virtqueue. */
        vq->handle_output = handle_output;
+
+       /* Set the "Don't Notify Me" flag if we don't have a handler */
        if (!handle_output)
                vq->vring.used->flags = VRING_USED_F_NO_NOTIFY;
 }
 
 /* This routine does all the creation and setup of a new device, including
- * caling new_dev_desc() to allocate the descriptor and device memory. */
+ * calling new_dev_desc() to allocate the descriptor and device memory. */
 static struct device *new_device(const char *name, u16 type, int fd,
                                 bool (*handle_input)(int, struct device *))
 {
@@ -1060,7 +1078,7 @@ static struct device *new_device(const char *name, u16 type, int fd,
        /* Append to device list.  Prepending to a single-linked list is
         * easier, but the user expects the devices to be arranged on the bus
         * in command-line order.  The first network device on the command line
-        * is eth0, the first block device /dev/lgba, etc. */
+        * is eth0, the first block device /dev/vda, etc. */
        *devices.lastdev = dev;
        dev->next = NULL;
        devices.lastdev = &dev->next;
@@ -1104,7 +1122,7 @@ static void setup_console(void)
        /* The console needs two virtqueues: the input then the output.  When
         * they put something the input queue, we make sure we're listening to
         * stdin.  When they put something in the output queue, we write it to
-        * stdout.  */
+        * stdout. */
        add_virtqueue(dev, VIRTQUEUE_NUM, enable_fd);
        add_virtqueue(dev, VIRTQUEUE_NUM, handle_console_output);
 
@@ -1252,21 +1270,17 @@ static void setup_tun_net(const char *arg)
                verbose("attached to bridge: %s\n", br_name);
 }
 
-
-/*
- * Block device.
+/* Our block (disk) device should be really simple: the Guest asks for a block
+ * number and we read or write that position in the file.  Unfortunately, that
+ * was amazingly slow: the Guest waits until the read is finished before
+ * running anything else, even if it could have been doing useful work.
  *
- * Serving a block device is really easy: the Guest asks for a block number and
- * we read or write that position in the file.
- *
- * Unfortunately, this is amazingly slow: the Guest waits until the read is
- * finished before running anything else, even if it could be doing useful
- * work.  We could use async I/O, except it's reputed to suck so hard that
- * characters actually go missing from your code when you try to use it.
+ * We could use async I/O, except it's reputed to suck so hard that characters
+ * actually go missing from your code when you try to use it.
  *
  * So we farm the I/O out to thread, and communicate with it via a pipe. */
 
-/* This hangs off device->priv, with the data. */
+/* This hangs off device->priv. */
 struct vblk_info
 {
        /* The size of the file. */
@@ -1282,8 +1296,14 @@ struct vblk_info
         * Launcher triggers interrupt to Guest. */
        int done_fd;
 };
+/*:*/
 
-/* This is the core of the I/O thread.  It returns true if it did something. */
+/*L:210
+ * The Disk
+ *
+ * Remember that the block device is handled by a separate I/O thread.  We head
+ * straight into the core of that thread here:
+ */
 static bool service_io(struct device *dev)
 {
        struct vblk_info *vblk = dev->priv;
@@ -1294,10 +1314,14 @@ static bool service_io(struct device *dev)
        struct iovec iov[dev->vq->vring.num];
        off64_t off;
 
+       /* See if there's a request waiting.  If not, nothing to do. */
        head = get_vq_desc(dev->vq, iov, &out_num, &in_num);
        if (head == dev->vq->vring.num)
                return false;
 
+       /* Every block request should contain at least one output buffer
+        * (detailing the location on disk and the type of request) and one
+        * input buffer (to hold the result). */
        if (out_num == 0 || in_num == 0)
                errx(1, "Bad virtblk cmd %u out=%u in=%u",
                     head, out_num, in_num);
@@ -1306,10 +1330,15 @@ static bool service_io(struct device *dev)
        in = convert(&iov[out_num+in_num-1], struct virtio_blk_inhdr);
        off = out->sector * 512;
 
-       /* This is how we implement barriers.  Pretty poor, no? */
+       /* The block device implements "barriers", where the Guest indicates
+        * that it wants all previous writes to occur before this write.  We
+        * don't have a way of asking our kernel to do a barrier, so we just
+        * synchronize all the data in the file.  Pretty poor, no? */
        if (out->type & VIRTIO_BLK_T_BARRIER)
                fdatasync(vblk->fd);
 
+       /* In general the virtio block driver is allowed to try SCSI commands.
+        * It'd be nice if we supported eject, for example, but we don't. */
        if (out->type & VIRTIO_BLK_T_SCSI_CMD) {
                fprintf(stderr, "Scsi commands unsupported\n");
                in->status = VIRTIO_BLK_S_UNSUPP;
@@ -1375,7 +1404,7 @@ static int io_thread(void *_dev)
 
        /* When this read fails, it means Launcher died, so we follow. */
        while (read(vblk->workpipe[0], &c, 1) == 1) {
-               /* We acknowledge each request immediately, to reduce latency,
+               /* 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. */
                while (service_io(dev))
@@ -1384,12 +1413,14 @@ static int io_thread(void *_dev)
        return 0;
 }
 
-/* When the thread says some I/O is done, we interrupt the Guest. */
+/* 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. */
 static bool handle_io_finish(int fd, struct device *dev)
 {
        char c;
 
-       /* If child died, presumably it printed message. */
+       /* If the I/O thread died, presumably it printed the error, so we
+        * simply exit. */
        if (read(dev->fd, &c, 1) != 1)
                exit(1);
 
@@ -1398,7 +1429,7 @@ static bool handle_io_finish(int fd, struct device *dev)
        return true;
 }
 
-/* When the Guest submits some I/O, we wake the I/O thread. */
+/* When the Guest submits some I/O, we just need to wake the I/O thread. */
 static void handle_virtblk_output(int fd, struct virtqueue *vq)
 {
        struct vblk_info *vblk = vq->dev->priv;
@@ -1410,7 +1441,7 @@ static void handle_virtblk_output(int fd, struct virtqueue *vq)
                exit(1);
 }
 
-/* This creates a virtual block device. */
+/*L:198 This actually sets up a virtual block device. */
 static void setup_block_file(const char *filename)
 {
        int p[2];
@@ -1426,7 +1457,7 @@ static void setup_block_file(const char *filename)
        /* The device responds to return from I/O thread. */
        dev = new_device("block", VIRTIO_ID_BLOCK, p[0], handle_io_finish);
 
-       /* The device has a virtqueue. */
+       /* The device has one virtqueue, where the Guest places requests. */
        add_virtqueue(dev, VIRTQUEUE_NUM, handle_virtblk_output);
 
        /* Allocate the room for our own bookkeeping */
@@ -1448,7 +1479,8 @@ static void setup_block_file(const char *filename)
        /* The I/O thread writes to this end of the pipe when done. */
        vblk->done_fd = p[1];
 
-       /* This is how we tell the I/O thread about more work. */
+       /* This is the second pipe, which is how we tell the I/O thread about
+        * more work. */
        pipe(vblk->workpipe);
 
        /* Create stack for thread and run it */
@@ -1487,24 +1519,25 @@ static void __attribute__((noreturn)) run_guest(int lguest_fd)
                        char reason[1024] = { 0 };
                        read(lguest_fd, reason, sizeof(reason)-1);
                        errx(1, "%s", reason);
-               /* EAGAIN means the waker wanted us to look at some input.
+               /* EAGAIN means the Waker wanted us to look at some input.
                 * Anything else means a bug or incompatible change. */
                } else if (errno != EAGAIN)
                        err(1, "Running guest failed");
 
-               /* Service input, then unset the BREAK which releases
-                * the Waker. */
+               /* Service input, then unset the BREAK to release the Waker. */
                handle_input(lguest_fd);
                if (write(lguest_fd, args, sizeof(args)) < 0)
                        err(1, "Resetting break");
        }
 }
 /*
- * This is the end of the Launcher.
+ * 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.
  *
- * But wait!  We've seen I/O from the Launcher, and we've seen I/O from the
- * Drivers.  If we were to see the Host kernel I/O code, our understanding
* would be complete... :*/
+ * Are you ready?  Take a deep breath and join me in the core of the Host, in
+ * "make Host".
+ :*/
 
 static struct option opts[] = {
        { "verbose", 0, NULL, 'v' },
@@ -1527,7 +1560,7 @@ int main(int argc, char *argv[])
        /* Memory, top-level pagetable, code startpoint and size of the
         * (optional) initrd. */
        unsigned long mem = 0, pgdir, start, initrd_size = 0;
-       /* A temporary and the /dev/lguest file descriptor. */
+       /* Two temporaries and the /dev/lguest file descriptor. */
        int i, c, lguest_fd;
        /* The boot information for the Guest. */
        struct boot_params *boot;
@@ -1622,6 +1655,7 @@ int main(int argc, char *argv[])
        /* The boot header contains a command line pointer: we put the command
         * line after the boot header. */
        boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1);
+       /* We use a simple helper to copy the arguments separated by spaces. */
        concat((char *)(boot + 1), argv+optind+2);
 
        /* Boot protocol version: 2.07 supports the fields for lguest. */
index 153d84d..f5a5e6d 100644 (file)
@@ -80,8 +80,6 @@ multicast.txt
        - Behaviour of cards under Multicast
 ncsa-telnet
        - notes on how NCSA telnet (DOS) breaks with MTU discovery enabled.
-net-modules.txt
-       - info and "insmod" parameters for all network driver modules.
 netdevices.txt
        - info on network device driver functions exported to the kernel.
 olympic.txt
index 747a5d1..6f7872b 100644 (file)
@@ -184,14 +184,14 @@ tcp_frto - INTEGER
        F-RTO is an enhanced recovery algorithm for TCP retransmission
        timeouts.  It is particularly beneficial in wireless environments
        where packet loss is typically due to random radio interference
-       rather than intermediate router congestion.  FRTO is sender-side
+       rather than intermediate router congestion.  F-RTO is sender-side
        only modification.  Therefore it does not require any support from
        the peer, but in a typical case, however, where wireless link is
        the local access link and most of the data flows downlink, the
-       faraway servers should have FRTO enabled to take advantage of it.
+       faraway servers should have F-RTO enabled to take advantage of it.
        If set to 1, basic version is enabled.  2 enables SACK enhanced
        F-RTO if flow uses SACK.  The basic version can be used also when
-       SACK is in use though scenario(s) with it exists where FRTO
+       SACK is in use though scenario(s) with it exists where F-RTO
        interacts badly with the packet counting of the SACK enabled TCP
        flow.
 
diff --git a/Documentation/networking/net-modules.txt b/Documentation/networking/net-modules.txt
deleted file mode 100644 (file)
index 98c4392..0000000
+++ /dev/null
@@ -1,315 +0,0 @@
-Wed 2-Aug-95  <matti.aarnio@utu.fi>
-
-               Linux network driver modules
-
-       Do not mistake this for "README.modules" at the top-level
-       directory!  That document tells about modules in general, while
-       this one tells only about network device driver modules.
-
-       This is a potpourri of INSMOD-time(*) configuration options
-       (if such exists) and their default values of various modules
-       in the Linux network drivers collection.
-
-       Some modules have also hidden (= non-documented) tunable values.
-       The choice of not documenting them is based on general belief, that
-       the less the user needs to know, the better.  (There are things that
-       driver developers can use, others should not confuse themselves.)
-
-       In many cases it is highly preferred that insmod:ing is done
-       ONLY with defining an explicit address for the card, AND BY
-       NOT USING AUTO-PROBING!
-
-       Now most cards have some explicitly defined base address that they
-       are compiled with (to avoid auto-probing, among other things).
-       If that compiled value does not match your actual configuration,
-       do use the "io=0xXXX" -parameter for the insmod, and give there
-       a value matching your environment.
-
-       If you are adventurous, you can ask the driver to autoprobe
-       by using the "io=0" parameter, however it is a potentially dangerous
-       thing to do in a live system.  (If you don't know where the
-       card is located, you can try autoprobing, and after possible
-       crash recovery, insmod with proper IO-address..)
-
-       --------------------------
-       (*)     "INSMOD-time" means when you load module with
-               /sbin/insmod  you can feed it optional parameters.
-               See "man insmod".
-       --------------------------
-
-
-       8390 based Network Modules              (Paul Gortmaker, Nov 12, 1995)
-       --------------------------
-
-(Includes: smc-ultra, ne, wd, 3c503, hp, hp-plus, e2100 and ac3200)
-
-The 8390 series of network drivers now support multiple card systems without 
-reloading the same module multiple times (memory efficient!) This is done by 
-specifying multiple comma separated values, such as:
-
-       insmod 3c503.o io=0x280,0x300,0x330,0x350  xcvr=0,1,0,1
-
-The above would have the one module controlling four 3c503 cards, with card 2
-and 4 using external transceivers. The "insmod" manual describes the usage
-of comma separated value lists.
-
-It is *STRONGLY RECOMMENDED* that you supply "io=" instead of autoprobing.
-If an "io=" argument is not supplied, then the ISA drivers will complain
-about autoprobing being not recommended, and begrudgingly autoprobe for
-a *SINGLE CARD ONLY* -- if you want to use multiple cards you *have* to 
-supply an "io=0xNNN,0xQQQ,..." argument.
-
-The ne module is an exception to the above. A NE2000 is essentially an
-8390 chip, some bus glue and some RAM. Because of this, the ne probe is
-more invasive than the rest, and so at boot we make sure the ne probe is 
-done last of all the 8390 cards (so that it won't trip over other 8390 based
-cards) With modules we can't ensure that all other non-ne 8390 cards have
-already been found. Because of this, the ne module REQUIRES an "io=0xNNN" 
-argument passed in via insmod. It will refuse to autoprobe.
-
-It is also worth noting that auto-IRQ probably isn't as reliable during 
-the flurry of interrupt activity on a running machine. Cards such as the 
-ne2000 that can't get the IRQ setting from an EEPROM or configuration
-register are probably best supplied with an "irq=M" argument as well.
-
-
-----------------------------------------------------------------------
-Card/Module List - Configurable Parameters and Default Values
-----------------------------------------------------------------------
-
-3c501.c:
-       io  = 0x280     IO base address
-       irq = 5         IRQ
-       (Probes ports:  0x280, 0x300)
-
-3c503.c:
-       io = 0          (It will complain if you don't supply an "io=0xNNN")
-       irq = 0         (IRQ software selected by driver using autoIRQ)
-       xcvr = 0        (Use xcvr=1 to select external transceiver.)
-       (Probes ports: 0x300, 0x310, 0x330, 0x350, 0x250, 0x280, 0x2A0, 0x2E0)
-
-3c505.c:
-       io = 0
-       irq = 0
-       dma = 6         (not autoprobed)
-       (Probes ports: 0x300, 0x280, 0x310)
-
-3c507.c:
-       io = 0x300
-       irq = 0
-       (Probes ports: 0x300, 0x320, 0x340, 0x280)
-
-3c509.c:
-       io = 0
-       irq = 0
-       ( Module load-time probing Works reliably only on EISA, ISA ID-PROBE
-         IS NOT RELIABLE!  Compile this driver statically into kernel for
-         now, if you need it auto-probing on an ISA-bus machine. )
-
-8390.c:
-       (No public options, several other modules need this one)
-
-a2065.c:
-       Since this is a Zorro board, it supports full autoprobing, even for
-       multiple boards. (m68k/Amiga)
-
-ac3200.c:
-       io = 0          (Checks 0x1000 to 0x8fff in 0x1000 intervals)
-       irq = 0         (Read from config register)
-       (EISA probing..)
-
-apricot.c:
-       io = 0x300  (Can't be altered!)
-       irq = 10
-
-arcnet.c:
-       io = 0
-       irqnum = 0
-       shmem = 0
-       num = 0
-       DO SET THESE MANUALLY AT INSMOD!
-       (When probing, looks at the following possible addresses:
-        Suggested ones:
-               0x300, 0x2E0, 0x2F0, 0x2D0
-        Other ones:
-               0x200, 0x210, 0x220, 0x230, 0x240, 0x250, 0x260, 0x270,
-               0x280, 0x290, 0x2A0, 0x2B0, 0x2C0,
-                      0x310, 0x320, 0x330, 0x340, 0x350, 0x360, 0x370,
-               0x380, 0x390, 0x3A0,                      0x3E0, 0x3F0  )
-
-ariadne.c:
-       Since this is a Zorro board, it supports full autoprobing, even for
-       multiple boards. (m68k/Amiga)
-
-at1700.c:
-       io = 0x260
-       irq = 0
-       (Probes ports: 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300)
-
-atarilance.c:
-       Supports full autoprobing. (m68k/Atari)
-
-atp.c: *Not modularized*
-       (Probes ports: 0x378, 0x278, 0x3BC;
-        fixed IRQs: 5 and 7                    )
-
-cops.c:
-       io = 0x240
-       irq = 5
-       nodeid = 0      (AutoSelect = 0, NodeID 1-254 is hand selected.)
-       (Probes ports: 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260,
-                      0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360) 
-
-de4x5.c:
-       io = 0x000b
-       irq = 10
-       is_not_dec = 0  -- For non-DEC card using DEC 21040/21041/21140 chip, set this to 1
-       (EISA, and PCI probing)
-
-de600.c:
-       de600_debug = 0
-       (On port 0x378, irq 7 -- lpt1;  compile time configurable)
-
-de620.c:
-       bnc = 0, utp = 0  <-- Force media by setting either.
-       io = 0x378      (also compile-time configurable)
-       irq = 7
-
-depca.c:
-       io = 0x200
-       irq = 7
-       (Probes ports:  ISA:  0x300, 0x200;
-                       EISA: 0x0c00            )
-
-dummy.c:
-       No options
-
-e2100.c:
-       io = 0          (It will complain if you don't supply an "io=0xNNN")
-       irq = 0         (IRQ software selected by driver)
-       mem = 0         (Override default shared memory start of 0xd0000)
-       xcvr = 0        (Use xcvr=1 to select external transceiver.)
-       (Probes ports: 0x300, 0x280, 0x380, 0x220)
-
-eepro.c:
-       io = 0x200
-       irq = 0
-       (Probes ports: 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340, 0x360)
-
-eexpress.c:
-       io = 0x300
-       irq = 0         (IRQ value read from EEPROM)
-       (Probes ports: 0x300, 0x270, 0x320, 0x340)
-
-eql.c:
-       (No parameters)
-
-ewrk3.c:
-       io = 0x300
-       irq = 5
-       (With module no autoprobing!
-        On EISA-bus does EISA probing.
-        Static linkage probes ports on ISA bus:
-               0x100, 0x120, 0x140, 0x160, 0x180, 0x1A0, 0x1C0,
-               0x200, 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x2E0,
-               0x300,        0x340, 0x360, 0x380, 0x3A0, 0x3C0)
-
-hp-plus.c:
-       io = 0          (It will complain if you don't supply an "io=0xNNN")
-       irq = 0         (IRQ read from configuration register)
-       (Probes ports: 0x200, 0x240, 0x280, 0x2C0, 0x300, 0x320, 0x340)
-
-hp.c:
-       io = 0          (It will complain if you don't supply an "io=0xNNN")
-       irq = 0         (IRQ software selected by driver using autoIRQ)
-       (Probes ports: 0x300, 0x320, 0x340, 0x280, 0x2C0, 0x200, 0x240)
-
-hp100.c:
-       hp100_port = 0 (IO-base address)
-       (Does EISA-probing, if on EISA-slot;
-        On ISA-bus probes all ports from 0x100 thru to 0x3E0
-        in increments of 0x020)
-
-hydra.c:
-       Since this is a Zorro board, it supports full autoprobing, even for
-       multiple boards. (m68k/Amiga)
-
-ibmtr.c:
-       io = 0xa20, 0xa24 (autoprobed by default)
-       irq = 0 (driver cannot select irq - read from hardware)
-       mem = 0 (shared memory base set at 0xd0000 and not yet 
-                able to override thru mem= parameter.)
-
-lance.c: *Not modularized*
-       (PCI, and ISA probing; "CONFIG_PCI" needed for PCI support)
-       (Probes ISA ports: 0x300, 0x320, 0x340, 0x360)
-
-loopback.c: *Static kernel component*
-
-ne.c:
-       io = 0          (Explicitly *requires* an "io=0xNNN" value)
-       irq = 0         (Tries to determine configured IRQ via autoIRQ)
-       (Probes ports: 0x300, 0x280, 0x320, 0x340, 0x360)
-
-net_init.c: *Static kernel component*
-
-ni52.c: *Not modularized*
-       (Probes ports:  0x300, 0x280, 0x360, 0x320, 0x340
-               mems:   0xD0000, 0xD2000, 0xC8000, 0xCA000,
-                       0xD4000, 0xD6000, 0xD8000 )
-
-ni65.c: *Not modularized*  **16MB MEMORY BARRIER BUG**
-       (Probes ports:  0x300, 0x320, 0x340, 0x360)
-
-pi2.c: *Not modularized* (well, NON-STANDARD modularization!)
-       Only one card supported at this time.
-       (Probes ports: 0x380, 0x300, 0x320, 0x340, 0x360, 0x3A0)
-
-plip.c:
-       io = 0
-       irq = 0         (by default, uses IRQ 5 for port at 0x3bc, IRQ 7
-                       for port at 0x378, and IRQ 2 for port at 0x278)
-       (Probes ports: 0x278, 0x378, 0x3bc)
-
-ppp.c:
-       No options (ppp-2.2+ has some, this is based on non-dynamic
-       version from ppp-2.1.2d)
-
-seeq8005.c: *Not modularized*
-       (Probes ports: 0x300, 0x320, 0x340, 0x360)
-
-skeleton.c: *Skeleton*
-
-slhc.c:
-       No configuration parameters
-
-slip.c:
-       slip_maxdev = 256 (default value from SL_NRUNIT on slip.h)
-
-
-smc-ultra.c:
-       io = 0          (It will complain if you don't supply an "io=0xNNN")
-       irq = 0         (IRQ val. read from EEPROM)
-       (Probes ports:  0x200, 0x220, 0x240, 0x280, 0x300, 0x340, 0x380)
-
-tulip.c: *Partial modularization*
-       (init-time memory allocation makes problems..)
-
-tunnel.c:
-       No insmod parameters
-
-wavelan.c:
-       io = 0x390      (Settable, but change not recommended)
-       irq = 0         (Not honoured, if changed..)
-
-wd.c:
-       io = 0          (It will complain if you don't supply an "io=0xNNN")
-       irq = 0         (IRQ val. read from EEPROM, ancient cards use autoIRQ)
-       mem = 0         (Force shared-memory on address 0xC8000, or whatever..)
-       mem_end = 0     (Force non-std. mem. size via supplying mem_end val.)
-                       (eg. for 32k WD8003EBT, use mem=0xd0000 mem_end=0xd8000)
-       (Probes ports:  0x300, 0x280, 0x380, 0x240)
-
-znet.c: *Not modularized*
-       (Only one device on  Zenith Z-Note (notebook?) systems,
-        configuration information from (EE)PROM)
diff --git a/Documentation/networking/tc-actions-env-rules.txt b/Documentation/networking/tc-actions-env-rules.txt
new file mode 100644 (file)
index 0000000..01e716d
--- /dev/null
@@ -0,0 +1,29 @@
+
+The "enviromental" rules for authors of any new tc actions are:
+
+1) If you stealeth or borroweth any packet thou shalt be branching
+from the righteous path and thou shalt cloneth.
+
+For example if your action queues a packet to be processed later
+or intentionaly branches by redirecting a packet then you need to
+clone the packet.
+There are certain fields in the skb tc_verd that need to be reset so we
+avoid loops etc. A few are generic enough so much so that skb_act_clone()
+resets them for you. So invoke skb_act_clone() rather than skb_clone()
+
+2) If you munge any packet thou shalt call pskb_expand_head in the case
+someone else is referencing the skb. After that you "own" the skb.
+You must also tell us if it is ok to munge the packet (TC_OK2MUNGE),
+this way any action downstream can stomp on the packet.
+
+3) dropping packets you dont own is a nono. You simply return
+TC_ACT_SHOT to the caller and they will drop it.
+
+The "enviromental" rules for callers of actions (qdiscs etc) are:
+
+*) thou art responsible for freeing anything returned as being
+TC_ACT_SHOT/STOLEN/QUEUED. If none of TC_ACT_SHOT/STOLEN/QUEUED is
+returned then all is great and you dont need to do anything.
+
+Post on netdev if something is unclear.
+
diff --git a/Documentation/scsi/link_power_management_policy.txt b/Documentation/scsi/link_power_management_policy.txt
new file mode 100644 (file)
index 0000000..d18993d
--- /dev/null
@@ -0,0 +1,19 @@
+This parameter allows the user to set the link (interface) power management.
+There are 3 possible options:
+
+Value                  Effect
+----------------------------------------------------------------------------
+min_power              Tell the controller to try to make the link use the
+                       least possible power when possible.  This may
+                       sacrifice some performance due to increased latency
+                       when coming out of lower power states.
+
+max_performance                Generally, this means no power management.  Tell
+                       the controller to have performance be a priority
+                       over power management.
+
+medium_power           Tell the controller to enter a lower power state
+                       when possible, but do not enter the lowest power
+                       state, thus improving latency over min_power setting.
+
+
index 3ceeb56..4a26f83 100644 (file)
@@ -2129,8 +2129,8 @@ S:        Maintained
 JOURNALLING FLASH FILE SYSTEM V2 (JFFS2)
 P:     David Woodhouse
 M:     dwmw2@infradead.org
-L:     jffs-dev@axis.com
-W:     http://sources.redhat.com/jffs2/
+L:     linux-mtd@lists.infradead.org
+W:     http://www.linux-mtd.infradead.org/doc/jffs2.html
 S:     Maintained
 
 JFS FILESYSTEM
@@ -2259,6 +2259,13 @@ L:       legousb-devel@lists.sourceforge.net
 W:     http://legousb.sourceforge.net/
 S:     Maintained
 
+LGUEST
+P:     Rusty Russell
+M:     rusty@rustcorp.com.au
+L:     lguest@ozlabs.org
+W:     http://lguest.ozlabs.org/
+S:     Maintained
+
 LINUX FOR IBM pSERIES (RS/6000)
 P:     Paul Mackerras
 M:     paulus@au.ibm.com
@@ -2442,13 +2449,15 @@ W:      http://www.tazenda.demon.co.uk/phil/linux-hp
 S:     Maintained
 
 MAC80211
-P:     Jiri Benc
-M:     jbenc@suse.cz
 P:     Michael Wu
 M:     flamingice@sourmilk.net
+P:     Johannes Berg
+M:     johannes@sipsolutions.net
+P:     Jiri Benc
+M:     jbenc@suse.cz
 L:     linux-wireless@vger.kernel.org
 W:     http://linuxwireless.org/
-T:     git kernel.org:/pub/scm/linux/kernel/git/jbenc/mac80211.git
+T:     git kernel.org:/pub/scm/linux/kernel/git/linville/wireless-2.6.git
 S:     Maintained
 
 MACVLAN DRIVER
@@ -4143,6 +4152,12 @@ W:       http://linuxtv.org
 T:     git kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb.git
 S:     Maintained
 
+VLAN (802.1Q)
+P:     Patrick McHardy
+M:     kaber@trash.net
+L:     netdev@vger.kernel.org
+S:     Maintained
+
 VT1211 HARDWARE MONITOR DRIVER
 P:     Juerg Haefliger
 M:     juergh@gmail.com
index 2a47290..8816060 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -196,6 +196,9 @@ CROSS_COMPILE       ?=
 UTS_MACHINE    := $(ARCH)
 SRCARCH        := $(ARCH)
 
+# for i386 and x86_64 we use SRCARCH equal to x86
+SRCARCH := $(if $(filter x86_64 i386,$(SRCARCH)),x86,$(SRCARCH))
+
 KCONFIG_CONFIG ?= .config
 
 # SHELL used by kbuild
@@ -418,7 +421,7 @@ ifeq ($(config-targets),1)
 # Read arch specific Makefile to set KBUILD_DEFCONFIG as needed.
 # KBUILD_DEFCONFIG may point out an alternative default configuration
 # used for 'make defconfig'
-include $(srctree)/arch/$(ARCH)/Makefile
+include $(srctree)/arch/$(SRCARCH)/Makefile
 export KBUILD_DEFCONFIG
 
 config %config: scripts_basic outputmakefile FORCE
@@ -497,7 +500,7 @@ else
 KBUILD_CFLAGS  += -O2
 endif
 
-include $(srctree)/arch/$(ARCH)/Makefile
+include $(srctree)/arch/$(SRCARCH)/Makefile
 
 ifdef CONFIG_FRAME_POINTER
 KBUILD_CFLAGS  += -fno-omit-frame-pointer -fno-optimize-sibling-calls
index a16cb03..d6b61d5 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/device.h>
 #include <linux/dma-mapping.h>
 #include <linux/io.h>
+#include <linux/scatterlist.h>
 #include <asm/cacheflush.h>
 #include <asm/bfin-global.h>
 
index 671ce1e..662f7b1 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/pci.h>
 #include <linux/highmem.h>
+#include <linux/scatterlist.h>
 #include <asm/io.h>
 
 void *dma_alloc_coherent(struct device *hwdev, size_t size, dma_addr_t *dma_handle, gfp_t gfp)
@@ -86,7 +87,7 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
        dampr2 = __get_DAMPR(2);
 
        for (i = 0; i < nents; i++) {
-               vaddr = kmap_atomic(sg[i].page, __KM_CACHE);
+               vaddr = kmap_atomic(sg_page(&sg[i]), __KM_CACHE);
 
                frv_dcache_writeback((unsigned long) vaddr,
                                     (unsigned long) vaddr + PAGE_SIZE);
diff --git a/arch/i386/.gitignore b/arch/i386/.gitignore
deleted file mode 100644 (file)
index 36ef4c3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-boot
index ef490e1..6f8c080 100644 (file)
@@ -9,10 +9,10 @@
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
 #include <linux/kernel.h>
+#include <linux/scatterlist.h>
 #include <linux/vmalloc.h>
 
 #include <asm/pgalloc.h>
-#include <asm/scatterlist.h>
 
 void *dma_alloc_coherent(struct device *dev, size_t size,
                         dma_addr_t *handle, gfp_t flag)
index f2eae45..f2d432e 100644 (file)
@@ -753,7 +753,7 @@ void __init pci_time_init(void)
        local_irq_enable();
 }
 
-static __inline__ unsigned long do_gettimeoffset(void)
+static inline unsigned long do_gettimeoffset(void)
 {
        /*
         * We divide all by 100
index 33f7a3d..77460e3 100644 (file)
@@ -1,7 +1,6 @@
-/*  $Id: process.c,v 1.161 2002/01/23 11:27:32 davem Exp $
- *  linux/arch/sparc/kernel/process.c
+/*  linux/arch/sparc/kernel/process.c
  *
- *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ *  Copyright (C) 1995 David S. Miller (davem@davemloft.net)
  *  Copyright (C) 1996 Eddie C. Dost   (ecd@skynet.be)
  */
 
@@ -397,7 +396,7 @@ void flush_thread(void)
        }
 }
 
-static __inline__ struct sparc_stackf __user *
+static inline struct sparc_stackf __user *
 clone_stackframe(struct sparc_stackf __user *dst,
                 struct sparc_stackf __user *src)
 {
index 4bf78a5..45cb7c5 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: time.c,v 1.60 2002/01/23 14:33:55 davem Exp $
- * linux/arch/sparc/kernel/time.c
+/* linux/arch/sparc/kernel/time.c
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
  *
  * Chris Davis (cdavis@cois.on.ca) 03/27/1998
@@ -210,7 +209,7 @@ static void __devinit kick_start_clock(void)
 }
 
 /* Return nonzero if the clock chip battery is low. */
-static __inline__ int has_low_battery(void)
+static inline int has_low_battery(void)
 {
        struct mostek48t02 *regs = (struct mostek48t02 *)mstk48t02_regs;
        unsigned char data1, data2;
@@ -252,7 +251,7 @@ static void __devinit mostek_set_system_time(void)
 }
 
 /* Probe for the real time clock chip on Sun4 */
-static __inline__ void sun4_clock_probe(void)
+static inline void sun4_clock_probe(void)
 {
 #ifdef CONFIG_SUN4
        int temp;
index ec4231c..a312d12 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: btfixup.c,v 1.10 2000/05/09 17:40:13 davem Exp $
- * btfixup.c: Boot time code fixup and relocator, so that
+/* btfixup.c: Boot time code fixup and relocator, so that
  * we can get rid of most indirect calls to achieve single
  * image sun4c and srmmu kernel.
  *
@@ -69,7 +68,7 @@ static void __init set_addr(unsigned int *addr, unsigned int q1, int fmangled, u
        }
 }
 #else
-static __inline__ void set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value)
+static inline void set_addr(unsigned int *addr, unsigned int q1, int fmangled, unsigned int value)
 {
        *addr = value;
 }
index 1666087..b86dfce 100644 (file)
@@ -144,7 +144,7 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
        spin_lock_irqsave(&iounit->lock, flags);
        while (sz != 0) {
                --sz;
-               sg->dvma_address = iounit_get_area(iounit, sg_virt(sg), sg->length);
+               sg->dvma_address = iounit_get_area(iounit, (unsigned long) sg_virt(sg), sg->length);
                sg->dvma_length = sg->length;
                sg = sg_next(sg);
        }
index a2cc141..0729305 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: sun4c.c,v 1.212 2001/12/21 04:56:15 davem Exp $
- * sun4c.c: Doing in software what should be done in hardware.
+/* sun4c.c: Doing in software what should be done in hardware.
  *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
  * Copyright (C) 1996 Andrew Tridgell (Andrew.Tridgell@anu.edu.au)
  * Copyright (C) 1997-2000 Anton Blanchard (anton@samba.org)
@@ -719,7 +718,7 @@ static void add_ring(struct sun4c_mmu_ring *ring,
        ring->num_entries++;
 }
 
-static __inline__ void add_lru(struct sun4c_mmu_entry *entry)
+static inline void add_lru(struct sun4c_mmu_entry *entry)
 {
        struct sun4c_mmu_ring *ring = &sun4c_ulru_ring;
        struct sun4c_mmu_entry *head = &ring->ringhd;
@@ -746,7 +745,7 @@ static void add_ring_ordered(struct sun4c_mmu_ring *ring,
        add_lru(entry);
 }
 
-static __inline__ void remove_ring(struct sun4c_mmu_ring *ring,
+static inline void remove_ring(struct sun4c_mmu_ring *ring,
                                   struct sun4c_mmu_entry *entry)
 {
        struct sun4c_mmu_entry *next = entry->next;
@@ -1836,7 +1835,7 @@ static unsigned long sun4c_pte_to_pgoff(pte_t pte)
 }
 
 
-static __inline__ unsigned long sun4c_pmd_page_v(pmd_t pmd)
+static inline unsigned long sun4c_pmd_page_v(pmd_t pmd)
 {
        return (pmd_val(pmd) & PAGE_MASK);
 }
@@ -1922,7 +1921,7 @@ static void sun4c_free_pgd_fast(pgd_t *pgd)
 }
 
 
-static __inline__ pte_t *
+static inline pte_t *
 sun4c_pte_alloc_one_fast(struct mm_struct *mm, unsigned long address)
 {
        unsigned long *ret;
@@ -1956,7 +1955,7 @@ static struct page *sun4c_pte_alloc_one(struct mm_struct *mm, unsigned long addr
        return virt_to_page(pte);
 }
 
-static __inline__ void sun4c_free_pte_fast(pte_t *pte)
+static inline void sun4c_free_pte_fast(pte_t *pte)
 {
        *(unsigned long *)pte = (unsigned long) pte_quicklist;
        pte_quicklist = (unsigned long *) pte;
index 9ad84ff..1587a29 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * binfmt_elf32.c: Support 32-bit Sparc ELF binaries on Ultra.
  *
- * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller        (davem@redhat.com)
+ * Copyright (C) 1995, 1996, 1997, 1998 David S. Miller        (davem@davemloft.net)
  * Copyright (C) 1995, 1996, 1997, 1998 Jakub Jelinek  (jj@ultra.linux.cz)
  */
 
@@ -133,7 +133,7 @@ struct elf_prpsinfo32
 
 #undef cputime_to_timeval
 #define cputime_to_timeval cputime_to_compat_timeval
-static __inline__ void
+static inline void
 cputime_to_compat_timeval(const cputime_t cputime, struct compat_timeval *value)
 {
        unsigned long jiffies = cputime_to_jiffies(cputime);
index 8230099..b61b8df 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: central.c,v 1.15 2001/12/19 00:29:51 davem Exp $
- * central.c: Central FHC driver for Sunfire/Starfire/Wildfire.
+/* central.c: Central FHC driver for Sunfire/Starfire/Wildfire.
  *
- * Copyright (C) 1997, 1999 David S. Miller (davem@redhat.com)
+ * Copyright (C) 1997, 1999 David S. Miller (davem@davemloft.net)
  */
 
 #include <linux/kernel.h>
@@ -385,7 +384,7 @@ void __init central_probe(void)
        init_all_fhc_hw();
 }
 
-static __inline__ void fhc_ledblink(struct linux_fhc *fhc, int on)
+static inline void fhc_ledblink(struct linux_fhc *fhc, int on)
 {
        u32 tmp;
 
@@ -402,7 +401,7 @@ static __inline__ void fhc_ledblink(struct linux_fhc *fhc, int on)
        upa_readl(fhc->fhc_regs.pregs + FHC_PREGS_CTRL);
 }
 
-static __inline__ void central_ledblink(struct linux_central *central, int on)
+static inline void central_ledblink(struct linux_central *central, int on)
 {
        u8 tmp;
 
index b70324e..efd5dff 100644 (file)
@@ -234,7 +234,7 @@ unsigned long prepare_sg(struct scatterlist *sg, int nents)
        dma_sg->dma_length = dent_len;
 
        if (dma_sg != sg) {
-               dma_sg = next_sg(dma_sg);
+               dma_sg = sg_next(dma_sg);
                dma_sg->dma_length = 0;
        }
 
index c8313cb..217478a 100644 (file)
@@ -2121,7 +2121,7 @@ int ldc_map_sg(struct ldc_channel *lp,
        state.nc = 0;
 
        for (i = 0; i < num_sg; i++)
-               fill_cookies(&state, page_to_pfn(sg[i].page) << PAGE_SHIFT,
+               fill_cookies(&state, page_to_pfn(sg_page(&sg[i])) << PAGE_SHIFT,
                             sg[i].offset, sg[i].length);
 
        return state.nc;
index a809e63..9974a68 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: semaphore.c,v 1.9 2001/11/18 00:12:56 davem Exp $
- * semaphore.c: Sparc64 semaphore implementation.
+/* semaphore.c: Sparc64 semaphore implementation.
  *
  * This is basically the PPC semaphore scheme ported to use
  * the sparc64 atomic instructions, so see the PPC code for
@@ -19,7 +18,7 @@
  *     sem->count = tmp;
  *     return old_count;
  */
-static __inline__ int __sem_update_count(struct semaphore *sem, int incr)
+static inline int __sem_update_count(struct semaphore *sem, int incr)
 {
        int old_count, tmp;
 
index 407d74a..7cd8d94 100644 (file)
@@ -459,7 +459,7 @@ again:
        }
 }
 
-static __inline__ void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
+static inline void spitfire_xcall_deliver(u64 data0, u64 data1, u64 data2, cpumask_t mask)
 {
        u64 pstate;
        int i;
@@ -906,7 +906,7 @@ extern atomic_t dcpage_flushes;
 extern atomic_t dcpage_flushes_xcall;
 #endif
 
-static __inline__ void __local_flush_dcache_page(struct page *page)
+static inline void __local_flush_dcache_page(struct page *page)
 {
 #ifdef DCACHE_ALIASING_POSSIBLE
        __flush_dcache_page(page_address(page),
index 560cb1e..c56573a 100644 (file)
@@ -318,7 +318,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
 
        if (flags & MAP_FIXED) {
                /* Ok, don't mess with it. */
-               return get_unmapped_area(NULL, addr, len, pgoff, flags);
+               return get_unmapped_area(NULL, orig_addr, len, pgoff, flags);
        }
        flags &= ~MAP_SHARED;
 
index e9c7e4f..0499838 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: traps.c,v 1.85 2002/02/09 19:49:31 davem Exp $
- * arch/sparc64/kernel/traps.c
+/* arch/sparc64/kernel/traps.c
  *
- * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995,1997 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1997,1999,2000 Jakub Jelinek (jakub@redhat.com)
  */
 
@@ -765,7 +764,7 @@ static unsigned long cheetah_afsr_errors;
  */
 struct cheetah_err_info *cheetah_error_log;
 
-static __inline__ struct cheetah_err_info *cheetah_get_error_log(unsigned long afsr)
+static inline struct cheetah_err_info *cheetah_get_error_log(unsigned long afsr)
 {
        struct cheetah_err_info *p;
        int cpu = smp_processor_id();
@@ -1085,7 +1084,7 @@ static unsigned char cheetah_mtag_syntab[] = {
 };
 
 /* Return the highest priority error conditon mentioned. */
-static __inline__ unsigned long cheetah_get_hipri(unsigned long afsr)
+static inline unsigned long cheetah_get_hipri(unsigned long afsr)
 {
        unsigned long tmp = 0;
        int i;
index 100c445..e18ccf8 100644 (file)
@@ -201,7 +201,7 @@ inline void flush_dcache_page_impl(struct page *page)
 #define dcache_dirty_cpu(page) \
        (((page)->flags >> PG_dcache_cpu_shift) & PG_dcache_cpu_mask)
 
-static __inline__ void set_dcache_dirty(struct page *page, int this_cpu)
+static inline void set_dcache_dirty(struct page *page, int this_cpu)
 {
        unsigned long mask = this_cpu;
        unsigned long non_cpu_bits;
@@ -223,7 +223,7 @@ static __inline__ void set_dcache_dirty(struct page *page, int this_cpu)
                             : "g1", "g7");
 }
 
-static __inline__ void clear_dcache_dirty_cpu(struct page *page, unsigned long cpu)
+static inline void clear_dcache_dirty_cpu(struct page *page, unsigned long cpu)
 {
        unsigned long mask = (1UL << PG_dcache_dirty);
 
index 3fafa9a..e1c3fc8 100644 (file)
@@ -1,8 +1,7 @@
-/* $Id: console.c,v 1.9 1997/10/29 07:41:43 ecd Exp $
- * console.c: Routines that deal with sending and receiving IO
+/* console.c: Routines that deal with sending and receiving IO
  *            to/from the current console device using the PROM.
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996,1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
  */
 
@@ -19,7 +18,7 @@ extern int prom_stdin, prom_stdout;
 /* Non blocking get character from console input device, returns -1
  * if no input was taken.  This can be used for polling.
  */
-__inline__ int
+inline int
 prom_nbgetchar(void)
 {
        char inc;
@@ -35,7 +34,7 @@ prom_nbgetchar(void)
 /* Non blocking put character to console device, returns -1 if
  * unsuccessful.
  */
-__inline__ int
+inline int
 prom_nbputchar(char c)
 {
        char outc;
index b2c5b12..a99ccd7 100644 (file)
 /* Return the child of node 'node' or zero if no this node has no
  * direct descendent.
  */
-__inline__ int
-__prom_getchild(int node)
+inline int __prom_getchild(int node)
 {
        return p1275_cmd ("child", P1275_INOUT(1, 1), node);
 }
 
-__inline__ int
-prom_getchild(int node)
+inline int prom_getchild(int node)
 {
        int cnode;
 
@@ -35,8 +33,7 @@ prom_getchild(int node)
        return (int)cnode;
 }
 
-__inline__ int
-prom_getparent(int node)
+inline int prom_getparent(int node)
 {
        int cnode;
 
@@ -49,14 +46,12 @@ prom_getparent(int node)
 /* Return the next sibling of node 'node' or zero if no more siblings
  * at this level of depth in the tree.
  */
-__inline__ int
-__prom_getsibling(int node)
+inline int __prom_getsibling(int node)
 {
        return p1275_cmd(prom_peer_name, P1275_INOUT(1, 1), node);
 }
 
-__inline__ int
-prom_getsibling(int node)
+inline int prom_getsibling(int node)
 {
        int sibnode;
 
@@ -72,8 +67,7 @@ prom_getsibling(int node)
 /* Return the length in bytes of property 'prop' at node 'node'.
  * Return -1 on error.
  */
-__inline__ int
-prom_getproplen(int node, const char *prop)
+inline int prom_getproplen(int node, const char *prop)
 {
        if((!node) || (!prop)) return -1;
        return p1275_cmd ("getproplen", 
@@ -86,8 +80,8 @@ prom_getproplen(int node, const char *prop)
  * 'buffer' which has a size of 'bufsize'.  If the acquisition
  * was successful the length will be returned, else -1 is returned.
  */
-__inline__ int
-prom_getproperty(int node, const char *prop, char *buffer, int bufsize)
+inline int prom_getproperty(int node, const char *prop,
+                           char *buffer, int bufsize)
 {
        int plen;
 
@@ -107,8 +101,7 @@ prom_getproperty(int node, const char *prop, char *buffer, int bufsize)
 /* Acquire an integer property and return its value.  Returns -1
  * on failure.
  */
-__inline__ int
-prom_getint(int node, const char *prop)
+inline int prom_getint(int node, const char *prop)
 {
        int intprop;
 
@@ -122,8 +115,7 @@ prom_getint(int node, const char *prop)
  * integer.
  */
 
-int
-prom_getintdefault(int node, const char *property, int deflt)
+int prom_getintdefault(int node, const char *property, int deflt)
 {
        int retval;
 
@@ -134,8 +126,7 @@ prom_getintdefault(int node, const char *property, int deflt)
 }
 
 /* Acquire a boolean property, 1=TRUE 0=FALSE. */
-int
-prom_getbool(int node, const char *prop)
+int prom_getbool(int node, const char *prop)
 {
        int retval;
 
@@ -148,8 +139,7 @@ prom_getbool(int node, const char *prop)
  * string on error.  The char pointer is the user supplied string
  * buffer.
  */
-void
-prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
+void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
 {
        int len;
 
@@ -163,8 +153,7 @@ prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
 /* Does the device at node 'node' have name 'name'?
  * YES = 1   NO = 0
  */
-int
-prom_nodematch(int node, const char *name)
+int prom_nodematch(int node, const char *name)
 {
        char namebuf[128];
        prom_getproperty(node, "name", namebuf, sizeof(namebuf));
@@ -175,8 +164,7 @@ prom_nodematch(int node, const char *name)
 /* Search siblings at 'node_start' for a node with name
  * 'nodename'.  Return node if successful, zero if not.
  */
-int
-prom_searchsiblings(int node_start, const char *nodename)
+int prom_searchsiblings(int node_start, const char *nodename)
 {
 
        int thisnode, error;
@@ -197,8 +185,7 @@ prom_searchsiblings(int node_start, const char *nodename)
 /* Return the first property type for node 'node'.
  * buffer should be at least 32B in length
  */
-__inline__ char *
-prom_firstprop(int node, char *buffer)
+inline char *prom_firstprop(int node, char *buffer)
 {
        *buffer = 0;
        if(node == -1) return buffer;
@@ -212,8 +199,7 @@ prom_firstprop(int node, char *buffer)
  * at node 'node' .  Returns NULL string if no more
  * property types for this node.
  */
-__inline__ char *
-prom_nextprop(int node, const char *oprop, char *buffer)
+inline char *prom_nextprop(int node, const char *oprop, char *buffer)
 {
        char buf[32];
 
@@ -279,8 +265,7 @@ prom_setprop(int node, const char *pname, char *value, int size)
                                          node, pname, value, P1275_SIZE(size));
 }
 
-__inline__ int
-prom_inst2pkg(int inst)
+inline int prom_inst2pkg(int inst)
 {
        int node;
        
index 9876d80..e0ac74e 100644 (file)
@@ -1,6 +1,6 @@
 menu "Host processor type and features"
 
-source "arch/i386/Kconfig.cpu"
+source "arch/x86/Kconfig.cpu"
 
 endmenu
 
index 0178df3..b01dfb0 100644 (file)
@@ -9,6 +9,7 @@ ELF_ARCH                := $(SUBARCH)
 ELF_FORMAT             := elf32-$(SUBARCH)
 OBJCOPYFLAGS           := -O binary -R .note -R .comment -S
 HEADER_ARCH            := x86
+CHECKFLAGS     += -D__i386__
 
 ifeq ("$(origin SUBARCH)", "command line")
 ifneq ("$(shell uname -m | sed -e s/i.86/i386/)", "$(SUBARCH)")
@@ -26,10 +27,8 @@ AFLAGS                       += -DCONFIG_X86_32
 CONFIG_X86_32          := y
 export CONFIG_X86_32
 
-ARCH_KERNEL_DEFINES += -U__$(SUBARCH)__ -U$(SUBARCH)
-
 # First of all, tune CFLAGS for the specific CPU. This actually sets cflags-y.
-include $(srctree)/arch/i386/Makefile.cpu
+include $(srctree)/arch/x86/Makefile_32.cpu
 
 # prevent gcc from keeping the stack 16 byte aligned. Taken from i386.
 cflags-y += $(call cc-option,-mpreferred-stack-boundary=2)
index fe5316f..8ed362f 100644 (file)
@@ -6,12 +6,9 @@ START := 0x60000000
 
 _extra_flags_ = -fno-builtin -m64
 
-#We #undef __x86_64__ for kernelspace, not for userspace where
-#it's needed for headers to work!
-ARCH_KERNEL_DEFINES = -U__$(SUBARCH)__
 KBUILD_CFLAGS += $(_extra_flags_)
 
-CHECKFLAGS  += -m64
+CHECKFLAGS  += -m64 -D__x86_64__
 KBUILD_AFLAGS += -m64
 LDFLAGS += -m elf_x86_64
 KBUILD_CPPFLAGS += -m64
index 3a8cd3d..e184b44 100644 (file)
@@ -35,6 +35,7 @@
 #include "linux/genhd.h"
 #include "linux/spinlock.h"
 #include "linux/platform_device.h"
+#include "linux/scatterlist.h"
 #include "asm/segment.h"
 #include "asm/uaccess.h"
 #include "asm/irq.h"
@@ -704,6 +705,7 @@ static int ubd_add(int n, char **error_out)
        ubd_dev->size = ROUND_BLOCK(ubd_dev->size);
 
        INIT_LIST_HEAD(&ubd_dev->restart);
+       sg_init_table(&ubd_dev->sg, MAX_SG);
 
        err = -ENOMEM;
        ubd_dev->queue = blk_init_queue(do_ubd_request, &ubd_dev->lock);
index 8456397..59822de 100644 (file)
@@ -165,7 +165,7 @@ static void __init kmap_init(void)
        kmap_prot = PAGE_KERNEL;
 }
 
-static void init_highmem(void)
+static void __init init_highmem(void)
 {
        pgd_t *pgd;
        pud_t *pud;
index 9657c89..bd3da8a 100644 (file)
@@ -155,7 +155,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
        if (err)
                return err;
 
-       n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
+       n = copy_to_user(buf, fpregs, sizeof(fpregs));
        if(n > 0)
                return -EFAULT;
 
@@ -168,7 +168,7 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
        long fpregs[HOST_FP_SIZE];
 
        BUG_ON(sizeof(*buf) != sizeof(fpregs));
-       n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
+       n = copy_from_user(fpregs, buf, sizeof(fpregs));
        if (n > 0)
                return -EFAULT;
 
@@ -185,7 +185,7 @@ int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
        if (err)
                return err;
 
-       n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
+       n = copy_to_user(buf, fpregs, sizeof(fpregs));
        if(n > 0)
                return -EFAULT;
 
@@ -198,7 +198,7 @@ int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
        long fpregs[HOST_XFP_SIZE];
 
        BUG_ON(sizeof(*buf) != sizeof(fpregs));
-       n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
+       n = copy_from_user(fpregs, buf, sizeof(fpregs));
        if (n > 0)
                return -EFAULT;
 
index a3cfeed..b7631b0 100644 (file)
@@ -154,7 +154,7 @@ int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
        if (err)
                return err;
 
-       n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
+       n = copy_to_user(buf, fpregs, sizeof(fpregs));
        if(n > 0)
                return -EFAULT;
 
@@ -167,7 +167,7 @@ int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
        long fpregs[HOST_FP_SIZE];
 
        BUG_ON(sizeof(*buf) != sizeof(fpregs));
-       n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
+       n = copy_from_user(fpregs, buf, sizeof(fpregs));
        if (n > 0)
                return -EFAULT;
 
similarity index 100%
rename from arch/i386/Kconfig.cpu
rename to arch/x86/Kconfig.cpu
similarity index 65%
rename from arch/i386/Kconfig.debug
rename to arch/x86/Kconfig.debug
index f03531e..970b2de 100644 (file)
@@ -1,14 +1,14 @@
 menu "Kernel hacking"
 
 config TRACE_IRQFLAGS_SUPPORT
-       bool
-       default y
+       def_bool y
 
 source "lib/Kconfig.debug"
 
 config EARLY_PRINTK
        bool "Early printk" if EMBEDDED && DEBUG_KERNEL
        default y
+       depends on X86_32
        help
          Write kernel log output directly into the VGA buffer or to a serial
          port.
@@ -37,10 +37,12 @@ config DEBUG_STACK_USAGE
 
 comment "Page alloc debug is incompatible with Software Suspend on i386"
        depends on DEBUG_KERNEL && HIBERNATION
+       depends on X86_32
 
 config DEBUG_PAGEALLOC
        bool "Debug page memory allocations"
        depends on DEBUG_KERNEL && !HIBERNATION && !HUGETLBFS
+       depends on X86_32
        help
          Unmap pages from the kernel linear mapping after free_pages().
          This results in a large slowdown, but helps to find certain types
@@ -59,6 +61,7 @@ config DEBUG_RODATA
 config 4KSTACKS
        bool "Use 4Kb for kernel stacks instead of 8Kb"
        depends on DEBUG_KERNEL
+       depends on X86_32
        help
          If you say Y here the kernel will use a 4Kb stacksize for the
          kernel stack attached to each process/thread. This facilitates
@@ -67,22 +70,50 @@ config 4KSTACKS
          will also use IRQ stacks to compensate for the reduced stackspace.
 
 config X86_FIND_SMP_CONFIG
-       bool
+       def_bool y
        depends on X86_LOCAL_APIC || X86_VOYAGER
-       default y
+       depends on X86_32
 
 config X86_MPPARSE
-       bool
+       def_bool y
        depends on X86_LOCAL_APIC && !X86_VISWS
-       default y
+       depends on X86_32
 
 config DOUBLEFAULT
        default y
        bool "Enable doublefault exception handler" if EMBEDDED
+       depends on X86_32
+       help
+         This option allows trapping of rare doublefault exceptions that
+         would otherwise cause a system to silently reboot. Disabling this
+         option saves about 4k and might cause you much additional grey
+         hair.
+
+config IOMMU_DEBUG
+       bool "Enable IOMMU debugging"
+       depends on IOMMU && DEBUG_KERNEL
+       depends on X86_64
        help
-          This option allows trapping of rare doublefault exceptions that
-          would otherwise cause a system to silently reboot. Disabling this
-          option saves about 4k and might cause you much additional grey
-          hair.
+         Force the IOMMU to on even when you have less than 4GB of
+         memory and add debugging code. On overflow always panic. And
+         allow to enable IOMMU leak tracing. Can be disabled at boot
+         time with iommu=noforce. This will also enable scatter gather
+         list merging.  Currently not recommended for production
+         code. When you use it make sure you have a big enough
+         IOMMU/AGP aperture.  Most of the options enabled by this can
+         be set more finegrained using the iommu= command line
+         options. See Documentation/x86_64/boot-options.txt for more
+         details.
+
+config IOMMU_LEAK
+       bool "IOMMU leak tracing"
+       depends on DEBUG_KERNEL
+       depends on IOMMU_DEBUG
+       help
+         Add a simple leak tracer to the IOMMU code. This is useful when you
+         are debugging a buggy device driver that leaks IOMMU mappings.
+
+#config X86_REMOTE_DEBUG
+#      bool "kgdb debugging stub"
 
 endmenu
similarity index 99%
rename from arch/i386/Kconfig
rename to arch/x86/Kconfig.i386
index b4437ce..7331efe 100644 (file)
@@ -287,7 +287,7 @@ config ES7000_CLUSTERED_APIC
        default y
        depends on SMP && X86_ES7000 && MPENTIUMIII
 
-source "arch/i386/Kconfig.cpu"
+source "arch/x86/Kconfig.cpu"
 
 config HPET_TIMER
        bool "HPET Timer Support"
@@ -1272,7 +1272,7 @@ source "fs/Kconfig"
 
 source "kernel/Kconfig.instrumentation"
 
-source "arch/i386/Kconfig.debug"
+source "arch/x86/Kconfig.debug"
 
 source "security/Kconfig"
 
similarity index 99%
rename from arch/x86_64/Kconfig
rename to arch/x86/Kconfig.x86_64
index 308970a..e2542e5 100644 (file)
@@ -835,7 +835,7 @@ source fs/Kconfig
 
 source "kernel/Kconfig.instrumentation"
 
-source "arch/x86_64/Kconfig.debug"
+source "arch/x86/Kconfig.debug"
 
 source "security/Kconfig"
 
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
new file mode 100644 (file)
index 0000000..3095973
--- /dev/null
@@ -0,0 +1,16 @@
+# Unified Makefile for i386 and x86_64
+
+# select defconfig based on actual architecture
+KBUILD_DEFCONFIG := $(ARCH)_defconfig
+
+# # No need to remake these files
+$(srctree)/arch/x86/Makefile%: ;
+
+ifeq ($(ARCH),i386)
+        include $(srctree)/arch/x86/Makefile_32
+else
+        include $(srctree)/arch/x86/Makefile_64
+endif
+
+
+
similarity index 98%
rename from arch/i386/Makefile
rename to arch/x86/Makefile_32
index f5b9a37..346ac07 100644 (file)
@@ -1,5 +1,5 @@
 #
-# i386/Makefile
+# i386 Makefile
 #
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
@@ -17,9 +17,6 @@
 # 20050320  Kianusch Sayah Karadji <kianusch@sk-tech.net>
 #           Added support for GEODE CPU
 
-# Fill in SRCARCH
-SRCARCH        := x86
-
 # BITS is used as extension for files which are available in a 32 bit
 # and a 64 bit version to simplify shared Makefiles.
 # e.g.: obj-y += foo_$(BITS).o
@@ -46,7 +43,7 @@ KBUILD_CFLAGS += -pipe -msoft-float -mregparm=3 -freg-struct-return
 KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2)
 
 # CPU-specific tuning. Anything which can be shared with UML should go here.
-include $(srctree)/arch/i386/Makefile.cpu
+include $(srctree)/arch/x86/Makefile_32.cpu
 
 # temporary until string.h is fixed
 cflags-y += -ffreestanding
similarity index 99%
rename from arch/x86_64/Makefile
rename to arch/x86/Makefile_64
index 20eb69b..57e714a 100644 (file)
@@ -1,5 +1,5 @@
 #
-# x86_64/Makefile
+# x86_64 Makefile
 #
 # This file is included by the global makefile so that you can add your own
 # architecture-specific flags and dependencies. Remember to do have actions
@@ -21,9 +21,6 @@
 #
 # $Id: Makefile,v 1.31 2002/03/22 15:56:07 ak Exp $
 
-# Fill in SRCARCH
-SRCARCH        := x86
-
 # BITS is used as extension for files which are available in a 32 bit
 # and a 64 bit version to simplify shared Makefiles.
 # e.g.: obj-y += foo_$(BITS).o
index 5f9a2e7..d2b5adf 100644 (file)
@@ -17,6 +17,8 @@
 #ifndef BOOT_BOOT_H
 #define BOOT_BOOT_H
 
+#define STACK_SIZE     512     /* Minimum number of bytes for stack */
+
 #ifndef __ASSEMBLY__
 
 #include <stdarg.h>
@@ -198,8 +200,6 @@ static inline int isdigit(int ch)
 }
 
 /* Heap -- available for dynamic lists. */
-#define STACK_SIZE     512     /* Minimum number of bytes for stack */
-
 extern char _end[];
 extern char *HEAP;
 extern char *heap_end;
@@ -216,9 +216,9 @@ static inline char *__get_heap(size_t s, size_t a, size_t n)
 #define GET_HEAP(type, n) \
        ((type *)__get_heap(sizeof(type),__alignof__(type),(n)))
 
-static inline int heap_free(void)
+static inline bool heap_free(size_t n)
 {
-       return heap_end-HEAP;
+       return (int)(heap_end-HEAP) >= (int)n;
 }
 
 /* copy.S */
index a0ae2e7..036e635 100644 (file)
        .globl startup_32
 
 startup_32:
-       /* check to see if KEEP_SEGMENTS flag is meaningful */
-       cmpw $0x207, BP_version(%esi)
-       jb 1f
-
+       cld
        /* test KEEP_SEGMENTS flag to see if the bootloader is asking
         * us to not reload segments */
        testb $(1<<6), BP_loadflags(%esi)
-       jnz 2f
+       jnz 1f
 
-1:     cli
+       cli
        movl $(__BOOT_DS),%eax
        movl %eax,%ds
        movl %eax,%es
        movl %eax,%fs
        movl %eax,%gs
        movl %eax,%ss
-
-2:     cld
+1:
 
 /* Calculate the delta between where we were compiled to run
  * at and where we were actually loaded at.  This can only be done
index 4946764..1ccb38a 100644 (file)
@@ -29,6 +29,7 @@
 #include <asm/pgtable.h>
 #include <asm/page.h>
 #include <asm/msr.h>
+#include <asm/asm-offsets.h>
 
 .section ".text.head"
        .code32
 
 startup_32:
        cld
+       /* test KEEP_SEGMENTS flag to see if the bootloader is asking
+        * us to not reload segments */
+       testb $(1<<6), BP_loadflags(%esi)
+       jnz 1f
+
        cli
        movl    $(__KERNEL_DS), %eax
        movl    %eax, %ds
        movl    %eax, %es
        movl    %eax, %ss
+1:
 
 /* Calculate the delta between where we were compiled to run
  * at and where we were actually loaded at.  This can only be done
index 8353c81..6ef5a06 100644 (file)
@@ -173,7 +173,8 @@ ramdisk_size:       .long   0               # its size in bytes
 bootsect_kludge:
                .long   0               # obsolete
 
-heap_end_ptr:  .word   _end+1024       # (Header version 0x0201 or later)
+heap_end_ptr:  .word   _end+STACK_SIZE-512
+                                       # (Header version 0x0201 or later)
                                        # space from here (exclusive) down to
                                        # end of setup code can be used by setup
                                        # for local heap purposes.
@@ -230,28 +231,53 @@ start_of_setup:
        int     $0x13
 #endif
 
-# We will have entered with %cs = %ds+0x20, normalize %cs so
-# it is on par with the other segments.
-       pushw   %ds
-       pushw   $setup2
-       lretw
-
-setup2:
 # Force %es = %ds
        movw    %ds, %ax
        movw    %ax, %es
        cld
 
-# Stack paranoia: align the stack and make sure it is good
-# for both 16- and 32-bit references.  In particular, if we
-# were meant to have been using the full 16-bit segment, the
-# caller might have set %sp to zero, which breaks %esp-based
-# references.
-       andw    $~3, %sp        # dword align (might as well...)
-       jnz     1f
-       movw    $0xfffc, %sp    # Make sure we're not zero
-1:     movzwl  %sp, %esp       # Clear upper half of %esp
-       sti
+# Apparently some ancient versions of LILO invoked the kernel
+# with %ss != %ds, which happened to work by accident for the
+# old code.  If the CAN_USE_HEAP flag is set in loadflags, or
+# %ss != %ds, then adjust the stack pointer.
+
+       # Smallest possible stack we can tolerate
+       movw    $(_end+STACK_SIZE), %cx
+
+       movw    heap_end_ptr, %dx
+       addw    $512, %dx
+       jnc     1f
+       xorw    %dx, %dx        # Wraparound - whole segment available
+1:     testb   $CAN_USE_HEAP, loadflags
+       jnz     2f
+
+       # No CAN_USE_HEAP
+       movw    %ss, %dx
+       cmpw    %ax, %dx        # %ds == %ss?
+       movw    %sp, %dx
+       # If so, assume %sp is reasonably set, otherwise use
+       # the smallest possible stack.
+       jne     4f              # -> Smallest possible stack...
+
+       # Make sure the stack is at least minimum size.  Take a value
+       # of zero to mean "full segment."
+2:
+       andw    $~3, %dx        # dword align (might as well...)
+       jnz     3f
+       movw    $0xfffc, %dx    # Make sure we're not zero
+3:     cmpw    %cx, %dx
+       jnb     5f
+4:     movw    %cx, %dx        # Minimum value we can possibly use
+5:     movw    %ax, %ss
+       movzwl  %dx, %esp       # Clear upper half of %esp
+       sti                     # Now we should have a working stack
+
+# We will have entered with %cs = %ds+0x20, normalize %cs so
+# it is on par with the other segments.
+       pushw   %ds
+       pushw   $6f
+       lretw
+6:
 
 # Check signature at end of setup
        cmpl    $0x5a5aaa55, setup_sig
index 68e65d9..ed0672a 100644 (file)
@@ -79,7 +79,7 @@ static int bios_probe(void)
        video_bios.modes = GET_HEAP(struct mode_info, 0);
 
        for (mode = 0x14; mode <= 0x7f; mode++) {
-               if (heap_free() < sizeof(struct mode_info))
+               if (!heap_free(sizeof(struct mode_info)))
                        break;
 
                if (mode_defined(VIDEO_FIRST_BIOS+mode))
index 1921907..4716b9a 100644 (file)
@@ -57,7 +57,7 @@ static int vesa_probe(void)
        while ((mode = rdfs16(mode_ptr)) != 0xffff) {
                mode_ptr += 2;
 
-               if (heap_free() < sizeof(struct mode_info))
+               if (!heap_free(sizeof(struct mode_info)))
                        break;  /* Heap full, can't save mode info */
 
                if (mode & ~0x1ff)
index e4ba897..ad9712f 100644 (file)
@@ -371,7 +371,7 @@ static void save_screen(void)
        saved.curx = boot_params.screen_info.orig_x;
        saved.cury = boot_params.screen_info.orig_y;
 
-       if (heap_free() < saved.x*saved.y*sizeof(u16)+512)
+       if (!heap_free(saved.x*saved.y*sizeof(u16)+512))
                return;         /* Not enough heap to save the screen */
 
        saved.data = GET_HEAP(u16, saved.x*saved.y);
index 2ed0a4c..f63e5ff 100644 (file)
@@ -62,8 +62,7 @@ static void init_intel_pdc(struct acpi_processor *pr, struct cpuinfo_x86 *c)
 /* Initialize _PDC data based on the CPU vendor */
 void arch_acpi_processor_init_pdc(struct acpi_processor *pr)
 {
-       unsigned int cpu = pr->id;
-       struct cpuinfo_x86 *c = &cpu_data(cpu);
+       struct cpuinfo_x86 *c = &cpu_data(pr->id);
 
        pr->pdc = NULL;
        if (c->x86_vendor == X86_VENDOR_INTEL)
index 7e50bda..d1b6ed9 100644 (file)
 #include <asm/segment.h>
 #include <asm/thread_info.h>
 #include <asm/ia32.h>
+#include <asm/bootparam.h>
 
 #define DEFINE(sym, val) \
         asm volatile("\n->" #sym " %0 " #val : : "i" (val))
 
 #define BLANK() asm volatile("\n->" : : )
 
+#define OFFSET(sym, str, mem) \
+       DEFINE(sym, offsetof(struct str, mem))
+
 #define __NO_STUBS 1
 #undef __SYSCALL
 #undef _ASM_X86_64_UNISTD_H_
@@ -109,5 +113,11 @@ int main(void)
        DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
        BLANK();
        DEFINE(__NR_syscall_max, sizeof(syscalls) - 1);
+
+       BLANK();
+       OFFSET(BP_scratch, boot_params, scratch);
+       OFFSET(BP_loadflags, boot_params, hdr.loadflags);
+       OFFSET(BP_hardware_subarch, boot_params, hdr.hardware_subarch);
+       OFFSET(BP_version, boot_params, hdr.version);
        return 0;
 }
index af0253f..8bb482f 100644 (file)
@@ -25,7 +25,7 @@
 #include <linux/kdebug.h>
 #include <asm/smp.h>
 
-#ifdef X86_32
+#ifdef CONFIG_X86_32
 #include <mach_ipi.h>
 #else
 #include <asm/mach_apic.h>
@@ -41,7 +41,7 @@ static int crash_nmi_callback(struct notifier_block *self,
                        unsigned long val, void *data)
 {
        struct pt_regs *regs;
-#ifdef X86_32
+#ifdef CONFIG_X86_32
        struct pt_regs fixed_regs;
 #endif
        int cpu;
@@ -60,7 +60,7 @@ static int crash_nmi_callback(struct notifier_block *self,
                return NOTIFY_STOP;
        local_irq_disable();
 
-#ifdef X86_32
+#ifdef CONFIG_X86_32
        if (!user_mode_vm(regs)) {
                crash_fixup_ss_esp(&fixed_regs, regs);
                regs = &fixed_regs;
index dc34acb..639e632 100644 (file)
@@ -35,12 +35,14 @@ static void __init via_bugs(void)
 }
 
 #ifdef CONFIG_ACPI
+#ifdef CONFIG_X86_IO_APIC
 
 static int __init nvidia_hpet_check(struct acpi_table_header *header)
 {
        return 0;
 }
-#endif
+#endif /* CONFIG_X86_IO_APIC */
+#endif /* CONFIG_ACPI */
 
 static void __init nvidia_bugs(void)
 {
index 0d8577f..aa3d2c8 100644 (file)
@@ -233,6 +233,8 @@ NORET_TYPE void machine_kexec(struct kimage *image)
 
 void arch_crash_save_vmcoreinfo(void)
 {
+       VMCOREINFO_SYMBOL(init_level4_pgt);
+
 #ifdef CONFIG_ARCH_DISCONTIGMEM_ENABLE
        VMCOREINFO_SYMBOL(node_data);
        VMCOREINFO_LENGTH(node_data, MAX_NUMNODES);
index c56e9ee..79b514b 100644 (file)
@@ -338,7 +338,6 @@ static int __dma_map_cont(struct scatterlist *start, int nelems,
                
                BUG_ON(s != start && s->offset);
                if (s == start) {
-                       *sout = *s; 
                        sout->dma_address = iommu_bus_base;
                        sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
                        sout->dma_length = s->length;
@@ -365,7 +364,7 @@ static inline int dma_map_cont(struct scatterlist *start, int nelems,
 {
        if (!need) {
                BUG_ON(nelems != 1);
-               *sout = *start;
+               sout->dma_address = start->dma_address;
                sout->dma_length = start->length;
                return 0;
        }
@@ -436,7 +435,7 @@ static int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents,
 
 error:
        flush_gart();
-       gart_unmap_sg(dev, sg, nents, dir);
+       gart_unmap_sg(dev, sg, out, dir);
        /* When it was forced or merged try again in a dumb way */
        if (force_iommu || iommu_merge) {
                out = dma_map_sg_nonforce(dev, sg, nents, dir);
index f321153..fcaa026 100644 (file)
@@ -708,10 +708,4 @@ struct smp_ops smp_ops = {
        .smp_send_reschedule = native_smp_send_reschedule,
        .smp_call_function_mask = native_smp_call_function_mask,
 };
-
-int smp_call_function_mask(cpumask_t mask, void (*func) (void *info),
-                          void *info, int wait)
-{
-       return smp_ops.smp_call_function_mask(mask, func, info, wait);
-}
-EXPORT_SYMBOL(smp_call_function_mask);
+EXPORT_SYMBOL_GPL(smp_ops);
index d2235db..a55b090 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/lguest.h>
 #include <linux/lguest_launcher.h>
 #include <linux/virtio_console.h>
+#include <linux/pm.h>
 #include <asm/paravirt.h>
 #include <asm/param.h>
 #include <asm/page.h>
@@ -98,7 +99,7 @@ static cycle_t clock_base;
  * When lazy_mode is set, it means we're allowed to defer all hypercalls and do
  * them as a batch when lazy_mode is eventually turned off.  Because hypercalls
  * are reasonably expensive, batching them up makes sense.  For example, a
- * large mmap might update dozens of page table entries: that code calls
+ * large munmap might update dozens of page table entries: that code calls
  * paravirt_enter_lazy_mmu(), does the dozen updates, then calls
  * lguest_leave_lazy_mode().
  *
@@ -163,8 +164,8 @@ void async_hcall(unsigned long call,
 /*:*/
 
 /*G:033
- * Here are our first native-instruction replacements: four functions for
- * interrupt control.
+ * After that diversion we return to our first native-instruction
+ * replacements: four functions for interrupt control.
  *
  * The simplest way of implementing these would be to have "turn interrupts
  * off" and "turn interrupts on" hypercalls.  Unfortunately, this is too slow:
@@ -183,7 +184,7 @@ static unsigned long save_fl(void)
        return lguest_data.irq_enabled;
 }
 
-/* "restore_flags" just sets the flags back to the value given. */
+/* restore_flags() just sets the flags back to the value given. */
 static void restore_fl(unsigned long flags)
 {
        lguest_data.irq_enabled = flags;
@@ -356,7 +357,7 @@ static void lguest_cpuid(unsigned int *eax, unsigned int *ebx,
  * it.  The Host needs to know when the Guest wants to change them, so we have
  * a whole series of functions like read_cr0() and write_cr0().
  *
- * We start with CR0.  CR0 allows you to turn on and off all kinds of basic
+ * We start with cr0.  cr0 allows you to turn on and off all kinds of basic
  * features, but Linux only really cares about one: the horrifically-named Task
  * Switched (TS) bit at bit 3 (ie. 8)
  *
@@ -371,8 +372,7 @@ static void lguest_cpuid(unsigned int *eax, unsigned int *ebx,
 static unsigned long current_cr0, current_cr3;
 static void lguest_write_cr0(unsigned long val)
 {
-       /* 8 == TS bit. */
-       lazy_hcall(LHCALL_TS, val & 8, 0, 0);
+       lazy_hcall(LHCALL_TS, val & X86_CR0_TS, 0, 0);
        current_cr0 = val;
 }
 
@@ -387,10 +387,10 @@ static unsigned long lguest_read_cr0(void)
 static void lguest_clts(void)
 {
        lazy_hcall(LHCALL_TS, 0, 0, 0);
-       current_cr0 &= ~8U;
+       current_cr0 &= ~X86_CR0_TS;
 }
 
-/* CR2 is the virtual address of the last page fault, which the Guest only ever
+/* cr2 is the virtual address of the last page fault, which the Guest only ever
  * reads.  The Host kindly writes this into our "struct lguest_data", so we
  * just read it out of there. */
 static unsigned long lguest_read_cr2(void)
@@ -398,7 +398,7 @@ static unsigned long lguest_read_cr2(void)
        return lguest_data.cr2;
 }
 
-/* CR3 is the current toplevel pagetable page: the principle is the same as
+/* cr3 is the current toplevel pagetable page: the principle is the same as
  * cr0.  Keep a local copy, and tell the Host when it changes. */
 static void lguest_write_cr3(unsigned long cr3)
 {
@@ -411,7 +411,7 @@ static unsigned long lguest_read_cr3(void)
        return current_cr3;
 }
 
-/* CR4 is used to enable and disable PGE, but we don't care. */
+/* cr4 is used to enable and disable PGE, but we don't care. */
 static unsigned long lguest_read_cr4(void)
 {
        return 0;
@@ -432,7 +432,7 @@ static void lguest_write_cr4(unsigned long val)
  * maps virtual addresses to physical addresses using "page tables".  We could
  * use one huge index of 1 million entries: each address is 4 bytes, so that's
  * 1024 pages just to hold the page tables.   But since most virtual addresses
- * are unused, we use a two level index which saves space.  The CR3 register
+ * are unused, we use a two level index which saves space.  The cr3 register
  * contains the physical address of the top level "page directory" page, which
  * contains physical addresses of up to 1024 second-level pages.  Each of these
  * second level pages contains up to 1024 physical addresses of actual pages,
@@ -440,7 +440,7 @@ static void lguest_write_cr4(unsigned long val)
  *
  * Here's a diagram, where arrows indicate physical addresses:
  *
- * CR3 ---> +---------+
+ * cr3 ---> +---------+
  *         |      --------->+---------+
  *         |         |      | PADDR1  |
  *       Top-level   |      | PADDR2  |
@@ -498,8 +498,7 @@ static void lguest_set_pmd(pmd_t *pmdp, pmd_t pmdval)
  *
  * ... except in early boot when the kernel sets up the initial pagetables,
  * which makes booting astonishingly slow.  So we don't even tell the Host
- * anything changed until we've done the first page table switch.
- */
+ * anything changed until we've done the first page table switch. */
 static void lguest_set_pte(pte_t *ptep, pte_t pteval)
 {
        *ptep = pteval;
@@ -720,10 +719,10 @@ static void lguest_time_init(void)
        /* Set up the timer interrupt (0) to go to our simple timer routine */
        set_irq_handler(0, lguest_time_irq);
 
-       /* Our clock structure look like arch/i386/kernel/tsc.c if we can use
-        * the TSC, otherwise it's a dumb nanosecond-resolution clock.  Either
-        * way, the "rating" is initialized so high that it's always chosen
-        * over any other clocksource. */
+       /* Our clock structure looks like arch/x86/kernel/tsc_32.c if we can
+        * use the TSC, otherwise it's a dumb nanosecond-resolution clock.
+        * Either way, the "rating" is set so high that it's always chosen over
+        * any other clocksource. */
        if (lguest_data.tsc_khz)
                lguest_clock.mult = clocksource_khz2mult(lguest_data.tsc_khz,
                                                         lguest_clock.shift);
@@ -749,7 +748,7 @@ static void lguest_time_init(void)
  * to work.  They're pretty simple.
  */
 
-/* The Guest needs to tell the host what stack it expects traps to use.  For
+/* The Guest needs to tell the Host what stack it expects traps to use.  For
  * native hardware, this is part of the Task State Segment mentioned above in
  * lguest_load_tr_desc(), but to help hypervisors there's this special call.
  *
@@ -850,13 +849,16 @@ static __init char *lguest_memory_setup(void)
        return "LGUEST";
 }
 
-/* Before virtqueues are set up, we use LHCALL_NOTIFY on normal memory to
- * produce console output. */
+/* We will eventually use the virtio console device to produce console output,
+ * but before that is set up we use LHCALL_NOTIFY on normal memory to produce
+ * console output. */
 static __init int early_put_chars(u32 vtermno, const char *buf, int count)
 {
        char scratch[17];
        unsigned int len = count;
 
+       /* We use a nul-terminated string, so we have to make a copy.  Icky,
+        * huh? */
        if (len > sizeof(scratch) - 1)
                len = sizeof(scratch) - 1;
        scratch[len] = '\0';
@@ -883,7 +885,7 @@ static __init int early_put_chars(u32 vtermno, const char *buf, int count)
  * Our current solution is to allow the paravirt back end to optionally patch
  * over the indirect calls to replace them with something more efficient.  We
  * patch the four most commonly called functions: disable interrupts, enable
- * interrupts, restore interrupts and save interrupts.  We usually have 10
+ * interrupts, restore interrupts and save interrupts.  We usually have 6 or 10
  * bytes to patch into: the Guest versions of these operations are small enough
  * that we can fit comfortably.
  *
@@ -1015,7 +1017,7 @@ __init void lguest_init(void)
        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 much it needs in
+        * Host<->Guest Switcher, and it tells us how big that is in
         * lguest_data.reserve_mem, set up on the LGUEST_INIT hypercall. */
        reserve_top_address(lguest_data.reserve_mem);
 
@@ -1065,6 +1067,6 @@ __init void lguest_init(void)
 /*
  * This marks the end of stage II of our journey, The Guest.
  *
- * It is now time for us to explore the nooks and crannies of the three Guest
- * devices and complete our understanding of the Guest in "make Drivers".
+ * It is now time for us to explore the layer of virtual drivers and complete
+ * our understanding of the Guest in "make Drivers".
  */
index ebc6ac7..95b6fbc 100644 (file)
@@ -6,7 +6,7 @@
 #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.  The boot header is in %esi.
+ * type field is "1" (lguest), so 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
  * boot. */
 .section .init.text, "ax", @progbits
 ENTRY(lguest_entry)
-       /* Make initial hypercall now, so we can set up the pagetables. */
+       /* We make the "initialization" hypercall now to tell the Host about
+        * us, and also find out where it put our page tables. */
        movl $LHCALL_LGUEST_INIT, %eax
        movl $lguest_data - __PAGE_OFFSET, %edx
        int $LGUEST_TRAP_ENTRY
 
        /* The Host put the toplevel pagetable in lguest_data.pgdir.  The movsl
-        * instruction uses %esi implicitly. */
+        * instruction uses %esi implicitly as the source for the copy we'
+        * about to do. */
        movl lguest_data - __PAGE_OFFSET + LGUEST_DATA_pgdir, %esi
 
        /* Copy first 32 entries of page directory to __PAGE_OFFSET entries.
index 361ac51..6937143 100644 (file)
 #include <asm/arch_hooks.h>
 
 /* TLB state -- visible externally, indexed physically */
-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate) ____cacheline_aligned = { &init_mm, 0 };
+DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate) = { &init_mm, 0 };
 
 /* CPU IRQ affinity -- set to all ones initially */
 static unsigned long cpu_irq_affinity[NR_CPUS] __cacheline_aligned = { [0 ... NR_CPUS-1]  = ~0UL };
 
 /* per CPU data structure (for /proc/cpuinfo et al), visible externally
  * indexed physically */
-DEFINE_PER_CPU(cpuinfo_x86, cpu_info) __cacheline_aligned;
+DEFINE_PER_CPU_SHARED_ALIGNED(struct cpuinfo_x86, cpu_info);
 EXPORT_PER_CPU_SYMBOL(cpu_info);
 
 /* physical ID of the CPU used to boot the system */
index 503dfc0..33563ee 100644 (file)
@@ -550,7 +550,7 @@ no_context:
                        page &= PAGE_MASK;
                        page = ((__typeof__(page) *) __va(page))[(address >> PMD_SHIFT)
                                                                 & (PTRS_PER_PMD - 1)];
-                       printk(KERN_ALERT "*pde = %016Lx ", page);
+                       printk(KERN_CONT "*pde = %016Lx ", page);
                        page &= ~_PAGE_NX;
                }
 #else
index 1e3862e..a7308b2 100644 (file)
@@ -728,12 +728,6 @@ int in_gate_area_no_task(unsigned long addr)
        return (addr >= VSYSCALL_START) && (addr < VSYSCALL_END);
 }
 
-void * __init alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
-{
-       return __alloc_bootmem_core(pgdat->bdata, size,
-                       SMP_CACHE_BYTES, (4UL*1024*1024*1024), 0);
-}
-
 const char *arch_vma_name(struct vm_area_struct *vma)
 {
        if (vma->vm_mm && vma->vm_start == (long)vma->vm_mm->context.vdso)
diff --git a/arch/x86_64/.gitignore b/arch/x86_64/.gitignore
deleted file mode 100644 (file)
index 36ef4c3..0000000
+++ /dev/null
@@ -1 +0,0 @@
-boot
diff --git a/arch/x86_64/Kconfig.debug b/arch/x86_64/Kconfig.debug
deleted file mode 100644 (file)
index 775d211..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-menu "Kernel hacking"
-
-config TRACE_IRQFLAGS_SUPPORT
-       bool
-       default y
-
-source "lib/Kconfig.debug"
-
-config DEBUG_RODATA
-       bool "Write protect kernel read-only data structures"
-       depends on DEBUG_KERNEL
-       help
-        Mark the kernel read-only data as write-protected in the pagetables,
-        in order to catch accidental (and incorrect) writes to such const data.
-        This option may have a slight performance impact because a portion
-        of the kernel code won't be covered by a 2MB TLB anymore.
-        If in doubt, say "N".
-
-config IOMMU_DEBUG
-       depends on IOMMU && DEBUG_KERNEL
-       bool "Enable IOMMU debugging"
-       help
-         Force the IOMMU to on even when you have less than 4GB of
-        memory and add debugging code. On overflow always panic. And
-        allow to enable IOMMU leak tracing. Can be disabled at boot
-        time with iommu=noforce. This will also enable scatter gather
-        list merging.  Currently not recommended for production
-        code. When you use it make sure you have a big enough
-        IOMMU/AGP aperture.  Most of the options enabled by this can
-        be set more finegrained using the iommu= command line
-        options. See Documentation/x86_64/boot-options.txt for more
-        details.
-
-config IOMMU_LEAK
-       bool "IOMMU leak tracing"
-       depends on DEBUG_KERNEL
-       depends on IOMMU_DEBUG
-       help
-         Add a simple leak tracer to the IOMMU code. This is useful when you
-        are debugging a buggy device driver that leaks IOMMU mappings.
-
-config DEBUG_STACKOVERFLOW
-        bool "Check for stack overflows"
-        depends on DEBUG_KERNEL
-        help
-         This option will cause messages to be printed if free stack space
-         drops below a certain limit.
-
-config DEBUG_STACK_USAGE
-        bool "Stack utilization instrumentation"
-        depends on DEBUG_KERNEL
-        help
-         Enables the display of the minimum amount of free stack which each
-         task has ever had available in the sysrq-T and sysrq-P debug output.
-
-         This option will slow down process creation somewhat.
-
-#config X86_REMOTE_DEBUG
-#       bool "kgdb debugging stub"
-
-endmenu
index 54dc054..e47a930 100644 (file)
@@ -1443,8 +1443,11 @@ cfq_get_queue(struct cfq_data *cfqd, int is_sync, struct task_struct *tsk,
                cfqq = *async_cfqq;
        }
 
-       if (!cfqq)
+       if (!cfqq) {
                cfqq = cfq_find_alloc_queue(cfqd, is_sync, tsk, gfp_mask);
+               if (!cfqq)
+                       return NULL;
+       }
 
        /*
         * pin the queue now that it's allocated, scheduler exit will prune it
@@ -2053,7 +2056,7 @@ static void cfq_shutdown_timer_wq(struct cfq_data *cfqd)
 {
        del_timer_sync(&cfqd->idle_slice_timer);
        del_timer_sync(&cfqd->idle_class_timer);
-       blk_sync_queue(cfqd->queue);
+       kblockd_flush_work(&cfqd->unplug_work);
 }
 
 static void cfq_put_async_queues(struct cfq_data *cfqd)
index f84093b..cae0a85 100644 (file)
@@ -581,7 +581,7 @@ static int compat_blkdev_driver_ioctl(struct inode *inode, struct file *file,
 {
        int ret;
 
-       switch (arg) {
+       switch (cmd) {
        case HDIO_GET_UNMASKINTR:
        case HDIO_GET_MULTCOUNT:
        case HDIO_GET_KEEPSETTINGS:
index de5ba47..56f2646 100644 (file)
@@ -39,7 +39,7 @@
 
 static void blk_unplug_work(struct work_struct *work);
 static void blk_unplug_timeout(unsigned long data);
-static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io);
+static void drive_stat_acct(struct request *rq, int new_io);
 static void init_request_from_bio(struct request *req, struct bio *bio);
 static int __make_request(struct request_queue *q, struct bio *bio);
 static struct io_context *current_io_context(gfp_t gfp_flags, int node);
@@ -791,7 +791,6 @@ static int __blk_free_tags(struct blk_queue_tag *bqt)
        retval = atomic_dec_and_test(&bqt->refcnt);
        if (retval) {
                BUG_ON(bqt->busy);
-               BUG_ON(!list_empty(&bqt->busy_list));
 
                kfree(bqt->tag_index);
                bqt->tag_index = NULL;
@@ -903,7 +902,6 @@ static struct blk_queue_tag *__blk_queue_init_tags(struct request_queue *q,
        if (init_tag_map(q, tags, depth))
                goto fail;
 
-       INIT_LIST_HEAD(&tags->busy_list);
        tags->busy = 0;
        atomic_set(&tags->refcnt, 1);
        return tags;
@@ -954,6 +952,7 @@ int blk_queue_init_tags(struct request_queue *q, int depth,
         */
        q->queue_tags = tags;
        q->queue_flags |= (1 << QUEUE_FLAG_QUEUED);
+       INIT_LIST_HEAD(&q->tag_busy_list);
        return 0;
 fail:
        kfree(tags);
@@ -1057,18 +1056,16 @@ void blk_queue_end_tag(struct request_queue *q, struct request *rq)
 
        bqt->tag_index[tag] = NULL;
 
-       /*
-        * We use test_and_clear_bit's memory ordering properties here.
-        * The tag_map bit acts as a lock for tag_index[bit], so we need
-        * a barrer before clearing the bit (precisely: release semantics).
-        * Could use clear_bit_unlock when it is merged.
-        */
-       if (unlikely(!test_and_clear_bit(tag, bqt->tag_map))) {
+       if (unlikely(!test_bit(tag, bqt->tag_map))) {
                printk(KERN_ERR "%s: attempt to clear non-busy tag (%d)\n",
                       __FUNCTION__, tag);
                return;
        }
-
+       /*
+        * The tag_map bit acts as a lock for tag_index[bit], so we need
+        * unlock memory barrier semantics.
+        */
+       clear_bit_unlock(tag, bqt->tag_map);
        bqt->busy--;
 }
 
@@ -1114,17 +1111,17 @@ int blk_queue_start_tag(struct request_queue *q, struct request *rq)
                if (tag >= bqt->max_depth)
                        return 1;
 
-       } while (test_and_set_bit(tag, bqt->tag_map));
+       } while (test_and_set_bit_lock(tag, bqt->tag_map));
        /*
-        * We rely on test_and_set_bit providing lock memory ordering semantics
-        * (could use test_and_set_bit_lock when it is merged).
+        * We need lock ordering semantics given by test_and_set_bit_lock.
+        * See blk_queue_end_tag for details.
         */
 
        rq->cmd_flags |= REQ_QUEUED;
        rq->tag = tag;
        bqt->tag_index[tag] = rq;
        blkdev_dequeue_request(rq);
-       list_add(&rq->queuelist, &bqt->busy_list);
+       list_add(&rq->queuelist, &q->tag_busy_list);
        bqt->busy++;
        return 0;
 }
@@ -1145,11 +1142,10 @@ EXPORT_SYMBOL(blk_queue_start_tag);
  **/
 void blk_queue_invalidate_tags(struct request_queue *q)
 {
-       struct blk_queue_tag *bqt = q->queue_tags;
        struct list_head *tmp, *n;
        struct request *rq;
 
-       list_for_each_safe(tmp, n, &bqt->busy_list) {
+       list_for_each_safe(tmp, n, &q->tag_busy_list) {
                rq = list_entry_rq(tmp);
 
                if (rq->tag == -1) {
@@ -1366,9 +1362,7 @@ new_segment:
                                sg = sg_next(sg);
                        }
 
-                       sg_set_page(sg, bvec->bv_page);
-                       sg->length = nbytes;
-                       sg->offset = bvec->bv_offset;
+                       sg_set_page(sg, bvec->bv_page, nbytes, bvec->bv_offset);
                        nsegs++;
                }
                bvprv = bvec;
@@ -1740,6 +1734,7 @@ EXPORT_SYMBOL(blk_stop_queue);
 void blk_sync_queue(struct request_queue *q)
 {
        del_timer_sync(&q->unplug_timer);
+       kblockd_flush_work(&q->unplug_work);
 }
 EXPORT_SYMBOL(blk_sync_queue);
 
@@ -2343,7 +2338,7 @@ void blk_insert_request(struct request_queue *q, struct request *rq,
        if (blk_rq_tagged(rq))
                blk_queue_end_tag(q, rq);
 
-       drive_stat_acct(rq, rq->nr_sectors, 1);
+       drive_stat_acct(rq, 1);
        __elv_add_request(q, rq, where, 0);
        blk_start_queueing(q);
        spin_unlock_irqrestore(q->queue_lock, flags);
@@ -2738,7 +2733,7 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
 
 EXPORT_SYMBOL(blkdev_issue_flush);
 
-static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
+static void drive_stat_acct(struct request *rq, int new_io)
 {
        int rw = rq_data_dir(rq);
 
@@ -2760,7 +2755,7 @@ static void drive_stat_acct(struct request *rq, int nr_sectors, int new_io)
  */
 static inline void add_request(struct request_queue * q, struct request * req)
 {
-       drive_stat_acct(req, req->nr_sectors, 1);
+       drive_stat_acct(req, 1);
 
        /*
         * elevator indicated where it wants this request to be
@@ -3017,7 +3012,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
                        req->biotail = bio;
                        req->nr_sectors = req->hard_nr_sectors += nr_sectors;
                        req->ioprio = ioprio_best(req->ioprio, prio);
-                       drive_stat_acct(req, nr_sectors, 0);
+                       drive_stat_acct(req, 0);
                        if (!attempt_back_merge(q, req))
                                elv_merged_request(q, req, el_ret);
                        goto out;
@@ -3044,7 +3039,7 @@ static int __make_request(struct request_queue *q, struct bio *bio)
                        req->sector = req->hard_sector = bio->bi_sector;
                        req->nr_sectors = req->hard_nr_sectors += nr_sectors;
                        req->ioprio = ioprio_best(req->ioprio, prio);
-                       drive_stat_acct(req, nr_sectors, 0);
+                       drive_stat_acct(req, 0);
                        if (!attempt_front_merge(q, req))
                                elv_merged_request(q, req, el_ret);
                        goto out;
index e4eb6ac..0f05be7 100644 (file)
@@ -61,7 +61,7 @@ static int hmac_setkey(struct crypto_hash *parent,
                desc.tfm = tfm;
                desc.flags = crypto_hash_get_flags(parent);
                desc.flags &= CRYPTO_TFM_REQ_MAY_SLEEP;
-               sg_set_buf(&tmp, inkey, keylen);
+               sg_init_one(&tmp, inkey, keylen);
 
                err = crypto_hash_digest(&desc, &tmp, keylen, digest);
                if (err)
@@ -96,7 +96,7 @@ static int hmac_init(struct hash_desc *pdesc)
 
        desc.tfm = ctx->child;
        desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
-       sg_set_buf(&tmp, ipad, bs);
+       sg_init_one(&tmp, ipad, bs);
 
        err = crypto_hash_init(&desc);
        if (unlikely(err))
@@ -131,7 +131,7 @@ static int hmac_final(struct hash_desc *pdesc, u8 *out)
 
        desc.tfm = ctx->child;
        desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
-       sg_set_buf(&tmp, opad, bs + ds);
+       sg_init_one(&tmp, opad, bs + ds);
 
        err = crypto_hash_final(&desc, digest);
        if (unlikely(err))
@@ -158,10 +158,11 @@ static int hmac_digest(struct hash_desc *pdesc, struct scatterlist *sg,
        desc.tfm = ctx->child;
        desc.flags = pdesc->flags & CRYPTO_TFM_REQ_MAY_SLEEP;
 
+       sg_init_table(sg1, 2);
        sg_set_buf(sg1, ipad, bs);
+       sg_set_page(&sg1[1], (void *) sg, 0, 0);
 
-       sg_set_page(&sg[1], (void *) sg);
-       sg1[1].length = 0;
+       sg_init_table(sg2, 1);
        sg_set_buf(sg2, opad, bs + ds);
 
        err = crypto_hash_digest(&desc, sg1, nbytes + bs, digest);
index d741c63..24141fb 100644 (file)
@@ -139,7 +139,7 @@ static void test_hash(char *algo, struct hash_testvec *template,
                printk("test %u:\n", i + 1);
                memset(result, 0, 64);
 
-               sg_set_buf(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize);
+               sg_init_one(&sg[0], hash_tv[i].plaintext, hash_tv[i].psize);
 
                if (hash_tv[i].ksize) {
                        ret = crypto_hash_setkey(tfm, hash_tv[i].key,
@@ -176,6 +176,7 @@ static void test_hash(char *algo, struct hash_testvec *template,
                        memset(result, 0, 64);
 
                        temp = 0;
+                       sg_init_table(sg, hash_tv[i].np);
                        for (k = 0; k < hash_tv[i].np; k++) {
                                memcpy(&xbuf[IDX[k]],
                                       hash_tv[i].plaintext + temp,
@@ -289,8 +290,8 @@ static void test_cipher(char *algo, int enc,
                                        goto out;
                        }
 
-                       sg_set_buf(&sg[0], cipher_tv[i].input,
-                                  cipher_tv[i].ilen);
+                       sg_init_one(&sg[0], cipher_tv[i].input,
+                                   cipher_tv[i].ilen);
 
                        ablkcipher_request_set_crypt(req, sg, sg,
                                                     cipher_tv[i].ilen,
@@ -353,6 +354,7 @@ static void test_cipher(char *algo, int enc,
                        }
 
                        temp = 0;
+                       sg_init_table(sg, cipher_tv[i].np);
                        for (k = 0; k < cipher_tv[i].np; k++) {
                                memcpy(&xbuf[IDX[k]],
                                       cipher_tv[i].input + temp,
@@ -414,7 +416,7 @@ static int test_cipher_jiffies(struct blkcipher_desc *desc, int enc, char *p,
        int bcount;
        int ret;
 
-       sg_set_buf(sg, p, blen);
+       sg_init_one(sg, p, blen);
 
        for (start = jiffies, end = start + sec * HZ, bcount = 0;
             time_before(jiffies, end); bcount++) {
@@ -440,7 +442,7 @@ static int test_cipher_cycles(struct blkcipher_desc *desc, int enc, char *p,
        int ret = 0;
        int i;
 
-       sg_set_buf(sg, p, blen);
+       sg_init_one(sg, p, blen);
 
        local_bh_disable();
        local_irq_disable();
@@ -570,6 +572,8 @@ static int test_hash_jiffies_digest(struct hash_desc *desc, char *p, int blen,
        int bcount;
        int ret;
 
+       sg_init_table(sg, 1);
+
        for (start = jiffies, end = start + sec * HZ, bcount = 0;
             time_before(jiffies, end); bcount++) {
                sg_set_buf(sg, p, blen);
@@ -595,6 +599,8 @@ static int test_hash_jiffies(struct hash_desc *desc, char *p, int blen,
        if (plen == blen)
                return test_hash_jiffies_digest(desc, p, blen, out, sec);
 
+       sg_init_table(sg, 1);
+
        for (start = jiffies, end = start + sec * HZ, bcount = 0;
             time_before(jiffies, end); bcount++) {
                ret = crypto_hash_init(desc);
@@ -626,6 +632,8 @@ static int test_hash_cycles_digest(struct hash_desc *desc, char *p, int blen,
        int i;
        int ret;
 
+       sg_init_table(sg, 1);
+
        local_bh_disable();
        local_irq_disable();
 
@@ -677,6 +685,8 @@ static int test_hash_cycles(struct hash_desc *desc, char *p, int blen,
        if (plen == blen)
                return test_hash_cycles_digest(desc, p, blen, out);
 
+       sg_init_table(sg, 1);
+
        local_bh_disable();
        local_irq_disable();
 
index 92422a3..da3a08f 100644 (file)
@@ -88,7 +88,8 @@ config ACPI_PROC_EVENT
 
 config ACPI_AC
        tristate "AC Adapter"
-       depends on X86 && POWER_SUPPLY
+       depends on X86
+       select POWER_SUPPLY
        default y
        help
          This driver adds support for the AC Adapter object, which indicates
@@ -97,7 +98,8 @@ config ACPI_AC
 
 config ACPI_BATTERY
        tristate "Battery"
-       depends on X86 && POWER_SUPPLY
+       depends on X86
+       select POWER_SUPPLY
        default y
        help
          This driver adds support for battery information through
@@ -352,7 +354,7 @@ config ACPI_HOTPLUG_MEMORY
 config ACPI_SBS
        tristate "Smart Battery System"
        depends on X86
-       depends on POWER_SUPPLY
+       select POWER_SUPPLY
        help
          This driver adds support for the Smart Battery System, another
          type of access to battery information, found on some laptops.
index 681e26b..c2ce0ad 100644 (file)
@@ -125,11 +125,15 @@ static int acpi_battery_technology(struct acpi_battery *battery)
                return POWER_SUPPLY_TECHNOLOGY_NiMH;
        if (!strcasecmp("LION", battery->type))
                return POWER_SUPPLY_TECHNOLOGY_LION;
+       if (!strcasecmp("LI-ION", battery->type))
+               return POWER_SUPPLY_TECHNOLOGY_LION;
        if (!strcasecmp("LiP", battery->type))
                return POWER_SUPPLY_TECHNOLOGY_LIPO;
        return POWER_SUPPLY_TECHNOLOGY_UNKNOWN;
 }
 
+static int acpi_battery_update(struct acpi_battery *battery);
+
 static int acpi_battery_get_property(struct power_supply *psy,
                                     enum power_supply_property psp,
                                     union power_supply_propval *val)
@@ -139,6 +143,7 @@ static int acpi_battery_get_property(struct power_supply *psy,
        if ((!acpi_battery_present(battery)) &&
             psp != POWER_SUPPLY_PROP_PRESENT)
                return -ENODEV;
+       acpi_battery_update(battery);
        switch (psp) {
        case POWER_SUPPLY_PROP_STATUS:
                if (battery->state & 0x01)
@@ -257,7 +262,7 @@ static int extract_package(struct acpi_battery *battery,
                           union acpi_object *package,
                           struct acpi_offsets *offsets, int num)
 {
-       int i, *x;
+       int i;
        union acpi_object *element;
        if (package->type != ACPI_TYPE_PACKAGE)
                return -EFAULT;
@@ -266,16 +271,21 @@ static int extract_package(struct acpi_battery *battery,
                        return -EFAULT;
                element = &package->package.elements[i];
                if (offsets[i].mode) {
-                       if (element->type != ACPI_TYPE_STRING &&
-                           element->type != ACPI_TYPE_BUFFER)
-                               return -EFAULT;
-                       strncpy((u8 *)battery + offsets[i].offset,
-                               element->string.pointer, 32);
+                       u8 *ptr = (u8 *)battery + offsets[i].offset;
+                       if (element->type == ACPI_TYPE_STRING ||
+                           element->type == ACPI_TYPE_BUFFER)
+                               strncpy(ptr, element->string.pointer, 32);
+                       else if (element->type == ACPI_TYPE_INTEGER) {
+                               strncpy(ptr, (u8 *)&element->integer.value,
+                                       sizeof(acpi_integer));
+                               ptr[sizeof(acpi_integer)] = 0;
+                       } else return -EFAULT;
                } else {
-                       if (element->type != ACPI_TYPE_INTEGER)
-                               return -EFAULT;
-                       x = (int *)((u8 *)battery + offsets[i].offset);
-                       *x = element->integer.value;
+                       if (element->type == ACPI_TYPE_INTEGER) {
+                               int *x = (int *)((u8 *)battery +
+                                               offsets[i].offset);
+                               *x = element->integer.value;
+                       } else return -EFAULT;
                }
        }
        return 0;
@@ -385,29 +395,81 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)
        return acpi_battery_set_alarm(battery);
 }
 
+static ssize_t acpi_battery_alarm_show(struct device *dev,
+                                       struct device_attribute *attr,
+                                       char *buf)
+{
+       struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+       return sprintf(buf, "%d\n", battery->alarm * 1000);
+}
+
+static ssize_t acpi_battery_alarm_store(struct device *dev,
+                                       struct device_attribute *attr,
+                                       const char *buf, size_t count)
+{
+       unsigned long x;
+       struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
+       if (sscanf(buf, "%ld\n", &x) == 1)
+               battery->alarm = x/1000;
+       if (acpi_battery_present(battery))
+               acpi_battery_set_alarm(battery);
+       return count;
+}
+
+static struct device_attribute alarm_attr = {
+       .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
+       .show = acpi_battery_alarm_show,
+       .store = acpi_battery_alarm_store,
+};
+
+static int sysfs_add_battery(struct acpi_battery *battery)
+{
+       int result;
+
+       battery->update_time = 0;
+       result = acpi_battery_get_info(battery);
+       acpi_battery_init_alarm(battery);
+       if (result)
+               return result;
+       if (battery->power_unit) {
+               battery->bat.properties = charge_battery_props;
+               battery->bat.num_properties =
+                       ARRAY_SIZE(charge_battery_props);
+       } else {
+               battery->bat.properties = energy_battery_props;
+               battery->bat.num_properties =
+                       ARRAY_SIZE(energy_battery_props);
+       }
+
+       battery->bat.name = acpi_device_bid(battery->device);
+       battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
+       battery->bat.get_property = acpi_battery_get_property;
+
+       result = power_supply_register(&battery->device->dev, &battery->bat);
+       if (result)
+               return result;
+       return device_create_file(battery->bat.dev, &alarm_attr);
+}
+
+static void sysfs_remove_battery(struct acpi_battery *battery)
+{
+       if (!battery->bat.dev)
+               return;
+       device_remove_file(battery->bat.dev, &alarm_attr);
+       power_supply_unregister(&battery->bat);
+}
+
 static int acpi_battery_update(struct acpi_battery *battery)
 {
-       int saved_present = acpi_battery_present(battery);
        int result = acpi_battery_get_status(battery);
-       if (result || !acpi_battery_present(battery))
+       if (result)
                return result;
-       if (saved_present != acpi_battery_present(battery) ||
-           !battery->update_time) {
-               battery->update_time = 0;
-               result = acpi_battery_get_info(battery);
-               if (result)
-                       return result;
-               if (battery->power_unit) {
-                       battery->bat.properties = charge_battery_props;
-                       battery->bat.num_properties =
-                               ARRAY_SIZE(charge_battery_props);
-               } else {
-                       battery->bat.properties = energy_battery_props;
-                       battery->bat.num_properties =
-                               ARRAY_SIZE(energy_battery_props);
-               }
-               acpi_battery_init_alarm(battery);
+       if (!acpi_battery_present(battery)) {
+               sysfs_remove_battery(battery);
+               return 0;
        }
+       if (!battery->bat.dev)
+               sysfs_add_battery(battery);
        return acpi_battery_get_state(battery);
 }
 
@@ -554,10 +616,6 @@ static ssize_t acpi_battery_write_alarm(struct file *file,
 
        if (!battery || (count > sizeof(alarm_string) - 1))
                return -EINVAL;
-       if (result) {
-               result = -ENODEV;
-               goto end;
-       }
        if (!acpi_battery_present(battery)) {
                result = -ENODEV;
                goto end;
@@ -688,33 +746,6 @@ static void acpi_battery_remove_fs(struct acpi_device *device)
 
 #endif
 
-static ssize_t acpi_battery_alarm_show(struct device *dev,
-                                       struct device_attribute *attr,
-                                       char *buf)
-{
-       struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
-       return sprintf(buf, "%d\n", battery->alarm * 1000);
-}
-
-static ssize_t acpi_battery_alarm_store(struct device *dev,
-                                       struct device_attribute *attr,
-                                       const char *buf, size_t count)
-{
-       unsigned long x;
-       struct acpi_battery *battery = to_acpi_battery(dev_get_drvdata(dev));
-       if (sscanf(buf, "%ld\n", &x) == 1)
-               battery->alarm = x/1000;
-       if (acpi_battery_present(battery))
-               acpi_battery_set_alarm(battery);
-       return count;
-}
-
-static struct device_attribute alarm_attr = {
-       .attr = {.name = "alarm", .mode = 0644, .owner = THIS_MODULE},
-       .show = acpi_battery_alarm_show,
-       .store = acpi_battery_alarm_store,
-};
-
 /* --------------------------------------------------------------------------
                                  Driver Interface
    -------------------------------------------------------------------------- */
@@ -732,7 +763,9 @@ static void acpi_battery_notify(acpi_handle handle, u32 event, void *data)
        acpi_bus_generate_netlink_event(device->pnp.device_class,
                                        device->dev.bus_id, event,
                                        acpi_battery_present(battery));
-       kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
+       /* acpi_batter_update could remove power_supply object */
+       if (battery->bat.dev)
+               kobject_uevent(&battery->bat.dev->kobj, KOBJ_CHANGE);
 }
 
 static int acpi_battery_add(struct acpi_device *device)
@@ -756,11 +789,6 @@ static int acpi_battery_add(struct acpi_device *device)
        if (result)
                goto end;
 #endif
-       battery->bat.name = acpi_device_bid(device);
-       battery->bat.type = POWER_SUPPLY_TYPE_BATTERY;
-       battery->bat.get_property = acpi_battery_get_property;
-       result = power_supply_register(&battery->device->dev, &battery->bat);
-       result = device_create_file(battery->bat.dev, &alarm_attr);
        status = acpi_install_notify_handler(device->handle,
                                             ACPI_ALL_NOTIFY,
                                             acpi_battery_notify, battery);
@@ -796,10 +824,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type)
 #ifdef CONFIG_ACPI_PROCFS
        acpi_battery_remove_fs(device);
 #endif
-       if (battery->bat.dev) {
-               device_remove_file(battery->bat.dev, &alarm_attr);
-               power_supply_unregister(&battery->bat);
-       }
+       sysfs_remove_battery(battery);
        mutex_destroy(&battery->lock);
        kfree(battery);
        return 0;
@@ -813,6 +838,7 @@ static int acpi_battery_resume(struct acpi_device *device)
                return -EINVAL;
        battery = acpi_driver_data(device);
        battery->update_time = 0;
+       acpi_battery_update(battery);
        return 0;
 }
 
index fb2cff9..49d432d 100644 (file)
@@ -198,12 +198,10 @@ int acpi_bus_set_power(acpi_handle handle, int state)
                return -ENODEV;
        }
        /*
-        * Get device's current power state if it's unknown
-        * This means device power state isn't initialized or previous setting failed
+        * Get device's current power state
         */
-       if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state)
-               acpi_bus_get_power(device->handle, &device->power.state);
-       if ((state == device->power.state) && !device->flags.force_power_state) {
+       acpi_bus_get_power(device->handle, &device->power.state);
+       if (state == device->power.state) {
                ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
                                  state));
                return 0;
index 301e832..24a7865 100644 (file)
@@ -78,6 +78,7 @@ MODULE_DEVICE_TABLE(acpi, button_device_ids);
 
 static int acpi_button_add(struct acpi_device *device);
 static int acpi_button_remove(struct acpi_device *device, int type);
+static int acpi_button_resume(struct acpi_device *device);
 static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
 static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
 
@@ -87,6 +88,7 @@ static struct acpi_driver acpi_button_driver = {
        .ids = button_device_ids,
        .ops = {
                .add = acpi_button_add,
+               .resume = acpi_button_resume,
                .remove = acpi_button_remove,
        },
 };
@@ -253,6 +255,19 @@ static int acpi_button_remove_fs(struct acpi_device *device)
 /* --------------------------------------------------------------------------
                                 Driver Interface
    -------------------------------------------------------------------------- */
+static int acpi_lid_send_state(struct acpi_button *button)
+{
+       unsigned long state;
+       acpi_status status;
+
+       status = acpi_evaluate_integer(button->device->handle, "_LID", NULL,
+                                       &state);
+       if (ACPI_FAILURE(status))
+               return -ENODEV;
+       /* input layer checks if event is redundant */
+       input_report_switch(button->input, SW_LID, !state);
+       return 0;
+}
 
 static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
 {
@@ -265,15 +280,8 @@ static void acpi_button_notify(acpi_handle handle, u32 event, void *data)
        switch (event) {
        case ACPI_BUTTON_NOTIFY_STATUS:
                input = button->input;
-
                if (button->type == ACPI_BUTTON_TYPE_LID) {
-                       struct acpi_handle *handle = button->device->handle;
-                       unsigned long state;
-
-                       if (!ACPI_FAILURE(acpi_evaluate_integer(handle, "_LID",
-                                                               NULL, &state)))
-                               input_report_switch(input, SW_LID, !state);
-
+                       acpi_lid_send_state(button);
                } else {
                        int keycode = test_bit(KEY_SLEEP, input->keybit) ?
                                                KEY_SLEEP : KEY_POWER;
@@ -336,6 +344,17 @@ static int acpi_button_install_notify_handlers(struct acpi_button *button)
        return ACPI_FAILURE(status) ? -ENODEV : 0;
 }
 
+static int acpi_button_resume(struct acpi_device *device)
+{
+       struct acpi_button *button;
+       if (!device)
+               return -EINVAL;
+       button = acpi_driver_data(device);
+       if (button && button->type == ACPI_BUTTON_TYPE_LID)
+               return acpi_lid_send_state(button);
+       return 0;
+}
+
 static void acpi_button_remove_notify_handlers(struct acpi_button *button)
 {
        switch (button->type) {
@@ -453,6 +472,8 @@ static int acpi_button_add(struct acpi_device *device)
        error = input_register_device(input);
        if (error)
                goto err_remove_handlers;
+       if (button->type == ACPI_BUTTON_TYPE_LID)
+               acpi_lid_send_state(button);
 
        if (device->wakeup.flags.valid) {
                /* Button's GPE is run-wake GPE */
index 7b41783..06b78e5 100644 (file)
@@ -65,16 +65,18 @@ enum ec_command {
 /* EC events */
 enum ec_event {
        ACPI_EC_EVENT_OBF_1 = 1,        /* Output buffer full */
-       ACPI_EC_EVENT_IBF_0,    /* Input buffer empty */
+       ACPI_EC_EVENT_IBF_0,            /* Input buffer empty */
 };
 
 #define ACPI_EC_DELAY          500     /* Wait 500ms max. during EC ops */
 #define ACPI_EC_UDELAY_GLK     1000    /* Wait 1ms max. to get global lock */
 
-static enum ec_mode {
-       EC_INTR = 1,            /* Output buffer full */
-       EC_POLL,                /* Input buffer empty */
-} acpi_ec_mode = EC_INTR;
+enum {
+       EC_FLAGS_WAIT_GPE = 0,          /* Don't check status until GPE arrives */
+       EC_FLAGS_QUERY_PENDING,         /* Query is pending */
+       EC_FLAGS_GPE_MODE,              /* Expect GPE to be sent for status change */
+       EC_FLAGS_ONLY_IBF_GPE,          /* Expect GPE only for IBF = 0 event */
+};
 
 static int acpi_ec_remove(struct acpi_device *device, int type);
 static int acpi_ec_start(struct acpi_device *device);
@@ -116,9 +118,8 @@ static struct acpi_ec {
        unsigned long command_addr;
        unsigned long data_addr;
        unsigned long global_lock;
+       unsigned long flags;
        struct mutex lock;
-       atomic_t query_pending;
-       atomic_t event_count;
        wait_queue_head_t wait;
        struct list_head list;
        u8 handlers_installed;
@@ -148,45 +149,54 @@ static inline void acpi_ec_write_data(struct acpi_ec *ec, u8 data)
        outb(data, ec->data_addr);
 }
 
-static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event,
-                                      unsigned old_count)
+static inline int acpi_ec_check_status(struct acpi_ec *ec, enum ec_event event)
 {
-       u8 status = acpi_ec_read_status(ec);
-       if (old_count == atomic_read(&ec->event_count))
+       if (test_bit(EC_FLAGS_WAIT_GPE, &ec->flags))
                return 0;
        if (event == ACPI_EC_EVENT_OBF_1) {
-               if (status & ACPI_EC_FLAG_OBF)
+               if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_OBF)
                        return 1;
        } else if (event == ACPI_EC_EVENT_IBF_0) {
-               if (!(status & ACPI_EC_FLAG_IBF))
+               if (!(acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF))
                        return 1;
        }
 
        return 0;
 }
 
-static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event,
-                        unsigned count, int force_poll)
+static int acpi_ec_wait(struct acpi_ec *ec, enum ec_event event, int force_poll)
 {
-       if (unlikely(force_poll) || acpi_ec_mode == EC_POLL) {
+       if (likely(test_bit(EC_FLAGS_GPE_MODE, &ec->flags)) &&
+           likely(!force_poll)) {
+               if (wait_event_timeout(ec->wait, acpi_ec_check_status(ec, event),
+                                      msecs_to_jiffies(ACPI_EC_DELAY)))
+                       return 0;
+               clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+               if (acpi_ec_check_status(ec, event)) {
+                       if (event == ACPI_EC_EVENT_OBF_1) {
+                               /* miss OBF = 1 GPE, don't expect it anymore */
+                               printk(KERN_INFO PREFIX "missing OBF_1 confirmation,"
+                                       "switching to degraded mode.\n");
+                               set_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags);
+                       } else {
+                               /* missing GPEs, switch back to poll mode */
+                               printk(KERN_INFO PREFIX "missing IBF_1 confirmations,"
+                                       "switch off interrupt mode.\n");
+                               clear_bit(EC_FLAGS_GPE_MODE, &ec->flags);
+                       }
+                       return 0;
+               }
+       } else {
                unsigned long delay = jiffies + msecs_to_jiffies(ACPI_EC_DELAY);
+               clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                while (time_before(jiffies, delay)) {
-                       if (acpi_ec_check_status(ec, event, 0))
+                       if (acpi_ec_check_status(ec, event))
                                return 0;
                }
-       } else {
-               if (wait_event_timeout(ec->wait,
-                                      acpi_ec_check_status(ec, event, count),
-                                      msecs_to_jiffies(ACPI_EC_DELAY)) ||
-                   acpi_ec_check_status(ec, event, 0)) {
-                       return 0;
-               } else {
-                       printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
+       }
+       printk(KERN_ERR PREFIX "acpi_ec_wait timeout,"
                               " status = %d, expect_event = %d\n",
                               acpi_ec_read_status(ec), event);
-               }
-       }
-
        return -ETIME;
 }
 
@@ -196,39 +206,42 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, u8 command,
                                        int force_poll)
 {
        int result = 0;
-       unsigned count = atomic_read(&ec->event_count);
+       set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
        acpi_ec_write_cmd(ec, command);
 
        for (; wdata_len > 0; --wdata_len) {
-               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count, force_poll);
+               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
                if (result) {
                        printk(KERN_ERR PREFIX
                               "write_cmd timeout, command = %d\n", command);
                        goto end;
                }
-               count = atomic_read(&ec->event_count);
+               set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                acpi_ec_write_data(ec, *(wdata++));
        }
 
        if (!rdata_len) {
-               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, count, force_poll);
+               result = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, force_poll);
                if (result) {
                        printk(KERN_ERR PREFIX
                               "finish-write timeout, command = %d\n", command);
                        goto end;
                }
-       } else if (command == ACPI_EC_COMMAND_QUERY) {
-               atomic_set(&ec->query_pending, 0);
-       }
+       } else if (command == ACPI_EC_COMMAND_QUERY)
+               clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
 
        for (; rdata_len > 0; --rdata_len) {
-               result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, count, force_poll);
+               if (test_bit(EC_FLAGS_ONLY_IBF_GPE, &ec->flags))
+                       force_poll = 1;
+               result = acpi_ec_wait(ec, ACPI_EC_EVENT_OBF_1, force_poll);
                if (result) {
                        printk(KERN_ERR PREFIX "read timeout, command = %d\n",
                               command);
                        goto end;
                }
-               count = atomic_read(&ec->event_count);
+               /* Don't expect GPE after last read */
+               if (rdata_len > 1)
+                       set_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
                *(rdata++) = acpi_ec_read_data(ec);
        }
       end:
@@ -258,10 +271,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
                }
        }
 
-       /* Make sure GPE is enabled before doing transaction */
-       acpi_enable_gpe(NULL, ec->gpe, ACPI_NOT_ISR);
-
-       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0, 0);
+       status = acpi_ec_wait(ec, ACPI_EC_EVENT_IBF_0, 0);
        if (status) {
                printk(KERN_ERR PREFIX
                       "input buffer is not empty, aborting transaction\n");
@@ -435,9 +445,9 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler);
 
 void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)
 {
-       struct acpi_ec_query_handler *handler;
+       struct acpi_ec_query_handler *handler, *tmp;
        mutex_lock(&ec->lock);
-       list_for_each_entry(handler, &ec->list, node) {
+       list_for_each_entry_safe(handler, tmp, &ec->list, node) {
                if (query_bit == handler->query_bit) {
                        list_del(&handler->node);
                        kfree(handler);
@@ -476,23 +486,24 @@ static void acpi_ec_gpe_query(void *ec_cxt)
 static u32 acpi_ec_gpe_handler(void *data)
 {
        acpi_status status = AE_OK;
-       u8 value;
        struct acpi_ec *ec = data;
 
-       atomic_inc(&ec->event_count);
-
-       if (acpi_ec_mode == EC_INTR) {
+       clear_bit(EC_FLAGS_WAIT_GPE, &ec->flags);
+       if (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))
                wake_up(&ec->wait);
-       }
 
-       value = acpi_ec_read_status(ec);
-       if ((value & ACPI_EC_FLAG_SCI) && !atomic_read(&ec->query_pending)) {
-               atomic_set(&ec->query_pending, 1);
-               status =
-                   acpi_os_execute(OSL_EC_BURST_HANDLER, acpi_ec_gpe_query, ec);
+       if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_SCI) {
+               if (!test_and_set_bit(EC_FLAGS_QUERY_PENDING, &ec->flags))
+                       status = acpi_os_execute(OSL_EC_BURST_HANDLER,
+                               acpi_ec_gpe_query, ec);
+       } else if (unlikely(!test_bit(EC_FLAGS_GPE_MODE, &ec->flags))) {
+               /* this is non-query, must be confirmation */
+               printk(KERN_INFO PREFIX "non-query interrupt received,"
+                       " switching to interrupt mode\n");
+               set_bit(EC_FLAGS_GPE_MODE, &ec->flags);
        }
 
-       return status == AE_OK ?
+       return ACPI_SUCCESS(status) ?
            ACPI_INTERRUPT_HANDLED : ACPI_INTERRUPT_NOT_HANDLED;
 }
 
@@ -641,13 +652,10 @@ static struct acpi_ec *make_acpi_ec(void)
        struct acpi_ec *ec = kzalloc(sizeof(struct acpi_ec), GFP_KERNEL);
        if (!ec)
                return NULL;
-
-       atomic_set(&ec->query_pending, 1);
-       atomic_set(&ec->event_count, 1);
+       ec->flags = 1 << EC_FLAGS_QUERY_PENDING;
        mutex_init(&ec->lock);
        init_waitqueue_head(&ec->wait);
        INIT_LIST_HEAD(&ec->list);
-
        return ec;
 }
 
@@ -741,6 +749,8 @@ static int acpi_ec_add(struct acpi_device *device)
        acpi_ec_add_fs(device);
        printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n",
                          ec->gpe, ec->command_addr, ec->data_addr);
+       printk(KERN_INFO PREFIX "driver started in %s mode\n",
+               (test_bit(EC_FLAGS_GPE_MODE, &ec->flags))?"interrupt":"poll");
        return 0;
 }
 
@@ -833,7 +843,7 @@ static int acpi_ec_start(struct acpi_device *device)
        ret = ec_install_handlers(ec);
 
        /* EC is fully operational, allow queries */
-       atomic_set(&ec->query_pending, 0);
+       clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags);
        return ret;
 }
 
@@ -924,20 +934,4 @@ static void __exit acpi_ec_exit(void)
 
        return;
 }
-#endif                         /* 0 */
-
-static int __init acpi_ec_set_intr_mode(char *str)
-{
-       int intr;
-
-       if (!get_option(&str, &intr))
-               return 0;
-
-       acpi_ec_mode = (intr) ? EC_INTR : EC_POLL;
-
-       printk(KERN_NOTICE PREFIX "%s mode.\n", intr ? "interrupt" : "polling");
-
-       return 1;
-}
-
-__setup("ec_intr=", acpi_ec_set_intr_mode);
+#endif /* 0 */
index c81f6bd..a5a5532 100644 (file)
@@ -47,8 +47,6 @@ MODULE_LICENSE("GPL");
 
 static int acpi_fan_add(struct acpi_device *device);
 static int acpi_fan_remove(struct acpi_device *device, int type);
-static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
-static int acpi_fan_resume(struct acpi_device *device);
 
 static const struct acpi_device_id fan_device_ids[] = {
        {"PNP0C0B", 0},
@@ -63,15 +61,9 @@ static struct acpi_driver acpi_fan_driver = {
        .ops = {
                .add = acpi_fan_add,
                .remove = acpi_fan_remove,
-               .suspend = acpi_fan_suspend,
-               .resume = acpi_fan_resume,
                },
 };
 
-struct acpi_fan {
-       struct acpi_device * device;
-};
-
 /* --------------------------------------------------------------------------
                               FS Interface (/proc)
    -------------------------------------------------------------------------- */
@@ -80,12 +72,12 @@ static struct proc_dir_entry *acpi_fan_dir;
 
 static int acpi_fan_read_state(struct seq_file *seq, void *offset)
 {
-       struct acpi_fan *fan = seq->private;
+       struct acpi_device *device = seq->private;
        int state = 0;
 
 
-       if (fan) {
-               if (acpi_bus_get_power(fan->device->handle, &state))
+       if (device) {
+               if (acpi_bus_get_power(device->handle, &state))
                        seq_printf(seq, "status:                  ERROR\n");
                else
                        seq_printf(seq, "status:                  %s\n",
@@ -105,11 +97,10 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
 {
        int result = 0;
        struct seq_file *m = file->private_data;
-       struct acpi_fan *fan = m->private;
+       struct acpi_device *device = m->private;
        char state_string[12] = { '\0' };
 
-
-       if (!fan || (count > sizeof(state_string) - 1))
+       if (count > sizeof(state_string) - 1)
                return -EINVAL;
 
        if (copy_from_user(state_string, buffer, count))
@@ -117,7 +108,7 @@ acpi_fan_write_state(struct file *file, const char __user * buffer,
 
        state_string[count] = '\0';
 
-       result = acpi_bus_set_power(fan->device->handle,
+       result = acpi_bus_set_power(device->handle,
                                    simple_strtoul(state_string, NULL, 0));
        if (result)
                return result;
@@ -158,7 +149,7 @@ static int acpi_fan_add_fs(struct acpi_device *device)
                return -ENODEV;
        else {
                entry->proc_fops = &acpi_fan_state_ops;
-               entry->data = acpi_driver_data(device);
+               entry->data = device;
                entry->owner = THIS_MODULE;
        }
 
@@ -191,14 +182,8 @@ static int acpi_fan_add(struct acpi_device *device)
        if (!device)
                return -EINVAL;
 
-       fan = kzalloc(sizeof(struct acpi_fan), GFP_KERNEL);
-       if (!fan)
-               return -ENOMEM;
-
-       fan->device = device;
        strcpy(acpi_device_name(device), "Fan");
        strcpy(acpi_device_class(device), ACPI_FAN_CLASS);
-       acpi_driver_data(device) = fan;
 
        result = acpi_bus_get_power(device->handle, &state);
        if (result) {
@@ -206,10 +191,6 @@ static int acpi_fan_add(struct acpi_device *device)
                goto end;
        }
 
-       device->flags.force_power_state = 1;
-       acpi_bus_set_power(device->handle, state);
-       device->flags.force_power_state = 0;
-
        result = acpi_fan_add_fs(device);
        if (result)
                goto end;
@@ -227,53 +208,14 @@ static int acpi_fan_add(struct acpi_device *device)
 
 static int acpi_fan_remove(struct acpi_device *device, int type)
 {
-       struct acpi_fan *fan = NULL;
-
-
        if (!device || !acpi_driver_data(device))
                return -EINVAL;
 
-       fan = acpi_driver_data(device);
-
        acpi_fan_remove_fs(device);
 
-       kfree(fan);
-
        return 0;
 }
 
-static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state)
-{
-       if (!device)
-               return -EINVAL;
-
-       acpi_bus_set_power(device->handle, ACPI_STATE_D0);
-
-       return AE_OK;
-}
-
-static int acpi_fan_resume(struct acpi_device *device)
-{
-       int result = 0;
-       int power_state = 0;
-
-       if (!device)
-               return -EINVAL;
-
-       result = acpi_bus_get_power(device->handle, &power_state);
-       if (result) {
-               ACPI_DEBUG_PRINT((ACPI_DB_ERROR,
-                                 "Error reading fan power state\n"));
-               return result;
-       }
-
-       device->flags.force_power_state = 1;
-       acpi_bus_set_power(device->handle, power_state);
-       device->flags.force_power_state = 0;
-
-       return result;
-}
-
 static int __init acpi_fan_init(void)
 {
        int result = 0;
index 57b9a29..af1769a 100644 (file)
@@ -86,7 +86,6 @@ struct acpi_power_resource {
        acpi_bus_id name;
        u32 system_level;
        u32 order;
-       int state;
        struct mutex resource_lock;
        struct list_head reference;
 };
@@ -128,33 +127,31 @@ acpi_power_get_context(acpi_handle handle,
        return 0;
 }
 
-static int acpi_power_get_state(struct acpi_power_resource *resource)
+static int acpi_power_get_state(struct acpi_power_resource *resource, int *state)
 {
        acpi_status status = AE_OK;
        unsigned long sta = 0;
 
 
-       if (!resource)
+       if (!resource || !state)
                return -EINVAL;
 
        status = acpi_evaluate_integer(resource->device->handle, "_STA", NULL, &sta);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       if (sta & 0x01)
-               resource->state = ACPI_POWER_RESOURCE_STATE_ON;
-       else
-               resource->state = ACPI_POWER_RESOURCE_STATE_OFF;
+       *state = (sta & 0x01)?ACPI_POWER_RESOURCE_STATE_ON:
+                             ACPI_POWER_RESOURCE_STATE_OFF;
 
        ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] is %s\n",
-                         resource->name, resource->state ? "on" : "off"));
+                         resource->name, state ? "on" : "off"));
 
        return 0;
 }
 
 static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
 {
-       int result = 0;
+       int result = 0, state1;
        struct acpi_power_resource *resource = NULL;
        u32 i = 0;
 
@@ -168,11 +165,11 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
                result = acpi_power_get_context(list->handles[i], &resource);
                if (result)
                        return result;
-               result = acpi_power_get_state(resource);
+               result = acpi_power_get_state(resource, &state1);
                if (result)
                        return result;
 
-               *state = resource->state;
+               *state = state1;
 
                if (*state != ACPI_POWER_RESOURCE_STATE_ON)
                        break;
@@ -186,7 +183,7 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
 
 static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
 {
-       int result = 0;
+       int result = 0, state;
        int found = 0;
        acpi_status status = AE_OK;
        struct acpi_power_resource *resource = NULL;
@@ -224,20 +221,14 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
        }
        mutex_unlock(&resource->resource_lock);
 
-       if (resource->state == ACPI_POWER_RESOURCE_STATE_ON) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n",
-                                 resource->name));
-               return 0;
-       }
-
        status = acpi_evaluate_object(resource->device->handle, "_ON", NULL, NULL);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       result = acpi_power_get_state(resource);
+       result = acpi_power_get_state(resource, &state);
        if (result)
                return result;
-       if (resource->state != ACPI_POWER_RESOURCE_STATE_ON)
+       if (state != ACPI_POWER_RESOURCE_STATE_ON)
                return -ENOEXEC;
 
        /* Update the power resource's _device_ power state */
@@ -250,7 +241,7 @@ static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
 
 static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
 {
-       int result = 0;
+       int result = 0, state;
        acpi_status status = AE_OK;
        struct acpi_power_resource *resource = NULL;
        struct list_head *node, *next;
@@ -281,20 +272,14 @@ static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
        }
        mutex_unlock(&resource->resource_lock);
 
-       if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
-               ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
-                                 resource->name));
-               return 0;
-       }
-
        status = acpi_evaluate_object(resource->device->handle, "_OFF", NULL, NULL);
        if (ACPI_FAILURE(status))
                return -ENODEV;
 
-       result = acpi_power_get_state(resource);
+       result = acpi_power_get_state(resource, &state);
        if (result)
                return result;
-       if (resource->state != ACPI_POWER_RESOURCE_STATE_OFF)
+       if (state != ACPI_POWER_RESOURCE_STATE_OFF)
                return -ENOEXEC;
 
        /* Update the power resource's _device_ power state */
@@ -494,7 +479,7 @@ static struct proc_dir_entry *acpi_power_dir;
 static int acpi_power_seq_show(struct seq_file *seq, void *offset)
 {
        int count = 0;
-       int result = 0;
+       int result = 0, state;
        struct acpi_power_resource *resource = NULL;
        struct list_head *node, *next;
        struct acpi_power_reference *ref;
@@ -505,12 +490,12 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
        if (!resource)
                goto end;
 
-       result = acpi_power_get_state(resource);
+       result = acpi_power_get_state(resource, &state);
        if (result)
                goto end;
 
        seq_puts(seq, "state:                   ");
-       switch (resource->state) {
+       switch (state) {
        case ACPI_POWER_RESOURCE_STATE_ON:
                seq_puts(seq, "on\n");
                break;
@@ -591,7 +576,7 @@ static int acpi_power_remove_fs(struct acpi_device *device)
 
 static int acpi_power_add(struct acpi_device *device)
 {
-       int result = 0;
+       int result = 0, state;
        acpi_status status = AE_OK;
        struct acpi_power_resource *resource = NULL;
        union acpi_object acpi_object;
@@ -622,11 +607,11 @@ static int acpi_power_add(struct acpi_device *device)
        resource->system_level = acpi_object.power_resource.system_level;
        resource->order = acpi_object.power_resource.resource_order;
 
-       result = acpi_power_get_state(resource);
+       result = acpi_power_get_state(resource, &state);
        if (result)
                goto end;
 
-       switch (resource->state) {
+       switch (state) {
        case ACPI_POWER_RESOURCE_STATE_ON:
                device->power.state = ACPI_STATE_D0;
                break;
@@ -643,7 +628,7 @@ static int acpi_power_add(struct acpi_device *device)
                goto end;
 
        printk(KERN_INFO PREFIX "%s [%s] (%s)\n", acpi_device_name(device),
-              acpi_device_bid(device), resource->state ? "on" : "off");
+              acpi_device_bid(device), state ? "on" : "off");
 
       end:
        if (result)
@@ -680,7 +665,7 @@ static int acpi_power_remove(struct acpi_device *device, int type)
 
 static int acpi_power_resume(struct acpi_device *device)
 {
-       int result = 0;
+       int result = 0, state;
        struct acpi_power_resource *resource = NULL;
        struct acpi_power_reference *ref;
 
@@ -689,12 +674,12 @@ static int acpi_power_resume(struct acpi_device *device)
 
        resource = (struct acpi_power_resource *)acpi_driver_data(device);
 
-       result = acpi_power_get_state(resource);
+       result = acpi_power_get_state(resource, &state);
        if (result)
                return result;
 
        mutex_lock(&resource->resource_lock);
-       if ((resource->state == ACPI_POWER_RESOURCE_STATE_OFF) &&
+       if (state == ACPI_POWER_RESOURCE_STATE_OFF &&
            !list_empty(&resource->reference)) {
                ref = container_of(resource->reference.next, struct acpi_power_reference, node);
                mutex_unlock(&resource->resource_lock);
index f3d3867..2c0b663 100644 (file)
@@ -167,8 +167,8 @@ static void acpi_pm_finish(void)
 {
        u32 acpi_state = acpi_target_sleep_state;
 
-       acpi_leave_sleep_state(acpi_state);
        acpi_disable_wakeup_device(acpi_state);
+       acpi_leave_sleep_state(acpi_state);
 
        /* reset firmware waking vector */
        acpi_set_firmware_waking_vector((acpi_physical_address) 0);
@@ -272,8 +272,8 @@ static void acpi_hibernation_finish(void)
         * enable it here.
         */
        acpi_enable();
-       acpi_leave_sleep_state(ACPI_STATE_S4);
        acpi_disable_wakeup_device(ACPI_STATE_S4);
+       acpi_leave_sleep_state(ACPI_STATE_S4);
 
        /* reset firmware waking vector */
        acpi_set_firmware_waking_vector((acpi_physical_address) 0);
@@ -410,6 +410,7 @@ static void acpi_power_off(void)
        /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */
        printk("%s called\n", __FUNCTION__);
        local_irq_disable();
+       acpi_enable_wakeup_device(ACPI_STATE_S5);
        acpi_enter_sleep_state(ACPI_STATE_S5);
 }
 
index 3839efd..1538355 100644 (file)
@@ -194,6 +194,23 @@ static int get_date_field(char **p, u32 * value)
        return result;
 }
 
+/* Read a possibly BCD register, always return binary */
+static u32 cmos_bcd_read(int offset, int rtc_control)
+{
+       u32 val = CMOS_READ(offset);
+       if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+               BCD_TO_BIN(val);
+       return val;
+}
+
+/* Write binary value into possibly BCD register */
+static void cmos_bcd_write(u32 val, int offset, int rtc_control)
+{
+       if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD)
+               BIN_TO_BCD(val);
+       CMOS_WRITE(val, offset);
+}
+
 static ssize_t
 acpi_system_write_alarm(struct file *file,
                        const char __user * buffer, size_t count, loff_t * ppos)
@@ -258,35 +275,18 @@ acpi_system_write_alarm(struct file *file,
        spin_lock_irq(&rtc_lock);
 
        rtc_control = CMOS_READ(RTC_CONTROL);
-       if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               BIN_TO_BCD(yr);
-               BIN_TO_BCD(mo);
-               BIN_TO_BCD(day);
-               BIN_TO_BCD(hr);
-               BIN_TO_BCD(min);
-               BIN_TO_BCD(sec);
-       }
 
        if (adjust) {
-               yr += CMOS_READ(RTC_YEAR);
-               mo += CMOS_READ(RTC_MONTH);
-               day += CMOS_READ(RTC_DAY_OF_MONTH);
-               hr += CMOS_READ(RTC_HOURS);
-               min += CMOS_READ(RTC_MINUTES);
-               sec += CMOS_READ(RTC_SECONDS);
+               yr += cmos_bcd_read(RTC_YEAR, rtc_control);
+               mo += cmos_bcd_read(RTC_MONTH, rtc_control);
+               day += cmos_bcd_read(RTC_DAY_OF_MONTH, rtc_control);
+               hr += cmos_bcd_read(RTC_HOURS, rtc_control);
+               min += cmos_bcd_read(RTC_MINUTES, rtc_control);
+               sec += cmos_bcd_read(RTC_SECONDS, rtc_control);
        }
 
        spin_unlock_irq(&rtc_lock);
 
-       if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               BCD_TO_BIN(yr);
-               BCD_TO_BIN(mo);
-               BCD_TO_BIN(day);
-               BCD_TO_BIN(hr);
-               BCD_TO_BIN(min);
-               BCD_TO_BIN(sec);
-       }
-
        if (sec > 59) {
                min++;
                sec -= 60;
@@ -307,14 +307,6 @@ acpi_system_write_alarm(struct file *file,
                yr++;
                mo -= 12;
        }
-       if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) {
-               BIN_TO_BCD(yr);
-               BIN_TO_BCD(mo);
-               BIN_TO_BCD(day);
-               BIN_TO_BCD(hr);
-               BIN_TO_BCD(min);
-               BIN_TO_BCD(sec);
-       }
 
        spin_lock_irq(&rtc_lock);
        /*
@@ -326,9 +318,9 @@ acpi_system_write_alarm(struct file *file,
        CMOS_READ(RTC_INTR_FLAGS);
 
        /* write the fields the rtc knows about */
-       CMOS_WRITE(hr, RTC_HOURS_ALARM);
-       CMOS_WRITE(min, RTC_MINUTES_ALARM);
-       CMOS_WRITE(sec, RTC_SECONDS_ALARM);
+       cmos_bcd_write(hr, RTC_HOURS_ALARM, rtc_control);
+       cmos_bcd_write(min, RTC_MINUTES_ALARM, rtc_control);
+       cmos_bcd_write(sec, RTC_SECONDS_ALARM, rtc_control);
 
        /*
         * If the system supports an enhanced alarm it will have non-zero
@@ -336,11 +328,11 @@ acpi_system_write_alarm(struct file *file,
         * to the RTC area of memory.
         */
        if (acpi_gbl_FADT.day_alarm)
-               CMOS_WRITE(day, acpi_gbl_FADT.day_alarm);
+               cmos_bcd_write(day, acpi_gbl_FADT.day_alarm, rtc_control);
        if (acpi_gbl_FADT.month_alarm)
-               CMOS_WRITE(mo, acpi_gbl_FADT.month_alarm);
+               cmos_bcd_write(mo, acpi_gbl_FADT.month_alarm, rtc_control);
        if (acpi_gbl_FADT.century)
-               CMOS_WRITE(yr / 100, acpi_gbl_FADT.century);
+               cmos_bcd_write(yr / 100, acpi_gbl_FADT.century, rtc_control);
        /* enable the rtc alarm interrupt */
        rtc_control |= RTC_AIE;
        CMOS_WRITE(rtc_control, RTC_CONTROL);
index 95229e7..ed9b407 100644 (file)
@@ -41,6 +41,7 @@
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
 #include <linux/device.h>
+#include <linux/dmi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_cmnd.h>
 #include <linux/libata.h>
@@ -48,6 +49,9 @@
 #define DRV_NAME       "ahci"
 #define DRV_VERSION    "3.0"
 
+static int ahci_enable_alpm(struct ata_port *ap,
+               enum link_pm policy);
+static void ahci_disable_alpm(struct ata_port *ap);
 
 enum {
        AHCI_PCI_BAR            = 5,
@@ -98,6 +102,7 @@ enum {
        HOST_CAP_SSC            = (1 << 14), /* Slumber capable */
        HOST_CAP_PMP            = (1 << 17), /* Port Multiplier support */
        HOST_CAP_CLO            = (1 << 24), /* Command List Override support */
+       HOST_CAP_ALPM           = (1 << 26), /* Aggressive Link PM support */
        HOST_CAP_SSS            = (1 << 27), /* Staggered Spin-up */
        HOST_CAP_SNTF           = (1 << 29), /* SNotification register */
        HOST_CAP_NCQ            = (1 << 30), /* Native Command Queueing */
@@ -154,6 +159,8 @@ enum {
                                  PORT_IRQ_PIOS_FIS | PORT_IRQ_D2H_REG_FIS,
 
        /* PORT_CMD bits */
+       PORT_CMD_ASP            = (1 << 27), /* Aggressive Slumber/Partial */
+       PORT_CMD_ALPE           = (1 << 26), /* Aggressive Link PM enable */
        PORT_CMD_ATAPI          = (1 << 24), /* Device is ATAPI */
        PORT_CMD_PMP            = (1 << 17), /* PMP attached */
        PORT_CMD_LIST_ON        = (1 << 15), /* cmd list DMA engine running */
@@ -177,13 +184,14 @@ enum {
        AHCI_HFLAG_MV_PATA              = (1 << 4), /* PATA port */
        AHCI_HFLAG_NO_MSI               = (1 << 5), /* no PCI MSI */
        AHCI_HFLAG_NO_PMP               = (1 << 6), /* no PMP */
+       AHCI_HFLAG_NO_HOTPLUG           = (1 << 7), /* ignore PxSERR.DIAG.N */
 
        /* ap->flags bits */
-       AHCI_FLAG_NO_HOTPLUG            = (1 << 24), /* ignore PxSERR.DIAG.N */
 
        AHCI_FLAG_COMMON                = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
                                          ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
-                                         ATA_FLAG_ACPI_SATA | ATA_FLAG_AN,
+                                         ATA_FLAG_ACPI_SATA | ATA_FLAG_AN |
+                                         ATA_FLAG_IPM,
        AHCI_LFLAG_COMMON               = ATA_LFLAG_SKIP_D2H_BSY,
 };
 
@@ -241,6 +249,7 @@ static void ahci_pmp_attach(struct ata_port *ap);
 static void ahci_pmp_detach(struct ata_port *ap);
 static void ahci_error_handler(struct ata_port *ap);
 static void ahci_vt8251_error_handler(struct ata_port *ap);
+static void ahci_p5wdh_error_handler(struct ata_port *ap);
 static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
 static int ahci_port_resume(struct ata_port *ap);
 static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl);
@@ -252,6 +261,11 @@ static int ahci_pci_device_suspend(struct pci_dev *pdev, pm_message_t mesg);
 static int ahci_pci_device_resume(struct pci_dev *pdev);
 #endif
 
+static struct class_device_attribute *ahci_shost_attrs[] = {
+       &class_device_attr_link_power_management_policy,
+       NULL
+};
+
 static struct scsi_host_template ahci_sht = {
        .module                 = THIS_MODULE,
        .name                   = DRV_NAME,
@@ -269,6 +283,7 @@ static struct scsi_host_template ahci_sht = {
        .slave_configure        = ata_scsi_slave_config,
        .slave_destroy          = ata_scsi_slave_destroy,
        .bios_param             = ata_std_bios_param,
+       .shost_attrs            = ahci_shost_attrs,
 };
 
 static const struct ata_port_operations ahci_ops = {
@@ -300,6 +315,8 @@ static const struct ata_port_operations ahci_ops = {
        .port_suspend           = ahci_port_suspend,
        .port_resume            = ahci_port_resume,
 #endif
+       .enable_pm              = ahci_enable_alpm,
+       .disable_pm             = ahci_disable_alpm,
 
        .port_start             = ahci_port_start,
        .port_stop              = ahci_port_stop,
@@ -339,6 +356,40 @@ static const struct ata_port_operations ahci_vt8251_ops = {
        .port_stop              = ahci_port_stop,
 };
 
+static const struct ata_port_operations ahci_p5wdh_ops = {
+       .check_status           = ahci_check_status,
+       .check_altstatus        = ahci_check_status,
+       .dev_select             = ata_noop_dev_select,
+
+       .tf_read                = ahci_tf_read,
+
+       .qc_defer               = sata_pmp_qc_defer_cmd_switch,
+       .qc_prep                = ahci_qc_prep,
+       .qc_issue               = ahci_qc_issue,
+
+       .irq_clear              = ahci_irq_clear,
+
+       .scr_read               = ahci_scr_read,
+       .scr_write              = ahci_scr_write,
+
+       .freeze                 = ahci_freeze,
+       .thaw                   = ahci_thaw,
+
+       .error_handler          = ahci_p5wdh_error_handler,
+       .post_internal_cmd      = ahci_post_internal_cmd,
+
+       .pmp_attach             = ahci_pmp_attach,
+       .pmp_detach             = ahci_pmp_detach,
+
+#ifdef CONFIG_PM
+       .port_suspend           = ahci_port_suspend,
+       .port_resume            = ahci_port_resume,
+#endif
+
+       .port_start             = ahci_port_start,
+       .port_stop              = ahci_port_stop,
+};
+
 #define AHCI_HFLAGS(flags)     .private_data   = (void *)(flags)
 
 static const struct ata_port_info ahci_port_info[] = {
@@ -800,6 +851,130 @@ static void ahci_power_up(struct ata_port *ap)
        writel(cmd | PORT_CMD_ICC_ACTIVE, port_mmio + PORT_CMD);
 }
 
+static void ahci_disable_alpm(struct ata_port *ap)
+{
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       void __iomem *port_mmio = ahci_port_base(ap);
+       u32 cmd;
+       struct ahci_port_priv *pp = ap->private_data;
+
+       /* IPM bits should be disabled by libata-core */
+       /* get the existing command bits */
+       cmd = readl(port_mmio + PORT_CMD);
+
+       /* disable ALPM and ASP */
+       cmd &= ~PORT_CMD_ASP;
+       cmd &= ~PORT_CMD_ALPE;
+
+       /* force the interface back to active */
+       cmd |= PORT_CMD_ICC_ACTIVE;
+
+       /* write out new cmd value */
+       writel(cmd, port_mmio + PORT_CMD);
+       cmd = readl(port_mmio + PORT_CMD);
+
+       /* wait 10ms to be sure we've come out of any low power state */
+       msleep(10);
+
+       /* clear out any PhyRdy stuff from interrupt status */
+       writel(PORT_IRQ_PHYRDY, port_mmio + PORT_IRQ_STAT);
+
+       /* go ahead and clean out PhyRdy Change from Serror too */
+       ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18)));
+
+       /*
+        * Clear flag to indicate that we should ignore all PhyRdy
+        * state changes
+        */
+       hpriv->flags &= ~AHCI_HFLAG_NO_HOTPLUG;
+
+       /*
+        * Enable interrupts on Phy Ready.
+        */
+       pp->intr_mask |= PORT_IRQ_PHYRDY;
+       writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
+
+       /*
+        * don't change the link pm policy - we can be called
+        * just to turn of link pm temporarily
+        */
+}
+
+static int ahci_enable_alpm(struct ata_port *ap,
+       enum link_pm policy)
+{
+       struct ahci_host_priv *hpriv = ap->host->private_data;
+       void __iomem *port_mmio = ahci_port_base(ap);
+       u32 cmd;
+       struct ahci_port_priv *pp = ap->private_data;
+       u32 asp;
+
+       /* Make sure the host is capable of link power management */
+       if (!(hpriv->cap & HOST_CAP_ALPM))
+               return -EINVAL;
+
+       switch (policy) {
+       case MAX_PERFORMANCE:
+       case NOT_AVAILABLE:
+               /*
+                * if we came here with NOT_AVAILABLE,
+                * it just means this is the first time we
+                * have tried to enable - default to max performance,
+                * and let the user go to lower power modes on request.
+                */
+               ahci_disable_alpm(ap);
+               return 0;
+       case MIN_POWER:
+               /* configure HBA to enter SLUMBER */
+               asp = PORT_CMD_ASP;
+               break;
+       case MEDIUM_POWER:
+               /* configure HBA to enter PARTIAL */
+               asp = 0;
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /*
+        * Disable interrupts on Phy Ready. This keeps us from
+        * getting woken up due to spurious phy ready interrupts
+        * TBD - Hot plug should be done via polling now, is
+        * that even supported?
+        */
+       pp->intr_mask &= ~PORT_IRQ_PHYRDY;
+       writel(pp->intr_mask, port_mmio + PORT_IRQ_MASK);
+
+       /*
+        * Set a flag to indicate that we should ignore all PhyRdy
+        * state changes since these can happen now whenever we
+        * change link state
+        */
+       hpriv->flags |= AHCI_HFLAG_NO_HOTPLUG;
+
+       /* get the existing command bits */
+       cmd = readl(port_mmio + PORT_CMD);
+
+       /*
+        * Set ASP based on Policy
+        */
+       cmd |= asp;
+
+       /*
+        * Setting this bit will instruct the HBA to aggressively
+        * enter a lower power link state when it's appropriate and
+        * based on the value set above for ASP
+        */
+       cmd |= PORT_CMD_ALPE;
+
+       /* write out new cmd value */
+       writel(cmd, port_mmio + PORT_CMD);
+       cmd = readl(port_mmio + PORT_CMD);
+
+       /* IPM bits should be set by libata-core */
+       return 0;
+}
+
 #ifdef CONFIG_PM
 static void ahci_power_down(struct ata_port *ap)
 {
@@ -862,8 +1037,10 @@ static int ahci_reset_controller(struct ata_host *host)
         * AHCI-specific, such as HOST_RESET.
         */
        tmp = readl(mmio + HOST_CTL);
-       if (!(tmp & HOST_AHCI_EN))
-               writel(tmp | HOST_AHCI_EN, mmio + HOST_CTL);
+       if (!(tmp & HOST_AHCI_EN)) {
+               tmp |= HOST_AHCI_EN;
+               writel(tmp, mmio + HOST_CTL);
+       }
 
        /* global controller reset */
        if ((tmp & HOST_RESET) == 0) {
@@ -1117,15 +1294,8 @@ static int ahci_do_softreset(struct ata_link *link, unsigned int *class,
        tf.ctl &= ~ATA_SRST;
        ahci_exec_polled_cmd(ap, pmp, &tf, 0, 0, 0);
 
-       /* spec mandates ">= 2ms" before checking status.
-        * We wait 150ms, because that was the magic delay used for
-        * ATAPI devices in Hale Landis's ATADRVR, for the period of time
-        * between when the ATA command register is written, and then
-        * status is checked.  Because waiting for "a while" before
-        * checking status is fine, post SRST, we perform this magic
-        * delay here as well.
-        */
-       msleep(150);
+       /* wait a while before checking status */
+       ata_wait_after_reset(ap, deadline);
 
        rc = ata_wait_ready(ap, deadline);
        /* link occupied, -ENODEV too is an error */
@@ -1213,6 +1383,53 @@ static int ahci_vt8251_hardreset(struct ata_link *link, unsigned int *class,
        return rc ?: -EAGAIN;
 }
 
+static int ahci_p5wdh_hardreset(struct ata_link *link, unsigned int *class,
+                               unsigned long deadline)
+{
+       struct ata_port *ap = link->ap;
+       struct ahci_port_priv *pp = ap->private_data;
+       u8 *d2h_fis = pp->rx_fis + RX_FIS_D2H_REG;
+       struct ata_taskfile tf;
+       int rc;
+
+       ahci_stop_engine(ap);
+
+       /* clear D2H reception area to properly wait for D2H FIS */
+       ata_tf_init(link->device, &tf);
+       tf.command = 0x80;
+       ata_tf_to_fis(&tf, 0, 0, d2h_fis);
+
+       rc = sata_link_hardreset(link, sata_ehc_deb_timing(&link->eh_context),
+                                deadline);
+
+       ahci_start_engine(ap);
+
+       if (rc || ata_link_offline(link))
+               return rc;
+
+       /* spec mandates ">= 2ms" before checking status */
+       msleep(150);
+
+       /* The pseudo configuration device on SIMG4726 attached to
+        * ASUS P5W-DH Deluxe doesn't send signature FIS after
+        * hardreset if no device is attached to the first downstream
+        * port && the pseudo device locks up on SRST w/ PMP==0.  To
+        * work around this, wait for !BSY only briefly.  If BSY isn't
+        * cleared, perform CLO and proceed to IDENTIFY (achieved by
+        * ATA_LFLAG_NO_SRST and ATA_LFLAG_ASSUME_ATA).
+        *
+        * Wait for two seconds.  Devices attached to downstream port
+        * which can't process the following IDENTIFY after this will
+        * have to be reset again.  For most cases, this should
+        * suffice while making probing snappish enough.
+        */
+       rc = ata_wait_ready(ap, jiffies + 2 * HZ);
+       if (rc)
+               ahci_kick_engine(ap, 0);
+
+       return 0;
+}
+
 static void ahci_postreset(struct ata_link *link, unsigned int *class)
 {
        struct ata_port *ap = link->ap;
@@ -1426,6 +1643,17 @@ static void ahci_port_intr(struct ata_port *ap)
        if (unlikely(resetting))
                status &= ~PORT_IRQ_BAD_PMP;
 
+       /* If we are getting PhyRdy, this is
+        * just a power state change, we should
+        * clear out this, plus the PhyRdy/Comm
+        * Wake bits from Serror
+        */
+       if ((hpriv->flags & AHCI_HFLAG_NO_HOTPLUG) &&
+               (status & PORT_IRQ_PHYRDY)) {
+               status &= ~PORT_IRQ_PHYRDY;
+               ahci_scr_write(ap, SCR_ERROR, ((1 << 16) | (1 << 18)));
+       }
+
        if (unlikely(status & PORT_IRQ_ERROR)) {
                ahci_error_intr(ap, status);
                return;
@@ -1670,6 +1898,19 @@ static void ahci_vt8251_error_handler(struct ata_port *ap)
                  ahci_postreset);
 }
 
+static void ahci_p5wdh_error_handler(struct ata_port *ap)
+{
+       if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
+               /* restart engine */
+               ahci_stop_engine(ap);
+               ahci_start_engine(ap);
+       }
+
+       /* perform recovery */
+       ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_p5wdh_hardreset,
+                 ahci_postreset);
+}
+
 static void ahci_post_internal_cmd(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
@@ -1955,6 +2196,51 @@ static void ahci_print_info(struct ata_host *host)
                );
 }
 
+/* On ASUS P5W DH Deluxe, the second port of PCI device 00:1f.2 is
+ * hardwired to on-board SIMG 4726.  The chipset is ICH8 and doesn't
+ * support PMP and the 4726 either directly exports the device
+ * attached to the first downstream port or acts as a hardware storage
+ * controller and emulate a single ATA device (can be RAID 0/1 or some
+ * other configuration).
+ *
+ * When there's no device attached to the first downstream port of the
+ * 4726, "Config Disk" appears, which is a pseudo ATA device to
+ * configure the 4726.  However, ATA emulation of the device is very
+ * lame.  It doesn't send signature D2H Reg FIS after the initial
+ * hardreset, pukes on SRST w/ PMP==0 and has bunch of other issues.
+ *
+ * The following function works around the problem by always using
+ * hardreset on the port and not depending on receiving signature FIS
+ * afterward.  If signature FIS isn't received soon, ATA class is
+ * assumed without follow-up softreset.
+ */
+static void ahci_p5wdh_workaround(struct ata_host *host)
+{
+       static struct dmi_system_id sysids[] = {
+               {
+                       .ident = "P5W DH Deluxe",
+                       .matches = {
+                               DMI_MATCH(DMI_SYS_VENDOR,
+                                         "ASUSTEK COMPUTER INC"),
+                               DMI_MATCH(DMI_PRODUCT_NAME, "P5W DH Deluxe"),
+                       },
+               },
+               { }
+       };
+       struct pci_dev *pdev = to_pci_dev(host->dev);
+
+       if (pdev->bus->number == 0 && pdev->devfn == PCI_DEVFN(0x1f, 2) &&
+           dmi_check_system(sysids)) {
+               struct ata_port *ap = host->ports[1];
+
+               dev_printk(KERN_INFO, &pdev->dev, "enabling ASUS P5W DH "
+                          "Deluxe on-board SIMG4726 workaround\n");
+
+               ap->ops = &ahci_p5wdh_ops;
+               ap->link.flags |= ATA_LFLAG_NO_SRST | ATA_LFLAG_ASSUME_ATA;
+       }
+}
+
 static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
@@ -2015,6 +2301,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                ata_port_pbar_desc(ap, AHCI_PCI_BAR,
                                   0x100 + ap->port_no * 0x80, "port");
 
+               /* set initial link pm policy */
+               ap->pm_policy = NOT_AVAILABLE;
+
                /* standard SATA port setup */
                if (hpriv->port_map & (1 << i))
                        ap->ioaddr.cmd_addr = port_mmio;
@@ -2024,6 +2313,9 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
                        ap->ops = &ata_dummy_port_ops;
        }
 
+       /* apply workaround for ASUS P5W DH Deluxe mainboard */
+       ahci_p5wdh_workaround(host);
+
        /* initialize adapter */
        rc = ahci_configure_dma_masks(pdev, hpriv->cap & HOST_CAP_64);
        if (rc)
index 2d147b5..63035d7 100644 (file)
@@ -68,7 +68,8 @@ const unsigned long sata_deb_timing_long[]            = { 100, 2000, 5000 };
 static unsigned int ata_dev_init_params(struct ata_device *dev,
                                        u16 heads, u16 sectors);
 static unsigned int ata_dev_set_xfermode(struct ata_device *dev);
-static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable);
+static unsigned int ata_dev_set_feature(struct ata_device *dev,
+                                       u8 enable, u8 feature);
 static void ata_dev_xfermask(struct ata_device *dev);
 static unsigned long ata_dev_blacklisted(const struct ata_device *dev);
 
@@ -619,6 +620,177 @@ void ata_dev_disable(struct ata_device *dev)
        }
 }
 
+static int ata_dev_set_dipm(struct ata_device *dev, enum link_pm policy)
+{
+       struct ata_link *link = dev->link;
+       struct ata_port *ap = link->ap;
+       u32 scontrol;
+       unsigned int err_mask;
+       int rc;
+
+       /*
+        * disallow DIPM for drivers which haven't set
+        * ATA_FLAG_IPM.  This is because when DIPM is enabled,
+        * phy ready will be set in the interrupt status on
+        * state changes, which will cause some drivers to
+        * think there are errors - additionally drivers will
+        * need to disable hot plug.
+        */
+       if (!(ap->flags & ATA_FLAG_IPM) || !ata_dev_enabled(dev)) {
+               ap->pm_policy = NOT_AVAILABLE;
+               return -EINVAL;
+       }
+
+       /*
+        * For DIPM, we will only enable it for the
+        * min_power setting.
+        *
+        * Why?  Because Disks are too stupid to know that
+        * If the host rejects a request to go to SLUMBER
+        * they should retry at PARTIAL, and instead it
+        * just would give up.  So, for medium_power to
+        * work at all, we need to only allow HIPM.
+        */
+       rc = sata_scr_read(link, SCR_CONTROL, &scontrol);
+       if (rc)
+               return rc;
+
+       switch (policy) {
+       case MIN_POWER:
+               /* no restrictions on IPM transitions */
+               scontrol &= ~(0x3 << 8);
+               rc = sata_scr_write(link, SCR_CONTROL, scontrol);
+               if (rc)
+                       return rc;
+
+               /* enable DIPM */
+               if (dev->flags & ATA_DFLAG_DIPM)
+                       err_mask = ata_dev_set_feature(dev,
+                                       SETFEATURES_SATA_ENABLE, SATA_DIPM);
+               break;
+       case MEDIUM_POWER:
+               /* allow IPM to PARTIAL */
+               scontrol &= ~(0x1 << 8);
+               scontrol |= (0x2 << 8);
+               rc = sata_scr_write(link, SCR_CONTROL, scontrol);
+               if (rc)
+                       return rc;
+
+               /* disable DIPM */
+               if (ata_dev_enabled(dev) && (dev->flags & ATA_DFLAG_DIPM))
+                       err_mask = ata_dev_set_feature(dev,
+                                       SETFEATURES_SATA_DISABLE, SATA_DIPM);
+               break;
+       case NOT_AVAILABLE:
+       case MAX_PERFORMANCE:
+               /* disable all IPM transitions */
+               scontrol |= (0x3 << 8);
+               rc = sata_scr_write(link, SCR_CONTROL, scontrol);
+               if (rc)
+                       return rc;
+
+               /* disable DIPM */
+               if (ata_dev_enabled(dev) && (dev->flags & ATA_DFLAG_DIPM))
+                       err_mask = ata_dev_set_feature(dev,
+                                       SETFEATURES_SATA_DISABLE, SATA_DIPM);
+               break;
+       }
+
+       /* FIXME: handle SET FEATURES failure */
+       (void) err_mask;
+
+       return 0;
+}
+
+/**
+ *     ata_dev_enable_pm - enable SATA interface power management
+ *     @device - device to enable ipm for
+ *     @policy - the link power management policy
+ *
+ *     Enable SATA Interface power management.  This will enable
+ *     Device Interface Power Management (DIPM) for min_power
+ *     policy, and then call driver specific callbacks for
+ *     enabling Host Initiated Power management.
+ *
+ *     Locking: Caller.
+ *     Returns: -EINVAL if IPM is not supported, 0 otherwise.
+ */
+void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy)
+{
+       int rc = 0;
+       struct ata_port *ap = dev->link->ap;
+
+       /* set HIPM first, then DIPM */
+       if (ap->ops->enable_pm)
+               rc = ap->ops->enable_pm(ap, policy);
+       if (rc)
+               goto enable_pm_out;
+       rc = ata_dev_set_dipm(dev, policy);
+
+enable_pm_out:
+       if (rc)
+               ap->pm_policy = MAX_PERFORMANCE;
+       else
+               ap->pm_policy = policy;
+       return /* rc */;        /* hopefully we can use 'rc' eventually */
+}
+
+/**
+ *     ata_dev_disable_pm - disable SATA interface power management
+ *     @device - device to enable ipm for
+ *
+ *     Disable SATA Interface power management.  This will disable
+ *     Device Interface Power Management (DIPM) without changing
+ *     policy,  call driver specific callbacks for disabling Host
+ *     Initiated Power management.
+ *
+ *     Locking: Caller.
+ *     Returns: void
+ */
+static void ata_dev_disable_pm(struct ata_device *dev)
+{
+       struct ata_port *ap = dev->link->ap;
+
+       ata_dev_set_dipm(dev, MAX_PERFORMANCE);
+       if (ap->ops->disable_pm)
+               ap->ops->disable_pm(ap);
+}
+
+void ata_lpm_schedule(struct ata_port *ap, enum link_pm policy)
+{
+       ap->pm_policy = policy;
+       ap->link.eh_info.action |= ATA_EHI_LPM;
+       ap->link.eh_info.flags |= ATA_EHI_NO_AUTOPSY;
+       ata_port_schedule_eh(ap);
+}
+
+static void ata_lpm_enable(struct ata_host *host)
+{
+       struct ata_link *link;
+       struct ata_port *ap;
+       struct ata_device *dev;
+       int i;
+
+       for (i = 0; i < host->n_ports; i++) {
+               ap = host->ports[i];
+               ata_port_for_each_link(link, ap) {
+                       ata_link_for_each_dev(dev, link)
+                               ata_dev_disable_pm(dev);
+               }
+       }
+}
+
+static void ata_lpm_disable(struct ata_host *host)
+{
+       int i;
+
+       for (i = 0; i < host->n_ports; i++) {
+               struct ata_port *ap = host->ports[i];
+               ata_lpm_schedule(ap, ap->pm_policy);
+       }
+}
+
+
 /**
  *     ata_devchk - PATA device presence detection
  *     @ap: ATA channel to examine
@@ -1799,13 +1971,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
                 * SET_FEATURES spin-up subcommand before it will accept
                 * anything other than the original IDENTIFY command.
                 */
-               ata_tf_init(dev, &tf);
-               tf.command = ATA_CMD_SET_FEATURES;
-               tf.feature = SETFEATURES_SPINUP;
-               tf.protocol = ATA_PROT_NODATA;
-               tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
-               err_mask = ata_exec_internal(dev, &tf, NULL,
-                                            DMA_NONE, NULL, 0, 0);
+               err_mask = ata_dev_set_feature(dev, SETFEATURES_SPINUP, 0);
                if (err_mask && id[2] != 0x738c) {
                        rc = -EIO;
                        reason = "SPINUP failed";
@@ -2075,7 +2241,8 @@ int ata_dev_configure(struct ata_device *dev)
                        unsigned int err_mask;
 
                        /* issue SET feature command to turn this on */
-                       err_mask = ata_dev_set_AN(dev, SETFEATURES_SATA_ENABLE);
+                       err_mask = ata_dev_set_feature(dev,
+                                       SETFEATURES_SATA_ENABLE, SATA_AN);
                        if (err_mask)
                                ata_dev_printk(dev, KERN_ERR,
                                        "failed to enable ATAPI AN "
@@ -2105,6 +2272,13 @@ int ata_dev_configure(struct ata_device *dev)
        if (dev->flags & ATA_DFLAG_LBA48)
                dev->max_sectors = ATA_MAX_SECTORS_LBA48;
 
+       if (!(dev->horkage & ATA_HORKAGE_IPM)) {
+               if (ata_id_has_hipm(dev->id))
+                       dev->flags |= ATA_DFLAG_HIPM;
+               if (ata_id_has_dipm(dev->id))
+                       dev->flags |= ATA_DFLAG_DIPM;
+       }
+
        if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
                /* Let the user know. We don't want to disallow opens for
                   rescue purposes, or in case the vendor is just a blithering
@@ -2130,6 +2304,13 @@ int ata_dev_configure(struct ata_device *dev)
                dev->max_sectors = min_t(unsigned int, ATA_MAX_SECTORS_128,
                                         dev->max_sectors);
 
+       if (ata_dev_blacklisted(dev) & ATA_HORKAGE_IPM) {
+               dev->horkage |= ATA_HORKAGE_IPM;
+
+               /* reset link pm_policy for this port to no pm */
+               ap->pm_policy = MAX_PERFORMANCE;
+       }
+
        if (ap->ops->dev_config)
                ap->ops->dev_config(dev);
 
@@ -2223,6 +2404,25 @@ int ata_bus_probe(struct ata_port *ap)
                tries[dev->devno] = ATA_PROBE_MAX_TRIES;
 
  retry:
+       ata_link_for_each_dev(dev, &ap->link) {
+               /* If we issue an SRST then an ATA drive (not ATAPI)
+                * may change configuration and be in PIO0 timing. If
+                * we do a hard reset (or are coming from power on)
+                * this is true for ATA or ATAPI. Until we've set a
+                * suitable controller mode we should not touch the
+                * bus as we may be talking too fast.
+                */
+               dev->pio_mode = XFER_PIO_0;
+
+               /* If the controller has a pio mode setup function
+                * then use it to set the chipset to rights. Don't
+                * touch the DMA setup as that will be dealt with when
+                * configuring devices.
+                */
+               if (ap->ops->set_piomode)
+                       ap->ops->set_piomode(ap, dev);
+       }
+
        /* reset and determine device classes */
        ap->ops->phy_reset(ap);
 
@@ -2238,12 +2438,6 @@ int ata_bus_probe(struct ata_port *ap)
 
        ata_port_probe(ap);
 
-       /* after the reset the device state is PIO 0 and the controller
-          state is undefined. Record the mode */
-
-       ata_link_for_each_dev(dev, &ap->link)
-               dev->pio_mode = XFER_PIO_0;
-
        /* read IDENTIFY page and configure devices. We have to do the identify
           specific sequence bass-ackwards so that PDIAG- is released by
           the slave device */
@@ -2886,6 +3080,13 @@ static int ata_dev_set_mode(struct ata_device *dev)
                        dev->pio_mode <= XFER_PIO_2)
                err_mask &= ~AC_ERR_DEV;
 
+       /* Early MWDMA devices do DMA but don't allow DMA mode setting.
+          Don't fail an MWDMA0 set IFF the device indicates it is in MWDMA0 */
+       if (dev->xfer_shift == ATA_SHIFT_MWDMA && 
+           dev->dma_mode == XFER_MW_DMA_0 &&
+           (dev->id[63] >> 8) & 1)
+               err_mask &= ~AC_ERR_DEV;
+
        if (err_mask) {
                ata_dev_printk(dev, KERN_ERR, "failed to set xfermode "
                               "(err_mask=0x%x)\n", err_mask);
@@ -3115,6 +3316,55 @@ int ata_busy_sleep(struct ata_port *ap,
 }
 
 /**
+ *     ata_wait_after_reset - wait before checking status after reset
+ *     @ap: port containing status register to be polled
+ *     @deadline: deadline jiffies for the operation
+ *
+ *     After reset, we need to pause a while before reading status.
+ *     Also, certain combination of controller and device report 0xff
+ *     for some duration (e.g. until SATA PHY is up and running)
+ *     which is interpreted as empty port in ATA world.  This
+ *     function also waits for such devices to get out of 0xff
+ *     status.
+ *
+ *     LOCKING:
+ *     Kernel thread context (may sleep).
+ */
+void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline)
+{
+       unsigned long until = jiffies + ATA_TMOUT_FF_WAIT;
+
+       if (time_before(until, deadline))
+               deadline = until;
+
+       /* Spec mandates ">= 2ms" before checking status.  We wait
+        * 150ms, because that was the magic delay used for ATAPI
+        * devices in Hale Landis's ATADRVR, for the period of time
+        * between when the ATA command register is written, and then
+        * status is checked.  Because waiting for "a while" before
+        * checking status is fine, post SRST, we perform this magic
+        * delay here as well.
+        *
+        * Old drivers/ide uses the 2mS rule and then waits for ready.
+        */
+       msleep(150);
+
+       /* Wait for 0xff to clear.  Some SATA devices take a long time
+        * to clear 0xff after reset.  For example, HHD424020F7SV00
+        * iVDR needs >= 800ms while.  Quantum GoVault needs even more
+        * than that.
+        */
+       while (1) {
+               u8 status = ata_chk_status(ap);
+
+               if (status != 0xff || time_after(jiffies, deadline))
+                       return;
+
+               msleep(50);
+       }
+}
+
+/**
  *     ata_wait_ready - sleep until BSY clears, or timeout
  *     @ap: port containing status register to be polled
  *     @deadline: deadline jiffies for the operation
@@ -3220,8 +3470,6 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
                             unsigned long deadline)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
-       struct ata_device *dev;
-       int i = 0;
 
        DPRINTK("ata%u: bus reset via SRST\n", ap->print_id);
 
@@ -3232,36 +3480,8 @@ static int ata_bus_softreset(struct ata_port *ap, unsigned int devmask,
        udelay(20);     /* FIXME: flush */
        iowrite8(ap->ctl, ioaddr->ctl_addr);
 
-       /* If we issued an SRST then an ATA drive (not ATAPI)
-        * may have changed configuration and be in PIO0 timing. If
-        * we did a hard reset (or are coming from power on) this is
-        * true for ATA or ATAPI. Until we've set a suitable controller
-        * mode we should not touch the bus as we may be talking too fast.
-        */
-
-       ata_link_for_each_dev(dev, &ap->link)
-               dev->pio_mode = XFER_PIO_0;
-
-       /* If the controller has a pio mode setup function then use
-          it to set the chipset to rights. Don't touch the DMA setup
-          as that will be dealt with when revalidating */
-       if (ap->ops->set_piomode) {
-               ata_link_for_each_dev(dev, &ap->link)
-                       if (devmask & (1 << i++))
-                               ap->ops->set_piomode(ap, dev);
-       }
-
-       /* spec mandates ">= 2ms" before checking status.
-        * We wait 150ms, because that was the magic delay used for
-        * ATAPI devices in Hale Landis's ATADRVR, for the period of time
-        * between when the ATA command register is written, and then
-        * status is checked.  Because waiting for "a while" before
-        * checking status is fine, post SRST, we perform this magic
-        * delay here as well.
-        *
-        * Old drivers/ide uses the 2mS rule and then waits for ready
-        */
-       msleep(150);
+       /* wait a while before checking status */
+       ata_wait_after_reset(ap, deadline);
 
        /* Before we perform post reset processing we want to see if
         * the bus shows 0xFF because the odd clown forgets the D7
@@ -3688,8 +3908,8 @@ int sata_std_hardreset(struct ata_link *link, unsigned int *class,
                return 0;
        }
 
-       /* wait a while before checking status, see SRST for more info */
-       msleep(150);
+       /* wait a while before checking status */
+       ata_wait_after_reset(ap, deadline);
 
        /* If PMP is supported, we have to do follow-up SRST.  Note
         * that some PMPs don't send D2H Reg FIS after hardreset at
@@ -3947,9 +4167,6 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "_NEC DV5800A",       NULL,           ATA_HORKAGE_NODMA },
        { "SAMSUNG CD-ROM SN-124", "N001",      ATA_HORKAGE_NODMA },
        { "Seagate STT20000A", NULL,            ATA_HORKAGE_NODMA },
-       { "IOMEGA  ZIP 250       ATAPI", NULL,  ATA_HORKAGE_NODMA }, /* temporary fix */
-       { "IOMEGA  ZIP 250       ATAPI       Floppy",
-                               NULL,           ATA_HORKAGE_NODMA },
        /* Odd clown on sil3726/4726 PMPs */
        { "Config  Disk",       NULL,           ATA_HORKAGE_NODMA |
                                                ATA_HORKAGE_SKIP_PM },
@@ -3992,6 +4209,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { "ST3160812AS",        "3.ADJ",        ATA_HORKAGE_NONCQ, },
        { "ST980813AS",         "3.ADB",        ATA_HORKAGE_NONCQ, },
        { "SAMSUNG HD401LJ",    "ZZ100-15",     ATA_HORKAGE_NONCQ, },
+       { "Maxtor 7V300F0",     "VA111900",     ATA_HORKAGE_NONCQ, },
 
        /* devices which puke on READ_NATIVE_MAX */
        { "HDS724040KLSA80",    "KFAOA20N",     ATA_HORKAGE_BROKEN_HPA, },
@@ -4007,7 +4225,7 @@ static const struct ata_blacklist_entry ata_device_blacklist [] = {
        { }
 };
 
-int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
+static int strn_pattern_cmp(const char *patt, const char *name, int wildchar)
 {
        const char *p;
        int len;
@@ -4181,15 +4399,14 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
        DPRINTK("EXIT, err_mask=%x\n", err_mask);
        return err_mask;
 }
-
 /**
- *     ata_dev_set_AN - Issue SET FEATURES - SATA FEATURES
+ *     ata_dev_set_feature - Issue SET FEATURES - SATA FEATURES
  *     @dev: Device to which command will be sent
  *     @enable: Whether to enable or disable the feature
+ *     @feature: The sector count represents the feature to set
  *
  *     Issue SET FEATURES - SATA FEATURES command to device @dev
- *     on port @ap with sector count set to indicate Asynchronous
- *     Notification feature
+ *     on port @ap with sector count
  *
  *     LOCKING:
  *     PCI/etc. bus probe sem.
@@ -4197,7 +4414,8 @@ static unsigned int ata_dev_set_xfermode(struct ata_device *dev)
  *     RETURNS:
  *     0 on success, AC_ERR_* mask otherwise.
  */
-static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable)
+static unsigned int ata_dev_set_feature(struct ata_device *dev, u8 enable,
+                                       u8 feature)
 {
        struct ata_taskfile tf;
        unsigned int err_mask;
@@ -4210,7 +4428,7 @@ static unsigned int ata_dev_set_AN(struct ata_device *dev, u8 enable)
        tf.feature = enable;
        tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
        tf.protocol = ATA_PROT_NODATA;
-       tf.nsect = SATA_AN;
+       tf.nsect = feature;
 
        err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0);
 
@@ -4689,8 +4907,9 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
                 * data in this function or read data in ata_sg_clean.
                 */
                offset = lsg->offset + lsg->length - qc->pad_len;
-               sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT));
-               psg->offset = offset_in_page(offset);
+               sg_init_table(psg, 1);
+               sg_set_page(psg, nth_page(sg_page(lsg), offset >> PAGE_SHIFT),
+                               qc->pad_len, offset_in_page(offset));
 
                if (qc->tf.flags & ATA_TFLAG_WRITE) {
                        void *addr = kmap_atomic(sg_page(psg), KM_IRQ0);
@@ -5594,6 +5813,9 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
         * taken care of.
         */
        if (ap->ops->error_handler) {
+               struct ata_device *dev = qc->dev;
+               struct ata_eh_info *ehi = &dev->link->eh_info;
+
                WARN_ON(ap->pflags & ATA_PFLAG_FROZEN);
 
                if (unlikely(qc->err_mask))
@@ -5612,6 +5834,27 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
                if (qc->flags & ATA_QCFLAG_RESULT_TF)
                        fill_result_tf(qc);
 
+               /* Some commands need post-processing after successful
+                * completion.
+                */
+               switch (qc->tf.command) {
+               case ATA_CMD_SET_FEATURES:
+                       if (qc->tf.feature != SETFEATURES_WC_ON &&
+                           qc->tf.feature != SETFEATURES_WC_OFF)
+                               break;
+                       /* fall through */
+               case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
+               case ATA_CMD_SET_MULTI: /* multi_count changed */
+                       /* revalidate device */
+                       ehi->dev_action[dev->devno] |= ATA_EH_REVALIDATE;
+                       ata_port_schedule_eh(ap);
+                       break;
+
+               case ATA_CMD_SLEEP:
+                       dev->flags |= ATA_DFLAG_SLEEPING;
+                       break;
+               }
+
                __ata_qc_complete(qc);
        } else {
                if (qc->flags & ATA_QCFLAG_EH_SCHEDULED)
@@ -5749,6 +5992,14 @@ void ata_qc_issue(struct ata_queued_cmd *qc)
                qc->flags &= ~ATA_QCFLAG_DMAMAP;
        }
 
+       /* if device is sleeping, schedule softreset and abort the link */
+       if (unlikely(qc->dev->flags & ATA_DFLAG_SLEEPING)) {
+               link->eh_info.action |= ATA_EH_SOFTRESET;
+               ata_ehi_push_desc(&link->eh_info, "waking up from sleep");
+               ata_link_abort(link);
+               return;
+       }
+
        ap->ops->qc_prep(qc);
 
        qc->err_mask |= ap->ops->qc_issue(qc);
@@ -6296,6 +6547,12 @@ int ata_host_suspend(struct ata_host *host, pm_message_t mesg)
 {
        int rc;
 
+       /*
+        * disable link pm on all ports before requesting
+        * any pm activity
+        */
+       ata_lpm_enable(host);
+
        rc = ata_host_request_pm(host, mesg, 0, ATA_EHI_QUIET, 1);
        if (rc == 0)
                host->dev->power.power_state = mesg;
@@ -6318,6 +6575,9 @@ void ata_host_resume(struct ata_host *host)
        ata_host_request_pm(host, PMSG_ON, ATA_EH_SOFTRESET,
                            ATA_EHI_NO_AUTOPSY | ATA_EHI_QUIET, 0);
        host->dev->power.power_state = PMSG_ON;
+
+       /* reenable link pm */
+       ata_lpm_disable(host);
 }
 #endif
 
@@ -6860,6 +7120,7 @@ int ata_host_register(struct ata_host *host, struct scsi_host_template *sht)
                struct ata_port *ap = host->ports[i];
 
                ata_scsi_scan_host(ap, 1);
+               ata_lpm_schedule(ap, ap->pm_policy);
        }
 
        return 0;
@@ -6921,7 +7182,7 @@ int ata_host_activate(struct ata_host *host, int irq,
  *     LOCKING:
  *     Kernel thread context (may sleep).
  */
-void ata_port_detach(struct ata_port *ap)
+static void ata_port_detach(struct ata_port *ap)
 {
        unsigned long flags;
        struct ata_link *link;
@@ -7256,7 +7517,6 @@ const struct ata_port_info ata_dummy_port_info = {
  * likely to change as new drivers are added and updated.
  * Do not depend on ABI/API stability.
  */
-
 EXPORT_SYMBOL_GPL(sata_deb_timing_normal);
 EXPORT_SYMBOL_GPL(sata_deb_timing_hotplug);
 EXPORT_SYMBOL_GPL(sata_deb_timing_long);
@@ -7326,6 +7586,7 @@ EXPORT_SYMBOL_GPL(ata_port_disable);
 EXPORT_SYMBOL_GPL(ata_ratelimit);
 EXPORT_SYMBOL_GPL(ata_wait_register);
 EXPORT_SYMBOL_GPL(ata_busy_sleep);
+EXPORT_SYMBOL_GPL(ata_wait_after_reset);
 EXPORT_SYMBOL_GPL(ata_wait_ready);
 EXPORT_SYMBOL_GPL(ata_port_queue_task);
 EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
index 93e2b54..fefea74 100644 (file)
@@ -2071,7 +2071,7 @@ int ata_eh_reset(struct ata_link *link, int classify,
        int try = 0;
        struct ata_device *dev;
        unsigned long deadline;
-       unsigned int action;
+       unsigned int tmp_action;
        ata_reset_fn_t reset;
        unsigned long flags;
        int rc;
@@ -2083,17 +2083,36 @@ int ata_eh_reset(struct ata_link *link, int classify,
 
        ata_eh_about_to_do(link, NULL, ehc->i.action & ATA_EH_RESET_MASK);
 
+       ata_link_for_each_dev(dev, link) {
+               /* If we issue an SRST then an ATA drive (not ATAPI)
+                * may change configuration and be in PIO0 timing. If
+                * we do a hard reset (or are coming from power on)
+                * this is true for ATA or ATAPI. Until we've set a
+                * suitable controller mode we should not touch the
+                * bus as we may be talking too fast.
+                */
+               dev->pio_mode = XFER_PIO_0;
+
+               /* If the controller has a pio mode setup function
+                * then use it to set the chipset to rights. Don't
+                * touch the DMA setup as that will be dealt with when
+                * configuring devices.
+                */
+               if (ap->ops->set_piomode)
+                       ap->ops->set_piomode(ap, dev);
+       }
+
        /* Determine which reset to use and record in ehc->i.action.
         * prereset() may examine and modify it.
         */
-       action = ehc->i.action;
-       ehc->i.action &= ~ATA_EH_RESET_MASK;
        if (softreset && (!hardreset || (!(link->flags & ATA_LFLAG_NO_SRST) &&
                                         !sata_set_spd_needed(link) &&
-                                        !(action & ATA_EH_HARDRESET))))
-               ehc->i.action |= ATA_EH_SOFTRESET;
+                                        !(ehc->i.action & ATA_EH_HARDRESET))))
+               tmp_action = ATA_EH_SOFTRESET;
        else
-               ehc->i.action |= ATA_EH_HARDRESET;
+               tmp_action = ATA_EH_HARDRESET;
+
+       ehc->i.action = (ehc->i.action & ~ATA_EH_RESET_MASK) | tmp_action;
 
        if (prereset) {
                rc = prereset(link, jiffies + ATA_EH_PRERESET_TIMEOUT);
@@ -2208,9 +2227,11 @@ int ata_eh_reset(struct ata_link *link, int classify,
                ata_link_for_each_dev(dev, link) {
                        /* After the reset, the device state is PIO 0
                         * and the controller state is undefined.
-                        * Record the mode.
+                        * Reset also wakes up drives from sleeping
+                        * mode.
                         */
                        dev->pio_mode = XFER_PIO_0;
+                       dev->flags &= ~ATA_DFLAG_SLEEPING;
 
                        if (ata_link_offline(link))
                                continue;
@@ -2416,7 +2437,7 @@ static int ata_eh_handle_dev_fail(struct ata_device *dev, int err)
                /* give it just one more chance */
                ehc->tries[dev->devno] = min(ehc->tries[dev->devno], 1);
        case -EIO:
-               if (ehc->tries[dev->devno] == 1) {
+               if (ehc->tries[dev->devno] == 1 && dev->pio_mode > XFER_PIO_0) {
                        /* This is the last chance, better to slow
                         * down than lose it.
                         */
@@ -2607,6 +2628,10 @@ int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
                        ehc->i.flags &= ~ATA_EHI_SETMODE;
                }
 
+               if (ehc->i.action & ATA_EHI_LPM)
+                       ata_link_for_each_dev(dev, link)
+                               ata_dev_enable_pm(dev, ap->pm_policy);
+
                /* this link is okay now */
                ehc->i.flags = 0;
                continue;
index f5d5420..93bd36c 100644 (file)
@@ -110,6 +110,74 @@ static struct scsi_transport_template ata_scsi_transport_template = {
 };
 
 
+static const struct {
+       enum link_pm    value;
+       const char      *name;
+} link_pm_policy[] = {
+       { NOT_AVAILABLE, "max_performance" },
+       { MIN_POWER, "min_power" },
+       { MAX_PERFORMANCE, "max_performance" },
+       { MEDIUM_POWER, "medium_power" },
+};
+
+const char *ata_scsi_lpm_get(enum link_pm policy)
+{
+       int i;
+
+       for (i = 0; i < ARRAY_SIZE(link_pm_policy); i++)
+               if (link_pm_policy[i].value == policy)
+                       return link_pm_policy[i].name;
+
+       return NULL;
+}
+
+static ssize_t ata_scsi_lpm_put(struct class_device *class_dev,
+       const char *buf, size_t count)
+{
+       struct Scsi_Host *shost = class_to_shost(class_dev);
+       struct ata_port *ap = ata_shost_to_port(shost);
+       enum link_pm policy = 0;
+       int i;
+
+       /*
+        * we are skipping array location 0 on purpose - this
+        * is because a value of NOT_AVAILABLE is displayed
+        * to the user as max_performance, but when the user
+        * writes "max_performance", they actually want the
+        * value to match MAX_PERFORMANCE.
+        */
+       for (i = 1; i < ARRAY_SIZE(link_pm_policy); i++) {
+               const int len = strlen(link_pm_policy[i].name);
+               if (strncmp(link_pm_policy[i].name, buf, len) == 0 &&
+                  buf[len] == '\n') {
+                       policy = link_pm_policy[i].value;
+                       break;
+               }
+       }
+       if (!policy)
+               return -EINVAL;
+
+       ata_lpm_schedule(ap, policy);
+       return count;
+}
+
+static ssize_t
+ata_scsi_lpm_show(struct class_device *class_dev, char *buf)
+{
+       struct Scsi_Host *shost = class_to_shost(class_dev);
+       struct ata_port *ap = ata_shost_to_port(shost);
+       const char *policy =
+               ata_scsi_lpm_get(ap->pm_policy);
+
+       if (!policy)
+               return -EINVAL;
+
+       return snprintf(buf, 23, "%s\n", policy);
+}
+CLASS_DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
+               ata_scsi_lpm_show, ata_scsi_lpm_put);
+EXPORT_SYMBOL_GPL(class_device_attr_link_power_management_policy);
+
 static void ata_scsi_invalid_field(struct scsi_cmnd *cmd,
                                   void (*done)(struct scsi_cmnd *))
 {
@@ -1361,33 +1429,10 @@ nothing_to_do:
 static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
-       struct ata_eh_info *ehi = &qc->dev->link->eh_info;
        struct scsi_cmnd *cmd = qc->scsicmd;
        u8 *cdb = cmd->cmnd;
        int need_sense = (qc->err_mask != 0);
 
-       /* We snoop the SET_FEATURES - Write Cache ON/OFF command, and
-        * schedule EH_REVALIDATE operation to update the IDENTIFY DEVICE
-        * cache
-        */
-       if (ap->ops->error_handler && !need_sense) {
-               switch (qc->tf.command) {
-               case ATA_CMD_SET_FEATURES:
-                       if ((qc->tf.feature == SETFEATURES_WC_ON) ||
-                           (qc->tf.feature == SETFEATURES_WC_OFF)) {
-                               ehi->action |= ATA_EH_REVALIDATE;
-                               ata_port_schedule_eh(ap);
-                       }
-                       break;
-
-               case ATA_CMD_INIT_DEV_PARAMS: /* CHS translation changed */
-               case ATA_CMD_SET_MULTI: /* multi_count changed */
-                       ehi->action |= ATA_EH_REVALIDATE;
-                       ata_port_schedule_eh(ap);
-                       break;
-               }
-       }
-
        /* For ATA pass thru (SAT) commands, generate a sense block if
         * user mandated it or if there's an error.  Note that if we
         * generate because the user forced us to, a check condition
index 90df58a..0e6cf3a 100644 (file)
@@ -101,6 +101,8 @@ extern int sata_link_init_spd(struct ata_link *link);
 extern int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg);
 extern int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg);
 extern struct ata_port *ata_port_alloc(struct ata_host *host);
+extern void ata_dev_enable_pm(struct ata_device *dev, enum link_pm policy);
+extern void ata_lpm_schedule(struct ata_port *ap, enum link_pm);
 
 /* libata-acpi.c */
 #ifdef CONFIG_ATA_ACPI
index 0f6f7bc..e4542ab 100644 (file)
@@ -181,7 +181,7 @@ static void pacpi_set_piomode(struct ata_port *ap, struct ata_device *adev)
        int unit = adev->devno;
        struct pata_acpi *acpi = ap->private_data;
 
-       if(!(acpi->gtm.flags & 0x10))
+       if (!(acpi->gtm.flags & 0x10))
                unit = 0;
 
        /* Now stuff the nS values into the structure */
@@ -202,7 +202,7 @@ static void pacpi_set_dmamode(struct ata_port *ap, struct ata_device *adev)
        int unit = adev->devno;
        struct pata_acpi *acpi = ap->private_data;
 
-       if(!(acpi->gtm.flags & 0x10))
+       if (!(acpi->gtm.flags & 0x10))
                unit = 0;
 
        /* Now stuff the nS values into the structure */
index be30923..842fe08 100644 (file)
@@ -332,12 +332,13 @@ static void ata_dummy_noret(struct ata_port *port)
 {
 }
 
-static void pata_icside_postreset(struct ata_port *ap, unsigned int *classes)
+static void pata_icside_postreset(struct ata_link *link, unsigned int *classes)
 {
+       struct ata_port *ap = link->ap;
        struct pata_icside_state *state = ap->host->private_data;
 
        if (classes[0] != ATA_DEV_NONE || classes[1] != ATA_DEV_NONE)
-               return ata_std_postreset(ap, classes);
+               return ata_std_postreset(link, classes);
 
        state->port[ap->port_no].disabled = 1;
 
@@ -395,29 +396,30 @@ static struct ata_port_operations pata_icside_port_ops = {
 
 static void __devinit
 pata_icside_setup_ioaddr(struct ata_port *ap, void __iomem *base,
-                        const struct portinfo *info)
+                        struct pata_icside_info *info,
+                        const struct portinfo *port)
 {
        struct ata_ioports *ioaddr = &ap->ioaddr;
-       void __iomem *cmd = base + info->dataoffset;
+       void __iomem *cmd = base + port->dataoffset;
 
        ioaddr->cmd_addr        = cmd;
-       ioaddr->data_addr       = cmd + (ATA_REG_DATA    << info->stepping);
-       ioaddr->error_addr      = cmd + (ATA_REG_ERR     << info->stepping);
-       ioaddr->feature_addr    = cmd + (ATA_REG_FEATURE << info->stepping);
-       ioaddr->nsect_addr      = cmd + (ATA_REG_NSECT   << info->stepping);
-       ioaddr->lbal_addr       = cmd + (ATA_REG_LBAL    << info->stepping);
-       ioaddr->lbam_addr       = cmd + (ATA_REG_LBAM    << info->stepping);
-       ioaddr->lbah_addr       = cmd + (ATA_REG_LBAH    << info->stepping);
-       ioaddr->device_addr     = cmd + (ATA_REG_DEVICE  << info->stepping);
-       ioaddr->status_addr     = cmd + (ATA_REG_STATUS  << info->stepping);
-       ioaddr->command_addr    = cmd + (ATA_REG_CMD     << info->stepping);
-
-       ioaddr->ctl_addr        = base + info->ctrloffset;
+       ioaddr->data_addr       = cmd + (ATA_REG_DATA    << port->stepping);
+       ioaddr->error_addr      = cmd + (ATA_REG_ERR     << port->stepping);
+       ioaddr->feature_addr    = cmd + (ATA_REG_FEATURE << port->stepping);
+       ioaddr->nsect_addr      = cmd + (ATA_REG_NSECT   << port->stepping);
+       ioaddr->lbal_addr       = cmd + (ATA_REG_LBAL    << port->stepping);
+       ioaddr->lbam_addr       = cmd + (ATA_REG_LBAM    << port->stepping);
+       ioaddr->lbah_addr       = cmd + (ATA_REG_LBAH    << port->stepping);
+       ioaddr->device_addr     = cmd + (ATA_REG_DEVICE  << port->stepping);
+       ioaddr->status_addr     = cmd + (ATA_REG_STATUS  << port->stepping);
+       ioaddr->command_addr    = cmd + (ATA_REG_CMD     << port->stepping);
+
+       ioaddr->ctl_addr        = base + port->ctrloffset;
        ioaddr->altstatus_addr  = ioaddr->ctl_addr;
 
        ata_port_desc(ap, "cmd 0x%lx ctl 0x%lx",
-                     info->raw_base + info->dataoffset,
-                     info->raw_base + info->ctrloffset);
+                     info->raw_base + port->dataoffset,
+                     info->raw_base + port->ctrloffset);
 
        if (info->raw_ioc_base)
                ata_port_desc(ap, "iocbase 0x%lx", info->raw_ioc_base);
@@ -441,7 +443,7 @@ static int __devinit pata_icside_register_v5(struct pata_icside_info *info)
        info->nr_ports = 1;
        info->port[0] = &pata_icside_portinfo_v5;
 
-       info->raw_base = ecard_resource_start(ec, ECARD_RES_MEMC);
+       info->raw_base = ecard_resource_start(info->ec, ECARD_RES_MEMC);
 
        return 0;
 }
@@ -522,7 +524,7 @@ static int __devinit pata_icside_add_ports(struct pata_icside_info *info)
                ap->flags |= ATA_FLAG_SLAVE_POSS;
                ap->ops = &pata_icside_port_ops;
 
-               pata_icside_setup_ioaddr(ap, info->base, info->port[i]);
+               pata_icside_setup_ioaddr(ap, info->base, info, info->port[i]);
        }
 
        return ata_host_activate(host, ec->irq, ata_interrupt, 0,
index b9a17eb..d0e2e50 100644 (file)
@@ -215,6 +215,8 @@ static int ns87415_check_atapi_dma(struct ata_queued_cmd *qc)
 
 #include <asm/superio.h>
 
+#define SUPERIO_IDE_MAX_RETRIES 25
+
 /**
  *     ns87560_read_buggy      -       workaround buggy Super I/O chip
  *     @port: Port to read
index 6b07b5b..f9b485a 100644 (file)
@@ -449,7 +449,7 @@ static int optiplus_with_udma(struct pci_dev *pdev)
 
        /* Find function 1 */
        dev1 = pci_get_device(0x1045, 0xC701, NULL);
-       if(dev1 == NULL)
+       if (dev1 == NULL)
                return 0;
 
        /* Rev must be >= 0x10 */
index 5db2013..fd36099 100644 (file)
@@ -74,8 +74,7 @@ static int pcmcia_set_mode(struct ata_link *link, struct ata_device **r_failed_d
                return ata_do_set_mode(link, r_failed_dev);
 
        if (memcmp(master->id + ATA_ID_FW_REV,  slave->id + ATA_ID_FW_REV,
-                          ATA_ID_FW_REV_LEN + ATA_ID_PROD_LEN) == 0)
-       {
+                          ATA_ID_FW_REV_LEN + ATA_ID_PROD_LEN) == 0) {
                /* Suspicious match, but could be two cards from
                   the same vendor - check serial */
                if (memcmp(master->id + ATA_ID_SERNO, slave->id + ATA_ID_SERNO,
@@ -248,7 +247,8 @@ static int pcmcia_init_one(struct pcmcia_device *pdev)
                                        goto next_entry;
                                io_base = pdev->io.BasePort1;
                                ctl_base = pdev->io.BasePort1 + 0x0e;
-                       } else goto next_entry;
+                       } else
+                               goto next_entry;
                        /* If we've got this far, we're done */
                        break;
                }
@@ -285,8 +285,8 @@ next_entry:
                printk(KERN_WARNING DRV_NAME ": second channel not yet supported.\n");
 
        /*
-        *      Having done the PCMCIA plumbing the ATA side is relatively
-        *      sane.
+        *      Having done the PCMCIA plumbing the ATA side is relatively
+        *      sane.
         */
        ret = -ENOMEM;
        host = ata_host_alloc(&pdev->dev, 1);
@@ -363,7 +363,7 @@ static struct pcmcia_device_id pcmcia_devices[] = {
        PCMCIA_DEVICE_MANF_CARD(0x0098, 0x0000),        /* Toshiba */
        PCMCIA_DEVICE_MANF_CARD(0x00a4, 0x002d),
        PCMCIA_DEVICE_MANF_CARD(0x00ce, 0x0000),        /* Samsung */
-       PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),        /* Hitachi */
+       PCMCIA_DEVICE_MANF_CARD(0x0319, 0x0000),        /* Hitachi */
        PCMCIA_DEVICE_MANF_CARD(0x2080, 0x0001),
        PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0100),        /* Viking CFA */
        PCMCIA_DEVICE_MANF_CARD(0x4e01, 0x0200),        /* Lexar, Viking CFA */
index 3d3f155..2622577 100644 (file)
@@ -348,7 +348,7 @@ static unsigned long pdc2027x_mode_filter(struct ata_device *adev, unsigned long
        ata_id_c_string(pair->id, model_num, ATA_ID_PROD,
                          ATA_ID_PROD_LEN + 1);
        /* If the master is a maxtor in UDMA6 then the slave should not use UDMA 6 */
-       if(strstr(model_num, "Maxtor") == 0 && pair->dma_mode == XFER_UDMA_6)
+       if (strstr(model_num, "Maxtor") == 0 && pair->dma_mode == XFER_UDMA_6)
                mask &= ~ (1 << (6 + ATA_SHIFT_UDMA));
 
        return ata_pci_default_filter(adev, mask);
index 65d9516..bc7c2d5 100644 (file)
@@ -351,9 +351,9 @@ static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id
                struct pci_dev *bridge = dev->bus->self;
                /* Don't grab anything behind a Promise I2O RAID */
                if (bridge && bridge->vendor == PCI_VENDOR_ID_INTEL) {
-                       ifbridge->device == PCI_DEVICE_ID_INTEL_I960)
+                       if (bridge->device == PCI_DEVICE_ID_INTEL_I960)
                                return -ENODEV;
-                       ifbridge->device == PCI_DEVICE_ID_INTEL_I960RM)
+                       if (bridge->device == PCI_DEVICE_ID_INTEL_I960RM)
                                return -ENODEV;
                }
        }
index 5557613..ea2ef9f 100644 (file)
@@ -570,17 +570,8 @@ static unsigned int scc_bus_softreset(struct ata_port *ap, unsigned int devmask,
        udelay(20);
        out_be32(ioaddr->ctl_addr, ap->ctl);
 
-       /* spec mandates ">= 2ms" before checking status.
-        * We wait 150ms, because that was the magic delay used for
-        * ATAPI devices in Hale Landis's ATADRVR, for the period of time
-        * between when the ATA command register is written, and then
-        * status is checked.  Because waiting for "a while" before
-        * checking status is fine, post SRST, we perform this magic
-        * delay here as well.
-        *
-        * Old drivers/ide uses the 2mS rule and then waits for ready
-        */
-       msleep(150);
+       /* wait a while before checking status */
+       ata_wait_after_reset(ap, deadline);
 
        /* Before we perform post reset processing we want to see if
         * the bus shows 0xFF because the odd clown forgets the D7
index ea7a9a6..a4175fb 100644 (file)
@@ -176,7 +176,7 @@ static int via_cable_detect(struct ata_port *ap) {
        if ((config->flags & VIA_UDMA) < VIA_UDMA_66)
                return ATA_CBL_PATA40;
        /* UDMA 66 chips have only drive side logic */
-       else if((config->flags & VIA_UDMA) < VIA_UDMA_100)
+       else if ((config->flags & VIA_UDMA) < VIA_UDMA_100)
                return ATA_CBL_PATA_UNK;
        /* UDMA 100 or later */
        pci_read_config_dword(pdev, 0x50, &ata66);
index 549cbbe..311cdb3 100644 (file)
@@ -279,7 +279,7 @@ static __init int winbond_init(void)
 
                        if (request_region(port, 2, "pata_winbond")) {
                                ret = winbond_init_one(port);
-                               if(ret <= 0)
+                               if (ret <= 0)
                                        release_region(port, 2);
                                else ct+= ret;
                        }
index 199f7e1..bd4c2a3 100644 (file)
 #define DRV_VERSION    "1.0"
 
 /* macro to calculate base address for ATA regs */
-#define ADMA_ATA_REGS(base,port_no)    ((base) + ((port_no) * 0x40))
+#define ADMA_ATA_REGS(base, port_no)   ((base) + ((port_no) * 0x40))
 
 /* macro to calculate base address for ADMA regs */
-#define ADMA_REGS(base,port_no)                ((base) + 0x80 + ((port_no) * 0x20))
+#define ADMA_REGS(base, port_no)       ((base) + 0x80 + ((port_no) * 0x20))
 
 /* macro to obtain addresses from ata_port */
 #define ADMA_PORT_REGS(ap) \
@@ -128,7 +128,7 @@ struct adma_port_priv {
        adma_state_t            state;
 };
 
-static int adma_ata_init_one (struct pci_dev *pdev,
+static int adma_ata_init_one(struct pci_dev *pdev,
                                const struct pci_device_id *ent);
 static int adma_port_start(struct ata_port *ap);
 static void adma_host_stop(struct ata_host *host);
@@ -340,8 +340,8 @@ static int adma_fill_sg(struct ata_queued_cmd *qc)
                buf[i++] = 0;   /* pPKLW */
                buf[i++] = 0;   /* reserved */
 
-               *(__le32 *)(buf + i)
-                       (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4);
+               *(__le32 *)(buf + i) =
+                       (pFLAGS & pEND) ? 0 : cpu_to_le32(pp->pkt_dma + i + 4);
                i += 4;
 
                VPRINTK("PRD[%u] = (0x%lX, 0x%X)\n", i/4,
@@ -617,7 +617,7 @@ static int adma_port_start(struct ata_port *ap)
                return -ENOMEM;
        /* paranoia? */
        if ((pp->pkt_dma & 7) != 0) {
-               printk("bad alignment for pp->pkt_dma: %08x\n",
+               printk(KERN_ERR "bad alignment for pp->pkt_dma: %08x\n",
                                                (u32)pp->pkt_dma);
                return -ENOMEM;
        }
index 08595f3..323c087 100644 (file)
@@ -143,7 +143,7 @@ static const int scr_map[] = {
        [SCR_CONTROL]   = 2,
 };
 
-static void __iomem * inic_port_base(struct ata_port *ap)
+static void __iomem *inic_port_base(struct ata_port *ap)
 {
        return ap->host->iomap[MMIO_BAR] + ap->port_no * PORT_SIZE;
 }
@@ -448,7 +448,7 @@ static int inic_hardreset(struct ata_link *link, unsigned int *class,
                struct ata_taskfile tf;
 
                /* wait a while before checking status */
-               msleep(150);
+               ata_wait_after_reset(ap, deadline);
 
                rc = ata_wait_ready(ap, deadline);
                /* link occupied, -ENODEV too is an error */
index b39648f..a43f64d 100644 (file)
@@ -1156,7 +1156,7 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
                last_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL);
 }
 
-static inline void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
+static void mv_crqb_pack_cmd(__le16 *cmdw, u8 data, u8 addr, unsigned last)
 {
        u16 tmp = data | (addr << CRQB_CMD_ADDR_SHIFT) | CRQB_CMD_CS |
                (last ? CRQB_CMD_LAST : 0);
@@ -2429,7 +2429,7 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
        struct mv_host_priv *hpriv = host->private_data;
        u32 hp_flags = hpriv->hp_flags;
 
-       switch(board_idx) {
+       switch (board_idx) {
        case chip_5080:
                hpriv->ops = &mv5xxx_ops;
                hp_flags |= MV_HP_GEN_I;
@@ -2510,7 +2510,8 @@ static int mv_chip_id(struct ata_host *host, unsigned int board_idx)
                break;
 
        default:
-               printk(KERN_ERR DRV_NAME ": BUG: invalid board index %u\n", board_idx);
+               dev_printk(KERN_ERR, &pdev->dev,
+                          "BUG: invalid board index %u\n", board_idx);
                return 1;
        }
 
index 2e0279f..35b2df2 100644 (file)
@@ -291,7 +291,7 @@ struct nv_swncq_port_priv {
 };
 
 
-#define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT)))))
+#define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & (1 << (19 + (12 * (PORT)))))
 
 static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 #ifdef CONFIG_PM
@@ -365,9 +365,9 @@ static const struct pci_device_id nv_pci_tbl[] = {
        { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2), SWNCQ },
        { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA), SWNCQ },
        { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2), SWNCQ },
-       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), SWNCQ },
-       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), SWNCQ },
-       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), SWNCQ },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA), GENERIC },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2), GENERIC },
+       { PCI_VDEVICE(NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3), GENERIC },
 
        { } /* terminate list */
 };
@@ -884,8 +884,9 @@ static int nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
                        /* Notifier bits set without a command may indicate the drive
                           is misbehaving. Raise host state machine violation on this
                           condition. */
-                       ata_port_printk(ap, KERN_ERR, "notifier for tag %d with no command?\n",
-                               cpb_num);
+                       ata_port_printk(ap, KERN_ERR,
+                                       "notifier for tag %d with no cmd?\n",
+                                       cpb_num);
                        ehi->err_mask |= AC_ERR_HSM;
                        ehi->action |= ATA_EH_SOFTRESET;
                        ata_port_freeze(ap);
@@ -1012,7 +1013,7 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
                                u32 check_commands;
                                int pos, error = 0;
 
-                               if(ata_tag_valid(ap->link.active_tag))
+                               if (ata_tag_valid(ap->link.active_tag))
                                        check_commands = 1 << ap->link.active_tag;
                                else
                                        check_commands = ap->link.sactive;
@@ -1021,14 +1022,14 @@ static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
                                while ((pos = ffs(check_commands)) && !error) {
                                        pos--;
                                        error = nv_adma_check_cpb(ap, pos,
-                                               notifier_error & (1 << pos) );
-                                       check_commands &= ~(1 << pos );
+                                               notifier_error & (1 << pos));
+                                       check_commands &= ~(1 << pos);
                                }
                        }
                }
        }
 
-       if(notifier_clears[0] || notifier_clears[1]) {
+       if (notifier_clears[0] || notifier_clears[1]) {
                /* Note: Both notifier clear registers must be written
                   if either is set, even if one is zero, according to NVIDIA. */
                struct nv_adma_port_priv *pp = host->ports[0]->private_data;
@@ -1061,7 +1062,7 @@ static void nv_adma_freeze(struct ata_port *ap)
        tmp = readw(mmio + NV_ADMA_CTL);
        writew(tmp & ~(NV_ADMA_CTL_AIEN | NV_ADMA_CTL_HOTPLUG_IEN),
                mmio + NV_ADMA_CTL);
-       readw(mmio + NV_ADMA_CTL );     /* flush posted write */
+       readw(mmio + NV_ADMA_CTL);      /* flush posted write */
 }
 
 static void nv_adma_thaw(struct ata_port *ap)
@@ -1079,7 +1080,7 @@ static void nv_adma_thaw(struct ata_port *ap)
        tmp = readw(mmio + NV_ADMA_CTL);
        writew(tmp | (NV_ADMA_CTL_AIEN | NV_ADMA_CTL_HOTPLUG_IEN),
                mmio + NV_ADMA_CTL);
-       readw(mmio + NV_ADMA_CTL );     /* flush posted write */
+       readw(mmio + NV_ADMA_CTL);      /* flush posted write */
 }
 
 static void nv_adma_irq_clear(struct ata_port *ap)
@@ -1119,7 +1120,7 @@ static void nv_adma_post_internal_cmd(struct ata_queued_cmd *qc)
 {
        struct nv_adma_port_priv *pp = qc->ap->private_data;
 
-       if(pp->flags & NV_ADMA_PORT_REGISTER_MODE)
+       if (pp->flags & NV_ADMA_PORT_REGISTER_MODE)
                ata_bmdma_post_internal_cmd(qc);
 }
 
@@ -1165,7 +1166,7 @@ static int nv_adma_port_start(struct ata_port *ap)
        pp->cpb_dma = mem_dma;
 
        writel(mem_dma & 0xFFFFFFFF,    mmio + NV_ADMA_CPB_BASE_LOW);
-       writel((mem_dma >> 16 ) >> 16,  mmio + NV_ADMA_CPB_BASE_HIGH);
+       writel((mem_dma >> 16) >> 16,   mmio + NV_ADMA_CPB_BASE_HIGH);
 
        mem     += NV_ADMA_MAX_CPBS * NV_ADMA_CPB_SZ;
        mem_dma += NV_ADMA_MAX_CPBS * NV_ADMA_CPB_SZ;
@@ -1189,15 +1190,15 @@ static int nv_adma_port_start(struct ata_port *ap)
 
        /* clear GO for register mode, enable interrupt */
        tmp = readw(mmio + NV_ADMA_CTL);
-       writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN |
-                NV_ADMA_CTL_HOTPLUG_IEN, mmio + NV_ADMA_CTL);
+       writew((tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN |
+               NV_ADMA_CTL_HOTPLUG_IEN, mmio + NV_ADMA_CTL);
 
        tmp = readw(mmio + NV_ADMA_CTL);
        writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
-       readw( mmio + NV_ADMA_CTL );    /* flush posted write */
+       readw(mmio + NV_ADMA_CTL);      /* flush posted write */
        udelay(1);
        writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
-       readw( mmio + NV_ADMA_CTL );    /* flush posted write */
+       readw(mmio + NV_ADMA_CTL);      /* flush posted write */
 
        return 0;
 }
@@ -1237,7 +1238,7 @@ static int nv_adma_port_resume(struct ata_port *ap)
 
        /* set CPB block location */
        writel(pp->cpb_dma & 0xFFFFFFFF,        mmio + NV_ADMA_CPB_BASE_LOW);
-       writel((pp->cpb_dma >> 16 ) >> 16,      mmio + NV_ADMA_CPB_BASE_HIGH);
+       writel((pp->cpb_dma >> 16) >> 16,       mmio + NV_ADMA_CPB_BASE_HIGH);
 
        /* clear any outstanding interrupt conditions */
        writew(0xffff, mmio + NV_ADMA_STAT);
@@ -1250,15 +1251,15 @@ static int nv_adma_port_resume(struct ata_port *ap)
 
        /* clear GO for register mode, enable interrupt */
        tmp = readw(mmio + NV_ADMA_CTL);
-       writew( (tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN |
-                NV_ADMA_CTL_HOTPLUG_IEN, mmio + NV_ADMA_CTL);
+       writew((tmp & ~NV_ADMA_CTL_GO) | NV_ADMA_CTL_AIEN |
+               NV_ADMA_CTL_HOTPLUG_IEN, mmio + NV_ADMA_CTL);
 
        tmp = readw(mmio + NV_ADMA_CTL);
        writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
-       readw( mmio + NV_ADMA_CTL );    /* flush posted write */
+       readw(mmio + NV_ADMA_CTL);      /* flush posted write */
        udelay(1);
        writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
-       readw( mmio + NV_ADMA_CTL );    /* flush posted write */
+       readw(mmio + NV_ADMA_CTL);      /* flush posted write */
 
        return 0;
 }
@@ -1342,7 +1343,8 @@ static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb)
        idx = 0;
 
        ata_for_each_sg(sg, qc) {
-               aprd = (idx < 5) ? &cpb->aprd[idx] : &pp->aprd[NV_ADMA_SGTBL_LEN * qc->tag + (idx-5)];
+               aprd = (idx < 5) ? &cpb->aprd[idx] :
+                              &pp->aprd[NV_ADMA_SGTBL_LEN * qc->tag + (idx-5)];
                nv_adma_fill_aprd(qc, sg, idx, aprd);
                idx++;
        }
@@ -1359,12 +1361,12 @@ static int nv_adma_use_reg_mode(struct ata_queued_cmd *qc)
        /* ADMA engine can only be used for non-ATAPI DMA commands,
           or interrupt-driven no-data commands, where a result taskfile
           is not required. */
-       if((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
+       if ((pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE) ||
           (qc->tf.flags & ATA_TFLAG_POLLING) ||
           (qc->flags & ATA_QCFLAG_RESULT_TF))
                return 1;
 
-       if((qc->flags & ATA_QCFLAG_DMAMAP) ||
+       if ((qc->flags & ATA_QCFLAG_DMAMAP) ||
           (qc->tf.protocol == ATA_PROT_NODATA))
                return 0;
 
@@ -1401,14 +1403,14 @@ static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
 
        nv_adma_tf_to_cpb(&qc->tf, cpb->tf);
 
-       if(qc->flags & ATA_QCFLAG_DMAMAP) {
+       if (qc->flags & ATA_QCFLAG_DMAMAP) {
                nv_adma_fill_sg(qc, cpb);
                ctl_flags |= NV_CPB_CTL_APRD_VALID;
        } else
                memset(&cpb->aprd[0], 0, sizeof(struct nv_adma_prd) * 5);
 
-       /* Be paranoid and don't let the device see NV_CPB_CTL_CPB_VALID until we are
-          finished filling in all of the contents */
+       /* Be paranoid and don't let the device see NV_CPB_CTL_CPB_VALID
+          until we are finished filling in all of the contents */
        wmb();
        cpb->ctl_flags = ctl_flags;
        wmb();
@@ -1435,16 +1437,16 @@ static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
           and (number of cpbs to append -1) in top 8 bits */
        wmb();
 
-       if(curr_ncq != pp->last_issue_ncq) {
-               /* Seems to need some delay before switching between NCQ and non-NCQ
-                  commands, else we get command timeouts and such. */
+       if (curr_ncq != pp->last_issue_ncq) {
+               /* Seems to need some delay before switching between NCQ and
+                  non-NCQ commands, else we get command timeouts and such. */
                udelay(20);
                pp->last_issue_ncq = curr_ncq;
        }
 
        writew(qc->tag, mmio + NV_ADMA_APPEND);
 
-       DPRINTK("Issued tag %u\n",qc->tag);
+       DPRINTK("Issued tag %u\n", qc->tag);
 
        return 0;
 }
@@ -1641,12 +1643,12 @@ static void nv_error_handler(struct ata_port *ap)
 static void nv_adma_error_handler(struct ata_port *ap)
 {
        struct nv_adma_port_priv *pp = ap->private_data;
-       if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
+       if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
                void __iomem *mmio = pp->ctl_block;
                int i;
                u16 tmp;
 
-               if(ata_tag_valid(ap->link.active_tag) || ap->link.sactive) {
+               if (ata_tag_valid(ap->link.active_tag) || ap->link.sactive) {
                        u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
                        u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
                        u32 gen_ctl = readl(pp->gen_block + NV_ADMA_GEN_CTL);
@@ -1654,16 +1656,17 @@ static void nv_adma_error_handler(struct ata_port *ap)
                        u8 cpb_count = readb(mmio + NV_ADMA_CPB_COUNT);
                        u8 next_cpb_idx = readb(mmio + NV_ADMA_NEXT_CPB_IDX);
 
-                       ata_port_printk(ap, KERN_ERR, "EH in ADMA mode, notifier 0x%X "
+                       ata_port_printk(ap, KERN_ERR,
+                               "EH in ADMA mode, notifier 0x%X "
                                "notifier_error 0x%X gen_ctl 0x%X status 0x%X "
                                "next cpb count 0x%X next cpb idx 0x%x\n",
                                notifier, notifier_error, gen_ctl, status,
                                cpb_count, next_cpb_idx);
 
-                       for( i=0;i<NV_ADMA_MAX_CPBS;i++) {
+                       for (i = 0; i < NV_ADMA_MAX_CPBS; i++) {
                                struct nv_adma_cpb *cpb = &pp->cpb[i];
-                               if(ata_tag_valid(ap->link.active_tag) && i == ap->link.active_tag) ||
-                                   ap->link.sactive & (1 << i) )
+                               if ((ata_tag_valid(ap->link.active_tag) && i == ap->link.active_tag) ||
+                                   ap->link.sactive & (1 << i))
                                        ata_port_printk(ap, KERN_ERR,
                                                "CPB %d: ctl_flags 0x%x, resp_flags 0x%x\n",
                                                i, cpb->ctl_flags, cpb->resp_flags);
@@ -1673,8 +1676,9 @@ static void nv_adma_error_handler(struct ata_port *ap)
                /* Push us back into port register mode for error handling. */
                nv_adma_register_mode(ap);
 
-               /* Mark all of the CPBs as invalid to prevent them from being executed */
-               for( i=0;i<NV_ADMA_MAX_CPBS;i++)
+               /* Mark all of the CPBs as invalid to prevent them from
+                  being executed */
+               for (i = 0; i < NV_ADMA_MAX_CPBS; i++)
                        pp->cpb[i].ctl_flags &= ~NV_CPB_CTL_CPB_VALID;
 
                /* clear CPB fetch count */
@@ -1683,10 +1687,10 @@ static void nv_adma_error_handler(struct ata_port *ap)
                /* Reset channel */
                tmp = readw(mmio + NV_ADMA_CTL);
                writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
-               readw( mmio + NV_ADMA_CTL );    /* flush posted write */
+               readw(mmio + NV_ADMA_CTL);      /* flush posted write */
                udelay(1);
                writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
-               readw( mmio + NV_ADMA_CTL );    /* flush posted write */
+               readw(mmio + NV_ADMA_CTL);      /* flush posted write */
        }
 
        ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
@@ -2350,9 +2354,9 @@ static irqreturn_t nv_swncq_interrupt(int irq, void *dev_instance)
        return IRQ_RETVAL(handled);
 }
 
-static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int nv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       static int printed_version = 0;
+       static int printed_version;
        const struct ata_port_info *ppi[] = { NULL, NULL };
        struct ata_host *host;
        struct nv_host_priv *hpriv;
@@ -2364,7 +2368,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
         // Make sure this is a SATA controller by counting the number of bars
         // (NVIDIA SATA controllers will always have six bars).  Otherwise,
         // it's an IDE controller and we ignore it.
-       for (bar=0; bar<6; bar++)
+       for (bar = 0; bar < 6; bar++)
                if (pci_resource_start(pdev, bar) == 0)
                        return -ENODEV;
 
@@ -2381,6 +2385,14 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                type = ADMA;
        }
 
+       if (type == SWNCQ) {
+               if (swncq_enabled)
+                       dev_printk(KERN_NOTICE, &pdev->dev,
+                                  "Using SWNCQ mode\n");
+               else
+                       type = GENERIC;
+       }
+
        ppi[0] = &nv_port_info[type];
        rc = ata_pci_prepare_sff_host(pdev, ppi, &host);
        if (rc)
@@ -2422,10 +2434,8 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                rc = nv_adma_host_init(host);
                if (rc)
                        return rc;
-       } else if (type == SWNCQ && swncq_enabled) {
-               dev_printk(KERN_NOTICE, &pdev->dev, "Using SWNCQ mode\n");
+       } else if (type == SWNCQ)
                nv_swncq_host_init(host);
-       }
 
        pci_set_master(pdev);
        return ata_host_activate(host, pdev->irq, ppi[0]->irq_handler,
@@ -2440,37 +2450,37 @@ static int nv_pci_device_resume(struct pci_dev *pdev)
        int rc;
 
        rc = ata_pci_device_do_resume(pdev);
-       if(rc)
+       if (rc)
                return rc;
 
        if (pdev->dev.power.power_state.event == PM_EVENT_SUSPEND) {
-               if(hpriv->type >= CK804) {
+               if (hpriv->type >= CK804) {
                        u8 regval;
 
                        pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
                        regval |= NV_MCP_SATA_CFG_20_SATA_SPACE_EN;
                        pci_write_config_byte(pdev, NV_MCP_SATA_CFG_20, regval);
                }
-               if(hpriv->type == ADMA) {
+               if (hpriv->type == ADMA) {
                        u32 tmp32;
                        struct nv_adma_port_priv *pp;
                        /* enable/disable ADMA on the ports appropriately */
                        pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32);
 
                        pp = host->ports[0]->private_data;
-                       if(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)
+                       if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)
                                tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT0_EN |
-                                          NV_MCP_SATA_CFG_20_PORT0_PWB_EN);
+                                          NV_MCP_SATA_CFG_20_PORT0_PWB_EN);
                        else
                                tmp32 |=  (NV_MCP_SATA_CFG_20_PORT0_EN |
-                                          NV_MCP_SATA_CFG_20_PORT0_PWB_EN);
+                                          NV_MCP_SATA_CFG_20_PORT0_PWB_EN);
                        pp = host->ports[1]->private_data;
-                       if(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)
+                       if (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)
                                tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT1_EN |
-                                          NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
+                                          NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
                        else
                                tmp32 |=  (NV_MCP_SATA_CFG_20_PORT1_EN |
-                                          NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
+                                          NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
 
                        pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
                }
index 9032131..deb26f0 100644 (file)
@@ -83,10 +83,12 @@ enum {
        PDC_PCI_SYS_ERR         = (1 << 22), /* PCI system error */
        PDC1_PCI_PARITY_ERR     = (1 << 23), /* PCI parity error (from SATA150 driver) */
        PDC1_ERR_MASK           = PDC1_PCI_PARITY_ERR,
-       PDC2_ERR_MASK           = PDC2_HTO_ERR | PDC2_ATA_HBA_ERR | PDC2_ATA_DMA_CNT_ERR,
-       PDC_ERR_MASK            = (PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR | PDC_OVERRUN_ERR
-                                  | PDC_UNDERRUN_ERR | PDC_DRIVE_ERR | PDC_PCI_SYS_ERR
-                                  | PDC1_ERR_MASK | PDC2_ERR_MASK),
+       PDC2_ERR_MASK           = PDC2_HTO_ERR | PDC2_ATA_HBA_ERR |
+                                 PDC2_ATA_DMA_CNT_ERR,
+       PDC_ERR_MASK            = PDC_PH_ERR | PDC_SH_ERR | PDC_DH_ERR |
+                                 PDC_OVERRUN_ERR | PDC_UNDERRUN_ERR |
+                                 PDC_DRIVE_ERR | PDC_PCI_SYS_ERR |
+                                 PDC1_ERR_MASK | PDC2_ERR_MASK,
 
        board_2037x             = 0,    /* FastTrak S150 TX2plus */
        board_2037x_pata        = 1,    /* FastTrak S150 TX2plus PATA port */
@@ -695,19 +697,20 @@ static void pdc_irq_clear(struct ata_port *ap)
        readl(mmio + PDC_INT_SEQMASK);
 }
 
-static inline int pdc_is_sataii_tx4(unsigned long flags)
+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 inline unsigned int pdc_port_no_to_ata_no(unsigned int port_no, int is_sataii_tx4)
+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)
+static irqreturn_t pdc_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        struct ata_port *ap;
@@ -839,15 +842,16 @@ static unsigned int pdc_qc_issue_prot(struct ata_queued_cmd *qc)
 
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
-       WARN_ON (tf->protocol == ATA_PROT_DMA ||
-                tf->protocol == ATA_PROT_ATAPI_DMA);
+       WARN_ON(tf->protocol == ATA_PROT_DMA ||
+               tf->protocol == ATA_PROT_ATAPI_DMA);
        ata_tf_load(ap, tf);
 }
 
-static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
+static void pdc_exec_command_mmio(struct ata_port *ap,
+                                 const struct ata_taskfile *tf)
 {
-       WARN_ON (tf->protocol == ATA_PROT_DMA ||
-                tf->protocol == ATA_PROT_ATAPI_DMA);
+       WARN_ON(tf->protocol == ATA_PROT_DMA ||
+               tf->protocol == ATA_PROT_ATAPI_DMA);
        ata_exec_command(ap, tf);
 }
 
@@ -870,8 +874,11 @@ static int pdc_check_atapi_dma(struct ata_queued_cmd *qc)
        }
        /* -45150 (FFFF4FA2) to -1 (FFFFFFFF) shall use PIO mode */
        if (scsicmd[0] == WRITE_10) {
-               unsigned int lba;
-               lba = (scsicmd[2] << 24) | (scsicmd[3] << 16) | (scsicmd[4] << 8) | scsicmd[5];
+               unsigned int lba =
+                       (scsicmd[2] << 24) |
+                       (scsicmd[3] << 16) |
+                       (scsicmd[4] << 8) |
+                       scsicmd[5];
                if (lba >= 0xFFFF4FA2)
                        pio = 1;
        }
@@ -956,7 +963,8 @@ static void pdc_host_init(struct ata_host *host)
        writel(tmp, mmio + PDC_SLEW_CTL);
 }
 
-static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int pdc_ata_init_one(struct pci_dev *pdev,
+                           const struct pci_device_id *ent)
 {
        static int printed_version;
        const struct ata_port_info *pi = &pdc_port_info[ent->driver_data];
index c4c4cd2..6d43ba7 100644 (file)
@@ -113,7 +113,7 @@ struct qs_port_priv {
 
 static int qs_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
 static int qs_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
-static int qs_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static int qs_ata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int qs_port_start(struct ata_port *ap);
 static void qs_host_stop(struct ata_host *host);
 static void qs_phy_reset(struct ata_port *ap);
@@ -135,7 +135,6 @@ static struct scsi_host_template qs_ata_sht = {
        .sg_tablesize           = QS_MAX_PRD,
        .cmd_per_lun            = ATA_SHT_CMD_PER_LUN,
        .emulated               = ATA_SHT_EMULATED,
-       //FIXME .use_clustering         = ATA_SHT_USE_CLUSTERING,
        .use_clustering         = ENABLE_CLUSTERING,
        .proc_name              = DRV_NAME,
        .dma_boundary           = QS_DMA_BOUNDARY,
index ea3a0ab..4e6e381 100644 (file)
@@ -111,7 +111,7 @@ enum {
        SIL_QUIRK_UDMA5MAX      = (1 << 1),
 };
 
-static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 #ifdef CONFIG_PM
 static int sil_pci_device_resume(struct pci_dev *pdev);
 #endif
@@ -138,7 +138,7 @@ static const struct pci_device_id sil_pci_tbl[] = {
 
 /* TODO firmware versions should be added - eric */
 static const struct sil_drivelist {
-       const char * product;
+       const char *product;
        unsigned int quirk;
 } sil_blacklist [] = {
        { "ST320012AS",         SIL_QUIRK_MOD15WRITE },
@@ -279,7 +279,7 @@ MODULE_LICENSE("GPL");
 MODULE_DEVICE_TABLE(pci, sil_pci_tbl);
 MODULE_VERSION(DRV_VERSION);
 
-static int slow_down = 0;
+static int slow_down;
 module_param(slow_down, int, 0444);
 MODULE_PARM_DESC(slow_down, "Sledgehammer used to work around random problems, by limiting commands to 15 sectors (0=off, 1=on)");
 
@@ -332,7 +332,8 @@ static int sil_set_mode(struct ata_link *link, struct ata_device **r_failed)
        return 0;
 }
 
-static inline void __iomem *sil_scr_addr(struct ata_port *ap, unsigned int sc_reg)
+static inline void __iomem *sil_scr_addr(struct ata_port *ap,
+                                        unsigned int sc_reg)
 {
        void __iomem *offset = ap->ioaddr.scr_addr;
 
@@ -643,7 +644,7 @@ static void sil_init_controller(struct ata_host *host)
        }
 }
 
-static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int sil_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        int board_id = ent->driver_data;
index 26ebffc..3c481e0 100644 (file)
@@ -674,7 +674,7 @@ static int sil24_do_softreset(struct ata_link *link, unsigned int *class,
 
        /* put the port into known state */
        if (sil24_init_port(ap)) {
-               reason ="port not ready";
+               reason = "port not ready";
                goto err;
        }
 
@@ -756,7 +756,8 @@ static int sil24_hardreset(struct ata_link *link, unsigned int *class,
 
        writel(PORT_CS_DEV_RST, port + PORT_CTRL_STAT);
        tmp = ata_wait_register(port + PORT_CTRL_STAT,
-                               PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10, tout_msec);
+                               PORT_CS_DEV_RST, PORT_CS_DEV_RST, 10,
+                               tout_msec);
 
        /* SStatus oscillates between zero and valid status after
         * DEV_RST, debounce it.
@@ -1270,7 +1271,7 @@ static void sil24_init_controller(struct ata_host *host)
                                                PORT_CS_PORT_RST, 10, 100);
                        if (tmp & PORT_CS_PORT_RST)
                                dev_printk(KERN_ERR, host->dev,
-                                          "failed to clear port RST\n");
+                                          "failed to clear port RST\n");
                }
 
                /* configure port */
@@ -1283,7 +1284,7 @@ static void sil24_init_controller(struct ata_host *host)
 
 static int sil24_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
-       static int printed_version = 0;
+       static int printed_version;
        struct ata_port_info pi = sil24_port_info[ent->driver_data];
        const struct ata_port_info *ppi[] = { &pi, NULL };
        void __iomem * const *iomap;
index f147dc7..a01260a 100644 (file)
@@ -63,17 +63,17 @@ enum {
        GENCTL_IOMAPPED_SCR     = (1 << 26), /* if set, SCRs are in IO space */
 };
 
-static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static int sis_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+static int sis_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
+static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
 
 static const struct pci_device_id sis_pci_tbl[] = {
-       { PCI_VDEVICE(SI, 0x0180), sis_180 },           /* SiS 964/180 */
-       { PCI_VDEVICE(SI, 0x0181), sis_180 },           /* SiS 964/180 */
-       { PCI_VDEVICE(SI, 0x0182), sis_180 },           /* SiS 965/965L */
-       { PCI_VDEVICE(SI, 0x0183), sis_180 },           /* SiS 965/965L */
-       { PCI_VDEVICE(SI, 0x1182), sis_180 },           /* SiS 966/680 */
-       { PCI_VDEVICE(SI, 0x1183), sis_180 },           /* SiS 966/966L/968/680 */
+       { PCI_VDEVICE(SI, 0x0180), sis_180 },   /* SiS 964/180 */
+       { PCI_VDEVICE(SI, 0x0181), sis_180 },   /* SiS 964/180 */
+       { PCI_VDEVICE(SI, 0x0182), sis_180 },   /* SiS 965/965L */
+       { PCI_VDEVICE(SI, 0x0183), sis_180 },   /* SiS 965/965L */
+       { PCI_VDEVICE(SI, 0x1182), sis_180 },   /* SiS 966/680 */
+       { PCI_VDEVICE(SI, 0x1183), sis_180 },   /* SiS 966/966L/968/680 */
 
        { }     /* terminate list */
 };
@@ -149,24 +149,24 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
 
        if (ap->port_no)  {
                switch (pdev->device) {
-                       case 0x0180:
-                       case 0x0181:
-                               pci_read_config_byte(pdev, SIS_PMR, &pmr);
-                               if ((pmr & SIS_PMR_COMBINED) == 0)
-                                       addr += SIS180_SATA1_OFS;
-                               break;
-
-                       case 0x0182:
-                       case 0x0183:
-                       case 0x1182:
-                               addr += SIS182_SATA1_OFS;
-                               break;
+               case 0x0180:
+               case 0x0181:
+                       pci_read_config_byte(pdev, SIS_PMR, &pmr);
+                       if ((pmr & SIS_PMR_COMBINED) == 0)
+                               addr += SIS180_SATA1_OFS;
+                       break;
+
+               case 0x0182:
+               case 0x0183:
+               case 0x1182:
+                       addr += SIS182_SATA1_OFS;
+                       break;
                }
        }
        return addr;
 }
 
-static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static u32 sis_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
@@ -190,7 +190,7 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg, u32 *val)
        return 0;
 }
 
-static void sis_scr_cfg_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
+static void sis_scr_cfg_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
@@ -253,7 +253,7 @@ static int sis_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
        return 0;
 }
 
-static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int sis_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        struct ata_port_info pi = sis_port_info;
@@ -309,29 +309,33 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                } else {
                        dev_printk(KERN_INFO, &pdev->dev,
                                   "Detected SiS 180/181 chipset in combined mode\n");
-                       port2_start=0;
+                       port2_start = 0;
                        pi.flags |= ATA_FLAG_SLAVE_POSS;
                }
                break;
 
        case 0x0182:
        case 0x0183:
-               pci_read_config_dword ( pdev, 0x6C, &val);
+               pci_read_config_dword(pdev, 0x6C, &val);
                if (val & (1L << 31)) {
-                       dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965 chipset\n");
+                       dev_printk(KERN_INFO, &pdev->dev,
+                                  "Detected SiS 182/965 chipset\n");
                        pi.flags |= ATA_FLAG_SLAVE_POSS;
                } else {
-                       dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965L chipset\n");
+                       dev_printk(KERN_INFO, &pdev->dev,
+                                  "Detected SiS 182/965L chipset\n");
                }
                break;
 
        case 0x1182:
-               dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1182/966/680 SATA controller\n");
+               dev_printk(KERN_INFO, &pdev->dev,
+                          "Detected SiS 1182/966/680 SATA controller\n");
                pi.flags |= ATA_FLAG_SLAVE_POSS;
                break;
 
        case 0x1183:
-               dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 1183/966/966L/968/680 controller in PATA mode\n");
+               dev_printk(KERN_INFO, &pdev->dev,
+                          "Detected SiS 1183/966/966L/968/680 controller in PATA mode\n");
                ppi[0] = &sis_info133_for_sata;
                ppi[1] = &sis_info133_for_sata;
                break;
index 12d613c..69f651e 100644 (file)
@@ -182,7 +182,7 @@ static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
                tf->hob_lbal = lbal >> 8;
                tf->hob_lbam = lbam >> 8;
                tf->hob_lbah = lbah >> 8;
-        }
+       }
 }
 
 /**
@@ -193,7 +193,7 @@ static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
  *     spin_lock_irqsave(host lock)
  */
 
-static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
+static void k2_bmdma_setup_mmio(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
@@ -224,7 +224,7 @@ static void k2_bmdma_setup_mmio (struct ata_queued_cmd *qc)
  *     spin_lock_irqsave(host lock)
  */
 
-static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
+static void k2_bmdma_start_mmio(struct ata_queued_cmd *qc)
 {
        struct ata_port *ap = qc->ap;
        void __iomem *mmio = ap->ioaddr.bmdma_addr;
@@ -255,7 +255,7 @@ static void k2_bmdma_start_mmio (struct ata_queued_cmd *qc)
 
 static u8 k2_stat_check_status(struct ata_port *ap)
 {
-               return readl(ap->ioaddr.status_addr);
+       return readl(ap->ioaddr.status_addr);
 }
 
 #ifdef CONFIG_PPC_OF
@@ -395,7 +395,7 @@ static void k2_sata_setup_port(struct ata_ioports *port, void __iomem *base)
 }
 
 
-static int k2_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        const struct ata_port_info *ppi[] =
index b6026bc..4d85718 100644 (file)
@@ -212,9 +212,9 @@ struct pdc_host_priv {
 };
 
 
-static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static int pdc_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void pdc_eng_timeout(struct ata_port *ap);
-static void pdc_20621_phy_reset (struct ata_port *ap);
+static void pdc_20621_phy_reset(struct ata_port *ap);
 static int pdc_port_start(struct ata_port *ap);
 static void pdc20621_qc_prep(struct ata_queued_cmd *qc);
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf);
@@ -320,16 +320,16 @@ static int pdc_port_start(struct ata_port *ap)
        return 0;
 }
 
-static void pdc_20621_phy_reset (struct ata_port *ap)
+static void pdc_20621_phy_reset(struct ata_port *ap)
 {
        VPRINTK("ENTER\n");
-        ap->cbl = ATA_CBL_SATA;
-        ata_port_probe(ap);
-        ata_bus_reset(ap);
+       ap->cbl = ATA_CBL_SATA;
+       ata_port_probe(ap);
+       ata_bus_reset(ap);
 }
 
 static inline void pdc20621_ata_sg(struct ata_taskfile *tf, u8 *buf,
-                                          unsigned int portno,
+                                  unsigned int portno,
                                           unsigned int total_len)
 {
        u32 addr;
@@ -351,7 +351,7 @@ static inline void pdc20621_ata_sg(struct ata_taskfile *tf, u8 *buf,
 }
 
 static inline void pdc20621_host_sg(struct ata_taskfile *tf, u8 *buf,
-                                           unsigned int portno,
+                                   unsigned int portno,
                                            unsigned int total_len)
 {
        u32 addr;
@@ -711,8 +711,8 @@ static unsigned int pdc20621_qc_issue_prot(struct ata_queued_cmd *qc)
        return ata_qc_issue_prot(qc);
 }
 
-static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
-                                          struct ata_queued_cmd *qc,
+static inline unsigned int pdc20621_host_intr(struct ata_port *ap,
+                                         struct ata_queued_cmd *qc,
                                          unsigned int doing_hdma,
                                          void __iomem *mmio)
 {
@@ -803,7 +803,7 @@ static void pdc20621_irq_clear(struct ata_port *ap)
        readl(mmio + PDC_20621_SEQMASK);
 }
 
-static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance)
+static irqreturn_t pdc20621_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        struct ata_port *ap;
@@ -836,9 +836,9 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance)
                return IRQ_NONE;
        }
 
-        spin_lock(&host->lock);
+       spin_lock(&host->lock);
 
-        for (i = 1; i < 9; i++) {
+       for (i = 1; i < 9; i++) {
                port_no = i - 1;
                if (port_no > 3)
                        port_no -= 4;
@@ -859,7 +859,7 @@ static irqreturn_t pdc20621_interrupt (int irq, void *dev_instance)
                }
        }
 
-        spin_unlock(&host->lock);
+       spin_unlock(&host->lock);
 
        VPRINTK("mask == 0x%x\n", mask);
 
@@ -906,16 +906,16 @@ static void pdc_eng_timeout(struct ata_port *ap)
 
 static void pdc_tf_load_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
-       WARN_ON (tf->protocol == ATA_PROT_DMA ||
-                tf->protocol == ATA_PROT_NODATA);
+       WARN_ON(tf->protocol == ATA_PROT_DMA ||
+               tf->protocol == ATA_PROT_NODATA);
        ata_tf_load(ap, tf);
 }
 
 
 static void pdc_exec_command_mmio(struct ata_port *ap, const struct ata_taskfile *tf)
 {
-       WARN_ON (tf->protocol == ATA_PROT_DMA ||
-                tf->protocol == ATA_PROT_NODATA);
+       WARN_ON(tf->protocol == ATA_PROT_DMA ||
+               tf->protocol == ATA_PROT_NODATA);
        ata_exec_command(ap, tf);
 }
 
@@ -953,7 +953,7 @@ static void pdc20621_get_from_dimm(struct ata_host *host, void *psource,
        mmio += PDC_CHIP0_OFS;
 
        page_mask = 0x00;
-       window_size = 0x2000 * 4; /* 32K byte uchar size */
+       window_size = 0x2000 * 4; /* 32K byte uchar size */
        idx = (u16) (offset / window_size);
 
        writel(0x01, mmio + PDC_GENERAL_CTLR);
@@ -979,7 +979,7 @@ static void pdc20621_get_from_dimm(struct ata_host *host, void *psource,
                              window_size / 4);
                psource += window_size;
                size -= window_size;
-               idx ++;
+               idx++;
        }
 
        if (size) {
@@ -1008,7 +1008,7 @@ static void pdc20621_put_to_dimm(struct ata_host *host, void *psource,
        mmio += PDC_CHIP0_OFS;
 
        page_mask = 0x00;
-       window_size = 0x2000 * 4;       /* 32K byte uchar size */
+       window_size = 0x2000 * 4;       /* 32K byte uchar size */
        idx = (u16) (offset / window_size);
 
        writel(((idx) << page_mask), mmio + PDC_DIMM_WINDOW_CTLR);
@@ -1031,7 +1031,7 @@ static void pdc20621_put_to_dimm(struct ata_host *host, void *psource,
                readl(mmio + PDC_GENERAL_CTLR);
                psource += window_size;
                size -= window_size;
-               idx ++;
+               idx++;
        }
 
        if (size) {
@@ -1050,7 +1050,7 @@ static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
        void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
        u32 i2creg  = 0;
        u32 status;
-       u32 count =0;
+       u32 count = 0;
 
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
@@ -1082,21 +1082,21 @@ static unsigned int pdc20621_i2c_read(struct ata_host *host, u32 device,
 
 static int pdc20621_detect_dimm(struct ata_host *host)
 {
-       u32 data=0 ;
+       u32 data = 0;
        if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                             PDC_DIMM_SPD_SYSTEM_FREQ, &data)) {
-               if (data == 100)
+               if (data == 100)
                        return 100;
-       } else
+       } else
                return 0;
 
        if (pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, 9, &data)) {
-               if(data <= 0x75)
+               if (data <= 0x75)
                        return 133;
-       } else
+       } else
                return 0;
 
-       return 0;
+       return 0;
 }
 
 
@@ -1104,8 +1104,8 @@ static int pdc20621_prog_dimm0(struct ata_host *host)
 {
        u32 spd0[50];
        u32 data = 0;
-       int size, i;
-       u8 bdimmsize;
+       int size, i;
+       u8 bdimmsize;
        void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
        static const struct {
                unsigned int reg;
@@ -1128,40 +1128,40 @@ static int pdc20621_prog_dimm0(struct ata_host *host)
        /* hard-code chip #0 */
        mmio += PDC_CHIP0_OFS;
 
-       for(i=0; i<ARRAY_SIZE(pdc_i2c_read_data); i++)
+       for (i = 0; i < ARRAY_SIZE(pdc_i2c_read_data); i++)
                pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS,
                                  pdc_i2c_read_data[i].reg,
                                  &spd0[pdc_i2c_read_data[i].ofs]);
 
-       data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4);
-       data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) |
+       data |= (spd0[4] - 8) | ((spd0[21] != 0) << 3) | ((spd0[3]-11) << 4);
+       data |= ((spd0[17] / 4) << 6) | ((spd0[5] / 2) << 7) |
                ((((spd0[27] + 9) / 10) - 1) << 8) ;
-       data |= (((((spd0[29] > spd0[28])
+       data |= (((((spd0[29] > spd0[28])
                    ? spd0[29] : spd0[28]) + 9) / 10) - 1) << 10;
-       data |= ((spd0[30] - spd0[29] + 9) / 10 - 2) << 12;
+       data |= ((spd0[30] - spd0[29] + 9) / 10 - 2) << 12;
 
-       if (spd0[18] & 0x08)
+       if (spd0[18] & 0x08)
                data |= ((0x03) << 14);
-       else if (spd0[18] & 0x04)
+       else if (spd0[18] & 0x04)
                data |= ((0x02) << 14);
-       else if (spd0[18] & 0x01)
+       else if (spd0[18] & 0x01)
                data |= ((0x01) << 14);
-       else
+       else
                data |= (0 << 14);
 
-       /*
+       /*
           Calculate the size of bDIMMSize (power of 2) and
           merge the DIMM size by program start/end address.
        */
 
-       bdimmsize = spd0[4] + (spd0[5] / 2) + spd0[3] + (spd0[17] / 2) + 3;
-       size = (1 << bdimmsize) >> 20;  /* size = xxx(MB) */
-       data |= (((size / 16) - 1) << 16);
-       data |= (0 << 23);
+       bdimmsize = spd0[4] + (spd0[5] / 2) + spd0[3] + (spd0[17] / 2) + 3;
+       size = (1 << bdimmsize) >> 20;  /* size = xxx(MB) */
+       data |= (((size / 16) - 1) << 16);
+       data |= (0 << 23);
        data |= 8;
-       writel(data, mmio + PDC_DIMM0_CONTROL);
+       writel(data, mmio + PDC_DIMM0_CONTROL);
        readl(mmio + PDC_DIMM0_CONTROL);
-       return size;
+       return size;
 }
 
 
@@ -1172,9 +1172,9 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
        void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
-       mmio += PDC_CHIP0_OFS;
+       mmio += PDC_CHIP0_OFS;
 
-       /*
+       /*
          Set To Default : DIMM Module Global Control Register (0x022259F1)
          DIMM Arbitration Disable (bit 20)
          DIMM Data/Control Output Driving Selection (bit12 - bit15)
@@ -1193,40 +1193,40 @@ static unsigned int pdc20621_prog_dimm_global(struct ata_host *host)
                writel(data, mmio + PDC_SDRAM_CONTROL);
                readl(mmio + PDC_SDRAM_CONTROL);
                printk(KERN_ERR "Local DIMM ECC Enabled\n");
-       }
+       }
 
-       /* DIMM Initialization Select/Enable (bit 18/19) */
-       data &= (~(1<<18));
-       data |= (1<<19);
-       writel(data, mmio + PDC_SDRAM_CONTROL);
+       /* DIMM Initialization Select/Enable (bit 18/19) */
+       data &= (~(1<<18));
+       data |= (1<<19);
+       writel(data, mmio + PDC_SDRAM_CONTROL);
 
-       error = 1;
-       for (i = 1; i <= 10; i++) {   /* polling ~5 secs */
+       error = 1;
+       for (i = 1; i <= 10; i++) {   /* polling ~5 secs */
                data = readl(mmio + PDC_SDRAM_CONTROL);
                if (!(data & (1<<19))) {
-                       error = 0;
-                       break;
+                       error = 0;
+                       break;
                }
                msleep(i*100);
-       }
-       return error;
+       }
+       return error;
 }
 
 
 static unsigned int pdc20621_dimm_init(struct ata_host *host)
 {
        int speed, size, length;
-       u32 addr,spd0,pci_status;
-       u32 tmp=0;
-       u32 time_period=0;
-       u32 tcount=0;
-       u32 ticks=0;
-       u32 clock=0;
-       u32 fparam=0;
+       u32 addr, spd0, pci_status;
+       u32 tmp = 0;
+       u32 time_period = 0;
+       u32 tcount = 0;
+       u32 ticks = 0;
+       u32 clock = 0;
+       u32 fparam = 0;
        void __iomem *mmio = host->iomap[PDC_MMIO_BAR];
 
        /* hard-code chip #0 */
-       mmio += PDC_CHIP0_OFS;
+       mmio += PDC_CHIP0_OFS;
 
        /* Initialize PLL based upon PCI Bus Frequency */
 
@@ -1254,7 +1254,7 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host)
           If SX4 is on PCI-X bus, after 3 seconds, the timer counter
           register should be >= (0xffffffff - 3x10^8).
        */
-       if(tcount >= PCI_X_TCOUNT) {
+       if (tcount >= PCI_X_TCOUNT) {
                ticks = (time_period - tcount);
                VPRINTK("Num counters 0x%x (%d)\n", ticks, ticks);
 
@@ -1285,41 +1285,43 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host)
        if (!(speed = pdc20621_detect_dimm(host))) {
                printk(KERN_ERR "Detect Local DIMM Fail\n");
                return 1;       /* DIMM error */
-       }
-       VPRINTK("Local DIMM Speed = %d\n", speed);
+       }
+       VPRINTK("Local DIMM Speed = %d\n", speed);
 
-       /* Programming DIMM0 Module Control Register (index_CID0:80h) */
+       /* Programming DIMM0 Module Control Register (index_CID0:80h) */
        size = pdc20621_prog_dimm0(host);
-       VPRINTK("Local DIMM Size = %dMB\n",size);
+       VPRINTK("Local DIMM Size = %dMB\n", size);
 
-       /* Programming DIMM Module Global Control Register (index_CID0:88h) */
+       /* Programming DIMM Module Global Control Register (index_CID0:88h) */
        if (pdc20621_prog_dimm_global(host)) {
                printk(KERN_ERR "Programming DIMM Module Global Control Register Fail\n");
                return 1;
-       }
+       }
 
 #ifdef ATA_VERBOSE_DEBUG
        {
-               u8 test_parttern1[40] = {0x55,0xAA,'P','r','o','m','i','s','e',' ',
-                               'N','o','t',' ','Y','e','t',' ','D','e','f','i','n','e','d',' ',
-                                '1','.','1','0',
-                               '9','8','0','3','1','6','1','2',0,0};
+               u8 test_parttern1[40] =
+                       {0x55,0xAA,'P','r','o','m','i','s','e',' ',
+                       'N','o','t',' ','Y','e','t',' ',
+                       'D','e','f','i','n','e','d',' ',
+                       '1','.','1','0',
+                       '9','8','0','3','1','6','1','2',0,0};
                u8 test_parttern2[40] = {0};
 
-               pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x10040, 40);
-               pdc20621_put_to_dimm(host, (void *) test_parttern2, 0x40, 40);
+               pdc20621_put_to_dimm(host, test_parttern2, 0x10040, 40);
+               pdc20621_put_to_dimm(host, test_parttern2, 0x40, 40);
 
-               pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x10040, 40);
-               pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
+               pdc20621_put_to_dimm(host, test_parttern1, 0x10040, 40);
+               pdc20621_get_from_dimm(host, test_parttern2, 0x40, 40);
                printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
                       test_parttern2[1], &(test_parttern2[2]));
-               pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x10040,
+               pdc20621_get_from_dimm(host, test_parttern2, 0x10040,
                                       40);
                printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
                       test_parttern2[1], &(test_parttern2[2]));
 
-               pdc20621_put_to_dimm(host, (void *) test_parttern1, 0x40, 40);
-               pdc20621_get_from_dimm(host, (void *) test_parttern2, 0x40, 40);
+               pdc20621_put_to_dimm(host, test_parttern1, 0x40, 40);
+               pdc20621_get_from_dimm(host, test_parttern2, 0x40, 40);
                printk(KERN_ERR "%x, %x, %s\n", test_parttern2[0],
                       test_parttern2[1], &(test_parttern2[2]));
        }
@@ -1375,7 +1377,8 @@ static void pdc_20621_init(struct ata_host *host)
        readl(mmio + PDC_HDMA_CTLSTAT);         /* flush */
 }
 
-static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int pdc_sata_init_one(struct pci_dev *pdev,
+                            const struct pci_device_id *ent)
 {
        static int printed_version;
        const struct ata_port_info *ppi[] =
index d394da0..e710e71 100644 (file)
@@ -56,9 +56,9 @@ struct uli_priv {
        unsigned int            scr_cfg_addr[uli_max_ports];
 };
 
-static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
-static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val);
-static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val);
+static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
+static int uli_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
+static int uli_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
 
 static const struct pci_device_id uli_pci_tbl[] = {
        { PCI_VDEVICE(AL, 0x5289), uli_5289 },
@@ -143,7 +143,7 @@ static unsigned int get_scr_cfg_addr(struct ata_port *ap, unsigned int sc_reg)
        return hpriv->scr_cfg_addr[ap->port_no] + (4 * sc_reg);
 }
 
-static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
+static u32 uli_scr_cfg_read(struct ata_port *ap, unsigned int sc_reg)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        unsigned int cfg_addr = get_scr_cfg_addr(ap, sc_reg);
@@ -153,7 +153,7 @@ static u32 uli_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
        return val;
 }
 
-static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
+static void uli_scr_cfg_write(struct ata_port *ap, unsigned int scr, u32 val)
 {
        struct pci_dev *pdev = to_pci_dev(ap->host->dev);
        unsigned int cfg_addr = get_scr_cfg_addr(ap, scr);
@@ -161,7 +161,7 @@ static void uli_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
        pci_write_config_dword(pdev, cfg_addr, val);
 }
 
-static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val)
+static int uli_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val)
 {
        if (sc_reg > SCR_CONTROL)
                return -EINVAL;
@@ -170,16 +170,16 @@ static int uli_scr_read (struct ata_port *ap, unsigned int sc_reg, u32 *val)
        return 0;
 }
 
-static int uli_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
+static int uli_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val)
 {
-       if (sc_reg > SCR_CONTROL)       //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0
+       if (sc_reg > SCR_CONTROL) //SCR_CONTROL=2, SCR_ERROR=1, SCR_STATUS=0
                return -EINVAL;
 
        uli_scr_cfg_write(ap, sc_reg, val);
        return 0;
 }
 
-static int uli_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int uli_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        const struct ata_port_info *ppi[] = { &uli_port_info, NULL };
index cc6ee08..3ef072f 100644 (file)
@@ -3,7 +3,7 @@
  *
  *  Maintained by:  Jeff Garzik <jgarzik@pobox.com>
  *                Please ALWAYS copy linux-ide@vger.kernel.org
                 on emails.
*                on emails.
  *
  *  Copyright 2003-2004 Red Hat, Inc.  All rights reserved.
  *  Copyright 2003-2004 Jeff Garzik
@@ -69,7 +69,7 @@ enum {
        SATA_EXT_PHY            = (1 << 6), /* 0==use PATA, 1==ext phy */
 };
 
-static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
+static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent);
 static int svia_scr_read(struct ata_port *ap, unsigned int sc_reg, u32 *val);
 static int svia_scr_write(struct ata_port *ap, unsigned int sc_reg, u32 val);
 static void svia_noop_freeze(struct ata_port *ap);
@@ -372,12 +372,12 @@ static const unsigned int vt6421_bar_sizes[] = {
        16, 16, 16, 16, 32, 128
 };
 
-static void __iomem * svia_scr_addr(void __iomem *addr, unsigned int port)
+static void __iomem *svia_scr_addr(void __iomem *addr, unsigned int port)
 {
        return addr + (port * 128);
 }
 
-static void __iomem * vt6421_scr_addr(void __iomem *addr, unsigned int port)
+static void __iomem *vt6421_scr_addr(void __iomem *addr, unsigned int port)
 {
        return addr + (port * 64);
 }
@@ -472,7 +472,7 @@ static void svia_configure(struct pci_dev *pdev)
        if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "enabling SATA channels (0x%x)\n",
-                          (int) tmp8);
+                          (int) tmp8);
                tmp8 |= ALL_PORTS;
                pci_write_config_byte(pdev, SATA_CHAN_ENAB, tmp8);
        }
@@ -482,7 +482,7 @@ static void svia_configure(struct pci_dev *pdev)
        if ((tmp8 & ALL_PORTS) != ALL_PORTS) {
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "enabling SATA channel interrupts (0x%x)\n",
-                          (int) tmp8);
+                          (int) tmp8);
                tmp8 |= ALL_PORTS;
                pci_write_config_byte(pdev, SATA_INT_GATE, tmp8);
        }
@@ -492,13 +492,13 @@ static void svia_configure(struct pci_dev *pdev)
        if ((tmp8 & NATIVE_MODE_ALL) != NATIVE_MODE_ALL) {
                dev_printk(KERN_DEBUG, &pdev->dev,
                           "enabling SATA channel native mode (0x%x)\n",
-                          (int) tmp8);
+                          (int) tmp8);
                tmp8 |= NATIVE_MODE_ALL;
                pci_write_config_byte(pdev, SATA_NATIVE_MODE, tmp8);
        }
 }
 
-static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int svia_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
 {
        static int printed_version;
        unsigned int i;
@@ -525,8 +525,8 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
                        dev_printk(KERN_ERR, &pdev->dev,
                                "invalid PCI BAR %u (sz 0x%llx, val 0x%llx)\n",
                                i,
-                               (unsigned long long)pci_resource_start(pdev, i),
-                               (unsigned long long)pci_resource_len(pdev, i));
+                               (unsigned long long)pci_resource_start(pdev, i),
+                               (unsigned long long)pci_resource_len(pdev, i));
                        return -ENODEV;
                }
 
index 0d9be16..95ae3ed 100644 (file)
@@ -162,7 +162,8 @@ static void vsc_sata_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
        /*
         * The only thing the ctl register is used for is SRST.
         * That is not enabled or disabled via tf_load.
-        * However, if ATA_NIEN is changed, then we need to change the interrupt register.
+        * However, if ATA_NIEN is changed, then we need to change
+        * the interrupt register.
         */
        if ((tf->ctl & ATA_NIEN) != (ap->last_ctl & ATA_NIEN)) {
                ap->last_ctl = tf->ctl;
@@ -219,7 +220,7 @@ static void vsc_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
                tf->hob_lbal = lbal >> 8;
                tf->hob_lbam = lbam >> 8;
                tf->hob_lbah = lbah >> 8;
-        }
+       }
 }
 
 static inline void vsc_error_intr(u8 port_status, struct ata_port *ap)
@@ -256,9 +257,10 @@ static void vsc_port_intr(u8 port_status, struct ata_port *ap)
 /*
  * vsc_sata_interrupt
  *
- * Read the interrupt register and process for the devices that have them pending.
+ * Read the interrupt register and process for the devices that have
+ * them pending.
  */
-static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance)
+static irqreturn_t vsc_sata_interrupt(int irq, void *dev_instance)
 {
        struct ata_host *host = dev_instance;
        unsigned int i;
@@ -287,7 +289,7 @@ static irqreturn_t vsc_sata_interrupt (int irq, void *dev_instance)
                                handled++;
                        } else
                                dev_printk(KERN_ERR, host->dev,
-                                       "interrupt from disabled port %d\n", i);
+                                       "interrupt from disabled port %d\n", i);
                }
        }
 
@@ -363,7 +365,8 @@ static void __devinit vsc_sata_setup_port(struct ata_ioports *port,
 }
 
 
-static int __devinit vsc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
+static int __devinit vsc_sata_init_one(struct pci_dev *pdev,
+                                      const struct pci_device_id *ent)
 {
        static const struct ata_port_info pi = {
                .flags          = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
index 5a6fe17..7d70496 100644 (file)
@@ -1,20 +1,20 @@
 /*
- *    Disk Array driver for HP SA 5xxx and 6xxx Controllers
- *    Copyright 2000, 2006 Hewlett-Packard Development Company, L.P.
+ *    Disk Array driver for HP Smart Array controllers.
+ *    (C) Copyright 2000, 2007 Hewlett-Packard Development Company, L.P.
  *
  *    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.
+ *    the Free Software Foundation; version 2 of the License.
  *
  *    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, GOOD TITLE or
- *    NON INFRINGEMENT.  See the GNU General Public License for more details.
+ *    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.
+ *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ *    02111-1307, USA.
  *
  *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *
index 4aca7dd..63ee6c0 100644 (file)
@@ -1,20 +1,20 @@
 /*
- *    Disk Array driver for Compaq SA53xx Controllers, SCSI Tape module
- *    Copyright 2001 Compaq Computer Corporation
+ *    Disk Array driver for HP Smart Array controllers, SCSI Tape module.
+ *    (C) Copyright 2001, 2007 Hewlett-Packard Development Company, L.P.
  *
  *    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.
+ *    the Free Software Foundation; version 2 of the License.
  *
  *    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, GOOD TITLE or
- *    NON INFRINGEMENT.  See the GNU General Public License for more details.
+ *    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.
+ *    Foundation, Inc., 59 Temple Place, Suite 300, Boston, MA
+ *    02111-1307, USA.
  *
  *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *    
index 5e7e06c..d9c2c58 100644 (file)
@@ -1,20 +1,20 @@
 /*
- *    Disk Array driver for Compaq SA53xx Controllers, SCSI Tape module
- *    Copyright 2001 Compaq Computer Corporation
+ *    Disk Array driver for HP Smart Array controllers, SCSI Tape module.
+ *    (C) Copyright 2001, 2007 Hewlett-Packard Development Company, L.P.
  *
  *    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.
+ *    the Free Software Foundation; version 2 of the License.
  *
  *    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, GOOD TITLE or
- *    NON INFRINGEMENT.  See the GNU General Public License for more details.
+ *    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.
+ *    Foundation, Inc., 59 Temple Place, Suite 300, Boston, MA
+ *    02111-1307, USA.
  *
  *    Questions/Comments/Bugfixes to iss_storagedev@hp.com
  *
index 1b58b01..2411678 100644 (file)
@@ -150,13 +150,8 @@ cryptoloop_transfer(struct loop_device *lo, int cmd,
                u32 iv[4] = { 0, };
                iv[0] = cpu_to_le32(IV & 0xffffffff);
 
-               sg_set_page(&sg_in, in_page);
-               sg_in.offset = in_offs;
-               sg_in.length = sz;
-
-               sg_set_page(&sg_out, out_page);
-               sg_out.offset = out_offs;
-               sg_out.length = sz;
+               sg_set_page(&sg_in, in_page, sz, in_offs);
+               sg_set_page(&sg_out, out_page, sz, out_offs);
 
                desc.info = iv;
                err = encdecfunc(&desc, &sg_out, &sg_in, sz);
index 7276f7d..fac4c6c 100644 (file)
@@ -15,6 +15,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/list.h>
+#include <linux/scatterlist.h>
 
 #include <asm/vio.h>
 #include <asm/ldc.h>
index 14143f2..08e909d 100644 (file)
@@ -1428,9 +1428,9 @@ static void ub_state_sense(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        scmd->state = UB_CMDST_INIT;
        scmd->nsg = 1;
        sg = &scmd->sgv[0];
-       sg_set_page(sg, virt_to_page(sc->top_sense));
-       sg->offset = (unsigned long)sc->top_sense & (PAGE_SIZE-1);
-       sg->length = UB_SENSE_SIZE;
+       sg_init_table(sg, UB_MAX_REQ_SG);
+       sg_set_page(sg, virt_to_page(sc->top_sense), UB_SENSE_SIZE,
+                       (unsigned long)sc->top_sense & (PAGE_SIZE-1));
        scmd->len = UB_SENSE_SIZE;
        scmd->lun = cmd->lun;
        scmd->done = ub_top_sense_done;
@@ -1864,9 +1864,8 @@ static int ub_sync_read_cap(struct ub_dev *sc, struct ub_lun *lun,
        cmd->state = UB_CMDST_INIT;
        cmd->nsg = 1;
        sg = &cmd->sgv[0];
-       sg_set_page(sg, virt_to_page(p));
-       sg->offset = (unsigned long)p & (PAGE_SIZE-1);
-       sg->length = 8;
+       sg_init_table(sg, UB_MAX_REQ_SG);
+       sg_set_page(sg, virt_to_page(p), 8, (unsigned long)p & (PAGE_SIZE-1));
        cmd->len = 8;
        cmd->lun = lun;
        cmd->done = ub_probe_done;
index a901eee..3cf7129 100644 (file)
@@ -4,7 +4,9 @@
 #include <linux/hdreg.h>
 #include <linux/virtio.h>
 #include <linux/virtio_blk.h>
-#include <linux/virtio_blk.h>
+#include <linux/scatterlist.h>
+
+#define VIRTIO_MAX_SG  (3+MAX_PHYS_SEGMENTS)
 
 static unsigned char virtblk_index = 'a';
 struct virtio_blk
@@ -23,7 +25,7 @@ struct virtio_blk
        mempool_t *pool;
 
        /* Scatterlist: can be too big for stack. */
-       struct scatterlist sg[3+MAX_PHYS_SEGMENTS];
+       struct scatterlist sg[VIRTIO_MAX_SG];
 };
 
 struct virtblk_req
@@ -94,8 +96,8 @@ static bool do_req(struct request_queue *q, struct virtio_blk *vblk,
        if (blk_barrier_rq(vbr->req))
                vbr->out_hdr.type |= VIRTIO_BLK_T_BARRIER;
 
-       /* We have to zero this, otherwise blk_rq_map_sg gets upset. */
-       memset(vblk->sg, 0, sizeof(vblk->sg));
+       /* This init could be done at vblk creation time */
+       sg_init_table(vblk->sg, VIRTIO_MAX_SG);
        sg_set_buf(&vblk->sg[0], &vbr->out_hdr, sizeof(vbr->out_hdr));
        num = blk_rq_map_sg(q, vbr->req, vblk->sg+1);
        sg_set_buf(&vblk->sg[num+1], &vbr->in_hdr, sizeof(vbr->in_hdr));
index 880b5dc..d8bb44b 100644 (file)
@@ -41,9 +41,9 @@
 #include <linux/completion.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
+#include <linux/scatterlist.h>
 
 #include <asm/vio.h>
-#include <asm/scatterlist.h>
 #include <asm/iseries/hv_types.h>
 #include <asm/iseries/hv_lp_event.h>
 #include <asm/iseries/vio.h>
@@ -258,6 +258,7 @@ static int send_request(struct request *req)
                cmd = viomajorsubtype_cdio | viocdwrite;
        }
 
+       sg_init_table(&sg, 1);
         if (blk_rq_map_sg(req->q, req, &sg) == 0) {
                printk(VIOCD_KERN_WARNING
                                "error setting up scatter/gather list\n");
index 0e937f6..20070b7 100644 (file)
@@ -41,7 +41,7 @@
  */
 static inline int uncached_access(struct file *file, unsigned long addr)
 {
-#if defined(__i386__)
+#if defined(__i386__) && !defined(__arch_um__)
        /*
         * On the PPro and successors, the MTRRs are used to set
         * memory types for physical addresses outside main memory,
@@ -57,7 +57,7 @@ static inline int uncached_access(struct file *file, unsigned long addr)
                  test_bit(X86_FEATURE_CYRIX_ARR, boot_cpu_data.x86_capability) ||
                  test_bit(X86_FEATURE_CENTAUR_MCR, boot_cpu_data.x86_capability) )
          && addr >= __pa(high_memory);
-#elif defined(__x86_64__)
+#elif defined(__x86_64__) && !defined(__arch_um__)
        /* 
         * This is broken because it can generate memory type aliases,
         * which can cause cache corruptions
index fdf4106..d2fabe7 100644 (file)
@@ -19,7 +19,6 @@
 #include "cpuidle.h"
 
 DEFINE_PER_CPU(struct cpuidle_device *, cpuidle_devices);
-EXPORT_PER_CPU_SYMBOL_GPL(cpuidle_devices);
 
 DEFINE_MUTEX(cpuidle_lock);
 LIST_HEAD(cpuidle_detected_devices);
index bb699cb..70b5964 100644 (file)
@@ -94,8 +94,6 @@ int cpuidle_register_governor(struct cpuidle_governor *gov)
        return ret;
 }
 
-EXPORT_SYMBOL_GPL(cpuidle_register_governor);
-
 /**
  * cpuidle_replace_governor - find a replacement governor
  * @exclude_rating: the rating that will be skipped while looking for
@@ -138,4 +136,3 @@ void cpuidle_unregister_governor(struct cpuidle_governor *gov)
        mutex_unlock(&cpuidle_lock);
 }
 
-EXPORT_SYMBOL_GPL(cpuidle_unregister_governor);
index 4e8de16..c666b4e 100644 (file)
@@ -55,7 +55,7 @@ static void padlock_sha_bypass(struct crypto_tfm *tfm)
        if (ctx(tfm)->data && ctx(tfm)->used) {
                struct scatterlist sg;
 
-               sg_set_buf(&sg, ctx(tfm)->data, ctx(tfm)->used);
+               sg_init_one(&sg, ctx(tfm)->data, ctx(tfm)->used);
                crypto_hash_update(&ctx(tfm)->fallback, &sg, sg.length);
        }
 
@@ -79,7 +79,7 @@ static void padlock_sha_update(struct crypto_tfm *tfm,
 
        if (unlikely(ctx(tfm)->bypass)) {
                struct scatterlist sg;
-               sg_set_buf(&sg, (uint8_t *)data, length);
+               sg_init_one(&sg, (uint8_t *)data, length);
                crypto_hash_update(&ctx(tfm)->fallback, &sg, length);
                return;
        }
index 410a0d1..93f71fc 100644 (file)
@@ -316,13 +316,13 @@ static int icside_dma_end(ide_drive_t *drive)
 
        drive->waiting_for_dma = 0;
 
-       disable_dma(state->dev->dma);
+       disable_dma(ECARD_DEV(state->dev)->dma);
 
        /* Teardown mappings after DMA has completed. */
        dma_unmap_sg(state->dev, hwif->sg_table, hwif->sg_nents,
                     hwif->sg_dma_direction);
 
-       return get_dma_residue(state->dev->dma) != 0;
+       return get_dma_residue(ECARD_DEV(state->dev)->dma) != 0;
 }
 
 static void icside_dma_start(ide_drive_t *drive)
@@ -331,8 +331,8 @@ static void icside_dma_start(ide_drive_t *drive)
        struct icside_state *state = hwif->hwif_data;
 
        /* We can not enable DMA on both channels simultaneously. */
-       BUG_ON(dma_channel_active(state->dev->dma));
-       enable_dma(state->dev->dma);
+       BUG_ON(dma_channel_active(ECARD_DEV(state->dev)->dma));
+       enable_dma(ECARD_DEV(state->dev)->dma);
 }
 
 static int icside_dma_setup(ide_drive_t *drive)
@@ -350,7 +350,7 @@ static int icside_dma_setup(ide_drive_t *drive)
        /*
         * We can not enable DMA on both channels.
         */
-       BUG_ON(dma_channel_active(state->dev->dma));
+       BUG_ON(dma_channel_active(ECARD_DEV(state->dev)->dma));
 
        icside_build_sglist(drive, rq);
 
@@ -367,14 +367,14 @@ static int icside_dma_setup(ide_drive_t *drive)
        /*
         * Select the correct timing for this drive.
         */
-       set_dma_speed(state->dev->dma, drive->drive_data);
+       set_dma_speed(ECARD_DEV(state->dev)->dma, drive->drive_data);
 
        /*
         * Tell the DMA engine about the SG table and
         * data direction.
         */
-       set_dma_sg(state->dev->dma, hwif->sg_table, hwif->sg_nents);
-       set_dma_mode(state->dev->dma, dma_mode);
+       set_dma_sg(ECARD_DEV(state->dev)->dma, hwif->sg_table, hwif->sg_nents);
+       set_dma_mode(ECARD_DEV(state->dev)->dma, dma_mode);
 
        drive->waiting_for_dma = 1;
 
index 9516883..dcda0f1 100644 (file)
@@ -582,9 +582,12 @@ EXPORT_SYMBOL_GPL(ide_in_drive_list);
 /*
  * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid.
  * We list them here and depend on the device side cable detection for them.
+ *
+ * Some optical devices with the buggy firmwares have the same problem.
  */
 static const struct drive_list_entry ivb_list[] = {
        { "QUANTUM FIREBALLlct10 05"    , "A03.0900"    },
+       { "TSSTcorp CDDVDW SH-S202J"    , "SB00"        },
        { NULL                          , NULL          }
 };
 
index 3ef4fc1..1cd4e9c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/cy82c693.c            Version 0.41    Aug 27, 2007
+ * linux/drivers/ide/pci/cy82c693.c            Version 0.42    Oct 23, 2007
  *
  *  Copyright (C) 1998-2000 Andreas S. Krebs (akrebs@altavista.net), Maintainer
  *  Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>, Integrator
@@ -436,10 +436,10 @@ static void __devinit init_hwif_cy82c693(ide_hwif_t *hwif)
        hwif->ide_dma_on = &cy82c693_ide_dma_on;
 }
 
-static __devinitdata ide_hwif_t *primary;
-
 static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
 {
+       static ide_hwif_t *primary;
+
        if (PCI_FUNC(hwif->pci_dev->devfn) == 1)
                primary = hwif;
        else {
index f44d708..0688569 100644 (file)
@@ -49,7 +49,7 @@ static int __init ide_generic_all_on(char *unused)
        printk(KERN_INFO "IDE generic will claim all unknown PCI IDE storage controllers.\n");
        return 1;
 }
-__setup("all-generic-ide", ide_generic_all_on);
+const __setup("all-generic-ide", ide_generic_all_on);
 #endif
 module_param_named(all_generic_ide, ide_generic_all, bool, 0444);
 MODULE_PARM_DESC(all_generic_ide, "IDE generic will claim all unknown PCI IDE storage controllers.");
index 612b795..5682895 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * linux/drivers/ide/pci/hpt366.c              Version 1.20    Oct 1, 2007
+ * linux/drivers/ide/pci/hpt366.c              Version 1.21    Oct 23, 2007
  *
  * Copyright (C) 1999-2003             Andre Hedrick <andre@linux-ide.org>
  * Portions Copyright (C) 2001         Sun Microsystems, Inc.
@@ -433,7 +433,7 @@ static u32 *hpt37x_settings[NUM_ATA_CLOCKS] = {
        sixty_six_base_hpt37x
 };
 
-static struct hpt_info hpt36x __devinitdata = {
+static const struct hpt_info hpt36x __devinitdata = {
        .chip_name      = "HPT36x",
        .chip_type      = HPT36x,
        .udma_mask      = HPT366_ALLOW_ATA66_3 ? (HPT366_ALLOW_ATA66_4 ? ATA_UDMA4 : ATA_UDMA3) : ATA_UDMA2,
@@ -441,7 +441,7 @@ static struct hpt_info hpt36x __devinitdata = {
        .settings       = hpt36x_settings
 };
 
-static struct hpt_info hpt370 __devinitdata = {
+static const struct hpt_info hpt370 __devinitdata = {
        .chip_name      = "HPT370",
        .chip_type      = HPT370,
        .udma_mask      = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
@@ -449,7 +449,7 @@ static struct hpt_info hpt370 __devinitdata = {
        .settings       = hpt37x_settings
 };
 
-static struct hpt_info hpt370a __devinitdata = {
+static const struct hpt_info hpt370a __devinitdata = {
        .chip_name      = "HPT370A",
        .chip_type      = HPT370A,
        .udma_mask      = HPT370_ALLOW_ATA100_5 ? ATA_UDMA5 : ATA_UDMA4,
@@ -457,7 +457,7 @@ static struct hpt_info hpt370a __devinitdata = {
        .settings       = hpt37x_settings
 };
 
-static struct hpt_info hpt374 __devinitdata = {
+static const struct hpt_info hpt374 __devinitdata = {
        .chip_name      = "HPT374",
        .chip_type      = HPT374,
        .udma_mask      = ATA_UDMA5,
@@ -465,7 +465,7 @@ static struct hpt_info hpt374 __devinitdata = {
        .settings       = hpt37x_settings
 };
 
-static struct hpt_info hpt372 __devinitdata = {
+static const struct hpt_info hpt372 __devinitdata = {
        .chip_name      = "HPT372",
        .chip_type      = HPT372,
        .udma_mask      = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -473,7 +473,7 @@ static struct hpt_info hpt372 __devinitdata = {
        .settings       = hpt37x_settings
 };
 
-static struct hpt_info hpt372a __devinitdata = {
+static const struct hpt_info hpt372a __devinitdata = {
        .chip_name      = "HPT372A",
        .chip_type      = HPT372A,
        .udma_mask      = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -481,7 +481,7 @@ static struct hpt_info hpt372a __devinitdata = {
        .settings       = hpt37x_settings
 };
 
-static struct hpt_info hpt302 __devinitdata = {
+static const struct hpt_info hpt302 __devinitdata = {
        .chip_name      = "HPT302",
        .chip_type      = HPT302,
        .udma_mask      = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -489,7 +489,7 @@ static struct hpt_info hpt302 __devinitdata = {
        .settings       = hpt37x_settings
 };
 
-static struct hpt_info hpt371 __devinitdata = {
+static const struct hpt_info hpt371 __devinitdata = {
        .chip_name      = "HPT371",
        .chip_type      = HPT371,
        .udma_mask      = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -497,7 +497,7 @@ static struct hpt_info hpt371 __devinitdata = {
        .settings       = hpt37x_settings
 };
 
-static struct hpt_info hpt372n __devinitdata = {
+static const struct hpt_info hpt372n __devinitdata = {
        .chip_name      = "HPT372N",
        .chip_type      = HPT372N,
        .udma_mask      = HPT372_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -505,7 +505,7 @@ static struct hpt_info hpt372n __devinitdata = {
        .settings       = hpt37x_settings
 };
 
-static struct hpt_info hpt302n __devinitdata = {
+static const struct hpt_info hpt302n __devinitdata = {
        .chip_name      = "HPT302N",
        .chip_type      = HPT302N,
        .udma_mask      = HPT302_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -513,7 +513,7 @@ static struct hpt_info hpt302n __devinitdata = {
        .settings       = hpt37x_settings
 };
 
-static struct hpt_info hpt371n __devinitdata = {
+static const struct hpt_info hpt371n __devinitdata = {
        .chip_name      = "HPT371N",
        .chip_type      = HPT371N,
        .udma_mask      = HPT371_ALLOW_ATA133_6 ? ATA_UDMA6 : ATA_UDMA5,
@@ -1508,7 +1508,7 @@ static const struct ide_port_info hpt366_chipsets[] __devinitdata = {
  */
 static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_device_id *id)
 {
-       struct hpt_info *info = NULL;
+       const struct hpt_info *info = NULL;
        struct pci_dev *dev2 = NULL;
        struct ide_port_info d;
        u8 idx = id->driver_data;
@@ -1522,7 +1522,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
                if (rev < 3)
                        info = &hpt36x;
                else {
-                       static struct hpt_info *hpt37x_info[] =
+                       static const struct hpt_info *hpt37x_info[] =
                                { &hpt370, &hpt370a, &hpt372, &hpt372n };
 
                        info = hpt37x_info[min_t(u8, rev, 6) - 3];
@@ -1552,7 +1552,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
        d.name = info->chip_name;
        d.udma_mask = info->udma_mask;
 
-       pci_set_drvdata(dev, info);
+       pci_set_drvdata(dev, (void *)info);
 
        if (info == &hpt36x || info == &hpt374)
                dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
@@ -1560,7 +1560,7 @@ static int __devinit hpt366_init_one(struct pci_dev *dev, const struct pci_devic
        if (dev2) {
                int ret;
 
-               pci_set_drvdata(dev2, info);
+               pci_set_drvdata(dev2, (void *)info);
 
                if (info == &hpt374)
                        hpt374_init(dev, dev2);
index d2c8b55..0a7b320 100644 (file)
@@ -324,17 +324,18 @@ static int sc1200_suspend (struct pci_dev *dev, pm_message_t state)
 
        pci_disable_device(dev);
        pci_set_power_state(dev, pci_choose_state(dev, state));
-       dev->current_state = state.event;
        return 0;
 }
 
 static int sc1200_resume (struct pci_dev *dev)
 {
        ide_hwif_t      *hwif = NULL;
+       int             i;
+
+       i = pci_enable_device(dev);
+       if (i)
+               return i;
 
-       pci_set_power_state(dev, PCI_D0);       // bring chip back from sleep state
-       dev->current_state = PM_EVENT_ON;
-       pci_enable_device(dev);
        //
        // loop over all interfaces that are part of this pci device:
        //
index 3051e31..f5f4983 100644 (file)
@@ -111,8 +111,8 @@ int dma_region_alloc(struct dma_region *dma, unsigned long n_bytes,
                unsigned long va =
                    (unsigned long)dma->kvirt + (i << PAGE_SHIFT);
 
-               sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va));
-               dma->sglist[i].length = PAGE_SIZE;
+               sg_set_page(&dma->sglist[i], vmalloc_to_page((void *)va),
+                               PAGE_SIZE, 0);
        }
 
        /* map sglist to the IOMMU */
index 14159ff..4e3128f 100644 (file)
@@ -171,9 +171,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
                                if (vma_list &&
                                    !is_vm_hugetlb_page(vma_list[i + off]))
                                        umem->hugetlb = 0;
-                               sg_set_page(&chunk->page_list[i], page_list[i + off]);
-                               chunk->page_list[i].offset = 0;
-                               chunk->page_list[i].length = PAGE_SIZE;
+                               sg_set_page(&chunk->page_list[i], page_list[i + off], PAGE_SIZE, 0);
                        }
 
                        chunk->nmap = ib_dma_map_sg(context->device,
index 007b381..1f4d27d 100644 (file)
@@ -113,9 +113,7 @@ static int mthca_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_m
        if (!page)
                return -ENOMEM;
 
-       sg_set_page(mem, page);
-       mem->length = PAGE_SIZE << order;
-       mem->offset = 0;
+       sg_set_page(mem, page, PAGE_SIZE << order, 0);
        return 0;
 }
 
@@ -481,9 +479,8 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
        if (ret < 0)
                goto out;
 
-       sg_set_page(&db_tab->page[i].mem, pages[0]);
-       db_tab->page[i].mem.length = MTHCA_ICM_PAGE_SIZE;
-       db_tab->page[i].mem.offset = uaddr & ~PAGE_MASK;
+       sg_set_page(&db_tab->page[i].mem, pages[0], MTHCA_ICM_PAGE_SIZE,
+                       uaddr & ~PAGE_MASK);
 
        ret = pci_map_sg(dev->pdev, &db_tab->page[i].mem, 1, PCI_DMA_TODEVICE);
        if (ret < 0) {
index 476012b..48c1775 100644 (file)
@@ -1843,6 +1843,7 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
        int msglen;
        u16 errcode;
        u16 datahandle;
+       u32 data;
 
        if (!card) {
                printk(KERN_ERR "capidrv: if_sendbuf called with invalid driverId %d!\n",
@@ -1860,9 +1861,26 @@ static int if_sendbuf(int id, int channel, int doack, struct sk_buff *skb)
                return 0;
        }
        datahandle = nccip->datahandle;
+
+       /*
+        * Here we copy pointer skb->data into the 32-bit 'Data' field.
+        * The 'Data' field is not used in practice in linux kernel
+        * (neither in 32 or 64 bit), but should have some value,
+        * since a CAPI message trace will display it.
+        *
+        * The correct value in the 32 bit case is the address of the
+        * data, in 64 bit it makes no sense, we use 0 there.
+        */
+
+#ifdef CONFIG_64BIT
+       data = 0;
+#else
+       data = (unsigned long) skb->data;
+#endif
+
        capi_fill_DATA_B3_REQ(&sendcmsg, global.ap.applid, card->msgid++,
                              nccip->ncci,      /* adr */
-                             (u32) skb->data,  /* Data */
+                             data,             /* Data */
                              skb->len,         /* DataLength */
                              datahandle,       /* DataHandle */
                              0 /* Flags */
@@ -2123,7 +2141,10 @@ static int capidrv_delcontr(u16 contr)
                printk(KERN_ERR "capidrv: delcontr: no contr %u\n", contr);
                return -1;
        }
-       #warning FIXME: maybe a race condition the card should be removed here from global list /kkeil
+
+       /* FIXME: maybe a race condition the card should be removed
+        * here from global list /kkeil
+        */
        spin_unlock_irqrestore(&global_lock, flags);
 
        del_timer(&card->listentimer);
index 034d41a..e0331e0 100644 (file)
@@ -28,15 +28,15 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n)
 {
        unsigned long flags;
        unsigned char ch;
+       unsigned long dest_rem = ((unsigned long) dest) % 0x4000;
 
-       if(!IS_VALID_CARD(card)) {
+       if (!IS_VALID_CARD(card)) {
                pr_debug("Invalid param: %d is not a valid card id\n", card);
                return;
        }
 
-       if(n > SRAM_PAGESIZE) {
+       if (n > SRAM_PAGESIZE)
                return;
-       }
 
        /*
         * determine the page to load from the address
@@ -50,8 +50,7 @@ void memcpy_toshmem(int card, void *dest, const void *src, size_t n)
 
        outb(((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE) >> 14) | 0x80,
                sc_adapter[card]->ioport[sc_adapter[card]->shmem_pgport]);
-       memcpy_toio(sc_adapter[card]->rambase +
-               ((unsigned long) dest % 0x4000), src, n);
+       memcpy_toio(sc_adapter[card]->rambase + dest_rem, src, n);
        spin_unlock_irqrestore(&sc_adapter[card]->lock, flags);
        pr_debug("%s: set page to %#x\n",sc_adapter[card]->devicename,
                ((sc_adapter[card]->shmem_magic + ch * SRAM_PAGESIZE)>>14)|0x80);
index 35d19ae..cb4c670 100644 (file)
@@ -128,9 +128,12 @@ static void unmap_switcher(void)
                __free_pages(switcher_page[i], 0);
 }
 
-/*L:305
+/*H:032
  * Dealing With Guest Memory.
  *
+ * Before we go too much further into the Host, we need to grok the routines
+ * we use to deal with Guest memory.
+ *
  * When the Guest gives us (what it thinks is) a physical address, we can use
  * the normal copy_from_user() & copy_to_user() on the corresponding place in
  * the memory region allocated by the Launcher.
index 9d5184c..b478aff 100644 (file)
@@ -90,6 +90,7 @@ static void do_hcall(struct lguest *lg, struct hcall_args *args)
                lg->pending_notify = args->arg1;
                break;
        default:
+               /* It should be an architecture-specific hypercall. */
                if (lguest_arch_do_hcall(lg, args))
                        kill_guest(lg, "Bad hypercall %li\n", args->arg0);
        }
@@ -157,7 +158,6 @@ static void do_async_hcalls(struct lguest *lg)
  * Guest makes a hypercall, we end up here to set things up: */
 static void initialize(struct lguest *lg)
 {
-
        /* You can't do anything until you're initialized.  The Guest knows the
         * rules, so we're unforgiving here. */
        if (lg->hcall->arg0 != LHCALL_LGUEST_INIT) {
@@ -174,7 +174,8 @@ static void initialize(struct lguest *lg)
            || get_user(lg->noirq_end, &lg->lguest_data->noirq_end))
                kill_guest(lg, "bad guest page %p", lg->lguest_data);
 
-       /* We write the current time into the Guest's data page once now. */
+       /* We write the current time into the Guest's data page once so it can
+        * set its clock. */
        write_timestamp(lg);
 
        /* page_tables.c will also do some setup. */
@@ -182,8 +183,8 @@ static void initialize(struct lguest *lg)
 
        /* This is the one case where the above accesses might have been the
         * first write to a Guest page.  This may have caused a copy-on-write
-        * fault, but the Guest might be referring to the old (read-only)
-        * page. */
+        * fault, but the old page might be (read-only) in the Guest
+        * pagetable. */
        guest_pagetable_clear_all(lg);
 }
 
@@ -220,7 +221,7 @@ void do_hypercalls(struct lguest *lg)
                 * Normally it doesn't matter: the Guest will run again and
                 * update the trap number before we come back here.
                 *
-                * However, if we are signalled or the Guest sends DMA to the
+                * 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. */
index 8296698..2b66f79 100644 (file)
@@ -92,8 +92,8 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
 
        /* Remember that we never let the Guest actually disable interrupts, so
         * the "Interrupt Flag" bit is always set.  We copy that bit from the
-        * Guest's "irq_enabled" field into the eflags word: the Guest copies
-        * it back in "lguest_iret". */
+        * Guest's "irq_enabled" field into the eflags word: we saw the Guest
+        * copy it back in "lguest_iret". */
        eflags = lg->regs->eflags;
        if (get_user(irq_enable, &lg->lguest_data->irq_enabled) == 0
            && !(irq_enable & X86_EFLAGS_IF))
@@ -124,7 +124,7 @@ static void set_guest_interrupt(struct lguest *lg, u32 lo, u32 hi, int has_err)
                        kill_guest(lg, "Disabling interrupts");
 }
 
-/*H:200
+/*H:205
  * Virtual Interrupts.
  *
  * maybe_do_interrupt() gets called before every entry to the Guest, to see if
@@ -256,19 +256,21 @@ int deliver_trap(struct lguest *lg, unsigned int num)
         * bogus one in): if we fail here, the Guest will be killed. */
        if (!idt_present(lg->arch.idt[num].a, lg->arch.idt[num].b))
                return 0;
-       set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b, has_err(num));
+       set_guest_interrupt(lg, lg->arch.idt[num].a, lg->arch.idt[num].b,
+                           has_err(num));
        return 1;
 }
 
 /*H:250 Here's the hard part: returning to the Host every time a trap happens
  * and then calling deliver_trap() and re-entering the Guest is slow.
- * Particularly because Guest userspace system calls are traps (trap 128).
+ * Particularly because Guest userspace system calls are traps (usually trap
+ * 128).
  *
  * So we'd like to set up the IDT to tell the CPU to deliver traps directly
  * into the Guest.  This is possible, but the complexities cause the size of
  * this file to double!  However, 150 lines of code is worth writing for taking
  * system calls down from 1750ns to 270ns.  Plus, if lguest didn't do it, all
- * the other hypervisors would tease it.
+ * the other hypervisors would beat it up at lunchtime.
  *
  * This routine indicates if a particular trap number could be delivered
  * directly. */
@@ -331,7 +333,7 @@ void pin_stack_pages(struct lguest *lg)
  * change stacks on each context switch. */
 void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages)
 {
-       /* You are not allowd have a stack segment with privilege level 0: bad
+       /* You are not allowed have a stack segment with privilege level 0: bad
         * Guest! */
        if ((seg & 0x3) != GUEST_PL)
                kill_guest(lg, "bad stack segment %i", seg);
@@ -350,7 +352,7 @@ void guest_set_stack(struct lguest *lg, u32 seg, u32 esp, unsigned int pages)
  * part of the Host: page table handling. */
 
 /*H:235 This is the routine which actually checks the Guest's IDT entry and
- * transfers it into our entry in "struct lguest": */
+ * transfers it into the entry in "struct lguest": */
 static void set_trap(struct lguest *lg, struct desc_struct *trap,
                     unsigned int num, u32 lo, u32 hi)
 {
@@ -456,6 +458,18 @@ void copy_traps(const struct lguest *lg, struct desc_struct *idt,
        }
 }
 
+/*H:200
+ * The Guest Clock.
+ *
+ * There are two sources of virtual interrupts.  We saw one in lguest_user.c:
+ * the Launcher sending interrupts for virtual devices.  The other is the Guest
+ * timer interrupt.
+ *
+ * The Guest uses the LHCALL_SET_CLOCKEVENT hypercall to tell us how long to
+ * the next timer interrupt (in nanoseconds).  We use the high-resolution timer
+ * infrastructure to set a callback at that time.
+ *
+ * 0 means "turn off the clock". */
 void guest_set_clockevent(struct lguest *lg, unsigned long delta)
 {
        ktime_t expires;
@@ -466,20 +480,27 @@ void guest_set_clockevent(struct lguest *lg, unsigned long delta)
                return;
        }
 
+       /* We use wallclock time here, so the Guest might not be running for
+        * all the time between now and the timer interrupt it asked for.  This
+        * is almost always the right thing to do. */
        expires = ktime_add_ns(ktime_get_real(), delta);
        hrtimer_start(&lg->hrt, expires, HRTIMER_MODE_ABS);
 }
 
+/* This is the function called when the Guest's timer expires. */
 static enum hrtimer_restart clockdev_fn(struct hrtimer *timer)
 {
        struct lguest *lg = container_of(timer, struct lguest, hrt);
 
+       /* Remember the first interrupt is the timer interrupt. */
        set_bit(0, lg->irqs_pending);
+       /* If the Guest is actually stopped, we need to wake it up. */
        if (lg->halted)
                wake_up_process(lg->tsk);
        return HRTIMER_NORESTART;
 }
 
+/* This sets up the timer for this Guest. */
 void init_clockdev(struct lguest *lg)
 {
        hrtimer_init(&lg->hrt, CLOCK_REALTIME, HRTIMER_MODE_ABS);
index d9144be..8692489 100644 (file)
@@ -74,9 +74,6 @@ struct lguest
        u32 pgdidx;
        struct pgdir pgdirs[4];
 
-       /* Cached wakeup: we hold a reference to this task. */
-       struct task_struct *wake;
-
        unsigned long noirq_start, noirq_end;
        unsigned long pending_notify; /* pfn from LHCALL_NOTIFY */
 
@@ -103,7 +100,7 @@ int lguest_address_ok(const struct lguest *lg,
 void __lgread(struct lguest *, void *, unsigned long, unsigned);
 void __lgwrite(struct lguest *, unsigned long, const void *, unsigned);
 
-/*L:306 Using memory-copy operations like that is usually inconvient, so we
+/*H:035 Using memory-copy operations like that is usually inconvient, so we
  * have the following helper macros which read and write a specific type (often
  * an unsigned long).
  *
@@ -191,7 +188,7 @@ void write_timestamp(struct lguest *lg);
  * Let's step aside for the moment, to study one important routine that's used
  * widely in the Host code.
  *
- * There are many cases where the Guest does something invalid, like pass crap
+ * There are many cases where the Guest can do something invalid, like pass crap
  * to a hypercall.  Since only the Guest kernel can make hypercalls, it's quite
  * acceptable to simply terminate the Guest and give the Launcher a nicely
  * formatted reason.  It's also simpler for the Guest itself, which doesn't
index 71c6483..8904f72 100644 (file)
@@ -53,7 +53,8 @@ struct lguest_device {
  * Device configurations
  *
  * The configuration information for a device consists of a series of fields.
- * The device will look for these fields during setup.
+ * We don't really care what they are: the Launcher set them up, and the driver
+ * will look at them during setup.
  *
  * For us these fields come immediately after that device's descriptor in the
  * lguest_devices page.
@@ -122,8 +123,8 @@ static void lg_set_status(struct virtio_device *vdev, u8 status)
  * The other piece of infrastructure virtio needs is a "virtqueue": a way of
  * the Guest device registering buffers for the other side to read from or
  * write into (ie. send and receive buffers).  Each device can have multiple
- * virtqueues: for example the console has one queue for sending and one for
- * receiving.
+ * virtqueues: for example the console driver uses one queue for sending and
+ * another for receiving.
  *
  * Fortunately for us, a very fast shared-memory-plus-descriptors virtqueue
  * already exists in virtio_ring.c.  We just need to connect it up.
@@ -158,7 +159,7 @@ static void lg_notify(struct virtqueue *vq)
  *
  * This is kind of an ugly duckling.  It'd be nicer to have a standard
  * representation of a virtqueue in the configuration space, but it seems that
- * everyone wants to do it differently.  The KVM guys want the Guest to
+ * everyone wants to do it differently.  The KVM coders want the Guest to
  * 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.
  *
@@ -284,6 +285,8 @@ static void add_lguest_device(struct lguest_device_desc *d)
 {
        struct lguest_device *ldev;
 
+       /* Start with zeroed memory; Linux's device layer seems to count on
+        * it. */
        ldev = kzalloc(sizeof(*ldev), GFP_KERNEL);
        if (!ldev) {
                printk(KERN_EMERG "Cannot allocate lguest dev %u\n",
index ee405b3..9d716fa 100644 (file)
@@ -8,20 +8,22 @@
 #include <linux/fs.h>
 #include "lg.h"
 
-/*L:315 To force the Guest to stop running and return to the Launcher, the
- * Waker sets writes LHREQ_BREAK and the value "1" to /dev/lguest.  The
- * Launcher then writes LHREQ_BREAK and "0" to release the Waker. */
+/*L:055 When something happens, the Waker process needs a way to stop the
+ * kernel running the Guest and return to the Launcher.  So the Waker writes
+ * LHREQ_BREAK and the value "1" to /dev/lguest to do this.  Once the Launcher
+ * has done whatever needs attention, it writes LHREQ_BREAK and "0" to release
+ * the Waker. */
 static int break_guest_out(struct lguest *lg, const unsigned long __user *input)
 {
        unsigned long on;
 
-       /* Fetch whether they're turning break on or off.. */
+       /* Fetch whether they're turning break on or off. */
        if (get_user(on, input) != 0)
                return -EFAULT;
 
        if (on) {
                lg->break_out = 1;
-               /* Pop it out (may be running on different CPU) */
+               /* Pop it out of the Guest (may be running on different CPU) */
                wake_up_process(lg->tsk);
                /* Wait for them to reset it */
                return wait_event_interruptible(lg->break_wq, !lg->break_out);
@@ -58,7 +60,7 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
        if (!lg)
                return -EINVAL;
 
-       /* If you're not the task which owns the guest, go away. */
+       /* If you're not the task which owns the Guest, go away. */
        if (current != lg->tsk)
                return -EPERM;
 
@@ -92,8 +94,8 @@ static ssize_t read(struct file *file, char __user *user, size_t size,loff_t*o)
  * base: The start of the Guest-physical memory inside the Launcher memory.
  *
  * pfnlimit: The highest (Guest-physical) page number the Guest should be
- * allowed to access.  The Launcher has to live in Guest memory, so it sets
- * this to ensure the Guest can't reach it.
+ * allowed to access.  The Guest memory lives inside the Launcher, so it sets
+ * this to ensure the Guest can only reach its own memory.
  *
  * pgdir: The (Guest-physical) address of the top of the initial Guest
  * pagetables (which are set up by the Launcher).
@@ -189,7 +191,7 @@ unlock:
 }
 
 /*L:010 The first operation the Launcher does must be a write.  All writes
- * start with a 32 bit number: for the first write this must be
+ * 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. */
 static ssize_t write(struct file *file, const char __user *in,
@@ -275,8 +277,7 @@ static int close(struct inode *inode, struct file *file)
  * The Launcher is the Host userspace program which sets up, runs and services
  * the Guest.  In fact, many comments in the Drivers which refer to "the Host"
  * doing things are inaccurate: the Launcher does all the device handling for
- * the Guest.  The Guest can't tell what's done by the the Launcher and what by
- * the Host.
+ * the Guest, but the Guest can't know that.
  *
  * Just to confuse you: to the Host kernel, the Launcher *is* the Guest and we
  * shall see more of that later.
index 2a45f06..fffabb3 100644 (file)
@@ -26,7 +26,8 @@
  *
  * We use two-level page tables for the Guest.  If you're not entirely
  * comfortable with virtual addresses, physical addresses and page tables then
- * I recommend you review lguest.c's "Page Table Handling" (with diagrams!).
+ * I recommend you review arch/x86/lguest/boot.c's "Page Table Handling" (with
+ * diagrams!).
  *
  * The Guest keeps page tables, but we maintain the actual ones here: these are
  * called "shadow" page tables.  Which is a very Guest-centric name: these are
  *
  * Anyway, this is the most complicated part of the Host code.  There are seven
  * parts to this:
- *  (i) Setting up a page table entry for the Guest when it faults,
- *  (ii) Setting up the page table entry for the Guest stack,
- *  (iii) Setting up a page table entry when the Guest tells us it has changed,
+ *  (i) Looking up a page table entry when the Guest faults,
+ *  (ii) Making sure the Guest stack is mapped,
+ *  (iii) Setting up a page table entry when the Guest tells us one has changed,
  *  (iv) Switching page tables,
- *  (v) Flushing (thowing away) page tables,
+ *  (v) Flushing (throwing away) page tables,
  *  (vi) Mapping the Switcher when the Guest is about to run,
  *  (vii) Setting up the page tables initially.
  :*/
 static DEFINE_PER_CPU(pte_t *, switcher_pte_pages);
 #define switcher_pte_page(cpu) per_cpu(switcher_pte_pages, cpu)
 
-/*H:320 With our shadow and Guest types established, we need to deal with
- * them: the page table code is curly enough to need helper functions to keep
- * it clear and clean.
+/*H:320 The page table code is curly enough to need helper functions to keep it
+ * clear and clean.
  *
  * There are two functions which return pointers to the shadow (aka "real")
  * page tables.
  *
  * spgd_addr() takes the virtual address and returns a pointer to the top-level
- * page directory entry for that address.  Since we keep track of several page
- * tables, the "i" argument tells us which one we're interested in (it's
+ * page directory entry (PGD) for that address.  Since we keep track of several
+ * page tables, the "i" argument tells us which one we're interested in (it's
  * usually the current one). */
 static pgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr)
 {
@@ -81,9 +81,9 @@ static pgd_t *spgd_addr(struct lguest *lg, u32 i, unsigned long vaddr)
        return &lg->pgdirs[i].pgdir[index];
 }
 
-/* This routine then takes the PGD entry given above, which contains the
- * address of the PTE page.  It then returns a pointer to the PTE entry for the
- * given address. */
+/* This routine then takes the page directory entry returned above, which
+ * contains the address of the page table entry (PTE) page.  It then returns a
+ * pointer to the PTE entry for the given address. */
 static pte_t *spte_addr(struct lguest *lg, pgd_t spgd, unsigned long vaddr)
 {
        pte_t *page = __va(pgd_pfn(spgd) << PAGE_SHIFT);
@@ -191,7 +191,7 @@ static void check_gpgd(struct lguest *lg, pgd_t gpgd)
 }
 
 /*H:330
- * (i) Setting up a page table entry for the Guest when it faults
+ * (i) Looking up a page table entry when the Guest faults.
  *
  * We saw this call in run_guest(): when we see a page fault in the Guest, we
  * come here.  That's because we only set up the shadow page tables lazily as
@@ -199,7 +199,7 @@ static void check_gpgd(struct lguest *lg, pgd_t gpgd)
  * and return to the Guest without it knowing.
  *
  * If we fixed up the fault (ie. we mapped the address), this routine returns
- * true. */
+ * true.  Otherwise, it was a real fault and we need to tell the Guest. */
 int demand_page(struct lguest *lg, unsigned long vaddr, int errcode)
 {
        pgd_t gpgd;
@@ -246,16 +246,16 @@ int demand_page(struct lguest *lg, unsigned long vaddr, int errcode)
        if ((errcode & 2) && !(pte_flags(gpte) & _PAGE_RW))
                return 0;
 
-       /* User access to a kernel page? (bit 3 == user access) */
+       /* User access to a kernel-only page? (bit 3 == user access) */
        if ((errcode & 4) && !(pte_flags(gpte) & _PAGE_USER))
                return 0;
 
        /* Check that the Guest PTE flags are OK, and the page number is below
         * the pfn_limit (ie. not mapping the Launcher binary). */
        check_gpte(lg, gpte);
+
        /* Add the _PAGE_ACCESSED and (for a write) _PAGE_DIRTY flag */
        gpte = pte_mkyoung(gpte);
-
        if (errcode & 2)
                gpte = pte_mkdirty(gpte);
 
@@ -272,23 +272,28 @@ int demand_page(struct lguest *lg, unsigned long vaddr, int errcode)
        else
                /* If this is a read, don't set the "writable" bit in the page
                 * table entry, even if the Guest says it's writable.  That way
-                * we come back here when a write does actually ocur, so we can
-                * update the Guest's _PAGE_DIRTY flag. */
+                * we will come back here when a write does actually occur, so
+                * we can update the Guest's _PAGE_DIRTY flag. */
                *spte = gpte_to_spte(lg, pte_wrprotect(gpte), 0);
 
        /* Finally, we write the Guest PTE entry back: we've set the
         * _PAGE_ACCESSED and maybe the _PAGE_DIRTY flags. */
        lgwrite(lg, gpte_ptr, pte_t, gpte);
 
-       /* We succeeded in mapping the page! */
+       /* The fault is fixed, the page table is populated, the mapping
+        * manipulated, the result returned and the code complete.  A small
+        * delay and a trace of alliteration are the only indications the Guest
+        * has that a page fault occurred at all. */
        return 1;
 }
 
-/*H:360 (ii) Setting up the page table entry for the Guest stack.
+/*H:360
+ * (ii) Making sure the Guest stack is mapped.
  *
- * Remember pin_stack_pages() which makes sure the stack is mapped?  It could
- * simply call demand_page(), but as we've seen that logic is quite long, and
- * usually the stack pages are already mapped anyway, so it's not required.
+ * Remember that direct traps into the Guest need a mapped Guest kernel stack.
+ * pin_stack_pages() calls us here: we could simply call demand_page(), but as
+ * we've seen that logic is quite long, and usually the stack pages are already
+ * mapped, so it's overkill.
  *
  * This is a quick version which answers the question: is this virtual address
  * mapped by the shadow page tables, and is it writable? */
@@ -297,7 +302,7 @@ static int page_writable(struct lguest *lg, unsigned long vaddr)
        pgd_t *spgd;
        unsigned long flags;
 
-       /* Look at the top level entry: is it present? */
+       /* Look at the current top level entry: is it present? */
        spgd = spgd_addr(lg, lg->pgdidx, vaddr);
        if (!(pgd_flags(*spgd) & _PAGE_PRESENT))
                return 0;
@@ -333,15 +338,14 @@ static void release_pgd(struct lguest *lg, pgd_t *spgd)
                        release_pte(ptepage[i]);
                /* Now we can free the page of PTEs */
                free_page((long)ptepage);
-               /* And zero out the PGD entry we we never release it twice. */
+               /* And zero out the PGD entry so we never release it twice. */
                *spgd = __pgd(0);
        }
 }
 
-/*H:440 (v) Flushing (thowing away) page tables,
- *
- * We saw flush_user_mappings() called when we re-used a top-level pgdir page.
- * It simply releases every PTE page from 0 up to the kernel address. */
+/*H:445 We saw flush_user_mappings() twice: once from the flush_user_mappings()
+ * hypercall and once in new_pgdir() when we re-used a top-level pgdir page.
+ * It simply releases every PTE page from 0 up to the Guest's kernel address. */
 static void flush_user_mappings(struct lguest *lg, int idx)
 {
        unsigned int i;
@@ -350,8 +354,10 @@ static void flush_user_mappings(struct lguest *lg, int idx)
                release_pgd(lg, lg->pgdirs[idx].pgdir + i);
 }
 
-/* The Guest also has a hypercall to do this manually: it's used when a large
- * number of mappings have been changed. */
+/*H:440 (v) Flushing (throwing away) page tables,
+ *
+ * The Guest has a hypercall to throw away the page tables: it's used when a
+ * large number of mappings have been changed. */
 void guest_pagetable_flush_user(struct lguest *lg)
 {
        /* Drop the userspace part of the current page table. */
@@ -423,8 +429,9 @@ static unsigned int new_pgdir(struct lguest *lg,
 
 /*H:430 (iv) Switching page tables
  *
- * This is what happens when the Guest changes page tables (ie. changes the
- * top-level pgdir).  This happens on almost every context switch. */
+ * Now we've seen all the page table setting and manipulation, let's see what
+ * what happens when the Guest changes page tables (ie. changes the top-level
+ * pgdir).  This occurs on almost every context switch. */
 void guest_new_pagetable(struct lguest *lg, unsigned long pgtable)
 {
        int newpgdir, repin = 0;
@@ -443,7 +450,8 @@ void guest_new_pagetable(struct lguest *lg, unsigned long pgtable)
 }
 
 /*H:470 Finally, a routine which throws away everything: all PGD entries in all
- * the shadow page tables.  This is used when we destroy the Guest. */
+ * the shadow page tables, including the Guest's kernel mappings.  This is used
+ * when we destroy the Guest. */
 static void release_all_pagetables(struct lguest *lg)
 {
        unsigned int i, j;
@@ -458,13 +466,22 @@ static void release_all_pagetables(struct lguest *lg)
 
 /* We also throw away everything when a Guest tells us it's changed a kernel
  * mapping.  Since kernel mappings are in every page table, it's easiest to
- * throw them all away.  This is amazingly slow, but thankfully rare. */
+ * throw them all away.  This traps the Guest in amber for a while as
+ * everything faults back in, but it's rare. */
 void guest_pagetable_clear_all(struct lguest *lg)
 {
        release_all_pagetables(lg);
        /* We need the Guest kernel stack mapped again. */
        pin_stack_pages(lg);
 }
+/*:*/
+/*M:009 Since we throw away all mappings when a kernel mapping changes, our
+ * performance sucks for guests using highmem.  In fact, a guest with
+ * PAGE_OFFSET 0xc0000000 (the default) and more than about 700MB of RAM is
+ * usually slower than a Guest with less memory.
+ *
+ * This, of course, cannot be fixed.  It would take some kind of... well, I
+ * don't know, but the term "puissant code-fu" comes to mind. :*/
 
 /*H:420 This is the routine which actually sets the page table entry for then
  * "idx"'th shadow page table.
@@ -483,7 +500,7 @@ void guest_pagetable_clear_all(struct lguest *lg)
 static void do_set_pte(struct lguest *lg, int idx,
                       unsigned long vaddr, pte_t gpte)
 {
-       /* Look up the matching shadow page directot entry. */
+       /* Look up the matching shadow page directory entry. */
        pgd_t *spgd = spgd_addr(lg, idx, vaddr);
 
        /* If the top level isn't present, there's no entry to update. */
@@ -500,7 +517,8 @@ static void do_set_pte(struct lguest *lg, int idx,
                        *spte = gpte_to_spte(lg, gpte,
                                             pte_flags(gpte) & _PAGE_DIRTY);
                } else
-                       /* Otherwise we can demand_page() it in later. */
+                       /* Otherwise kill it and we can demand_page() it in
+                        * later. */
                        *spte = __pte(0);
        }
 }
@@ -535,7 +553,7 @@ void guest_set_pte(struct lguest *lg,
 }
 
 /*H:400
- * (iii) Setting up a page table entry when the Guest tells us it has changed.
+ * (iii) Setting up a page table entry when the Guest tells us one has changed.
  *
  * Just like we did in interrupts_and_traps.c, it makes sense for us to deal
  * with the other side of page tables while we're here: what happens when the
@@ -612,9 +630,10 @@ void free_guest_pagetable(struct lguest *lg)
 
 /*H:480 (vi) Mapping the Switcher when the Guest is about to run.
  *
- * The Switcher and the two pages for this CPU need to be available to the
+ * The Switcher and the two pages for this CPU need to be visible in the
  * Guest (and not the pages for other CPUs).  We have the appropriate PTE pages
- * for each CPU already set up, we just need to hook them in. */
+ * for each CPU already set up, we just need to hook them in now we know which
+ * Guest is about to run on this CPU. */
 void map_switcher_in_guest(struct lguest *lg, struct lguest_pages *pages)
 {
        pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages);
@@ -677,6 +696,18 @@ static __init void populate_switcher_pte_page(unsigned int cpu,
                           __pgprot(_PAGE_PRESENT|_PAGE_ACCESSED));
 }
 
+/* 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.
+ *
+ * There is just one file remaining in the Host. */
+
 /*H:510 At boot or module load time, init_pagetables() allocates and populates
  * the Switcher PTE page for each CPU. */
 __init int init_pagetables(struct page **switcher_page, unsigned int pages)
index c2434ec..9e189cb 100644 (file)
@@ -12,8 +12,6 @@
 #include "lg.h"
 
 /*H:600
- * We've almost completed the Host; there's just one file to go!
- *
  * Segments & The Global Descriptor Table
  *
  * (That title sounds like a bad Nerdcore group.  Not to suggest that there are
@@ -55,7 +53,7 @@ static int ignored_gdt(unsigned int num)
                || num == GDT_ENTRY_DOUBLEFAULT_TSS);
 }
 
-/*H:610 Once the GDT has been changed, we fix the new entries up a little.  We
+/*H:630 Once the Guest gave us new GDT entries, we fix them up a little.  We
  * don't care if they're invalid: the worst that can happen is a General
  * Protection Fault in the Switcher when it restores a Guest segment register
  * which tries to use that entry.  Then we kill the Guest for causing such a
@@ -84,25 +82,33 @@ static void fixup_gdt_table(struct lguest *lg, unsigned start, unsigned end)
        }
 }
 
-/* This routine is called at boot or modprobe time for each CPU to set up the
- * "constant" GDT entries for Guests running on that CPU. */
+/*H:610 Like the IDT, we never simply use the GDT the Guest gives us.  We keep
+ * a GDT for each CPU, and copy across the Guest's entries each time we want to
+ * run the Guest on that CPU.
+ *
+ * This routine is called at boot or modprobe time for each CPU to set up the
+ * constant GDT entries: the ones which are the same no matter what Guest we're
+ * running. */
 void setup_default_gdt_entries(struct lguest_ro_state *state)
 {
        struct desc_struct *gdt = state->guest_gdt;
        unsigned long tss = (unsigned long)&state->guest_tss;
 
-       /* The hypervisor segments are full 0-4G segments, privilege level 0 */
+       /* The Switcher segments are full 0-4G segments, privilege level 0 */
        gdt[GDT_ENTRY_LGUEST_CS] = FULL_EXEC_SEGMENT;
        gdt[GDT_ENTRY_LGUEST_DS] = FULL_SEGMENT;
 
-       /* The TSS segment refers to the TSS entry for this CPU, so we cannot
-        * copy it from the Guest.  Forgive the magic flags */
+       /* The TSS segment refers to the TSS entry for this particular CPU.
+        * Forgive the magic flags: the 0x8900 means the entry is Present, it's
+        * privilege level 0 Available 386 TSS system segment, and the 0x67
+        * means Saturn is eclipsed by Mercury in the twelfth house. */
        gdt[GDT_ENTRY_TSS].a = 0x00000067 | (tss << 16);
        gdt[GDT_ENTRY_TSS].b = 0x00008900 | (tss & 0xFF000000)
                | ((tss >> 16) & 0x000000FF);
 }
 
-/* This routine is called before the Guest is run for the first time. */
+/* This routine sets up the initial Guest GDT for booting.  All entries start
+ * as 0 (unusable). */
 void setup_guest_gdt(struct lguest *lg)
 {
        /* Start with full 0-4G segments... */
@@ -114,13 +120,8 @@ void setup_guest_gdt(struct lguest *lg)
        lg->arch.gdt[GDT_ENTRY_KERNEL_DS].b |= (GUEST_PL << 13);
 }
 
-/* Like the IDT, we never simply use the GDT the Guest gives us.  We set up the
- * GDTs for each CPU, then we copy across the entries each time we want to run
- * a different Guest on that CPU. */
-
-/* A partial GDT load, for the three "thead-local storage" entries.  Otherwise
- * it's just like load_guest_gdt().  So much, in fact, it would probably be
- * neater to have a single hypercall to cover both. */
+/*H:650 An optimization of copy_gdt(), for just the three "thead-local storage"
+ * entries. */
 void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt)
 {
        unsigned int i;
@@ -129,7 +130,9 @@ void copy_gdt_tls(const struct lguest *lg, struct desc_struct *gdt)
                gdt[i] = lg->arch.gdt[i];
 }
 
-/* This is the full version */
+/*H:640 When the Guest is run on a different CPU, or the GDT entries have
+ * changed, copy_gdt() is called to copy the Guest's GDT entries across to this
+ * CPU's GDT. */
 void copy_gdt(const struct lguest *lg, struct desc_struct *gdt)
 {
        unsigned int i;
@@ -141,7 +144,8 @@ void copy_gdt(const struct lguest *lg, struct desc_struct *gdt)
                        gdt[i] = lg->arch.gdt[i];
 }
 
-/* This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT). */
+/*H:620 This is where the Guest asks us to load a new GDT (LHCALL_LOAD_GDT).
+ * We copy it from the Guest and tweak the entries. */
 void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num)
 {
        /* We assume the Guest has the same number of GDT entries as the
@@ -157,16 +161,22 @@ void load_guest_gdt(struct lguest *lg, unsigned long table, u32 num)
        lg->changed |= CHANGED_GDT;
 }
 
+/* This is the fast-track version for just changing the three TLS entries.
+ * Remember that this happens on every context switch, so it's worth
+ * optimizing.  But wouldn't it be neater to have a single hypercall to cover
+ * both cases? */
 void guest_load_tls(struct lguest *lg, unsigned long gtls)
 {
        struct desc_struct *tls = &lg->arch.gdt[GDT_ENTRY_TLS_MIN];
 
        __lgread(lg, tls, gtls, sizeof(*tls)*GDT_ENTRY_TLS_ENTRIES);
        fixup_gdt_table(lg, GDT_ENTRY_TLS_MIN, GDT_ENTRY_TLS_MAX+1);
+       /* Note that just the TLS entries have changed. */
        lg->changed |= CHANGED_GDT_TLS;
 }
+/*:*/
 
-/*
+/*H:660
  * With this, we have finished the Host.
  *
  * Five of the seven parts of our task are complete.  You have made it through
index 9eed12d..482aec2 100644 (file)
@@ -63,7 +63,7 @@ static struct lguest_pages *lguest_pages(unsigned int cpu)
 static DEFINE_PER_CPU(struct lguest *, last_guest);
 
 /*S:010
- * We are getting close to the Switcher.
+ * We approach the Switcher.
  *
  * Remember that each CPU has two pages which are visible to the Guest when it
  * runs on that CPU.  This has to contain the state for that Guest: we copy the
@@ -134,7 +134,7 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages)
         *
         * The lcall also pushes the old code segment (KERNEL_CS) onto the
         * stack, then the address of this call.  This stack layout happens to
-        * exactly match the stack of an interrupt... */
+        * exactly match the stack layout created by an interrupt... */
        asm volatile("pushf; lcall *lguest_entry"
                     /* This is how we tell GCC that %eax ("a") and %ebx ("b")
                      * are changed by this routine.  The "=" means output. */
@@ -151,40 +151,46 @@ static void run_guest_once(struct lguest *lg, struct lguest_pages *pages)
 }
 /*:*/
 
+/*M:002 There are hooks in the scheduler which we can register to tell when we
+ * get kicked off the CPU (preempt_notifier_register()).  This would allow us
+ * to lazily disable SYSENTER which would regain some performance, and should
+ * 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.
+ *
+ * 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
  * are disabled: we own the CPU. */
 void lguest_arch_run_guest(struct lguest *lg)
 {
-       /* Remember the awfully-named TS bit?  If the Guest has asked
-        * to set it we set it now, so we can trap and pass that trap
-        * to the Guest if it uses the FPU. */
+       /* Remember the awfully-named TS bit?  If the Guest has asked to set it
+        * we set it now, so we can trap and pass that trap to the Guest if it
+        * uses the FPU. */
        if (lg->ts)
                lguest_set_ts();
 
-       /* SYSENTER is an optimized way of doing system calls.  We
-        * can't allow it because it always jumps to privilege level 0.
-        * A normal Guest won't try it because we don't advertise it in
-        * CPUID, but a malicious Guest (or malicious Guest userspace
-        * program) could, so we tell the CPU to disable it before
-        * running the Guest. */
+       /* SYSENTER is an optimized way of doing system calls.  We can't allow
+        * it because it always jumps to privilege level 0.  A normal Guest
+        * won't try it because we don't advertise it in CPUID, but a malicious
+        * Guest (or malicious Guest userspace program) could, so we tell the
+        * CPU to disable it before running the Guest. */
        if (boot_cpu_has(X86_FEATURE_SEP))
                wrmsr(MSR_IA32_SYSENTER_CS, 0, 0);
 
-       /* Now we actually run the Guest.  It will pop back out when
-        * something interesting happens, and we can examine its
-        * registers to see what it was doing. */
+       /* Now we actually run the Guest.  It will return when something
+        * interesting happens, and we can examine its registers to see what it
+        * was doing. */
        run_guest_once(lg, lguest_pages(raw_smp_processor_id()));
 
-       /* The "regs" pointer 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.  */
+       /* Note that the "regs" pointer 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.  */
 
-       /* If the Guest page faulted, then the cr2 register will tell
-        * us the bad virtual address.  We have to grab this now,
-        * because once we re-enable interrupts an interrupt could
-        * fault and thus overwrite cr2, or we could even move off to a
-        * different CPU. */
+       /* If the Guest page faulted, then the cr2 register will tell us the
+        * bad virtual address.  We have to grab this now, because once we
+        * re-enable interrupts an interrupt could fault and thus overwrite
+        * cr2, or we could even move off to a different CPU. */
        if (lg->regs->trapnum == 14)
                lg->arch.last_pagefault = read_cr2();
        /* Similarly, if we took a trap because the Guest used the FPU,
@@ -197,14 +203,15 @@ void lguest_arch_run_guest(struct lguest *lg)
                wrmsr(MSR_IA32_SYSENTER_CS, __KERNEL_CS, 0);
 }
 
-/*H:130 Our Guest is usually so well behaved; it never tries to do things it
- * isn't allowed to.  Unfortunately, Linux's paravirtual infrastructure isn't
- * quite complete, because it doesn't contain replacements for the Intel I/O
- * instructions.  As a result, the Guest sometimes fumbles across one during
- * the boot process as it probes for various things which are usually attached
- * to a PC.
+/*H:130 Now we've examined the hypercall code; our Guest can make requests.
+ * Our Guest is usually so well behaved; it never tries to do things it isn't
+ * allowed to, and uses hypercalls instead.  Unfortunately, Linux's paravirtual
+ * infrastructure isn't quite complete, because it doesn't contain replacements
+ * for the Intel I/O instructions.  As a result, the Guest sometimes fumbles
+ * across one during the boot process as it probes for various things which are
+ * usually attached to a PC.
  *
- * When the Guest uses one of these instructions, we get trap #13 (General
+ * When the Guest uses one of these instructions, we get a trap (General
  * Protection Fault) and come here.  We see if it's one of those troublesome
  * instructions and skip over it.  We return true if we did. */
 static int emulate_insn(struct lguest *lg)
@@ -275,43 +282,43 @@ static int emulate_insn(struct lguest *lg)
 void lguest_arch_handle_trap(struct lguest *lg)
 {
        switch (lg->regs->trapnum) {
-       case 13: /* We've intercepted a GPF. */
-                /* Check if this was one of those annoying IN or OUT
-                 * instructions which we need to emulate.  If so, we
-                 * just go back into the Guest after we've done it. */
+       case 13: /* We've intercepted a General Protection Fault. */
+               /* Check if this was one of those annoying IN or OUT
+                * instructions which we need to emulate.  If so, we just go
+                * back into the Guest after we've done it. */
                if (lg->regs->errcode == 0) {
                        if (emulate_insn(lg))
                                return;
                }
                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.
-                 *
-                 * The errcode tells whether this was a read or a
-                 * write, and whether kernel or userspace code. */
+       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.
+                *
+                * The errcode tells whether this was a read or a write, and
+                * whether kernel or userspace code. */
                if (demand_page(lg, lg->arch.last_pagefault, lg->regs->errcode))
                        return;
 
-                /* OK, it's really not there (or not OK): the Guest
-                 * needs to know.  We write out the cr2 value so it
-                 * knows where the fault occurred.
-                 *
-                 * Note that if the Guest were really messed up, this
-                 * could happen before it's done the INITIALIZE
-                 * hypercall, so lg->lguest_data will be NULL */
+               /* OK, it's really not there (or not OK): the Guest needs to
+                * know.  We write out the cr2 value so it knows where the
+                * fault occurred.
+                *
+                * Note that if the Guest were really messed up, this could
+                * happen before it's done the LHCALL_LGUEST_INIT hypercall, so
+                * lg->lguest_data could be NULL */
                if (lg->lguest_data &&
                    put_user(lg->arch.last_pagefault, &lg->lguest_data->cr2))
                        kill_guest(lg, "Writing cr2");
                break;
        case 7: /* We've intercepted a Device Not Available fault. */
-               /* If the Guest doesn't want to know, we already
-                * restored the Floating Point Unit, so we just
-                * continue without telling it. */
+               /* If the Guest doesn't want to know, we already restored the
+                * Floating Point Unit, so we just continue without telling
+                * it. */
                if (!lg->ts)
                        return;
                break;
@@ -536,9 +543,6 @@ int lguest_arch_init_hypercalls(struct lguest *lg)
 
        return 0;
 }
-/* Now we've examined the hypercall code; our Guest can make requests.  There
- * is one other way we can do things for the Guest, as we see in
- * emulate_insn(). :*/
 
 /*L:030 lguest_arch_setup_regs()
  *
@@ -562,7 +566,7 @@ void lguest_arch_setup_regs(struct lguest *lg, unsigned long start)
         * is supposed to always be "1".  Bit 9 (0x200) controls whether
         * interrupts are enabled.  We always leave interrupts enabled while
         * running the Guest. */
-       regs->eflags = 0x202;
+       regs->eflags = X86_EFLAGS_IF | 0x2;
 
        /* The "Extended Instruction Pointer" register says where the Guest is
         * running. */
@@ -570,8 +574,8 @@ void lguest_arch_setup_regs(struct lguest *lg, unsigned long start)
 
        /* %esi points to our boot information, at physical address 0, so don't
         * touch it. */
+
        /* There are a couple of GDT entries the Guest expects when first
         * booting. */
-
        setup_guest_gdt(lg);
 }
index 1010b90..0af8baa 100644 (file)
@@ -6,6 +6,37 @@
  * are feeling invigorated and refreshed then the next, more challenging stage
  * can be found in "make Guest". :*/
 
+/*M:012 Lguest is meant to be simple: my rule of thumb is that 1% more LOC must
+ * gain at least 1% more performance.  Since neither LOC nor performance can be
+ * measured beforehand, it generally means implementing a feature then deciding
+ * if it's worth it.  And once it's implemented, who can say no?
+ *
+ * This is why I haven't implemented this idea myself.  I want to, but I
+ * haven't.  You could, though.
+ *
+ * The main place where lguest performance sucks is Guest page faulting.  When
+ * a Guest userspace process hits an unmapped page we switch back to the Host,
+ * walk the page tables, find it's not mapped, switch back to the Guest page
+ * fault handler, which calls a hypercall to set the page table entry, then
+ * finally returns to userspace.  That's two round-trips.
+ *
+ * If we had a small walker in the Switcher, we could quickly check the Guest
+ * page table and if the page isn't mapped, immediately reflect the fault back
+ * into the Guest.  This means the Switcher would have to know the top of the
+ * Guest page table and the page fault handler address.
+ *
+ * For simplicity, the Guest should only handle the case where the privilege
+ * level of the fault is 3 and probably only not present or write faults.  It
+ * should also detect recursive faults, and hand the original fault to the
+ * Host (which is actually really easy).
+ *
+ * Two questions remain.  Would the performance gain outweigh the complexity?
+ * And who would write the verse documenting it? :*/
+
+/*M:011 Lguest64 handles NMI.  This gave me NMI envy (until I looked at their
+ * code).  It's worth doing though, since it would let us use oprofile in the
+ * Host when a Guest is running. :*/
+
 /*S:100
  * Welcome to the Switcher itself!
  *
@@ -88,7 +119,7 @@ ENTRY(switch_to_guest)
 
        // All saved and there's now five steps before us:
        // Stack, GDT, IDT, TSS
-       // And last of all the page tables are flipped.
+       // Then last of all the page tables are flipped.
 
        // Yet beware that our stack pointer must be
        // Always valid lest an NMI hits
@@ -103,25 +134,25 @@ ENTRY(switch_to_guest)
        lgdt    LGUEST_PAGES_guest_gdt_desc(%eax)
 
        // The Guest's IDT we did partially
-       // Move to the "struct lguest_pages" as well.
+       // Copy to "struct lguest_pages" as well.
        lidt    LGUEST_PAGES_guest_idt_desc(%eax)
 
        // The TSS entry which controls traps
        // Must be loaded up with "ltr" now:
+       // The GDT entry that TSS uses 
+       // Changes type when we load it: damn Intel!
        // For after we switch over our page tables
-       // It (as the rest) will be writable no more.
-       // (The GDT entry TSS needs
-       // Changes type when we load it: damn Intel!)
+       // That entry will be read-only: we'd crash.
        movl    $(GDT_ENTRY_TSS*8), %edx
        ltr     %dx
 
        // Look back now, before we take this last step!
        // The Host's TSS entry was also marked used;
-       // Let's clear it again, ere we return.
+       // Let's clear it again for our return.
        // The GDT descriptor of the Host
        // Points to the table after two "size" bytes
        movl    (LGUEST_PAGES_host_gdt_desc+2)(%eax), %edx
-       // Clear the type field of "used" (byte 5, bit 2)
+       // Clear "used" from type field (byte 5, bit 2)
        andb    $0xFD, (GDT_ENTRY_TSS*8 + 5)(%edx)
 
        // Once our page table's switched, the Guest is live!
@@ -131,7 +162,7 @@ ENTRY(switch_to_guest)
 
        // The page table change did one tricky thing:
        // The Guest's register page has been mapped
-       // Writable onto our %esp (stack) --
+       // Writable under our %esp (stack) --
        // We can simply pop off all Guest regs.
        popl    %eax
        popl    %ebx
@@ -152,16 +183,15 @@ ENTRY(switch_to_guest)
        addl    $8, %esp
 
        // The last five stack slots hold return address
-       // And everything needed to change privilege
-       // Into the Guest privilege level of 1,
+       // And everything needed to switch privilege
+       // From Switcher's level 0 to Guest's 1,
        // And the stack where the Guest had last left it.
        // Interrupts are turned back on: we are Guest.
        iret
 
-// There are two paths where we switch to the Host
+// We treat 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.
-// We are on our way home, back to the Host
-// Interrupted out of the Guest, we come here.
 #define SWITCH_TO_HOST                                                 \
        /* We save the Guest state: all registers first                 \
         * Laid out just as "struct lguest_regs" defines */             \
@@ -194,7 +224,7 @@ ENTRY(switch_to_guest)
        movl    %esp, %eax;                                             \
        andl    $(~(1 << PAGE_SHIFT - 1)), %eax;                        \
        /* Save our trap number: the switch will obscure it             \
-        * (The Guest regs are not mapped here in the Host)             \
+        * (In the Host the Guest regs are not mapped here)             \
         * %ebx holds it safe for deliver_to_host */                    \
        movl    LGUEST_PAGES_regs_trapnum(%eax), %ebx;                  \
        /* The Host GDT, IDT and stack!                                 \
@@ -210,9 +240,9 @@ ENTRY(switch_to_guest)
        /* Switch to Host's GDT, IDT. */                                \
        lgdt    LGUEST_PAGES_host_gdt_desc(%eax);                       \
        lidt    LGUEST_PAGES_host_idt_desc(%eax);                       \
-       /* Restore the Host's stack where it's saved regs lie */        \
+       /* Restore the Host's stack where its saved regs lie */         \
        movl    LGUEST_PAGES_host_sp(%eax), %esp;                       \
-       /* Last the TSS: our Host is complete */                        \
+       /* Last the TSS: our Host is returned */                        \
        movl    $(GDT_ENTRY_TSS*8), %edx;                               \
        ltr     %dx;                                                    \
        /* Restore now the regs saved right at the first. */            \
@@ -222,14 +252,15 @@ ENTRY(switch_to_guest)
        popl    %ds;                                                    \
        popl    %es
 
-// Here's where we come when the Guest has just trapped:
-// (Which trap we'll see has been pushed on the stack).
+// The first path is trod when the Guest has trapped:
+// (Which trap it was has been pushed on the stack).
 // We need only switch back, and the Host will decode
 // Why we came home, and what needs to be done.
 return_to_host:
        SWITCH_TO_HOST
        iret
 
+// We are lead to the second path like so:
 // An interrupt, with some cause external
 // Has ajerked us rudely from the Guest's code
 // Again we must return home to the Host
@@ -238,7 +269,7 @@ deliver_to_host:
        // But now we must go home via that place
        // Where that interrupt was supposed to go
        // Had we not been ensconced, running the Guest.
-       // Here we see the cleverness of our stack:
+       // Here we see the trickness of run_guest_once():
        // The Host stack is formed like an interrupt
        // With EIP, CS and EFLAGS layered.
        // Interrupt handlers end with "iret"
@@ -263,7 +294,7 @@ deliver_to_host:
        xorw    %ax, %ax
        orl     %eax, %edx
        // Now the address of the handler's in %edx
-       // We call it now: its "iret" takes us home.
+       // We call it now: its "iret" drops us home.
        jmp     *%edx
 
 // Every interrupt can come to us here
index ac54f69..28c6ae0 100644 (file)
@@ -168,7 +168,7 @@ static int crypt_iv_essiv_ctr(struct crypt_config *cc, struct dm_target *ti,
                return -ENOMEM;
        }
 
-       sg_set_buf(&sg, cc->key, cc->key_size);
+       sg_init_one(&sg, cc->key, cc->key_size);
        desc.tfm = hash_tfm;
        desc.flags = CRYPTO_TFM_REQ_MAY_SLEEP;
        err = crypto_hash_digest(&desc, &sg, cc->key_size, salt);
@@ -351,14 +351,10 @@ static int crypt_convert(struct crypt_config *cc,
                struct scatterlist sg_in, sg_out;
 
                sg_init_table(&sg_in, 1);
-               sg_set_page(&sg_in, bv_in->bv_page);
-               sg_in.offset = bv_in->bv_offset + ctx->offset_in;
-               sg_in.length = 1 << SECTOR_SHIFT;
+               sg_set_page(&sg_in, bv_in->bv_page, 1 << SECTOR_SHIFT, bv_in->bv_offset + ctx->offset_in);
 
                sg_init_table(&sg_out, 1);
-               sg_set_page(&sg_out, bv_out->bv_page);
-               sg_out.offset = bv_out->bv_offset + ctx->offset_out;
-               sg_out.length = 1 << SECTOR_SHIFT;
+               sg_set_page(&sg_out, bv_out->bv_page, 1 << SECTOR_SHIFT, bv_out->bv_offset + ctx->offset_out);
 
                ctx->offset_in += sg_in.length;
                if (ctx->offset_in >= bv_in->bv_len) {
index 9265761..77a6e4b 100644 (file)
@@ -52,7 +52,7 @@ const struct raid6_calls * const raid6_algos[] = {
        &raid6_intx16,
        &raid6_intx32,
 #endif
-#if defined(__i386__)
+#if defined(__i386__) && !defined(__arch_um__)
        &raid6_mmxx1,
        &raid6_mmxx2,
        &raid6_sse1x1,
@@ -60,7 +60,7 @@ const struct raid6_calls * const raid6_algos[] = {
        &raid6_sse2x1,
        &raid6_sse2x2,
 #endif
-#if defined(__x86_64__)
+#if defined(__x86_64__) && !defined(__arch_um__)
        &raid6_sse2x1,
        &raid6_sse2x2,
        &raid6_sse2x4,
index 6181a5a..d4e4a1b 100644 (file)
@@ -16,7 +16,7 @@
  * MMX implementation of RAID-6 syndrome functions
  */
 
-#if defined(__i386__)
+#if defined(__i386__) && !defined(__arch_um__)
 
 #include "raid6.h"
 #include "raid6x86.h"
index f0a1ba8..0666237 100644 (file)
@@ -21,7 +21,7 @@
  * worthwhile as a separate implementation.
  */
 
-#if defined(__i386__)
+#if defined(__i386__) && !defined(__arch_um__)
 
 #include "raid6.h"
 #include "raid6x86.h"
index 0f01976..b034ad8 100644 (file)
@@ -17,7 +17,7 @@
  *
  */
 
-#if defined(__i386__) || defined(__x86_64__)
+#if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__)
 
 #include "raid6.h"
 #include "raid6x86.h"
@@ -161,7 +161,7 @@ const struct raid6_calls raid6_sse2x2 = {
 
 #endif
 
-#ifdef __x86_64__
+#if defined(__x86_64__) && !defined(__arch_um__)
 
 /*
  * Unrolled-by-4 SSE2 implementation
index 9111950..99fea7a 100644 (file)
@@ -19,7 +19,7 @@
 #ifndef LINUX_RAID_RAID6X86_H
 #define LINUX_RAID_RAID6X86_H
 
-#if defined(__i386__) || defined(__x86_64__)
+#if (defined(__i386__) || defined(__x86_64__)) && !defined(__arch_um__)
 
 #ifdef __KERNEL__ /* Real code */
 
index 2b1f8b4..cb034ea 100644 (file)
@@ -118,8 +118,7 @@ static struct scatterlist* vmalloc_to_sg(unsigned char *virt, int nr_pages)
                if (NULL == pg)
                        goto err;
                BUG_ON(PageHighMem(pg));
-               sg_set_page(&sglist[i], pg);
-               sglist[i].length = PAGE_SIZE;
+               sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
        }
        return sglist;
 
index 912b424..460db03 100644 (file)
@@ -49,8 +49,6 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
                unsigned int len = (i == dma_page->page_count - 1) ?
                        dma_page->tail : PAGE_SIZE - offset;
 
-               dma->SGlist[map_offset].length = len;
-               dma->SGlist[map_offset].offset = offset;
                if (PageHighMem(dma->map[map_offset])) {
                        void *src;
 
@@ -63,10 +61,10 @@ int ivtv_udma_fill_sg_list (struct ivtv_user_dma *dma, struct ivtv_dma_page_info
                        memcpy(page_address(dma->bouncemap[map_offset]) + offset, src, len);
                        kunmap_atomic(src, KM_BOUNCE_READ);
                        local_irq_restore(flags);
-                       sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset]);
+                       sg_set_page(&dma->SGlist[map_offset], dma->bouncemap[map_offset], len, offset);
                }
                else {
-                       sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset]);
+                       sg_set_page(&dma->SGlist[map_offset], dma->map[map_offset], len, offset);
                }
                offset = 0;
                map_offset++;
index 9ab94a7..44ee408 100644 (file)
@@ -67,8 +67,7 @@ videobuf_vmalloc_to_sg(unsigned char *virt, int nr_pages)
                if (NULL == pg)
                        goto err;
                BUG_ON(PageHighMem(pg));
-               sg_set_page(&sglist[i], pg);
-               sglist[i].length = PAGE_SIZE;
+               sg_set_page(&sglist[i], pg, PAGE_SIZE, 0);
        }
        return sglist;
 
@@ -95,16 +94,13 @@ videobuf_pages_to_sg(struct page **pages, int nr_pages, int offset)
        if (PageHighMem(pages[0]))
                /* DMA to highmem pages might not work */
                goto highmem;
-       sg_set_page(&sglist[0], pages[0]);
-       sglist[0].offset = offset;
-       sglist[0].length = PAGE_SIZE - offset;
+       sg_set_page(&sglist[0], pages[0], PAGE_SIZE - offset, offset);
        for (i = 1; i < nr_pages; i++) {
                if (NULL == pages[i])
                        goto nopage;
                if (PageHighMem(pages[i]))
                        goto highmem;
-               sg_set_page(&sglist[i], pages[i]);
-               sglist[i].length = PAGE_SIZE;
+               sg_set_page(&sglist[i], pages[i], PAGE_SIZE, 0);
        }
        return sglist;
 
index d602ba6..6824061 100644 (file)
@@ -284,6 +284,7 @@ static inline struct i2o_block_request *i2o_block_request_alloc(void)
                return ERR_PTR(-ENOMEM);
 
        INIT_LIST_HEAD(&ireq->queue);
+       sg_init_table(ireq->sg_table, I2O_MAX_PHYS_SEGMENTS);
 
        return ireq;
 };
index d366a6c..c8d62c2 100644 (file)
@@ -122,9 +122,6 @@ static int get_lcd_level(void)
        else
                fujitsu->brightness_changed = 0;
 
-       if (status < 0)
-               return status;
-
        return fujitsu->brightness_level;
 }
 
@@ -198,7 +195,7 @@ static struct platform_driver fujitsupf_driver = {
 
 /* ACPI device */
 
-int acpi_fujitsu_add(struct acpi_device *device)
+static int acpi_fujitsu_add(struct acpi_device *device)
 {
        int result = 0;
        int state = 0;
@@ -229,7 +226,7 @@ int acpi_fujitsu_add(struct acpi_device *device)
        return result;
 }
 
-int acpi_fujitsu_remove(struct acpi_device *device, int type)
+static int acpi_fujitsu_remove(struct acpi_device *device, int type)
 {
        ACPI_FUNCTION_TRACE("acpi_fujitsu_remove");
 
index bf4bc6a..7471d49 100644 (file)
@@ -267,15 +267,26 @@ mmc_send_cxd_data(struct mmc_card *card, struct mmc_host *host,
 
 int mmc_send_csd(struct mmc_card *card, u32 *csd)
 {
+       int ret, i;
+
        if (!mmc_host_is_spi(card->host))
                return mmc_send_cxd_native(card->host, card->rca << 16,
                                csd, MMC_SEND_CSD);
 
-       return mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
+       ret = mmc_send_cxd_data(card, card->host, MMC_SEND_CSD, csd, 16);
+       if (ret)
+               return ret;
+
+       for (i = 0;i < 4;i++)
+               csd[i] = be32_to_cpu(csd[i]);
+
+       return 0;
 }
 
 int mmc_send_cid(struct mmc_host *host, u32 *cid)
 {
+       int ret, i;
+
        if (!mmc_host_is_spi(host)) {
                if (!host->card)
                        return -EINVAL;
@@ -283,7 +294,14 @@ int mmc_send_cid(struct mmc_host *host, u32 *cid)
                                cid, MMC_SEND_CID);
        }
 
-       return mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
+       ret = mmc_send_cxd_data(NULL, host, MMC_SEND_CID, cid, 16);
+       if (ret)
+               return ret;
+
+       for (i = 0;i < 4;i++)
+               cid[i] = be32_to_cpu(cid[i]);
+
+       return 0;
 }
 
 int mmc_send_ext_csd(struct mmc_card *card, u8 *ext_csd)
index ee4029a..a6dafe6 100644 (file)
@@ -294,8 +294,8 @@ int mmc_app_send_scr(struct mmc_card *card, u32 *scr)
        if (data.error)
                return data.error;
 
-       scr[0] = ntohl(scr[0]);
-       scr[1] = ntohl(scr[1]);
+       scr[0] = be32_to_cpu(scr[0]);
+       scr[1] = be32_to_cpu(scr[1]);
 
        return 0;
 }
index bcbb6d2..c3926eb 100644 (file)
 #include <linux/mm.h>
 #include <linux/interrupt.h>
 #include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
 
 #include <linux/mmc/host.h>
 #include <asm/io.h>
 #include <asm/mach-au1x00/au1000.h>
 #include <asm/mach-au1x00/au1xxx_dbdma.h>
 #include <asm/mach-au1x00/au1100_mmc.h>
-#include <asm/scatterlist.h>
 
 #include <au1xxx.h>
 #include "au1xmmc.h"
@@ -212,12 +212,12 @@ static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
        }
 
        if (data) {
-               if (flags & MMC_DATA_READ) {
+               if (data->flags & MMC_DATA_READ) {
                        if (data->blocks > 1)
                                mmccmd |= SD_CMD_CT_4;
                        else
                                mmccmd |= SD_CMD_CT_2;
-               } else if (flags & MMC_DATA_WRITE) {
+               } else if (data->flags & MMC_DATA_WRITE) {
                        if (data->blocks > 1)
                                mmccmd |= SD_CMD_CT_3;
                        else
index fc72e1f..f2070a1 100644 (file)
@@ -262,7 +262,7 @@ static void imxmci_setup_data(struct imxmci_host *host, struct mmc_data *data)
                }
 
                /* Convert back to virtual address */
-               host->data_ptr = (u16*)sg_virt(sg);
+               host->data_ptr = (u16*)sg_virt(data->sg);
                host->data_cnt = 0;
 
                clear_bit(IMXMCI_PEND_DMA_DATA_b, &host->pending_events);
index 12c2d80..a646921 100644 (file)
@@ -1165,6 +1165,23 @@ mmc_spi_detect_irq(int irq, void *mmc)
        return IRQ_HANDLED;
 }
 
+struct count_children {
+       unsigned        n;
+       struct bus_type *bus;
+};
+
+static int maybe_count_child(struct device *dev, void *c)
+{
+       struct count_children *ccp = c;
+
+       if (dev->bus == ccp->bus) {
+               if (ccp->n)
+                       return -EBUSY;
+               ccp->n++;
+       }
+       return 0;
+}
+
 static int mmc_spi_probe(struct spi_device *spi)
 {
        void                    *ones;
@@ -1188,33 +1205,30 @@ static int mmc_spi_probe(struct spi_device *spi)
                return status;
        }
 
-       /* We can use the bus safely iff nobody else will interfere with
-        * us.  That is, either we have the experimental exclusive access
-        * primitives ... or else there's nobody to share it with.
+       /* We can use the bus safely iff nobody else will interfere with us.
+        * Most commands consist of one SPI message to issue a command, then
+        * several more to collect its response, then possibly more for data
+        * transfer.  Clocking access to other devices during that period will
+        * corrupt the command execution.
+        *
+        * Until we have software primitives which guarantee non-interference,
+        * we'll aim for a hardware-level guarantee.
+        *
+        * REVISIT we can't guarantee another device won't be added later...
         */
        if (spi->master->num_chipselect > 1) {
-               struct device   *parent = spi->dev.parent;
+               struct count_children cc;
 
-               /* If there are multiple devices on this bus, we
-                * can't proceed.
-                */
-               spin_lock(&parent->klist_children.k_lock);
-               if (parent->klist_children.k_list.next
-                               != parent->klist_children.k_list.prev)
-                       status = -EMLINK;
-               else
-                       status = 0;
-               spin_unlock(&parent->klist_children.k_lock);
+               cc.n = 0;
+               cc.bus = spi->dev.bus;
+               status = device_for_each_child(spi->dev.parent, &cc,
+                               maybe_count_child);
                if (status < 0) {
                        dev_err(&spi->dev, "can't share SPI bus\n");
                        return status;
                }
 
-               /* REVISIT we can't guarantee another device won't
-                * be added later.  It's uncommon though ... for now,
-                * work as if this is safe.
-                */
-               dev_warn(&spi->dev, "ASSUMING unshared SPI bus!\n");
+               dev_warn(&spi->dev, "ASSUMING SPI bus stays unshared!\n");
        }
 
        /* We need a supply of ones to transmit.  This is the only time
index d0eb0a2..95244a7 100644 (file)
 #include <linux/mmc/host.h>
 #include <linux/amba/bus.h>
 #include <linux/clk.h>
+#include <linux/scatterlist.h>
 
 #include <asm/cacheflush.h>
 #include <asm/div64.h>
 #include <asm/io.h>
-#include <asm/scatterlist.h>
 #include <asm/sizes.h>
 #include <asm/mach/mmc.h>
 
@@ -167,7 +167,7 @@ mmci_data_irq(struct mmci_host *host, struct mmc_data *data,
                 * partially written to a page is properly coherent.
                 */
                if (host->sg_len && data->flags & MMC_DATA_READ)
-                       flush_dcache_page(host->sg_ptr->page);
+                       flush_dcache_page(sg_page(host->sg_ptr));
        }
        if (status & MCI_DATAEND) {
                mmci_stop_data(host);
@@ -319,7 +319,7 @@ static irqreturn_t mmci_pio_irq(int irq, void *dev_id)
                 * page, ensure that the data cache is coherent.
                 */
                if (status & MCI_RXACTIVE)
-                       flush_dcache_page(host->sg_ptr->page);
+                       flush_dcache_page(sg_page(host->sg_ptr));
 
                if (!mmci_next_sg(host))
                        break;
index 0601e01..a25ee71 100644 (file)
@@ -29,7 +29,6 @@
 
 #include <asm/dma.h>
 #include <asm/io.h>
-#include <asm/scatterlist.h>
 #include <asm/sizes.h>
 
 #include <asm/arch/pxa-regs.h>
index d7c5b94..6b80bf7 100644 (file)
@@ -17,8 +17,6 @@
 
 #include <linux/mmc/host.h>
 
-#include <asm/scatterlist.h>
-
 #include "sdhci.h"
 
 #define DRIVER_NAME "sdhci"
index fa4c8c5..4d5f374 100644 (file)
 #include <linux/pnp.h>
 #include <linux/highmem.h>
 #include <linux/mmc/host.h>
+#include <linux/scatterlist.h>
 
 #include <asm/io.h>
 #include <asm/dma.h>
-#include <asm/scatterlist.h>
 
 #include "wbsd.h"
 
index 86b8641..867cb73 100644 (file)
@@ -166,13 +166,14 @@ config NET_SB1000
          If you don't have this card, of course say N.
 
 config IP1000
-       tristate "IP1000 Gigabit Ethernet support"
-       depends on PCI && EXPERIMENTAL
-       ---help---
-         This driver supports IP1000 gigabit Ethernet cards.
+       tristate "IP1000 Gigabit Ethernet support"
+       depends on PCI && EXPERIMENTAL
+       select MII
+       ---help---
+         This driver supports IP1000 gigabit Ethernet cards.
 
-         To compile this driver as a module, choose M here: the module
-         will be called ipg.  This is recommended.
+         To compile this driver as a module, choose M here: the module
+         will be called ipg.  This is recommended.
 
 source "drivers/net/arcnet/Kconfig"
 
@@ -1880,6 +1881,30 @@ config FEC2
          Say Y here if you want to use the second built-in 10/100 Fast
          ethernet controller on some Motorola ColdFire processors.
 
+config FEC_MPC52xx
+       tristate "MPC52xx FEC driver"
+       depends on PPC_MPC52xx
+       select PPC_BESTCOMM
+       select PPC_BESTCOMM_FEC
+       select CRC32
+       select PHYLIB
+       ---help---
+         This option enables support for the MPC5200's on-chip
+         Fast Ethernet Controller
+         If compiled as module, it will be called 'fec_mpc52xx.ko'.
+
+config FEC_MPC52xx_MDIO
+       bool "MPC52xx FEC MDIO bus driver"
+       depends on FEC_MPC52xx
+       default y
+       ---help---
+         The MPC5200's FEC can connect to the Ethernet either with
+         an external MII PHY chip or 10 Mbps 7-wire interface
+         (Motorola? industry standard).
+         If your board uses an external PHY connected to FEC, enable this.
+         If not sure, enable.
+         If compiled as module, it will be called 'fec_mpc52xx_phy.ko'.
+
 config NE_H8300
        tristate "NE2000 compatible support for H8/300"
        depends on H8300
index 5932620..0e5fde4 100644 (file)
@@ -96,6 +96,10 @@ obj-$(CONFIG_SHAPER) += shaper.o
 obj-$(CONFIG_HP100) += hp100.o
 obj-$(CONFIG_SMC9194) += smc9194.o
 obj-$(CONFIG_FEC) += fec.o
+obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx.o
+ifeq ($(CONFIG_FEC_MPC52xx_MDIO),y)
+       obj-$(CONFIG_FEC_MPC52xx) += fec_mpc52xx_phy.o
+endif
 obj-$(CONFIG_68360_ENET) += 68360enet.o
 obj-$(CONFIG_WD80x3) += wd.o 8390.o
 obj-$(CONFIG_EL2) += 3c503.o 8390.o
index 6909bec..6937ef0 100644 (file)
@@ -188,6 +188,7 @@ struct bond_parm_tbl arp_validate_tbl[] = {
 /*-------------------------- Forward declarations ---------------------------*/
 
 static void bond_send_gratuitous_arp(struct bonding *bond);
+static void bond_deinit(struct net_device *bond_dev);
 
 /*---------------------------- General routines -----------------------------*/
 
@@ -3681,7 +3682,7 @@ static int bond_open(struct net_device *bond_dev)
        }
 
        if (bond->params.mode == BOND_MODE_8023AD) {
-               INIT_DELAYED_WORK(&bond->ad_work, bond_alb_monitor);
+               INIT_DELAYED_WORK(&bond->ad_work, bond_3ad_state_machine_handler);
                queue_delayed_work(bond->wq, &bond->ad_work, 0);
                /* register to receive LACPDUs */
                bond_register_lacpdu(bond);
@@ -4449,7 +4450,7 @@ static int bond_init(struct net_device *bond_dev, struct bond_params *params)
 /* De-initialize device specific data.
  * Caller must hold rtnl_lock.
  */
-void bond_deinit(struct net_device *bond_dev)
+static void bond_deinit(struct net_device *bond_dev)
 {
        struct bonding *bond = bond_dev->priv;
 
index d1ed14b..61c1b45 100644 (file)
@@ -302,7 +302,6 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, struct net_de
 int bond_create(char *name, struct bond_params *params, struct bonding **newbond);
 void bond_destroy(struct bonding *bond);
 int  bond_release_and_destroy(struct net_device *bond_dev, struct net_device *slave_dev);
-void bond_deinit(struct net_device *bond_dev);
 int bond_create_sysfs(void);
 void bond_destroy_sysfs(void);
 void bond_destroy_sysfs_entry(struct bonding *bond);
index 57541d2..6fd95a2 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/skbuff.h>
 #include <linux/mii.h>
 #include <linux/phy.h>
+#include <linux/phy_fixed.h>
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <asm/gpio.h>
@@ -53,12 +54,6 @@ MODULE_PARM_DESC(debug_level, "Number of NETIF_MSG bits to enable");
 MODULE_PARM_DESC(dumb_switch, "Assume switch is not connected to MDIO bus");
 
 #define CPMAC_VERSION "0.5.0"
-/* stolen from net/ieee80211.h */
-#ifndef MAC_FMT
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#define MAC_ARG(x) ((u8*)(x))[0], ((u8*)(x))[1], ((u8*)(x))[2], \
-                  ((u8*)(x))[3], ((u8*)(x))[4], ((u8*)(x))[5]
-#endif
 /* frame size + 802.1q tag */
 #define CPMAC_SKB_SIZE         (ETH_FRAME_LEN + 4)
 #define CPMAC_QUEUES   8
@@ -211,6 +206,7 @@ struct cpmac_priv {
        struct net_device *dev;
        struct work_struct reset_work;
        struct platform_device *pdev;
+       struct napi_struct napi;
 };
 
 static irqreturn_t cpmac_irq(int, void *);
@@ -362,47 +358,48 @@ static void cpmac_set_multicast_list(struct net_device *dev)
        }
 }
 
-static struct sk_buff *cpmac_rx_one(struct net_device *dev,
-                                   struct cpmac_priv *priv,
+static struct sk_buff *cpmac_rx_one(struct cpmac_priv *priv,
                                    struct cpmac_desc *desc)
 {
        struct sk_buff *skb, *result = NULL;
 
        if (unlikely(netif_msg_hw(priv)))
-               cpmac_dump_desc(dev, desc);
+               cpmac_dump_desc(priv->dev, desc);
        cpmac_write(priv->regs, CPMAC_RX_ACK(0), (u32)desc->mapping);
        if (unlikely(!desc->datalen)) {
                if (netif_msg_rx_err(priv) && net_ratelimit())
                        printk(KERN_WARNING "%s: rx: spurious interrupt\n",
-                              dev->name);
+                              priv->dev->name);
                return NULL;
        }
 
-       skb = netdev_alloc_skb(dev, CPMAC_SKB_SIZE);
+       skb = netdev_alloc_skb(priv->dev, CPMAC_SKB_SIZE);
        if (likely(skb)) {
                skb_reserve(skb, 2);
                skb_put(desc->skb, desc->datalen);
-               desc->skb->protocol = eth_type_trans(desc->skb, dev);
+               desc->skb->protocol = eth_type_trans(desc->skb, priv->dev);
                desc->skb->ip_summed = CHECKSUM_NONE;
-               dev->stats.rx_packets++;
-               dev->stats.rx_bytes += desc->datalen;
+               priv->dev->stats.rx_packets++;
+               priv->dev->stats.rx_bytes += desc->datalen;
                result = desc->skb;
-               dma_unmap_single(&dev->dev, desc->data_mapping, CPMAC_SKB_SIZE,
-                                DMA_FROM_DEVICE);
+               dma_unmap_single(&priv->dev->dev, desc->data_mapping,
+                                CPMAC_SKB_SIZE, DMA_FROM_DEVICE);
                desc->skb = skb;
-               desc->data_mapping = dma_map_single(&dev->dev, skb->data,
+               desc->data_mapping = dma_map_single(&priv->dev->dev, skb->data,
                                                    CPMAC_SKB_SIZE,
                                                    DMA_FROM_DEVICE);
                desc->hw_data = (u32)desc->data_mapping;
                if (unlikely(netif_msg_pktdata(priv))) {
-                       printk(KERN_DEBUG "%s: received packet:\n", dev->name);
-                       cpmac_dump_skb(dev, result);
+                       printk(KERN_DEBUG "%s: received packet:\n",
+                              priv->dev->name);
+                       cpmac_dump_skb(priv->dev, result);
                }
        } else {
                if (netif_msg_rx_err(priv) && net_ratelimit())
                        printk(KERN_WARNING
-                              "%s: low on skbs, dropping packet\n", dev->name);
-               dev->stats.rx_dropped++;
+                              "%s: low on skbs, dropping packet\n",
+                              priv->dev->name);
+               priv->dev->stats.rx_dropped++;
        }
 
        desc->buflen = CPMAC_SKB_SIZE;
@@ -411,25 +408,25 @@ static struct sk_buff *cpmac_rx_one(struct net_device *dev,
        return result;
 }
 
-static int cpmac_poll(struct net_device *dev, int *budget)
+static int cpmac_poll(struct napi_struct *napi, int budget)
 {
        struct sk_buff *skb;
        struct cpmac_desc *desc;
-       int received = 0, quota = min(dev->quota, *budget);
-       struct cpmac_priv *priv = netdev_priv(dev);
+       int received = 0;
+       struct cpmac_priv *priv = container_of(napi, struct cpmac_priv, napi);
 
        spin_lock(&priv->rx_lock);
        if (unlikely(!priv->rx_head)) {
                if (netif_msg_rx_err(priv) && net_ratelimit())
                        printk(KERN_WARNING "%s: rx: polling, but no queue\n",
-                              dev->name);
-               netif_rx_complete(dev);
+                              priv->dev->name);
+               netif_rx_complete(priv->dev, napi);
                return 0;
        }
 
        desc = priv->rx_head;
-       while ((received < quota) && ((desc->dataflags & CPMAC_OWN) == 0)) {
-               skb = cpmac_rx_one(dev, priv, desc);
+       while (((desc->dataflags & CPMAC_OWN) == 0) && (received < budget)) {
+               skb = cpmac_rx_one(priv, desc);
                if (likely(skb)) {
                        netif_receive_skb(skb);
                        received++;
@@ -439,13 +436,11 @@ static int cpmac_poll(struct net_device *dev, int *budget)
 
        priv->rx_head = desc;
        spin_unlock(&priv->rx_lock);
-       *budget -= received;
-       dev->quota -= received;
        if (unlikely(netif_msg_rx_status(priv)))
-               printk(KERN_DEBUG "%s: poll processed %d packets\n", dev->name,
-                      received);
+               printk(KERN_DEBUG "%s: poll processed %d packets\n",
+                      priv->dev->name, received);
        if (desc->dataflags & CPMAC_OWN) {
-               netif_rx_complete(dev);
+               netif_rx_complete(priv->dev, napi);
                cpmac_write(priv->regs, CPMAC_RX_PTR(0), (u32)desc->mapping);
                cpmac_write(priv->regs, CPMAC_RX_INT_ENABLE, 1);
                return 0;
@@ -655,6 +650,7 @@ static void cpmac_hw_error(struct work_struct *work)
        spin_unlock(&priv->rx_lock);
        cpmac_clear_tx(priv->dev);
        cpmac_hw_start(priv->dev);
+       napi_enable(&priv->napi);
        netif_start_queue(priv->dev);
 }
 
@@ -681,8 +677,10 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
 
        if (status & MAC_INT_RX) {
                queue = (status >> 8) & 7;
-               netif_rx_schedule(dev);
-               cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
+               if (netif_rx_schedule_prep(dev, &priv->napi)) {
+                       cpmac_write(priv->regs, CPMAC_RX_INT_CLEAR, 1 << queue);
+                       __netif_rx_schedule(dev, &priv->napi);
+               }
        }
 
        cpmac_write(priv->regs, CPMAC_MAC_EOI_VECTOR, 0);
@@ -692,6 +690,7 @@ static irqreturn_t cpmac_irq(int irq, void *dev_id)
                        printk(KERN_ERR "%s: hw error, resetting...\n",
                               dev->name);
                netif_stop_queue(dev);
+               napi_disable(&priv->napi);
                cpmac_hw_stop(dev);
                schedule_work(&priv->reset_work);
                if (unlikely(netif_msg_hw(priv)))
@@ -849,6 +848,15 @@ static void cpmac_adjust_link(struct net_device *dev)
        spin_unlock(&priv->lock);
 }
 
+static int cpmac_link_update(struct net_device *dev,
+                            struct fixed_phy_status *status)
+{
+       status->link = 1;
+       status->speed = 100;
+       status->duplex = 1;
+       return 0;
+}
+
 static int cpmac_open(struct net_device *dev)
 {
        int i, size, res;
@@ -857,15 +865,6 @@ static int cpmac_open(struct net_device *dev)
        struct cpmac_desc *desc;
        struct sk_buff *skb;
 
-       priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link,
-                               0, PHY_INTERFACE_MODE_MII);
-       if (IS_ERR(priv->phy)) {
-               if (netif_msg_drv(priv))
-                       printk(KERN_ERR "%s: Could not attach to PHY\n",
-                              dev->name);
-               return PTR_ERR(priv->phy);
-       }
-
        mem = platform_get_resource_byname(priv->pdev, IORESOURCE_MEM, "regs");
        if (!request_mem_region(mem->start, mem->end - mem->start, dev->name)) {
                if (netif_msg_drv(priv))
@@ -927,6 +926,7 @@ static int cpmac_open(struct net_device *dev)
        INIT_WORK(&priv->reset_work, cpmac_hw_error);
        cpmac_hw_start(dev);
 
+       napi_enable(&priv->napi);
        priv->phy->state = PHY_CHANGELINK;
        phy_start(priv->phy);
 
@@ -951,8 +951,6 @@ fail_remap:
        release_mem_region(mem->start, mem->end - mem->start);
 
 fail_reserve:
-       phy_disconnect(priv->phy);
-
        return res;
 }
 
@@ -965,9 +963,8 @@ static int cpmac_stop(struct net_device *dev)
        netif_stop_queue(dev);
 
        cancel_work_sync(&priv->reset_work);
+       napi_disable(&priv->napi);
        phy_stop(priv->phy);
-       phy_disconnect(priv->phy);
-       priv->phy = NULL;
 
        cpmac_hw_stop(dev);
 
@@ -1001,11 +998,13 @@ static int external_switch;
 
 static int __devinit cpmac_probe(struct platform_device *pdev)
 {
-       int rc, phy_id;
+       int rc, phy_id, i;
        struct resource *mem;
        struct cpmac_priv *priv;
        struct net_device *dev;
        struct plat_cpmac_data *pdata;
+       struct fixed_info *fixed_phy;
+       DECLARE_MAC_BUF(mac);
 
        pdata = pdev->dev.platform_data;
 
@@ -1053,21 +1052,51 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
        dev->set_multicast_list = cpmac_set_multicast_list;
        dev->tx_timeout         = cpmac_tx_timeout;
        dev->ethtool_ops        = &cpmac_ethtool_ops;
-       dev->poll = cpmac_poll;
-       dev->weight = 64;
        dev->features |= NETIF_F_MULTI_QUEUE;
 
+       netif_napi_add(dev, &priv->napi, cpmac_poll, 64);
+
        spin_lock_init(&priv->lock);
        spin_lock_init(&priv->rx_lock);
        priv->dev = dev;
        priv->ring_size = 64;
        priv->msg_enable = netif_msg_init(debug_level, 0xff);
        memcpy(dev->dev_addr, pdata->dev_addr, sizeof(dev->dev_addr));
+
        if (phy_id == 31) {
-               snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT,
-                        cpmac_mii.id, phy_id);
-       } else
-               snprintf(priv->phy_name, BUS_ID_SIZE, "fixed@%d:%d", 100, 1);
+               snprintf(priv->phy_name, BUS_ID_SIZE, PHY_ID_FMT, cpmac_mii.id,
+                        phy_id);
+       } else {
+               /* Let's try to get a free fixed phy... */
+               for (i = 0; i < MAX_PHY_AMNT; i++) {
+                       fixed_phy = fixed_mdio_get_phydev(i);
+                       if (!fixed_phy)
+                               continue;
+                       if (!fixed_phy->phydev->attached_dev) {
+                               strncpy(priv->phy_name,
+                                       fixed_phy->phydev->dev.bus_id,
+                                       BUS_ID_SIZE);
+                               fixed_mdio_set_link_update(fixed_phy->phydev,
+                                                          &cpmac_link_update);
+                               goto phy_found;
+                       }
+               }
+               if (netif_msg_drv(priv))
+                       printk(KERN_ERR "%s: Could not find fixed PHY\n",
+                              dev->name);
+               rc = -ENODEV;
+               goto fail;
+       }
+
+phy_found:
+       priv->phy = phy_connect(dev, priv->phy_name, &cpmac_adjust_link, 0,
+                               PHY_INTERFACE_MODE_MII);
+       if (IS_ERR(priv->phy)) {
+               if (netif_msg_drv(priv))
+                       printk(KERN_ERR "%s: Could not attach to PHY\n",
+                              dev->name);
+               return PTR_ERR(priv->phy);
+       }
 
        if ((rc = register_netdev(dev))) {
                printk(KERN_ERR "cpmac: error %i registering device %s\n", rc,
@@ -1077,9 +1106,9 @@ static int __devinit cpmac_probe(struct platform_device *pdev)
 
        if (netif_msg_probe(priv)) {
                printk(KERN_INFO
-                      "cpmac: device %s (regs: %p, irq: %d, phy: %s, mac: "
-                      MAC_FMT ")\n", dev->name, (void *)mem->start, dev->irq,
-                      priv->phy_name, MAC_ARG(dev->dev_addr));
+                      "cpmac: device %s (regs: %p, irq: %d, phy: %s, "
+                      "mac: %s)\n", dev->name, (void *)mem->start, dev->irq,
+                      priv->phy_name, print_mac(mac, dev->dev_addr));
        }
        return 0;
 
index d2499bb..473f78d 100644 (file)
@@ -122,7 +122,8 @@ struct e1000_buffer {
                        u16 next_to_watch;
                };
                /* RX */
-               struct page *page;
+               /* arrays of page information for packet split */
+               struct e1000_ps_page *ps_pages;
        };
 
 };
@@ -142,8 +143,6 @@ struct e1000_ring {
        /* array of buffer information structs */
        struct e1000_buffer *buffer_info;
 
-       /* arrays of page information for packet split */
-       struct e1000_ps_page *ps_pages;
        struct sk_buff *rx_skb_top;
 
        struct e1000_queue_stats stats;
index 033e124..4fd2e23 100644 (file)
@@ -245,37 +245,36 @@ static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
                rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
 
                for (j = 0; j < PS_PAGE_BUFFERS; j++) {
-                       ps_page = &rx_ring->ps_pages[(i * PS_PAGE_BUFFERS)
-                                                    + j];
-                       if (j < adapter->rx_ps_pages) {
+                       ps_page = &buffer_info->ps_pages[j];
+                       if (j >= adapter->rx_ps_pages) {
+                               /* all unused desc entries get hw null ptr */
+                               rx_desc->read.buffer_addr[j+1] = ~0;
+                               continue;
+                       }
+                       if (!ps_page->page) {
+                               ps_page->page = alloc_page(GFP_ATOMIC);
                                if (!ps_page->page) {
-                                       ps_page->page = alloc_page(GFP_ATOMIC);
-                                       if (!ps_page->page) {
-                                               adapter->alloc_rx_buff_failed++;
-                                               goto no_buffers;
-                                       }
-                                       ps_page->dma = pci_map_page(pdev,
-                                                          ps_page->page,
-                                                          0, PAGE_SIZE,
-                                                          PCI_DMA_FROMDEVICE);
-                                       if (pci_dma_mapping_error(
-                                                       ps_page->dma)) {
-                                               dev_err(&adapter->pdev->dev,
-                                                 "RX DMA page map failed\n");
-                                               adapter->rx_dma_failed++;
-                                               goto no_buffers;
-                                       }
+                                       adapter->alloc_rx_buff_failed++;
+                                       goto no_buffers;
+                               }
+                               ps_page->dma = pci_map_page(pdev,
+                                                  ps_page->page,
+                                                  0, PAGE_SIZE,
+                                                  PCI_DMA_FROMDEVICE);
+                               if (pci_dma_mapping_error(ps_page->dma)) {
+                                       dev_err(&adapter->pdev->dev,
+                                         "RX DMA page map failed\n");
+                                       adapter->rx_dma_failed++;
+                                       goto no_buffers;
                                }
-                               /*
-                                * Refresh the desc even if buffer_addrs
-                                * didn't change because each write-back
-                                * erases this info.
-                                */
-                               rx_desc->read.buffer_addr[j+1] =
-                                    cpu_to_le64(ps_page->dma);
-                       } else {
-                               rx_desc->read.buffer_addr[j+1] = ~0;
                        }
+                       /*
+                        * Refresh the desc even if buffer_addrs
+                        * didn't change because each write-back
+                        * erases this info.
+                        */
+                       rx_desc->read.buffer_addr[j+1] =
+                            cpu_to_le64(ps_page->dma);
                }
 
                skb = netdev_alloc_skb(netdev,
@@ -334,94 +333,6 @@ no_buffers:
 }
 
 /**
- * e1000_alloc_rx_buffers_jumbo - Replace used jumbo receive buffers
- *
- * @adapter: address of board private structure
- * @cleaned_count: number of buffers to allocate this pass
- **/
-static void e1000_alloc_rx_buffers_jumbo(struct e1000_adapter *adapter,
-                                        int cleaned_count)
-{
-       struct net_device *netdev = adapter->netdev;
-       struct pci_dev *pdev = adapter->pdev;
-       struct e1000_ring *rx_ring = adapter->rx_ring;
-       struct e1000_rx_desc *rx_desc;
-       struct e1000_buffer *buffer_info;
-       struct sk_buff *skb;
-       unsigned int i;
-       unsigned int bufsz = 256 -
-                            16 /*for skb_reserve */ -
-                            NET_IP_ALIGN;
-
-       i = rx_ring->next_to_use;
-       buffer_info = &rx_ring->buffer_info[i];
-
-       while (cleaned_count--) {
-               skb = buffer_info->skb;
-               if (skb) {
-                       skb_trim(skb, 0);
-                       goto check_page;
-               }
-
-               skb = netdev_alloc_skb(netdev, bufsz);
-               if (!skb) {
-                       /* Better luck next round */
-                       adapter->alloc_rx_buff_failed++;
-                       break;
-               }
-
-               /* Make buffer alignment 2 beyond a 16 byte boundary
-                * this will result in a 16 byte aligned IP header after
-                * the 14 byte MAC header is removed
-                */
-               skb_reserve(skb, NET_IP_ALIGN);
-
-               buffer_info->skb = skb;
-check_page:
-               /* allocate a new page if necessary */
-               if (!buffer_info->page) {
-                       buffer_info->page = alloc_page(GFP_ATOMIC);
-                       if (!buffer_info->page) {
-                               adapter->alloc_rx_buff_failed++;
-                               break;
-                       }
-               }
-
-               if (!buffer_info->dma)
-                       buffer_info->dma = pci_map_page(pdev,
-                                                       buffer_info->page, 0,
-                                                       PAGE_SIZE,
-                                                       PCI_DMA_FROMDEVICE);
-               if (pci_dma_mapping_error(buffer_info->dma)) {
-                       dev_err(&adapter->pdev->dev, "RX DMA page map failed\n");
-                       adapter->rx_dma_failed++;
-                       break;
-               }
-
-               rx_desc = E1000_RX_DESC(*rx_ring, i);
-               rx_desc->buffer_addr = cpu_to_le64(buffer_info->dma);
-
-               i++;
-               if (i == rx_ring->count)
-                       i = 0;
-               buffer_info = &rx_ring->buffer_info[i];
-       }
-
-       if (rx_ring->next_to_use != i) {
-               rx_ring->next_to_use = i;
-               if (i-- == 0)
-                       i = (rx_ring->count - 1);
-
-               /* Force memory writes to complete before letting h/w
-                * know there are new descriptors to fetch.  (Only
-                * applicable for weak-ordered memory model archs,
-                * such as IA-64). */
-               wmb();
-               writel(i, adapter->hw.hw_addr + rx_ring->tail);
-       }
-}
-
-/**
  * e1000_clean_rx_irq - Send received data up the network stack; legacy
  * @adapter: board private structure
  *
@@ -495,10 +406,6 @@ static bool e1000_clean_rx_irq(struct e1000_adapter *adapter,
                        goto next_desc;
                }
 
-               /* adjust length to remove Ethernet CRC */
-               length -= 4;
-
-               /* probably a little skewed due to removing CRC */
                total_rx_bytes += length;
                total_rx_packets++;
 
@@ -554,15 +461,6 @@ next_desc:
        return cleaned;
 }
 
-static void e1000_consume_page(struct e1000_buffer *bi, struct sk_buff *skb,
-                              u16 length)
-{
-       bi->page = NULL;
-       skb->len += length;
-       skb->data_len += length;
-       skb->truesize += length;
-}
-
 static void e1000_put_txbuf(struct e1000_adapter *adapter,
                             struct e1000_buffer *buffer_info)
 {
@@ -699,174 +597,6 @@ static bool e1000_clean_tx_irq(struct e1000_adapter *adapter)
 }
 
 /**
- * e1000_clean_rx_irq_jumbo - Send received data up the network stack; legacy
- * @adapter: board private structure
- *
- * the return value indicates whether actual cleaning was done, there
- * is no guarantee that everything was cleaned
- **/
-static bool e1000_clean_rx_irq_jumbo(struct e1000_adapter *adapter,
-                                    int *work_done, int work_to_do)
-{
-       struct net_device *netdev = adapter->netdev;
-       struct pci_dev *pdev = adapter->pdev;
-       struct e1000_ring *rx_ring = adapter->rx_ring;
-       struct e1000_rx_desc *rx_desc, *next_rxd;
-       struct e1000_buffer *buffer_info, *next_buffer;
-       u32 length;
-       unsigned int i;
-       int cleaned_count = 0;
-       bool cleaned = 0;
-       unsigned int total_rx_bytes = 0, total_rx_packets = 0;
-
-       i = rx_ring->next_to_clean;
-       rx_desc = E1000_RX_DESC(*rx_ring, i);
-       buffer_info = &rx_ring->buffer_info[i];
-
-       while (rx_desc->status & E1000_RXD_STAT_DD) {
-               struct sk_buff *skb;
-               u8 status;
-
-               if (*work_done >= work_to_do)
-                       break;
-               (*work_done)++;
-
-               status = rx_desc->status;
-               skb = buffer_info->skb;
-               buffer_info->skb = NULL;
-
-               i++;
-               if (i == rx_ring->count)
-                       i = 0;
-               next_rxd = E1000_RX_DESC(*rx_ring, i);
-               prefetch(next_rxd);
-
-               next_buffer = &rx_ring->buffer_info[i];
-
-               cleaned = 1;
-               cleaned_count++;
-               pci_unmap_page(pdev,
-                              buffer_info->dma,
-                              PAGE_SIZE,
-                              PCI_DMA_FROMDEVICE);
-               buffer_info->dma = 0;
-
-               length = le16_to_cpu(rx_desc->length);
-
-               /* errors is only valid for DD + EOP descriptors */
-               if ((status & E1000_RXD_STAT_EOP) &&
-                   (rx_desc->errors & E1000_RXD_ERR_FRAME_ERR_MASK)) {
-                       /* recycle both page and skb */
-                       buffer_info->skb = skb;
-                       /* an error means any chain goes out the window too */
-                       if (rx_ring->rx_skb_top)
-                               dev_kfree_skb(rx_ring->rx_skb_top);
-                       rx_ring->rx_skb_top = NULL;
-                       goto next_desc;
-               }
-
-#define rxtop rx_ring->rx_skb_top
-               if (!(status & E1000_RXD_STAT_EOP)) {
-                       /* this descriptor is only the beginning (or middle) */
-                       if (!rxtop) {
-                               /* this is the beginning of a chain */
-                               rxtop = skb;
-                               skb_fill_page_desc(rxtop, 0, buffer_info->page,
-                                                  0, length);
-                       } else {
-                               /* this is the middle of a chain */
-                               skb_fill_page_desc(rxtop,
-                                                  skb_shinfo(rxtop)->nr_frags,
-                                                  buffer_info->page, 0,
-                                                  length);
-                               /* re-use the skb, only consumed the page */
-                               buffer_info->skb = skb;
-                       }
-                       e1000_consume_page(buffer_info, rxtop, length);
-                       goto next_desc;
-               } else {
-                       if (rxtop) {
-                               /* end of the chain */
-                               skb_fill_page_desc(rxtop,
-                                   skb_shinfo(rxtop)->nr_frags,
-                                   buffer_info->page, 0, length);
-                               /* re-use the current skb, we only consumed the
-                                * page */
-                               buffer_info->skb = skb;
-                               skb = rxtop;
-                               rxtop = NULL;
-                               e1000_consume_page(buffer_info, skb, length);
-                       } else {
-                               /* no chain, got EOP, this buf is the packet
-                                * copybreak to save the put_page/alloc_page */
-                               if (length <= copybreak &&
-                                   skb_tailroom(skb) >= length) {
-                                       u8 *vaddr;
-                                       vaddr = kmap_atomic(buffer_info->page,
-                                                          KM_SKB_DATA_SOFTIRQ);
-                                       memcpy(skb_tail_pointer(skb),
-                                              vaddr, length);
-                                       kunmap_atomic(vaddr,
-                                                     KM_SKB_DATA_SOFTIRQ);
-                                       /* re-use the page, so don't erase
-                                        * buffer_info->page */
-                                       skb_put(skb, length);
-                               } else {
-                                       skb_fill_page_desc(skb, 0,
-                                                          buffer_info->page, 0,
-                                                          length);
-                                       e1000_consume_page(buffer_info, skb,
-                                                          length);
-                               }
-                       }
-               }
-
-               /* Receive Checksum Offload XXX recompute due to CRC strip? */
-               e1000_rx_checksum(adapter,
-                                 (u32)(status) |
-                                 ((u32)(rx_desc->errors) << 24),
-                                 le16_to_cpu(rx_desc->csum), skb);
-
-               pskb_trim(skb, skb->len - 4);
-
-               /* probably a little skewed due to removing CRC */
-               total_rx_bytes += skb->len;
-               total_rx_packets++;
-
-               /* eth type trans needs skb->data to point to something */
-               if (!pskb_may_pull(skb, ETH_HLEN)) {
-                       ndev_err(netdev, "__pskb_pull_tail failed.\n");
-                       dev_kfree_skb(skb);
-                       goto next_desc;
-               }
-
-               e1000_receive_skb(adapter, netdev, skb,status,rx_desc->special);
-
-next_desc:
-               rx_desc->status = 0;
-
-               /* return some buffers to hardware, one at a time is too slow */
-               if (cleaned_count >= E1000_RX_BUFFER_WRITE) {
-                       adapter->alloc_rx_buf(adapter, cleaned_count);
-                       cleaned_count = 0;
-               }
-
-               /* use prefetched values */
-               rx_desc = next_rxd;
-               buffer_info = next_buffer;
-       }
-       rx_ring->next_to_clean = i;
-
-       cleaned_count = e1000_desc_unused(rx_ring);
-       if (cleaned_count)
-               adapter->alloc_rx_buf(adapter, cleaned_count);
-
-       adapter->total_rx_packets += total_rx_packets;
-       adapter->total_rx_bytes += total_rx_bytes;
-       return cleaned;
-}
-
-/**
  * e1000_clean_rx_irq_ps - Send received data up the network stack; packet split
  * @adapter: board private structure
  *
@@ -953,7 +683,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                    ((length + l1) <= adapter->rx_ps_bsize0)) {
                        u8 *vaddr;
 
-                       ps_page = &rx_ring->ps_pages[i * PS_PAGE_BUFFERS];
+                       ps_page = &buffer_info->ps_pages[0];
 
                        /* there is no documentation about how to call
                         * kmap_atomic, so we can't hold the mapping
@@ -965,8 +695,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                        kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
                        pci_dma_sync_single_for_device(pdev, ps_page->dma,
                                PAGE_SIZE, PCI_DMA_FROMDEVICE);
-                       /* remove the CRC */
-                       l1 -= 4;
+
                        skb_put(skb, l1);
                        goto copydone;
                } /* if */
@@ -977,7 +706,7 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                        if (!length)
                                break;
 
-                       ps_page = &rx_ring->ps_pages[(i * PS_PAGE_BUFFERS) + j];
+                       ps_page = &buffer_info->ps_pages[j];
                        pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE,
                                       PCI_DMA_FROMDEVICE);
                        ps_page->dma = 0;
@@ -988,10 +717,6 @@ static bool e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
                        skb->truesize += length;
                }
 
-               /* strip the ethernet crc, problem is we're using pages now so
-                * this whole operation can get a little cpu intensive */
-               pskb_trim(skb, skb->len - 4);
-
 copydone:
                total_rx_bytes += skb->len;
                total_rx_packets++;
@@ -1043,7 +768,6 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
        struct e1000_buffer *buffer_info;
        struct e1000_ps_page *ps_page;
        struct pci_dev *pdev = adapter->pdev;
-       unsigned long size;
        unsigned int i, j;
 
        /* Free all the Rx ring sk_buffs */
@@ -1054,9 +778,6 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
                                pci_unmap_single(pdev, buffer_info->dma,
                                                 adapter->rx_buffer_len,
                                                 PCI_DMA_FROMDEVICE);
-                       else if (adapter->clean_rx == e1000_clean_rx_irq_jumbo)
-                               pci_unmap_page(pdev, buffer_info->dma,
-                                              PAGE_SIZE, PCI_DMA_FROMDEVICE);
                        else if (adapter->clean_rx == e1000_clean_rx_irq_ps)
                                pci_unmap_single(pdev, buffer_info->dma,
                                                 adapter->rx_ps_bsize0,
@@ -1064,19 +785,13 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
                        buffer_info->dma = 0;
                }
 
-               if (buffer_info->page) {
-                       put_page(buffer_info->page);
-                       buffer_info->page = NULL;
-               }
-
                if (buffer_info->skb) {
                        dev_kfree_skb(buffer_info->skb);
                        buffer_info->skb = NULL;
                }
 
                for (j = 0; j < PS_PAGE_BUFFERS; j++) {
-                       ps_page = &rx_ring->ps_pages[(i * PS_PAGE_BUFFERS)
-                                                    + j];
+                       ps_page = &buffer_info->ps_pages[j];
                        if (!ps_page->page)
                                break;
                        pci_unmap_page(pdev, ps_page->dma, PAGE_SIZE,
@@ -1093,12 +808,6 @@ static void e1000_clean_rx_ring(struct e1000_adapter *adapter)
                rx_ring->rx_skb_top = NULL;
        }
 
-       size = sizeof(struct e1000_buffer) * rx_ring->count;
-       memset(rx_ring->buffer_info, 0, size);
-       size = sizeof(struct e1000_ps_page)
-              * (rx_ring->count * PS_PAGE_BUFFERS);
-       memset(rx_ring->ps_pages, 0, size);
-
        /* Zero out the descriptor ring */
        memset(rx_ring->desc, 0, rx_ring->size);
 
@@ -1421,7 +1130,8 @@ err:
 int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
 {
        struct e1000_ring *rx_ring = adapter->rx_ring;
-       int size, desc_len, err = -ENOMEM;
+       struct e1000_buffer *buffer_info;
+       int i, size, desc_len, err = -ENOMEM;
 
        size = sizeof(struct e1000_buffer) * rx_ring->count;
        rx_ring->buffer_info = vmalloc(size);
@@ -1429,11 +1139,14 @@ int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
                goto err;
        memset(rx_ring->buffer_info, 0, size);
 
-       rx_ring->ps_pages = kcalloc(rx_ring->count * PS_PAGE_BUFFERS,
-                                   sizeof(struct e1000_ps_page),
-                                   GFP_KERNEL);
-       if (!rx_ring->ps_pages)
-               goto err;
+       for (i = 0; i < rx_ring->count; i++) {
+               buffer_info = &rx_ring->buffer_info[i];
+               buffer_info->ps_pages = kcalloc(PS_PAGE_BUFFERS,
+                                               sizeof(struct e1000_ps_page),
+                                               GFP_KERNEL);
+               if (!buffer_info->ps_pages)
+                       goto err_pages;
+       }
 
        desc_len = sizeof(union e1000_rx_desc_packet_split);
 
@@ -1443,16 +1156,21 @@ int e1000e_setup_rx_resources(struct e1000_adapter *adapter)
 
        err = e1000_alloc_ring_dma(adapter, rx_ring);
        if (err)
-               goto err;
+               goto err_pages;
 
        rx_ring->next_to_clean = 0;
        rx_ring->next_to_use = 0;
        rx_ring->rx_skb_top = NULL;
 
        return 0;
+
+err_pages:
+       for (i = 0; i < rx_ring->count; i++) {
+               buffer_info = &rx_ring->buffer_info[i];
+               kfree(buffer_info->ps_pages);
+       }
 err:
        vfree(rx_ring->buffer_info);
-       kfree(rx_ring->ps_pages);
        ndev_err(adapter->netdev,
        "Unable to allocate memory for the transmit descriptor ring\n");
        return err;
@@ -1518,15 +1236,17 @@ void e1000e_free_rx_resources(struct e1000_adapter *adapter)
 {
        struct pci_dev *pdev = adapter->pdev;
        struct e1000_ring *rx_ring = adapter->rx_ring;
+       int i;
 
        e1000_clean_rx_ring(adapter);
 
+       for (i = 0; i < rx_ring->count; i++) {
+               kfree(rx_ring->buffer_info[i].ps_pages);
+       }
+
        vfree(rx_ring->buffer_info);
        rx_ring->buffer_info = NULL;
 
-       kfree(rx_ring->ps_pages);
-       rx_ring->ps_pages = NULL;
-
        dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
                          rx_ring->dma);
        rx_ring->desc = NULL;
@@ -2032,9 +1752,11 @@ static void e1000_setup_rctl(struct e1000_adapter *adapter)
 
                ew32(RFCTL, rfctl);
 
-               /* disable the stripping of CRC because it breaks
-                * BMC firmware connected over SMBUS */
-               rctl |= E1000_RCTL_DTYP_PS /* | E1000_RCTL_SECRC */;
+               /* Enable Packet split descriptors */
+               rctl |= E1000_RCTL_DTYP_PS;
+               
+               /* Enable hardware CRC frame stripping */
+               rctl |= E1000_RCTL_SECRC;
 
                psrctl |= adapter->rx_ps_bsize0 >>
                        E1000_PSRCTL_BSIZE0_SHIFT;
@@ -2077,11 +1799,6 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
                        sizeof(union e1000_rx_desc_packet_split);
                adapter->clean_rx = e1000_clean_rx_irq_ps;
                adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
-       } else if (adapter->netdev->mtu > ETH_FRAME_LEN + VLAN_HLEN + 4) {
-               rdlen = rx_ring->count *
-                       sizeof(struct e1000_rx_desc);
-               adapter->clean_rx = e1000_clean_rx_irq_jumbo;
-               adapter->alloc_rx_buf = e1000_alloc_rx_buffers_jumbo;
        } else {
                rdlen = rx_ring->count *
                        sizeof(struct e1000_rx_desc);
@@ -2326,8 +2043,11 @@ void e1000e_reset(struct e1000_adapter *adapter)
        struct e1000_mac_info *mac = &adapter->hw.mac;
        struct e1000_hw *hw = &adapter->hw;
        u32 tx_space, min_tx_space, min_rx_space;
+       u32 pba;
        u16 hwm;
 
+       ew32(PBA, adapter->pba);
+
        if (mac->max_frame_size > ETH_FRAME_LEN + ETH_FCS_LEN ) {
                /* To maintain wire speed transmits, the Tx FIFO should be
                 * large enough to accommodate two full transmit packets,
@@ -2335,11 +2055,11 @@ void e1000e_reset(struct e1000_adapter *adapter)
                 * the Rx FIFO should be large enough to accommodate at least
                 * one full receive packet and is similarly rounded up and
                 * expressed in KB. */
-               adapter->pba = er32(PBA);
+               pba = er32(PBA);
                /* upper 16 bits has Tx packet buffer allocation size in KB */
-               tx_space = adapter->pba >> 16;
+               tx_space = pba >> 16;
                /* lower 16 bits has Rx packet buffer allocation size in KB */
-               adapter->pba &= 0xffff;
+               pba &= 0xffff;
                /* the tx fifo also stores 16 bytes of information about the tx
                 * but don't include ethernet FCS because hardware appends it */
                min_tx_space = (mac->max_frame_size +
@@ -2355,20 +2075,21 @@ void e1000e_reset(struct e1000_adapter *adapter)
                /* If current Tx allocation is less than the min Tx FIFO size,
                 * and the min Tx FIFO size is less than the current Rx FIFO
                 * allocation, take space away from current Rx allocation */
-               if (tx_space < min_tx_space &&
-                   ((min_tx_space - tx_space) < adapter->pba)) {
-                       adapter->pba -= - (min_tx_space - tx_space);
+               if ((tx_space < min_tx_space) &&
+                   ((min_tx_space - tx_space) < pba)) {
+                       pba -= min_tx_space - tx_space;
 
                        /* if short on rx space, rx wins and must trump tx
                         * adjustment or use Early Receive if available */
-                       if ((adapter->pba < min_rx_space) &&
+                       if ((pba < min_rx_space) &&
                            (!(adapter->flags & FLAG_HAS_ERT)))
                                /* ERT enabled in e1000_configure_rx */
-                               adapter->pba = min_rx_space;
+                               pba = min_rx_space;
                }
+
+               ew32(PBA, pba);
        }
 
-       ew32(PBA, adapter->pba);
 
        /* flow control settings */
        /* The high water mark must be low enough to fit one full frame
@@ -3624,9 +3345,7 @@ static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
        /* NOTE: netdev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN
         * means we reserve 2 more, this pushes us to allocate from the next
         * larger slab size.
-        * i.e. RXBUFFER_2048 --> size-4096 slab
-        *  however with the new *_jumbo* routines, jumbo receives will use
-        *  fragmented skbs */
+        * i.e. RXBUFFER_2048 --> size-4096 slab */
 
        if (max_frame <= 256)
                adapter->rx_buffer_len = 256;
index b557bb4..f78e5bf 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "ehea"
-#define DRV_VERSION    "EHEA_0078"
+#define DRV_VERSION    "EHEA_0080"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
index 2809c99..f0319f1 100644 (file)
@@ -33,6 +33,9 @@
 #include <linux/if.h>
 #include <linux/list.h>
 #include <linux/if_ether.h>
+#include <linux/notifier.h>
+#include <linux/reboot.h>
+
 #include <net/ip.h>
 
 #include "ehea.h"
@@ -2329,7 +2332,7 @@ static void port_napi_disable(struct ehea_port *port)
 {
        int i;
 
-       for (i = 0; i < port->num_def_qps; i++)
+       for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++)
                napi_disable(&port->port_res[i].napi);
 }
 
@@ -2337,7 +2340,7 @@ static void port_napi_enable(struct ehea_port *port)
 {
        int i;
 
-       for (i = 0; i < port->num_def_qps; i++)
+       for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++)
                napi_enable(&port->port_res[i].napi);
 }
 
@@ -2373,8 +2376,6 @@ static int ehea_down(struct net_device *dev)
        ehea_drop_multicast_list(dev);
        ehea_free_interrupts(dev);
 
-       port_napi_disable(port);
-
        port->state = EHEA_PORT_DOWN;
 
        ret = ehea_clean_all_portres(port);
@@ -2396,6 +2397,7 @@ static int ehea_stop(struct net_device *dev)
        flush_scheduled_work();
        down(&port->port_lock);
        netif_stop_queue(dev);
+       port_napi_disable(port);
        ret = ehea_down(dev);
        up(&port->port_lock);
        return ret;
@@ -3296,6 +3298,20 @@ static int __devexit ehea_remove(struct of_device *dev)
        return 0;
 }
 
+static int ehea_reboot_notifier(struct notifier_block *nb,
+                               unsigned long action, void *unused)
+{
+       if (action == SYS_RESTART) {
+               ehea_info("Reboot: freeing all eHEA resources");
+               ibmebus_unregister_driver(&ehea_driver);
+       }
+       return NOTIFY_DONE;
+}
+
+static struct notifier_block ehea_reboot_nb = {
+        .notifier_call = ehea_reboot_notifier,
+};
+
 static int check_module_parm(void)
 {
        int ret = 0;
@@ -3352,6 +3368,8 @@ int __init ehea_module_init(void)
        if (ret)
                goto out;
 
+       register_reboot_notifier(&ehea_reboot_nb);
+
        ret = ibmebus_register_driver(&ehea_driver);
        if (ret) {
                ehea_error("failed registering eHEA device driver on ebus");
@@ -3363,6 +3381,7 @@ int __init ehea_module_init(void)
        if (ret) {
                ehea_error("failed to register capabilities attribute, ret=%d",
                           ret);
+               unregister_reboot_notifier(&ehea_reboot_nb);
                ibmebus_unregister_driver(&ehea_driver);
                goto out;
        }
@@ -3376,6 +3395,7 @@ static void __exit ehea_module_exit(void)
        flush_scheduled_work();
        driver_remove_file(&ehea_driver.driver, &driver_attr_capabilities);
        ibmebus_unregister_driver(&ehea_driver);
+       unregister_reboot_notifier(&ehea_reboot_nb);
        ehea_destroy_busmap();
 }
 
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
new file mode 100644 (file)
index 0000000..fc1cf0b
--- /dev/null
@@ -0,0 +1,1112 @@
+/*
+ * Driver for the MPC5200 Fast Ethernet Controller
+ *
+ * Originally written by Dale Farnsworth <dfarnsworth@mvista.com> and
+ * now maintained by Sylvain Munaut <tnt@246tNt.com>
+ *
+ * Copyright (C) 2007  Domen Puncer, Telargo, Inc.
+ * Copyright (C) 2007  Sylvain Munaut <tnt@246tNt.com>
+ * Copyright (C) 2003-2004  MontaVista, Software, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ *
+ */
+
+#include <linux/module.h>
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/spinlock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/crc32.h>
+#include <linux/hardirq.h>
+#include <linux/delay.h>
+#include <linux/of_device.h>
+#include <linux/of_platform.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/mpc52xx.h>
+
+#include <sysdev/bestcomm/bestcomm.h>
+#include <sysdev/bestcomm/fec.h>
+
+#include "fec_mpc52xx.h"
+
+#define DRIVER_NAME "mpc52xx-fec"
+
+static irqreturn_t mpc52xx_fec_interrupt(int, void *);
+static irqreturn_t mpc52xx_fec_rx_interrupt(int, void *);
+static irqreturn_t mpc52xx_fec_tx_interrupt(int, void *);
+static void mpc52xx_fec_stop(struct net_device *dev);
+static void mpc52xx_fec_start(struct net_device *dev);
+static void mpc52xx_fec_reset(struct net_device *dev);
+
+static u8 mpc52xx_fec_mac_addr[6];
+module_param_array_named(mac, mpc52xx_fec_mac_addr, byte, NULL, 0);
+MODULE_PARM_DESC(mac, "six hex digits, ie. 0x1,0x2,0xc0,0x01,0xba,0xbe");
+
+#define MPC52xx_MESSAGES_DEFAULT ( NETIF_MSG_DRV | NETIF_MSG_PROBE | \
+               NETIF_MSG_LINK | NETIF_MSG_IFDOWN | NETIF_MSG_IFDOWN )
+static int debug = -1; /* the above default */
+module_param(debug, int, 0);
+MODULE_PARM_DESC(debug, "debugging messages level");
+
+static void mpc52xx_fec_tx_timeout(struct net_device *dev)
+{
+       dev_warn(&dev->dev, "transmit timed out\n");
+
+       mpc52xx_fec_reset(dev);
+
+       dev->stats.tx_errors++;
+
+       netif_wake_queue(dev);
+}
+
+static void mpc52xx_fec_set_paddr(struct net_device *dev, u8 *mac)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+
+       out_be32(&fec->paddr1, *(u32 *)(&mac[0]));
+       out_be32(&fec->paddr2, (*(u16 *)(&mac[4]) << 16) | FEC_PADDR2_TYPE);
+}
+
+static void mpc52xx_fec_get_paddr(struct net_device *dev, u8 *mac)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+
+       *(u32 *)(&mac[0]) = in_be32(&fec->paddr1);
+       *(u16 *)(&mac[4]) = in_be32(&fec->paddr2) >> 16;
+}
+
+static int mpc52xx_fec_set_mac_address(struct net_device *dev, void *addr)
+{
+       struct sockaddr *sock = addr;
+
+       memcpy(dev->dev_addr, sock->sa_data, dev->addr_len);
+
+       mpc52xx_fec_set_paddr(dev, sock->sa_data);
+       return 0;
+}
+
+static void mpc52xx_fec_free_rx_buffers(struct net_device *dev, struct bcom_task *s)
+{
+       while (!bcom_queue_empty(s)) {
+               struct bcom_fec_bd *bd;
+               struct sk_buff *skb;
+
+               skb = bcom_retrieve_buffer(s, NULL, (struct bcom_bd **)&bd);
+               dma_unmap_single(&dev->dev, bd->skb_pa, skb->len, DMA_FROM_DEVICE);
+               kfree_skb(skb);
+       }
+}
+
+static int mpc52xx_fec_alloc_rx_buffers(struct net_device *dev, struct bcom_task *rxtsk)
+{
+       while (!bcom_queue_full(rxtsk)) {
+               struct sk_buff *skb;
+               struct bcom_fec_bd *bd;
+
+               skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
+               if (skb == NULL)
+                       return -EAGAIN;
+
+               /* zero out the initial receive buffers to aid debugging */
+               memset(skb->data, 0, FEC_RX_BUFFER_SIZE);
+
+               bd = (struct bcom_fec_bd *)bcom_prepare_next_buffer(rxtsk);
+
+               bd->status = FEC_RX_BUFFER_SIZE;
+               bd->skb_pa = dma_map_single(&dev->dev, skb->data,
+                               FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
+
+               bcom_submit_next_buffer(rxtsk, skb);
+       }
+
+       return 0;
+}
+
+/* based on generic_adjust_link from fs_enet-main.c */
+static void mpc52xx_fec_adjust_link(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct phy_device *phydev = priv->phydev;
+       int new_state = 0;
+
+       if (phydev->link != PHY_DOWN) {
+               if (phydev->duplex != priv->duplex) {
+                       struct mpc52xx_fec __iomem *fec = priv->fec;
+                       u32 rcntrl;
+                       u32 tcntrl;
+
+                       new_state = 1;
+                       priv->duplex = phydev->duplex;
+
+                       rcntrl = in_be32(&fec->r_cntrl);
+                       tcntrl = in_be32(&fec->x_cntrl);
+
+                       rcntrl &= ~FEC_RCNTRL_DRT;
+                       tcntrl &= ~FEC_TCNTRL_FDEN;
+                       if (phydev->duplex == DUPLEX_FULL)
+                               tcntrl |= FEC_TCNTRL_FDEN;      /* FD enable */
+                       else
+                               rcntrl |= FEC_RCNTRL_DRT;       /* disable Rx on Tx (HD) */
+
+                       out_be32(&fec->r_cntrl, rcntrl);
+                       out_be32(&fec->x_cntrl, tcntrl);
+               }
+
+               if (phydev->speed != priv->speed) {
+                       new_state = 1;
+                       priv->speed = phydev->speed;
+               }
+
+               if (priv->link == PHY_DOWN) {
+                       new_state = 1;
+                       priv->link = phydev->link;
+                       netif_schedule(dev);
+                       netif_carrier_on(dev);
+                       netif_start_queue(dev);
+               }
+
+       } else if (priv->link) {
+               new_state = 1;
+               priv->link = PHY_DOWN;
+               priv->speed = 0;
+               priv->duplex = -1;
+               netif_stop_queue(dev);
+               netif_carrier_off(dev);
+       }
+
+       if (new_state && netif_msg_link(priv))
+               phy_print_status(phydev);
+}
+
+static int mpc52xx_fec_init_phy(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct phy_device *phydev;
+       char phy_id[BUS_ID_SIZE];
+
+       snprintf(phy_id, BUS_ID_SIZE, PHY_ID_FMT,
+                       (unsigned int)dev->base_addr, priv->phy_addr);
+
+       priv->link = PHY_DOWN;
+       priv->speed = 0;
+       priv->duplex = -1;
+
+       phydev = phy_connect(dev, phy_id, &mpc52xx_fec_adjust_link, 0, PHY_INTERFACE_MODE_MII);
+       if (IS_ERR(phydev)) {
+               dev_err(&dev->dev, "phy_connect failed\n");
+               return PTR_ERR(phydev);
+       }
+       dev_info(&dev->dev, "attached phy %i to driver %s\n",
+                       phydev->addr, phydev->drv->name);
+
+       priv->phydev = phydev;
+
+       return 0;
+}
+
+static int mpc52xx_fec_phy_start(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       int err;
+
+       if (!priv->has_phy)
+               return 0;
+
+       err = mpc52xx_fec_init_phy(dev);
+       if (err) {
+               dev_err(&dev->dev, "mpc52xx_fec_init_phy failed\n");
+               return err;
+       }
+
+       /* reset phy - this also wakes it from PDOWN */
+       phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
+       phy_start(priv->phydev);
+
+       return 0;
+}
+
+static void mpc52xx_fec_phy_stop(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+
+       if (!priv->has_phy)
+               return;
+
+       phy_disconnect(priv->phydev);
+       /* power down phy */
+       phy_stop(priv->phydev);
+       phy_write(priv->phydev, MII_BMCR, BMCR_PDOWN);
+}
+
+static int mpc52xx_fec_phy_mii_ioctl(struct mpc52xx_fec_priv *priv,
+               struct mii_ioctl_data *mii_data, int cmd)
+{
+       if (!priv->has_phy)
+               return -ENOTSUPP;
+
+       return phy_mii_ioctl(priv->phydev, mii_data, cmd);
+}
+
+static void mpc52xx_fec_phy_hw_init(struct mpc52xx_fec_priv *priv)
+{
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+
+       if (!priv->has_phy)
+               return;
+
+       out_be32(&fec->mii_speed, priv->phy_speed);
+}
+
+static int mpc52xx_fec_open(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       int err = -EBUSY;
+
+       if (request_irq(dev->irq, &mpc52xx_fec_interrupt, IRQF_SHARED,
+                       DRIVER_NAME "_ctrl", dev)) {
+               dev_err(&dev->dev, "ctrl interrupt request failed\n");
+               goto out;
+       }
+       if (request_irq(priv->r_irq, &mpc52xx_fec_rx_interrupt, 0,
+                       DRIVER_NAME "_rx", dev)) {
+               dev_err(&dev->dev, "rx interrupt request failed\n");
+               goto free_ctrl_irq;
+       }
+       if (request_irq(priv->t_irq, &mpc52xx_fec_tx_interrupt, 0,
+                       DRIVER_NAME "_tx", dev)) {
+               dev_err(&dev->dev, "tx interrupt request failed\n");
+               goto free_2irqs;
+       }
+
+       bcom_fec_rx_reset(priv->rx_dmatsk);
+       bcom_fec_tx_reset(priv->tx_dmatsk);
+
+       err = mpc52xx_fec_alloc_rx_buffers(dev, priv->rx_dmatsk);
+       if (err) {
+               dev_err(&dev->dev, "mpc52xx_fec_alloc_rx_buffers failed\n");
+               goto free_irqs;
+       }
+
+       err = mpc52xx_fec_phy_start(dev);
+       if (err)
+               goto free_skbs;
+
+       bcom_enable(priv->rx_dmatsk);
+       bcom_enable(priv->tx_dmatsk);
+
+       mpc52xx_fec_start(dev);
+
+       netif_start_queue(dev);
+
+       return 0;
+
+ free_skbs:
+       mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk);
+
+ free_irqs:
+       free_irq(priv->t_irq, dev);
+ free_2irqs:
+       free_irq(priv->r_irq, dev);
+ free_ctrl_irq:
+       free_irq(dev->irq, dev);
+ out:
+
+       return err;
+}
+
+static int mpc52xx_fec_close(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+
+       netif_stop_queue(dev);
+
+       mpc52xx_fec_stop(dev);
+
+       mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk);
+
+       free_irq(dev->irq, dev);
+       free_irq(priv->r_irq, dev);
+       free_irq(priv->t_irq, dev);
+
+       mpc52xx_fec_phy_stop(dev);
+
+       return 0;
+}
+
+/* This will only be invoked if your driver is _not_ in XOFF state.
+ * What this means is that you need not check it, and that this
+ * invariant will hold if you make sure that the netif_*_queue()
+ * calls are done at the proper times.
+ */
+static int mpc52xx_fec_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct bcom_fec_bd *bd;
+
+       if (bcom_queue_full(priv->tx_dmatsk)) {
+               if (net_ratelimit())
+                       dev_err(&dev->dev, "transmit queue overrun\n");
+               return 1;
+       }
+
+       spin_lock_irq(&priv->lock);
+       dev->trans_start = jiffies;
+
+       bd = (struct bcom_fec_bd *)
+               bcom_prepare_next_buffer(priv->tx_dmatsk);
+
+       bd->status = skb->len | BCOM_FEC_TX_BD_TFD | BCOM_FEC_TX_BD_TC;
+       bd->skb_pa = dma_map_single(&dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
+
+       bcom_submit_next_buffer(priv->tx_dmatsk, skb);
+
+       if (bcom_queue_full(priv->tx_dmatsk)) {
+               netif_stop_queue(dev);
+       }
+
+       spin_unlock_irq(&priv->lock);
+
+       return 0;
+}
+
+/* This handles BestComm transmit task interrupts
+ */
+static irqreturn_t mpc52xx_fec_tx_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+
+       spin_lock(&priv->lock);
+
+       while (bcom_buffer_done(priv->tx_dmatsk)) {
+               struct sk_buff *skb;
+               struct bcom_fec_bd *bd;
+               skb = bcom_retrieve_buffer(priv->tx_dmatsk, NULL,
+                               (struct bcom_bd **)&bd);
+               dma_unmap_single(&dev->dev, bd->skb_pa, skb->len, DMA_TO_DEVICE);
+
+               dev_kfree_skb_irq(skb);
+       }
+
+       netif_wake_queue(dev);
+
+       spin_unlock(&priv->lock);
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t mpc52xx_fec_rx_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+
+       while (bcom_buffer_done(priv->rx_dmatsk)) {
+               struct sk_buff *skb;
+               struct sk_buff *rskb;
+               struct bcom_fec_bd *bd;
+               u32 status;
+
+               rskb = bcom_retrieve_buffer(priv->rx_dmatsk, &status,
+                               (struct bcom_bd **)&bd);
+               dma_unmap_single(&dev->dev, bd->skb_pa, skb->len, DMA_FROM_DEVICE);
+
+               /* Test for errors in received frame */
+               if (status & BCOM_FEC_RX_BD_ERRORS) {
+                       /* Drop packet and reuse the buffer */
+                       bd = (struct bcom_fec_bd *)
+                               bcom_prepare_next_buffer(priv->rx_dmatsk);
+
+                       bd->status = FEC_RX_BUFFER_SIZE;
+                       bd->skb_pa = dma_map_single(&dev->dev, rskb->data,
+                                       FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
+
+                       bcom_submit_next_buffer(priv->rx_dmatsk, rskb);
+
+                       dev->stats.rx_dropped++;
+
+                       continue;
+               }
+
+               /* skbs are allocated on open, so now we allocate a new one,
+                * and remove the old (with the packet) */
+               skb = dev_alloc_skb(FEC_RX_BUFFER_SIZE);
+               if (skb) {
+                       /* Process the received skb */
+                       int length = status & BCOM_FEC_RX_BD_LEN_MASK;
+
+                       skb_put(rskb, length - 4);      /* length without CRC32 */
+
+                       rskb->dev = dev;
+                       rskb->protocol = eth_type_trans(rskb, dev);
+
+                       netif_rx(rskb);
+                       dev->last_rx = jiffies;
+               } else {
+                       /* Can't get a new one : reuse the same & drop pkt */
+                       dev_notice(&dev->dev, "Memory squeeze, dropping packet.\n");
+                       dev->stats.rx_dropped++;
+
+                       skb = rskb;
+               }
+
+               bd = (struct bcom_fec_bd *)
+                       bcom_prepare_next_buffer(priv->rx_dmatsk);
+
+               bd->status = FEC_RX_BUFFER_SIZE;
+               bd->skb_pa = dma_map_single(&dev->dev, rskb->data,
+                               FEC_RX_BUFFER_SIZE, DMA_FROM_DEVICE);
+
+               bcom_submit_next_buffer(priv->rx_dmatsk, skb);
+       }
+
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t mpc52xx_fec_interrupt(int irq, void *dev_id)
+{
+       struct net_device *dev = dev_id;
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+       u32 ievent;
+
+       ievent = in_be32(&fec->ievent);
+
+       ievent &= ~FEC_IEVENT_MII;      /* mii is handled separately */
+       if (!ievent)
+               return IRQ_NONE;
+
+       out_be32(&fec->ievent, ievent);         /* clear pending events */
+
+       if (ievent & ~(FEC_IEVENT_RFIFO_ERROR | FEC_IEVENT_XFIFO_ERROR)) {
+               if (ievent & ~FEC_IEVENT_TFINT)
+                       dev_dbg(&dev->dev, "ievent: %08x\n", ievent);
+               return IRQ_HANDLED;
+       }
+
+       if (net_ratelimit() && (ievent & FEC_IEVENT_RFIFO_ERROR))
+               dev_warn(&dev->dev, "FEC_IEVENT_RFIFO_ERROR\n");
+       if (net_ratelimit() && (ievent & FEC_IEVENT_XFIFO_ERROR))
+               dev_warn(&dev->dev, "FEC_IEVENT_XFIFO_ERROR\n");
+
+       mpc52xx_fec_reset(dev);
+
+       netif_wake_queue(dev);
+       return IRQ_HANDLED;
+}
+
+/*
+ * Get the current statistics.
+ * This may be called with the card open or closed.
+ */
+static struct net_device_stats *mpc52xx_fec_get_stats(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct net_device_stats *stats = &dev->stats;
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+
+       stats->rx_bytes = in_be32(&fec->rmon_r_octets);
+       stats->rx_packets = in_be32(&fec->rmon_r_packets);
+       stats->rx_errors = in_be32(&fec->rmon_r_crc_align) +
+               in_be32(&fec->rmon_r_undersize) +
+               in_be32(&fec->rmon_r_oversize) +
+               in_be32(&fec->rmon_r_frag) +
+               in_be32(&fec->rmon_r_jab);
+
+       stats->tx_bytes = in_be32(&fec->rmon_t_octets);
+       stats->tx_packets = in_be32(&fec->rmon_t_packets);
+       stats->tx_errors = in_be32(&fec->rmon_t_crc_align) +
+               in_be32(&fec->rmon_t_undersize) +
+               in_be32(&fec->rmon_t_oversize) +
+               in_be32(&fec->rmon_t_frag) +
+               in_be32(&fec->rmon_t_jab);
+
+       stats->multicast = in_be32(&fec->rmon_r_mc_pkt);
+       stats->collisions = in_be32(&fec->rmon_t_col);
+
+       /* detailed rx_errors: */
+       stats->rx_length_errors = in_be32(&fec->rmon_r_undersize)
+                                       + in_be32(&fec->rmon_r_oversize)
+                                       + in_be32(&fec->rmon_r_frag)
+                                       + in_be32(&fec->rmon_r_jab);
+       stats->rx_over_errors = in_be32(&fec->r_macerr);
+       stats->rx_crc_errors = in_be32(&fec->ieee_r_crc);
+       stats->rx_frame_errors = in_be32(&fec->ieee_r_align);
+       stats->rx_fifo_errors = in_be32(&fec->rmon_r_drop);
+       stats->rx_missed_errors = in_be32(&fec->rmon_r_drop);
+
+       /* detailed tx_errors: */
+       stats->tx_aborted_errors = 0;
+       stats->tx_carrier_errors = in_be32(&fec->ieee_t_cserr);
+       stats->tx_fifo_errors = in_be32(&fec->rmon_t_drop);
+       stats->tx_heartbeat_errors = in_be32(&fec->ieee_t_sqe);
+       stats->tx_window_errors = in_be32(&fec->ieee_t_lcol);
+
+       return stats;
+}
+
+/*
+ * Read MIB counters in order to reset them,
+ * then zero all the stats fields in memory
+ */
+static void mpc52xx_fec_reset_stats(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+
+       out_be32(&fec->mib_control, FEC_MIB_DISABLE);
+       memset_io(&fec->rmon_t_drop, 0, (__force u32)&fec->reserved10 -
+                       (__force u32)&fec->rmon_t_drop);
+       out_be32(&fec->mib_control, 0);
+
+       memset(&dev->stats, 0, sizeof(dev->stats));
+}
+
+/*
+ * Set or clear the multicast filter for this adaptor.
+ */
+static void mpc52xx_fec_set_multicast_list(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+       u32 rx_control;
+
+       rx_control = in_be32(&fec->r_cntrl);
+
+       if (dev->flags & IFF_PROMISC) {
+               rx_control |= FEC_RCNTRL_PROM;
+               out_be32(&fec->r_cntrl, rx_control);
+       } else {
+               rx_control &= ~FEC_RCNTRL_PROM;
+               out_be32(&fec->r_cntrl, rx_control);
+
+               if (dev->flags & IFF_ALLMULTI) {
+                       out_be32(&fec->gaddr1, 0xffffffff);
+                       out_be32(&fec->gaddr2, 0xffffffff);
+               } else {
+                       u32 crc;
+                       int i;
+                       struct dev_mc_list *dmi;
+                       u32 gaddr1 = 0x00000000;
+                       u32 gaddr2 = 0x00000000;
+
+                       dmi = dev->mc_list;
+                       for (i=0; i<dev->mc_count; i++) {
+                               crc = ether_crc_le(6, dmi->dmi_addr) >> 26;
+                               if (crc >= 32)
+                                       gaddr1 |= 1 << (crc-32);
+                               else
+                                       gaddr2 |= 1 << crc;
+                               dmi = dmi->next;
+                       }
+                       out_be32(&fec->gaddr1, gaddr1);
+                       out_be32(&fec->gaddr2, gaddr2);
+               }
+       }
+}
+
+/**
+ * mpc52xx_fec_hw_init
+ * @dev: network device
+ *
+ * Setup various hardware setting, only needed once on start
+ */
+static void mpc52xx_fec_hw_init(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+       int i;
+
+       /* Whack a reset.  We should wait for this. */
+       out_be32(&fec->ecntrl, FEC_ECNTRL_RESET);
+       for (i = 0; i < FEC_RESET_DELAY; ++i) {
+               if ((in_be32(&fec->ecntrl) & FEC_ECNTRL_RESET) == 0)
+                       break;
+               udelay(1);
+       }
+       if (i == FEC_RESET_DELAY)
+               dev_err(&dev->dev, "FEC Reset timeout!\n");
+
+       /* set pause to 0x20 frames */
+       out_be32(&fec->op_pause, FEC_OP_PAUSE_OPCODE | 0x20);
+
+       /* high service request will be deasserted when there's < 7 bytes in fifo
+        * low service request will be deasserted when there's < 4*7 bytes in fifo
+        */
+       out_be32(&fec->rfifo_cntrl, FEC_FIFO_CNTRL_FRAME | FEC_FIFO_CNTRL_LTG_7);
+       out_be32(&fec->tfifo_cntrl, FEC_FIFO_CNTRL_FRAME | FEC_FIFO_CNTRL_LTG_7);
+
+       /* alarm when <= x bytes in FIFO */
+       out_be32(&fec->rfifo_alarm, 0x0000030c);
+       out_be32(&fec->tfifo_alarm, 0x00000100);
+
+       /* begin transmittion when 256 bytes are in FIFO (or EOF or FIFO full) */
+       out_be32(&fec->x_wmrk, FEC_FIFO_WMRK_256B);
+
+       /* enable crc generation */
+       out_be32(&fec->xmit_fsm, FEC_XMIT_FSM_APPEND_CRC | FEC_XMIT_FSM_ENABLE_CRC);
+       out_be32(&fec->iaddr1, 0x00000000);     /* No individual filter */
+       out_be32(&fec->iaddr2, 0x00000000);     /* No individual filter */
+
+       /* set phy speed.
+        * this can't be done in phy driver, since it needs to be called
+        * before fec stuff (even on resume) */
+       mpc52xx_fec_phy_hw_init(priv);
+}
+
+/**
+ * mpc52xx_fec_start
+ * @dev: network device
+ *
+ * This function is called to start or restart the FEC during a link
+ * change.  This happens on fifo errors or when switching between half
+ * and full duplex.
+ */
+static void mpc52xx_fec_start(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+       u32 rcntrl;
+       u32 tcntrl;
+       u32 tmp;
+
+       /* clear sticky error bits */
+       tmp = FEC_FIFO_STATUS_ERR | FEC_FIFO_STATUS_UF | FEC_FIFO_STATUS_OF;
+       out_be32(&fec->rfifo_status, in_be32(&fec->rfifo_status) & tmp);
+       out_be32(&fec->tfifo_status, in_be32(&fec->tfifo_status) & tmp);
+
+       /* FIFOs will reset on mpc52xx_fec_enable */
+       out_be32(&fec->reset_cntrl, FEC_RESET_CNTRL_ENABLE_IS_RESET);
+
+       /* Set station address. */
+       mpc52xx_fec_set_paddr(dev, dev->dev_addr);
+
+       mpc52xx_fec_set_multicast_list(dev);
+
+       /* set max frame len, enable flow control, select mii mode */
+       rcntrl = FEC_RX_BUFFER_SIZE << 16;      /* max frame length */
+       rcntrl |= FEC_RCNTRL_FCE;
+
+       if (priv->has_phy)
+               rcntrl |= FEC_RCNTRL_MII_MODE;
+
+       if (priv->duplex == DUPLEX_FULL)
+               tcntrl = FEC_TCNTRL_FDEN;       /* FD enable */
+       else {
+               rcntrl |= FEC_RCNTRL_DRT;       /* disable Rx on Tx (HD) */
+               tcntrl = 0;
+       }
+       out_be32(&fec->r_cntrl, rcntrl);
+       out_be32(&fec->x_cntrl, tcntrl);
+
+       /* Clear any outstanding interrupt. */
+       out_be32(&fec->ievent, 0xffffffff);
+
+       /* Enable interrupts we wish to service. */
+       out_be32(&fec->imask, FEC_IMASK_ENABLE);
+
+       /* And last, enable the transmit and receive processing. */
+       out_be32(&fec->ecntrl, FEC_ECNTRL_ETHER_EN);
+       out_be32(&fec->r_des_active, 0x01000000);
+}
+
+/**
+ * mpc52xx_fec_stop
+ * @dev: network device
+ *
+ * stop all activity on fec and empty dma buffers
+ */
+static void mpc52xx_fec_stop(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+       unsigned long timeout;
+
+       /* disable all interrupts */
+       out_be32(&fec->imask, 0);
+
+       /* Disable the rx task. */
+       bcom_disable(priv->rx_dmatsk);
+
+       /* Wait for tx queue to drain, but only if we're in process context */
+       if (!in_interrupt()) {
+               timeout = jiffies + msecs_to_jiffies(2000);
+               while (time_before(jiffies, timeout) &&
+                               !bcom_queue_empty(priv->tx_dmatsk))
+                       msleep(100);
+
+               if (time_after_eq(jiffies, timeout))
+                       dev_err(&dev->dev, "queues didn't drain\n");
+#if 1
+               if (time_after_eq(jiffies, timeout)) {
+                       dev_err(&dev->dev, "  tx: index: %i, outdex: %i\n",
+                                       priv->tx_dmatsk->index,
+                                       priv->tx_dmatsk->outdex);
+                       dev_err(&dev->dev, "  rx: index: %i, outdex: %i\n",
+                                       priv->rx_dmatsk->index,
+                                       priv->rx_dmatsk->outdex);
+               }
+#endif
+       }
+
+       bcom_disable(priv->tx_dmatsk);
+
+       /* Stop FEC */
+       out_be32(&fec->ecntrl, in_be32(&fec->ecntrl) & ~FEC_ECNTRL_ETHER_EN);
+
+       return;
+}
+
+/* reset fec and bestcomm tasks */
+static void mpc52xx_fec_reset(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       struct mpc52xx_fec __iomem *fec = priv->fec;
+
+       mpc52xx_fec_stop(dev);
+
+       out_be32(&fec->rfifo_status, in_be32(&fec->rfifo_status));
+       out_be32(&fec->reset_cntrl, FEC_RESET_CNTRL_RESET_FIFO);
+
+       mpc52xx_fec_free_rx_buffers(dev, priv->rx_dmatsk);
+
+       mpc52xx_fec_hw_init(dev);
+
+       phy_stop(priv->phydev);
+       phy_write(priv->phydev, MII_BMCR, BMCR_RESET);
+       phy_start(priv->phydev);
+
+       bcom_fec_rx_reset(priv->rx_dmatsk);
+       bcom_fec_tx_reset(priv->tx_dmatsk);
+
+       mpc52xx_fec_alloc_rx_buffers(dev, priv->rx_dmatsk);
+
+       bcom_enable(priv->rx_dmatsk);
+       bcom_enable(priv->tx_dmatsk);
+
+       mpc52xx_fec_start(dev);
+}
+
+
+/* ethtool interface */
+static void mpc52xx_fec_get_drvinfo(struct net_device *dev,
+               struct ethtool_drvinfo *info)
+{
+       strcpy(info->driver, DRIVER_NAME);
+}
+
+static int mpc52xx_fec_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       return phy_ethtool_gset(priv->phydev, cmd);
+}
+
+static int mpc52xx_fec_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       return phy_ethtool_sset(priv->phydev, cmd);
+}
+
+static u32 mpc52xx_fec_get_msglevel(struct net_device *dev)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       return priv->msg_enable;
+}
+
+static void mpc52xx_fec_set_msglevel(struct net_device *dev, u32 level)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+       priv->msg_enable = level;
+}
+
+static const struct ethtool_ops mpc52xx_fec_ethtool_ops = {
+       .get_drvinfo = mpc52xx_fec_get_drvinfo,
+       .get_settings = mpc52xx_fec_get_settings,
+       .set_settings = mpc52xx_fec_set_settings,
+       .get_link = ethtool_op_get_link,
+       .get_msglevel = mpc52xx_fec_get_msglevel,
+       .set_msglevel = mpc52xx_fec_set_msglevel,
+};
+
+
+static int mpc52xx_fec_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+       struct mpc52xx_fec_priv *priv = netdev_priv(dev);
+
+       return mpc52xx_fec_phy_mii_ioctl(priv, if_mii(rq), cmd);
+}
+
+/* ======================================================================== */
+/* OF Driver                                                                */
+/* ======================================================================== */
+
+static int __devinit
+mpc52xx_fec_probe(struct of_device *op, const struct of_device_id *match)
+{
+       int rv;
+       struct net_device *ndev;
+       struct mpc52xx_fec_priv *priv = NULL;
+       struct resource mem;
+       const phandle *ph;
+
+       phys_addr_t rx_fifo;
+       phys_addr_t tx_fifo;
+
+       /* Get the ether ndev & it's private zone */
+       ndev = alloc_etherdev(sizeof(struct mpc52xx_fec_priv));
+       if (!ndev)
+               return -ENOMEM;
+
+       priv = netdev_priv(ndev);
+
+       /* Reserve FEC control zone */
+       rv = of_address_to_resource(op->node, 0, &mem);
+       if (rv) {
+               printk(KERN_ERR DRIVER_NAME ": "
+                               "Error while parsing device node resource\n" );
+               return rv;
+       }
+       if ((mem.end - mem.start + 1) != sizeof(struct mpc52xx_fec)) {
+               printk(KERN_ERR DRIVER_NAME
+                       " - invalid resource size (%lx != %x), check mpc52xx_devices.c\n",
+                       (unsigned long)(mem.end - mem.start + 1), sizeof(struct mpc52xx_fec));
+               return -EINVAL;
+       }
+
+       if (!request_mem_region(mem.start, sizeof(struct mpc52xx_fec), DRIVER_NAME))
+               return -EBUSY;
+
+       /* Init ether ndev with what we have */
+       ndev->open              = mpc52xx_fec_open;
+       ndev->stop              = mpc52xx_fec_close;
+       ndev->hard_start_xmit   = mpc52xx_fec_hard_start_xmit;
+       ndev->do_ioctl          = mpc52xx_fec_ioctl;
+       ndev->ethtool_ops       = &mpc52xx_fec_ethtool_ops;
+       ndev->get_stats         = mpc52xx_fec_get_stats;
+       ndev->set_mac_address   = mpc52xx_fec_set_mac_address;
+       ndev->set_multicast_list = mpc52xx_fec_set_multicast_list;
+       ndev->tx_timeout        = mpc52xx_fec_tx_timeout;
+       ndev->watchdog_timeo    = FEC_WATCHDOG_TIMEOUT;
+       ndev->base_addr         = mem.start;
+
+       priv->t_irq = priv->r_irq = ndev->irq = NO_IRQ; /* IRQ are free for now */
+
+       spin_lock_init(&priv->lock);
+
+       /* ioremap the zones */
+       priv->fec = ioremap(mem.start, sizeof(struct mpc52xx_fec));
+
+       if (!priv->fec) {
+               rv = -ENOMEM;
+               goto probe_error;
+       }
+
+       /* Bestcomm init */
+       rx_fifo = ndev->base_addr + offsetof(struct mpc52xx_fec, rfifo_data);
+       tx_fifo = ndev->base_addr + offsetof(struct mpc52xx_fec, tfifo_data);
+
+       priv->rx_dmatsk = bcom_fec_rx_init(FEC_RX_NUM_BD, rx_fifo, FEC_RX_BUFFER_SIZE);
+       priv->tx_dmatsk = bcom_fec_tx_init(FEC_TX_NUM_BD, tx_fifo);
+
+       if (!priv->rx_dmatsk || !priv->tx_dmatsk) {
+               printk(KERN_ERR DRIVER_NAME ": Can not init SDMA tasks\n" );
+               rv = -ENOMEM;
+               goto probe_error;
+       }
+
+       /* Get the IRQ we need one by one */
+               /* Control */
+       ndev->irq = irq_of_parse_and_map(op->node, 0);
+
+               /* RX */
+       priv->r_irq = bcom_get_task_irq(priv->rx_dmatsk);
+
+               /* TX */
+       priv->t_irq = bcom_get_task_irq(priv->tx_dmatsk);
+
+       /* MAC address init */
+       if (!is_zero_ether_addr(mpc52xx_fec_mac_addr))
+               memcpy(ndev->dev_addr, mpc52xx_fec_mac_addr, 6);
+       else
+               mpc52xx_fec_get_paddr(ndev, ndev->dev_addr);
+
+       priv->msg_enable = netif_msg_init(debug, MPC52xx_MESSAGES_DEFAULT);
+       priv->duplex = DUPLEX_FULL;
+
+       /* is the phy present in device tree? */
+       ph = of_get_property(op->node, "phy-handle", NULL);
+       if (ph) {
+               const unsigned int *prop;
+               struct device_node *phy_dn;
+               priv->has_phy = 1;
+
+               phy_dn = of_find_node_by_phandle(*ph);
+               prop = of_get_property(phy_dn, "reg", NULL);
+               priv->phy_addr = *prop;
+
+               of_node_put(phy_dn);
+
+               /* Phy speed */
+               priv->phy_speed = ((mpc52xx_find_ipb_freq(op->node) >> 20) / 5) << 1;
+       } else {
+               dev_info(&ndev->dev, "can't find \"phy-handle\" in device"
+                               " tree, using 7-wire mode\n");
+       }
+
+       /* Hardware init */
+       mpc52xx_fec_hw_init(ndev);
+
+       mpc52xx_fec_reset_stats(ndev);
+
+       /* Register the new network device */
+       rv = register_netdev(ndev);
+       if (rv < 0)
+               goto probe_error;
+
+       /* We're done ! */
+       dev_set_drvdata(&op->dev, ndev);
+
+       return 0;
+
+
+       /* Error handling - free everything that might be allocated */
+probe_error:
+
+       irq_dispose_mapping(ndev->irq);
+
+       if (priv->rx_dmatsk)
+               bcom_fec_rx_release(priv->rx_dmatsk);
+       if (priv->tx_dmatsk)
+               bcom_fec_tx_release(priv->tx_dmatsk);
+
+       if (priv->fec)
+               iounmap(priv->fec);
+
+       release_mem_region(mem.start, sizeof(struct mpc52xx_fec));
+
+       free_netdev(ndev);
+
+       return rv;
+}
+
+static int
+mpc52xx_fec_remove(struct of_device *op)
+{
+       struct net_device *ndev;
+       struct mpc52xx_fec_priv *priv;
+
+       ndev = dev_get_drvdata(&op->dev);
+       priv = netdev_priv(ndev);
+
+       unregister_netdev(ndev);
+
+       irq_dispose_mapping(ndev->irq);
+
+       bcom_fec_rx_release(priv->rx_dmatsk);
+       bcom_fec_tx_release(priv->tx_dmatsk);
+
+       iounmap(priv->fec);
+
+       release_mem_region(ndev->base_addr, sizeof(struct mpc52xx_fec));
+
+       free_netdev(ndev);
+
+       dev_set_drvdata(&op->dev, NULL);
+       return 0;
+}
+
+#ifdef CONFIG_PM
+static int mpc52xx_fec_of_suspend(struct of_device *op, pm_message_t state)
+{
+       struct net_device *dev = dev_get_drvdata(&op->dev);
+
+       if (netif_running(dev))
+               mpc52xx_fec_close(dev);
+
+       return 0;
+}
+
+static int mpc52xx_fec_of_resume(struct of_device *op)
+{
+       struct net_device *dev = dev_get_drvdata(&op->dev);
+
+       mpc52xx_fec_hw_init(dev);
+       mpc52xx_fec_reset_stats(dev);
+
+       if (netif_running(dev))
+               mpc52xx_fec_open(dev);
+
+       return 0;
+}
+#endif
+
+static struct of_device_id mpc52xx_fec_match[] = {
+       {
+               .type           = "network",
+               .compatible     = "mpc5200-fec",
+       },
+       { }
+};
+
+MODULE_DEVICE_TABLE(of, mpc52xx_fec_match);
+
+static struct of_platform_driver mpc52xx_fec_driver = {
+       .owner          = THIS_MODULE,
+       .name           = DRIVER_NAME,
+       .match_table    = mpc52xx_fec_match,
+       .probe          = mpc52xx_fec_probe,
+       .remove         = mpc52xx_fec_remove,
+#ifdef CONFIG_PM
+       .suspend        = mpc52xx_fec_of_suspend,
+       .resume         = mpc52xx_fec_of_resume,
+#endif
+};
+
+
+/* ======================================================================== */
+/* Module                                                                   */
+/* ======================================================================== */
+
+static int __init
+mpc52xx_fec_init(void)
+{
+#ifdef CONFIG_FEC_MPC52xx_MDIO
+       int ret;
+       ret = of_register_platform_driver(&mpc52xx_fec_mdio_driver);
+       if (ret) {
+               printk(KERN_ERR DRIVER_NAME ": failed to register mdio driver\n");
+               return ret;
+       }
+#endif
+       return of_register_platform_driver(&mpc52xx_fec_driver);
+}
+
+static void __exit
+mpc52xx_fec_exit(void)
+{
+       of_unregister_platform_driver(&mpc52xx_fec_driver);
+#ifdef CONFIG_FEC_MPC52xx_MDIO
+       of_unregister_platform_driver(&mpc52xx_fec_mdio_driver);
+#endif
+}
+
+
+module_init(mpc52xx_fec_init);
+module_exit(mpc52xx_fec_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Dale Farnsworth");
+MODULE_DESCRIPTION("Ethernet driver for the Freescale MPC52xx FEC");
diff --git a/drivers/net/fec_mpc52xx.h b/drivers/net/fec_mpc52xx.h
new file mode 100644 (file)
index 0000000..8b1f753
--- /dev/null
@@ -0,0 +1,313 @@
+/*
+ * drivers/drivers/net/fec_mpc52xx/fec.h
+ *
+ * Driver for the MPC5200 Fast Ethernet Controller
+ *
+ * Author: Dale Farnsworth <dfarnsworth@mvista.com>
+ *
+ * 2003-2004 (c) MontaVista, Software, Inc.  This file is licensed under
+ * the terms of the GNU General Public License version 2.  This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __DRIVERS_NET_MPC52XX_FEC_H__
+#define __DRIVERS_NET_MPC52XX_FEC_H__
+
+#include <linux/phy.h>
+
+/* Tunable constant */
+/* FEC_RX_BUFFER_SIZE includes 4 bytes for CRC32 */
+#define FEC_RX_BUFFER_SIZE     1522    /* max receive packet size */
+#define FEC_RX_NUM_BD          256
+#define FEC_TX_NUM_BD          64
+
+#define FEC_RESET_DELAY                50      /* uS */
+
+#define FEC_WATCHDOG_TIMEOUT   ((400*HZ)/1000)
+
+struct mpc52xx_fec_priv {
+       int duplex;
+       int r_irq;
+       int t_irq;
+       struct mpc52xx_fec __iomem *fec;
+       struct bcom_task *rx_dmatsk;
+       struct bcom_task *tx_dmatsk;
+       spinlock_t lock;
+       int msg_enable;
+
+       int has_phy;
+       unsigned int phy_speed;
+       unsigned int phy_addr;
+       struct phy_device *phydev;
+       enum phy_state link;
+       int speed;
+};
+
+
+/* ======================================================================== */
+/* Hardware register sets & bits                                            */
+/* ======================================================================== */
+
+struct mpc52xx_fec {
+       u32 fec_id;                     /* FEC + 0x000 */
+       u32 ievent;                     /* FEC + 0x004 */
+       u32 imask;                      /* FEC + 0x008 */
+
+       u32 reserved0[1];               /* FEC + 0x00C */
+       u32 r_des_active;               /* FEC + 0x010 */
+       u32 x_des_active;               /* FEC + 0x014 */
+       u32 r_des_active_cl;            /* FEC + 0x018 */
+       u32 x_des_active_cl;            /* FEC + 0x01C */
+       u32 ivent_set;                  /* FEC + 0x020 */
+       u32 ecntrl;                     /* FEC + 0x024 */
+
+       u32 reserved1[6];               /* FEC + 0x028-03C */
+       u32 mii_data;                   /* FEC + 0x040 */
+       u32 mii_speed;                  /* FEC + 0x044 */
+       u32 mii_status;                 /* FEC + 0x048 */
+
+       u32 reserved2[5];               /* FEC + 0x04C-05C */
+       u32 mib_data;                   /* FEC + 0x060 */
+       u32 mib_control;                /* FEC + 0x064 */
+
+       u32 reserved3[6];               /* FEC + 0x068-7C */
+       u32 r_activate;                 /* FEC + 0x080 */
+       u32 r_cntrl;                    /* FEC + 0x084 */
+       u32 r_hash;                     /* FEC + 0x088 */
+       u32 r_data;                     /* FEC + 0x08C */
+       u32 ar_done;                    /* FEC + 0x090 */
+       u32 r_test;                     /* FEC + 0x094 */
+       u32 r_mib;                      /* FEC + 0x098 */
+       u32 r_da_low;                   /* FEC + 0x09C */
+       u32 r_da_high;                  /* FEC + 0x0A0 */
+
+       u32 reserved4[7];               /* FEC + 0x0A4-0BC */
+       u32 x_activate;                 /* FEC + 0x0C0 */
+       u32 x_cntrl;                    /* FEC + 0x0C4 */
+       u32 backoff;                    /* FEC + 0x0C8 */
+       u32 x_data;                     /* FEC + 0x0CC */
+       u32 x_status;                   /* FEC + 0x0D0 */
+       u32 x_mib;                      /* FEC + 0x0D4 */
+       u32 x_test;                     /* FEC + 0x0D8 */
+       u32 fdxfc_da1;                  /* FEC + 0x0DC */
+       u32 fdxfc_da2;                  /* FEC + 0x0E0 */
+       u32 paddr1;                     /* FEC + 0x0E4 */
+       u32 paddr2;                     /* FEC + 0x0E8 */
+       u32 op_pause;                   /* FEC + 0x0EC */
+
+       u32 reserved5[4];               /* FEC + 0x0F0-0FC */
+       u32 instr_reg;                  /* FEC + 0x100 */
+       u32 context_reg;                /* FEC + 0x104 */
+       u32 test_cntrl;                 /* FEC + 0x108 */
+       u32 acc_reg;                    /* FEC + 0x10C */
+       u32 ones;                       /* FEC + 0x110 */
+       u32 zeros;                      /* FEC + 0x114 */
+       u32 iaddr1;                     /* FEC + 0x118 */
+       u32 iaddr2;                     /* FEC + 0x11C */
+       u32 gaddr1;                     /* FEC + 0x120 */
+       u32 gaddr2;                     /* FEC + 0x124 */
+       u32 random;                     /* FEC + 0x128 */
+       u32 rand1;                      /* FEC + 0x12C */
+       u32 tmp;                        /* FEC + 0x130 */
+
+       u32 reserved6[3];               /* FEC + 0x134-13C */
+       u32 fifo_id;                    /* FEC + 0x140 */
+       u32 x_wmrk;                     /* FEC + 0x144 */
+       u32 fcntrl;                     /* FEC + 0x148 */
+       u32 r_bound;                    /* FEC + 0x14C */
+       u32 r_fstart;                   /* FEC + 0x150 */
+       u32 r_count;                    /* FEC + 0x154 */
+       u32 r_lag;                      /* FEC + 0x158 */
+       u32 r_read;                     /* FEC + 0x15C */
+       u32 r_write;                    /* FEC + 0x160 */
+       u32 x_count;                    /* FEC + 0x164 */
+       u32 x_lag;                      /* FEC + 0x168 */
+       u32 x_retry;                    /* FEC + 0x16C */
+       u32 x_write;                    /* FEC + 0x170 */
+       u32 x_read;                     /* FEC + 0x174 */
+
+       u32 reserved7[2];               /* FEC + 0x178-17C */
+       u32 fm_cntrl;                   /* FEC + 0x180 */
+       u32 rfifo_data;                 /* FEC + 0x184 */
+       u32 rfifo_status;               /* FEC + 0x188 */
+       u32 rfifo_cntrl;                /* FEC + 0x18C */
+       u32 rfifo_lrf_ptr;              /* FEC + 0x190 */
+       u32 rfifo_lwf_ptr;              /* FEC + 0x194 */
+       u32 rfifo_alarm;                /* FEC + 0x198 */
+       u32 rfifo_rdptr;                /* FEC + 0x19C */
+       u32 rfifo_wrptr;                /* FEC + 0x1A0 */
+       u32 tfifo_data;                 /* FEC + 0x1A4 */
+       u32 tfifo_status;               /* FEC + 0x1A8 */
+       u32 tfifo_cntrl;                /* FEC + 0x1AC */
+       u32 tfifo_lrf_ptr;              /* FEC + 0x1B0 */
+       u32 tfifo_lwf_ptr;              /* FEC + 0x1B4 */
+       u32 tfifo_alarm;                /* FEC + 0x1B8 */
+       u32 tfifo_rdptr;                /* FEC + 0x1BC */
+       u32 tfifo_wrptr;                /* FEC + 0x1C0 */
+
+       u32 reset_cntrl;                /* FEC + 0x1C4 */
+       u32 xmit_fsm;                   /* FEC + 0x1C8 */
+
+       u32 reserved8[3];               /* FEC + 0x1CC-1D4 */
+       u32 rdes_data0;                 /* FEC + 0x1D8 */
+       u32 rdes_data1;                 /* FEC + 0x1DC */
+       u32 r_length;                   /* FEC + 0x1E0 */
+       u32 x_length;                   /* FEC + 0x1E4 */
+       u32 x_addr;                     /* FEC + 0x1E8 */
+       u32 cdes_data;                  /* FEC + 0x1EC */
+       u32 status;                     /* FEC + 0x1F0 */
+       u32 dma_control;                /* FEC + 0x1F4 */
+       u32 des_cmnd;                   /* FEC + 0x1F8 */
+       u32 data;                       /* FEC + 0x1FC */
+
+       u32 rmon_t_drop;                /* FEC + 0x200 */
+       u32 rmon_t_packets;             /* FEC + 0x204 */
+       u32 rmon_t_bc_pkt;              /* FEC + 0x208 */
+       u32 rmon_t_mc_pkt;              /* FEC + 0x20C */
+       u32 rmon_t_crc_align;           /* FEC + 0x210 */
+       u32 rmon_t_undersize;           /* FEC + 0x214 */
+       u32 rmon_t_oversize;            /* FEC + 0x218 */
+       u32 rmon_t_frag;                /* FEC + 0x21C */
+       u32 rmon_t_jab;                 /* FEC + 0x220 */
+       u32 rmon_t_col;                 /* FEC + 0x224 */
+       u32 rmon_t_p64;                 /* FEC + 0x228 */
+       u32 rmon_t_p65to127;            /* FEC + 0x22C */
+       u32 rmon_t_p128to255;           /* FEC + 0x230 */
+       u32 rmon_t_p256to511;           /* FEC + 0x234 */
+       u32 rmon_t_p512to1023;          /* FEC + 0x238 */
+       u32 rmon_t_p1024to2047;         /* FEC + 0x23C */
+       u32 rmon_t_p_gte2048;           /* FEC + 0x240 */
+       u32 rmon_t_octets;              /* FEC + 0x244 */
+       u32 ieee_t_drop;                /* FEC + 0x248 */
+       u32 ieee_t_frame_ok;            /* FEC + 0x24C */
+       u32 ieee_t_1col;                /* FEC + 0x250 */
+       u32 ieee_t_mcol;                /* FEC + 0x254 */
+       u32 ieee_t_def;                 /* FEC + 0x258 */
+       u32 ieee_t_lcol;                /* FEC + 0x25C */
+       u32 ieee_t_excol;               /* FEC + 0x260 */
+       u32 ieee_t_macerr;              /* FEC + 0x264 */
+       u32 ieee_t_cserr;               /* FEC + 0x268 */
+       u32 ieee_t_sqe;                 /* FEC + 0x26C */
+       u32 t_fdxfc;                    /* FEC + 0x270 */
+       u32 ieee_t_octets_ok;           /* FEC + 0x274 */
+
+       u32 reserved9[2];               /* FEC + 0x278-27C */
+       u32 rmon_r_drop;                /* FEC + 0x280 */
+       u32 rmon_r_packets;             /* FEC + 0x284 */
+       u32 rmon_r_bc_pkt;              /* FEC + 0x288 */
+       u32 rmon_r_mc_pkt;              /* FEC + 0x28C */
+       u32 rmon_r_crc_align;           /* FEC + 0x290 */
+       u32 rmon_r_undersize;           /* FEC + 0x294 */
+       u32 rmon_r_oversize;            /* FEC + 0x298 */
+       u32 rmon_r_frag;                /* FEC + 0x29C */
+       u32 rmon_r_jab;                 /* FEC + 0x2A0 */
+
+       u32 rmon_r_resvd_0;             /* FEC + 0x2A4 */
+
+       u32 rmon_r_p64;                 /* FEC + 0x2A8 */
+       u32 rmon_r_p65to127;            /* FEC + 0x2AC */
+       u32 rmon_r_p128to255;           /* FEC + 0x2B0 */
+       u32 rmon_r_p256to511;           /* FEC + 0x2B4 */
+       u32 rmon_r_p512to1023;          /* FEC + 0x2B8 */
+       u32 rmon_r_p1024to2047;         /* FEC + 0x2BC */
+       u32 rmon_r_p_gte2048;           /* FEC + 0x2C0 */
+       u32 rmon_r_octets;              /* FEC + 0x2C4 */
+       u32 ieee_r_drop;                /* FEC + 0x2C8 */
+       u32 ieee_r_frame_ok;            /* FEC + 0x2CC */
+       u32 ieee_r_crc;                 /* FEC + 0x2D0 */
+       u32 ieee_r_align;               /* FEC + 0x2D4 */
+       u32 r_macerr;                   /* FEC + 0x2D8 */
+       u32 r_fdxfc;                    /* FEC + 0x2DC */
+       u32 ieee_r_octets_ok;           /* FEC + 0x2E0 */
+
+       u32 reserved10[7];              /* FEC + 0x2E4-2FC */
+
+       u32 reserved11[64];             /* FEC + 0x300-3FF */
+};
+
+#define        FEC_MIB_DISABLE                 0x80000000
+
+#define        FEC_IEVENT_HBERR                0x80000000
+#define        FEC_IEVENT_BABR                 0x40000000
+#define        FEC_IEVENT_BABT                 0x20000000
+#define        FEC_IEVENT_GRA                  0x10000000
+#define        FEC_IEVENT_TFINT                0x08000000
+#define        FEC_IEVENT_MII                  0x00800000
+#define        FEC_IEVENT_LATE_COL             0x00200000
+#define        FEC_IEVENT_COL_RETRY_LIM        0x00100000
+#define        FEC_IEVENT_XFIFO_UN             0x00080000
+#define        FEC_IEVENT_XFIFO_ERROR          0x00040000
+#define        FEC_IEVENT_RFIFO_ERROR          0x00020000
+
+#define        FEC_IMASK_HBERR                 0x80000000
+#define        FEC_IMASK_BABR                  0x40000000
+#define        FEC_IMASK_BABT                  0x20000000
+#define        FEC_IMASK_GRA                   0x10000000
+#define        FEC_IMASK_MII                   0x00800000
+#define        FEC_IMASK_LATE_COL              0x00200000
+#define        FEC_IMASK_COL_RETRY_LIM         0x00100000
+#define        FEC_IMASK_XFIFO_UN              0x00080000
+#define        FEC_IMASK_XFIFO_ERROR           0x00040000
+#define        FEC_IMASK_RFIFO_ERROR           0x00020000
+
+/* all but MII, which is enabled separately */
+#define FEC_IMASK_ENABLE       (FEC_IMASK_HBERR | FEC_IMASK_BABR | \
+               FEC_IMASK_BABT | FEC_IMASK_GRA | FEC_IMASK_LATE_COL | \
+               FEC_IMASK_COL_RETRY_LIM | FEC_IMASK_XFIFO_UN | \
+               FEC_IMASK_XFIFO_ERROR | FEC_IMASK_RFIFO_ERROR)
+
+#define        FEC_RCNTRL_MAX_FL_SHIFT         16
+#define        FEC_RCNTRL_LOOP                 0x01
+#define        FEC_RCNTRL_DRT                  0x02
+#define        FEC_RCNTRL_MII_MODE             0x04
+#define        FEC_RCNTRL_PROM                 0x08
+#define        FEC_RCNTRL_BC_REJ               0x10
+#define        FEC_RCNTRL_FCE                  0x20
+
+#define        FEC_TCNTRL_GTS                  0x00000001
+#define        FEC_TCNTRL_HBC                  0x00000002
+#define        FEC_TCNTRL_FDEN                 0x00000004
+#define        FEC_TCNTRL_TFC_PAUSE            0x00000008
+#define        FEC_TCNTRL_RFC_PAUSE            0x00000010
+
+#define        FEC_ECNTRL_RESET                0x00000001
+#define        FEC_ECNTRL_ETHER_EN             0x00000002
+
+#define FEC_MII_DATA_ST                        0x40000000      /* Start frame */
+#define FEC_MII_DATA_OP_RD             0x20000000      /* Perform read */
+#define FEC_MII_DATA_OP_WR             0x10000000      /* Perform write */
+#define FEC_MII_DATA_PA_MSK            0x0f800000      /* PHY Address mask */
+#define FEC_MII_DATA_RA_MSK            0x007c0000      /* PHY Register mask */
+#define FEC_MII_DATA_TA                        0x00020000      /* Turnaround */
+#define FEC_MII_DATA_DATAMSK           0x0000ffff      /* PHY data mask */
+
+#define FEC_MII_READ_FRAME     (FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA)
+#define FEC_MII_WRITE_FRAME    (FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR | FEC_MII_DATA_TA)
+
+#define FEC_MII_DATA_RA_SHIFT          0x12            /* MII reg addr bits */
+#define FEC_MII_DATA_PA_SHIFT          0x17            /* MII PHY addr bits */
+
+#define FEC_PADDR2_TYPE                        0x8808
+
+#define FEC_OP_PAUSE_OPCODE            0x00010000
+
+#define FEC_FIFO_WMRK_256B             0x3
+
+#define FEC_FIFO_STATUS_ERR            0x00400000
+#define FEC_FIFO_STATUS_UF             0x00200000
+#define FEC_FIFO_STATUS_OF             0x00100000
+
+#define FEC_FIFO_CNTRL_FRAME           0x08000000
+#define FEC_FIFO_CNTRL_LTG_7           0x07000000
+
+#define FEC_RESET_CNTRL_RESET_FIFO     0x02000000
+#define FEC_RESET_CNTRL_ENABLE_IS_RESET        0x01000000
+
+#define FEC_XMIT_FSM_APPEND_CRC                0x02000000
+#define FEC_XMIT_FSM_ENABLE_CRC                0x01000000
+
+
+extern struct of_platform_driver mpc52xx_fec_mdio_driver;
+
+#endif /* __DRIVERS_NET_MPC52XX_FEC_H__ */
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
new file mode 100644 (file)
index 0000000..ba6e8b2
--- /dev/null
@@ -0,0 +1,198 @@
+/*
+ * Driver for the MPC5200 Fast Ethernet Controller - MDIO bus driver
+ *
+ * Copyright (C) 2007  Domen Puncer, Telargo, Inc.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/phy.h>
+#include <linux/of_platform.h>
+#include <asm/io.h>
+#include <asm/mpc52xx.h>
+#include "fec_mpc52xx.h"
+
+struct mpc52xx_fec_mdio_priv {
+       struct mpc52xx_fec __iomem *regs;
+};
+
+static int mpc52xx_fec_mdio_read(struct mii_bus *bus, int phy_id, int reg)
+{
+       struct mpc52xx_fec_mdio_priv *priv = bus->priv;
+       struct mpc52xx_fec __iomem *fec;
+       int tries = 100;
+       u32 request = FEC_MII_READ_FRAME;
+
+       fec = priv->regs;
+       out_be32(&fec->ievent, FEC_IEVENT_MII);
+
+       request |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
+       request |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
+
+       out_be32(&priv->regs->mii_data, request);
+
+       /* wait for it to finish, this takes about 23 us on lite5200b */
+       while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
+               udelay(5);
+
+       if (tries == 0)
+               return -ETIMEDOUT;
+
+       return in_be32(&priv->regs->mii_data) & FEC_MII_DATA_DATAMSK;
+}
+
+static int mpc52xx_fec_mdio_write(struct mii_bus *bus, int phy_id, int reg, u16 data)
+{
+       struct mpc52xx_fec_mdio_priv *priv = bus->priv;
+       struct mpc52xx_fec __iomem *fec;
+       u32 value = data;
+       int tries = 100;
+
+       fec = priv->regs;
+       out_be32(&fec->ievent, FEC_IEVENT_MII);
+
+       value |= FEC_MII_WRITE_FRAME;
+       value |= (phy_id << FEC_MII_DATA_PA_SHIFT) & FEC_MII_DATA_PA_MSK;
+       value |= (reg << FEC_MII_DATA_RA_SHIFT) & FEC_MII_DATA_RA_MSK;
+
+       out_be32(&priv->regs->mii_data, value);
+
+       /* wait for request to finish */
+       while (!(in_be32(&fec->ievent) & FEC_IEVENT_MII) && --tries)
+               udelay(5);
+
+       if (tries == 0)
+               return -ETIMEDOUT;
+
+       return 0;
+}
+
+static int mpc52xx_fec_mdio_probe(struct of_device *of, const struct of_device_id *match)
+{
+       struct device *dev = &of->dev;
+       struct device_node *np = of->node;
+       struct device_node *child = NULL;
+       struct mii_bus *bus;
+       struct mpc52xx_fec_mdio_priv *priv;
+       struct resource res = {};
+       int err;
+       int i;
+
+       bus = kzalloc(sizeof(*bus), GFP_KERNEL);
+       if (bus == NULL)
+               return -ENOMEM;
+       priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+       if (priv == NULL) {
+               err = -ENOMEM;
+               goto out_free;
+       }
+
+       bus->name = "mpc52xx MII bus";
+       bus->read = mpc52xx_fec_mdio_read;
+       bus->write = mpc52xx_fec_mdio_write;
+
+       /* setup irqs */
+       bus->irq = kmalloc(sizeof(bus->irq[0]) * PHY_MAX_ADDR, GFP_KERNEL);
+       if (bus->irq == NULL) {
+               err = -ENOMEM;
+               goto out_free;
+       }
+       for (i=0; i<PHY_MAX_ADDR; i++)
+               bus->irq[i] = PHY_POLL;
+
+       while ((child = of_get_next_child(np, child)) != NULL) {
+               int irq = irq_of_parse_and_map(child, 0);
+               if (irq != NO_IRQ) {
+                       const u32 *id = of_get_property(child, "reg", NULL);
+                       bus->irq[*id] = irq;
+               }
+       }
+
+       /* setup registers */
+       err = of_address_to_resource(np, 0, &res);
+       if (err)
+               goto out_free;
+       priv->regs = ioremap(res.start, res.end - res.start + 1);
+       if (priv->regs == NULL) {
+               err = -ENOMEM;
+               goto out_free;
+       }
+
+       bus->id = res.start;
+       bus->priv = priv;
+
+       bus->dev = dev;
+       dev_set_drvdata(dev, bus);
+
+       /* set MII speed */
+       out_be32(&priv->regs->mii_speed, ((mpc52xx_find_ipb_freq(of->node) >> 20) / 5) << 1);
+
+       /* enable MII interrupt */
+       out_be32(&priv->regs->imask, in_be32(&priv->regs->imask) | FEC_IMASK_MII);
+
+       err = mdiobus_register(bus);
+       if (err)
+               goto out_unmap;
+
+       return 0;
+
+ out_unmap:
+       iounmap(priv->regs);
+ out_free:
+       for (i=0; i<PHY_MAX_ADDR; i++)
+               if (bus->irq[i] != PHY_POLL)
+                       irq_dispose_mapping(bus->irq[i]);
+       kfree(bus->irq);
+       kfree(priv);
+       kfree(bus);
+
+       return err;
+}
+
+static int mpc52xx_fec_mdio_remove(struct of_device *of)
+{
+       struct device *dev = &of->dev;
+       struct mii_bus *bus = dev_get_drvdata(dev);
+       struct mpc52xx_fec_mdio_priv *priv = bus->priv;
+       int i;
+
+       mdiobus_unregister(bus);
+       dev_set_drvdata(dev, NULL);
+
+       iounmap(priv->regs);
+       for (i=0; i<PHY_MAX_ADDR; i++)
+               if (bus->irq[i])
+                       irq_dispose_mapping(bus->irq[i]);
+       kfree(priv);
+       kfree(bus->irq);
+       kfree(bus);
+
+       return 0;
+}
+
+
+static struct of_device_id mpc52xx_fec_mdio_match[] = {
+       {
+               .type = "mdio",
+               .compatible = "mpc5200b-fec-phy",
+       },
+       {},
+};
+
+struct of_platform_driver mpc52xx_fec_mdio_driver = {
+       .name = "mpc5200b-fec-phy",
+       .probe = mpc52xx_fec_mdio_probe,
+       .remove = mpc52xx_fec_mdio_remove,
+       .match_table = mpc52xx_fec_mdio_match,
+};
+
+/* let fec driver call it, since this has to be registered before it */
+EXPORT_SYMBOL_GPL(mpc52xx_fec_mdio_driver);
+
+
+MODULE_LICENSE("Dual BSD/GPL");
index 70ddf1a..92ce2e3 100644 (file)
@@ -5597,6 +5597,22 @@ static struct pci_device_id pci_tbl[] = {
                PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_31),
                .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL|DEV_HAS_MSI|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR,
        },
+       {       /* MCP77 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_32),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP77 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_33),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP77 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_34),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
+       {       /* MCP77 Ethernet Controller */
+               PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_35),
+               .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX|DEV_HAS_STATISTICS_V2|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT,
+       },
        {0,},
 };
 
index 6888723..dbd23bb 100644 (file)
@@ -55,6 +55,26 @@ MODULE_DESCRIPTION("IC Plus IP1000 Gigabit Ethernet Adapter Linux Driver "
                   DrvVer);
 MODULE_LICENSE("GPL");
 
+//variable record -- index by leading revision/length
+//Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
+static unsigned short DefaultPhyParam[] = {
+       // 11/12/03 IP1000A v1-3 rev=0x40
+       /*--------------------------------------------------------------------------
+       (0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
+                                27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6,
+                                31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7,  9, 0x0700,
+         --------------------------------------------------------------------------*/
+       // 12/17/03 IP1000A v1-4 rev=0x40
+       (0x4000 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
+           0x0000,
+       30, 0x005e, 9, 0x0700,
+       // 01/09/04 IP1000A v1-5 rev=0x41
+       (0x4100 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
+           0x0000,
+       30, 0x005e, 9, 0x0700,
+       0x0000
+};
+
 static const char *ipg_brand_name[] = {
        "IC PLUS IP1000 1000/100/10 based NIC",
        "Sundance Technology ST2021 based NIC",
@@ -990,7 +1010,7 @@ static void ipg_nic_txcleanup(struct net_device *dev)
 }
 
 /* Provides statistical information about the IPG NIC. */
-struct net_device_stats *ipg_nic_get_stats(struct net_device *dev)
+static struct net_device_stats *ipg_nic_get_stats(struct net_device *dev)
 {
        struct ipg_nic_private *sp = netdev_priv(dev);
        void __iomem *ioaddr = sp->ioaddr;
index e418b90..d5d092c 100644 (file)
@@ -833,24 +833,4 @@ struct ipg_nic_private {
        struct delayed_work task;
 };
 
-//variable record -- index by leading revision/length
-//Revision/Length(=N*4), Address1, Data1, Address2, Data2,...,AddressN,DataN
-unsigned short DefaultPhyParam[] = {
-       // 11/12/03 IP1000A v1-3 rev=0x40
-       /*--------------------------------------------------------------------------
-       (0x4000|(15*4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 22, 0x85bd, 24, 0xfff2,
-                                27, 0x0c10, 28, 0x0c10, 29, 0x2c10, 31, 0x0003, 23, 0x92f6,
-                                31, 0x0000, 23, 0x003d, 30, 0x00de, 20, 0x20e7,  9, 0x0700,
-         --------------------------------------------------------------------------*/
-       // 12/17/03 IP1000A v1-4 rev=0x40
-       (0x4000 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
-           0x0000,
-       30, 0x005e, 9, 0x0700,
-       // 01/09/04 IP1000A v1-5 rev=0x41
-       (0x4100 | (07 * 4)), 31, 0x0001, 27, 0x01e0, 31, 0x0002, 27, 0xeb8e, 31,
-           0x0000,
-       30, 0x005e, 9, 0x0700,
-       0x0000
-};
-
 #endif                         /* __LINUX_IPG_H */
index 4dbdfaa..a1e4508 100644 (file)
@@ -627,19 +627,16 @@ static int au1k_irda_rx(struct net_device *dev)
 }
 
 
-void au1k_irda_interrupt(int irq, void *dev_id)
+static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id)
 {
-       struct net_device *dev = (struct net_device *) dev_id;
-
-       if (dev == NULL) {
-               printk(KERN_ERR "%s: isr: null dev ptr\n", dev->name);
-               return;
-       }
+       struct net_device *dev = dev_id;
 
        writel(0, IR_INT_CLEAR); /* ack irda interrupts */
 
        au1k_irda_rx(dev);
        au1k_tx_ack(dev);
+
+       return IRQ_HANDLED;
 }
 
 
index 662b8d1..45f30a2 100644 (file)
@@ -284,7 +284,7 @@ static __net_exit void loopback_net_exit(struct net *net)
        unregister_netdev(dev);
 }
 
-static struct pernet_operations __net_initdata loopback_net_ops = {
+static struct pernet_operations loopback_net_ops = {
        .init = loopback_net_init,
        .exit = loopback_net_exit,
 };
index 887633b..2a5bef6 100644 (file)
@@ -101,9 +101,7 @@ static int mlx4_alloc_icm_pages(struct scatterlist *mem, int order, gfp_t gfp_ma
        if (!page)
                return -ENOMEM;
 
-       sg_set_page(mem, page);
-       mem->length = PAGE_SIZE << order;
-       mem->offset = 0;
+       sg_set_page(mem, page, PAGE_SIZE << order, 0);
        return 0;
 }
 
index 9531171..87cde06 100644 (file)
@@ -864,6 +864,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev,
 
        np = netdev_priv(dev);
        netif_napi_add(dev, &np->napi, natsemi_poll, 64);
+       np->dev = dev;
 
        np->pci_dev = pdev;
        pci_set_drvdata(pdev, dev);
index 73dcbb7..ad134a6 100644 (file)
@@ -274,7 +274,7 @@ static int tc574_probe(struct pcmcia_device *link)
        spin_lock_init(&lp->window_lock);
        link->io.NumPorts1 = 32;
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
        link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->irq.Handler = &el3_interrupt;
        link->irq.Instance = dev;
index 32076ca..a98fe07 100644 (file)
@@ -188,7 +188,7 @@ static int tc589_probe(struct pcmcia_device *link)
     spin_lock_init(&lp->lock);
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &el3_interrupt;
     link->irq.Instance = dev;
index a95a2ca..8d910a3 100644 (file)
@@ -158,7 +158,7 @@ static int axnet_probe(struct pcmcia_device *link)
     info = PRIV(dev);
     info->p_dev = link;
     link->priv = dev;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
index 6284467..8c719b4 100644 (file)
@@ -249,7 +249,7 @@ static int fmvj18x_probe(struct pcmcia_device *link)
     link->io.IOAddrLines = 5;
 
     /* Interrupt setup */
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &fjn_interrupt;
     link->irq.Instance = dev;
index 9d45e96..db6a97d 100644 (file)
@@ -254,7 +254,7 @@ static int pcnet_probe(struct pcmcia_device *link)
     info->p_dev = link;
     link->priv = dev;
 
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->conf.Attributes = CONF_ENABLE_IRQ;
     link->conf.IntType = INT_MEMORY_AND_IO;
index 58d716f..c9868e9 100644 (file)
@@ -328,7 +328,7 @@ static int smc91c92_probe(struct pcmcia_device *link)
     link->io.NumPorts1 = 16;
     link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
     link->io.IOAddrLines = 4;
-    link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
+    link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING|IRQ_HANDLE_PRESENT;
     link->irq.IRQInfo1 = IRQ_LEVEL_ID;
     link->irq.Handler = &smc_interrupt;
     link->irq.Instance = dev;
index c3b6960..1f09bea 100644 (file)
@@ -886,7 +886,7 @@ xirc2ps_config(struct pcmcia_device * link)
        }
        printk(KNOT_XIRC "no ports available\n");
     } else {
-       link->irq.Attributes |= IRQ_TYPE_EXCLUSIVE;
+       link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING;
        link->io.NumPorts1 = 16;
        for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {
            link->io.BasePort1 = ioaddr;
index bcb0885..b35d794 100644 (file)
@@ -68,7 +68,7 @@ MODULE_VERSION("1.0.2");
 static unsigned int
 setup_sg(struct scatterlist *sg, const void *address, unsigned int length)
 {
-       sg_init_one(sg, address, length);
+       sg_set_buf(sg, address, length);
        return length;
 }
 
@@ -140,6 +140,8 @@ static void get_new_key_from_sha(struct ppp_mppe_state * state)
        struct scatterlist sg[4];
        unsigned int nbytes;
 
+       sg_init_table(sg, 4);
+
        nbytes = setup_sg(&sg[0], state->master_key, state->keylen);
        nbytes += setup_sg(&sg[1], sha_pad->sha_pad1,
                           sizeof(sha_pad->sha_pad1));
@@ -166,6 +168,8 @@ static void mppe_rekey(struct ppp_mppe_state * state, int initial_key)
        if (!initial_key) {
                crypto_blkcipher_setkey(state->arc4, state->sha1_digest,
                                        state->keylen);
+               sg_init_table(sg_in, 1);
+               sg_init_table(sg_out, 1);
                setup_sg(sg_in, state->sha1_digest, state->keylen);
                setup_sg(sg_out, state->session_key, state->keylen);
                if (crypto_blkcipher_encrypt(&desc, sg_out, sg_in,
@@ -421,6 +425,8 @@ mppe_compress(void *arg, unsigned char *ibuf, unsigned char *obuf,
        isize -= 2;
 
        /* Encrypt packet */
+       sg_init_table(sg_in, 1);
+       sg_init_table(sg_out, 1);
        setup_sg(sg_in, ibuf, isize);
        setup_sg(sg_out, obuf, osize);
        if (crypto_blkcipher_encrypt(&desc, sg_out, sg_in, isize) != 0) {
@@ -608,6 +614,8 @@ mppe_decompress(void *arg, unsigned char *ibuf, int isize, unsigned char *obuf,
         * Decrypt the first byte in order to check if it is
         * a compressed or uncompressed protocol field.
         */
+       sg_init_table(sg_in, 1);
+       sg_init_table(sg_out, 1);
        setup_sg(sg_in, ibuf, 1);
        setup_sg(sg_out, obuf, 1);
        if (crypto_blkcipher_decrypt(&desc, sg_out, sg_in, 1) != 0) {
index e8960f2..b94fa7e 100644 (file)
@@ -392,7 +392,9 @@ struct rtl8169_private {
        void __iomem *mmio_addr;        /* memory map physical address */
        struct pci_dev *pci_dev;        /* Index of PCI device */
        struct net_device *dev;
+#ifdef CONFIG_R8169_NAPI
        struct napi_struct napi;
+#endif
        spinlock_t lock;                /* spin lock flag */
        u32 msg_enable;
        int chipset;
@@ -2989,13 +2991,16 @@ static void rtl8169_down(struct net_device *dev)
 {
        struct rtl8169_private *tp = netdev_priv(dev);
        void __iomem *ioaddr = tp->mmio_addr;
-       unsigned int poll_locked = 0;
        unsigned int intrmask;
 
        rtl8169_delete_timer(dev);
 
        netif_stop_queue(dev);
 
+#ifdef CONFIG_R8169_NAPI
+       napi_disable(&tp->napi);
+#endif
+
 core_down:
        spin_lock_irq(&tp->lock);
 
@@ -3009,11 +3014,6 @@ core_down:
 
        synchronize_irq(dev->irq);
 
-       if (!poll_locked) {
-               napi_disable(&tp->napi);
-               poll_locked++;
-       }
-
        /* Give a racing hard_start_xmit a few cycles to complete. */
        synchronize_sched();  /* FIXME: should this be synchronize_irq()? */
 
index 19152f5..b822859 100644 (file)
@@ -79,12 +79,10 @@ static char version[] __devinitdata = "rrunner.c: v0.50 11/11/2002  Jes Sorensen
  */
 
 /*
- * These are checked at init time to see if they are at least 256KB
- * and increased to 256KB if they are not. This is done to avoid ending
- * up with socket buffers smaller than the MTU size,
+ * sysctl_[wr]mem_max are checked at init time to see if they are at
+ * least 256KB and increased to 256KB if they are not. This is done to
+ * avoid ending up with socket buffers smaller than the MTU size,
  */
-extern __u32 sysctl_wmem_max;
-extern __u32 sysctl_rmem_max;
 
 static int __devinit rr_init_one(struct pci_dev *pdev,
        const struct pci_device_id *ent)
index 9741d61..a3ff270 100644 (file)
@@ -2214,9 +2214,7 @@ static void ucc_geth_set_multi(struct net_device *dev)
        struct dev_mc_list *dmi;
        struct ucc_fast *uf_regs;
        struct ucc_geth_82xx_address_filtering_pram *p_82xx_addr_filt;
-       u8 tempaddr[6];
-       u8 *mcptr, *tdptr;
-       int i, j;
+       int i;
 
        ugeth = netdev_priv(dev);
 
@@ -2255,19 +2253,10 @@ static void ucc_geth_set_multi(struct net_device *dev)
                                if (!(dmi->dmi_addr[0] & 1))
                                        continue;
 
-                               /* The address in dmi_addr is LSB first,
-                                * and taddr is MSB first.  We have to
-                                * copy bytes MSB first from dmi_addr.
-                                */
-                               mcptr = (u8 *) dmi->dmi_addr + 5;
-                               tdptr = (u8 *) tempaddr;
-                               for (j = 0; j < 6; j++)
-                                       *tdptr++ = *mcptr--;
-
                                /* Ask CPM to run CRC and set bit in
                                 * filter mask.
                                 */
-                               hw_add_addr_in_hash(ugeth, tempaddr);
+                               hw_add_addr_in_hash(ugeth, dmi->dmi_addr);
                        }
                }
        }
index cd991a0..1ebe325 100644 (file)
@@ -512,11 +512,19 @@ static int rndis_bind(struct usbnet *dev, struct usb_interface *intf)
        }
        tmp = le32_to_cpu(u.init_c->max_transfer_size);
        if (tmp < dev->hard_mtu) {
-               dev_err(&intf->dev,
-                       "dev can't take %u byte packets (max %u)\n",
-                       dev->hard_mtu, tmp);
-               retval = -EINVAL;
-               goto fail_and_release;
+               if (tmp <= net->hard_header_len) {
+                       dev_err(&intf->dev,
+                               "dev can't take %u byte packets (max %u)\n",
+                               dev->hard_mtu, tmp);
+                       retval = -EINVAL;
+                       goto fail_and_release;
+               }
+               dev->hard_mtu = tmp;
+               net->mtu = dev->hard_mtu - net->hard_header_len;
+               dev_warn(&intf->dev,
+                        "dev can't take %u byte packets (max %u), "
+                        "adjusting MTU to %u\n",
+                        dev->hard_mtu, tmp, net->mtu);
        }
 
        /* REVISIT:  peripheral "alignment" request is ignored ... */
index 9d9ff76..5058e60 100644 (file)
@@ -2391,7 +2391,7 @@ out_requeue:
        if (b43_debug(dev, B43_DBG_PWORK_FAST))
                delay = msecs_to_jiffies(50);
        else
-               delay = round_jiffies(HZ * 15);
+               delay = round_jiffies_relative(HZ * 15);
        queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay);
 out:
        mutex_unlock(&wl->mutex);
index d09479e..f0e56df 100644 (file)
@@ -2260,7 +2260,7 @@ out_requeue:
        if (b43legacy_debug(dev, B43legacy_DBG_PWORK_FAST))
                delay = msecs_to_jiffies(50);
        else
-               delay = round_jiffies(HZ);
+               delay = round_jiffies_relative(HZ);
        queue_delayed_work(dev->wl->hw->workqueue,
                           &dev->periodic_work, delay);
 out:
index a6c7904..8d53d08 100644 (file)
@@ -1769,7 +1769,7 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
                if (priv->stop_rf_kill) {
                        priv->stop_rf_kill = 0;
                        queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies(HZ));
+                                          round_jiffies_relative(HZ));
                }
 
                deferred = 1;
@@ -2086,7 +2086,8 @@ static void isr_indicate_rf_kill(struct ipw2100_priv *priv, u32 status)
        /* Make sure the RF Kill check timer is running */
        priv->stop_rf_kill = 0;
        cancel_delayed_work(&priv->rf_kill);
-       queue_delayed_work(priv->workqueue, &priv->rf_kill, round_jiffies(HZ));
+       queue_delayed_work(priv->workqueue, &priv->rf_kill,
+                          round_jiffies_relative(HZ));
 }
 
 static void send_scan_event(void *data)
@@ -2123,7 +2124,7 @@ static void isr_scan_complete(struct ipw2100_priv *priv, u32 status)
                if (!delayed_work_pending(&priv->scan_event_later))
                        queue_delayed_work(priv->workqueue,
                                        &priv->scan_event_later,
-                                       round_jiffies(msecs_to_jiffies(4000)));
+                                       round_jiffies_relative(msecs_to_jiffies(4000)));
        } else {
                priv->user_requested_scan = 0;
                cancel_delayed_work(&priv->scan_event_later);
@@ -4242,7 +4243,7 @@ static int ipw_radio_kill_sw(struct ipw2100_priv *priv, int disable_radio)
                        priv->stop_rf_kill = 0;
                        cancel_delayed_work(&priv->rf_kill);
                        queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies(HZ));
+                                          round_jiffies_relative(HZ));
                } else
                        schedule_reset(priv);
        }
@@ -5981,7 +5982,7 @@ static void ipw2100_rf_kill(struct work_struct *work)
                IPW_DEBUG_RF_KILL("RF Kill active, rescheduling GPIO check\n");
                if (!priv->stop_rf_kill)
                        queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies(HZ));
+                                          round_jiffies_relative(HZ));
                goto exit_unlock;
        }
 
index e3c8284..54f44e5 100644 (file)
@@ -1753,7 +1753,7 @@ static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
                        /* Make sure the RF_KILL check timer is running */
                        cancel_delayed_work(&priv->rf_kill);
                        queue_delayed_work(priv->workqueue, &priv->rf_kill,
-                                          round_jiffies(2 * HZ));
+                                          round_jiffies_relative(2 * HZ));
                } else
                        queue_work(priv->workqueue, &priv->up);
        }
@@ -4364,7 +4364,7 @@ static void handle_scan_event(struct ipw_priv *priv)
        if (!priv->user_requested_scan) {
                if (!delayed_work_pending(&priv->scan_event))
                        queue_delayed_work(priv->workqueue, &priv->scan_event,
-                                        round_jiffies(msecs_to_jiffies(4000)));
+                                        round_jiffies_relative(msecs_to_jiffies(4000)));
        } else {
                union iwreq_data wrqu;
 
@@ -4728,7 +4728,7 @@ static void ipw_rx_notification(struct ipw_priv *priv,
                                 && priv->status & STATUS_ASSOCIATED)
                                queue_delayed_work(priv->workqueue,
                                                   &priv->request_scan,
-                                                  round_jiffies(HZ));
+                                                  round_jiffies_relative(HZ));
 
                        /* Send an empty event to user space.
                         * We don't send the received data on the event because
index 557deeb..891f90d 100644 (file)
@@ -3232,9 +3232,7 @@ int iwl4965_tx_cmd(struct iwl_priv *priv, struct iwl_cmd *out_cmd,
        tx->rate_n_flags = iwl_hw_set_rate_n_flags(iwl_rates[rate_index].plcp,
                                                rate_flags);
 
-       if (ieee80211_is_probe_request(fc))
-               tx->tx_flags |= TX_CMD_FLG_TSF_MSK;
-       else if (ieee80211_is_back_request(fc))
+       if (ieee80211_is_back_request(fc))
                tx->tx_flags |= TX_CMD_FLG_ACK_MSK |
                        TX_CMD_FLG_IMM_BA_RSP_MASK;
 #ifdef CONFIG_IWLWIFI_HT
@@ -3872,7 +3870,7 @@ static void iwl4965_rx_reply_rx(struct iwl_priv *priv,
                         */
                case IEEE80211_STYPE_ASSOC_RESP:
                case IEEE80211_STYPE_REASSOC_RESP:
-                       if (network_packet && iwl_is_associated(priv)) {
+                       if (network_packet) {
 #ifdef CONFIG_IWLWIFI_HT
                                u8 *pos = NULL;
                                struct ieee802_11_elems elems;
index 83019d1..4f22a71 100644 (file)
@@ -6478,8 +6478,9 @@ static void iwl_bg_scan_check(struct work_struct *data)
                IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN,
                          "Scan completion watchdog resetting adapter (%dms)\n",
                          jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
+
                if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
-                       queue_work(priv->workqueue, &priv->restart);
+                       iwl_send_scan_abort(priv);
        }
        mutex_unlock(&priv->mutex);
 }
@@ -6575,7 +6576,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
                spin_unlock_irqrestore(&priv->lock, flags);
 
                scan->suspend_time = 0;
-               scan->max_out_time = cpu_to_le32(600 * 1024);
+               scan->max_out_time = cpu_to_le32(200 * 1024);
                if (!interval)
                        interval = suspend_time;
                /*
@@ -6605,7 +6606,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
                memcpy(scan->direct_scan[0].ssid,
                       priv->direct_ssid, priv->direct_ssid_len);
                direct_mask = 1;
-       } else if (!iwl_is_associated(priv)) {
+       } else if (!iwl_is_associated(priv) && priv->essid_len) {
                scan->direct_scan[0].id = WLAN_EID_SSID;
                scan->direct_scan[0].len = priv->essid_len;
                memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
@@ -6744,6 +6745,12 @@ static void iwl_bg_post_associate(struct work_struct *data)
 
        mutex_lock(&priv->mutex);
 
+       if (!priv->interface_id || !priv->is_open) {
+               mutex_unlock(&priv->mutex);
+               return;
+       }
+       iwl_scan_cancel_timeout(priv, 200);
+
        conf = ieee80211_get_hw_conf(priv->hw);
 
        priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -6882,9 +6889,19 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
        struct iwl_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
+
+
+       mutex_lock(&priv->mutex);
+       /* stop mac, cancel any scan request and clear
+        * RXON_FILTER_ASSOC_MSK BIT
+        */
        priv->is_open = 0;
-       /*netif_stop_queue(dev); */
-       flush_workqueue(priv->workqueue);
+       iwl_scan_cancel_timeout(priv, 100);
+       cancel_delayed_work(&priv->post_associate);
+       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       iwl_commit_rxon(priv);
+       mutex_unlock(&priv->mutex);
+
        IWL_DEBUG_MAC80211("leave\n");
 }
 
@@ -7169,8 +7186,6 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
                        iwl_config_ap(priv);
                else {
-                       priv->staging_rxon.filter_flags |=
-                                               RXON_FILTER_ASSOC_MSK;
                        rc = iwl_commit_rxon(priv);
                        if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc)
                                iwl_add_station(priv,
@@ -7178,6 +7193,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                }
 
        } else {
+               iwl_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
                iwl_commit_rxon(priv);
        }
@@ -7217,6 +7233,12 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
        IWL_DEBUG_MAC80211("enter\n");
 
        mutex_lock(&priv->mutex);
+
+       iwl_scan_cancel_timeout(priv, 100);
+       cancel_delayed_work(&priv->post_associate);
+       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       iwl_commit_rxon(priv);
+
        if (priv->interface_id == conf->if_id) {
                priv->interface_id = 0;
                memset(priv->bssid, 0, ETH_ALEN);
@@ -7238,6 +7260,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
 
        IWL_DEBUG_MAC80211("enter\n");
 
+       mutex_lock(&priv->mutex);
        spin_lock_irqsave(&priv->lock, flags);
 
        if (!iwl_is_ready_rf(priv)) {
@@ -7268,7 +7291,8 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
                priv->direct_ssid_len = (u8)
                    min((u8) len, (u8) IW_ESSID_MAX_SIZE);
                memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
-       }
+       } else
+               priv->one_direct_scan = 0;
 
        rc = iwl_scan_initiate(priv);
 
@@ -7276,6 +7300,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
 
 out_unlock:
        spin_unlock_irqrestore(&priv->lock, flags);
+       mutex_unlock(&priv->mutex);
 
        return rc;
 }
@@ -7310,6 +7335,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        mutex_lock(&priv->mutex);
 
+       iwl_scan_cancel_timeout(priv, 100);
+
        switch (cmd) {
        case  SET_KEY:
                rc = iwl_update_sta_key_info(priv, key, sta_id);
@@ -7479,8 +7506,18 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
+       /* we are restarting association process
+        * clear RXON_FILTER_ASSOC_MSK bit
+       */
+       if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
+               iwl_scan_cancel_timeout(priv, 100);
+               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+               iwl_commit_rxon(priv);
+       }
+
        /* Per mac80211.h: This is only used in IBSS mode... */
        if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
+
                IWL_DEBUG_MAC80211("leave - not in IBSS\n");
                mutex_unlock(&priv->mutex);
                return;
@@ -8558,6 +8595,9 @@ static void iwl_pci_remove(struct pci_dev *pdev)
                iwl_rate_control_unregister(priv->hw);
        }
 
+       /*netif_stop_queue(dev); */
+       flush_workqueue(priv->workqueue);
+
        /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes
         * priv->workqueue... so we can't take down the workqueue
         * until now... */
index 5e12792..d60adcb 100644 (file)
@@ -6845,8 +6845,9 @@ static void iwl_bg_scan_check(struct work_struct *data)
                IWL_DEBUG(IWL_DL_INFO | IWL_DL_SCAN,
                          "Scan completion watchdog resetting adapter (%dms)\n",
                          jiffies_to_msecs(IWL_SCAN_CHECK_WATCHDOG));
+
                if (!test_bit(STATUS_EXIT_PENDING, &priv->status))
-                       queue_work(priv->workqueue, &priv->restart);
+                       iwl_send_scan_abort(priv);
        }
        mutex_unlock(&priv->mutex);
 }
@@ -6942,7 +6943,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
                spin_unlock_irqrestore(&priv->lock, flags);
 
                scan->suspend_time = 0;
-               scan->max_out_time = cpu_to_le32(600 * 1024);
+               scan->max_out_time = cpu_to_le32(200 * 1024);
                if (!interval)
                        interval = suspend_time;
 
@@ -6965,7 +6966,7 @@ static void iwl_bg_request_scan(struct work_struct *data)
                memcpy(scan->direct_scan[0].ssid,
                       priv->direct_ssid, priv->direct_ssid_len);
                direct_mask = 1;
-       } else if (!iwl_is_associated(priv)) {
+       } else if (!iwl_is_associated(priv) && priv->essid_len) {
                scan->direct_scan[0].id = WLAN_EID_SSID;
                scan->direct_scan[0].len = priv->essid_len;
                memcpy(scan->direct_scan[0].ssid, priv->essid, priv->essid_len);
@@ -7118,6 +7119,12 @@ static void iwl_bg_post_associate(struct work_struct *data)
 
        mutex_lock(&priv->mutex);
 
+       if (!priv->interface_id || !priv->is_open) {
+               mutex_unlock(&priv->mutex);
+               return;
+       }
+       iwl_scan_cancel_timeout(priv, 200);
+
        conf = ieee80211_get_hw_conf(priv->hw);
 
        priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
@@ -7271,9 +7278,19 @@ static void iwl_mac_stop(struct ieee80211_hw *hw)
        struct iwl_priv *priv = hw->priv;
 
        IWL_DEBUG_MAC80211("enter\n");
+
+
+       mutex_lock(&priv->mutex);
+       /* stop mac, cancel any scan request and clear
+        * RXON_FILTER_ASSOC_MSK BIT
+        */
        priv->is_open = 0;
-       /*netif_stop_queue(dev); */
-       flush_workqueue(priv->workqueue);
+       iwl_scan_cancel_timeout(priv, 100);
+       cancel_delayed_work(&priv->post_associate);
+       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       iwl_commit_rxon(priv);
+       mutex_unlock(&priv->mutex);
+
        IWL_DEBUG_MAC80211("leave\n");
 }
 
@@ -7573,8 +7590,6 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                if (priv->iw_mode == IEEE80211_IF_TYPE_AP)
                        iwl_config_ap(priv);
                else {
-                       priv->staging_rxon.filter_flags |=
-                                               RXON_FILTER_ASSOC_MSK;
                        rc = iwl_commit_rxon(priv);
                        if ((priv->iw_mode == IEEE80211_IF_TYPE_STA) && rc)
                                iwl_rxon_add_station(
@@ -7582,6 +7597,7 @@ static int iwl_mac_config_interface(struct ieee80211_hw *hw, int if_id,
                }
 
        } else {
+               iwl_scan_cancel_timeout(priv, 100);
                priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
                iwl_commit_rxon(priv);
        }
@@ -7621,6 +7637,12 @@ static void iwl_mac_remove_interface(struct ieee80211_hw *hw,
        IWL_DEBUG_MAC80211("enter\n");
 
        mutex_lock(&priv->mutex);
+
+       iwl_scan_cancel_timeout(priv, 100);
+       cancel_delayed_work(&priv->post_associate);
+       priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+       iwl_commit_rxon(priv);
+
        if (priv->interface_id == conf->if_id) {
                priv->interface_id = 0;
                memset(priv->bssid, 0, ETH_ALEN);
@@ -7642,6 +7664,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
 
        IWL_DEBUG_MAC80211("enter\n");
 
+       mutex_lock(&priv->mutex);
        spin_lock_irqsave(&priv->lock, flags);
 
        if (!iwl_is_ready_rf(priv)) {
@@ -7672,7 +7695,8 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
                priv->direct_ssid_len = (u8)
                    min((u8) len, (u8) IW_ESSID_MAX_SIZE);
                memcpy(priv->direct_ssid, ssid, priv->direct_ssid_len);
-       }
+       } else
+               priv->one_direct_scan = 0;
 
        rc = iwl_scan_initiate(priv);
 
@@ -7680,6 +7704,7 @@ static int iwl_mac_hw_scan(struct ieee80211_hw *hw, u8 *ssid, size_t len)
 
 out_unlock:
        spin_unlock_irqrestore(&priv->lock, flags);
+       mutex_unlock(&priv->mutex);
 
        return rc;
 }
@@ -7713,6 +7738,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
 
        mutex_lock(&priv->mutex);
 
+       iwl_scan_cancel_timeout(priv, 100);
+
        switch (cmd) {
        case  SET_KEY:
                rc = iwl_update_sta_key_info(priv, key, sta_id);
@@ -7903,8 +7930,18 @@ static void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
 
        spin_unlock_irqrestore(&priv->lock, flags);
 
+       /* we are restarting association process
+        * clear RXON_FILTER_ASSOC_MSK bit
+        */
+       if (priv->iw_mode != IEEE80211_IF_TYPE_AP) {
+               iwl_scan_cancel_timeout(priv, 100);
+               priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
+               iwl_commit_rxon(priv);
+       }
+
        /* Per mac80211.h: This is only used in IBSS mode... */
        if (priv->iw_mode != IEEE80211_IF_TYPE_IBSS) {
+
                IWL_DEBUG_MAC80211("leave - not in IBSS\n");
                mutex_unlock(&priv->mutex);
                return;
@@ -9152,6 +9189,9 @@ static void iwl_pci_remove(struct pci_dev *pdev)
                iwl_rate_control_unregister(priv->hw);
        }
 
+       /*netif_stop_queue(dev); */
+       flush_workqueue(priv->workqueue);
+
        /* ieee80211_unregister_hw calls iwl_mac_stop, which flushes
         * priv->workqueue... so we can't take down the workqueue
         * until now... */
index 298faa9..06d9bc0 100644 (file)
@@ -30,7 +30,7 @@
  * Interval defines
  * Both the link tuner as the rfkill will be called once per second.
  */
-#define LINK_TUNE_INTERVAL     ( round_jiffies(HZ) )
+#define LINK_TUNE_INTERVAL     ( round_jiffies_relative(HZ) )
 #define RFKILL_POLL_INTERVAL   ( 1000 )
 
 /*
index de61c8f..e454ae8 100644 (file)
@@ -433,6 +433,9 @@ static int rtl8187_start(struct ieee80211_hw *dev)
 
        rtl818x_iowrite16(priv, &priv->map->INT_MASK, 0xFFFF);
 
+       rtl818x_iowrite32(priv, &priv->map->MAR[0], ~0);
+       rtl818x_iowrite32(priv, &priv->map->MAR[1], ~0);
+
        rtl8187_init_urbs(dev);
 
        reg = RTL818X_RX_CONF_ONLYERLPKT |
@@ -582,32 +585,31 @@ static int rtl8187_config_interface(struct ieee80211_hw *dev, int if_id,
 static void rtl8187_configure_filter(struct ieee80211_hw *dev,
                                     unsigned int changed_flags,
                                     unsigned int *total_flags,
-                                    int mc_count, struct dev_addr_list *mc_list)
+                                    int mc_count, struct dev_addr_list *mclist)
 {
        struct rtl8187_priv *priv = dev->priv;
 
-       *total_flags = 0;
-
-       if (changed_flags & FIF_ALLMULTI)
-               priv->rx_conf ^= RTL818X_RX_CONF_MULTICAST;
        if (changed_flags & FIF_FCSFAIL)
                priv->rx_conf ^= RTL818X_RX_CONF_FCS;
        if (changed_flags & FIF_CONTROL)
                priv->rx_conf ^= RTL818X_RX_CONF_CTRL;
        if (changed_flags & FIF_OTHER_BSS)
                priv->rx_conf ^= RTL818X_RX_CONF_MONITOR;
-
-       if (mc_count > 0)
+       if (*total_flags & FIF_ALLMULTI || mc_count > 0)
                priv->rx_conf |= RTL818X_RX_CONF_MULTICAST;
+       else
+               priv->rx_conf &= ~RTL818X_RX_CONF_MULTICAST;
+
+       *total_flags = 0;
 
-       if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
-               *total_flags |= FIF_ALLMULTI;
        if (priv->rx_conf & RTL818X_RX_CONF_FCS)
                *total_flags |= FIF_FCSFAIL;
        if (priv->rx_conf & RTL818X_RX_CONF_CTRL)
                *total_flags |= FIF_CONTROL;
        if (priv->rx_conf & RTL818X_RX_CONF_MONITOR)
                *total_flags |= FIF_OTHER_BSS;
+       if (priv->rx_conf & RTL818X_RX_CONF_MULTICAST)
+               *total_flags |= FIF_ALLMULTI;
 
        rtl818x_iowrite32_async(priv, &priv->map->RX_CONF, priv->rx_conf);
 }
index 0c4ab3b..9b35259 100644 (file)
@@ -745,7 +745,7 @@ static char *fault_reason_strings[] =
        "non-zero reserved fields in PTE",
        "Unknown"
 };
-#define MAX_FAULT_REASON_IDX   ARRAY_SIZE(fault_reason_strings)
+#define MAX_FAULT_REASON_IDX   ARRAY_SIZE(fault_reason_strings) - 1
 
 char *dmar_get_fault_reason(u8 fault_reason)
 {
@@ -995,7 +995,6 @@ static struct intel_iommu *alloc_iommu(struct dmar_drhd_unit *drhd)
        return iommu;
 error_unmap:
        iounmap(iommu->reg);
-       iommu->reg = 0;
 error:
        kfree(iommu);
        return NULL;
@@ -1808,7 +1807,7 @@ get_valid_domain_for_dev(struct pci_dev *pdev)
        if (!domain) {
                printk(KERN_ERR
                        "Allocating domain for %s failed", pci_name(pdev));
-               return 0;
+               return NULL;
        }
 
        /* make sure context mapping is ok */
@@ -1818,7 +1817,7 @@ get_valid_domain_for_dev(struct pci_dev *pdev)
                        printk(KERN_ERR
                                "Domain context map for %s failed",
                                pci_name(pdev));
-                       return 0;
+                       return NULL;
                }
        }
 
index ee88dd2..459ad1f 100644 (file)
@@ -58,7 +58,7 @@
                hi = readl(dmar + reg + 4); \
                (((u64) hi) << 32) + lo; })
 */
-static inline u64 dmar_readq(void *addr)
+static inline u64 dmar_readq(void __iomem *addr)
 {
        u32 lo, hi;
        lo = readl(addr);
index fd5d0c1..0011849 100644 (file)
@@ -562,8 +562,6 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
        sg_init_table(sg_list->sg, sg_list->count);
 
        for (i = 0, sg = sg_list->sg; i < sg_list->count; i++, sg++) {
-               sg->length = min(size, PAGE_SIZE);
-               sg->offset = 0;
                address = (void *) get_zeroed_page(GFP_KERNEL);
                if (address == NULL) {
                        sg_list->count = i;
@@ -571,7 +569,7 @@ zfcp_sg_list_alloc(struct zfcp_sg_list *sg_list, size_t size)
                        retval = -ENOMEM;
                        goto out;
                }
-               zfcp_address_to_sg(address, sg);
+               zfcp_address_to_sg(address, sg, min(size, PAGE_SIZE));
                size -= sg->length;
        }
 
@@ -1518,13 +1516,13 @@ zfcp_gid_pn_buffers_alloc(struct zfcp_gid_pn_data **gid_pn, mempool_t *pool)
                 return -ENOMEM;
 
        memset(data, 0, sizeof(*data));
+       sg_init_table(&data->req , 1);
+       sg_init_table(&data->resp , 1);
         data->ct.req = &data->req;
         data->ct.resp = &data->resp;
        data->ct.req_count = data->ct.resp_count = 1;
-       zfcp_address_to_sg(&data->ct_iu_req, &data->req);
-        zfcp_address_to_sg(&data->ct_iu_resp, &data->resp);
-        data->req.length = sizeof(struct ct_iu_gid_pn_req);
-        data->resp.length = sizeof(struct ct_iu_gid_pn_resp);
+       zfcp_address_to_sg(&data->ct_iu_req, &data->req, sizeof(struct ct_iu_gid_pn_req));
+        zfcp_address_to_sg(&data->ct_iu_resp, &data->resp, sizeof(struct ct_iu_gid_pn_resp));
 
        *gid_pn = data;
        return 0;
index 326e7ee..e268f79 100644 (file)
@@ -70,12 +70,12 @@ zfcp_sg_to_address(struct scatterlist *list)
  * zfcp_address_to_sg - set up struct scatterlist from kernel address
  * @address: kernel address
  * @list: struct scatterlist
+ * @size: buffer size
  */
 static inline void
-zfcp_address_to_sg(void *address, struct scatterlist *list)
+zfcp_address_to_sg(void *address, struct scatterlist *list, unsigned int size)
 {
-       sg_set_page(list, virt_to_page(address));
-       list->offset = ((unsigned long) address) & (PAGE_SIZE - 1);
+       sg_set_buf(list, address, size);
 }
 
 #define REQUEST_LIST_SIZE 128
index 9438d0b..5552b75 100644 (file)
@@ -322,9 +322,9 @@ zfcp_erp_adisc(struct zfcp_port *port)
        if (address == NULL)
                goto nomem;
 
-       zfcp_address_to_sg(address, send_els->req);
+       zfcp_address_to_sg(address, send_els->req, sizeof(struct zfcp_ls_adisc));
        address += PAGE_SIZE >> 1;
-       zfcp_address_to_sg(address, send_els->resp);
+       zfcp_address_to_sg(address, send_els->resp, sizeof(struct zfcp_ls_adisc_acc));
        send_els->req_count = send_els->resp_count = 1;
 
        send_els->adapter = adapter;
@@ -336,9 +336,6 @@ zfcp_erp_adisc(struct zfcp_port *port)
        adisc = zfcp_sg_to_address(send_els->req);
        send_els->ls_code = adisc->code = ZFCP_LS_ADISC;
 
-       send_els->req->length = sizeof(struct zfcp_ls_adisc);
-       send_els->resp->length = sizeof(struct zfcp_ls_adisc_acc);
-
        /* acc. to FC-FS, hard_nport_id in ADISC should not be set for ports
           without FC-AL-2 capability, so we don't set it */
        adisc->wwpn = fc_host_port_name(adapter->scsi_host);
index 72b0393..1e6d7a9 100644 (file)
@@ -391,7 +391,7 @@ static int close_getadapter_fib(struct aac_dev * dev, void __user *arg)
                /*
                 *      Extract the fibctx from the input parameters
                 */
-               if (fibctx->unique == (u32)(ptrdiff_t)arg) /* We found a winner */
+               if (fibctx->unique == (u32)(uintptr_t)arg) /* We found a winner */
                        break;
                entry = entry->next;
                fibctx = NULL;
@@ -590,7 +590,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
                                }
                                addr = (u64)upsg->sg[i].addr[0];
                                addr += ((u64)upsg->sg[i].addr[1]) << 32;
-                               sg_user[i] = (void __user *)(ptrdiff_t)addr;
+                               sg_user[i] = (void __user *)(uintptr_t)addr;
                                sg_list[i] = p; // save so we can clean up later
                                sg_indx = i;
 
@@ -633,7 +633,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
                                        rcode = -ENOMEM;
                                        goto cleanup;
                                }
-                               sg_user[i] = (void __user *)(ptrdiff_t)usg->sg[i].addr;
+                               sg_user[i] = (void __user *)(uintptr_t)usg->sg[i].addr;
                                sg_list[i] = p; // save so we can clean up later
                                sg_indx = i;
 
@@ -664,7 +664,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
                if (actual_fibsize64 == fibsize) {
                        struct user_sgmap64* usg = (struct user_sgmap64 *)upsg;
                        for (i = 0; i < upsg->count; i++) {
-                               u64 addr;
+                               uintptr_t addr;
                                void* p;
                                /* Does this really need to be GFP_DMA? */
                                p = kmalloc(usg->sg[i].count,GFP_KERNEL|__GFP_DMA);
@@ -676,7 +676,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
                                }
                                addr = (u64)usg->sg[i].addr[0];
                                addr += ((u64)usg->sg[i].addr[1]) << 32;
-                               sg_user[i] = (void __user *)(ptrdiff_t)addr;
+                               sg_user[i] = (void __user *)addr;
                                sg_list[i] = p; // save so we can clean up later
                                sg_indx = i;
 
@@ -704,7 +704,7 @@ static int aac_send_raw_srb(struct aac_dev* dev, void __user * arg)
                                        rcode = -ENOMEM;
                                        goto cleanup;
                                }
-                               sg_user[i] = (void __user *)(ptrdiff_t)upsg->sg[i].addr;
+                               sg_user[i] = (void __user *)(uintptr_t)upsg->sg[i].addr;
                                sg_list[i] = p; // save so we can clean up later
                                sg_indx = i;
 
index 3009ad8..8736813 100644 (file)
@@ -110,7 +110,7 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
        /*
         *      Align the beginning of Headers to commalign
         */
-       align = (commalign - ((ptrdiff_t)(base) & (commalign - 1)));
+       align = (commalign - ((uintptr_t)(base) & (commalign - 1)));
        base = base + align;
        phys = phys + align;
        /*
index fcd25f7..e6032ff 100644 (file)
@@ -254,7 +254,7 @@ unsigned int aac_intr_normal(struct aac_dev * dev, u32 Index)
                        kfree (fib);
                        return 1;
                }
-               memcpy(hw_fib, (struct hw_fib *)(((ptrdiff_t)(dev->regs.sa)) +
+               memcpy(hw_fib, (struct hw_fib *)(((uintptr_t)(dev->regs.sa)) +
                  (index & ~0x00000002L)), sizeof(struct hw_fib));
                INIT_LIST_HEAD(&fib->fiblink);
                fib->type = FSAFS_NTC_FIB_CONTEXT;
index ace7a15..a67e29f 100644 (file)
@@ -141,14 +141,14 @@ struct CMD_MESSAGE_FIELD
 #define IS_SG64_ADDR                0x01000000 /* bit24 */
 struct  SG32ENTRY
 {
-       uint32_t                                        length;
-       uint32_t                                        address;
+       __le32                                  length;
+       __le32                                  address;
 };
 struct  SG64ENTRY
 {
-       uint32_t                                        length;
-       uint32_t                                        address;
-       uint32_t                                        addresshigh;
+       __le32                                  length;
+       __le32                                  address;
+       __le32                                  addresshigh;
 };
 struct SGENTRY_UNION
 {
@@ -339,23 +339,15 @@ struct MessageUnit_B
        uint32_t        done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE];
        uint32_t        postq_index;
        uint32_t        doneq_index;
-       uint32_t        *drv2iop_doorbell_reg;
-       uint32_t        *drv2iop_doorbell_mask_reg;
-       uint32_t        *iop2drv_doorbell_reg;
-       uint32_t        *iop2drv_doorbell_mask_reg;
-       uint32_t        *msgcode_rwbuffer_reg;
-       uint32_t        *ioctl_wbuffer_reg;
-       uint32_t        *ioctl_rbuffer_reg;
+       uint32_t        __iomem *drv2iop_doorbell_reg;
+       uint32_t        __iomem *drv2iop_doorbell_mask_reg;
+       uint32_t        __iomem *iop2drv_doorbell_reg;
+       uint32_t        __iomem *iop2drv_doorbell_mask_reg;
+       uint32_t        __iomem *msgcode_rwbuffer_reg;
+       uint32_t        __iomem *ioctl_wbuffer_reg;
+       uint32_t        __iomem *ioctl_rbuffer_reg;
 };
 
-struct MessageUnit
-{
-       union
-       {
-               struct MessageUnit_A    pmu_A;
-               struct MessageUnit_B    pmu_B;
-       } u;
-};
 /*
 *******************************************************************************
 **                 Adapter Control Block
@@ -374,7 +366,10 @@ struct AdapterControlBlock
        /* Offset is used in making arc cdb physical to virtual calculations */
        uint32_t                        outbound_int_enable;
 
-       struct MessageUnit *                    pmu;
+       union {
+               struct MessageUnit_A __iomem *  pmuA;
+               struct MessageUnit_B *          pmuB;
+       };
        /* message unit ATU inbound base address0 */
 
        uint32_t                        acb_flags;
@@ -558,7 +553,7 @@ struct SENSE_DATA
 
 extern void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *);
 extern void arcmsr_iop_message_read(struct AdapterControlBlock *);
-extern struct QBUFFER *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *);
+extern struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *);
 extern struct class_device_attribute *arcmsr_host_attrs[];
 extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *);
 void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb);
index d04d1aa..7d7b0a5 100644 (file)
@@ -85,13 +85,13 @@ static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj,
                allxfer_len++;
        }
        if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
-               struct QBUFFER *prbuffer;
-               uint8_t *iop_data;
+               struct QBUFFER __iomem *prbuffer;
+               uint8_t __iomem *iop_data;
                int32_t iop_len;
 
                acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
                prbuffer = arcmsr_get_iop_rqbuffer(acb);
-               iop_data = (uint8_t *)prbuffer->data;
+               iop_data = prbuffer->data;
                iop_len = readl(&prbuffer->data_len);
                while (iop_len > 0) {
                        acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data);
index f7a2528..d466a2d 100644 (file)
@@ -236,18 +236,22 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
                uint32_t intmask_org;
                int i, j;
 
-               acb->pmu = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
-               if (!acb->pmu) {
+               acb->pmuA = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0));
+               if (!acb->pmuA) {
                        printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n",
                                                        acb->host->host_no);
+                       return -ENOMEM;
                }
 
                dma_coherent = dma_alloc_coherent(&pdev->dev,
                        ARCMSR_MAX_FREECCB_NUM *
                        sizeof (struct CommandControlBlock) + 0x20,
                        &dma_coherent_handle, GFP_KERNEL);
-               if (!dma_coherent)
+
+               if (!dma_coherent) {
+                       iounmap(acb->pmuA);
                        return -ENOMEM;
+               }
 
                acb->dma_coherent = dma_coherent;
                acb->dma_coherent_handle = dma_coherent_handle;
@@ -287,7 +291,7 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
 
                struct pci_dev *pdev = acb->pdev;
                struct MessageUnit_B *reg;
-               void *mem_base0, *mem_base1;
+               void __iomem *mem_base0, *mem_base1;
                void *dma_coherent;
                dma_addr_t dma_coherent_handle, dma_addr;
                uint32_t intmask_org;
@@ -328,25 +332,28 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
 
                reg = (struct MessageUnit_B *)(dma_coherent +
                ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock));
-               acb->pmu = (struct MessageUnit *)reg;
+               acb->pmuB = reg;
                mem_base0 = ioremap(pci_resource_start(pdev, 0),
                                        pci_resource_len(pdev, 0));
+               if (!mem_base0)
+                       goto out;
+
                mem_base1 = ioremap(pci_resource_start(pdev, 2),
                                        pci_resource_len(pdev, 2));
-               reg->drv2iop_doorbell_reg = (uint32_t *)((char *)mem_base0 +
-                                               ARCMSR_DRV2IOP_DOORBELL);
-               reg->drv2iop_doorbell_mask_reg = (uint32_t *)((char *)mem_base0 +
-                                               ARCMSR_DRV2IOP_DOORBELL_MASK);
-               reg->iop2drv_doorbell_reg = (uint32_t *)((char *)mem_base0 +
-                                                       ARCMSR_IOP2DRV_DOORBELL);
-               reg->iop2drv_doorbell_mask_reg = (uint32_t *)((char *)mem_base0 +
-                                               ARCMSR_IOP2DRV_DOORBELL_MASK);
-               reg->ioctl_wbuffer_reg = (uint32_t *)((char *)mem_base1 +
-                                                       ARCMSR_IOCTL_WBUFFER);
-               reg->ioctl_rbuffer_reg = (uint32_t *)((char *)mem_base1 +
-                                                       ARCMSR_IOCTL_RBUFFER);
-               reg->msgcode_rwbuffer_reg = (uint32_t *)((char *)mem_base1 +
-                                                       ARCMSR_MSGCODE_RWBUFFER);
+               if (!mem_base1) {
+                       iounmap(mem_base0);
+                       goto out;
+               }
+
+               reg->drv2iop_doorbell_reg = mem_base0 + ARCMSR_DRV2IOP_DOORBELL;
+               reg->drv2iop_doorbell_mask_reg = mem_base0 +
+                                               ARCMSR_DRV2IOP_DOORBELL_MASK;
+               reg->iop2drv_doorbell_reg = mem_base0 + ARCMSR_IOP2DRV_DOORBELL;
+               reg->iop2drv_doorbell_mask_reg = mem_base0 +
+                                               ARCMSR_IOP2DRV_DOORBELL_MASK;
+               reg->ioctl_wbuffer_reg = mem_base1 + ARCMSR_IOCTL_WBUFFER;
+               reg->ioctl_rbuffer_reg = mem_base1 + ARCMSR_IOCTL_RBUFFER;
+               reg->msgcode_rwbuffer_reg = mem_base1 + ARCMSR_MSGCODE_RWBUFFER;
 
                acb->vir2phy_offset = (unsigned long)ccb_tmp -(unsigned long)dma_addr;
                for (i = 0; i < ARCMSR_MAX_TARGETID; i++)
@@ -362,6 +369,12 @@ static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb)
                break;
        }
        return 0;
+
+out:
+       dma_free_coherent(&acb->pdev->dev,
+               ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock) + 0x20,
+               acb->dma_coherent, acb->dma_coherent_handle);
+       return -ENOMEM;
 }
 
 static int arcmsr_probe(struct pci_dev *pdev,
@@ -454,7 +467,6 @@ static int arcmsr_probe(struct pci_dev *pdev,
        free_irq(pdev->irq, acb);
  out_free_ccb_pool:
        arcmsr_free_ccb_pool(acb);
-       iounmap(acb->pmu);
  out_release_regions:
        pci_release_regions(pdev);
  out_host_put:
@@ -467,7 +479,7 @@ static int arcmsr_probe(struct pci_dev *pdev,
 
 static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
        uint32_t Index;
        uint8_t Retries = 0x00;
 
@@ -488,7 +500,7 @@ static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb)
 
 static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+       struct MessageUnit_B *reg = acb->pmuB;
        uint32_t Index;
        uint8_t Retries = 0x00;
 
@@ -509,7 +521,7 @@ static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb)
 
 static void arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
 
        writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, &reg->inbound_msgaddr0);
        if (arcmsr_hba_wait_msgint_ready(acb))
@@ -520,7 +532,7 @@ static void arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb)
 
 static void arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+       struct MessageUnit_B *reg = acb->pmuB;
 
        writel(ARCMSR_MESSAGE_ABORT_CMD, reg->drv2iop_doorbell_reg);
        if (arcmsr_hbb_wait_msgint_ready(acb))
@@ -566,7 +578,7 @@ static void arcmsr_ccb_complete(struct CommandControlBlock *ccb, int stand_flag)
 
 static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
        int retry_count = 30;
 
        writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, &reg->inbound_msgaddr0);
@@ -583,7 +595,7 @@ static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb)
 
 static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+       struct MessageUnit_B *reg = acb->pmuB;
        int retry_count = 30;
 
        writel(ARCMSR_MESSAGE_FLUSH_CACHE, reg->drv2iop_doorbell_reg);
@@ -637,7 +649,7 @@ static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb)
        switch (acb->adapter_type) {
 
        case ACB_ADAPTER_TYPE_A : {
-               struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
                orig_mask = readl(&reg->outbound_intmask)|\
                                ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE;
                writel(orig_mask|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, \
@@ -646,7 +658,7 @@ static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb)
                break;
 
        case ACB_ADAPTER_TYPE_B : {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                orig_mask = readl(reg->iop2drv_doorbell_mask_reg) & \
                                        (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE);
                writel(0, reg->iop2drv_doorbell_mask_reg);
@@ -748,14 +760,13 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
        switch (acb->adapter_type) {
 
        case ACB_ADAPTER_TYPE_A: {
-               struct MessageUnit_A __iomem *reg = \
-                       (struct MessageUnit_A *)acb->pmu;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
                uint32_t outbound_intstatus;
-               outbound_intstatus = readl(&reg->outbound_intstatus) & \
+               outbound_intstatus = readl(&reg->outbound_intstatus) &
                                        acb->outbound_int_enable;
                /*clear and abort all outbound posted Q*/
                writel(outbound_intstatus, &reg->outbound_intstatus);/*clear interrupt*/
-               while (((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF) \
+               while (((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF)
                                && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) {
                        arcmsr_drain_donequeue(acb, flag_ccb);
                }
@@ -763,7 +774,7 @@ static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb)
                break;
 
        case ACB_ADAPTER_TYPE_B: {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                /*clear all outbound posted Q*/
                for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) {
                        if ((flag_ccb = readl(&reg->done_qbuffer[i])) != 0) {
@@ -816,7 +827,6 @@ static void arcmsr_remove(struct pci_dev *pdev)
        }
 
        free_irq(pdev->irq, acb);
-       iounmap(acb->pmu);
        arcmsr_free_ccb_pool(acb);
        pci_release_regions(pdev);
 
@@ -859,7 +869,7 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, \
        switch (acb->adapter_type) {
 
        case ACB_ADAPTER_TYPE_A : {
-               struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
                mask = intmask_org & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE |
                             ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE);
                writel(mask, &reg->outbound_intmask);
@@ -868,7 +878,7 @@ static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, \
                break;
 
        case ACB_ADAPTER_TYPE_B : {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                mask = intmask_org | (ARCMSR_IOP2DRV_DATA_WRITE_OK | \
                        ARCMSR_IOP2DRV_DATA_READ_OK | ARCMSR_IOP2DRV_CDB_DONE);
                writel(mask, reg->iop2drv_doorbell_mask_reg);
@@ -882,7 +892,7 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
 {
        struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb;
        int8_t *psge = (int8_t *)&arcmsr_cdb->u;
-       uint32_t address_lo, address_hi;
+       __le32 address_lo, address_hi;
        int arccdbsize = 0x30;
        int nseg;
 
@@ -900,7 +910,8 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
        BUG_ON(nseg < 0);
 
        if (nseg) {
-               int length, i, cdb_sgcount = 0;
+               __le32 length;
+               int i, cdb_sgcount = 0;
                struct scatterlist *sg;
 
                /* map stor port SG list to our iop SG List. */
@@ -921,7 +932,7 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb,
 
                                pdma_sg->addresshigh = address_hi;
                                pdma_sg->address = address_lo;
-                               pdma_sg->length = length|IS_SG64_ADDR;
+                               pdma_sg->length = length|cpu_to_le32(IS_SG64_ADDR);
                                psge += sizeof (struct SG64ENTRY);
                                arccdbsize += sizeof (struct SG64ENTRY);
                        }
@@ -947,7 +958,7 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
 
        switch (acb->adapter_type) {
        case ACB_ADAPTER_TYPE_A: {
-               struct MessageUnit_A *reg = (struct MessageUnit_A *)acb->pmu;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
 
                if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE)
                        writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,
@@ -959,7 +970,7 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
                break;
 
        case ACB_ADAPTER_TYPE_B: {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                uint32_t ending_index, index = reg->postq_index;
 
                ending_index = ((index + 1) % ARCMSR_MAX_HBB_POSTQUEUE);
@@ -982,7 +993,7 @@ static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandContr
 
 static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
        acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
        writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, &reg->inbound_msgaddr0);
 
@@ -995,7 +1006,7 @@ static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb)
 
 static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+       struct MessageUnit_B *reg = acb->pmuB;
        acb->acb_flags &= ~ACB_F_MSG_START_BGRB;
        writel(ARCMSR_MESSAGE_STOP_BGRB, reg->drv2iop_doorbell_reg);
 
@@ -1023,6 +1034,17 @@ static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb)
 
 static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb)
 {
+       switch (acb->adapter_type) {
+       case ACB_ADAPTER_TYPE_A: {
+               iounmap(acb->pmuA);
+               break;
+       }
+       case ACB_ADAPTER_TYPE_B: {
+               struct MessageUnit_B *reg = acb->pmuB;
+               iounmap(reg->drv2iop_doorbell_reg - ARCMSR_DRV2IOP_DOORBELL);
+               iounmap(reg->ioctl_wbuffer_reg - ARCMSR_IOCTL_WBUFFER);
+       }
+       }
        dma_free_coherent(&acb->pdev->dev,
                ARCMSR_MAX_FREECCB_NUM * sizeof (struct CommandControlBlock) + 0x20,
                acb->dma_coherent,
@@ -1033,13 +1055,13 @@ void arcmsr_iop_message_read(struct AdapterControlBlock *acb)
 {
        switch (acb->adapter_type) {
        case ACB_ADAPTER_TYPE_A: {
-               struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
                writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, &reg->inbound_doorbell);
                }
                break;
 
        case ACB_ADAPTER_TYPE_B: {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell_reg);
                }
                break;
@@ -1050,7 +1072,7 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
 {
        switch (acb->adapter_type) {
        case ACB_ADAPTER_TYPE_A: {
-               struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
                /*
                ** push inbound doorbell tell iop, driver data write ok
                ** and wait reply on next hwinterrupt for next Qbuffer post
@@ -1060,7 +1082,7 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
                break;
 
        case ACB_ADAPTER_TYPE_B: {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                /*
                ** push inbound doorbell tell iop, driver data write ok
                ** and wait reply on next hwinterrupt for next Qbuffer post
@@ -1071,41 +1093,41 @@ static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb)
        }
 }
 
-struct QBUFFER *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb)
+struct QBUFFER __iomem *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb)
 {
-       static struct QBUFFER *qbuffer;
+       struct QBUFFER __iomem *qbuffer = NULL;
 
        switch (acb->adapter_type) {
 
        case ACB_ADAPTER_TYPE_A: {
-               struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
-               qbuffer = (struct QBUFFER __iomem *) &reg->message_rbuffer;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
+               qbuffer = (struct QBUFFER __iomem *)&reg->message_rbuffer;
                }
                break;
 
        case ACB_ADAPTER_TYPE_B: {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
-               qbuffer = (struct QBUFFER __iomem *) reg->ioctl_rbuffer_reg;
+               struct MessageUnit_B *reg = acb->pmuB;
+               qbuffer = (struct QBUFFER __iomem *)reg->ioctl_rbuffer_reg;
                }
                break;
        }
        return qbuffer;
 }
 
-static struct QBUFFER *arcmsr_get_iop_wqbuffer(struct AdapterControlBlock *acb)
+static struct QBUFFER __iomem *arcmsr_get_iop_wqbuffer(struct AdapterControlBlock *acb)
 {
-       static struct QBUFFER *pqbuffer;
+       struct QBUFFER __iomem *pqbuffer = NULL;
 
        switch (acb->adapter_type) {
 
        case ACB_ADAPTER_TYPE_A: {
-               struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
-               pqbuffer = (struct QBUFFER *) &reg->message_wbuffer;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
+               pqbuffer = (struct QBUFFER __iomem *) &reg->message_wbuffer;
                }
                break;
 
        case ACB_ADAPTER_TYPE_B: {
-               struct MessageUnit_B  *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B  *reg = acb->pmuB;
                pqbuffer = (struct QBUFFER __iomem *)reg->ioctl_wbuffer_reg;
                }
                break;
@@ -1115,15 +1137,15 @@ static struct QBUFFER *arcmsr_get_iop_wqbuffer(struct AdapterControlBlock *acb)
 
 static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb)
 {
-       struct QBUFFER *prbuffer;
+       struct QBUFFER __iomem *prbuffer;
        struct QBUFFER *pQbuffer;
-       uint8_t *iop_data;
+       uint8_t __iomem *iop_data;
        int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex;
 
        rqbuf_lastindex = acb->rqbuf_lastindex;
        rqbuf_firstindex = acb->rqbuf_firstindex;
        prbuffer = arcmsr_get_iop_rqbuffer(acb);
-       iop_data = (uint8_t *)prbuffer->data;
+       iop_data = (uint8_t __iomem *)prbuffer->data;
        iop_len = prbuffer->data_len;
        my_empty_len = (rqbuf_firstindex - rqbuf_lastindex -1)&(ARCMSR_MAX_QBUFFER -1);
 
@@ -1151,8 +1173,8 @@ static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
        acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED;
        if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) {
                uint8_t *pQbuffer;
-               struct QBUFFER *pwbuffer;
-               uint8_t *iop_data;
+               struct QBUFFER __iomem *pwbuffer;
+               uint8_t __iomem *iop_data;
                int32_t allxfer_len = 0;
 
                acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED);
@@ -1181,7 +1203,7 @@ static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb)
 static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
 {
        uint32_t outbound_doorbell;
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
 
        outbound_doorbell = readl(&reg->outbound_doorbell);
        writel(outbound_doorbell, &reg->outbound_doorbell);
@@ -1197,7 +1219,7 @@ static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb)
 static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb)
 {
        uint32_t flag_ccb;
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
 
        while ((flag_ccb = readl(&reg->outbound_queueport)) != 0xFFFFFFFF) {
                arcmsr_drain_donequeue(acb, flag_ccb);
@@ -1208,7 +1230,7 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
 {
        uint32_t index;
        uint32_t flag_ccb;
-       struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+       struct MessageUnit_B *reg = acb->pmuB;
 
        index = reg->doneq_index;
 
@@ -1224,7 +1246,7 @@ static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb)
 static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb)
 {
        uint32_t outbound_intstatus;
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
 
        outbound_intstatus = readl(&reg->outbound_intstatus) & \
                                                        acb->outbound_int_enable;
@@ -1244,7 +1266,7 @@ static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb)
 static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb)
 {
        uint32_t outbound_doorbell;
-       struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+       struct MessageUnit_B *reg = acb->pmuB;
 
        outbound_doorbell = readl(reg->iop2drv_doorbell_reg) & \
                                                        acb->outbound_int_enable;
@@ -1305,8 +1327,8 @@ void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb)
 {
        int32_t wqbuf_firstindex, wqbuf_lastindex;
        uint8_t *pQbuffer;
-       struct QBUFFER *pwbuffer;
-       uint8_t *iop_data;
+       struct QBUFFER __iomem *pwbuffer;
+       uint8_t __iomem *iop_data;
        int32_t allxfer_len = 0;
 
        pwbuffer = arcmsr_get_iop_wqbuffer(acb);
@@ -1380,13 +1402,13 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \
                }
                if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) {
 
-                       struct QBUFFER *prbuffer;
-                       uint8_t *iop_data;
+                       struct QBUFFER __iomem *prbuffer;
+                       uint8_t __iomem *iop_data;
                        int32_t iop_len;
 
                        acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW;
                        prbuffer = arcmsr_get_iop_rqbuffer(acb);
-                       iop_data = (uint8_t *)prbuffer->data;
+                       iop_data = prbuffer->data;
                        iop_len = readl(&prbuffer->data_len);
                        while (iop_len > 0) {
                                acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data);
@@ -1669,11 +1691,11 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd,
 
 static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
        char *acb_firm_model = acb->firm_model;
        char *acb_firm_version = acb->firm_version;
-       char *iop_firm_model = (char *) (&reg->message_rwbuffer[15]);
-       char *iop_firm_version = (char *) (&reg->message_rwbuffer[17]);
+       char __iomem *iop_firm_model = (char __iomem *)(&reg->message_rwbuffer[15]);
+       char __iomem *iop_firm_version = (char __iomem *)(&reg->message_rwbuffer[17]);
        int count;
 
        writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, &reg->inbound_msgaddr0);
@@ -1710,13 +1732,13 @@ static void arcmsr_get_hba_config(struct AdapterControlBlock *acb)
 
 static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
-       uint32_t *lrwbuffer = reg->msgcode_rwbuffer_reg;
+       struct MessageUnit_B *reg = acb->pmuB;
+       uint32_t __iomem *lrwbuffer = reg->msgcode_rwbuffer_reg;
        char *acb_firm_model = acb->firm_model;
        char *acb_firm_version = acb->firm_version;
-       char *iop_firm_model = (char *) (&lrwbuffer[15]);
+       char __iomem *iop_firm_model = (char __iomem *)(&lrwbuffer[15]);
        /*firm_model,15,60-67*/
-       char *iop_firm_version = (char *) (&lrwbuffer[17]);
+       char __iomem *iop_firm_version = (char __iomem *)(&lrwbuffer[17]);
        /*firm_version,17,68-83*/
        int count;
 
@@ -1777,7 +1799,7 @@ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb)
 static void arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,
        struct CommandControlBlock *poll_ccb)
 {
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
        struct CommandControlBlock *ccb;
        uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0;
 
@@ -1826,7 +1848,7 @@ static void arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb,
 static void arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, \
                                        struct CommandControlBlock *poll_ccb)
 {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                struct CommandControlBlock *ccb;
                uint32_t flag_ccb, poll_ccb_done = 0, poll_count = 0;
                int index;
@@ -1918,8 +1940,7 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
 
        case ACB_ADAPTER_TYPE_A: {
                if (ccb_phyaddr_hi32 != 0) {
-                       struct MessageUnit_A __iomem *reg = \
-                                       (struct MessageUnit_A *)acb->pmu;
+                       struct MessageUnit_A __iomem *reg = acb->pmuA;
                        uint32_t intmask_org;
                        intmask_org = arcmsr_disable_outbound_ints(acb);
                        writel(ARCMSR_SIGNATURE_SET_CONFIG, \
@@ -1940,9 +1961,9 @@ static int arcmsr_iop_confirm(struct AdapterControlBlock *acb)
 
        case ACB_ADAPTER_TYPE_B: {
                unsigned long post_queue_phyaddr;
-               uint32_t *rwbuffer;
+               uint32_t __iomem *rwbuffer;
 
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                uint32_t intmask_org;
                intmask_org = arcmsr_disable_outbound_ints(acb);
                reg->postq_index = 0;
@@ -1994,7 +2015,7 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
        switch (acb->adapter_type) {
 
        case ACB_ADAPTER_TYPE_A: {
-               struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
                do {
                        firmware_state = readl(&reg->outbound_msgaddr1);
                } while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0);
@@ -2002,7 +2023,7 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
                break;
 
        case ACB_ADAPTER_TYPE_B: {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                do {
                        firmware_state = readl(reg->iop2drv_doorbell_reg);
                } while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0);
@@ -2013,7 +2034,7 @@ static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb)
 
 static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu;
+       struct MessageUnit_A __iomem *reg = acb->pmuA;
        acb->acb_flags |= ACB_F_MSG_START_BGRB;
        writel(ARCMSR_INBOUND_MESG0_START_BGRB, &reg->inbound_msgaddr0);
        if (arcmsr_hba_wait_msgint_ready(acb)) {
@@ -2024,7 +2045,7 @@ static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb)
 
 static void arcmsr_start_hbb_bgrb(struct AdapterControlBlock *acb)
 {
-       struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+       struct MessageUnit_B *reg = acb->pmuB;
        acb->acb_flags |= ACB_F_MSG_START_BGRB;
        writel(ARCMSR_MESSAGE_START_BGRB, reg->drv2iop_doorbell_reg);
        if (arcmsr_hbb_wait_msgint_ready(acb)) {
@@ -2049,7 +2070,7 @@ static void arcmsr_clear_doorbell_queue_buffer(struct AdapterControlBlock *acb)
 {
        switch (acb->adapter_type) {
        case ACB_ADAPTER_TYPE_A: {
-               struct MessageUnit_A *reg = (struct MessageUnit_A *)acb->pmu;
+               struct MessageUnit_A __iomem *reg = acb->pmuA;
                uint32_t outbound_doorbell;
                /* empty doorbell Qbuffer if door bell ringed */
                outbound_doorbell = readl(&reg->outbound_doorbell);
@@ -2060,7 +2081,7 @@ static void arcmsr_clear_doorbell_queue_buffer(struct AdapterControlBlock *acb)
                break;
 
        case ACB_ADAPTER_TYPE_B: {
-               struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu;
+               struct MessageUnit_B *reg = acb->pmuB;
                /*clear interrupt and message state*/
                writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell_reg);
                writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell_reg);
index d178098..a9680b5 100644 (file)
@@ -477,10 +477,9 @@ static void merge_contiguous_buffers(Scsi_Cmnd *cmd)
 
        for (endaddr = virt_to_phys(cmd->SCp.ptr + cmd->SCp.this_residual - 1) + 1;
             cmd->SCp.buffers_residual &&
-            virt_to_phys(page_address(cmd->SCp.buffer[1].page) +
-                         cmd->SCp.buffer[1].offset) == endaddr;) {
+            virt_to_phys(sg_virt(&cmd->SCp.buffer[1])) == endaddr;) {
                MER_PRINTK("VTOP(%p) == %08lx -> merging\n",
-                          page_address(cmd->SCp.buffer[1].page), endaddr);
+                          page_address(sg_page(&cmd->SCp.buffer[1])), endaddr);
 #if (NDEBUG & NDEBUG_MERGING)
                ++cnt;
 #endif
index 439b97a..0841df0 100644 (file)
@@ -2890,7 +2890,7 @@ static struct ipr_sglist *ipr_alloc_ucode_buffer(int buf_len)
                        return NULL;
                }
 
-               sg_set_page(&scatterlist[i], page);
+               sg_set_page(&scatterlist[i], page, 0, 0);
        }
 
        return sglist;
index 6ce4109..4bcf916 100644 (file)
@@ -79,9 +79,7 @@ static inline void
 iscsi_buf_init_sg(struct iscsi_buf *ibuf, struct scatterlist *sg)
 {
        sg_init_table(&ibuf->sg, 1);
-       sg_set_page(&ibuf->sg, sg_page(sg));
-       ibuf->sg.offset = sg->offset;
-       ibuf->sg.length = sg->length;
+       sg_set_page(&ibuf->sg, sg_page(sg), sg->length, sg->offset);
        /*
         * Fastpath: sg element fits into single page
         */
@@ -676,9 +674,8 @@ partial_sg_digest_update(struct hash_desc *desc, struct scatterlist *sg,
 {
        struct scatterlist temp;
 
-       memcpy(&temp, sg, sizeof(struct scatterlist));
-       temp.offset = offset;
-       temp.length = length;
+       sg_init_table(&temp, 1);
+       sg_set_page(&temp, sg_page(sg), length, offset);
        crypto_hash_update(desc, &temp, length);
 }
 
index 1c5c4b6..4652ad2 100644 (file)
@@ -5256,8 +5256,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
 
                STbuffer->sg[0].offset = 0;
                if (page != NULL) {
-                   sg_set_page(&STbuffer->sg[0], page);
-                   STbuffer->sg[0].length = b_size;
+                   sg_set_page(&STbuffer->sg[0], page, b_size, 0);
                    STbuffer->b_data = page_address(page);
                    break;
                }
@@ -5285,8 +5284,7 @@ static int enlarge_buffer(struct osst_buffer *STbuffer, int need_dma)
                        normalize_buffer(STbuffer);
                        return 0;
                }
-               sg_set_page(&STbuffer->sg[segs], page);
-               STbuffer->sg[segs].length = (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size;
+               sg_set_page(&STbuffer->sg[segs], page, (OS_FRAME_SIZE - got <= PAGE_SIZE / 2) ? (OS_FRAME_SIZE - got) : b_size, 0);
                got += STbuffer->sg[segs].length;
                STbuffer->buffer_size = got;
                STbuffer->sg_segs = ++segs;
index cc19710..f1871ea 100644 (file)
@@ -1652,6 +1652,7 @@ sg_build_sgat(Sg_scatter_hold * schp, const Sg_fd * sfp, int tablesize)
        schp->buffer = kzalloc(sg_bufflen, gfp_flags);
        if (!schp->buffer)
                return -ENOMEM;
+       sg_init_table(schp->buffer, tablesize);
        schp->sglist_len = sg_bufflen;
        return tablesize;       /* number of scat_gath elements allocated */
 }
@@ -1717,16 +1718,12 @@ st_map_user_pages(struct scatterlist *sgl, const unsigned int max_pages,
                   goto out_unlock; */
         }
 
-       sg_set_page(sgl, pages[0]);
-       sgl[0].offset = uaddr & ~PAGE_MASK;
+       sg_set_page(sgl, pages[0], 0, uaddr & ~PAGE_MASK);
        if (nr_pages > 1) {
                sgl[0].length = PAGE_SIZE - sgl[0].offset;
                count -= sgl[0].length;
-               for (i=1; i < nr_pages ; i++) {
-                       sg_set_page(&sgl[i], pages[i]);
-                       sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
-                       count -= PAGE_SIZE;
-               }
+               for (i=1; i < nr_pages ; i++)
+                       sg_set_page(&sgl[i], pages[i], count < PAGE_SIZE ? count : PAGE_SIZE, 0);
        }
        else {
                sgl[0].length = count;
@@ -1854,8 +1851,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
                                scatter_elem_sz_prev = ret_sz;
                        }
                }
-               sg_set_page(sg, p);
-               sg->length = (ret_sz > num) ? num : ret_sz;
+               sg_set_page(sg, p, (ret_sz > num) ? num : ret_sz, 0);
 
                SCSI_LOG_TIMEOUT(5, printk("sg_build_indirect: k=%d, num=%d, "
                                 "ret_sz=%d\n", k, num, ret_sz));
index ce69b9e..98dfd6e 100644 (file)
@@ -3797,13 +3797,11 @@ static void buf_to_sg(struct st_buffer *STbp, unsigned int length)
        sg = &(STbp->sg[0]);
        frp = STbp->frp;
        for (i=count=0; count < length; i++) {
-               sg_set_page(&sg[i], frp[i].page);
                if (length - count > frp[i].length)
-                       sg[i].length = frp[i].length;
+                       sg_set_page(&sg[i], frp[i].page, frp[i].length, 0);
                else
-                       sg[i].length = length - count;
+                       sg_set_page(&sg[i], frp[i].page, length - count, 0);
                count += sg[i].length;
-               sg[i].offset = 0;
        }
        STbp->sg_segs = i;
        STbp->frp_sg_current = length;
@@ -4446,15 +4444,13 @@ static int sgl_map_user_pages(struct scatterlist *sgl, const unsigned int max_pa
         }
 
        /* Populate the scatter/gather list */
-       sg_set_page(&sgl[0], pages[0]);
-       sgl[0].offset = uaddr & ~PAGE_MASK;
+       sg_set_page(&sgl[0], pages[0], 0, uaddr & ~PAGE_MASK);
        if (nr_pages > 1) {
                sgl[0].length = PAGE_SIZE - sgl[0].offset;
                count -= sgl[0].length;
                for (i=1; i < nr_pages ; i++) {
-                       sg_set_page(&sgl[i], pages[i]);;
-                       sgl[i].offset = 0;
-                       sgl[i].length = count < PAGE_SIZE ? count : PAGE_SIZE;
+                       sg_set_page(&sgl[i], pages[i],
+                                   count < PAGE_SIZE ? count : PAGE_SIZE, 0);;
                        count -= PAGE_SIZE;
                }
        }
index 80fb3f8..1bc4190 100644 (file)
@@ -332,8 +332,8 @@ static void dma_mmu_get_scsi_sgl (struct NCR_ESP *esp, Scsi_Cmnd *sp)
     struct scatterlist *sg = sp->SCp.buffer;
 
     while (sz >= 0) {
-           sg[sz].dma_address = dvma_map((unsigned long)page_address(sg[sz].page) +
-                                          sg[sz].offset, sg[sz].length);
+           sg[sz].dma_address = dvma_map((unsigned long)sg_virt(&sg[sz]),
+                                         sg[sz].length);
            sz--;
     }
     sp->SCp.ptr=(char *)((unsigned long)sp->SCp.buffer->dma_address);
index 1031890..3bb5d24 100644 (file)
@@ -1875,6 +1875,7 @@ uart_set_options(struct uart_port *port, struct console *co,
                 int baud, int parity, int bits, int flow)
 {
        struct ktermios termios;
+       static struct ktermios dummy;
        int i;
 
        /*
@@ -1920,7 +1921,7 @@ uart_set_options(struct uart_port *port, struct console *co,
         */
        port->mctrl |= TIOCM_DTR;
 
-       port->ops->set_termios(port, &termios, NULL);
+       port->ops->set_termios(port, &termios, &dummy);
        co->cflag = termios.c_cflag;
 
        return 0;
index 5afcb2f..d8b6600 100644 (file)
@@ -345,7 +345,7 @@ static int serial_probe(struct pcmcia_device *link)
 
        link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
        link->io.NumPorts1 = 8;
-       link->irq.Attributes = IRQ_TYPE_EXCLUSIVE;
+       link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING;
        link->irq.IRQInfo1 = IRQ_LEVEL_ID;
        link->conf.Attributes = CONF_ENABLE_IRQ;
        if (do_sound) {
index c55459c..b3518ca 100644 (file)
@@ -184,14 +184,14 @@ static int spidev_message(struct spidev_data *spidev,
                if (u_tmp->rx_buf) {
                        k_tmp->rx_buf = buf;
                        if (!access_ok(VERIFY_WRITE, (u8 __user *)
-                                               (ptrdiff_t) u_tmp->rx_buf,
+                                               (uintptr_t) u_tmp->rx_buf,
                                                u_tmp->len))
                                goto done;
                }
                if (u_tmp->tx_buf) {
                        k_tmp->tx_buf = buf;
                        if (copy_from_user(buf, (const u8 __user *)
-                                               (ptrdiff_t) u_tmp->tx_buf,
+                                               (uintptr_t) u_tmp->tx_buf,
                                        u_tmp->len))
                                goto done;
                }
@@ -224,7 +224,7 @@ static int spidev_message(struct spidev_data *spidev,
        for (n = n_xfers, u_tmp = u_xfers; n; n--, u_tmp++) {
                if (u_tmp->rx_buf) {
                        if (__copy_to_user((u8 __user *)
-                                       (ptrdiff_t) u_tmp->rx_buf, buf,
+                                       (uintptr_t) u_tmp->rx_buf, buf,
                                        u_tmp->len)) {
                                status = -EFAULT;
                                goto done;
index 8bdaa15..eb4ac47 100644 (file)
@@ -1641,7 +1641,13 @@ free_interfaces:
                                intf->dev.bus_id, ret);
                        continue;
                }
-               usb_create_sysfs_intf_files (intf);
+
+               /* The driver's probe method can call usb_set_interface(),
+                * which would mean the interface's sysfs files are already
+                * created.  Just in case, we'll remove them first.
+                */
+               usb_remove_sysfs_intf_files(intf);
+               usb_create_sysfs_intf_files(intf);
        }
 
        usb_autosuspend_device(dev);
index c20c03a..d05ead2 100644 (file)
@@ -372,7 +372,7 @@ int usb_submit_urb(struct urb *urb, gfp_t mem_flags)
 
        /* enforce simple/standard policy */
        allowed = (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP |
-                       URB_NO_INTERRUPT | URB_DIR_MASK);
+                       URB_NO_INTERRUPT | URB_DIR_MASK | URB_FREE_BUFFER);
        switch (xfertype) {
        case USB_ENDPOINT_XFER_BULK:
                if (is_out)
index 1c80406..c72e962 100644 (file)
@@ -3289,7 +3289,7 @@ static int udc_pci_probe(
        dev->chiprev = pdev->revision;
 
        pci_set_master(pdev);
-       pci_set_mwi(pdev);
+       pci_try_set_mwi(pdev);
 
        /* init dma pools */
        if (use_dma) {
index c978d62..177e78e 100644 (file)
@@ -156,7 +156,7 @@ config USB_OHCI_HCD_PCI
 
 config USB_OHCI_HCD_SSB
        bool "OHCI support for Broadcom SSB OHCI core"
-       depends on USB_OHCI_HCD && SSB && EXPERIMENTAL
+       depends on USB_OHCI_HCD && (SSB = y || SSB = CONFIG_USB_OHCI_HCD) && EXPERIMENTAL
        default n
        ---help---
          Support for the Sonics Silicon Backplane (SSB) attached
index 240c7f5..704f33f 100644 (file)
@@ -80,7 +80,10 @@ static const char    hcd_name [] = "ohci_hcd";
 static void ohci_dump (struct ohci_hcd *ohci, int verbose);
 static int ohci_init (struct ohci_hcd *ohci);
 static void ohci_stop (struct usb_hcd *hcd);
+
+#if defined(CONFIG_PM) || defined(CONFIG_PCI)
 static int ohci_restart (struct ohci_hcd *ohci);
+#endif
 
 #include "ohci-hub.c"
 #include "ohci-dbg.c"
@@ -396,7 +399,7 @@ static int check_ed(struct ohci_hcd *ohci, struct ed *ed)
  */
 static void unlink_watchdog_func(unsigned long _ohci)
 {
-       long            flags;
+       unsigned long   flags;
        unsigned        max;
        unsigned        seen_count = 0;
        unsigned        i;
@@ -893,6 +896,8 @@ static void ohci_stop (struct usb_hcd *hcd)
 
 /*-------------------------------------------------------------------------*/
 
+#if defined(CONFIG_PM) || defined(CONFIG_PCI)
+
 /* must not be called from interrupt context */
 static int ohci_restart (struct ohci_hcd *ohci)
 {
@@ -954,6 +959,8 @@ static int ohci_restart (struct ohci_hcd *ohci)
        return 0;
 }
 
+#endif
+
 /*-------------------------------------------------------------------------*/
 
 #define DRIVER_INFO DRIVER_VERSION " " DRIVER_DESC
index e5d60d5..60379b1 100644 (file)
@@ -1271,7 +1271,8 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
        } else if (qh->period != urb->interval) {
                return -EINVAL;         /* Can't change the period */
 
-       } else {        /* Pick up where the last URB leaves off */
+       } else {
+               /* Find the next unused frame */
                if (list_empty(&qh->queue)) {
                        frame = qh->iso_frame;
                } else {
@@ -1283,10 +1284,18 @@ static int uhci_submit_isochronous(struct uhci_hcd *uhci, struct urb *urb,
                                        lurb->number_of_packets *
                                        lurb->interval;
                }
-               if (urb->transfer_flags & URB_ISO_ASAP)
-                       urb->start_frame = frame;
-               else if (urb->start_frame != frame)
-                       return -EINVAL;
+               if (urb->transfer_flags & URB_ISO_ASAP) {
+                       /* Skip some frames if necessary to insure
+                        * the start frame is in the future.
+                        */
+                       uhci_get_current_frame_number(uhci);
+                       if (uhci_frame_before_eq(frame, uhci->frame_number)) {
+                               frame = uhci->frame_number + 1;
+                               frame += ((qh->phase - frame) &
+                                       (qh->period - 1));
+                       }
+               }       /* Otherwise pick up where the last URB leaves off */
+               urb->start_frame = frame;
        }
 
        /* Make sure we won't have to go too far into the future */
index 2677fea..1cd9e7e 100644 (file)
@@ -399,7 +399,6 @@ static void cytherm_disconnect(struct usb_interface *interface)
        struct usb_cytherm *dev;
 
        dev = usb_get_intfdata (interface);
-       usb_set_intfdata (interface, NULL);
 
        device_remove_file(&interface->dev, &dev_attr_brightness);
        device_remove_file(&interface->dev, &dev_attr_temp);
@@ -407,6 +406,9 @@ static void cytherm_disconnect(struct usb_interface *interface)
        device_remove_file(&interface->dev, &dev_attr_port0);
        device_remove_file(&interface->dev, &dev_attr_port1);
 
+       /* first remove the files, then NULL the pointer */
+       usb_set_intfdata (interface, NULL);
+
        usb_put_dev(dev->udev);
 
        kfree(dev);
index cd13757..4a09b87 100644 (file)
@@ -114,6 +114,10 @@ static int emi26_load_firmware (struct usb_device *dev)
 
        /* De-assert reset (let the CPU run) */
        err = emi26_set_reset(dev,0);
+       if (err < 0) {
+               err("%s - error loading firmware: error = %d", __FUNCTION__, err);
+               goto wraperr;
+       }
        msleep(250);    /* let device settle */
 
        /* 2. We upload the FPGA firmware into the EMI
index 4758cc5..d136241 100644 (file)
@@ -123,6 +123,10 @@ static int emi62_load_firmware (struct usb_device *dev)
 
        /* De-assert reset (let the CPU run) */
        err = emi62_set_reset(dev,0);
+       if (err < 0) {
+               err("%s - error loading firmware: error = %d", __FUNCTION__, err);
+               goto wraperr;
+       }
        msleep(250);    /* let device settle */
 
        /* 2. We upload the FPGA firmware into the EMI
index d3d8cd6..148b7fe 100644 (file)
@@ -147,7 +147,7 @@ struct u132_target {
 /* Structure to hold all of our device specific stuff*/
 struct usb_ftdi {
         struct list_head ftdi_list;
-        struct semaphore u132_lock;
+        struct mutex u132_lock;
         int command_next;
         int command_head;
         struct u132_command command[COMMAND_SIZE];
@@ -330,39 +330,39 @@ static int ftdi_elan_hcd_init(struct usb_ftdi *ftdi)
 
 static void ftdi_elan_abandon_completions(struct usb_ftdi *ftdi)
 {
-        down(&ftdi->u132_lock);
+        mutex_lock(&ftdi->u132_lock);
         while (ftdi->respond_next > ftdi->respond_head) {
                 struct u132_respond *respond = &ftdi->respond[RESPOND_MASK &
                         ftdi->respond_head++];
                 *respond->result = -ESHUTDOWN;
                 *respond->value = 0;
                 complete(&respond->wait_completion);
-        } up(&ftdi->u132_lock);
+        } mutex_unlock(&ftdi->u132_lock);
 }
 
 static void ftdi_elan_abandon_targets(struct usb_ftdi *ftdi)
 {
         int ed_number = 4;
-        down(&ftdi->u132_lock);
+        mutex_lock(&ftdi->u132_lock);
         while (ed_number-- > 0) {
                 struct u132_target *target = &ftdi->target[ed_number];
                 if (target->active == 1) {
                         target->condition_code = TD_DEVNOTRESP;
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         ftdi_elan_do_callback(ftdi, target, NULL, 0);
-                        down(&ftdi->u132_lock);
+                        mutex_lock(&ftdi->u132_lock);
                 }
         }
         ftdi->recieved = 0;
         ftdi->expected = 4;
         ftdi->ed_found = 0;
-        up(&ftdi->u132_lock);
+        mutex_unlock(&ftdi->u132_lock);
 }
 
 static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
 {
         int ed_number = 4;
-        down(&ftdi->u132_lock);
+        mutex_lock(&ftdi->u132_lock);
         while (ed_number-- > 0) {
                 struct u132_target *target = &ftdi->target[ed_number];
                 target->abandoning = 1;
@@ -382,9 +382,9 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
                                 ftdi->command_next += 1;
                                 ftdi_elan_kick_command_queue(ftdi);
                         } else {
-                                up(&ftdi->u132_lock);
+                                mutex_unlock(&ftdi->u132_lock);
                                 msleep(100);
-                                down(&ftdi->u132_lock);
+                                mutex_lock(&ftdi->u132_lock);
                                 goto wait_1;
                         }
                 }
@@ -404,9 +404,9 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
                                 ftdi->command_next += 1;
                                 ftdi_elan_kick_command_queue(ftdi);
                         } else {
-                                up(&ftdi->u132_lock);
+                                mutex_unlock(&ftdi->u132_lock);
                                 msleep(100);
-                                down(&ftdi->u132_lock);
+                                mutex_lock(&ftdi->u132_lock);
                                 goto wait_2;
                         }
                 }
@@ -414,13 +414,13 @@ static void ftdi_elan_flush_targets(struct usb_ftdi *ftdi)
         ftdi->recieved = 0;
         ftdi->expected = 4;
         ftdi->ed_found = 0;
-        up(&ftdi->u132_lock);
+        mutex_unlock(&ftdi->u132_lock);
 }
 
 static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
 {
         int ed_number = 4;
-        down(&ftdi->u132_lock);
+        mutex_lock(&ftdi->u132_lock);
         while (ed_number-- > 0) {
                 struct u132_target *target = &ftdi->target[ed_number];
                 target->abandoning = 1;
@@ -440,9 +440,9 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
                                 ftdi->command_next += 1;
                                 ftdi_elan_kick_command_queue(ftdi);
                         } else {
-                                up(&ftdi->u132_lock);
+                                mutex_unlock(&ftdi->u132_lock);
                                 msleep(100);
-                                down(&ftdi->u132_lock);
+                                mutex_lock(&ftdi->u132_lock);
                                 goto wait;
                         }
                 }
@@ -450,7 +450,7 @@ static void ftdi_elan_cancel_targets(struct usb_ftdi *ftdi)
         ftdi->recieved = 0;
         ftdi->expected = 4;
         ftdi->ed_found = 0;
-        up(&ftdi->u132_lock);
+        mutex_unlock(&ftdi->u132_lock);
 }
 
 static void ftdi_elan_kick_command_queue(struct usb_ftdi *ftdi)
@@ -886,14 +886,14 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
         char *b)
 {
         int payload = (ed_length >> 0) & 0x07FF;
-        down(&ftdi->u132_lock);
+        mutex_lock(&ftdi->u132_lock);
         target->actual = 0;
         target->non_null = (ed_length >> 15) & 0x0001;
         target->repeat_number = (ed_length >> 11) & 0x000F;
         if (ed_type == 0x02) {
                 if (payload == 0 || target->abandoning > 0) {
                         target->abandoning = 0;
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
                                 payload);
                         ftdi->recieved = 0;
@@ -903,13 +903,13 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
                 } else {
                         ftdi->expected = 4 + payload;
                         ftdi->ed_found = 1;
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return b;
                 }
         } else if (ed_type == 0x03) {
                 if (payload == 0 || target->abandoning > 0) {
                         target->abandoning = 0;
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
                                 payload);
                         ftdi->recieved = 0;
@@ -919,12 +919,12 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
                 } else {
                         ftdi->expected = 4 + payload;
                         ftdi->ed_found = 1;
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return b;
                 }
         } else if (ed_type == 0x01) {
                 target->abandoning = 0;
-                up(&ftdi->u132_lock);
+                mutex_unlock(&ftdi->u132_lock);
                 ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
                         payload);
                 ftdi->recieved = 0;
@@ -933,7 +933,7 @@ static char *have_ed_set_response(struct usb_ftdi *ftdi,
                 return ftdi->response;
         } else {
                 target->abandoning = 0;
-                up(&ftdi->u132_lock);
+                mutex_unlock(&ftdi->u132_lock);
                 ftdi_elan_do_callback(ftdi, target, 4 + ftdi->response,
                         payload);
                 ftdi->recieved = 0;
@@ -947,12 +947,12 @@ static char *have_ed_get_response(struct usb_ftdi *ftdi,
         struct u132_target *target, u16 ed_length, int ed_number, int ed_type,
         char *b)
 {
-        down(&ftdi->u132_lock);
+        mutex_lock(&ftdi->u132_lock);
         target->condition_code = TD_DEVNOTRESP;
         target->actual = (ed_length >> 0) & 0x01FF;
         target->non_null = (ed_length >> 15) & 0x0001;
         target->repeat_number = (ed_length >> 11) & 0x000F;
-        up(&ftdi->u132_lock);
+        mutex_unlock(&ftdi->u132_lock);
         if (target->active)
                 ftdi_elan_do_callback(ftdi, target, NULL, 0);
         target->abandoning = 0;
@@ -1278,7 +1278,7 @@ static int ftdi_elan_write_reg(struct usb_ftdi *ftdi, u32 data)
                 return -ENODEV;
         } else {
                 int command_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
                         struct u132_command *command = &ftdi->command[
@@ -1292,10 +1292,10 @@ static int ftdi_elan_write_reg(struct usb_ftdi *ftdi, u32 data)
                         command->buffer = &command->value;
                         ftdi->command_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1310,7 +1310,7 @@ static int ftdi_elan_write_config(struct usb_ftdi *ftdi, int config_offset,
                 return -ENODEV;
         } else {
                 int command_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
                         struct u132_command *command = &ftdi->command[
@@ -1324,10 +1324,10 @@ static int ftdi_elan_write_config(struct usb_ftdi *ftdi, int config_offset,
                         command->buffer = &command->value;
                         ftdi->command_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1342,7 +1342,7 @@ static int ftdi_elan_write_pcimem(struct usb_ftdi *ftdi, int mem_offset,
                 return -ENODEV;
         } else {
                 int command_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
                         struct u132_command *command = &ftdi->command[
@@ -1356,10 +1356,10 @@ static int ftdi_elan_write_pcimem(struct usb_ftdi *ftdi, int mem_offset,
                         command->buffer = &command->value;
                         ftdi->command_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1382,7 +1382,7 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data)
         } else {
                 int command_size;
                 int respond_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 respond_size = ftdi->respond_next - ftdi->respond_head;
                 if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE)
@@ -1405,11 +1405,11 @@ static int ftdi_elan_read_reg(struct usb_ftdi *ftdi, u32 *data)
                         ftdi->command_next += 1;
                         ftdi->respond_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         wait_for_completion(&respond->wait_completion);
                         return result;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1425,7 +1425,7 @@ static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset,
         } else {
                 int command_size;
                 int respond_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 respond_size = ftdi->respond_next - ftdi->respond_head;
                 if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE)
@@ -1449,11 +1449,11 @@ static int ftdi_elan_read_config(struct usb_ftdi *ftdi, int config_offset,
                         ftdi->command_next += 1;
                         ftdi->respond_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         wait_for_completion(&respond->wait_completion);
                         return result;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1469,7 +1469,7 @@ static int ftdi_elan_read_pcimem(struct usb_ftdi *ftdi, int mem_offset,
         } else {
                 int command_size;
                 int respond_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 respond_size = ftdi->respond_next - ftdi->respond_head;
                 if (command_size < COMMAND_SIZE && respond_size < RESPOND_SIZE)
@@ -1493,11 +1493,11 @@ static int ftdi_elan_read_pcimem(struct usb_ftdi *ftdi, int mem_offset,
                         ftdi->command_next += 1;
                         ftdi->respond_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         wait_for_completion(&respond->wait_completion);
                         return result;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1529,7 +1529,7 @@ static int ftdi_elan_edset_setup(struct usb_ftdi *ftdi, u8 ed_number,
                 return -ENODEV;
         } else {
                 int command_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
                         struct u132_target *target = &ftdi->target[ed];
@@ -1550,10 +1550,10 @@ static int ftdi_elan_edset_setup(struct usb_ftdi *ftdi, u8 ed_number,
                         target->active = 1;
                         ftdi->command_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1586,7 +1586,7 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number,
                 return -ENODEV;
         } else {
                 int command_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
                         struct u132_target *target = &ftdi->target[ed];
@@ -1615,10 +1615,10 @@ static int ftdi_elan_edset_input(struct usb_ftdi *ftdi, u8 ed_number,
                         target->active = 1;
                         ftdi->command_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1651,7 +1651,7 @@ static int ftdi_elan_edset_empty(struct usb_ftdi *ftdi, u8 ed_number,
                 return -ENODEV;
         } else {
                 int command_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
                         struct u132_target *target = &ftdi->target[ed];
@@ -1672,10 +1672,10 @@ static int ftdi_elan_edset_empty(struct usb_ftdi *ftdi, u8 ed_number,
                         target->active = 1;
                         ftdi->command_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1708,7 +1708,7 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number,
                 return -ENODEV;
         } else {
                 int command_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
                         u8 *b;
@@ -1751,10 +1751,10 @@ static int ftdi_elan_edset_output(struct usb_ftdi *ftdi, u8 ed_number,
                         target->active = 1;
                         ftdi->command_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1787,7 +1787,7 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number,
                 return -ENODEV;
         } else {
                 int command_size;
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 command_size = ftdi->command_next - ftdi->command_head;
                 if (command_size < COMMAND_SIZE) {
                         int remaining_length = urb->transfer_buffer_length -
@@ -1816,10 +1816,10 @@ static int ftdi_elan_edset_single(struct usb_ftdi *ftdi, u8 ed_number,
                         target->active = 1;
                         ftdi->command_next += 1;
                         ftdi_elan_kick_command_queue(ftdi);
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 } else {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         msleep(100);
                         goto wait;
                 }
@@ -1849,9 +1849,9 @@ static int ftdi_elan_edset_flush(struct usb_ftdi *ftdi, u8 ed_number,
                 return -ENODEV;
         } else {
                 struct u132_target *target = &ftdi->target[ed];
-                down(&ftdi->u132_lock);
+                mutex_lock(&ftdi->u132_lock);
                 if (target->abandoning > 0) {
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 } else {
                         target->abandoning = 1;
@@ -1873,13 +1873,13 @@ static int ftdi_elan_edset_flush(struct usb_ftdi *ftdi, u8 ed_number,
                                         ftdi->command_next += 1;
                                         ftdi_elan_kick_command_queue(ftdi);
                                 } else {
-                                        up(&ftdi->u132_lock);
+                                        mutex_unlock(&ftdi->u132_lock);
                                         msleep(100);
-                                        down(&ftdi->u132_lock);
+                                        mutex_lock(&ftdi->u132_lock);
                                         goto wait_1;
                                 }
                         }
-                        up(&ftdi->u132_lock);
+                        mutex_unlock(&ftdi->u132_lock);
                         return 0;
                 }
         }
@@ -2793,7 +2793,7 @@ static int ftdi_elan_probe(struct usb_interface *interface,
         init_MUTEX(&ftdi->sw_lock);
         ftdi->udev = usb_get_dev(interface_to_usbdev(interface));
         ftdi->interface = interface;
-        init_MUTEX(&ftdi->u132_lock);
+        mutex_init(&ftdi->u132_lock);
         ftdi->expected = 4;
         iface_desc = interface->cur_altsetting;
         for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
index e6fd024..4bcf7fb 100644 (file)
@@ -66,6 +66,7 @@ static struct usb_device_id idmouse_table[] = {
        USB_TYPE_VENDOR | USB_RECIP_ENDPOINT | USB_DIR_OUT, value, index, NULL, 0, 1000)
 
 MODULE_DEVICE_TABLE(usb, idmouse_table);
+static DEFINE_MUTEX(open_disc_mutex);
 
 /* structure to hold all of our device specific stuff */
 struct usb_idmouse {
@@ -80,7 +81,7 @@ struct usb_idmouse {
 
        int open; /* if the port is open or not */
        int present; /* if the device is not disconnected */
-       struct semaphore sem; /* locks this structure */
+       struct mutex lock; /* locks this structure */
 
 };
 
@@ -213,13 +214,17 @@ static int idmouse_open(struct inode *inode, struct file *file)
        if (!interface)
                return -ENODEV;
 
+       mutex_lock(&open_disc_mutex);
        /* get the device information block from the interface */
        dev = usb_get_intfdata(interface);
-       if (!dev)
+       if (!dev) {
+               mutex_unlock(&open_disc_mutex);
                return -ENODEV;
+       }
 
        /* lock this device */
-       down(&dev->sem);
+       mutex_lock(&dev->lock);
+       mutex_unlock(&open_disc_mutex);
 
        /* check if already open */
        if (dev->open) {
@@ -245,7 +250,7 @@ static int idmouse_open(struct inode *inode, struct file *file)
 error:
 
        /* unlock this device */
-       up(&dev->sem);
+       mutex_unlock(&dev->lock);
        return result;
 }
 
@@ -258,12 +263,14 @@ static int idmouse_release(struct inode *inode, struct file *file)
        if (dev == NULL)
                return -ENODEV;
 
+       mutex_lock(&open_disc_mutex);
        /* lock our device */
-       down(&dev->sem);
+       mutex_lock(&dev->lock);
 
        /* are we really open? */
        if (dev->open <= 0) {
-               up(&dev->sem);
+               mutex_unlock(&dev->lock);
+               mutex_unlock(&open_disc_mutex);
                return -ENODEV;
        }
 
@@ -271,10 +278,12 @@ static int idmouse_release(struct inode *inode, struct file *file)
 
        if (!dev->present) {
                /* the device was unplugged before the file was released */
-               up(&dev->sem);
+               mutex_unlock(&dev->lock);
+               mutex_unlock(&open_disc_mutex);
                idmouse_delete(dev);
        } else {
-               up(&dev->sem);
+               mutex_unlock(&dev->lock);
+               mutex_unlock(&open_disc_mutex);
        }
        return 0;
 }
@@ -286,18 +295,18 @@ static ssize_t idmouse_read(struct file *file, char __user *buffer, size_t count
        int result;
 
        /* lock this object */
-       down(&dev->sem);
+       mutex_lock(&dev->lock);
 
        /* verify that the device wasn't unplugged */
        if (!dev->present) {
-               up(&dev->sem);
+               mutex_unlock(&dev->lock);
                return -ENODEV;
        }
 
        result = simple_read_from_buffer(buffer, count, ppos,
                                        dev->bulk_in_buffer, IMGSIZE);
        /* unlock the device */
-       up(&dev->sem);
+       mutex_unlock(&dev->lock);
        return result;
 }
 
@@ -320,7 +329,7 @@ static int idmouse_probe(struct usb_interface *interface,
        if (dev == NULL)
                return -ENOMEM;
 
-       init_MUTEX(&dev->sem);
+       mutex_init(&dev->lock);
        dev->udev = udev;
        dev->interface = interface;
 
@@ -372,24 +381,26 @@ static void idmouse_disconnect(struct usb_interface *interface)
 
        /* get device structure */
        dev = usb_get_intfdata(interface);
-       usb_set_intfdata(interface, NULL);
 
        /* give back our minor */
        usb_deregister_dev(interface, &idmouse_class);
 
-       /* lock it */
-       down(&dev->sem);
+       mutex_lock(&open_disc_mutex);
+       usb_set_intfdata(interface, NULL);
+       /* lock the device */
+       mutex_lock(&dev->lock);
+       mutex_unlock(&open_disc_mutex);
 
        /* prevent device read, write and ioctl */
        dev->present = 0;
 
        /* if the device is opened, idmouse_release will clean this up */
        if (!dev->open) {
-               up(&dev->sem);
+               mutex_unlock(&dev->lock);
                idmouse_delete(dev);
        } else {
                /* unlock */
-               up(&dev->sem);
+               mutex_unlock(&dev->lock);
        }
 
        info("%s disconnected", DRIVER_DESC);
index d372fbc..764696f 100644 (file)
@@ -66,6 +66,7 @@ module_param(debug, bool, 0644);
 MODULE_PARM_DESC(debug, "debug=1 enables debugging messages");
 
 static struct usb_driver iowarrior_driver;
+static DEFINE_MUTEX(iowarrior_open_disc_lock);
 
 /*--------------*/
 /*     data     */
@@ -351,7 +352,7 @@ static ssize_t iowarrior_write(struct file *file,
 
        mutex_lock(&dev->mutex);
        /* verify that the device wasn't unplugged */
-       if (dev == NULL || !dev->present) {
+       if (!dev->present) {
                retval = -ENODEV;
                goto exit;
        }
@@ -608,11 +609,15 @@ static int iowarrior_open(struct inode *inode, struct file *file)
                return -ENODEV;
        }
 
+       mutex_lock(&iowarrior_open_disc_lock);
        dev = usb_get_intfdata(interface);
-       if (!dev)
+       if (!dev) {
+               mutex_unlock(&iowarrior_open_disc_lock);
                return -ENODEV;
+       }
 
        mutex_lock(&dev->mutex);
+       mutex_unlock(&iowarrior_open_disc_lock);
 
        /* Only one process can open each device, no sharing. */
        if (dev->opened) {
@@ -866,6 +871,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
        int minor;
 
        dev = usb_get_intfdata(interface);
+       mutex_lock(&iowarrior_open_disc_lock);
        usb_set_intfdata(interface, NULL);
 
        minor = dev->minor;
@@ -879,6 +885,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
        dev->present = 0;
 
        mutex_unlock(&dev->mutex);
+       mutex_unlock(&iowarrior_open_disc_lock);
 
        if (dev->opened) {
                /* There is a process that holds a filedescriptor to the device ,
index 561970b..aab3200 100644 (file)
@@ -198,6 +198,7 @@ static struct usb_device_id tower_table [] = {
 };
 
 MODULE_DEVICE_TABLE (usb, tower_table);
+static DEFINE_MUTEX(open_disc_mutex);
 
 #define LEGO_USB_TOWER_MINOR_BASE      160
 
@@ -350,25 +351,31 @@ static int tower_open (struct inode *inode, struct file *file)
                goto exit;
        }
 
+       mutex_lock(&open_disc_mutex);
        dev = usb_get_intfdata(interface);
 
        if (!dev) {
+               mutex_unlock(&open_disc_mutex);
                retval = -ENODEV;
                goto exit;
        }
 
        /* lock this device */
        if (down_interruptible (&dev->sem)) {
+               mutex_unlock(&open_disc_mutex);
                retval = -ERESTARTSYS;
                goto exit;
        }
 
+
        /* allow opening only once */
        if (dev->open_count) {
+               mutex_unlock(&open_disc_mutex);
                retval = -EBUSY;
                goto unlock_exit;
        }
        dev->open_count = 1;
+       mutex_unlock(&open_disc_mutex);
 
        /* reset the tower */
        result = usb_control_msg (dev->udev,
@@ -437,9 +444,10 @@ static int tower_release (struct inode *inode, struct file *file)
        if (dev == NULL) {
                dbg(1, "%s: object is NULL", __FUNCTION__);
                retval = -ENODEV;
-               goto exit;
+               goto exit_nolock;
        }
 
+       mutex_lock(&open_disc_mutex);
        if (down_interruptible (&dev->sem)) {
                retval = -ERESTARTSYS;
                goto exit;
@@ -468,6 +476,8 @@ unlock_exit:
        up (&dev->sem);
 
 exit:
+       mutex_unlock(&open_disc_mutex);
+exit_nolock:
        dbg(2, "%s: leave, return value %d", __FUNCTION__, retval);
        return retval;
 }
@@ -989,6 +999,7 @@ static void tower_disconnect (struct usb_interface *interface)
        dbg(2, "%s: enter", __FUNCTION__);
 
        dev = usb_get_intfdata (interface);
+       mutex_lock(&open_disc_mutex);
        usb_set_intfdata (interface, NULL);
 
        minor = dev->minor;
@@ -997,6 +1008,7 @@ static void tower_disconnect (struct usb_interface *interface)
        usb_deregister_dev (interface, &tower_class);
 
        down (&dev->sem);
+       mutex_unlock(&open_disc_mutex);
 
        /* if the device is not opened, then we clean up right now */
        if (!dev->open_count) {
index 88f6abe..330c18e 100644 (file)
@@ -118,10 +118,7 @@ ioctl_rio(struct inode *inode, struct file *file, unsigned int cmd,
 
        mutex_lock(&(rio->lock));
         /* Sanity check to make sure rio is connected, powered, etc */
-        if ( rio == NULL ||
-             rio->present == 0 ||
-             rio->rio_dev == NULL )
-       {
+        if (rio->present == 0 || rio->rio_dev == NULL) {
                retval = -ENODEV;
                goto err_out;
        }
@@ -280,10 +277,7 @@ write_rio(struct file *file, const char __user *buffer,
        if (intr)
                return -EINTR;
         /* Sanity check to make sure rio is connected, powered, etc */
-        if ( rio == NULL ||
-             rio->present == 0 ||
-             rio->rio_dev == NULL )
-       {
+        if (rio->present == 0 || rio->rio_dev == NULL) {
                mutex_unlock(&(rio->lock));
                return -ENODEV;
        }
@@ -369,10 +363,7 @@ read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
        if (intr)
                return -EINTR;
        /* Sanity check to make sure rio is connected, powered, etc */
-        if ( rio == NULL ||
-             rio->present == 0 ||
-             rio->rio_dev == NULL )
-       {
+        if (rio->present == 0 || rio->rio_dev == NULL) {
                mutex_unlock(&(rio->lock));
                return -ENODEV;
        }
index 7198420..20777d0 100644 (file)
@@ -17,6 +17,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/errno.h>
+#include <linux/mutex.h>
 #include <asm/uaccess.h>
 #include <linux/usb.h>
 
@@ -34,6 +35,8 @@ static struct usb_device_id id_table [] = {
 };
 MODULE_DEVICE_TABLE (usb, id_table);
 
+static DEFINE_MUTEX(open_disc_mutex);
+
 
 struct usb_lcd {
        struct usb_device *     udev;                   /* init: probe_lcd */
@@ -79,12 +82,16 @@ static int lcd_open(struct inode *inode, struct file *file)
                return -ENODEV;
        }
 
+       mutex_lock(&open_disc_mutex);
        dev = usb_get_intfdata(interface);
-       if (!dev)
+       if (!dev) {
+               mutex_unlock(&open_disc_mutex);
                return -ENODEV;
+       }
 
        /* increment our usage count for the device */
        kref_get(&dev->kref);
+       mutex_unlock(&open_disc_mutex);
 
        /* grab a power reference */
        r = usb_autopm_get_interface(interface);
@@ -393,8 +400,10 @@ static void lcd_disconnect(struct usb_interface *interface)
        struct usb_lcd *dev;
         int minor = interface->minor;
 
+       mutex_lock(&open_disc_mutex);
         dev = usb_get_intfdata(interface);
         usb_set_intfdata(interface, NULL);
+       mutex_unlock(&open_disc_mutex);
 
         /* give back our minor */
         usb_deregister_dev(interface, &lcd_class);
index 2a8e537..ddfee91 100644 (file)
@@ -161,7 +161,8 @@ static void ark3116_set_termios(struct usb_serial_port *port,
 {
        struct usb_serial *serial = port->serial;
        struct ark3116_private *priv = usb_get_serial_port_data(port);
-       unsigned int cflag = port->tty->termios->c_cflag;
+       struct ktermios *termios = port->tty->termios;
+       unsigned int cflag = termios->c_cflag;
        unsigned long flags;
        int baud;
        int ark3116_baud;
@@ -177,11 +178,14 @@ static void ark3116_set_termios(struct usb_serial_port *port,
                *(port->tty->termios) = tty_std_termios;
                port->tty->termios->c_cflag = B9600 | CS8
                                              | CREAD | HUPCL | CLOCAL;
+               termios->c_ispeed = 9600;
+               termios->c_ospeed = 9600;
                priv->termios_initialized = 1;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
-       cflag = port->tty->termios->c_cflag;
+       cflag = termios->c_cflag;
+       termios->c_cflag &= ~(CMSPAR|CRTSCTS);
 
        buf = kmalloc(1, GFP_KERNEL);
        if (!buf) {
@@ -254,9 +258,13 @@ static void ark3116_set_termios(struct usb_serial_port *port,
                case 115200:
                case 230400:
                case 460800:
+                       /* Report the resulting rate back to the caller */
+                       tty_encode_baud_rate(port->tty, baud, baud);
                        break;
                /* set 9600 as default (if given baudrate is invalid for example) */
                default:
+                       tty_encode_baud_rate(port->tty, 9600, 9600);
+               case 0:
                        baud = 9600;
        }
 
@@ -302,6 +310,7 @@ static void ark3116_set_termios(struct usb_serial_port *port,
        /* TEST ARK3116_SND(154, 0xFE, 0x40, 0xFFFF, 0x0006); */
 
        kfree(buf);
+
        return;
 }
 
index 6b252ce..42582d4 100644 (file)
@@ -272,9 +272,6 @@ static void ch341_set_termios(struct usb_serial_port *port,
 
        dbg("ch341_set_termios()");
 
-       if (!tty || !tty->termios)
-               return;
-
        baud_rate = tty_get_baud_rate(tty);
 
        switch (baud_rate) {
@@ -299,6 +296,11 @@ static void ch341_set_termios(struct usb_serial_port *port,
         * (cflag & PARENB) : parity {NONE, EVEN, ODD}
         * (cflag & CSTOPB) : stop bits [1, 2]
         */
+
+        /* Copy back the old hardware settings */
+        tty_termios_copy_hw(tty->termios, old_termios);
+        /* And re-encode with the new baud */
+        tty_encode_baud_rate(tty, baud_rate, baud_rate);
 }
 
 static struct usb_driver ch341_driver = {
index 9386e21..0362654 100644 (file)
@@ -164,6 +164,7 @@ static int usb_console_setup(struct console *co, char *options)
        }
 
        if (serial->type->set_termios) {
+               struct ktermios dummy;
                /* build up a fake tty structure so that the open call has something
                 * to look at to get the cflag value */
                tty = kzalloc(sizeof(*tty), GFP_KERNEL);
@@ -177,12 +178,13 @@ static int usb_console_setup(struct console *co, char *options)
                        kfree (tty);
                        return -ENOMEM;
                }
+               memset(&dummy, 0, sizeof(struct ktermios));
                termios->c_cflag = cflag;
                tty->termios = termios;
                port->tty = tty;
 
                /* set up the initial termios settings */
-               serial->type->set_termios(port, NULL);
+               serial->type->set_termios(port, &dummy);
                port->tty = NULL;
                kfree (termios);
                kfree (tty);
index eb7df18..3a83cb4 100644 (file)
@@ -361,7 +361,6 @@ static void cp2101_get_termios (struct usb_serial_port *port)
                dbg("%s - no tty structures", __FUNCTION__);
                return;
        }
-       cflag = port->tty->termios->c_cflag;
 
        cp2101_get_config(port, CP2101_BAUDRATE, &baud, 2);
        /* Convert to baudrate */
@@ -369,40 +368,9 @@ static void cp2101_get_termios (struct usb_serial_port *port)
                baud = BAUD_RATE_GEN_FREQ / baud;
 
        dbg("%s - baud rate = %d", __FUNCTION__, baud);
-       cflag &= ~CBAUD;
-       switch (baud) {
-               /*
-                * The baud rates which are commented out below
-                * appear to be supported by the device
-                * but are non-standard
-                */
-               case 600:       cflag |= B600;          break;
-               case 1200:      cflag |= B1200;         break;
-               case 1800:      cflag |= B1800;         break;
-               case 2400:      cflag |= B2400;         break;
-               case 4800:      cflag |= B4800;         break;
-               /*case 7200:    cflag |= B7200;         break;*/
-               case 9600:      cflag |= B9600;         break;
-               /*case 14400:   cflag |= B14400;        break;*/
-               case 19200:     cflag |= B19200;        break;
-               /*case 28800:   cflag |= B28800;        break;*/
-               case 38400:     cflag |= B38400;        break;
-               /*case 55854:   cflag |= B55054;        break;*/
-               case 57600:     cflag |= B57600;        break;
-               case 115200:    cflag |= B115200;       break;
-               /*case 127117:  cflag |= B127117;       break;*/
-               case 230400:    cflag |= B230400;       break;
-               case 460800:    cflag |= B460800;       break;
-               case 921600:    cflag |= B921600;       break;
-               /*case 3686400: cflag |= B3686400;      break;*/
-               default:
-                       dbg("%s - Baud rate is not supported, "
-                                       "using 9600 baud", __FUNCTION__);
-                       cflag |= B9600;
-                       cp2101_set_config_single(port, CP2101_BAUDRATE,
-                                       (BAUD_RATE_GEN_FREQ/9600));
-                       break;
-       }
+
+       tty_encode_baud_rate(port->tty, baud, baud);
+       cflag = port->tty->termios->c_cflag;
 
        cp2101_get_config(port, CP2101_BITS, &bits, 2);
        cflag &= ~CSIZE;
@@ -516,7 +484,7 @@ static void cp2101_get_termios (struct usb_serial_port *port)
 static void cp2101_set_termios (struct usb_serial_port *port,
                struct ktermios *old_termios)
 {
-       unsigned int cflag, old_cflag=0;
+       unsigned int cflag, old_cflag;
        int baud=0, bits;
        unsigned int modem_ctl[4];
 
@@ -526,6 +494,8 @@ static void cp2101_set_termios (struct usb_serial_port *port,
                dbg("%s - no tty structures", __FUNCTION__);
                return;
        }
+       port->tty->termios->c_cflag &= ~CMSPAR;
+
        cflag = port->tty->termios->c_cflag;
        old_cflag = old_termios->c_cflag;
        baud = tty_get_baud_rate(port->tty);
@@ -563,11 +533,15 @@ static void cp2101_set_termios (struct usb_serial_port *port,
                        dbg("%s - Setting baud rate to %d baud", __FUNCTION__,
                                        baud);
                        if (cp2101_set_config_single(port, CP2101_BAUDRATE,
-                                               (BAUD_RATE_GEN_FREQ / baud)))
+                                               (BAUD_RATE_GEN_FREQ / baud))) {
                                dev_err(&port->dev, "Baud rate requested not "
                                                "supported by device\n");
+                               baud = tty_termios_baud_rate(old_termios);
+                       }
                }
        }
+       /* Report back the resulting baud rate */
+       tty_encode_baud_rate(port->tty, baud, baud);
 
        /* If the number of data bits is to be updated */
        if ((cflag & CSIZE) != (old_cflag & CSIZE)) {
index dab2e66..ae410c4 100644 (file)
@@ -973,6 +973,8 @@ static void digi_set_termios(struct usb_serial_port *port,
                }
        }
        /* set parity */
+       tty->termios->c_cflag &= ~CMSPAR;
+
        if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) {
                if (cflag&PARENB) {
                        if (cflag&PARODD)
@@ -1054,15 +1056,15 @@ static void digi_set_termios(struct usb_serial_port *port,
        }
 
        /* set output flow control */
-       if ((iflag&IXON) != (old_iflag&IXON)
-           || (cflag&CRTSCTS) != (old_cflag&CRTSCTS)) {
+       if ((iflag & IXON) != (old_iflag & IXON)
+           || (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
                arg = 0;
-               if (iflag&IXON)
+               if (iflag & IXON)
                        arg |= DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
                else
                        arg &= ~DIGI_OUTPUT_FLOW_CONTROL_XON_XOFF;
 
-               if (cflag&CRTSCTS) {
+               if (cflag & CRTSCTS) {
                        arg |= DIGI_OUTPUT_FLOW_CONTROL_CTS;
                } else {
                        arg &= ~DIGI_OUTPUT_FLOW_CONTROL_CTS;
@@ -1076,8 +1078,8 @@ static void digi_set_termios(struct usb_serial_port *port,
        }
 
        /* set receive enable/disable */
-       if ((cflag&CREAD) != (old_cflag&CREAD)) {
-               if (cflag&CREAD)
+       if ((cflag & CREAD) != (old_cflag & CREAD)) {
+               if (cflag & CREAD)
                        arg = DIGI_ENABLE;
                else
                        arg = DIGI_DISABLE;
@@ -1089,7 +1091,7 @@ static void digi_set_termios(struct usb_serial_port *port,
        }
        if ((ret = digi_write_oob_command(port, buf, i, 1)) != 0)
                dbg("digi_set_termios: write oob failed, ret=%d", ret);
-
+       tty_encode_baud_rate(tty, baud, baud);
 }
 
 
index 050fcc9..a5c8e1e 100644 (file)
@@ -449,14 +449,9 @@ static int empeg_ioctl (struct usb_serial_port *port, struct file * file, unsign
 
 static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
-
+       struct ktermios *termios = port->tty->termios;
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if ((!port->tty) || (!port->tty->termios)) {
-               dbg("%s - no tty structures", __FUNCTION__);
-               return;
-       }
-
        /*
          * The empeg-car player wants these particular tty settings.
          * You could, for example, change the baud rate, however the
@@ -466,7 +461,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
          *
          * The default requirements for this device are:
          */
-       port->tty->termios->c_iflag
+       termios->c_iflag
                &= ~(IGNBRK     /* disable ignore break */
                | BRKINT        /* disable break causes interrupt */
                | PARMRK        /* disable mark parity errors */
@@ -476,24 +471,23 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
                | ICRNL         /* disable translate CR to NL */
                | IXON);        /* disable enable XON/XOFF flow control */
 
-       port->tty->termios->c_oflag
+       termios->c_oflag
                &= ~OPOST;      /* disable postprocess output characters */
 
-       port->tty->termios->c_lflag
+       termios->c_lflag
                &= ~(ECHO       /* disable echo input characters */
                | ECHONL        /* disable echo new line */
                | ICANON        /* disable erase, kill, werase, and rprnt special characters */
                | ISIG          /* disable interrupt, quit, and suspend special characters */
                | IEXTEN);      /* disable non-POSIX special characters */
 
-       port->tty->termios->c_cflag
+       termios->c_cflag
                &= ~(CSIZE      /* no size */
                | PARENB        /* disable parity bit */
                | CBAUD);       /* clear current baud rate */
 
-       port->tty->termios->c_cflag
-               |= (CS8         /* character size 8 bits */
-               | B115200);     /* baud rate 115200 */
+       termios->c_cflag
+               |= CS8;         /* character size 8 bits */
 
        /*
         * Force low_latency on; otherwise the pushes are scheduled;
@@ -501,8 +495,7 @@ static void empeg_set_termios (struct usb_serial_port *port, struct ktermios *ol
         * on the floor.  We don't want to drop bytes on the floor. :)
         */
        port->tty->low_latency = 1;
-
-       return;
+       tty_encode_baud_rate(port->tty, 115200, 115200);
 }
 
 
index 8a8a6b9..c40e77d 100644 (file)
@@ -294,7 +294,7 @@ struct ftdi_private {
 
        __u16 interface;        /* FT2232C port interface (0 for FT232/245) */
 
-       int force_baud;         /* if non-zero, force the baud rate to this value */
+       speed_t force_baud;     /* if non-zero, force the baud rate to this value */
        int force_rtscts;       /* if non-zero, force RTS-CTS to always be enabled */
 
        spinlock_t tx_lock;     /* spinlock for transmit state */
@@ -878,6 +878,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
                if (div_value == 0) {
                        dbg("%s - Baudrate (%d) requested is not supported", __FUNCTION__,  baud);
                        div_value = ftdi_sio_b9600;
+                       baud = 9600;
                        div_okay = 0;
                }
                break;
@@ -886,6 +887,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
                        div_value = ftdi_232am_baud_to_divisor(baud);
                } else {
                        dbg("%s - Baud rate too high!", __FUNCTION__);
+                       baud = 9600;
                        div_value = ftdi_232am_baud_to_divisor(9600);
                        div_okay = 0;
                }
@@ -899,6 +901,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
                        dbg("%s - Baud rate too high!", __FUNCTION__);
                        div_value = ftdi_232bm_baud_to_divisor(9600);
                        div_okay = 0;
+                       baud = 9600;
                }
                break;
        } /* priv->chip_type */
@@ -909,6 +912,7 @@ static __u32 get_ftdi_divisor(struct usb_serial_port * port)
                        ftdi_chip_name[priv->chip_type]);
        }
 
+       tty_encode_baud_rate(port->tty, baud, baud);
        return(div_value);
 }
 
@@ -1263,7 +1267,7 @@ static void ftdi_USB_UIRT_setup (struct ftdi_private *priv)
 
        priv->flags |= ASYNC_SPD_CUST;
        priv->custom_divisor = 77;
-       priv->force_baud = B38400;
+       priv->force_baud = 38400;
 } /* ftdi_USB_UIRT_setup */
 
 /* Setup for the HE-TIRA1 device, which requires hardwired
@@ -1274,7 +1278,7 @@ static void ftdi_HE_TIRA1_setup (struct ftdi_private *priv)
 
        priv->flags |= ASYNC_SPD_CUST;
        priv->custom_divisor = 240;
-       priv->force_baud = B38400;
+       priv->force_baud = 38400;
        priv->force_rtscts = 1;
 } /* ftdi_HE_TIRA1_setup */
 
@@ -1363,7 +1367,7 @@ static int  ftdi_open (struct usb_serial_port *port, struct file *filp)
 
        /* ftdi_set_termios  will send usb control messages */
        if (port->tty)
-               ftdi_set_termios(port, NULL);
+               ftdi_set_termios(port, port->tty->termios);
 
        /* FIXME: Flow control might be enabled, so it should be checked -
           we have no control of defaults! */
@@ -1933,32 +1937,33 @@ static void ftdi_break_ctl( struct usb_serial_port *port, int break_state )
 static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 { /* ftdi_termios */
        struct usb_device *dev = port->serial->dev;
-       unsigned int cflag = port->tty->termios->c_cflag;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
+       struct ktermios *termios = port->tty->termios;
+       unsigned int cflag = termios->c_cflag;
        __u16 urb_value; /* will hold the new flags */
        char buf[1]; /* Perhaps I should dynamically alloc this? */
 
        // Added for xon/xoff support
-       unsigned int iflag = port->tty->termios->c_iflag;
+       unsigned int iflag = termios->c_iflag;
        unsigned char vstop;
        unsigned char vstart;
 
        dbg("%s", __FUNCTION__);
 
        /* Force baud rate if this device requires it, unless it is set to B0. */
-       if (priv->force_baud && ((port->tty->termios->c_cflag & CBAUD) != B0)) {
+       if (priv->force_baud && ((termios->c_cflag & CBAUD) != B0)) {
                dbg("%s: forcing baud rate for this device", __FUNCTION__);
-               port->tty->termios->c_cflag &= ~CBAUD;
-               port->tty->termios->c_cflag |= priv->force_baud;
+               tty_encode_baud_rate(port->tty, priv->force_baud,
+                                       priv->force_baud);
        }
 
        /* Force RTS-CTS if this device requires it. */
        if (priv->force_rtscts) {
                dbg("%s: forcing rtscts for this device", __FUNCTION__);
-               port->tty->termios->c_cflag |= CRTSCTS;
+               termios->c_cflag |= CRTSCTS;
        }
 
-       cflag = port->tty->termios->c_cflag;
+       cflag = termios->c_cflag;
 
        /* FIXME -For this cut I don't care if the line is really changing or
           not  - so just do the change regardless  - should be able to
@@ -1969,6 +1974,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
 
        /* Set number of data bits, parity, stop bits */
 
+       termios->c_cflag &= ~CMSPAR;
+
        urb_value = 0;
        urb_value |= (cflag & CSTOPB ? FTDI_SIO_SET_DATA_STOP_BITS_2 :
                      FTDI_SIO_SET_DATA_STOP_BITS_1);
@@ -2048,8 +2055,8 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct ktermios *old
                        // Set the vstart and vstop -- could have been done up above where
                        // a lot of other dereferencing is done but that would be very
                        // inefficient as vstart and vstop are not always needed
-                       vstart=port->tty->termios->c_cc[VSTART];
-                       vstop=port->tty->termios->c_cc[VSTOP];
+                       vstart = termios->c_cc[VSTART];
+                       vstop = termios->c_cc[VSTOP];
                        urb_value=(vstop << 8) | (vstart);
 
                        if (usb_control_msg(dev,
index 88a2c7d..9eb4a65 100644 (file)
@@ -208,14 +208,15 @@ int usb_serial_generic_write(struct usb_serial_port *port, const unsigned char *
 
        /* only do something if we have a bulk out endpoint */
        if (serial->num_bulk_out) {
-               spin_lock_bh(&port->lock);
+               unsigned long flags;
+               spin_lock_irqsave(&port->lock, flags);
                if (port->write_urb_busy) {
-                       spin_unlock_bh(&port->lock);
+                       spin_unlock_irqrestore(&port->lock, flags);
                        dbg("%s - already writing", __FUNCTION__);
                        return 0;
                }
                port->write_urb_busy = 1;
-               spin_unlock_bh(&port->lock);
+               spin_unlock_irqrestore(&port->lock, flags);
 
                count = (count > port->bulk_out_size) ? port->bulk_out_size : count;
 
index 8dd3abc..a5d2e11 100644 (file)
@@ -1503,22 +1503,16 @@ static void edge_unthrottle (struct usb_serial_port *port)
  *****************************************************************************/
 static void edge_set_termios (struct usb_serial_port *port, struct ktermios *old_termios)
 {
+       /* FIXME: This function appears unused ?? */
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        struct tty_struct *tty = port->tty;
        unsigned int cflag;
 
-       if (!port->tty || !port->tty->termios) {
-               dbg ("%s - no tty or termios", __FUNCTION__);
-               return;
-       }
-
        cflag = tty->termios->c_cflag;
        dbg("%s - clfag %08x iflag %08x", __FUNCTION__, 
            tty->termios->c_cflag, tty->termios->c_iflag);
-       if (old_termios) {
-               dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
-                   old_termios->c_cflag, old_termios->c_iflag);
-       }
+       dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
+           old_termios->c_cflag, old_termios->c_iflag);
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
@@ -2653,7 +2647,11 @@ static void change_port_settings (struct edgeport_port *edge_port, struct ktermi
 
        dbg("%s - baud rate = %d", __FUNCTION__, baud);
        status = send_cmd_write_baud_rate (edge_port, baud);
-
+       if (status == -1) {
+               /* Speed change was not possible - put back the old speed */
+               baud = tty_termios_baud_rate(old_termios);
+               tty_encode_baud_rate(tty, baud, baud);
+       }
        return;
 }
 
index 5ab6a0c..6b803ab 100644 (file)
@@ -504,11 +504,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
 
        dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if ((!port->tty) || (!port->tty->termios)) {
-               dbg("%s - no tty structures", __FUNCTION__);
-               return;
-       }
-
        baud = tty_get_baud_rate(port->tty);
 
        /*
@@ -531,8 +526,6 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
                default:
                        ir_baud = SPEED_9600;
                        baud = 9600;
-                       /* And once the new tty stuff is all done we need to
-                          call back to correct the baud bits */
        }
 
        if (xbof == -1)
@@ -562,6 +555,10 @@ static void ir_set_termios (struct usb_serial_port *port, struct ktermios *old_t
        result = usb_submit_urb (port->write_urb, GFP_KERNEL);
        if (result)
                dev_err(&port->dev, "%s - failed submitting write urb, error %d\n", __FUNCTION__, result);
+
+       /* Only speed changes are supported */
+       tty_termios_copy_hw(port->tty->termios, old_termios);
+       tty_encode_baud_rate(port->tty, baud, baud);
 }
 
 
index f2a6fce..6bfdba6 100644 (file)
@@ -278,29 +278,35 @@ static void keyspan_set_termios (struct usb_serial_port *port,
        struct keyspan_port_private     *p_priv;
        const struct keyspan_device_details     *d_details;
        unsigned int                    cflag;
+       struct tty_struct               *tty = port->tty;
 
        dbg("%s", __FUNCTION__); 
 
        p_priv = usb_get_serial_port_data(port);
        d_details = p_priv->device_details;
-       cflag = port->tty->termios->c_cflag;
+       cflag = tty->termios->c_cflag;
        device_port = port->number - port->serial->minor;
 
        /* Baud rate calculation takes baud rate as an integer
           so other rates can be generated if desired. */
-       baud_rate = tty_get_baud_rate(port->tty);
+       baud_rate = tty_get_baud_rate(tty);
        /* If no match or invalid, don't change */              
-       if (baud_rate >= 0
-           && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
+       if (d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
                                NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
                /* FIXME - more to do here to ensure rate changes cleanly */
+               /* FIXME - calcuate exact rate from divisor ? */
                p_priv->baud = baud_rate;
-       }
+       } else
+               baud_rate = tty_termios_baud_rate(old_termios);
 
+       tty_encode_baud_rate(tty, baud_rate, baud_rate);
        /* set CTS/RTS handshake etc. */
        p_priv->cflag = cflag;
        p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
 
+       /* Mark/Space not supported */
+       tty->termios->c_cflag &= ~CMSPAR;
+
        keyspan_send_setup(port, 0);
 }
 
index 6f22419..aee4502 100644 (file)
@@ -616,8 +616,9 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old
                case 1200:
                        urb_val = SUSBCR_SBR_1200;
                        break;
-               case 9600:
                default:
+                       speed = 9600;
+               case 9600:
                        urb_val = SUSBCR_SBR_9600;
                        break;
        }
@@ -641,6 +642,8 @@ static void kobil_set_termios(struct usb_serial_port *port, struct ktermios *old
                urb_val |= SUSBCR_SPASB_NoParity;
                strcat(settings, "No Parity");
        }
+       port->tty->termios->c_cflag &= ~CMSPAR;
+       tty_encode_baud_rate(port->tty, speed, speed);
 
        result = usb_control_msg( port->serial->dev,
                                  usb_rcvctrlpipe(port->serial->dev, 0 ),
index f76480f..a5ced7e 100644 (file)
@@ -1977,11 +1977,6 @@ static void mos7840_change_port_settings(struct moschip_port *mos7840_port,
 
        tty = mos7840_port->port->tty;
 
-       if ((!tty) || (!tty->termios)) {
-               dbg("%s - no tty structures", __FUNCTION__);
-               return;
-       }
-
        dbg("%s", "Entering .......... \n");
 
        lData = LCR_BITS_8;
@@ -2151,11 +2146,6 @@ static void mos7840_set_termios(struct usb_serial_port *port,
 
        tty = port->tty;
 
-       if (!port->tty || !port->tty->termios) {
-               dbg("%s - no tty or termios", __FUNCTION__);
-               return;
-       }
-
        if (!mos7840_port->open) {
                dbg("%s - port not opened", __FUNCTION__);
                return;
@@ -2165,19 +2155,10 @@ static void mos7840_set_termios(struct usb_serial_port *port,
 
        cflag = tty->termios->c_cflag;
 
-       if (!cflag) {
-               dbg("%s %s\n", __FUNCTION__, "cflag is NULL");
-               return;
-       }
-
        dbg("%s - clfag %08x iflag %08x", __FUNCTION__,
            tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
-
-       if (old_termios) {
-               dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
-                   old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
-       }
-
+       dbg("%s - old clfag %08x old iflag %08x", __FUNCTION__,
+           old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
        dbg("%s - port %d", __FUNCTION__, port->number);
 
        /* change the port settings to the new ones specified */
index a18659e..4590124 100644 (file)
@@ -172,6 +172,8 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4100) }, /* Novatel U727 */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x4400) }, /* Novatel MC950 */
        { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
        { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
        { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
@@ -311,7 +313,8 @@ static void option_set_termios(struct usb_serial_port *port,
                        struct ktermios *old_termios)
 {
        dbg("%s", __FUNCTION__);
-
+       /* Doesn't support option setting */
+       tty_termios_copy_hw(port->tty->termios, old_termios);
        option_send_setup(port);
 }
 
index 1da57fd..2cd3f1d 100644 (file)
@@ -56,6 +56,7 @@ static struct usb_device_id id_table [] = {
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_RSAQ3) },
        { USB_DEVICE(PL2303_VENDOR_ID, PL2303_PRODUCT_ID_PHAROS) },
        { 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) },
        { USB_DEVICE(ATEN_VENDOR_ID2, ATEN_PRODUCT_ID) },
        { USB_DEVICE(ELCOM_VENDOR_ID, ELCOM_PRODUCT_ID) },
@@ -470,16 +471,13 @@ static void pl2303_set_termios(struct usb_serial_port *port,
 
        dbg("%s -  port %d", __FUNCTION__, port->number);
 
-       if ((!port->tty) || (!port->tty->termios)) {
-               dbg("%s - no tty structures", __FUNCTION__);
-               return;
-       }
-
        spin_lock_irqsave(&priv->lock, flags);
        if (!priv->termios_initialized) {
                *(port->tty->termios) = tty_std_termios;
                port->tty->termios->c_cflag = B9600 | CS8 | CREAD |
                                              HUPCL | CLOCAL;
+               port->tty->termios->c_ispeed = 9600;
+               port->tty->termios->c_ospeed = 9600;
                priv->termios_initialized = 1;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
@@ -596,6 +594,10 @@ static void pl2303_set_termios(struct usb_serial_port *port,
                dbg ("0x40:0x1:0x0:0x0  %d", i);
        }
 
+       /* FIXME: Need to read back resulting baud rate */
+       if (baud)
+               tty_encode_baud_rate(port->tty, baud, baud);
+
        kfree(buf);
 }
 
index c39bace..ed603e3 100644 (file)
@@ -20,6 +20,7 @@
 
 #define IODATA_VENDOR_ID       0x04bb
 #define IODATA_PRODUCT_ID      0x0a03
+#define IODATA_PRODUCT_ID_RSAQ5        0x0a0e
 
 #define ELCOM_VENDOR_ID                0x056e
 #define ELCOM_PRODUCT_ID       0x5003
index 959b3e4..833f6e1 100644 (file)
@@ -224,7 +224,7 @@ static void sierra_set_termios(struct usb_serial_port *port,
                        struct ktermios *old_termios)
 {
        dbg("%s", __FUNCTION__);
-
+       tty_termios_copy_hw(port->tty->termios, old_termios);
        sierra_send_setup(port);
 }
 
index 4b1bd7d..497e29a 100644 (file)
@@ -429,6 +429,8 @@ static void serial_set_termios (struct tty_struct *tty, struct ktermios * old)
        /* pass on to the driver specific version of this function if it is available */
        if (port->serial->type->set_termios)
                port->serial->type->set_termios(port, old);
+       else
+               tty_termios_copy_hw(tty->termios, old);
 }
 
 static void serial_break (struct tty_struct *tty, int break_state)
@@ -1121,7 +1123,9 @@ int usb_serial_resume(struct usb_interface *intf)
 {
        struct usb_serial *serial = usb_get_intfdata(intf);
 
-       return serial->type->resume(serial);
+       if (serial->type->resume)
+               return serial->type->resume(serial);
+       return 0;
 }
 EXPORT_SYMBOL(usb_serial_resume);
 
index cc8b44c..ee5dd8b 100644 (file)
@@ -885,16 +885,7 @@ static int whiteheat_ioctl (struct usb_serial_port *port, struct file * file, un
 static void whiteheat_set_termios(struct usb_serial_port *port, struct ktermios *old_termios)
 {
        dbg("%s -port %d", __FUNCTION__, port->number);
-
-       if ((!port->tty) || (!port->tty->termios)) {
-               dbg("%s - no tty structures", __FUNCTION__);
-               goto exit;
-       }
-       
        firm_setup_port(port);
-
-exit:
-       return;
 }
 
 
@@ -1244,6 +1235,8 @@ static int firm_setup_port(struct usb_serial_port *port) {
        port_settings.baud = tty_get_baud_rate(port->tty);
        dbg("%s - baud rate = %d", __FUNCTION__, port_settings.baud);
 
+       /* fixme: should set validated settings */
+       tty_encode_baud_rate(port->tty, port_settings.baud, port_settings.baud);
        /* handle any settings that aren't specified in the tty structure */
        port_settings.lloop = 0;
        
index fe2c4cd..7e53333 100644 (file)
@@ -48,7 +48,6 @@ config USB_STORAGE_FREECOM
 config USB_STORAGE_ISD200
        bool "ISD-200 USB/ATA Bridge support"
        depends on USB_STORAGE
-       depends on BLK_DEV_IDE=y || BLK_DEV_IDE=USB_STORAGE
        ---help---
          Say Y here if you want to use USB Mass Store devices based
          on the In-Systems Design ISD-200 USB/ATA bridge.
index 93a7724..49ba6c0 100644 (file)
@@ -977,6 +977,109 @@ static int isd200_manual_enum(struct us_data *us)
        return(retStatus);
 }
 
+/*
+ *     We are the last non IDE user of the legacy IDE ident structures
+ *     and we thus want to keep a private copy of this function so the
+ *     driver can be used without the obsolete drivers/ide layer
+ */
+
+static void isd200_fix_driveid (struct hd_driveid *id)
+{
+#ifndef __LITTLE_ENDIAN
+# ifdef __BIG_ENDIAN
+       int i;
+       u16 *stringcast;
+
+       id->config         = __le16_to_cpu(id->config);
+       id->cyls           = __le16_to_cpu(id->cyls);
+       id->reserved2      = __le16_to_cpu(id->reserved2);
+       id->heads          = __le16_to_cpu(id->heads);
+       id->track_bytes    = __le16_to_cpu(id->track_bytes);
+       id->sector_bytes   = __le16_to_cpu(id->sector_bytes);
+       id->sectors        = __le16_to_cpu(id->sectors);
+       id->vendor0        = __le16_to_cpu(id->vendor0);
+       id->vendor1        = __le16_to_cpu(id->vendor1);
+       id->vendor2        = __le16_to_cpu(id->vendor2);
+       stringcast = (u16 *)&id->serial_no[0];
+       for (i = 0; i < (20/2); i++)
+               stringcast[i] = __le16_to_cpu(stringcast[i]);
+       id->buf_type       = __le16_to_cpu(id->buf_type);
+       id->buf_size       = __le16_to_cpu(id->buf_size);
+       id->ecc_bytes      = __le16_to_cpu(id->ecc_bytes);
+       stringcast = (u16 *)&id->fw_rev[0];
+       for (i = 0; i < (8/2); i++)
+               stringcast[i] = __le16_to_cpu(stringcast[i]);
+       stringcast = (u16 *)&id->model[0];
+       for (i = 0; i < (40/2); i++)
+               stringcast[i] = __le16_to_cpu(stringcast[i]);
+       id->dword_io       = __le16_to_cpu(id->dword_io);
+       id->reserved50     = __le16_to_cpu(id->reserved50);
+       id->field_valid    = __le16_to_cpu(id->field_valid);
+       id->cur_cyls       = __le16_to_cpu(id->cur_cyls);
+       id->cur_heads      = __le16_to_cpu(id->cur_heads);
+       id->cur_sectors    = __le16_to_cpu(id->cur_sectors);
+       id->cur_capacity0  = __le16_to_cpu(id->cur_capacity0);
+       id->cur_capacity1  = __le16_to_cpu(id->cur_capacity1);
+       id->lba_capacity   = __le32_to_cpu(id->lba_capacity);
+       id->dma_1word      = __le16_to_cpu(id->dma_1word);
+       id->dma_mword      = __le16_to_cpu(id->dma_mword);
+       id->eide_pio_modes = __le16_to_cpu(id->eide_pio_modes);
+       id->eide_dma_min   = __le16_to_cpu(id->eide_dma_min);
+       id->eide_dma_time  = __le16_to_cpu(id->eide_dma_time);
+       id->eide_pio       = __le16_to_cpu(id->eide_pio);
+       id->eide_pio_iordy = __le16_to_cpu(id->eide_pio_iordy);
+       for (i = 0; i < 2; ++i)
+               id->words69_70[i] = __le16_to_cpu(id->words69_70[i]);
+       for (i = 0; i < 4; ++i)
+               id->words71_74[i] = __le16_to_cpu(id->words71_74[i]);
+       id->queue_depth    = __le16_to_cpu(id->queue_depth);
+       for (i = 0; i < 4; ++i)
+               id->words76_79[i] = __le16_to_cpu(id->words76_79[i]);
+       id->major_rev_num  = __le16_to_cpu(id->major_rev_num);
+       id->minor_rev_num  = __le16_to_cpu(id->minor_rev_num);
+       id->command_set_1  = __le16_to_cpu(id->command_set_1);
+       id->command_set_2  = __le16_to_cpu(id->command_set_2);
+       id->cfsse          = __le16_to_cpu(id->cfsse);
+       id->cfs_enable_1   = __le16_to_cpu(id->cfs_enable_1);
+       id->cfs_enable_2   = __le16_to_cpu(id->cfs_enable_2);
+       id->csf_default    = __le16_to_cpu(id->csf_default);
+       id->dma_ultra      = __le16_to_cpu(id->dma_ultra);
+       id->trseuc         = __le16_to_cpu(id->trseuc);
+       id->trsEuc         = __le16_to_cpu(id->trsEuc);
+       id->CurAPMvalues   = __le16_to_cpu(id->CurAPMvalues);
+       id->mprc           = __le16_to_cpu(id->mprc);
+       id->hw_config      = __le16_to_cpu(id->hw_config);
+       id->acoustic       = __le16_to_cpu(id->acoustic);
+       id->msrqs          = __le16_to_cpu(id->msrqs);
+       id->sxfert         = __le16_to_cpu(id->sxfert);
+       id->sal            = __le16_to_cpu(id->sal);
+       id->spg            = __le32_to_cpu(id->spg);
+       id->lba_capacity_2 = __le64_to_cpu(id->lba_capacity_2);
+       for (i = 0; i < 22; i++)
+               id->words104_125[i]   = __le16_to_cpu(id->words104_125[i]);
+       id->last_lun       = __le16_to_cpu(id->last_lun);
+       id->word127        = __le16_to_cpu(id->word127);
+       id->dlf            = __le16_to_cpu(id->dlf);
+       id->csfo           = __le16_to_cpu(id->csfo);
+       for (i = 0; i < 26; i++)
+               id->words130_155[i] = __le16_to_cpu(id->words130_155[i]);
+       id->word156        = __le16_to_cpu(id->word156);
+       for (i = 0; i < 3; i++)
+               id->words157_159[i] = __le16_to_cpu(id->words157_159[i]);
+       id->cfa_power      = __le16_to_cpu(id->cfa_power);
+       for (i = 0; i < 14; i++)
+               id->words161_175[i] = __le16_to_cpu(id->words161_175[i]);
+       for (i = 0; i < 31; i++)
+               id->words176_205[i] = __le16_to_cpu(id->words176_205[i]);
+       for (i = 0; i < 48; i++)
+               id->words206_254[i] = __le16_to_cpu(id->words206_254[i]);
+       id->integrity_word  = __le16_to_cpu(id->integrity_word);
+# else
+#  error "Please fix <asm/byteorder.h>"
+# endif
+#endif
+}
+
 
 /**************************************************************************
  * isd200_get_inquiry_data
@@ -1018,7 +1121,7 @@ static int isd200_get_inquiry_data( struct us_data *us )
                                int i;
                                __be16 *src;
                                __u16 *dest;
-                               ide_fix_driveid(id);
+                               isd200_fix_driveid(id);
 
                                US_DEBUGP("   Identify Data Structure:\n");
                                US_DEBUGP("      config = 0x%x\n", id->config);
index f99cb77..f7e2d5a 100644 (file)
@@ -2509,8 +2509,7 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
        cinfo = info->par;
        cinfo->btype = btype;
 
-       assert(z > 0);
-       assert(z2 >= 0);
+       assert(z);
        assert(btype != BT_NONE);
 
        cinfo->zdev = z;
index 0a9882e..9d70289 100644 (file)
@@ -279,13 +279,13 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
        int offset;
        int remainder_of_page;
 
+       sg_init_table(sg, sg_size);
+
        while (size > 0 && i < sg_size) {
                pg = virt_to_page(addr);
                offset = offset_in_page(addr);
-               if (sg) {
-                       sg_set_page(&sg[i], pg);
-                       sg[i].offset = offset;
-               }
+               if (sg)
+                       sg_set_page(&sg[i], pg, 0, offset);
                remainder_of_page = PAGE_CACHE_SIZE - offset;
                if (size >= remainder_of_page) {
                        if (sg)
@@ -716,12 +716,8 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
        sg_init_table(&src_sg, 1);
        sg_init_table(&dst_sg, 1);
 
-       sg_set_page(&src_sg, src_page);
-       src_sg.offset = src_offset;
-       src_sg.length = size;
-       sg_set_page(&dst_sg, dst_page);
-       dst_sg.offset = dst_offset;
-       dst_sg.length = size;
+       sg_set_page(&src_sg, src_page, size, src_offset);
+       sg_set_page(&dst_sg, dst_page, size, dst_offset);
        return encrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
 }
 
@@ -746,14 +742,11 @@ ecryptfs_decrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
        struct scatterlist src_sg, dst_sg;
 
        sg_init_table(&src_sg, 1);
+       sg_set_page(&src_sg, src_page, size, src_offset);
+
        sg_init_table(&dst_sg, 1);
+       sg_set_page(&dst_sg, dst_page, size, dst_offset);
 
-       sg_set_page(&src_sg, src_page);
-       src_sg.offset = src_offset;
-       src_sg.length = size;
-       sg_set_page(&dst_sg, dst_page);
-       dst_sg.offset = dst_offset;
-       dst_sg.length = size;
        return decrypt_scatterlist(crypt_stat, &dst_sg, &src_sg, size, iv);
 }
 
index 9728614..77fc583 100644 (file)
@@ -372,7 +372,7 @@ int jffs2_init_acl_post(struct inode *inode)
                        return rc;
        }
 
-       return rc;
+       return 0;
 }
 
 void jffs2_clear_acl(struct jffs2_inode_info *f)
index 1046cbe..eb31b73 100644 (file)
@@ -403,9 +403,9 @@ mb_cache_entry_alloc(struct mb_cache *cache)
 {
        struct mb_cache_entry *ce;
 
-       atomic_inc(&cache->c_entry_count);
        ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
        if (ce) {
+               atomic_inc(&cache->c_entry_count);
                INIT_LIST_HEAD(&ce->e_lru_list);
                INIT_LIST_HEAD(&ce->e_block_list);
                ce->e_cache = cache;
index 2e91fb7..749def0 100644 (file)
@@ -185,7 +185,7 @@ static __net_exit void proc_net_ns_exit(struct net *net)
        kfree(net->proc_net_root);
 }
 
-struct pernet_operations __net_initdata proc_net_ns_ops = {
+static struct pernet_operations proc_net_ns_ops = {
        .init = proc_net_ns_init,
        .exit = proc_net_ns_exit,
 };
index 680c429..4e57fcf 100644 (file)
@@ -171,7 +171,8 @@ static ssize_t proc_sys_read(struct file *filp, char __user *buf,
        struct dentry *dentry = filp->f_dentry;
        struct ctl_table_header *head;
        struct ctl_table *table;
-       ssize_t error, res;
+       ssize_t error;
+       size_t res;
 
        table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
        /* Has the sysctl entry disappeared on us? */
@@ -209,7 +210,8 @@ static ssize_t proc_sys_write(struct file *filp, const char __user *buf,
        struct dentry *dentry = filp->f_dentry;
        struct ctl_table_header *head;
        struct ctl_table *table;
-       ssize_t error, res;
+       ssize_t error;
+       size_t res;
 
        table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head);
        /* Has the sysctl entry disappeared on us? */
index 7b74b60..19c3ead 100644 (file)
@@ -168,8 +168,7 @@ struct acpi_device_flags {
        u32 power_manageable:1;
        u32 performance_manageable:1;
        u32 wake_capable:1;     /* Wakeup(_PRW) supported? */
-       u32 force_power_state:1;
-       u32 reserved:19;
+       u32 reserved:20;
 };
 
 /* File System */
index a713163..57dc672 100644 (file)
@@ -3,7 +3,7 @@
 
 #include <linux/mm.h>
 #include <linux/device.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <asm/processor.h>
 #include <asm/cacheflush.h>
 #include <asm/io.h>
index 99ba76e..2e7143b 100644 (file)
@@ -16,8 +16,7 @@
  *
  * can be rewritten as
  *
- * sg_set_page(virt_to_page(some_ptr));
- * sg->offset = (unsigned long) some_ptr & ~PAGE_MASK;
+ * sg_set_buf(sg, some_ptr, length);
  *
  * and that's it. There's no excuse for not highmem enabling YOUR driver. /jens
  */
index bdca541..3328950 100644 (file)
@@ -1,6 +1,6 @@
 /* atomic.h: These still suck, but the I-cache hit rate is higher.
  *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 2000 Anton Blanchard (anton@linuxcare.com.au)
  * Copyright (C) 2007 Kyle McMartin (kyle@parisc-linux.org)
  *
@@ -33,7 +33,7 @@ extern void __cmpxchg_called_with_bad_pointer(void);
 extern unsigned long __cmpxchg_u32(volatile u32 *m, u32 old, u32 new_);
 
 /* don't worry...optimizer will get rid of most of this */
-static __inline__ unsigned long
+static inline unsigned long
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new_, int size)
 {
        switch(size) {
index 407b361..959d6c8 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: dma.h,v 1.35 1999/12/27 06:37:09 anton Exp $
- * include/asm-sparc/dma.h
+/* include/asm-sparc/dma.h
  *
- * Copyright 1995 (C) David S. Miller (davem@caip.rutgers.edu)
+ * Copyright 1995 (C) David S. Miller (davem@davemloft.net)
  */
 
 #ifndef _ASM_SPARC_DMA_H
 struct page;
 extern spinlock_t  dma_spin_lock;
 
-static __inline__ unsigned long claim_dma_lock(void)
+static inline unsigned long claim_dma_lock(void)
 {
        unsigned long flags;
        spin_lock_irqsave(&dma_spin_lock, flags);
        return flags;
 }
 
-static __inline__ void release_dma_lock(unsigned long flags)
+static inline void release_dma_lock(unsigned long flags)
 {
        spin_unlock_irqrestore(&dma_spin_lock, flags);
 }
index 5da1eef..dbe7a58 100644 (file)
@@ -1,6 +1,6 @@
 /* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver.
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
  */
 
 #ifndef __ASM_SPARC_FLOPPY_H
@@ -232,12 +232,12 @@ extern char *pdma_base;
 extern unsigned long pdma_areasize;
 
 /* Common routines to all controller types on the Sparc. */
-static __inline__ void virtual_dma_init(void)
+static inline void virtual_dma_init(void)
 {
        /* nothing... */
 }
 
-static __inline__ void sun_fd_disable_dma(void)
+static inline void sun_fd_disable_dma(void)
 {
        doing_pdma = 0;
        if (pdma_base) {
@@ -246,7 +246,7 @@ static __inline__ void sun_fd_disable_dma(void)
        }
 }
 
-static __inline__ void sun_fd_set_dma_mode(int mode)
+static inline void sun_fd_set_dma_mode(int mode)
 {
        switch(mode) {
        case DMA_MODE_READ:
@@ -261,17 +261,17 @@ static __inline__ void sun_fd_set_dma_mode(int mode)
        }
 }
 
-static __inline__ void sun_fd_set_dma_addr(char *buffer)
+static inline void sun_fd_set_dma_addr(char *buffer)
 {
        pdma_vaddr = buffer;
 }
 
-static __inline__ void sun_fd_set_dma_count(int length)
+static inline void sun_fd_set_dma_count(int length)
 {
        pdma_size = length;
 }
 
-static __inline__ void sun_fd_enable_dma(void)
+static inline void sun_fd_enable_dma(void)
 {
        pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
        pdma_base = pdma_vaddr;
index 4040227..4076cb5 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: ide.h,v 1.7 2002/01/16 20:58:40 davem Exp $
- * ide.h: SPARC PCI specific IDE glue.
+/* ide.h: SPARC PCI specific IDE glue.
  *
- * Copyright (C) 1997  David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1997  David S. Miller (davem@davemloft.net)
  * Copyright (C) 1998  Eddie C. Dost   (ecd@skynet.be)
  * Adaptation from sparc64 version to sparc by Pete Zaitcev.
  */
@@ -31,7 +30,7 @@
 #define __ide_mm_outsw __ide_outsw
 #define __ide_mm_outsl __ide_outsl
 
-static __inline__ void __ide_insw(unsigned long port,
+static inline void __ide_insw(unsigned long port,
                                  void *dst,
                                  unsigned long count)
 {
@@ -62,7 +61,7 @@ static __inline__ void __ide_insw(unsigned long port,
        /* __flush_dcache_range((unsigned long)dst, end); */ /* P3 see hme */
 }
 
-static __inline__ void __ide_outsw(unsigned long port,
+static inline void __ide_outsw(unsigned long port,
                                   const void *src,
                                   unsigned long count)
 {
index 9ef1b3d..62c8fa7 100644 (file)
@@ -49,7 +49,7 @@ typedef struct {
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
 {
        unsigned long _tmp = fd / __NFDBITS;
        unsigned long _rem = fd % __NFDBITS;
@@ -57,7 +57,7 @@ static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
 }
 
 #undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
 {
        unsigned long _tmp = fd / __NFDBITS;
        unsigned long _rem = fd % __NFDBITS;
@@ -65,7 +65,7 @@ static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
 }
 
 #undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
+static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
 { 
        unsigned long _tmp = fd / __NFDBITS;
        unsigned long _rem = fd % __NFDBITS;
@@ -77,7 +77,7 @@ static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
  * for 256 and 1024-bit fd_sets respectively)
  */
 #undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+static inline void __FD_ZERO(__kernel_fd_set *p)
 {
        unsigned long *tmp = p->fds_bits;
        int i;
index 8c259de..2655d14 100644 (file)
@@ -1,5 +1,3 @@
-/* $Id: system.h,v 1.86 2001/10/30 04:57:10 davem Exp $ */
-
 #ifndef __SPARC_SYSTEM_H
 #define __SPARC_SYSTEM_H
 
@@ -56,7 +54,7 @@ extern void sun_do_break(void);
 extern int serial_console;
 extern int stop_a_enabled;
 
-static __inline__ int con_is_present(void)
+static inline int con_is_present(void)
 {
        return serial_console ? 0 : 1;
 }
@@ -217,7 +215,7 @@ static inline unsigned long xchg_u32(__volatile__ unsigned long *m, unsigned lon
 
 extern void __xchg_called_with_bad_pointer(void);
 
-static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
+static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr, int size)
 {
        switch (size) {
        case 4:
index 3fb4e1f..2c71ec4 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: atomic.h,v 1.22 2001/07/11 23:56:07 davem Exp $
- * atomic.h: Thankfully the V9 is at least reasonable for this
+/* atomic.h: Thankfully the V9 is at least reasonable for this
  *           stuff.
  *
  * Copyright (C) 1996, 1997, 2000 David S. Miller (davem@redhat.com)
@@ -74,7 +73,7 @@ extern int atomic64_sub_ret(int, atomic64_t *);
 #define atomic_cmpxchg(v, o, n) (cmpxchg(&((v)->counter), (o), (n)))
 #define atomic_xchg(v, new) (xchg(&((v)->counter), new))
 
-static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
+static inline int atomic_add_unless(atomic_t *v, int a, int u)
 {
        int c, old;
        c = atomic_read(v);
@@ -95,7 +94,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u)
        ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
 #define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
 
-static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
+static inline int atomic64_add_unless(atomic64_t *v, long a, long u)
 {
        long c, old;
        c = atomic64_read(v);
index 0e32f8b..dadd6c3 100644 (file)
@@ -21,7 +21,9 @@
 #else
 
 #define BACKOFF_SETUP(reg)
-#define BACKOFF_SPIN(reg, tmp, label)
+#define BACKOFF_SPIN(reg, tmp, label) \
+       ba,pt   %xcc, label; \
+        nop;
 
 #endif
 
index c69b08a..3943022 100644 (file)
@@ -1,4 +1,3 @@
-/* $Id: byteorder.h,v 1.8 1997/12/18 02:44:14 ecd Exp $ */
 #ifndef _SPARC64_BYTEORDER_H
 #define _SPARC64_BYTEORDER_H
 
@@ -7,7 +6,7 @@
 
 #ifdef __GNUC__
 
-static __inline__ __u16 ___arch__swab16p(const __u16 *addr)
+static inline __u16 ___arch__swab16p(const __u16 *addr)
 {
        __u16 ret;
 
@@ -17,7 +16,7 @@ static __inline__ __u16 ___arch__swab16p(const __u16 *addr)
        return ret;
 }
 
-static __inline__ __u32 ___arch__swab32p(const __u32 *addr)
+static inline __u32 ___arch__swab32p(const __u32 *addr)
 {
        __u32 ret;
 
@@ -27,7 +26,7 @@ static __inline__ __u32 ___arch__swab32p(const __u32 *addr)
        return ret;
 }
 
-static __inline__ __u64 ___arch__swab64p(const __u64 *addr)
+static inline __u64 ___arch__swab64p(const __u64 *addr)
 {
        __u64 ret;
 
index d583e5e..cc463fe 100644 (file)
@@ -16,7 +16,7 @@ struct fpustate {
 
 #define FPUSTATE (struct fpustate *)(current_thread_info()->fpregs)
 
-static __inline__ unsigned long fprs_read(void)
+static inline unsigned long fprs_read(void)
 {
        unsigned long retval;
 
@@ -25,7 +25,7 @@ static __inline__ unsigned long fprs_read(void)
        return retval;
 }
 
-static __inline__ void fprs_write(unsigned long val)
+static inline void fprs_write(unsigned long val)
 {
        __asm__ __volatile__("wr %0, 0x0, %%fprs" : : "r" (val));
 }
index cd7ef30..c299b85 100644 (file)
@@ -1,4 +1,3 @@
-/* $Id: io.h,v 1.47 2001/12/13 10:36:02 davem Exp $ */
 #ifndef __SPARC64_IO_H
 #define __SPARC64_IO_H
 
@@ -19,7 +18,7 @@ extern unsigned long kern_base, kern_size;
 #define page_to_phys(page)     (page_to_pfn(page) << PAGE_SHIFT)
 #define BIO_VMERGE_BOUNDARY    8192
 
-static __inline__ u8 _inb(unsigned long addr)
+static inline u8 _inb(unsigned long addr)
 {
        u8 ret;
 
@@ -30,7 +29,7 @@ static __inline__ u8 _inb(unsigned long addr)
        return ret;
 }
 
-static __inline__ u16 _inw(unsigned long addr)
+static inline u16 _inw(unsigned long addr)
 {
        u16 ret;
 
@@ -41,7 +40,7 @@ static __inline__ u16 _inw(unsigned long addr)
        return ret;
 }
 
-static __inline__ u32 _inl(unsigned long addr)
+static inline u32 _inl(unsigned long addr)
 {
        u32 ret;
 
@@ -52,21 +51,21 @@ static __inline__ u32 _inl(unsigned long addr)
        return ret;
 }
 
-static __inline__ void _outb(u8 b, unsigned long addr)
+static inline void _outb(u8 b, unsigned long addr)
 {
        __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */"
                             : /* no outputs */
                             : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
 }
 
-static __inline__ void _outw(u16 w, unsigned long addr)
+static inline void _outw(u16 w, unsigned long addr)
 {
        __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */"
                             : /* no outputs */
                             : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
 }
 
-static __inline__ void _outl(u32 l, unsigned long addr)
+static inline void _outl(u32 l, unsigned long addr)
 {
        __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */"
                             : /* no outputs */
@@ -205,7 +204,7 @@ static inline void _writeq(u64 q, volatile void __iomem *addr)
 #define writeq(__q, __addr)    _writeq(__q, __addr)
 
 /* Now versions without byte-swapping. */
-static __inline__ u8 _raw_readb(unsigned long addr)
+static inline u8 _raw_readb(unsigned long addr)
 {
        u8 ret;
 
@@ -216,7 +215,7 @@ static __inline__ u8 _raw_readb(unsigned long addr)
        return ret;
 }
 
-static __inline__ u16 _raw_readw(unsigned long addr)
+static inline u16 _raw_readw(unsigned long addr)
 {
        u16 ret;
 
@@ -227,7 +226,7 @@ static __inline__ u16 _raw_readw(unsigned long addr)
        return ret;
 }
 
-static __inline__ u32 _raw_readl(unsigned long addr)
+static inline u32 _raw_readl(unsigned long addr)
 {
        u32 ret;
 
@@ -238,7 +237,7 @@ static __inline__ u32 _raw_readl(unsigned long addr)
        return ret;
 }
 
-static __inline__ u64 _raw_readq(unsigned long addr)
+static inline u64 _raw_readq(unsigned long addr)
 {
        u64 ret;
 
@@ -249,28 +248,28 @@ static __inline__ u64 _raw_readq(unsigned long addr)
        return ret;
 }
 
-static __inline__ void _raw_writeb(u8 b, unsigned long addr)
+static inline void _raw_writeb(u8 b, unsigned long addr)
 {
        __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
                             : /* no outputs */
                             : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
 }
 
-static __inline__ void _raw_writew(u16 w, unsigned long addr)
+static inline void _raw_writew(u16 w, unsigned long addr)
 {
        __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
                             : /* no outputs */
                             : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
 }
 
-static __inline__ void _raw_writel(u32 l, unsigned long addr)
+static inline void _raw_writel(u32 l, unsigned long addr)
 {
        __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
                             : /* no outputs */
                             : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
 }
 
-static __inline__ void _raw_writeq(u64 q, unsigned long addr)
+static inline void _raw_writeq(u64 q, unsigned long addr)
 {
        __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */"
                             : /* no outputs */
index 182dba0..30cb76b 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: irq.h,v 1.21 2002/01/23 11:27:36 davem Exp $
- * irq.h: IRQ registers on the 64-bit Sparc.
+/* irq.h: IRQ registers on the 64-bit Sparc.
  *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
  */
 
@@ -67,21 +66,21 @@ extern void virt_irq_free(unsigned int virt_irq);
 
 extern void fixup_irqs(void);
 
-static __inline__ void set_softint(unsigned long bits)
+static inline void set_softint(unsigned long bits)
 {
        __asm__ __volatile__("wr        %0, 0x0, %%set_softint"
                             : /* No outputs */
                             : "r" (bits));
 }
 
-static __inline__ void clear_softint(unsigned long bits)
+static inline void clear_softint(unsigned long bits)
 {
        __asm__ __volatile__("wr        %0, 0x0, %%clear_softint"
                             : /* No outputs */
                             : "r" (bits));
 }
 
-static __inline__ unsigned long get_softint(void)
+static inline unsigned long get_softint(void)
 {
        unsigned long retval;
 
index d14dd89..c5652de 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: mostek.h,v 1.4 2001/01/11 15:07:09 davem Exp $
- * mostek.h:  Describes the various Mostek time of day clock registers.
+/* mostek.h:  Describes the various Mostek time of day clock registers.
  *
- * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995 David S. Miller (davem@davemloft.net)
  * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
  */
 
@@ -38,7 +37,7 @@
  *
  * We now deal with physical addresses for I/O to the chip. -DaveM
  */
-static __inline__ u8 mostek_read(void __iomem *addr)
+static inline u8 mostek_read(void __iomem *addr)
 {
        u8 ret;
 
@@ -48,7 +47,7 @@ static __inline__ u8 mostek_read(void __iomem *addr)
        return ret;
 }
 
-static __inline__ void mostek_write(void __iomem *addr, u8 val)
+static inline void mostek_write(void __iomem *addr, u8 val)
 {
        __asm__ __volatile__("stba      %0, [%1] %2"
                             : /* no outputs */
index 6d58fdf..686defe 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: ns87303.h,v 1.3 2000/01/09 15:16:34 ecd Exp $
- * ns87303.h: Configuration Register Description for the
+/* ns87303.h: Configuration Register Description for the
  *            National Semiconductor PC87303 (SuperIO).
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -85,7 +84,7 @@
 
 extern spinlock_t ns87303_lock;
 
-static __inline__ int ns87303_modify(unsigned long port, unsigned int index,
+static inline int ns87303_modify(unsigned long port, unsigned int index,
                                     unsigned char clr, unsigned char set)
 {
        static unsigned char reserved[] = {
index 8116e8f..e9555b2 100644 (file)
@@ -1,5 +1,4 @@
-/* $Id: parport.h,v 1.11 2001/05/11 07:54:24 davem Exp $
- * parport.h: sparc64 specific parport initialization and dma.
+/* parport.h: sparc64 specific parport initialization and dma.
  *
  * Copyright (C) 1999  Eddie C. Dost  (ecd@skynet.be)
  */
@@ -42,7 +41,7 @@ static struct sparc_ebus_info {
 
 static DECLARE_BITMAP(dma_slot_map, PARPORT_PC_MAX_PORTS);
 
-static __inline__ int request_dma(unsigned int dmanr, const char *device_id)
+static inline int request_dma(unsigned int dmanr, const char *device_id)
 {
        if (dmanr >= PARPORT_PC_MAX_PORTS)
                return -EINVAL;
@@ -51,7 +50,7 @@ static __inline__ int request_dma(unsigned int dmanr, const char *device_id)
        return 0;
 }
 
-static __inline__ void free_dma(unsigned int dmanr)
+static inline void free_dma(unsigned int dmanr)
 {
        if (dmanr >= PARPORT_PC_MAX_PORTS) {
                printk(KERN_WARNING "Trying to free DMA%d\n", dmanr);
@@ -63,7 +62,7 @@ static __inline__ void free_dma(unsigned int dmanr)
        }       
 }
 
-static __inline__ void enable_dma(unsigned int dmanr)
+static inline void enable_dma(unsigned int dmanr)
 {
        ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 1);
 
@@ -73,32 +72,32 @@ static __inline__ void enable_dma(unsigned int dmanr)
                BUG();
 }
 
-static __inline__ void disable_dma(unsigned int dmanr)
+static inline void disable_dma(unsigned int dmanr)
 {
        ebus_dma_enable(&sparc_ebus_dmas[dmanr].info, 0);
 }
 
-static __inline__ void clear_dma_ff(unsigned int dmanr)
+static inline void clear_dma_ff(unsigned int dmanr)
 {
        /* nothing */
 }
 
-static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+static inline void set_dma_mode(unsigned int dmanr, char mode)
 {
        ebus_dma_prepare(&sparc_ebus_dmas[dmanr].info, (mode != DMA_MODE_WRITE));
 }
 
-static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int addr)
+static inline void set_dma_addr(unsigned int dmanr, unsigned int addr)
 {
        sparc_ebus_dmas[dmanr].addr = addr;
 }
 
-static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+static inline void set_dma_count(unsigned int dmanr, unsigned int count)
 {
        sparc_ebus_dmas[dmanr].count = count;
 }
 
-static __inline__ unsigned int get_dma_residue(unsigned int dmanr)
+static inline unsigned int get_dma_residue(unsigned int dmanr)
 {
        return ebus_dma_residue(&sparc_ebus_dmas[dmanr].info);
 }
index c86b945..3426a65 100644 (file)
@@ -53,7 +53,7 @@ typedef struct {
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #undef __FD_SET
-static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
+static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
 {
        unsigned long _tmp = fd / __NFDBITS;
        unsigned long _rem = fd % __NFDBITS;
@@ -61,7 +61,7 @@ static __inline__ void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp)
 }
 
 #undef __FD_CLR
-static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
+static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
 {
        unsigned long _tmp = fd / __NFDBITS;
        unsigned long _rem = fd % __NFDBITS;
@@ -69,7 +69,7 @@ static __inline__ void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp)
 }
 
 #undef __FD_ISSET
-static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
+static inline int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
 { 
        unsigned long _tmp = fd / __NFDBITS;
        unsigned long _rem = fd % __NFDBITS;
@@ -81,7 +81,7 @@ static __inline__ int __FD_ISSET(unsigned long fd, __const__ __kernel_fd_set *p)
  * for 256 and 1024-bit fd_sets respectively)
  */
 #undef __FD_ZERO
-static __inline__ void __FD_ZERO(__kernel_fd_set *p)
+static inline void __FD_ZERO(__kernel_fd_set *p)
 {
        unsigned long *tmp = p->fds_bits;
        int i;
index 0151cad..24a04a5 100644 (file)
  * numbers + offsets, and vice versa.
  */
 
-static __inline__ unsigned long sbus_devaddr(int slotnum, unsigned long offset)
+static inline unsigned long sbus_devaddr(int slotnum, unsigned long offset)
 {
   return (unsigned long) (SUN_SBUS_BVADDR+((slotnum)<<28)+(offset));
 }
 
-static __inline__ int sbus_dev_slot(unsigned long dev_addr)
+static inline int sbus_dev_slot(unsigned long dev_addr)
 {
   return (int) (((dev_addr)-SUN_SBUS_BVADDR)>>28);
 }
index cf78078..63b7040 100644 (file)
@@ -1,7 +1,6 @@
-/* $Id: spitfire.h,v 1.18 2001/11/29 16:42:10 kanoj Exp $
- * spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
+/* spitfire.h: SpitFire/BlackBird/Cheetah inline MMU operations.
  *
- * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
  */
 
 #ifndef _SPARC64_SPITFIRE_H
@@ -67,7 +66,7 @@ extern void cheetah_enable_pcache(void);
 /* The data cache is write through, so this just invalidates the
  * specified line.
  */
-static __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
+static inline void spitfire_put_dcache_tag(unsigned long addr, unsigned long tag)
 {
        __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
                             "membar    #Sync"
@@ -81,7 +80,7 @@ static __inline__ void spitfire_put_dcache_tag(unsigned long addr, unsigned long
  * a flush instruction (to any address) is sufficient to handle
  * this issue after the line is invalidated.
  */
-static __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
+static inline void spitfire_put_icache_tag(unsigned long addr, unsigned long tag)
 {
        __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
                             "membar    #Sync"
@@ -89,7 +88,7 @@ static __inline__ void spitfire_put_icache_tag(unsigned long addr, unsigned long
                             : "r" (tag), "r" (addr), "i" (ASI_IC_TAG));
 }
 
-static __inline__ unsigned long spitfire_get_dtlb_data(int entry)
+static inline unsigned long spitfire_get_dtlb_data(int entry)
 {
        unsigned long data;
 
@@ -103,7 +102,7 @@ static __inline__ unsigned long spitfire_get_dtlb_data(int entry)
        return data;
 }
 
-static __inline__ unsigned long spitfire_get_dtlb_tag(int entry)
+static inline unsigned long spitfire_get_dtlb_tag(int entry)
 {
        unsigned long tag;
 
@@ -113,7 +112,7 @@ static __inline__ unsigned long spitfire_get_dtlb_tag(int entry)
        return tag;
 }
 
-static __inline__ void spitfire_put_dtlb_data(int entry, unsigned long data)
+static inline void spitfire_put_dtlb_data(int entry, unsigned long data)
 {
        __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
                             "membar    #Sync"
@@ -122,7 +121,7 @@ static __inline__ void spitfire_put_dtlb_data(int entry, unsigned long data)
                               "i" (ASI_DTLB_DATA_ACCESS));
 }
 
-static __inline__ unsigned long spitfire_get_itlb_data(int entry)
+static inline unsigned long spitfire_get_itlb_data(int entry)
 {
        unsigned long data;
 
@@ -136,7 +135,7 @@ static __inline__ unsigned long spitfire_get_itlb_data(int entry)
        return data;
 }
 
-static __inline__ unsigned long spitfire_get_itlb_tag(int entry)
+static inline unsigned long spitfire_get_itlb_tag(int entry)
 {
        unsigned long tag;
 
@@ -146,7 +145,7 @@ static __inline__ unsigned long spitfire_get_itlb_tag(int entry)
        return tag;
 }
 
-static __inline__ void spitfire_put_itlb_data(int entry, unsigned long data)
+static inline void spitfire_put_itlb_data(int entry, unsigned long data)
 {
        __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
                             "membar    #Sync"
@@ -155,7 +154,7 @@ static __inline__ void spitfire_put_itlb_data(int entry, unsigned long data)
                               "i" (ASI_ITLB_DATA_ACCESS));
 }
 
-static __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page)
+static inline void spitfire_flush_dtlb_nucleus_page(unsigned long page)
 {
        __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
                             "membar    #Sync"
@@ -163,7 +162,7 @@ static __inline__ void spitfire_flush_dtlb_nucleus_page(unsigned long page)
                             : "r" (page | 0x20), "i" (ASI_DMMU_DEMAP));
 }
 
-static __inline__ void spitfire_flush_itlb_nucleus_page(unsigned long page)
+static inline void spitfire_flush_itlb_nucleus_page(unsigned long page)
 {
        __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
                             "membar    #Sync"
@@ -172,7 +171,7 @@ static __inline__ void spitfire_flush_itlb_nucleus_page(unsigned long page)
 }
 
 /* Cheetah has "all non-locked" tlb flushes. */
-static __inline__ void cheetah_flush_dtlb_all(void)
+static inline void cheetah_flush_dtlb_all(void)
 {
        __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
                             "membar    #Sync"
@@ -180,7 +179,7 @@ static __inline__ void cheetah_flush_dtlb_all(void)
                             : "r" (0x80), "i" (ASI_DMMU_DEMAP));
 }
 
-static __inline__ void cheetah_flush_itlb_all(void)
+static inline void cheetah_flush_itlb_all(void)
 {
        __asm__ __volatile__("stxa      %%g0, [%0] %1\n\t"
                             "membar    #Sync"
@@ -202,7 +201,7 @@ static __inline__ void cheetah_flush_itlb_all(void)
  * ASI_{D,I}TLB_DATA_ACCESS loads, doing the load twice fixes
  * the problem for me. -DaveM
  */
-static __inline__ unsigned long cheetah_get_ldtlb_data(int entry)
+static inline unsigned long cheetah_get_ldtlb_data(int entry)
 {
        unsigned long data;
 
@@ -215,7 +214,7 @@ static __inline__ unsigned long cheetah_get_ldtlb_data(int entry)
        return data;
 }
 
-static __inline__ unsigned long cheetah_get_litlb_data(int entry)
+static inline unsigned long cheetah_get_litlb_data(int entry)
 {
        unsigned long data;
 
@@ -228,7 +227,7 @@ static __inline__ unsigned long cheetah_get_litlb_data(int entry)
        return data;
 }
 
-static __inline__ unsigned long cheetah_get_ldtlb_tag(int entry)
+static inline unsigned long cheetah_get_ldtlb_tag(int entry)
 {
        unsigned long tag;
 
@@ -240,7 +239,7 @@ static __inline__ unsigned long cheetah_get_ldtlb_tag(int entry)
        return tag;
 }
 
-static __inline__ unsigned long cheetah_get_litlb_tag(int entry)
+static inline unsigned long cheetah_get_litlb_tag(int entry)
 {
        unsigned long tag;
 
@@ -252,7 +251,7 @@ static __inline__ unsigned long cheetah_get_litlb_tag(int entry)
        return tag;
 }
 
-static __inline__ void cheetah_put_ldtlb_data(int entry, unsigned long data)
+static inline void cheetah_put_ldtlb_data(int entry, unsigned long data)
 {
        __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
                             "membar    #Sync"
@@ -262,7 +261,7 @@ static __inline__ void cheetah_put_ldtlb_data(int entry, unsigned long data)
                               "i" (ASI_DTLB_DATA_ACCESS));
 }
 
-static __inline__ void cheetah_put_litlb_data(int entry, unsigned long data)
+static inline void cheetah_put_litlb_data(int entry, unsigned long data)
 {
        __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
                             "membar    #Sync"
@@ -272,7 +271,7 @@ static __inline__ void cheetah_put_litlb_data(int entry, unsigned long data)
                               "i" (ASI_ITLB_DATA_ACCESS));
 }
 
-static __inline__ unsigned long cheetah_get_dtlb_data(int entry, int tlb)
+static inline unsigned long cheetah_get_dtlb_data(int entry, int tlb)
 {
        unsigned long data;
 
@@ -284,7 +283,7 @@ static __inline__ unsigned long cheetah_get_dtlb_data(int entry, int tlb)
        return data;
 }
 
-static __inline__ unsigned long cheetah_get_dtlb_tag(int entry, int tlb)
+static inline unsigned long cheetah_get_dtlb_tag(int entry, int tlb)
 {
        unsigned long tag;
 
@@ -294,7 +293,7 @@ static __inline__ unsigned long cheetah_get_dtlb_tag(int entry, int tlb)
        return tag;
 }
 
-static __inline__ void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb)
+static inline void cheetah_put_dtlb_data(int entry, unsigned long data, int tlb)
 {
        __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
                             "membar    #Sync"
@@ -304,7 +303,7 @@ static __inline__ void cheetah_put_dtlb_data(int entry, unsigned long data, int
                               "i" (ASI_DTLB_DATA_ACCESS));
 }
 
-static __inline__ unsigned long cheetah_get_itlb_data(int entry)
+static inline unsigned long cheetah_get_itlb_data(int entry)
 {
        unsigned long data;
 
@@ -317,7 +316,7 @@ static __inline__ unsigned long cheetah_get_itlb_data(int entry)
        return data;
 }
 
-static __inline__ unsigned long cheetah_get_itlb_tag(int entry)
+static inline unsigned long cheetah_get_itlb_tag(int entry)
 {
        unsigned long tag;
 
@@ -327,7 +326,7 @@ static __inline__ unsigned long cheetah_get_itlb_tag(int entry)
        return tag;
 }
 
-static __inline__ void cheetah_put_itlb_data(int entry, unsigned long data)
+static inline void cheetah_put_itlb_data(int entry, unsigned long data)
 {
        __asm__ __volatile__("stxa      %0, [%1] %2\n\t"
                             "membar    #Sync"
index 3f175fa..159e62b 100644 (file)
@@ -1,4 +1,3 @@
-/* $Id: system.h,v 1.69 2002/02/09 19:49:31 davem Exp $ */
 #ifndef __SPARC64_SYSTEM_H
 #define __SPARC64_SYSTEM_H
 
@@ -240,7 +239,7 @@ static inline unsigned long xchg64(__volatile__ unsigned long *m, unsigned long
 
 extern void __xchg_called_with_bad_pointer(void);
 
-static __inline__ unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
+static inline unsigned long __xchg(unsigned long x, __volatile__ void * ptr,
                                       int size)
 {
        switch (size) {
@@ -263,7 +262,7 @@ extern void die_if_kernel(char *str, struct pt_regs *regs) __attribute__ ((noret
 
 #define __HAVE_ARCH_CMPXCHG 1
 
-static __inline__ unsigned long
+static inline unsigned long
 __cmpxchg_u32(volatile int *m, int old, int new)
 {
        __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n"
@@ -276,7 +275,7 @@ __cmpxchg_u32(volatile int *m, int old, int new)
        return new;
 }
 
-static __inline__ unsigned long
+static inline unsigned long
 __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
 {
        __asm__ __volatile__("membar #StoreLoad | #LoadLoad\n"
@@ -293,7 +292,7 @@ __cmpxchg_u64(volatile long *m, unsigned long old, unsigned long new)
    if something tries to do an invalid cmpxchg().  */
 extern void __cmpxchg_called_with_bad_pointer(void);
 
-static __inline__ unsigned long
+static inline unsigned long
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
        switch (size) {
index 7ae09a2..5b16332 100644 (file)
@@ -1,4 +1,3 @@
-/* $Id: upa.h,v 1.3 1999/09/21 14:39:47 davem Exp $ */
 #ifndef _SPARC64_UPA_H
 #define _SPARC64_UPA_H
 
@@ -25,7 +24,7 @@
 
 /* UPA I/O space accessors */
 #if defined(__KERNEL__) && !defined(__ASSEMBLY__)
-static __inline__ unsigned char _upa_readb(unsigned long addr)
+static inline unsigned char _upa_readb(unsigned long addr)
 {
        unsigned char ret;
 
@@ -36,7 +35,7 @@ static __inline__ unsigned char _upa_readb(unsigned long addr)
        return ret;
 }
 
-static __inline__ unsigned short _upa_readw(unsigned long addr)
+static inline unsigned short _upa_readw(unsigned long addr)
 {
        unsigned short ret;
 
@@ -47,7 +46,7 @@ static __inline__ unsigned short _upa_readw(unsigned long addr)
        return ret;
 }
 
-static __inline__ unsigned int _upa_readl(unsigned long addr)
+static inline unsigned int _upa_readl(unsigned long addr)
 {
        unsigned int ret;
 
@@ -58,7 +57,7 @@ static __inline__ unsigned int _upa_readl(unsigned long addr)
        return ret;
 }
 
-static __inline__ unsigned long _upa_readq(unsigned long addr)
+static inline unsigned long _upa_readq(unsigned long addr)
 {
        unsigned long ret;
 
@@ -69,28 +68,28 @@ static __inline__ unsigned long _upa_readq(unsigned long addr)
        return ret;
 }
 
-static __inline__ void _upa_writeb(unsigned char b, unsigned long addr)
+static inline void _upa_writeb(unsigned char b, unsigned long addr)
 {
        __asm__ __volatile__("stba\t%0, [%1] %2\t/* upa_writeb */"
                             : /* no outputs */
                             : "r" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
 }
 
-static __inline__ void _upa_writew(unsigned short w, unsigned long addr)
+static inline void _upa_writew(unsigned short w, unsigned long addr)
 {
        __asm__ __volatile__("stha\t%0, [%1] %2\t/* upa_writew */"
                             : /* no outputs */
                             : "r" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
 }
 
-static __inline__ void _upa_writel(unsigned int l, unsigned long addr)
+static inline void _upa_writel(unsigned int l, unsigned long addr)
 {
        __asm__ __volatile__("stwa\t%0, [%1] %2\t/* upa_writel */"
                             : /* no outputs */
                             : "r" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
 }
 
-static __inline__ void _upa_writeq(unsigned long q, unsigned long addr)
+static inline void _upa_writeq(unsigned long q, unsigned long addr)
 {
        __asm__ __volatile__("stxa\t%0, [%1] %2\t/* upa_writeq */"
                             : /* no outputs */
index a740785..34f2ec6 100644 (file)
@@ -1,4 +1,3 @@
-/* $Id: visasm.h,v 1.5 2001/04/24 01:09:12 davem Exp $ */
 #ifndef _SPARC64_VISASM_H
 #define _SPARC64_VISASM_H
 
@@ -44,7 +43,7 @@
        wr              %o5, 0, %fprs;
 
 #ifndef __ASSEMBLY__   
-static __inline__ void save_and_clear_fpu(void) {
+static inline void save_and_clear_fpu(void) {
        __asm__ __volatile__ (
 "              rd %%fprs, %%o5\n"
 "              andcc %%o5, %0, %%g0\n"
index 732c83f..38bd9d9 100644 (file)
@@ -14,7 +14,6 @@ extern int um_execve(const char *file, char *const argv[], char *const env[]);
 
 #ifdef __KERNEL__
 /* We get __ARCH_WANT_OLD_STAT and __ARCH_WANT_STAT64 from the base arch */
-#define __ARCH_WANT_IPC_PARSE_VERSION
 #define __ARCH_WANT_OLD_READDIR
 #define __ARCH_WANT_SYS_ALARM
 #define __ARCH_WANT_SYS_GETHOSTNAME
index 36ebb5b..0b40f6d 100644 (file)
@@ -183,9 +183,12 @@ static inline int test_and_set_bit(int nr, volatile unsigned long * addr)
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This is the same as test_and_set_bit on x86
+ * This is the same as test_and_set_bit on x86.
  */
-#define test_and_set_bit_lock test_and_set_bit
+static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr)
+{
+       return test_and_set_bit(nr, addr);
+}
 
 /**
  * __test_and_set_bit - Set a bit and return its old value
index b4d4794..766bcc0 100644 (file)
@@ -29,7 +29,7 @@
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-static __inline__ void set_bit(int nr, volatile void * addr)
+static inline void set_bit(int nr, volatile void *addr)
 {
        __asm__ __volatile__( LOCK_PREFIX
                "btsl %1,%0"
@@ -46,7 +46,7 @@ static __inline__ void set_bit(int nr, volatile void * addr)
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-static __inline__ void __set_bit(int nr, volatile void * addr)
+static inline void __set_bit(int nr, volatile void *addr)
 {
        __asm__ volatile(
                "btsl %1,%0"
@@ -64,7 +64,7 @@ static __inline__ void __set_bit(int nr, volatile void * addr)
  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  * in order to ensure changes are visible on other processors.
  */
-static __inline__ void clear_bit(int nr, volatile void * addr)
+static inline void clear_bit(int nr, volatile void *addr)
 {
        __asm__ __volatile__( LOCK_PREFIX
                "btrl %1,%0"
@@ -86,7 +86,7 @@ static inline void clear_bit_unlock(unsigned long nr, volatile unsigned long *ad
        clear_bit(nr, addr);
 }
 
-static __inline__ void __clear_bit(int nr, volatile void * addr)
+static inline void __clear_bit(int nr, volatile void *addr)
 {
        __asm__ __volatile__(
                "btrl %1,%0"
@@ -124,7 +124,7 @@ static inline void __clear_bit_unlock(unsigned long nr, volatile unsigned long *
  * If it's called on the same region of memory simultaneously, the effect
  * may be that only one operation succeeds.
  */
-static __inline__ void __change_bit(int nr, volatile void * addr)
+static inline void __change_bit(int nr, volatile void *addr)
 {
        __asm__ __volatile__(
                "btcl %1,%0"
@@ -141,7 +141,7 @@ static __inline__ void __change_bit(int nr, volatile void * addr)
  * Note that @nr may be almost arbitrarily large; this function is not
  * restricted to acting on a single-word quantity.
  */
-static __inline__ void change_bit(int nr, volatile void * addr)
+static inline void change_bit(int nr, volatile void *addr)
 {
        __asm__ __volatile__( LOCK_PREFIX
                "btcl %1,%0"
@@ -157,7 +157,7 @@ static __inline__ void change_bit(int nr, volatile void * addr)
  * This operation is atomic and cannot be reordered.  
  * It also implies a memory barrier.
  */
-static __inline__ int test_and_set_bit(int nr, volatile void * addr)
+static inline int test_and_set_bit(int nr, volatile void *addr)
 {
        int oldbit;
 
@@ -173,9 +173,12 @@ static __inline__ int test_and_set_bit(int nr, volatile void * addr)
  * @nr: Bit to set
  * @addr: Address to count from
  *
- * This is the same as test_and_set_bit on x86
+ * This is the same as test_and_set_bit on x86.
  */
-#define test_and_set_bit_lock test_and_set_bit
+static inline int test_and_set_bit_lock(int nr, volatile void *addr)
+{
+       return test_and_set_bit(nr, addr);
+}
 
 /**
  * __test_and_set_bit - Set a bit and return its old value
@@ -186,7 +189,7 @@ static __inline__ int test_and_set_bit(int nr, volatile void * addr)
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
+static inline int __test_and_set_bit(int nr, volatile void *addr)
 {
        int oldbit;
 
@@ -205,7 +208,7 @@ static __inline__ int __test_and_set_bit(int nr, volatile void * addr)
  * This operation is atomic and cannot be reordered.  
  * It also implies a memory barrier.
  */
-static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+static inline int test_and_clear_bit(int nr, volatile void *addr)
 {
        int oldbit;
 
@@ -225,7 +228,7 @@ static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
  * If two examples of this operation race, one can appear to succeed
  * but actually fail.  You must protect multiple accesses with a lock.
  */
-static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
+static inline int __test_and_clear_bit(int nr, volatile void *addr)
 {
        int oldbit;
 
@@ -237,7 +240,7 @@ static __inline__ int __test_and_clear_bit(int nr, volatile void * addr)
 }
 
 /* WARNING: non atomic and it can be reordered! */
-static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
+static inline int __test_and_change_bit(int nr, volatile void *addr)
 {
        int oldbit;
 
@@ -256,7 +259,7 @@ static __inline__ int __test_and_change_bit(int nr, volatile void * addr)
  * This operation is atomic and cannot be reordered.  
  * It also implies a memory barrier.
  */
-static __inline__ int test_and_change_bit(int nr, volatile void * addr)
+static inline int test_and_change_bit(int nr, volatile void *addr)
 {
        int oldbit;
 
@@ -273,15 +276,15 @@ static __inline__ int test_and_change_bit(int nr, volatile void * addr)
  * @nr: bit number to test
  * @addr: Address to start counting from
  */
-static int test_bit(int nr, const volatile void * addr);
+static int test_bit(int nr, const volatile void *addr);
 #endif
 
-static __inline__ int constant_test_bit(int nr, const volatile void * addr)
+static inline int constant_test_bit(int nr, const volatile void *addr)
 {
        return ((1UL << (nr & 31)) & (((const volatile unsigned int *) addr)[nr >> 5])) != 0;
 }
 
-static __inline__ int variable_test_bit(int nr, volatile const void * addr)
+static inline int variable_test_bit(int nr, volatile const void *addr)
 {
        int oldbit;
 
@@ -299,10 +302,10 @@ static __inline__ int variable_test_bit(int nr, volatile const void * addr)
 
 #undef ADDR
 
-extern long find_first_zero_bit(const unsigned long * addr, unsigned long size);
-extern long find_next_zero_bit (const unsigned long * addr, long size, long offset);
-extern long find_first_bit(const unsigned long * addr, unsigned long size);
-extern long find_next_bit(const unsigned long * addr, long size, long offset);
+extern long find_first_zero_bit(const unsigned long *addr, unsigned long size);
+extern long find_next_zero_bit(const unsigned long *addr, long size, long offset);
+extern long find_first_bit(const unsigned long *addr, unsigned long size);
+extern long find_next_bit(const unsigned long *addr, long size, long offset);
 
 /* return index of first bet set in val or max when no bit is set */
 static inline long __scanbit(unsigned long val, unsigned long max)
@@ -363,7 +366,7 @@ static inline void __clear_bit_string(unsigned long *bitmap, unsigned long i,
  *
  * Undefined if no zero exists, so code should check against ~0UL first.
  */
-static __inline__ unsigned long ffz(unsigned long word)
+static inline unsigned long ffz(unsigned long word)
 {
        __asm__("bsfq %1,%0"
                :"=r" (word)
@@ -377,7 +380,7 @@ static __inline__ unsigned long ffz(unsigned long word)
  *
  * Undefined if no bit exists, so code should check against 0 first.
  */
-static __inline__ unsigned long __ffs(unsigned long word)
+static inline unsigned long __ffs(unsigned long word)
 {
        __asm__("bsfq %1,%0"
                :"=r" (word)
@@ -391,7 +394,7 @@ static __inline__ unsigned long __ffs(unsigned long word)
  *
  * Undefined if no zero exists, so code should check against ~0UL first.
  */
-static __inline__ unsigned long __fls(unsigned long word)
+static inline unsigned long __fls(unsigned long word)
 {
        __asm__("bsrq %1,%0"
                :"=r" (word)
@@ -411,7 +414,7 @@ static __inline__ unsigned long __fls(unsigned long word)
  * the libc and compiler builtin ffs routines, therefore
  * differs in spirit from the above ffz (man ffs).
  */
-static __inline__ int ffs(int x)
+static inline int ffs(int x)
 {
        int r;
 
@@ -427,7 +430,7 @@ static __inline__ int ffs(int x)
  *
  * This is defined the same way as fls.
  */
-static __inline__ int fls64(__u64 x)
+static inline int fls64(__u64 x)
 {
        if (x == 0)
                return 0;
@@ -440,7 +443,7 @@ static __inline__ int fls64(__u64 x)
  *
  * This is defined the same way as ffs.
  */
-static __inline__ int fls(int x)
+static inline int fls(int x)
 {
        int r;
 
index f948491..9c5092b 100644 (file)
 #define LHCALL_LOAD_TLS                16
 #define LHCALL_NOTIFY          17
 
+#define LGUEST_TRAP_ENTRY 0x1F
+
+#ifndef __ASSEMBLY__
+#include <asm/hw_irq.h>
+
 /*G:031 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.
  *
  * Our hypercall mechanism uses the highest unused trap code (traps 32 and
- * above are used by real hardware interrupts).  Seventeen hypercalls are
+ * above are used by real hardware interrupts).  Fifteen hypercalls are
  * available: the hypercall number is put in the %eax register, and the
  * arguments (when required) are placed in %edx, %ebx and %ecx.  If a return
  * value makes sense, it's returned in %eax.
  * Grossly invalid calls result in Sudden Death at the hands of the vengeful
  * Host, rather than returning failure.  This reflects Winston Churchill's
  * definition of a gentleman: "someone who is only rude intentionally". */
-#define LGUEST_TRAP_ENTRY 0x1F
-
-#ifndef __ASSEMBLY__
-#include <asm/hw_irq.h>
-
 static inline unsigned long
 hcall(unsigned long call,
       unsigned long arg1, unsigned long arg2, unsigned long arg3)
 {
        /* "int" is the Intel instruction to trigger a trap. */
        asm volatile("int $" __stringify(LGUEST_TRAP_ENTRY)
-                      /* The call is in %eax (aka "a"), and can be replaced */
+                      /* The call in %eax (aka "a") might be overwritten */
                     : "=a"(call)
-                      /* The other arguments are in %eax, %edx, %ebx & %ecx */
+                      /* The arguments are in %eax, %edx, %ebx & %ecx */
                     : "a"(call), "d"(arg1), "b"(arg2), "c"(arg3)
                       /* "memory" means this might write somewhere in memory.
                        * This isn't true for all calls, but it's safe to tell
index 7056d86..e10b7af 100644 (file)
@@ -94,9 +94,12 @@ static inline void smp_send_reschedule(int cpu)
 {
        smp_ops.smp_send_reschedule(cpu);
 }
-extern int smp_call_function_mask(cpumask_t mask,
-                                 void (*func) (void *info), void *info,
-                                 int wait);
+static inline int smp_call_function_mask(cpumask_t mask,
+                                        void (*func) (void *info), void *info,
+                                        int wait)
+{
+       return smp_ops.smp_call_function_mask(mask, func, info, wait);
+}
 
 void native_smp_prepare_boot_cpu(void);
 void native_smp_prepare_cpus(unsigned int max_cpus);
index 8bd9d2c..3c7d537 100644 (file)
 #ifndef _XTENSA_DMA_MAPPING_H
 #define _XTENSA_DMA_MAPPING_H
 
-#include <asm/scatterlist.h>
 #include <asm/cache.h>
 #include <asm/io.h>
 #include <linux/mm.h>
+#include <linux/scatterlist.h>
 
 /*
  * DMA-consistent mapping functions.
index 8263a7b..128dc7a 100644 (file)
@@ -180,6 +180,7 @@ enum {
        ATA_CMD_VERIFY_EXT      = 0x42,
        ATA_CMD_STANDBYNOW1     = 0xE0,
        ATA_CMD_IDLEIMMEDIATE   = 0xE1,
+       ATA_CMD_SLEEP           = 0xE6,
        ATA_CMD_INIT_DEV_PARAMS = 0x91,
        ATA_CMD_READ_NATIVE_MAX = 0xF8,
        ATA_CMD_READ_NATIVE_MAX_EXT = 0x27,
@@ -235,6 +236,7 @@ enum {
 
        /* SETFEATURE Sector counts for SATA features */
        SATA_AN                 = 0x05,  /* Asynchronous Notification */
+       SATA_DIPM               = 0x03,  /* Device Initiated Power Management */
 
        /* ATAPI stuff */
        ATAPI_PKT_DMA           = (1 << 0),
@@ -377,6 +379,26 @@ struct ata_taskfile {
 
 #define ata_id_cdb_intr(id)    (((id)[0] & 0x60) == 0x20)
 
+static inline bool ata_id_has_hipm(const u16 *id)
+{
+       u16 val = id[76];
+
+       if (val == 0 || val == 0xffff)
+               return false;
+
+       return val & (1 << 9);
+}
+
+static inline bool ata_id_has_dipm(const u16 *id)
+{
+       u16 val = id[78];
+
+       if (val == 0 || val == 0xffff)
+               return false;
+
+       return val & (1 << 3);
+}
+
 static inline int ata_id_has_fua(const u16 *id)
 {
        if ((id[84] & 0xC000) != 0x4000)
index bbf906a..8396db2 100644 (file)
@@ -341,7 +341,6 @@ enum blk_queue_state {
 struct blk_queue_tag {
        struct request **tag_index;     /* map of busy tags */
        unsigned long *tag_map;         /* bit map of free/busy tags */
-       struct list_head busy_list;     /* fifo list of busy tags */
        int busy;                       /* current depth */
        int max_depth;                  /* what we will send to device */
        int real_max_depth;             /* what the array can hold */
@@ -435,6 +434,7 @@ struct request_queue
        unsigned int            dma_alignment;
 
        struct blk_queue_tag    *queue_tags;
+       struct list_head        tag_busy_list;
 
        unsigned int            nr_sorted;
        unsigned int            in_flight;
index c83534e..0365ec9 100644 (file)
@@ -59,7 +59,6 @@ extern void *__alloc_bootmem_core(struct bootmem_data *bdata,
                                  unsigned long align,
                                  unsigned long goal,
                                  unsigned long limit);
-extern void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size);
 
 #ifndef CONFIG_HAVE_ARCH_BOOTMEM_NODE
 extern void reserve_bootmem(unsigned long addr, unsigned long size);
index c811c8b..c68b67b 100644 (file)
@@ -101,6 +101,12 @@ extern void __chk_io_ptr(const volatile void __iomem *);
 #undef __must_check
 #define __must_check
 #endif
+#ifndef CONFIG_ENABLE_WARN_DEPRECATED
+#undef __deprecated
+#undef __deprecated_for_modules
+#define __deprecated
+#define __deprecated_for_modules
+#endif
 
 /*
  * Allow us to avoid 'defined but not used' warnings on functions and data,
index 268c5a4..33d6aaf 100644 (file)
@@ -42,15 +42,15 @@ static inline void init_completion(struct completion *x)
        init_waitqueue_head(&x->wait);
 }
 
-extern void FASTCALL(wait_for_completion(struct completion *));
-extern int FASTCALL(wait_for_completion_interruptible(struct completion *x));
-extern unsigned long FASTCALL(wait_for_completion_timeout(struct completion *x,
-                                                  unsigned long timeout));
-extern unsigned long FASTCALL(wait_for_completion_interruptible_timeout(
-                       struct completion *x, unsigned long timeout));
-
-extern void FASTCALL(complete(struct completion *));
-extern void FASTCALL(complete_all(struct completion *));
+extern void wait_for_completion(struct completion *);
+extern int wait_for_completion_interruptible(struct completion *x);
+extern unsigned long wait_for_completion_timeout(struct completion *x,
+                                                  unsigned long timeout);
+extern unsigned long wait_for_completion_interruptible_timeout(
+                       struct completion *x, unsigned long timeout);
+
+extern void complete(struct completion *);
+extern void complete_all(struct completion *);
 
 #define INIT_COMPLETION(x)     ((x).done = 0)
 
index f3fc439..333c3ea 100644 (file)
@@ -144,6 +144,8 @@ enum dccp_reset_codes {
        DCCP_RESET_CODE_TOO_BUSY,
        DCCP_RESET_CODE_BAD_INIT_COOKIE,
        DCCP_RESET_CODE_AGGRESSION_PENALTY,
+
+       DCCP_MAX_RESET_CODES            /* Leave at the end!  */
 };
 
 /* DCCP options */
@@ -270,10 +272,9 @@ static inline struct dccp_hdr *dccp_zeroed_hdr(struct sk_buff *skb, int headlen)
        return memset(skb_transport_header(skb), 0, headlen);
 }
 
-static inline struct dccp_hdr_ext *dccp_hdrx(const struct sk_buff *skb)
+static inline struct dccp_hdr_ext *dccp_hdrx(const struct dccp_hdr *dh)
 {
-       return (struct dccp_hdr_ext *)(skb_transport_header(skb) +
-                                      sizeof(struct dccp_hdr));
+       return (struct dccp_hdr_ext *)((unsigned char *)dh + sizeof(*dh));
 }
 
 static inline unsigned int __dccp_basic_hdr_len(const struct dccp_hdr *dh)
@@ -287,13 +288,12 @@ static inline unsigned int dccp_basic_hdr_len(const struct sk_buff *skb)
        return __dccp_basic_hdr_len(dh);
 }
 
-static inline __u64 dccp_hdr_seq(const struct sk_buff *skb)
+static inline __u64 dccp_hdr_seq(const struct dccp_hdr *dh)
 {
-       const struct dccp_hdr *dh = dccp_hdr(skb);
        __u64 seq_nr =  ntohs(dh->dccph_seq);
 
        if (dh->dccph_x != 0)
-               seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(skb)->dccph_seq_low);
+               seq_nr = (seq_nr << 32) + ntohl(dccp_hdrx(dh)->dccph_seq_low);
        else
                seq_nr += (u32)dh->dccph_seq2 << 16;
 
index d2a96cb..cf79853 100644 (file)
  * On x86-64 make the 64bit structure have the same alignment as the
  * 32bit structure. This makes 32bit emulation easier.
  *
- * UML/x86_64 needs the same packing as x86_64 - UML + UML_X86 +
- * 64_BIT adds up to UML/x86_64.
+ * UML/x86_64 needs the same packing as x86_64
  */
 #ifdef __x86_64__
 #define EPOLL_PACKED __attribute__((packed))
 #else
-#if defined(CONFIG_UML) && defined(CONFIG_UML_X86) && defined(CONFIG_64BIT)
-#define EPOLL_PACKED __attribute__((packed))
-#else
 #define EPOLL_PACKED
 #endif
-#endif
 
 struct epoll_event {
        __u32 events;
index 8beb291..175e63f 100644 (file)
@@ -12,8 +12,8 @@
 #define LG_CLOCK_MAX_DELTA     ULONG_MAX
 
 /*G:032 The second method of communicating with the Host is to via "struct
- * lguest_data".  The Guest's very first hypercall is to tell the Host where
- * this is, and then the Guest and Host both publish information in it. :*/
+ * lguest_data".  Once the Guest's initialization hypercall tells the Host where
+ * this is, the Guest and Host both publish information in it. :*/
 struct lguest_data
 {
        /* 512 == enabled (same as eflags in normal hardware).  The Guest
index 61e1e3e..697104d 100644 (file)
@@ -1,17 +1,7 @@
-#ifndef _ASM_LGUEST_USER
-#define _ASM_LGUEST_USER
+#ifndef _LINUX_LGUEST_LAUNCHER
+#define _LINUX_LGUEST_LAUNCHER
 /* Everything the "lguest" userspace program needs to know. */
 #include <linux/types.h>
-/* They can register up to 32 arrays of lguest_dma. */
-#define LGUEST_MAX_DMA         32
-/* At most we can dma 16 lguest_dma in one op. */
-#define LGUEST_MAX_DMA_SECTIONS        16
-
-/* How many devices?  Assume each one wants up to two dma arrays per device. */
-#define LGUEST_MAX_DEVICES (LGUEST_MAX_DMA/2)
-
-/* Where the Host expects the Guest to SEND_DMA console output to. */
-#define LGUEST_CONSOLE_DMA_KEY 0
 
 /*D:010
  * Drivers
  * real devices (think of the damage it could do!) we provide virtual devices.
  * We could emulate a PCI bus with various devices on it, but that is a fairly
  * complex burden for the Host and suboptimal for the Guest, so we have our own
- * "lguest" bus and simple drivers.
+ * simple lguest bus and we use "virtio" drivers.  These drivers need a set of
+ * routines from us which will actually do the virtual I/O, but they handle all
+ * the net/block/console stuff themselves.  This means that if we want to add
+ * 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.
  *
  * 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
@@ -51,9 +45,9 @@ struct lguest_vqconfig {
 /* Write command first word is a request. */
 enum lguest_req
 {
-       LHREQ_INITIALIZE, /* + pfnlimit, pgdir, start, pageoffset */
+       LHREQ_INITIALIZE, /* + base, pfnlimit, pgdir, start */
        LHREQ_GETDMA, /* No longer used */
        LHREQ_IRQ, /* + irq */
        LHREQ_BREAK, /* + on/off flag (on blocks until someone does off) */
 };
-#endif /* _ASM_LGUEST_USER */
+#endif /* _LINUX_LGUEST_LAUNCHER */
index 6fd24e0..147ccc4 100644 (file)
@@ -133,11 +133,14 @@ enum {
        ATA_DFLAG_ACPI_PENDING  = (1 << 5), /* ACPI resume action pending */
        ATA_DFLAG_ACPI_FAILED   = (1 << 6), /* ACPI on devcfg has failed */
        ATA_DFLAG_AN            = (1 << 7), /* AN configured */
+       ATA_DFLAG_HIPM          = (1 << 8), /* device supports HIPM */
+       ATA_DFLAG_DIPM          = (1 << 9), /* device supports DIPM */
        ATA_DFLAG_CFG_MASK      = (1 << 12) - 1,
 
        ATA_DFLAG_PIO           = (1 << 12), /* device limited to PIO mode */
        ATA_DFLAG_NCQ_OFF       = (1 << 13), /* device limited to non-NCQ mode */
        ATA_DFLAG_SPUNDOWN      = (1 << 14), /* XXX: for spindown_compat */
+       ATA_DFLAG_SLEEPING      = (1 << 15), /* device is sleeping */
        ATA_DFLAG_INIT_MASK     = (1 << 16) - 1,
 
        ATA_DFLAG_DETACH        = (1 << 16),
@@ -185,6 +188,7 @@ enum {
        ATA_FLAG_ACPI_SATA      = (1 << 17), /* need native SATA ACPI layout */
        ATA_FLAG_AN             = (1 << 18), /* controller supports AN */
        ATA_FLAG_PMP            = (1 << 19), /* controller supports PMP */
+       ATA_FLAG_IPM            = (1 << 20), /* driver can handle IPM */
 
        /* The following flag belongs to ap->pflags but is kept in
         * ap->flags because it's referenced in many LLDs and will be
@@ -234,6 +238,13 @@ enum {
        ATA_TMOUT_INTERNAL      = 30 * HZ,
        ATA_TMOUT_INTERNAL_QUICK = 5 * HZ,
 
+       /* FIXME: GoVault needs 2s but we can't afford that without
+        * parallel probing.  800ms is enough for iVDR disk
+        * HHD424020F7SV00.  Increase to 2secs when parallel probing
+        * is in place.
+        */
+       ATA_TMOUT_FF_WAIT       = 4 * HZ / 5,
+
        /* ATA bus states */
        BUS_UNKNOWN             = 0,
        BUS_DMA                 = 1,
@@ -294,6 +305,7 @@ enum {
        ATA_EHI_RESUME_LINK     = (1 << 1),  /* resume link (reset modifier) */
        ATA_EHI_NO_AUTOPSY      = (1 << 2),  /* no autopsy */
        ATA_EHI_QUIET           = (1 << 3),  /* be quiet */
+       ATA_EHI_LPM             = (1 << 4),  /* link power management action */
 
        ATA_EHI_DID_SOFTRESET   = (1 << 16), /* already soft-reset this port */
        ATA_EHI_DID_HARDRESET   = (1 << 17), /* already soft-reset this port */
@@ -325,6 +337,7 @@ enum {
        ATA_HORKAGE_BROKEN_HPA  = (1 << 4),     /* Broken HPA */
        ATA_HORKAGE_SKIP_PM     = (1 << 5),     /* Skip PM operations */
        ATA_HORKAGE_HPA_SIZE    = (1 << 6),     /* native size off by one */
+       ATA_HORKAGE_IPM         = (1 << 7),     /* Link PM problems */
 
         /* DMA mask for user DMA control: User visible values; DO NOT
            renumber */
@@ -370,6 +383,18 @@ typedef int (*ata_reset_fn_t)(struct ata_link *link, unsigned int *classes,
                              unsigned long deadline);
 typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes);
 
+/*
+ * host pm policy: If you alter this, you also need to alter libata-scsi.c
+ * (for the ascii descriptions)
+ */
+enum link_pm {
+       NOT_AVAILABLE,
+       MIN_POWER,
+       MAX_PERFORMANCE,
+       MEDIUM_POWER,
+};
+extern struct class_device_attribute class_device_attr_link_power_management_policy;
+
 struct ata_ioports {
        void __iomem            *cmd_addr;
        void __iomem            *data_addr;
@@ -616,6 +641,7 @@ struct ata_port {
 
        pm_message_t            pm_mesg;
        int                     *pm_result;
+       enum link_pm            pm_policy;
 
        struct timer_list       fastdrain_timer;
        unsigned long           fastdrain_cnt;
@@ -683,7 +709,8 @@ struct ata_port_operations {
 
        int (*port_suspend) (struct ata_port *ap, pm_message_t mesg);
        int (*port_resume) (struct ata_port *ap);
-
+       int (*enable_pm) (struct ata_port *ap, enum link_pm policy);
+       void (*disable_pm) (struct ata_port *ap);
        int (*port_start) (struct ata_port *ap);
        void (*port_stop) (struct ata_port *ap);
 
@@ -799,6 +826,7 @@ extern void ata_host_resume(struct ata_host *host);
 extern int ata_ratelimit(void);
 extern int ata_busy_sleep(struct ata_port *ap,
                          unsigned long timeout_pat, unsigned long timeout);
+extern void ata_wait_after_reset(struct ata_port *ap, unsigned long deadline);
 extern int ata_wait_ready(struct ata_port *ap, unsigned long deadline);
 extern void ata_port_queue_task(struct ata_port *ap, work_func_t fn,
                                void *data, unsigned long delay);
index 3f27239..8df230a 100644 (file)
@@ -8,6 +8,9 @@
 #define MV643XX_ETH_NAME               "mv643xx_eth"
 #define MV643XX_ETH_SHARED_REGS                0x2000
 #define MV643XX_ETH_SHARED_REGS_SIZE   0x2000
+#define MV643XX_ETH_BAR_4      0x220
+#define MV643XX_ETH_SIZE_REG_4 0x224
+#define MV643XX_ETH_BASE_ADDR_ENABLE_REG       0x0290
 
 struct mv643xx_eth_platform_data {
        int             port_number;
index c4de536..9b0c8f1 100644 (file)
@@ -390,7 +390,7 @@ static inline void napi_complete(struct napi_struct *n)
 static inline void napi_disable(struct napi_struct *n)
 {
        while (test_and_set_bit(NAPI_STATE_SCHED, &n->state))
-               msleep_interruptible(1);
+               msleep(1);
 }
 
 /**
@@ -669,6 +669,8 @@ struct net_device
 #define HAVE_SET_MAC_ADDR               
        int                     (*set_mac_address)(struct net_device *dev,
                                                   void *addr);
+#define HAVE_VALIDATE_ADDR
+       int                     (*validate_addr)(struct net_device *dev);
 #define HAVE_PRIVATE_IOCTL
        int                     (*do_ioctl)(struct net_device *dev,
                                            struct ifreq *ifr, int cmd);
index 4e10a07..e44aac8 100644 (file)
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE       0x0560
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP73_IDE       0x056C
 #define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP77_IDE       0x0759
+#define PCI_DEVICE_ID_NVIDIA_NVENET_32              0x0760
+#define PCI_DEVICE_ID_NVIDIA_NVENET_33              0x0761
+#define PCI_DEVICE_ID_NVIDIA_NVENET_34              0x0762
+#define PCI_DEVICE_ID_NVIDIA_NVENET_35              0x0763
 
 #define PCI_VENDOR_ID_IMS              0x10e0
 #define PCI_DEVICE_ID_IMS_TT128                0x9128
index df7ddce..32326c2 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef _LINUX_SCATTERLIST_H
 #define _LINUX_SCATTERLIST_H
 
+#include <asm/types.h>
 #include <asm/scatterlist.h>
 #include <linux/mm.h>
 #include <linux/string.h>
 #define SG_MAGIC       0x87654321
 
 /**
- * sg_set_page - Set sg entry to point at given page
- * @sg:                 SG entry
- * @page:       The page
+ * sg_assign_page - Assign a given page to an SG entry
+ * @sg:                    SG entry
+ * @page:          The page
  *
  * Description:
- *   Use this function to set an sg entry pointing at a page, never assign
- *   the page directly. We encode sg table information in the lower bits
- *   of the page pointer. See sg_page() for looking up the page belonging
- *   to an sg entry.
+ *   Assign page to sg entry. Also see sg_set_page(), the most commonly used
+ *   variant.
  *
  **/
-static inline void sg_set_page(struct scatterlist *sg, struct page *page)
+static inline void sg_assign_page(struct scatterlist *sg, struct page *page)
 {
        unsigned long page_link = sg->page_link & 0x3;
 
@@ -52,6 +51,28 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page)
        sg->page_link = page_link | (unsigned long) page;
 }
 
+/**
+ * sg_set_page - Set sg entry to point at given page
+ * @sg:                 SG entry
+ * @page:       The page
+ * @len:        Length of data
+ * @offset:     Offset into page
+ *
+ * Description:
+ *   Use this function to set an sg entry pointing at a page, never assign
+ *   the page directly. We encode sg table information in the lower bits
+ *   of the page pointer. See sg_page() for looking up the page belonging
+ *   to an sg entry.
+ *
+ **/
+static inline void sg_set_page(struct scatterlist *sg, struct page *page,
+                              unsigned int len, unsigned int offset)
+{
+       sg_assign_page(sg, page);
+       sg->offset = offset;
+       sg->length = len;
+}
+
 #define sg_page(sg)    ((struct page *) ((sg)->page_link & ~0x3))
 
 /**
@@ -64,9 +85,7 @@ static inline void sg_set_page(struct scatterlist *sg, struct page *page)
 static inline void sg_set_buf(struct scatterlist *sg, const void *buf,
                              unsigned int buflen)
 {
-       sg_set_page(sg, virt_to_page(buf));
-       sg->offset = offset_in_page(buf);
-       sg->length = buflen;
+       sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
 }
 
 /*
@@ -131,7 +150,7 @@ static inline struct scatterlist *sg_last(struct scatterlist *sgl,
        struct scatterlist *ret = &sgl[nents - 1];
 #else
        struct scatterlist *sg, *ret = NULL;
-       int i;
+       unsigned int i;
 
        for_each_sg(sgl, sg, nents, i)
                ret = sg;
@@ -160,7 +179,11 @@ static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
 #ifndef ARCH_HAS_SG_CHAIN
        BUG();
 #endif
-       prv[prv_nents - 1].page_link = (unsigned long) sgl | 0x01;
+       /*
+        * Set lowest bit to indicate a link pointer, and make sure to clear
+        * the termination bit if it happens to be set.
+        */
+       prv[prv_nents - 1].page_link = ((unsigned long) sgl | 0x01) & ~0x02;
 }
 
 /**
@@ -220,7 +243,7 @@ static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
        sg_mark_end(sgl, nents);
 #ifdef CONFIG_DEBUG_SG
        {
-               int i;
+               unsigned int i;
                for (i = 0; i < nents; i++)
                        sgl[i].sg_magic = SG_MAGIC;
        }
@@ -237,7 +260,7 @@ static inline void sg_init_table(struct scatterlist *sgl, unsigned int nents)
  *   on the sg page.
  *
  **/
-static inline unsigned long sg_phys(struct scatterlist *sg)
+static inline dma_addr_t sg_phys(struct scatterlist *sg)
 {
        return page_to_phys(sg_page(sg)) + sg->offset;
 }
index 13df99f..3c07d59 100644 (file)
@@ -828,12 +828,17 @@ struct sched_class {
        struct task_struct * (*pick_next_task) (struct rq *rq);
        void (*put_prev_task) (struct rq *rq, struct task_struct *p);
 
+#ifdef CONFIG_SMP
        unsigned long (*load_balance) (struct rq *this_rq, int this_cpu,
-                       struct rq *busiest,
-                       unsigned long max_nr_move, unsigned long max_load_move,
+                       struct rq *busiest, unsigned long max_load_move,
                        struct sched_domain *sd, enum cpu_idle_type idle,
                        int *all_pinned, int *this_best_prio);
 
+       int (*move_one_task) (struct rq *this_rq, int this_cpu,
+                             struct rq *busiest, struct sched_domain *sd,
+                             enum cpu_idle_type idle);
+#endif
+
        void (*set_curr_task) (struct rq *rq);
        void (*task_tick) (struct rq *rq, struct task_struct *p);
        void (*task_new) (struct rq *rq, struct task_struct *p);
index fd4e12f..94e4991 100644 (file)
@@ -994,7 +994,7 @@ static inline int pskb_may_pull(struct sk_buff *skb, unsigned int len)
  *
  *     Return the number of bytes of free space at the head of an &sk_buff.
  */
-static inline int skb_headroom(const struct sk_buff *skb)
+static inline unsigned int skb_headroom(const struct sk_buff *skb)
 {
        return skb->data - skb->head;
 }
@@ -1347,7 +1347,7 @@ static inline struct sk_buff *netdev_alloc_skb(struct net_device *dev,
  *     Returns true if modifying the header part of the cloned buffer
  *     does not requires the data to be copied.
  */
-static inline int skb_clone_writable(struct sk_buff *skb, int len)
+static inline int skb_clone_writable(struct sk_buff *skb, unsigned int len)
 {
        return !skb_header_cloned(skb) &&
               skb_headroom(skb) + len <= skb->hdr_len;
index 0013a0d..87b895d 100644 (file)
 #define _LINUX_SUNRPC_RPC_RDMA_H
 
 struct rpcrdma_segment {
-       uint32_t rs_handle;     /* Registered memory handle */
-       uint32_t rs_length;     /* Length of the chunk in bytes */
-       uint64_t rs_offset;     /* Chunk virtual address or offset */
+       __be32 rs_handle;       /* Registered memory handle */
+       __be32 rs_length;       /* Length of the chunk in bytes */
+       __be64 rs_offset;       /* Chunk virtual address or offset */
 };
 
 /*
  * read chunk(s), encoded as a linked list.
  */
 struct rpcrdma_read_chunk {
-       uint32_t rc_discrim;    /* 1 indicates presence */
-       uint32_t rc_position;   /* Position in XDR stream */
+       __be32 rc_discrim;      /* 1 indicates presence */
+       __be32 rc_position;     /* Position in XDR stream */
        struct rpcrdma_segment rc_target;
 };
 
@@ -66,29 +66,29 @@ struct rpcrdma_write_chunk {
  * write chunk(s), encoded as a counted array.
  */
 struct rpcrdma_write_array {
-       uint32_t wc_discrim;    /* 1 indicates presence */
-       uint32_t wc_nchunks;    /* Array count */
+       __be32 wc_discrim;      /* 1 indicates presence */
+       __be32 wc_nchunks;      /* Array count */
        struct rpcrdma_write_chunk wc_array[0];
 };
 
 struct rpcrdma_msg {
-       uint32_t rm_xid;        /* Mirrors the RPC header xid */
-       uint32_t rm_vers;       /* Version of this protocol */
-       uint32_t rm_credit;     /* Buffers requested/granted */
-       uint32_t rm_type;       /* Type of message (enum rpcrdma_proc) */
+       __be32 rm_xid;  /* Mirrors the RPC header xid */
+       __be32 rm_vers; /* Version of this protocol */
+       __be32 rm_credit;       /* Buffers requested/granted */
+       __be32 rm_type; /* Type of message (enum rpcrdma_proc) */
        union {
 
                struct {                        /* no chunks */
-                       uint32_t rm_empty[3];   /* 3 empty chunk lists */
+                       __be32 rm_empty[3];     /* 3 empty chunk lists */
                } rm_nochunks;
 
                struct {                        /* no chunks and padded */
-                       uint32_t rm_align;      /* Padding alignment */
-                       uint32_t rm_thresh;     /* Padding threshold */
-                       uint32_t rm_pempty[3];  /* 3 empty chunk lists */
+                       __be32 rm_align;        /* Padding alignment */
+                       __be32 rm_thresh;       /* Padding threshold */
+                       __be32 rm_pempty[3];    /* 3 empty chunk lists */
                } rm_padded;
 
-               uint32_t rm_chunks[0];  /* read, write and reply chunks */
+               __be32 rm_chunks[0];    /* read, write and reply chunks */
 
        } rm_body;
 };
index 4f0dad2..f4f8d19 100644 (file)
@@ -37,6 +37,8 @@ typedef __kernel_gid32_t      gid_t;
 typedef __kernel_uid16_t        uid16_t;
 typedef __kernel_gid16_t        gid16_t;
 
+typedef unsigned long          uintptr_t;
+
 #ifdef CONFIG_UID16
 /* This is defined by include/asm-{arch}/posix_types.h */
 typedef __kernel_old_uid_t     old_uid_t;
index 8228b57..4427dcd 100644 (file)
@@ -26,7 +26,6 @@
 
 #include <net/inet_connection_sock.h>
 #include <net/inet_sock.h>
-#include <net/route.h>
 #include <net/sock.h>
 #include <net/tcp_states.h>
 
@@ -266,11 +265,6 @@ out:
                wake_up(&hashinfo->lhash_wait);
 }
 
-static inline int inet_iif(const struct sk_buff *skb)
-{
-       return ((struct rtable *)skb->dst)->rt_iif;
-}
-
 extern struct sock *__inet_lookup_listener(struct inet_hashinfo *hashinfo,
                                           const __be32 daddr,
                                           const unsigned short hnum,
index 62daf21..70013c5 100644 (file)
@@ -24,6 +24,7 @@
 #include <net/flow.h>
 #include <net/sock.h>
 #include <net/request_sock.h>
+#include <net/route.h>
 
 /** struct ip_options - IP Options
  *
@@ -190,4 +191,10 @@ static inline int inet_sk_ehashfn(const struct sock *sk)
        return inet_ehashfn(laddr, lport, faddr, fport);
 }
 
+
+static inline int inet_iif(const struct sk_buff *skb)
+{
+       return ((struct rtable *)skb->dst)->rt_iif;
+}
+
 #endif /* _INET_SOCK_H */
index 8dabdd6..eea2e61 100644 (file)
@@ -127,7 +127,6 @@ extern int ircomm_tty_ioctl(struct tty_struct *tty, struct file *file,
                            unsigned int cmd, unsigned long arg);
 extern void ircomm_tty_set_termios(struct tty_struct *tty, 
                                   struct ktermios *old_termios);
-extern hashbin_t *ircomm_tty;
 
 #endif
 
index 93aa87d..5279466 100644 (file)
@@ -102,11 +102,9 @@ static inline void release_net(struct net *net)
 #ifdef CONFIG_NET_NS
 #define __net_init
 #define __net_exit
-#define __net_initdata
 #else
 #define __net_init     __init
 #define __net_exit     __exit_refok
-#define __net_initdata __initdata
 #endif
 
 struct pernet_operations {
index a02ec9e..c926551 100644 (file)
@@ -316,4 +316,19 @@ static inline u32 qdisc_l2t(struct qdisc_rate_table* rtab, unsigned int pktlen)
        return rtab->data[slot];
 }
 
+#ifdef CONFIG_NET_CLS_ACT
+static inline struct sk_buff *skb_act_clone(struct sk_buff *skb, gfp_t gfp_mask)
+{
+       struct sk_buff *n = skb_clone(skb, gfp_mask);
+
+       if (n) {
+               n->tc_verd = SET_TC_VERD(n->tc_verd, 0);
+               n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
+               n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
+               n->iif = skb->iif;
+       }
+       return n;
+}
+#endif
+
 #endif
index 4945954..5db261a 100644 (file)
@@ -88,7 +88,6 @@ static inline void sctp_auth_key_hold(struct sctp_auth_bytes *key)
 
 void sctp_auth_key_put(struct sctp_auth_bytes *key);
 struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp);
-void sctp_auth_shkey_free(struct sctp_shared_key *sh_key);
 void sctp_auth_destroy_keys(struct list_head *keys);
 int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp);
 struct sctp_shared_key *sctp_auth_get_shkey(
@@ -104,7 +103,7 @@ struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc);
 void sctp_auth_asoc_set_default_hmac(struct sctp_association *asoc,
                                     struct sctp_hmac_algo_param *hmacs);
 int sctp_auth_asoc_verify_hmac_id(const struct sctp_association *asoc,
-                                   __u16 hmac_id);
+                                   __be16 hmac_id);
 int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
 int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc);
 void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
index 119f5a1..93eb708 100644 (file)
@@ -156,7 +156,6 @@ int sctp_primitive_ASCONF(struct sctp_association *, void *arg);
 __u32 sctp_start_cksum(__u8 *ptr, __u16 count);
 __u32 sctp_update_cksum(__u8 *ptr, __u16 count, __u32 cksum);
 __u32 sctp_end_cksum(__u32 cksum);
-__u32 sctp_update_copy_cksum(__u8 *, __u8 *, __u16 count, __u32 cksum);
 
 /*
  * sctp/input.c
index 92049e6..d695cea 100644 (file)
@@ -803,7 +803,7 @@ static inline int tcp_is_cwnd_limited(const struct sock *sk, u32 in_flight)
                return left <= tcp_max_burst(tp);
 }
 
-static inline void tcp_minshall_update(struct tcp_sock *tp, int mss,
+static inline void tcp_minshall_update(struct tcp_sock *tp, unsigned int mss,
                                       const struct sk_buff *skb)
 {
        if (skb->len < mss)
index 688f6f5..58dfa82 100644 (file)
@@ -37,6 +37,8 @@
 extern struct sock *xfrm_nl;
 extern u32 sysctl_xfrm_aevent_etime;
 extern u32 sysctl_xfrm_aevent_rseqth;
+extern int sysctl_xfrm_larval_drop;
+extern u32 sysctl_xfrm_acq_expires;
 
 extern struct mutex xfrm_cfg_mutex;
 
index b7dffa8..8b88d0b 100644 (file)
@@ -322,7 +322,6 @@ config CPUSETS
 config FAIR_GROUP_SCHED
        bool "Fair group CPU scheduler"
        default y
-       depends on EXPERIMENTAL
        help
          This feature lets CPU scheduler recognize task groups and control CPU
          bandwidth allocation to such task groups.
index b6d2ff7..22a2514 100644 (file)
@@ -602,7 +602,7 @@ static int hrtimer_switch_to_hres(void)
        /* "Retrigger" the interrupt to get things going */
        retrigger_next_event(NULL);
        local_irq_restore(flags);
-       printk(KERN_INFO "Switched to high resolution mode on CPU %d\n",
+       printk(KERN_DEBUG "Switched to high resolution mode on CPU %d\n",
               smp_processor_id());
        return 1;
 }
index 631b75c..5e95330 100644 (file)
@@ -60,6 +60,7 @@ static int __init profile_setup(char * str)
        int par;
 
        if (!strncmp(str, sleepstr, strlen(sleepstr))) {
+#ifdef CONFIG_SCHEDSTATS
                prof_on = SLEEP_PROFILING;
                if (str[strlen(sleepstr)] == ',')
                        str += strlen(sleepstr) + 1;
@@ -68,6 +69,10 @@ static int __init profile_setup(char * str)
                printk(KERN_INFO
                        "kernel sleep profiling enabled (shift: %ld)\n",
                        prof_shift);
+#else
+               printk(KERN_WARNING
+                       "kernel sleep profiling requires CONFIG_SCHEDSTATS\n");
+#endif /* CONFIG_SCHEDSTATS */
        } else if (!strncmp(str, schedstr, strlen(schedstr))) {
                prof_on = SCHED_PROFILING;
                if (str[strlen(schedstr)] == ',')
index 2810e56..b4fbbc4 100644 (file)
@@ -66,6 +66,7 @@
 #include <linux/pagemap.h>
 
 #include <asm/tlb.h>
+#include <asm/irq_regs.h>
 
 /*
  * Scheduler clock - returns current time in nanosec units.
@@ -837,11 +838,18 @@ struct rq_iterator {
        struct task_struct *(*next)(void *);
 };
 
-static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
-                     unsigned long max_nr_move, unsigned long max_load_move,
-                     struct sched_domain *sd, enum cpu_idle_type idle,
-                     int *all_pinned, unsigned long *load_moved,
-                     int *this_best_prio, struct rq_iterator *iterator);
+#ifdef CONFIG_SMP
+static unsigned long
+balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
+             unsigned long max_load_move, struct sched_domain *sd,
+             enum cpu_idle_type idle, int *all_pinned,
+             int *this_best_prio, struct rq_iterator *iterator);
+
+static int
+iter_move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                  struct sched_domain *sd, enum cpu_idle_type idle,
+                  struct rq_iterator *iterator);
+#endif
 
 #include "sched_stats.h"
 #include "sched_idletask.c"
@@ -2223,17 +2231,17 @@ int can_migrate_task(struct task_struct *p, struct rq *rq, int this_cpu,
        return 1;
 }
 
-static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
-                     unsigned long max_nr_move, unsigned long max_load_move,
-                     struct sched_domain *sd, enum cpu_idle_type idle,
-                     int *all_pinned, unsigned long *load_moved,
-                     int *this_best_prio, struct rq_iterator *iterator)
+static unsigned long
+balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
+             unsigned long max_load_move, struct sched_domain *sd,
+             enum cpu_idle_type idle, int *all_pinned,
+             int *this_best_prio, struct rq_iterator *iterator)
 {
        int pulled = 0, pinned = 0, skip_for_load;
        struct task_struct *p;
        long rem_load_move = max_load_move;
 
-       if (max_nr_move == 0 || max_load_move == 0)
+       if (max_load_move == 0)
                goto out;
 
        pinned = 1;
@@ -2266,7 +2274,7 @@ next:
         * We only want to steal up to the prescribed number of tasks
         * and the prescribed amount of weighted load.
         */
-       if (pulled < max_nr_move && rem_load_move > 0) {
+       if (rem_load_move > 0) {
                if (p->prio < *this_best_prio)
                        *this_best_prio = p->prio;
                p = iterator->next(iterator->arg);
@@ -2274,7 +2282,7 @@ next:
        }
 out:
        /*
-        * Right now, this is the only place pull_task() is called,
+        * Right now, this is one of only two places pull_task() is called,
         * so we can safely collect pull_task() stats here rather than
         * inside pull_task().
         */
@@ -2282,8 +2290,8 @@ out:
 
        if (all_pinned)
                *all_pinned = pinned;
-       *load_moved = max_load_move - rem_load_move;
-       return pulled;
+
+       return max_load_move - rem_load_move;
 }
 
 /*
@@ -2305,7 +2313,7 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
        do {
                total_load_moved +=
                        class->load_balance(this_rq, this_cpu, busiest,
-                               ULONG_MAX, max_load_move - total_load_moved,
+                               max_load_move - total_load_moved,
                                sd, idle, all_pinned, &this_best_prio);
                class = class->next;
        } while (class && max_load_move > total_load_moved);
@@ -2313,6 +2321,32 @@ static int move_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
        return total_load_moved > 0;
 }
 
+static int
+iter_move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                  struct sched_domain *sd, enum cpu_idle_type idle,
+                  struct rq_iterator *iterator)
+{
+       struct task_struct *p = iterator->start(iterator->arg);
+       int pinned = 0;
+
+       while (p) {
+               if (can_migrate_task(p, busiest, this_cpu, sd, idle, &pinned)) {
+                       pull_task(busiest, p, this_rq, this_cpu);
+                       /*
+                        * Right now, this is only the second place pull_task()
+                        * is called, so we can safely collect pull_task()
+                        * stats here rather than inside pull_task().
+                        */
+                       schedstat_inc(sd, lb_gained[idle]);
+
+                       return 1;
+               }
+               p = iterator->next(iterator->arg);
+       }
+
+       return 0;
+}
+
 /*
  * move_one_task tries to move exactly one task from busiest to this_rq, as
  * part of active balancing operations within "domain".
@@ -2324,12 +2358,9 @@ static int move_one_task(struct rq *this_rq, int this_cpu, struct rq *busiest,
                         struct sched_domain *sd, enum cpu_idle_type idle)
 {
        const struct sched_class *class;
-       int this_best_prio = MAX_PRIO;
 
        for (class = sched_class_highest; class; class = class->next)
-               if (class->load_balance(this_rq, this_cpu, busiest,
-                                       1, ULONG_MAX, sd, idle, NULL,
-                                       &this_best_prio))
+               if (class->move_one_task(this_rq, this_cpu, busiest, sd, idle))
                        return 1;
 
        return 0;
@@ -3266,18 +3297,6 @@ static inline void idle_balance(int cpu, struct rq *rq)
 {
 }
 
-/* Avoid "used but not defined" warning on UP */
-static int balance_tasks(struct rq *this_rq, int this_cpu, struct rq *busiest,
-                     unsigned long max_nr_move, unsigned long max_load_move,
-                     struct sched_domain *sd, enum cpu_idle_type idle,
-                     int *all_pinned, unsigned long *load_moved,
-                     int *this_best_prio, struct rq_iterator *iterator)
-{
-       *load_moved = 0;
-
-       return 0;
-}
-
 #endif
 
 DEFINE_PER_CPU(struct kernel_stat, kstat);
@@ -3507,12 +3526,19 @@ EXPORT_SYMBOL(sub_preempt_count);
  */
 static noinline void __schedule_bug(struct task_struct *prev)
 {
-       printk(KERN_ERR "BUG: scheduling while atomic: %s/0x%08x/%d\n",
-               prev->comm, preempt_count(), task_pid_nr(prev));
+       struct pt_regs *regs = get_irq_regs();
+
+       printk(KERN_ERR "BUG: scheduling while atomic: %s/%d/0x%08x\n",
+               prev->comm, prev->pid, preempt_count());
+
        debug_show_held_locks(prev);
        if (irqs_disabled())
                print_irqtrace_events(prev);
-       dump_stack();
+
+       if (regs)
+               show_regs(regs);
+       else
+               dump_stack();
 }
 
 /*
@@ -3820,7 +3846,7 @@ __wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr_exclusive)
 }
 EXPORT_SYMBOL_GPL(__wake_up_sync);     /* For internal use only */
 
-void fastcall complete(struct completion *x)
+void complete(struct completion *x)
 {
        unsigned long flags;
 
@@ -3832,7 +3858,7 @@ void fastcall complete(struct completion *x)
 }
 EXPORT_SYMBOL(complete);
 
-void fastcall complete_all(struct completion *x)
+void complete_all(struct completion *x)
 {
        unsigned long flags;
 
@@ -3884,13 +3910,13 @@ wait_for_common(struct completion *x, long timeout, int state)
        return timeout;
 }
 
-void fastcall __sched wait_for_completion(struct completion *x)
+void __sched wait_for_completion(struct completion *x)
 {
        wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
 }
 EXPORT_SYMBOL(wait_for_completion);
 
-unsigned long fastcall __sched
+unsigned long __sched
 wait_for_completion_timeout(struct completion *x, unsigned long timeout)
 {
        return wait_for_common(x, timeout, TASK_UNINTERRUPTIBLE);
@@ -3906,7 +3932,7 @@ int __sched wait_for_completion_interruptible(struct completion *x)
 }
 EXPORT_SYMBOL(wait_for_completion_interruptible);
 
-unsigned long fastcall __sched
+unsigned long __sched
 wait_for_completion_interruptible_timeout(struct completion *x,
                                          unsigned long timeout)
 {
@@ -5461,11 +5487,12 @@ static void register_sched_domain_sysctl(void)
        struct ctl_table *entry = sd_alloc_ctl_entry(cpu_num + 1);
        char buf[32];
 
+       WARN_ON(sd_ctl_dir[0].child);
+       sd_ctl_dir[0].child = entry;
+
        if (entry == NULL)
                return;
 
-       sd_ctl_dir[0].child = entry;
-
        for_each_online_cpu(i) {
                snprintf(buf, 32, "cpu%d", i);
                entry->procname = kstrdup(buf, GFP_KERNEL);
@@ -5473,14 +5500,19 @@ static void register_sched_domain_sysctl(void)
                entry->child = sd_alloc_ctl_cpu_table(i);
                entry++;
        }
+
+       WARN_ON(sd_sysctl_header);
        sd_sysctl_header = register_sysctl_table(sd_ctl_root);
 }
 
+/* may be called multiple times per register */
 static void unregister_sched_domain_sysctl(void)
 {
-       unregister_sysctl_table(sd_sysctl_header);
+       if (sd_sysctl_header)
+               unregister_sysctl_table(sd_sysctl_header);
        sd_sysctl_header = NULL;
-       sd_free_ctl_entry(&sd_ctl_dir[0].child);
+       if (sd_ctl_dir[0].child)
+               sd_free_ctl_entry(&sd_ctl_dir[0].child);
 }
 #else
 static void register_sched_domain_sysctl(void)
@@ -5611,101 +5643,101 @@ int nr_cpu_ids __read_mostly = NR_CPUS;
 EXPORT_SYMBOL(nr_cpu_ids);
 
 #ifdef CONFIG_SCHED_DEBUG
-static void sched_domain_debug(struct sched_domain *sd, int cpu)
+
+static int sched_domain_debug_one(struct sched_domain *sd, int cpu, int level)
 {
-       int level = 0;
+       struct sched_group *group = sd->groups;
+       cpumask_t groupmask;
+       char str[NR_CPUS];
 
-       if (!sd) {
-               printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu);
-               return;
+       cpumask_scnprintf(str, NR_CPUS, sd->span);
+       cpus_clear(groupmask);
+
+       printk(KERN_DEBUG "%*s domain %d: ", level, "", level);
+
+       if (!(sd->flags & SD_LOAD_BALANCE)) {
+               printk("does not load-balance\n");
+               if (sd->parent)
+                       printk(KERN_ERR "ERROR: !SD_LOAD_BALANCE domain"
+                                       " has parent");
+               return -1;
        }
 
-       printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu);
+       printk(KERN_CONT "span %s\n", str);
+
+       if (!cpu_isset(cpu, sd->span)) {
+               printk(KERN_ERR "ERROR: domain->span does not contain "
+                               "CPU%d\n", cpu);
+       }
+       if (!cpu_isset(cpu, group->cpumask)) {
+               printk(KERN_ERR "ERROR: domain->groups does not contain"
+                               " CPU%d\n", cpu);
+       }
 
+       printk(KERN_DEBUG "%*s groups:", level + 1, "");
        do {
-               int i;
-               char str[NR_CPUS];
-               struct sched_group *group = sd->groups;
-               cpumask_t groupmask;
-
-               cpumask_scnprintf(str, NR_CPUS, sd->span);
-               cpus_clear(groupmask);
-
-               printk(KERN_DEBUG);
-               for (i = 0; i < level + 1; i++)
-                       printk(" ");
-               printk("domain %d: ", level);
-
-               if (!(sd->flags & SD_LOAD_BALANCE)) {
-                       printk("does not load-balance\n");
-                       if (sd->parent)
-                               printk(KERN_ERR "ERROR: !SD_LOAD_BALANCE domain"
-                                               " has parent");
+               if (!group) {
+                       printk("\n");
+                       printk(KERN_ERR "ERROR: group is NULL\n");
                        break;
                }
 
-               printk("span %s\n", str);
+               if (!group->__cpu_power) {
+                       printk(KERN_CONT "\n");
+                       printk(KERN_ERR "ERROR: domain->cpu_power not "
+                                       "set\n");
+                       break;
+               }
 
-               if (!cpu_isset(cpu, sd->span))
-                       printk(KERN_ERR "ERROR: domain->span does not contain "
-                                       "CPU%d\n", cpu);
-               if (!cpu_isset(cpu, group->cpumask))
-                       printk(KERN_ERR "ERROR: domain->groups does not contain"
-                                       " CPU%d\n", cpu);
+               if (!cpus_weight(group->cpumask)) {
+                       printk(KERN_CONT "\n");
+                       printk(KERN_ERR "ERROR: empty group\n");
+                       break;
+               }
 
-               printk(KERN_DEBUG);
-               for (i = 0; i < level + 2; i++)
-                       printk(" ");
-               printk("groups:");
-               do {
-                       if (!group) {
-                               printk("\n");
-                               printk(KERN_ERR "ERROR: group is NULL\n");
-                               break;
-                       }
+               if (cpus_intersects(groupmask, group->cpumask)) {
+                       printk(KERN_CONT "\n");
+                       printk(KERN_ERR "ERROR: repeated CPUs\n");
+                       break;
+               }
 
-                       if (!group->__cpu_power) {
-                               printk(KERN_CONT "\n");
-                               printk(KERN_ERR "ERROR: domain->cpu_power not "
-                                               "set\n");
-                               break;
-                       }
+               cpus_or(groupmask, groupmask, group->cpumask);
 
-                       if (!cpus_weight(group->cpumask)) {
-                               printk(KERN_CONT "\n");
-                               printk(KERN_ERR "ERROR: empty group\n");
-                               break;
-                       }
+               cpumask_scnprintf(str, NR_CPUS, group->cpumask);
+               printk(KERN_CONT " %s", str);
 
-                       if (cpus_intersects(groupmask, group->cpumask)) {
-                               printk(KERN_CONT "\n");
-                               printk(KERN_ERR "ERROR: repeated CPUs\n");
-                               break;
-                       }
+               group = group->next;
+       } while (group != sd->groups);
+       printk(KERN_CONT "\n");
 
-                       cpus_or(groupmask, groupmask, group->cpumask);
+       if (!cpus_equal(sd->span, groupmask))
+               printk(KERN_ERR "ERROR: groups don't span domain->span\n");
 
-                       cpumask_scnprintf(str, NR_CPUS, group->cpumask);
-                       printk(KERN_CONT " %s", str);
+       if (sd->parent && !cpus_subset(groupmask, sd->parent->span))
+               printk(KERN_ERR "ERROR: parent span is not a superset "
+                       "of domain->span\n");
+       return 0;
+}
 
-                       group = group->next;
-               } while (group != sd->groups);
-               printk(KERN_CONT "\n");
+static void sched_domain_debug(struct sched_domain *sd, int cpu)
+{
+       int level = 0;
 
-               if (!cpus_equal(sd->span, groupmask))
-                       printk(KERN_ERR "ERROR: groups don't span "
-                                       "domain->span\n");
+       if (!sd) {
+               printk(KERN_DEBUG "CPU%d attaching NULL sched-domain.\n", cpu);
+               return;
+       }
+
+       printk(KERN_DEBUG "CPU%d attaching sched-domain:\n", cpu);
 
+       for (;;) {
+               if (sched_domain_debug_one(sd, cpu, level))
+                       break;
                level++;
                sd = sd->parent;
                if (!sd)
-                       continue;
-
-               if (!cpus_subset(groupmask, sd->span))
-                       printk(KERN_ERR "ERROR: parent span is not a superset "
-                               "of domain->span\n");
-
-       } while (sd);
+                       break;
+       }
 }
 #else
 # define sched_domain_debug(sd, cpu) do { } while (0)
@@ -6424,13 +6456,17 @@ static cpumask_t fallback_doms;
  */
 static int arch_init_sched_domains(const cpumask_t *cpu_map)
 {
+       int err;
+
        ndoms_cur = 1;
        doms_cur = kmalloc(sizeof(cpumask_t), GFP_KERNEL);
        if (!doms_cur)
                doms_cur = &fallback_doms;
        cpus_andnot(*doms_cur, *cpu_map, cpu_isolated_map);
+       err = build_sched_domains(doms_cur);
        register_sched_domain_sysctl();
-       return build_sched_domains(doms_cur);
+
+       return err;
 }
 
 static void arch_destroy_sched_domains(const cpumask_t *cpu_map)
@@ -6479,6 +6515,9 @@ void partition_sched_domains(int ndoms_new, cpumask_t *doms_new)
 {
        int i, j;
 
+       /* always unregister in case we don't destroy any domains */
+       unregister_sched_domain_sysctl();
+
        if (doms_new == NULL) {
                ndoms_new = 1;
                doms_new = &fallback_doms;
@@ -6514,6 +6553,8 @@ match2:
                kfree(doms_cur);
        doms_cur = doms_new;
        ndoms_cur = ndoms_new;
+
+       register_sched_domain_sysctl();
 }
 
 #if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
@@ -7101,25 +7142,25 @@ unsigned long sched_group_shares(struct task_group *tg)
 #ifdef CONFIG_FAIR_CGROUP_SCHED
 
 /* return corresponding task_group object of a cgroup */
-static inline struct task_group *cgroup_tg(struct cgroup *cont)
+static inline struct task_group *cgroup_tg(struct cgroup *cgrp)
 {
-       return container_of(cgroup_subsys_state(cont, cpu_cgroup_subsys_id),
-                                        struct task_group, css);
+       return container_of(cgroup_subsys_state(cgrp, cpu_cgroup_subsys_id),
+                           struct task_group, css);
 }
 
 static struct cgroup_subsys_state *
-cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
+cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cgrp)
 {
        struct task_group *tg;
 
-       if (!cont->parent) {
+       if (!cgrp->parent) {
                /* This is early initialization for the top cgroup */
-               init_task_group.css.cgroup = cont;
+               init_task_group.css.cgroup = cgrp;
                return &init_task_group.css;
        }
 
        /* we support only 1-level deep hierarchical scheduler atm */
-       if (cont->parent->parent)
+       if (cgrp->parent->parent)
                return ERR_PTR(-EINVAL);
 
        tg = sched_create_group();
@@ -7127,21 +7168,21 @@ cpu_cgroup_create(struct cgroup_subsys *ss, struct cgroup *cont)
                return ERR_PTR(-ENOMEM);
 
        /* Bind the cgroup to task_group object we just created */
-       tg->css.cgroup = cont;
+       tg->css.cgroup = cgrp;
 
        return &tg->css;
 }
 
 static void cpu_cgroup_destroy(struct cgroup_subsys *ss,
-                                       struct cgroup *cont)
+                              struct cgroup *cgrp)
 {
-       struct task_group *tg = cgroup_tg(cont);
+       struct task_group *tg = cgroup_tg(cgrp);
 
        sched_destroy_group(tg);
 }
 
 static int cpu_cgroup_can_attach(struct cgroup_subsys *ss,
-                            struct cgroup *cont, struct task_struct *tsk)
+                            struct cgroup *cgrp, struct task_struct *tsk)
 {
        /* We don't support RT-tasks being in separate groups */
        if (tsk->sched_class != &fair_sched_class)
@@ -7151,38 +7192,21 @@ static int cpu_cgroup_can_attach(struct cgroup_subsys *ss,
 }
 
 static void
-cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cont,
+cpu_cgroup_attach(struct cgroup_subsys *ss, struct cgroup *cgrp,
                        struct cgroup *old_cont, struct task_struct *tsk)
 {
        sched_move_task(tsk);
 }
 
-static ssize_t cpu_shares_write(struct cgroup *cont, struct cftype *cftype,
-                               struct file *file, const char __user *userbuf,
-                               size_t nbytes, loff_t *ppos)
+static int cpu_shares_write_uint(struct cgroup *cgrp, struct cftype *cftype,
+                               u64 shareval)
 {
-       unsigned long shareval;
-       struct task_group *tg = cgroup_tg(cont);
-       char buffer[2*sizeof(unsigned long) + 1];
-       int rc;
-
-       if (nbytes > 2*sizeof(unsigned long))   /* safety check */
-               return -E2BIG;
-
-       if (copy_from_user(buffer, userbuf, nbytes))
-               return -EFAULT;
-
-       buffer[nbytes] = 0;     /* nul-terminate */
-       shareval = simple_strtoul(buffer, NULL, 10);
-
-       rc = sched_group_set_shares(tg, shareval);
-
-       return (rc < 0 ? rc : nbytes);
+       return sched_group_set_shares(cgroup_tg(cgrp), shareval);
 }
 
-static u64 cpu_shares_read_uint(struct cgroup *cont, struct cftype *cft)
+static u64 cpu_shares_read_uint(struct cgroup *cgrp, struct cftype *cft)
 {
-       struct task_group *tg = cgroup_tg(cont);
+       struct task_group *tg = cgroup_tg(cgrp);
 
        return (u64) tg->shares;
 }
@@ -7190,7 +7214,7 @@ static u64 cpu_shares_read_uint(struct cgroup *cont, struct cftype *cft)
 static struct cftype cpu_shares = {
        .name = "shares",
        .read_uint = cpu_shares_read_uint,
-       .write = cpu_shares_write,
+       .write_uint = cpu_shares_write_uint,
 };
 
 static int cpu_cgroup_populate(struct cgroup_subsys *ss, struct cgroup *cont)
index 166ed6d..9971831 100644 (file)
@@ -876,6 +876,7 @@ static void put_prev_task_fair(struct rq *rq, struct task_struct *prev)
        }
 }
 
+#ifdef CONFIG_SMP
 /**************************************************
  * Fair scheduling class load-balancing methods:
  */
@@ -936,12 +937,11 @@ static int cfs_rq_best_prio(struct cfs_rq *cfs_rq)
 
 static unsigned long
 load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
-                 unsigned long max_nr_move, unsigned long max_load_move,
+                 unsigned long max_load_move,
                  struct sched_domain *sd, enum cpu_idle_type idle,
                  int *all_pinned, int *this_best_prio)
 {
        struct cfs_rq *busy_cfs_rq;
-       unsigned long load_moved, total_nr_moved = 0, nr_moved;
        long rem_load_move = max_load_move;
        struct rq_iterator cfs_rq_iterator;
 
@@ -969,25 +969,48 @@ load_balance_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
 #else
 # define maxload rem_load_move
 #endif
-               /* pass busy_cfs_rq argument into
+               /*
+                * pass busy_cfs_rq argument into
                 * load_balance_[start|next]_fair iterators
                 */
                cfs_rq_iterator.arg = busy_cfs_rq;
-               nr_moved = balance_tasks(this_rq, this_cpu, busiest,
-                               max_nr_move, maxload, sd, idle, all_pinned,
-                               &load_moved, this_best_prio, &cfs_rq_iterator);
-
-               total_nr_moved += nr_moved;
-               max_nr_move -= nr_moved;
-               rem_load_move -= load_moved;
+               rem_load_move -= balance_tasks(this_rq, this_cpu, busiest,
+                                              maxload, sd, idle, all_pinned,
+                                              this_best_prio,
+                                              &cfs_rq_iterator);
 
-               if (max_nr_move <= 0 || rem_load_move <= 0)
+               if (rem_load_move <= 0)
                        break;
        }
 
        return max_load_move - rem_load_move;
 }
 
+static int
+move_one_task_fair(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                  struct sched_domain *sd, enum cpu_idle_type idle)
+{
+       struct cfs_rq *busy_cfs_rq;
+       struct rq_iterator cfs_rq_iterator;
+
+       cfs_rq_iterator.start = load_balance_start_fair;
+       cfs_rq_iterator.next = load_balance_next_fair;
+
+       for_each_leaf_cfs_rq(busiest, busy_cfs_rq) {
+               /*
+                * pass busy_cfs_rq argument into
+                * load_balance_[start|next]_fair iterators
+                */
+               cfs_rq_iterator.arg = busy_cfs_rq;
+               if (iter_move_one_task(this_rq, this_cpu, busiest, sd, idle,
+                                      &cfs_rq_iterator))
+                   return 1;
+       }
+
+       return 0;
+}
+#endif
+
 /*
  * scheduler tick hitting a task of our scheduling class:
  */
@@ -1063,7 +1086,10 @@ static const struct sched_class fair_sched_class = {
        .pick_next_task         = pick_next_task_fair,
        .put_prev_task          = put_prev_task_fair,
 
+#ifdef CONFIG_SMP
        .load_balance           = load_balance_fair,
+       .move_one_task          = move_one_task_fair,
+#endif
 
        .set_curr_task          = set_curr_task_fair,
        .task_tick              = task_tick_fair,
index 6e2ead4..bf9c25c 100644 (file)
@@ -37,15 +37,24 @@ static void put_prev_task_idle(struct rq *rq, struct task_struct *prev)
 {
 }
 
+#ifdef CONFIG_SMP
 static unsigned long
 load_balance_idle(struct rq *this_rq, int this_cpu, struct rq *busiest,
-                       unsigned long max_nr_move, unsigned long max_load_move,
-                       struct sched_domain *sd, enum cpu_idle_type idle,
-                       int *all_pinned, int *this_best_prio)
+                 unsigned long max_load_move,
+                 struct sched_domain *sd, enum cpu_idle_type idle,
+                 int *all_pinned, int *this_best_prio)
 {
        return 0;
 }
 
+static int
+move_one_task_idle(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                  struct sched_domain *sd, enum cpu_idle_type idle)
+{
+       return 0;
+}
+#endif
+
 static void task_tick_idle(struct rq *rq, struct task_struct *curr)
 {
 }
@@ -69,7 +78,10 @@ const struct sched_class idle_sched_class = {
        .pick_next_task         = pick_next_task_idle,
        .put_prev_task          = put_prev_task_idle,
 
+#ifdef CONFIG_SMP
        .load_balance           = load_balance_idle,
+       .move_one_task          = move_one_task_idle,
+#endif
 
        .set_curr_task          = set_curr_task_idle,
        .task_tick              = task_tick_idle,
index d0097a0..8abd752 100644 (file)
@@ -98,6 +98,7 @@ static void put_prev_task_rt(struct rq *rq, struct task_struct *p)
        p->se.exec_start = 0;
 }
 
+#ifdef CONFIG_SMP
 /*
  * Load-balancing iterator. Note: while the runqueue stays locked
  * during the whole iteration, the current task might be
@@ -172,13 +173,11 @@ static struct task_struct *load_balance_next_rt(void *arg)
 
 static unsigned long
 load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
-                       unsigned long max_nr_move, unsigned long max_load_move,
-                       struct sched_domain *sd, enum cpu_idle_type idle,
-                       int *all_pinned, int *this_best_prio)
+               unsigned long max_load_move,
+               struct sched_domain *sd, enum cpu_idle_type idle,
+               int *all_pinned, int *this_best_prio)
 {
-       int nr_moved;
        struct rq_iterator rt_rq_iterator;
-       unsigned long load_moved;
 
        rt_rq_iterator.start = load_balance_start_rt;
        rt_rq_iterator.next = load_balance_next_rt;
@@ -187,12 +186,24 @@ load_balance_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
         */
        rt_rq_iterator.arg = busiest;
 
-       nr_moved = balance_tasks(this_rq, this_cpu, busiest, max_nr_move,
-                       max_load_move, sd, idle, all_pinned, &load_moved,
-                       this_best_prio, &rt_rq_iterator);
+       return balance_tasks(this_rq, this_cpu, busiest, max_load_move, sd,
+                            idle, all_pinned, this_best_prio, &rt_rq_iterator);
+}
+
+static int
+move_one_task_rt(struct rq *this_rq, int this_cpu, struct rq *busiest,
+                struct sched_domain *sd, enum cpu_idle_type idle)
+{
+       struct rq_iterator rt_rq_iterator;
+
+       rt_rq_iterator.start = load_balance_start_rt;
+       rt_rq_iterator.next = load_balance_next_rt;
+       rt_rq_iterator.arg = busiest;
 
-       return load_moved;
+       return iter_move_one_task(this_rq, this_cpu, busiest, sd, idle,
+                                 &rt_rq_iterator);
 }
+#endif
 
 static void task_tick_rt(struct rq *rq, struct task_struct *p)
 {
@@ -236,7 +247,10 @@ const struct sched_class rt_sched_class = {
        .pick_next_task         = pick_next_task_rt,
        .put_prev_task          = put_prev_task_rt,
 
+#ifdef CONFIG_SMP
        .load_balance           = load_balance_rt,
+       .move_one_task          = move_one_task_rt,
+#endif
 
        .set_curr_task          = set_curr_task_rt,
        .task_tick              = task_tick_rt,
index 1200630..4537bdd 100644 (file)
@@ -732,7 +732,7 @@ static void print_fatal_signal(struct pt_regs *regs, int signr)
        printk("%s/%d: potentially unexpected fatal signal %d.\n",
                current->comm, task_pid_nr(current), signr);
 
-#ifdef __i386__
+#if defined(__i386__) && !defined(__arch_um__)
        printk("code at %08lx: ", regs->eip);
        {
                int i;
index 10a1347..5997456 100644 (file)
@@ -320,8 +320,6 @@ ktime_t tick_nohz_get_sleep_length(void)
        return ts->sleep_length;
 }
 
-EXPORT_SYMBOL_GPL(tick_nohz_get_sleep_length);
-
 /**
  * nohz_restart_sched_tick - restart the idle tick from the idle task
  *
index fdb2e03..12c5f4c 100644 (file)
@@ -129,7 +129,8 @@ static void print_cpu(struct seq_file *m, int cpu, u64 now)
        struct hrtimer_cpu_base *cpu_base = &per_cpu(hrtimer_bases, cpu);
        int i;
 
-       SEQ_printf(m, "\ncpu: %d\n", cpu);
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "cpu: %d\n", cpu);
        for (i = 0; i < HRTIMER_MAX_CLOCK_BASES; i++) {
                SEQ_printf(m, " clock %d:\n", i);
                print_base(m, cpu_base->clock_base + i, now);
@@ -184,7 +185,8 @@ print_tickdevice(struct seq_file *m, struct tick_device *td)
 {
        struct clock_event_device *dev = td->evtdev;
 
-       SEQ_printf(m, "\nTick Device: mode:     %d\n", td->mode);
+       SEQ_printf(m, "\n");
+       SEQ_printf(m, "Tick Device: mode:     %d\n", td->mode);
 
        SEQ_printf(m, "Clock Event Device: ");
        if (!dev) {
index e91331c..0f3aa02 100644 (file)
@@ -129,7 +129,7 @@ static inline void uids_mutex_unlock(void)
 }
 
 /* return cpu shares held by the user */
-ssize_t cpu_shares_show(struct kset *kset, char *buffer)
+static ssize_t cpu_shares_show(struct kset *kset, char *buffer)
 {
        struct user_struct *up = container_of(kset, struct user_struct, kset);
 
@@ -137,7 +137,8 @@ ssize_t cpu_shares_show(struct kset *kset, char *buffer)
 }
 
 /* modify cpu shares held by the user */
-ssize_t cpu_shares_store(struct kset *kset, const char *buffer, size_t size)
+static ssize_t cpu_shares_store(struct kset *kset, const char *buffer,
+                               size_t size)
 {
        struct user_struct *up = container_of(kset, struct user_struct, kset);
        unsigned long shares;
index 1faa508..1e5f207 100644 (file)
@@ -9,6 +9,14 @@ config PRINTK_TIME
          operations.  This is useful for identifying long delays
          in kernel startup.
 
+config ENABLE_WARN_DEPRECATED
+       bool "Enable __deprecated logic"
+       default y
+       help
+         Enable the __deprecated logic in the kernel build.
+         Disable this to suppress the "warning: 'foo' is deprecated
+         (declared at kernel/power/somefile.c:1234)" messages.
+
 config ENABLE_MUST_CHECK
        bool "Enable __must_check logic"
        default y
index 5209e47..7c86436 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/backing-dev.h>
 #include <linux/pagevec.h>
 #include <linux/blkdev.h>
+#include <linux/backing-dev.h>
 #include <linux/security.h>
 #include <linux/syscalls.h>
 #include <linux/cpuset.h>
index 8f09333..35622c5 100644 (file)
@@ -12,6 +12,7 @@
  *  Copyright (c) 2002      Greg Ungerer <gerg@snapgear.com>
  */
 
+#include <linux/module.h>
 #include <linux/mm.h>
 #include <linux/mman.h>
 #include <linux/swap.h>
index aac1dd3..bcdb2c8 100644 (file)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -2734,7 +2734,7 @@ static void slab_mem_offline_callback(void *arg)
                         * and offline_pages() function shoudn't call this
                         * callback. So, we must fail.
                         */
-                       BUG_ON(atomic_read(&n->nr_slabs));
+                       BUG_ON(atomic_long_read(&n->nr_slabs));
 
                        s->node[offline_node] = NULL;
                        kmem_cache_free(kmalloc_caches, n);
index 08fb14f..e06f514 100644 (file)
@@ -220,12 +220,6 @@ static int __meminit sparse_init_one_section(struct mem_section *ms,
        return 1;
 }
 
-__attribute__((weak)) __init
-void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
-{
-       return NULL;
-}
-
 static unsigned long usemap_size(void)
 {
        unsigned long size_bytes;
@@ -267,11 +261,6 @@ struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid)
        if (map)
                return map;
 
-       map = alloc_bootmem_high_node(NODE_DATA(nid),
-                       sizeof(struct page) * PAGES_PER_SECTION);
-       if (map)
-               return map;
-
        map = alloc_bootmem_node(NODE_DATA(nid),
                        sizeof(struct page) * PAGES_PER_SECTION);
        return map;
index f140147..c9f0805 100644 (file)
@@ -222,8 +222,10 @@ static int p9_mux_poll_start(struct p9_conn *m)
        }
 
        if (i >= ARRAY_SIZE(p9_mux_poll_tasks)) {
-               if (vptlast == NULL)
+               if (vptlast == NULL) {
+                       mutex_unlock(&p9_mux_task_lock);
                        return -ENOMEM;
+               }
 
                P9_DPRINTK(P9_DEBUG_MUX, "put in proc %d\n", i);
                list_add(&m->mux_list, &vptlast->mux_list);
index 8726589..853c8b5 100644 (file)
 #include <linux/ctype.h>
 #include <linux/if_arp.h>
 
+#include "net-sysfs.h"
+
 /*
  *     The list of packet types we will receive (as opposed to discard)
  *     and the routines to invoke.
@@ -249,10 +251,6 @@ static RAW_NOTIFIER_HEAD(netdev_chain);
 
 DEFINE_PER_CPU(struct softnet_data, softnet_data);
 
-extern int netdev_kobject_init(void);
-extern int netdev_register_kobject(struct net_device *);
-extern void netdev_unregister_kobject(struct net_device *);
-
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
 /*
  * register_netdevice() inits dev->_xmit_lock and sets lockdep class
@@ -885,6 +883,9 @@ int dev_change_name(struct net_device *dev, char *newname)
        if (!dev_valid_name(newname))
                return -EINVAL;
 
+       if (strncmp(newname, dev->name, IFNAMSIZ) == 0)
+               return 0;
+
        memcpy(oldname, dev->name, IFNAMSIZ);
 
        if (strchr(newname, '%')) {
@@ -1007,17 +1008,20 @@ int dev_open(struct net_device *dev)
         *      Call device private open method
         */
        set_bit(__LINK_STATE_START, &dev->state);
-       if (dev->open) {
+
+       if (dev->validate_addr)
+               ret = dev->validate_addr(dev);
+
+       if (!ret && dev->open)
                ret = dev->open(dev);
-               if (ret)
-                       clear_bit(__LINK_STATE_START, &dev->state);
-       }
 
        /*
         *      If it went open OK then:
         */
 
-       if (!ret) {
+       if (ret)
+               clear_bit(__LINK_STATE_START, &dev->state);
+       else {
                /*
                 *      Set the flags.
                 */
@@ -1038,6 +1042,7 @@ int dev_open(struct net_device *dev)
                 */
                call_netdevice_notifiers(NETDEV_UP, dev);
        }
+
        return ret;
 }
 
@@ -2663,7 +2668,7 @@ static void __net_exit dev_proc_net_exit(struct net *net)
        proc_net_remove(net, "dev");
 }
 
-static struct pernet_operations __net_initdata dev_proc_ops = {
+static struct pernet_operations dev_proc_ops = {
        .init = dev_proc_net_init,
        .exit = dev_proc_net_exit,
 };
@@ -4323,7 +4328,7 @@ static void __net_exit netdev_exit(struct net *net)
        kfree(net->dev_index_head);
 }
 
-static struct pernet_operations __net_initdata netdev_net_ops = {
+static struct pernet_operations  netdev_net_ops = {
        .init = netdev_init,
        .exit = netdev_exit,
 };
@@ -4354,7 +4359,7 @@ static void __net_exit default_device_exit(struct net *net)
        rtnl_unlock();
 }
 
-static struct pernet_operations __net_initdata default_device_ops = {
+static struct pernet_operations  default_device_ops = {
        .exit = default_device_exit,
 };
 
index 15241cf..ae35405 100644 (file)
@@ -285,7 +285,7 @@ static void __net_exit dev_mc_net_exit(struct net *net)
        proc_net_remove(net, "dev_mcast");
 }
 
-static struct pernet_operations __net_initdata dev_mc_net_ops = {
+static struct pernet_operations dev_mc_net_ops = {
        .init = dev_mc_net_init,
        .exit = dev_mc_net_exit,
 };
index 0ab5234..3ed2b4b 100644 (file)
@@ -142,8 +142,6 @@ typedef u64 flow_compare_t;
 typedef u32 flow_compare_t;
 #endif
 
-extern void flowi_is_missized(void);
-
 /* I hear what you're saying, use memcmp.  But memcmp cannot make
  * important assumptions that we can here, such as alignment and
  * constant size.
@@ -153,8 +151,7 @@ static int flow_key_compare(struct flowi *key1, struct flowi *key2)
        flow_compare_t *k1, *k1_lim, *k2;
        const int n_elem = sizeof(struct flowi) / sizeof(flow_compare_t);
 
-       if (sizeof(struct flowi) % sizeof(flow_compare_t))
-               flowi_is_missized();
+       BUILD_BUG_ON(sizeof(struct flowi) % sizeof(flow_compare_t));
 
        k1 = (flow_compare_t *) key1;
        k1_lim = k1 + n_elem;
index 6628e45..61ead1d 100644 (file)
@@ -18,6 +18,8 @@
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 
+#include "net-sysfs.h"
+
 #ifdef CONFIG_SYSFS
 static const char fmt_hex[] = "%#x\n";
 static const char fmt_long_hex[] = "%#lx\n";
diff --git a/net/core/net-sysfs.h b/net/core/net-sysfs.h
new file mode 100644 (file)
index 0000000..f5f108d
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef __NET_SYSFS_H__
+#define __NET_SYSFS_H__
+
+int netdev_kobject_init(void);
+int netdev_register_kobject(struct net_device *);
+void netdev_unregister_kobject(struct net_device *);
+
+#endif
index 4a2640d..e1ba26f 100644 (file)
@@ -742,7 +742,7 @@ static struct net *get_net_ns_by_pid(pid_t pid)
        /* Lookup the network namespace */
        net = ERR_PTR(-ESRCH);
        rcu_read_lock();
-       tsk = find_task_by_pid(pid);
+       tsk = find_task_by_vpid(pid);
        if (tsk) {
                struct nsproxy *nsproxy;
                nsproxy = task_nsproxy(tsk);
index 4e2c84f..573e172 100644 (file)
@@ -415,13 +415,6 @@ static struct sk_buff *__skb_clone(struct sk_buff *n, struct sk_buff *skb)
        n->hdr_len = skb->nohdr ? skb_headroom(skb) : skb->hdr_len;
        n->nohdr = 0;
        n->destructor = NULL;
-#ifdef CONFIG_NET_CLS_ACT
-       /* FIXME What is this and why don't we do it in copy_skb_header? */
-       n->tc_verd = SET_TC_VERD(n->tc_verd,0);
-       n->tc_verd = CLR_TC_OK2MUNGE(n->tc_verd);
-       n->tc_verd = CLR_TC_MUNGED(n->tc_verd);
-       C(iif);
-#endif
        C(truesize);
        atomic_set(&n->users, 1);
        C(head);
@@ -2045,9 +2038,7 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
        if (copy > 0) {
                if (copy > len)
                        copy = len;
-               sg_set_page(&sg[elt], virt_to_page(skb->data + offset));
-               sg[elt].offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
-               sg[elt].length = copy;
+               sg_set_buf(sg, skb->data + offset, copy);
                elt++;
                if ((len -= copy) == 0)
                        return elt;
@@ -2065,9 +2056,8 @@ skb_to_sgvec(struct sk_buff *skb, struct scatterlist *sg, int offset, int len)
 
                        if (copy > len)
                                copy = len;
-                       sg_set_page(&sg[elt], frag->page);
-                       sg[elt].offset = frag->page_offset+offset-start;
-                       sg[elt].length = copy;
+                       sg_set_page(&sg[elt], frag->page, copy,
+                                       frag->page_offset+offset-start);
                        elt++;
                        if (!(len -= copy))
                                return elt;
index febbcbc..bba9949 100644 (file)
@@ -1649,7 +1649,6 @@ void sock_enable_timestamp(struct sock *sk)
                net_enable_timestamp();
        }
 }
-EXPORT_SYMBOL(sock_enable_timestamp);
 
 /*
  *     Get a socket option on an socket.
index 6d5ea97..113cc72 100644 (file)
@@ -9,25 +9,12 @@
 #include <linux/sysctl.h>
 #include <linux/module.h>
 #include <linux/socket.h>
+#include <linux/netdevice.h>
 #include <net/sock.h>
+#include <net/xfrm.h>
 
 #ifdef CONFIG_SYSCTL
 
-extern int netdev_max_backlog;
-extern int weight_p;
-
-extern __u32 sysctl_wmem_max;
-extern __u32 sysctl_rmem_max;
-
-extern int sysctl_core_destroy_delay;
-
-#ifdef CONFIG_XFRM
-extern u32 sysctl_xfrm_aevent_etime;
-extern u32 sysctl_xfrm_aevent_rseqth;
-extern int sysctl_xfrm_larval_drop;
-extern u32 sysctl_xfrm_acq_expires;
-#endif
-
 ctl_table core_table[] = {
 #ifdef CONFIG_NET
        {
index 426008e..d694656 100644 (file)
@@ -750,20 +750,16 @@ static int ccid2_hc_tx_init(struct ccid *ccid, struct sock *sk)
         */
        hctx->ccid2hctx_ssthresh  = ~0;
        hctx->ccid2hctx_numdupack = 3;
-       hctx->ccid2hctx_seqbufc   = 0;
 
        /* XXX init ~ to window size... */
        if (ccid2_hc_tx_alloc_seq(hctx))
                return -ENOMEM;
 
-       hctx->ccid2hctx_sent     = 0;
        hctx->ccid2hctx_rto      = 3 * HZ;
        ccid2_change_srtt(hctx, -1);
        hctx->ccid2hctx_rttvar   = -1;
-       hctx->ccid2hctx_lastrtt  = 0;
        hctx->ccid2hctx_rpdupack = -1;
        hctx->ccid2hctx_last_cong = jiffies;
-       hctx->ccid2hctx_high_ack = 0;
 
        hctx->ccid2hctx_rtotimer.function = &ccid2_hc_tx_rto_expire;
        hctx->ccid2hctx_rtotimer.data     = (unsigned long)sk;
index 25772c3..19b3358 100644 (file)
@@ -40,6 +40,8 @@
 #include "lib/tfrc.h"
 #include "ccid3.h"
 
+#include <asm/unaligned.h>
+
 #ifdef CONFIG_IP_DCCP_CCID3_DEBUG
 static int ccid3_debug;
 #define ccid3_pr_debug(format, a...)   DCCP_PR_DEBUG(ccid3_debug, format, ##a)
@@ -544,6 +546,7 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
        const struct dccp_sock *dp = dccp_sk(sk);
        struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
        struct ccid3_options_received *opt_recv;
+       __be32 opt_val;
 
        opt_recv = &hctx->ccid3hctx_options_received;
 
@@ -563,8 +566,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
                                  dccp_role(sk), sk, len);
                        rc = -EINVAL;
                } else {
-                       opt_recv->ccid3or_loss_event_rate =
-                                               ntohl(*(__be32 *)value);
+                       opt_val = get_unaligned((__be32 *)value);
+                       opt_recv->ccid3or_loss_event_rate = ntohl(opt_val);
                        ccid3_pr_debug("%s(%p), LOSS_EVENT_RATE=%u\n",
                                       dccp_role(sk), sk,
                                       opt_recv->ccid3or_loss_event_rate);
@@ -585,8 +588,8 @@ static int ccid3_hc_tx_parse_options(struct sock *sk, unsigned char option,
                                  dccp_role(sk), sk, len);
                        rc = -EINVAL;
                } else {
-                       opt_recv->ccid3or_receive_rate =
-                                               ntohl(*(__be32 *)value);
+                       opt_val = get_unaligned((__be32 *)value);
+                       opt_recv->ccid3or_receive_rate = ntohl(opt_val);
                        ccid3_pr_debug("%s(%p), RECEIVE_RATE=%u\n",
                                       dccp_role(sk), sk,
                                       opt_recv->ccid3or_receive_rate);
@@ -601,8 +604,6 @@ static int ccid3_hc_tx_init(struct ccid *ccid, struct sock *sk)
 {
        struct ccid3_hc_tx_sock *hctx = ccid_priv(ccid);
 
-       hctx->ccid3hctx_s     = 0;
-       hctx->ccid3hctx_rtt   = 0;
        hctx->ccid3hctx_state = TFRC_SSTATE_NO_SENT;
        INIT_LIST_HEAD(&hctx->ccid3hctx_hist);
 
@@ -963,8 +964,6 @@ static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk)
        INIT_LIST_HEAD(&hcrx->ccid3hcrx_li_hist);
        hcrx->ccid3hcrx_tstamp_last_feedback =
                hcrx->ccid3hcrx_tstamp_last_ack = ktime_get_real();
-       hcrx->ccid3hcrx_s   = 0;
-       hcrx->ccid3hcrx_rtt = 0;
        return 0;
 }
 
index 3560a2a..1ce1010 100644 (file)
@@ -58,6 +58,42 @@ static void dccp_rcv_closereq(struct sock *sk, struct sk_buff *skb)
        dccp_send_close(sk, 0);
 }
 
+static u8 dccp_reset_code_convert(const u8 code)
+{
+       const u8 error_code[] = {
+       [DCCP_RESET_CODE_CLOSED]             = 0,       /* normal termination */
+       [DCCP_RESET_CODE_UNSPECIFIED]        = 0,       /* nothing known */
+       [DCCP_RESET_CODE_ABORTED]            = ECONNRESET,
+
+       [DCCP_RESET_CODE_NO_CONNECTION]      = ECONNREFUSED,
+       [DCCP_RESET_CODE_CONNECTION_REFUSED] = ECONNREFUSED,
+       [DCCP_RESET_CODE_TOO_BUSY]           = EUSERS,
+       [DCCP_RESET_CODE_AGGRESSION_PENALTY] = EDQUOT,
+
+       [DCCP_RESET_CODE_PACKET_ERROR]       = ENOMSG,
+       [DCCP_RESET_CODE_BAD_INIT_COOKIE]    = EBADR,
+       [DCCP_RESET_CODE_BAD_SERVICE_CODE]   = EBADRQC,
+       [DCCP_RESET_CODE_OPTION_ERROR]       = EILSEQ,
+       [DCCP_RESET_CODE_MANDATORY_ERROR]    = EOPNOTSUPP,
+       };
+
+       return code >= DCCP_MAX_RESET_CODES ? 0 : error_code[code];
+}
+
+static void dccp_rcv_reset(struct sock *sk, struct sk_buff *skb)
+{
+       u8 err = dccp_reset_code_convert(dccp_hdr_reset(skb)->dccph_reset_code);
+
+       sk->sk_err = err;
+
+       /* Queue the equivalent of TCP fin so that dccp_recvmsg exits the loop */
+       dccp_fin(sk, skb);
+
+       if (err && !sock_flag(sk, SOCK_DEAD))
+               sk_wake_async(sk, 0, POLL_ERR);
+       dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
+}
+
 static void dccp_event_ack_recv(struct sock *sk, struct sk_buff *skb)
 {
        struct dccp_sock *dp = dccp_sk(sk);
@@ -191,9 +227,8 @@ static int __dccp_rcv_established(struct sock *sk, struct sk_buff *skb,
                 *              S.state := TIMEWAIT
                 *              Set TIMEWAIT timer
                 *              Drop packet and return
-               */
-               dccp_fin(sk, skb);
-               dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
+                */
+               dccp_rcv_reset(sk, skb);
                return 0;
        case DCCP_PKT_CLOSEREQ:
                dccp_rcv_closereq(sk, skb);
@@ -521,12 +556,7 @@ int dccp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
         *              Drop packet and return
        */
        if (dh->dccph_type == DCCP_PKT_RESET) {
-               /*
-                * Queue the equivalent of TCP fin so that dccp_recvmsg
-                * exits the loop
-                */
-               dccp_fin(sk, skb);
-               dccp_time_wait(sk, DCCP_TIME_WAIT, 0);
+               dccp_rcv_reset(sk, skb);
                return 0;
                /*
                 *   Step 7: Check for unexpected packet types
index 222549a..01a6a80 100644 (file)
@@ -241,8 +241,8 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
                goto out;
 
        dp = dccp_sk(sk);
-       seq = dccp_hdr_seq(skb);
-       if (sk->sk_state != DCCP_LISTEN &&
+       seq = dccp_hdr_seq(dh);
+       if ((1 << sk->sk_state) & ~(DCCPF_REQUESTING | DCCPF_LISTEN) &&
            !between48(seq, dp->dccps_swl, dp->dccps_swh)) {
                NET_INC_STATS_BH(LINUX_MIB_OUTOFWINDOWICMPS);
                goto out;
@@ -795,7 +795,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
 
        dh = dccp_hdr(skb);
 
-       DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(skb);
+       DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(dh);
        DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
 
        dccp_pr_debug("%8.8s "
index bbadd66..62428ff 100644 (file)
@@ -173,7 +173,7 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
 
        icmpv6_err_convert(type, code, &err);
 
-       seq = DCCP_SKB_CB(skb)->dccpd_seq;
+       seq = dccp_hdr_seq(dh);
        /* Might be for an request_sock */
        switch (sk->sk_state) {
                struct request_sock *req, **prev;
@@ -787,7 +787,7 @@ static int dccp_v6_rcv(struct sk_buff *skb)
 
        dh = dccp_hdr(skb);
 
-       DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(skb);
+       DCCP_SKB_CB(skb)->dccpd_seq  = dccp_hdr_seq(dh);
        DCCP_SKB_CB(skb)->dccpd_type = dh->dccph_type;
 
        if (dccp_packet_without_ack(skb))
index d361b55..d286cff 100644 (file)
@@ -14,6 +14,7 @@
 #include <linux/dccp.h>
 #include <linux/module.h>
 #include <linux/types.h>
+#include <asm/unaligned.h>
 #include <linux/kernel.h>
 #include <linux/skbuff.h>
 
@@ -59,6 +60,7 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
        unsigned char opt, len;
        unsigned char *value;
        u32 elapsed_time;
+       __be32 opt_val;
        int rc;
        int mandatory = 0;
 
@@ -145,7 +147,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                        if (len != 4)
                                goto out_invalid_option;
 
-                       opt_recv->dccpor_timestamp = ntohl(*(__be32 *)value);
+                       opt_val = get_unaligned((__be32 *)value);
+                       opt_recv->dccpor_timestamp = ntohl(opt_val);
 
                        dp->dccps_timestamp_echo = opt_recv->dccpor_timestamp;
                        dp->dccps_timestamp_time = ktime_get_real();
@@ -159,7 +162,8 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                        if (len != 4 && len != 6 && len != 8)
                                goto out_invalid_option;
 
-                       opt_recv->dccpor_timestamp_echo = ntohl(*(__be32 *)value);
+                       opt_val = get_unaligned((__be32 *)value);
+                       opt_recv->dccpor_timestamp_echo = ntohl(opt_val);
 
                        dccp_pr_debug("%s rx opt: TIMESTAMP_ECHO=%u, len=%d, "
                                      "ackno=%llu", dccp_role(sk),
@@ -168,16 +172,20 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                                      (unsigned long long)
                                      DCCP_SKB_CB(skb)->dccpd_ack_seq);
 
+                       value += 4;
 
-                       if (len == 4) {
+                       if (len == 4) {         /* no elapsed time included */
                                dccp_pr_debug_cat("\n");
                                break;
                        }
 
-                       if (len == 6)
-                               elapsed_time = ntohs(*(__be16 *)(value + 4));
-                       else
-                               elapsed_time = ntohl(*(__be32 *)(value + 4));
+                       if (len == 6) {         /* 2-byte elapsed time */
+                               __be16 opt_val2 = get_unaligned((__be16 *)value);
+                               elapsed_time = ntohs(opt_val2);
+                       } else {                /* 4-byte elapsed time */
+                               opt_val = get_unaligned((__be32 *)value);
+                               elapsed_time = ntohl(opt_val);
+                       }
 
                        dccp_pr_debug_cat(", ELAPSED_TIME=%u\n", elapsed_time);
 
@@ -192,10 +200,13 @@ int dccp_parse_options(struct sock *sk, struct sk_buff *skb)
                        if (pkt_type == DCCP_PKT_DATA)
                                continue;
 
-                       if (len == 2)
-                               elapsed_time = ntohs(*(__be16 *)value);
-                       else
-                               elapsed_time = ntohl(*(__be32 *)value);
+                       if (len == 2) {
+                               __be16 opt_val2 = get_unaligned((__be16 *)value);
+                               elapsed_time = ntohs(opt_val2);
+                       } else {
+                               opt_val = get_unaligned((__be32 *)value);
+                               elapsed_time = ntohl(opt_val);
+                       }
 
                        if (elapsed_time > opt_recv->dccpor_elapsed_time)
                                opt_recv->dccpor_elapsed_time = elapsed_time;
index cc9bf1c..d849739 100644 (file)
@@ -26,6 +26,7 @@
 #include <net/sock.h>
 #include <net/xfrm.h>
 
+#include <asm/ioctls.h>
 #include <asm/semaphore.h>
 #include <linux/spinlock.h>
 #include <linux/timer.h>
@@ -378,8 +379,36 @@ EXPORT_SYMBOL_GPL(dccp_poll);
 
 int dccp_ioctl(struct sock *sk, int cmd, unsigned long arg)
 {
-       dccp_pr_debug("entry\n");
-       return -ENOIOCTLCMD;
+       int rc = -ENOTCONN;
+
+       lock_sock(sk);
+
+       if (sk->sk_state == DCCP_LISTEN)
+               goto out;
+
+       switch (cmd) {
+       case SIOCINQ: {
+               struct sk_buff *skb;
+               unsigned long amount = 0;
+
+               skb = skb_peek(&sk->sk_receive_queue);
+               if (skb != NULL) {
+                       /*
+                        * We will only return the amount of this packet since
+                        * that is all that will be read.
+                        */
+                       amount = skb->len;
+               }
+               rc = put_user(amount, (int __user *)arg);
+       }
+               break;
+       default:
+               rc = -ENOIOCTLCMD;
+               break;
+       }
+out:
+       release_sock(sk);
+       return rc;
 }
 
 EXPORT_SYMBOL_GPL(dccp_ioctl);
index ed8a3d4..6b2e454 100644 (file)
@@ -298,6 +298,14 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
+static int eth_validate_addr(struct net_device *dev)
+{
+       if (!is_valid_ether_addr(dev->dev_addr))
+               return -EINVAL;
+
+       return 0;
+}
+
 const struct header_ops eth_header_ops ____cacheline_aligned = {
        .create         = eth_header,
        .parse          = eth_header_parse,
@@ -317,6 +325,7 @@ void ether_setup(struct net_device *dev)
 
        dev->change_mtu         = eth_change_mtu;
        dev->set_mac_address    = eth_mac_addr;
+       dev->validate_addr      = eth_validate_addr;
 
        dev->type               = ARPHRD_ETHER;
        dev->hard_header_len    = ETH_HLEN;
index 8117776..4cce353 100644 (file)
@@ -25,7 +25,7 @@
 #include <net/ieee80211.h>
 
 #include <linux/crypto.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
@@ -537,13 +537,8 @@ static int michael_mic(struct crypto_hash *tfm_michael, u8 * key, u8 * hdr,
                return -1;
        }
        sg_init_table(sg, 2);
-       sg_set_page(&sg[0], virt_to_page(hdr));
-       sg[0].offset = offset_in_page(hdr);
-       sg[0].length = 16;
-
-       sg_set_page(&sg[1], virt_to_page(data));
-       sg[1].offset = offset_in_page(data);
-       sg[1].length = data_len;
+       sg_set_buf(&sg[0], hdr, 16);
+       sg_set_buf(&sg[1], data, data_len);
 
        if (crypto_hash_setkey(tfm_michael, key, 8))
                return -1;
index 9693429..866fc04 100644 (file)
@@ -22,7 +22,7 @@
 #include <net/ieee80211.h>
 
 #include <linux/crypto.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crc32.h>
 
 MODULE_AUTHOR("Jouni Malinen");
index 805a78e..f18e88b 100644 (file)
@@ -504,22 +504,16 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def)
        INIT_RCU_HEAD(&doi_def->rcu);
        INIT_LIST_HEAD(&doi_def->dom_list);
 
-       rcu_read_lock();
-       if (cipso_v4_doi_search(doi_def->doi) != NULL)
-               goto doi_add_failure_rlock;
        spin_lock(&cipso_v4_doi_list_lock);
        if (cipso_v4_doi_search(doi_def->doi) != NULL)
-               goto doi_add_failure_slock;
+               goto doi_add_failure;
        list_add_tail_rcu(&doi_def->list, &cipso_v4_doi_list);
        spin_unlock(&cipso_v4_doi_list_lock);
-       rcu_read_unlock();
 
        return 0;
 
-doi_add_failure_slock:
+doi_add_failure:
        spin_unlock(&cipso_v4_doi_list_lock);
-doi_add_failure_rlock:
-       rcu_read_unlock();
        return -EEXIST;
 }
 
@@ -543,29 +537,23 @@ int cipso_v4_doi_remove(u32 doi,
        struct cipso_v4_doi *doi_def;
        struct cipso_v4_domhsh_entry *dom_iter;
 
-       rcu_read_lock();
-       if (cipso_v4_doi_search(doi) != NULL) {
-               spin_lock(&cipso_v4_doi_list_lock);
-               doi_def = cipso_v4_doi_search(doi);
-               if (doi_def == NULL) {
-                       spin_unlock(&cipso_v4_doi_list_lock);
-                       rcu_read_unlock();
-                       return -ENOENT;
-               }
+       spin_lock(&cipso_v4_doi_list_lock);
+       doi_def = cipso_v4_doi_search(doi);
+       if (doi_def != NULL) {
                doi_def->valid = 0;
                list_del_rcu(&doi_def->list);
                spin_unlock(&cipso_v4_doi_list_lock);
+               rcu_read_lock();
                list_for_each_entry_rcu(dom_iter, &doi_def->dom_list, list)
                        if (dom_iter->valid)
                                netlbl_domhsh_remove(dom_iter->domain,
                                                     audit_info);
-               cipso_v4_cache_invalidate();
                rcu_read_unlock();
-
+               cipso_v4_cache_invalidate();
                call_rcu(&doi_def->rcu, callback);
                return 0;
        }
-       rcu_read_unlock();
+       spin_unlock(&cipso_v4_doi_list_lock);
 
        return -ENOENT;
 }
@@ -653,22 +641,19 @@ int cipso_v4_doi_domhsh_add(struct cipso_v4_doi *doi_def, const char *domain)
        new_dom->valid = 1;
        INIT_RCU_HEAD(&new_dom->rcu);
 
-       rcu_read_lock();
        spin_lock(&cipso_v4_doi_list_lock);
-       list_for_each_entry_rcu(iter, &doi_def->dom_list, list)
+       list_for_each_entry(iter, &doi_def->dom_list, list)
                if (iter->valid &&
                    ((domain != NULL && iter->domain != NULL &&
                      strcmp(iter->domain, domain) == 0) ||
                     (domain == NULL && iter->domain == NULL))) {
                        spin_unlock(&cipso_v4_doi_list_lock);
-                       rcu_read_unlock();
                        kfree(new_dom->domain);
                        kfree(new_dom);
                        return -EEXIST;
                }
        list_add_tail_rcu(&new_dom->list, &doi_def->dom_list);
        spin_unlock(&cipso_v4_doi_list_lock);
-       rcu_read_unlock();
 
        return 0;
 }
@@ -689,9 +674,8 @@ int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
 {
        struct cipso_v4_domhsh_entry *iter;
 
-       rcu_read_lock();
        spin_lock(&cipso_v4_doi_list_lock);
-       list_for_each_entry_rcu(iter, &doi_def->dom_list, list)
+       list_for_each_entry(iter, &doi_def->dom_list, list)
                if (iter->valid &&
                    ((domain != NULL && iter->domain != NULL &&
                      strcmp(iter->domain, domain) == 0) ||
@@ -699,13 +683,10 @@ int cipso_v4_doi_domhsh_remove(struct cipso_v4_doi *doi_def,
                        iter->valid = 0;
                        list_del_rcu(&iter->list);
                        spin_unlock(&cipso_v4_doi_list_lock);
-                       rcu_read_unlock();
                        call_rcu(&iter->rcu, cipso_v4_doi_domhsh_free);
-
                        return 0;
                }
        spin_unlock(&cipso_v4_doi_list_lock);
-       rcu_read_unlock();
 
        return -ENOENT;
 }
index 6b1a31a..cad4278 100644 (file)
@@ -3,7 +3,7 @@
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/esp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crypto.h>
 #include <linux/kernel.h>
 #include <linux/pfkeyv2.h>
@@ -110,7 +110,10 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
                        if (!sg)
                                goto unlock;
                }
-               skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
+               sg_init_table(sg, nfrags);
+               sg_mark_end(sg, skb_to_sgvec(skb, sg, esph->enc_data +
+                                                     esp->conf.ivlen -
+                                                     skb->data, clen));
                err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
                if (unlikely(sg != &esp->sgbuf[0]))
                        kfree(sg);
@@ -201,7 +204,9 @@ static int esp_input(struct xfrm_state *x, struct sk_buff *skb)
                if (!sg)
                        goto out;
        }
-       skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen);
+       sg_init_table(sg, nfrags);
+       sg_mark_end(sg, skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen,
+                                    elen));
        err = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
        if (unlikely(sg != &esp->sgbuf[0]))
                kfree(sg);
index 78b514b..6012390 100644 (file)
@@ -128,13 +128,14 @@ struct net_device * ip_dev_find(__be32 addr)
        struct flowi fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
        struct fib_result res;
        struct net_device *dev = NULL;
+       struct fib_table *local_table;
 
 #ifdef CONFIG_IP_MULTIPLE_TABLES
        res.r = NULL;
 #endif
 
-       if (!ip_fib_local_table ||
-           ip_fib_local_table->tb_lookup(ip_fib_local_table, &fl, &res))
+       local_table = fib_get_table(RT_TABLE_LOCAL);
+       if (!local_table || local_table->tb_lookup(local_table, &fl, &res))
                return NULL;
        if (res.type != RTN_LOCAL)
                goto out;
@@ -152,6 +153,7 @@ unsigned inet_addr_type(__be32 addr)
        struct flowi            fl = { .nl_u = { .ip4_u = { .daddr = addr } } };
        struct fib_result       res;
        unsigned ret = RTN_BROADCAST;
+       struct fib_table *local_table;
 
        if (ZERONET(addr) || BADCLASS(addr))
                return RTN_BROADCAST;
@@ -162,10 +164,10 @@ unsigned inet_addr_type(__be32 addr)
        res.r = NULL;
 #endif
 
-       if (ip_fib_local_table) {
+       local_table = fib_get_table(RT_TABLE_LOCAL);
+       if (local_table) {
                ret = RTN_UNICAST;
-               if (!ip_fib_local_table->tb_lookup(ip_fib_local_table,
-                                                  &fl, &res)) {
+               if (!local_table->tb_lookup(local_table, &fl, &res)) {
                        ret = res.type;
                        fib_res_put(&res);
                }
index 272c69e..233de06 100644 (file)
@@ -1104,5 +1104,4 @@ void __init icmp_init(struct net_proto_family *ops)
 EXPORT_SYMBOL(icmp_err_convert);
 EXPORT_SYMBOL(icmp_send);
 EXPORT_SYMBOL(icmp_statistics);
-EXPORT_SYMBOL(icmpmsg_statistics);
 EXPORT_SYMBOL(xrlim_allow);
index f151900..02b02a8 100644 (file)
@@ -674,7 +674,7 @@ static int ipgre_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        struct rtable *rt;                      /* Route to the other host */
        struct net_device *tdev;                        /* Device to other host */
        struct iphdr  *iph;                     /* Our new IP header */
-       int    max_headroom;                    /* The extra header space needed */
+       unsigned int max_headroom;              /* The extra header space needed */
        int    gre_hlen;
        __be32 dst;
        int    mtu;
@@ -1033,7 +1033,6 @@ static int ipgre_tunnel_change_mtu(struct net_device *dev, int new_mtu)
        return 0;
 }
 
-#ifdef CONFIG_NET_IPGRE_BROADCAST
 /* Nice toy. Unfortunately, useless in real life :-)
    It allows to construct virtual multiprotocol broadcast "LAN"
    over the Internet, provided multicast routing is tuned.
@@ -1092,10 +1091,19 @@ static int ipgre_header(struct sk_buff *skb, struct net_device *dev,
        return -t->hlen;
 }
 
+static int ipgre_header_parse(const struct sk_buff *skb, unsigned char *haddr)
+{
+       struct iphdr *iph = (struct iphdr*) skb_mac_header(skb);
+       memcpy(haddr, &iph->saddr, 4);
+       return 4;
+}
+
 static const struct header_ops ipgre_header_ops = {
        .create = ipgre_header,
+       .parse  = ipgre_header_parse,
 };
 
+#ifdef CONFIG_NET_IPGRE_BROADCAST
 static int ipgre_open(struct net_device *dev)
 {
        struct ip_tunnel *t = netdev_priv(dev);
@@ -1197,6 +1205,8 @@ static int ipgre_tunnel_init(struct net_device *dev)
                        dev->stop = ipgre_close;
                }
 #endif
+       } else {
+               dev->header_ops = &ipgre_header_ops;
        }
 
        if (!tdev && tunnel->parms.link)
index f508835..e5f7dc2 100644 (file)
@@ -161,7 +161,7 @@ static inline int ip_finish_output2(struct sk_buff *skb)
        struct dst_entry *dst = skb->dst;
        struct rtable *rt = (struct rtable *)dst;
        struct net_device *dev = dst->dev;
-       int hh_len = LL_RESERVED_SPACE(dev);
+       unsigned int hh_len = LL_RESERVED_SPACE(dev);
 
        if (rt->rt_type == RTN_MULTICAST)
                IP_INC_STATS(IPSTATS_MIB_OUTMCASTPKTS);
index 5cd5bbe..8c2b2b0 100644 (file)
@@ -515,7 +515,7 @@ static int ipip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        struct net_device *tdev;                        /* Device to other host */
        struct iphdr  *old_iph = ip_hdr(skb);
        struct iphdr  *iph;                     /* Our new IP header */
-       int    max_headroom;                    /* The extra header space needed */
+       unsigned int max_headroom;              /* The extra header space needed */
        __be32 dst = tiph->daddr;
        int    mtu;
 
index d0a92de..7c074e3 100644 (file)
@@ -325,7 +325,7 @@ ip_vs_tunnel_xmit(struct sk_buff *skb, struct ip_vs_conn *cp,
        __be16 df = old_iph->frag_off;
        sk_buff_data_t old_transport_header = skb->transport_header;
        struct iphdr  *iph;                     /* Our new IP header */
-       int    max_headroom;                    /* The extra header space needed */
+       unsigned int max_headroom;              /* The extra header space needed */
        int    mtu;
 
        EnterFunction(10);
index fd16cb8..9be0daa 100644 (file)
@@ -121,14 +121,6 @@ static const struct snmp_mib snmp4_ipextstats_list[] = {
        SNMP_MIB_SENTINEL
 };
 
-static const struct snmp_mib snmp4_icmp_list[] = {
-       SNMP_MIB_ITEM("InMsgs", ICMP_MIB_INMSGS),
-       SNMP_MIB_ITEM("InErrors", ICMP_MIB_INERRORS),
-       SNMP_MIB_ITEM("OutMsgs", ICMP_MIB_OUTMSGS),
-       SNMP_MIB_ITEM("OutErrors", ICMP_MIB_OUTERRORS),
-       SNMP_MIB_SENTINEL
-};
-
 static struct {
        char *name;
        int index;
index 9288220..69d8c38 100644 (file)
@@ -103,7 +103,7 @@ int sysctl_tcp_abc __read_mostly;
 #define FLAG_SLOWPATH          0x100 /* Do not skip RFC checks for window update.*/
 #define FLAG_ONLY_ORIG_SACKED  0x200 /* SACKs only non-rexmit sent before RTO */
 #define FLAG_SND_UNA_ADVANCED  0x400 /* Snd_una was changed (!= FLAG_DATA_ACKED) */
-#define FLAG_DSACKING_ACK      0x800 /* SACK blocks contained DSACK info */
+#define FLAG_DSACKING_ACK      0x800 /* SACK blocks contained D-SACK info */
 #define FLAG_NONHEAD_RETRANS_ACKED     0x1000 /* Non-head rexmitted data was ACKed */
 
 #define FLAG_ACKED             (FLAG_DATA_ACKED|FLAG_SYN_ACKED)
@@ -866,7 +866,7 @@ static void tcp_disable_fack(struct tcp_sock *tp)
        tp->rx_opt.sack_ok &= ~2;
 }
 
-/* Take a notice that peer is sending DSACKs */
+/* Take a notice that peer is sending D-SACKs */
 static void tcp_dsack_seen(struct tcp_sock *tp)
 {
        tp->rx_opt.sack_ok |= 4;
@@ -1058,7 +1058,7 @@ static void tcp_update_reordering(struct sock *sk, const int metric,
  *
  * With D-SACK the lower bound is extended to cover sequence space below
  * SND.UNA down to undo_marker, which is the last point of interest. Yet
- * again, DSACK block must not to go across snd_una (for the same reason as
+ * again, D-SACK block must not to go across snd_una (for the same reason as
  * for the normal SACK blocks, explained above). But there all simplicity
  * ends, TCP might receive valid D-SACKs below that. As long as they reside
  * fully below undo_marker they do not affect behavior in anyway and can
@@ -1080,7 +1080,7 @@ static int tcp_is_sackblock_valid(struct tcp_sock *tp, int is_dsack,
        if (!before(start_seq, tp->snd_nxt))
                return 0;
 
-       /* In outstanding window? ...This is valid exit for DSACKs too.
+       /* In outstanding window? ...This is valid exit for D-SACKs too.
         * start_seq == snd_una is non-sensical (see comments above)
         */
        if (after(start_seq, tp->snd_una))
@@ -1204,8 +1204,8 @@ static int tcp_check_dsack(struct tcp_sock *tp, struct sk_buff *ack_skb,
  * which may fail and creates some hassle (caller must handle error case
  * returns).
  */
-int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
-                         u32 start_seq, u32 end_seq)
+static int tcp_match_skb_to_sack(struct sock *sk, struct sk_buff *skb,
+                                u32 start_seq, u32 end_seq)
 {
        int in_sack, err;
        unsigned int pkt_len;
@@ -1248,6 +1248,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
        int cached_fack_count;
        int i;
        int first_sack_index;
+       int force_one_sack;
 
        if (!tp->sacked_out) {
                if (WARN_ON(tp->fackets_out))
@@ -1272,18 +1273,18 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
         * if the only SACK change is the increase of the end_seq of
         * the first block then only apply that SACK block
         * and use retrans queue hinting otherwise slowpath */
-       flag = 1;
+       force_one_sack = 1;
        for (i = 0; i < num_sacks; i++) {
                __be32 start_seq = sp[i].start_seq;
                __be32 end_seq = sp[i].end_seq;
 
                if (i == 0) {
                        if (tp->recv_sack_cache[i].start_seq != start_seq)
-                               flag = 0;
+                               force_one_sack = 0;
                } else {
                        if ((tp->recv_sack_cache[i].start_seq != start_seq) ||
                            (tp->recv_sack_cache[i].end_seq != end_seq))
-                               flag = 0;
+                               force_one_sack = 0;
                }
                tp->recv_sack_cache[i].start_seq = start_seq;
                tp->recv_sack_cache[i].end_seq = end_seq;
@@ -1295,7 +1296,7 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
        }
 
        first_sack_index = 0;
-       if (flag)
+       if (force_one_sack)
                num_sacks = 1;
        else {
                int j;
@@ -1321,9 +1322,6 @@ tcp_sacktag_write_queue(struct sock *sk, struct sk_buff *ack_skb, u32 prior_snd_
                }
        }
 
-       /* clear flag as used for different purpose in following code */
-       flag = 0;
-
        /* Use SACK fastpath hint if valid */
        cached_skb = tp->fastpath_skb_hint;
        cached_fack_count = tp->fastpath_cnt_hint;
@@ -1615,7 +1613,7 @@ void tcp_enter_frto(struct sock *sk)
             !icsk->icsk_retransmits)) {
                tp->prior_ssthresh = tcp_current_ssthresh(sk);
                /* Our state is too optimistic in ssthresh() call because cwnd
-                * is not reduced until tcp_enter_frto_loss() when previous FRTO
+                * is not reduced until tcp_enter_frto_loss() when previous F-RTO
                 * recovery has not yet completed. Pattern would be this: RTO,
                 * Cumulative ACK, RTO (2xRTO for the same segment does not end
                 * up here twice).
@@ -1801,7 +1799,7 @@ void tcp_enter_loss(struct sock *sk, int how)
        tcp_set_ca_state(sk, TCP_CA_Loss);
        tp->high_seq = tp->snd_nxt;
        TCP_ECN_queue_cwr(tp);
-       /* Abort FRTO algorithm if one is in progress */
+       /* Abort F-RTO algorithm if one is in progress */
        tp->frto_counter = 0;
 }
 
@@ -1946,7 +1944,7 @@ static int tcp_time_to_recover(struct sock *sk)
        struct tcp_sock *tp = tcp_sk(sk);
        __u32 packets_out;
 
-       /* Do not perform any recovery during FRTO algorithm */
+       /* Do not perform any recovery during F-RTO algorithm */
        if (tp->frto_counter)
                return 0;
 
@@ -2962,7 +2960,7 @@ static int tcp_process_frto(struct sock *sk, int flag)
        }
 
        if (tp->frto_counter == 1) {
-               /* Sending of the next skb must be allowed or no FRTO */
+               /* Sending of the next skb must be allowed or no F-RTO */
                if (!tcp_send_head(sk) ||
                    after(TCP_SKB_CB(tcp_send_head(sk))->end_seq,
                                     tp->snd_una + tp->snd_wnd)) {
@@ -3909,7 +3907,7 @@ tcp_collapse(struct sock *sk, struct sk_buff_head *list,
 
        while (before(start, end)) {
                struct sk_buff *nskb;
-               int header = skb_headroom(skb);
+               unsigned int header = skb_headroom(skb);
                int copy = SKB_MAX_ORDER(header, 0);
 
                /* Too big header? This can happen with IPv6. */
index 38cf73a..ad759f1 100644 (file)
@@ -1055,6 +1055,9 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
        bp->pad = 0;
        bp->protocol = protocol;
        bp->len = htons(tcplen);
+
+       sg_init_table(sg, 4);
+
        sg_set_buf(&sg[block++], bp, sizeof(*bp));
        nbytes += sizeof(*bp);
 
@@ -1080,6 +1083,8 @@ static int tcp_v4_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
        sg_set_buf(&sg[block++], key->key, key->keylen);
        nbytes += key->keylen;
 
+       sg_mark_end(sg, block);
+
        /* Now store the Hash into the packet */
        err = crypto_hash_init(desc);
        if (err)
index 35d2b0e..4bc25b4 100644 (file)
@@ -1152,7 +1152,7 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct hlist_head udptable[],
                return __udp4_lib_mcast_deliver(skb, uh, saddr, daddr, udptable);
 
        sk = __udp4_lib_lookup(saddr, uh->source, daddr, uh->dest,
-                              skb->dev->ifindex, udptable        );
+                              inet_iif(skb), udptable);
 
        if (sk != NULL) {
                int ret = udp_queue_rcv_skb(sk, skb);
index 72a6598..ab17b5e 100644 (file)
@@ -29,7 +29,7 @@
 #include <net/ip.h>
 #include <net/xfrm.h>
 #include <net/esp.h>
-#include <asm/scatterlist.h>
+#include <linux/scatterlist.h>
 #include <linux/crypto.h>
 #include <linux/kernel.h>
 #include <linux/pfkeyv2.h>
@@ -109,7 +109,10 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb)
                        if (!sg)
                                goto unlock;
                }
-               skb_to_sgvec(skb, sg, esph->enc_data+esp->conf.ivlen-skb->data, clen);
+               sg_init_table(sg, nfrags);
+               sg_mark_end(sg, skb_to_sgvec(skb, sg, esph->enc_data +
+                                                     esp->conf.ivlen -
+                                                     skb->data, clen));
                err = crypto_blkcipher_encrypt(&desc, sg, sg, clen);
                if (unlikely(sg != &esp->sgbuf[0]))
                        kfree(sg);
@@ -205,7 +208,10 @@ static int esp6_input(struct xfrm_state *x, struct sk_buff *skb)
                                goto out;
                        }
                }
-               skb_to_sgvec(skb, sg, sizeof(*esph) + esp->conf.ivlen, elen);
+               sg_init_table(sg, nfrags);
+               sg_mark_end(sg, skb_to_sgvec(skb, sg,
+                                            sizeof(*esph) + esp->conf.ivlen,
+                                            elen));
                ret = crypto_blkcipher_decrypt(&desc, sg, sg, elen);
                if (unlikely(sg != &esp->sgbuf[0]))
                        kfree(sg);
index 13565df..653fc0a 100644 (file)
@@ -171,7 +171,7 @@ int ip6_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
        u32 mtu;
 
        if (opt) {
-               int head_room;
+               unsigned int head_room;
 
                /* First: exthdrs may take lots of space (~8K for now)
                   MAX_HEADER is not enough.
index 2320cc2..5383b33 100644 (file)
@@ -838,7 +838,7 @@ static int ip6_tnl_xmit2(struct sk_buff *skb,
        struct dst_entry *dst;
        struct net_device *tdev;
        int mtu;
-       int max_headroom = sizeof(struct ipv6hdr);
+       unsigned int max_headroom = sizeof(struct ipv6hdr);
        u8 proto;
        int err = -1;
        int pkt_len;
index 466657a..71433d2 100644 (file)
@@ -430,7 +430,7 @@ static int ipip6_tunnel_xmit(struct sk_buff *skb, struct net_device *dev)
        struct rtable *rt;                      /* Route to the other host */
        struct net_device *tdev;                        /* Device to other host */
        struct iphdr  *iph;                     /* Our new IP header */
-       int    max_headroom;                    /* The extra header space needed */
+       unsigned int max_headroom;              /* The extra header space needed */
        __be32 dst = tiph->daddr;
        int    mtu;
        struct in6_addr *addr6;
index 737b755..8520802 100644 (file)
@@ -59,6 +59,7 @@
 #include <net/snmp.h>
 #include <net/dsfield.h>
 #include <net/timewait_sock.h>
+#include <net/netdma.h>
 
 #include <asm/uaccess.h>
 
@@ -757,6 +758,8 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
        bp->len = htonl(tcplen);
        bp->protocol = htonl(protocol);
 
+       sg_init_table(sg, 4);
+
        sg_set_buf(&sg[block++], bp, sizeof(*bp));
        nbytes += sizeof(*bp);
 
@@ -778,6 +781,8 @@ static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
        sg_set_buf(&sg[block++], key->key, key->keylen);
        nbytes += key->keylen;
 
+       sg_mark_end(sg, block);
+
        /* Now store the hash into the packet */
        err = crypto_hash_init(desc);
        if (err) {
@@ -1728,6 +1733,8 @@ process:
        if (!sock_owned_by_user(sk)) {
 #ifdef CONFIG_NET_DMA
                struct tcp_sock *tp = tcp_sk(sk);
+               if (!tp->ucopy.dma_chan && tp->ucopy.pinned_list)
+                       tp->ucopy.dma_chan = get_softnet_dma();
                if (tp->ucopy.dma_chan)
                        ret = tcp_v6_do_rcv(sk, skb);
                else
index 3d241e4..1120b15 100644 (file)
@@ -77,7 +77,7 @@ static int ircomm_tty_read_proc(char *buf, char **start, off_t offset, int len,
 #endif /* CONFIG_PROC_FS */
 static struct tty_driver *driver;
 
-hashbin_t *ircomm_tty = NULL;
+static hashbin_t *ircomm_tty = NULL;
 
 static const struct tty_operations ops = {
        .open            = ircomm_tty_open,
index f7ffeec..fda0e06 100644 (file)
@@ -1184,7 +1184,7 @@ static void ieee80211_rx_mgmt_assoc_resp(struct net_device *dev,
        printk(KERN_DEBUG "%s: RX %sssocResp from %s (capab=0x%x "
               "status=%d aid=%d)\n",
               dev->name, reassoc ? "Rea" : "A", print_mac(mac, mgmt->sa),
-              capab_info, status_code, aid & ~(BIT(15) | BIT(14)));
+              capab_info, status_code, (u16)(aid & ~(BIT(15) | BIT(14))));
 
        if (status_code != WLAN_STATUS_SUCCESS) {
                printk(KERN_DEBUG "%s: AP denied association (code=%d)\n",
@@ -2096,7 +2096,8 @@ static int ieee80211_sta_match_ssid(struct ieee80211_if_sta *ifsta,
 {
        int tmp, hidden_ssid;
 
-       if (!memcmp(ifsta->ssid, ssid, ssid_len))
+       if (ssid_len == ifsta->ssid_len &&
+           !memcmp(ifsta->ssid, ssid, ssid_len))
                return 1;
 
        if (ifsta->flags & IEEE80211_STA_AUTO_BSSID_SEL)
index b6c844b..b3675bd 100644 (file)
@@ -178,11 +178,9 @@ int netlbl_domhsh_init(u32 size)
        for (iter = 0; iter < hsh_tbl->size; iter++)
                INIT_LIST_HEAD(&hsh_tbl->tbl[iter]);
 
-       rcu_read_lock();
        spin_lock(&netlbl_domhsh_lock);
        rcu_assign_pointer(netlbl_domhsh, hsh_tbl);
        spin_unlock(&netlbl_domhsh_lock);
-       rcu_read_unlock();
 
        return 0;
 }
@@ -222,7 +220,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
        entry->valid = 1;
        INIT_RCU_HEAD(&entry->rcu);
 
-       ret_val = 0;
        rcu_read_lock();
        if (entry->domain != NULL) {
                bkt = netlbl_domhsh_hash(entry->domain);
@@ -233,7 +230,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
                else
                        ret_val = -EEXIST;
                spin_unlock(&netlbl_domhsh_lock);
-       } else if (entry->domain == NULL) {
+       } else {
                INIT_LIST_HEAD(&entry->list);
                spin_lock(&netlbl_domhsh_def_lock);
                if (rcu_dereference(netlbl_domhsh_def) == NULL)
@@ -241,9 +238,7 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
                else
                        ret_val = -EEXIST;
                spin_unlock(&netlbl_domhsh_def_lock);
-       } else
-               ret_val = -EINVAL;
-
+       }
        audit_buf = netlbl_audit_start_common(AUDIT_MAC_MAP_ADD, audit_info);
        if (audit_buf != NULL) {
                audit_log_format(audit_buf,
@@ -262,7 +257,6 @@ int netlbl_domhsh_add(struct netlbl_dom_map *entry,
                audit_log_format(audit_buf, " res=%u", ret_val == 0 ? 1 : 0);
                audit_log_end(audit_buf);
        }
-
        rcu_read_unlock();
 
        if (ret_val != 0) {
@@ -313,38 +307,30 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
        struct audit_buffer *audit_buf;
 
        rcu_read_lock();
-       if (domain != NULL)
-               entry = netlbl_domhsh_search(domain, 0);
-       else
-               entry = netlbl_domhsh_search(domain, 1);
+       entry = netlbl_domhsh_search(domain, (domain != NULL ? 0 : 1));
        if (entry == NULL)
                goto remove_return;
        switch (entry->type) {
-       case NETLBL_NLTYPE_UNLABELED:
-               break;
        case NETLBL_NLTYPE_CIPSOV4:
-               ret_val = cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4,
-                                                    entry->domain);
-               if (ret_val != 0)
-                       goto remove_return;
+               cipso_v4_doi_domhsh_remove(entry->type_def.cipsov4,
+                                          entry->domain);
                break;
        }
-       ret_val = 0;
        if (entry != rcu_dereference(netlbl_domhsh_def)) {
                spin_lock(&netlbl_domhsh_lock);
                if (entry->valid) {
                        entry->valid = 0;
                        list_del_rcu(&entry->list);
-               } else
-                       ret_val = -ENOENT;
+                       ret_val = 0;
+               }
                spin_unlock(&netlbl_domhsh_lock);
        } else {
                spin_lock(&netlbl_domhsh_def_lock);
                if (entry->valid) {
                        entry->valid = 0;
                        rcu_assign_pointer(netlbl_domhsh_def, NULL);
-               } else
-                       ret_val = -ENOENT;
+                       ret_val = 0;
+               }
                spin_unlock(&netlbl_domhsh_def_lock);
        }
 
@@ -357,11 +343,10 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info)
                audit_log_end(audit_buf);
        }
 
-       if (ret_val == 0)
-               call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
-
 remove_return:
        rcu_read_unlock();
+       if (ret_val == 0)
+               call_rcu(&entry->rcu, netlbl_domhsh_free_entry);
        return ret_val;
 }
 
index 5315dac..5648337 100644 (file)
@@ -85,11 +85,9 @@ static const struct nla_policy netlbl_mgmt_genl_policy[NLBL_MGMT_A_MAX + 1] = {
  */
 void netlbl_mgmt_protocount_inc(void)
 {
-       rcu_read_lock();
        spin_lock(&netlabel_mgmt_protocount_lock);
        netlabel_mgmt_protocount++;
        spin_unlock(&netlabel_mgmt_protocount_lock);
-       rcu_read_unlock();
 }
 
 /**
@@ -103,12 +101,10 @@ void netlbl_mgmt_protocount_inc(void)
  */
 void netlbl_mgmt_protocount_dec(void)
 {
-       rcu_read_lock();
        spin_lock(&netlabel_mgmt_protocount_lock);
        if (netlabel_mgmt_protocount > 0)
                netlabel_mgmt_protocount--;
        spin_unlock(&netlabel_mgmt_protocount_lock);
-       rcu_read_unlock();
 }
 
 /**
index 5c303c6..3482924 100644 (file)
@@ -84,12 +84,10 @@ static void netlbl_unlabel_acceptflg_set(u8 value,
        struct audit_buffer *audit_buf;
        u8 old_val;
 
-       rcu_read_lock();
-       old_val = netlabel_unlabel_acceptflg;
        spin_lock(&netlabel_unlabel_acceptflg_lock);
+       old_val = netlabel_unlabel_acceptflg;
        netlabel_unlabel_acceptflg = value;
        spin_unlock(&netlabel_unlabel_acceptflg_lock);
-       rcu_read_unlock();
 
        audit_buf = netlbl_audit_start_common(AUDIT_MAC_UNLBL_ALLOW,
                                              audit_info);
index 98e313e..4f994c0 100644 (file)
@@ -1565,7 +1565,11 @@ int netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
 
        netlink_dump(sk);
        sock_put(sk);
-       return 0;
+
+       /* We successfully started a dump, by returning -EINTR we
+        * signal not to send ACK even if it was requested.
+        */
+       return -EINTR;
 }
 
 void netlink_ack(struct sk_buff *in_skb, struct nlmsghdr *nlh, int err)
@@ -1619,17 +1623,21 @@ int netlink_rcv_skb(struct sk_buff *skb, int (*cb)(struct sk_buff *,
 
                /* Only requests are handled by the kernel */
                if (!(nlh->nlmsg_flags & NLM_F_REQUEST))
-                       goto skip;
+                       goto ack;
 
                /* Skip control messages */
                if (nlh->nlmsg_type < NLMSG_MIN_TYPE)
-                       goto skip;
+                       goto ack;
 
                err = cb(skb, nlh);
-skip:
+               if (err == -EINTR)
+                       goto skip;
+
+ack:
                if (nlh->nlmsg_flags & NLM_F_ACK || err)
                        netlink_ack(skb, nlh, err);
 
+skip:
                msglen = NLMSG_ALIGN(nlh->nlmsg_len);
                if (msglen > skb->len)
                        msglen = skb->len;
@@ -1880,7 +1888,7 @@ static void __net_exit netlink_net_exit(struct net *net)
 #endif
 }
 
-static struct pernet_operations __net_initdata netlink_net_ops = {
+static struct pernet_operations netlink_net_ops = {
        .init = netlink_net_init,
        .exit = netlink_net_exit,
 };
index ac3cabd..eebefb6 100644 (file)
@@ -135,9 +135,8 @@ static void rxkad_prime_packet_security(struct rxrpc_connection *conn)
        tmpbuf.x[2] = 0;
        tmpbuf.x[3] = htonl(conn->security_ix);
 
-       memset(sg, 0, sizeof(sg));
-       sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf));
-       sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf));
+       sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf));
+       sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf));
        crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
        memcpy(&conn->csum_iv, &tmpbuf.x[2], sizeof(conn->csum_iv));
@@ -180,9 +179,8 @@ static int rxkad_secure_packet_auth(const struct rxrpc_call *call,
        desc.info = iv.x;
        desc.flags = 0;
 
-       memset(sg, 0, sizeof(sg));
-       sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf));
-       sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf));
+       sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf));
+       sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf));
        crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
        memcpy(sechdr, &tmpbuf, sizeof(tmpbuf));
@@ -227,9 +225,8 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
        desc.info = iv.x;
        desc.flags = 0;
 
-       memset(sg, 0, sizeof(sg[0]) * 2);
-       sg_set_buf(&sg[0], sechdr, sizeof(rxkhdr));
-       sg_set_buf(&sg[1], &rxkhdr, sizeof(rxkhdr));
+       sg_init_one(&sg[0], sechdr, sizeof(rxkhdr));
+       sg_init_one(&sg[1], &rxkhdr, sizeof(rxkhdr));
        crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(rxkhdr));
 
        /* we want to encrypt the skbuff in-place */
@@ -240,7 +237,7 @@ static int rxkad_secure_packet_encrypt(const struct rxrpc_call *call,
        len = data_size + call->conn->size_align - 1;
        len &= ~(call->conn->size_align - 1);
 
-       skb_to_sgvec(skb, sg, 0, len);
+       sg_init_table(sg, skb_to_sgvec(skb, sg, 0, len));
        crypto_blkcipher_encrypt_iv(&desc, sg, sg, len);
 
        _leave(" = 0");
@@ -290,9 +287,8 @@ static int rxkad_secure_packet(const struct rxrpc_call *call,
        tmpbuf.x[0] = sp->hdr.callNumber;
        tmpbuf.x[1] = x;
 
-       memset(&sg, 0, sizeof(sg));
-       sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf));
-       sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf));
+       sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf));
+       sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf));
        crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
        x = ntohl(tmpbuf.x[1]);
@@ -332,20 +328,23 @@ static int rxkad_verify_packet_auth(const struct rxrpc_call *call,
        struct rxrpc_skb_priv *sp;
        struct blkcipher_desc desc;
        struct rxrpc_crypt iv;
-       struct scatterlist sg[2];
+       struct scatterlist sg[16];
        struct sk_buff *trailer;
        u32 data_size, buf;
        u16 check;
+       int nsg;
 
        _enter("");
 
        sp = rxrpc_skb(skb);
 
        /* we want to decrypt the skbuff in-place */
-       if (skb_cow_data(skb, 0, &trailer) < 0)
+       nsg = skb_cow_data(skb, 0, &trailer);
+       if (nsg < 0 || nsg > 16)
                goto nomem;
 
-       skb_to_sgvec(skb, sg, 0, 8);
+       sg_init_table(sg, nsg);
+       sg_mark_end(sg, skb_to_sgvec(skb, sg, 0, 8));
 
        /* start the decryption afresh */
        memset(&iv, 0, sizeof(iv));
@@ -426,7 +425,8 @@ static int rxkad_verify_packet_encrypt(const struct rxrpc_call *call,
                        goto nomem;
        }
 
-       skb_to_sgvec(skb, sg, 0, skb->len);
+       sg_init_table(sg, nsg);
+       sg_mark_end(sg, skb_to_sgvec(skb, sg, 0, skb->len));
 
        /* decrypt from the session key */
        payload = call->conn->key->payload.data;
@@ -521,9 +521,8 @@ static int rxkad_verify_packet(const struct rxrpc_call *call,
        tmpbuf.x[0] = call->call_id;
        tmpbuf.x[1] = x;
 
-       memset(&sg, 0, sizeof(sg));
-       sg_set_buf(&sg[0], &tmpbuf, sizeof(tmpbuf));
-       sg_set_buf(&sg[1], &tmpbuf, sizeof(tmpbuf));
+       sg_init_one(&sg[0], &tmpbuf, sizeof(tmpbuf));
+       sg_init_one(&sg[1], &tmpbuf, sizeof(tmpbuf));
        crypto_blkcipher_encrypt_iv(&desc, &sg[0], &sg[1], sizeof(tmpbuf));
 
        x = ntohl(tmpbuf.x[1]);
@@ -690,16 +689,20 @@ static void rxkad_calc_response_checksum(struct rxkad_response *response)
 static void rxkad_sg_set_buf2(struct scatterlist sg[2],
                              void *buf, size_t buflen)
 {
+       int nsg = 1;
 
-       memset(sg, 0, sizeof(sg));
+       sg_init_table(sg, 2);
 
        sg_set_buf(&sg[0], buf, buflen);
        if (sg[0].offset + buflen > PAGE_SIZE) {
                /* the buffer was split over two pages */
                sg[0].length = PAGE_SIZE - sg[0].offset;
                sg_set_buf(&sg[1], buf + sg[0].length, buflen - sg[0].length);
+               nsg++;
        }
 
+       sg_mark_end(sg, nsg);
+
        ASSERTCMP(sg[0].length + sg[1].length, ==, buflen);
 }
 
@@ -712,7 +715,7 @@ static void rxkad_encrypt_response(struct rxrpc_connection *conn,
 {
        struct blkcipher_desc desc;
        struct rxrpc_crypt iv;
-       struct scatterlist ssg[2], dsg[2];
+       struct scatterlist sg[2];
 
        /* continue encrypting from where we left off */
        memcpy(&iv, s2->session_key, sizeof(iv));
@@ -720,9 +723,8 @@ static void rxkad_encrypt_response(struct rxrpc_connection *conn,
        desc.info = iv.x;
        desc.flags = 0;
 
-       rxkad_sg_set_buf2(ssg, &resp->encrypted, sizeof(resp->encrypted));
-       memcpy(dsg, ssg, sizeof(dsg));
-       crypto_blkcipher_encrypt_iv(&desc, dsg, ssg, sizeof(resp->encrypted));
+       rxkad_sg_set_buf2(sg, &resp->encrypted, sizeof(resp->encrypted));
+       crypto_blkcipher_encrypt_iv(&desc, sg, sg, sizeof(resp->encrypted));
 }
 
 /*
@@ -817,7 +819,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
 {
        struct blkcipher_desc desc;
        struct rxrpc_crypt iv, key;
-       struct scatterlist ssg[1], dsg[1];
+       struct scatterlist sg[1];
        struct in_addr addr;
        unsigned life;
        time_t issue, now;
@@ -850,9 +852,8 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
        desc.info = iv.x;
        desc.flags = 0;
 
-       sg_init_one(&ssg[0], ticket, ticket_len);
-       memcpy(dsg, ssg, sizeof(dsg));
-       crypto_blkcipher_decrypt_iv(&desc, dsg, ssg, ticket_len);
+       sg_init_one(&sg[0], ticket, ticket_len);
+       crypto_blkcipher_decrypt_iv(&desc, sg, sg, ticket_len);
 
        p = ticket;
        end = p + ticket_len;
@@ -961,7 +962,7 @@ static void rxkad_decrypt_response(struct rxrpc_connection *conn,
                                   const struct rxrpc_crypt *session_key)
 {
        struct blkcipher_desc desc;
-       struct scatterlist ssg[2], dsg[2];
+       struct scatterlist sg[2];
        struct rxrpc_crypt iv;
 
        _enter(",,%08x%08x",
@@ -979,9 +980,8 @@ static void rxkad_decrypt_response(struct rxrpc_connection *conn,
        desc.info = iv.x;
        desc.flags = 0;
 
-       rxkad_sg_set_buf2(ssg, &resp->encrypted, sizeof(resp->encrypted));
-       memcpy(dsg, ssg, sizeof(dsg));
-       crypto_blkcipher_decrypt_iv(&desc, dsg, ssg, sizeof(resp->encrypted));
+       rxkad_sg_set_buf2(sg, &resp->encrypted, sizeof(resp->encrypted));
+       crypto_blkcipher_decrypt_iv(&desc, sg, sg, sizeof(resp->encrypted));
        mutex_unlock(&rxkad_ci_mutex);
 
        _leave("");
index fd7bca4..c3fde91 100644 (file)
@@ -166,7 +166,7 @@ bad_mirred:
                return TC_ACT_SHOT;
        }
 
-       skb2 = skb_clone(skb, GFP_ATOMIC);
+       skb2 = skb_act_clone(skb, GFP_ATOMIC);
        if (skb2 == NULL)
                goto bad_mirred;
        if (m->tcfm_eaction != TCA_EGRESS_MIRROR &&
index abd82fc..de89409 100644 (file)
@@ -136,7 +136,7 @@ prio_dequeue(struct Qdisc* sch)
                 * pulling an skb.  This way we avoid excessive requeues
                 * for slower queues.
                 */
-               if (!netif_subqueue_stopped(sch->dev, (q->mq ? prio : 0))) {
+               if (!__netif_subqueue_stopped(sch->dev, (q->mq ? prio : 0))) {
                        qdisc = q->queues[prio];
                        skb = qdisc->dequeue(qdisc);
                        if (skb) {
@@ -165,7 +165,7 @@ static struct sk_buff *rr_dequeue(struct Qdisc* sch)
                 * for slower queues.  If the queue is stopped, try the
                 * next queue.
                 */
-               if (!netif_subqueue_stopped(sch->dev,
+               if (!__netif_subqueue_stopped(sch->dev,
                                            (q->mq ? q->curband : 0))) {
                        qdisc = q->queues[q->curband];
                        skb = qdisc->dequeue(qdisc);
index cbd64b2..6d5fa6b 100644 (file)
@@ -107,7 +107,7 @@ struct sctp_shared_key *sctp_auth_shkey_create(__u16 key_id, gfp_t gfp)
 }
 
 /* Free the shared key stucture */
-void sctp_auth_shkey_free(struct sctp_shared_key *sh_key)
+static void sctp_auth_shkey_free(struct sctp_shared_key *sh_key)
 {
        BUG_ON(!list_empty(&sh_key->key_list));
        sctp_auth_key_put(sh_key->key);
@@ -220,7 +220,7 @@ static struct sctp_auth_bytes *sctp_auth_make_key_vector(
 
 
 /* Make a key vector based on our local parameters */
-struct sctp_auth_bytes *sctp_auth_make_local_vector(
+static struct sctp_auth_bytes *sctp_auth_make_local_vector(
                                    const struct sctp_association *asoc,
                                    gfp_t gfp)
 {
@@ -232,7 +232,7 @@ struct sctp_auth_bytes *sctp_auth_make_local_vector(
 }
 
 /* Make a key vector based on peer's parameters */
-struct sctp_auth_bytes *sctp_auth_make_peer_vector(
+static struct sctp_auth_bytes *sctp_auth_make_peer_vector(
                                    const struct sctp_association *asoc,
                                    gfp_t gfp)
 {
@@ -556,7 +556,7 @@ struct sctp_hmac *sctp_auth_asoc_get_hmac(const struct sctp_association *asoc)
        return &sctp_hmac_list[id];
 }
 
-static int __sctp_auth_find_hmacid(__u16 *hmacs, int n_elts, __u16 hmac_id)
+static int __sctp_auth_find_hmacid(__be16 *hmacs, int n_elts, __be16 hmac_id)
 {
        int  found = 0;
        int  i;
@@ -573,7 +573,7 @@ static int __sctp_auth_find_hmacid(__u16 *hmacs, int n_elts, __u16 hmac_id)
 
 /* See if the HMAC_ID is one that we claim as supported */
 int sctp_auth_asoc_verify_hmac_id(const struct sctp_association *asoc,
-                                   __u16 hmac_id)
+                                   __be16 hmac_id)
 {
        struct sctp_hmac_algo_param *hmacs;
        __u16 n_elt;
@@ -726,10 +726,7 @@ void sctp_auth_calculate_hmac(const struct sctp_association *asoc,
 
        /* set up scatter list */
        end = skb_tail_pointer(skb);
-       sg_init_table(&sg, 1);
-       sg_set_page(&sg, virt_to_page(auth));
-       sg.offset = (unsigned long)(auth) % PAGE_SIZE;
-       sg.length = end - (unsigned char *)auth;
+       sg_init_one(&sg, auth, end - (unsigned char *)auth);
 
        desc.tfm = asoc->ep->auth_hmacs[hmac_id];
        desc.flags = 0;
index 59cf7b0..181edab 100644 (file)
@@ -170,6 +170,7 @@ __u32 sctp_update_cksum(__u8 *buffer, __u16 length, __u32 crc32)
        return crc32;
 }
 
+#if 0
 __u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 length, __u32 crc32)
 {
        __u32 i;
@@ -186,6 +187,7 @@ __u32 sctp_update_copy_cksum(__u8 *to, __u8 *from, __u16 length, __u32 crc32)
 
        return crc32;
 }
+#endif  /*  0  */
 
 __u32 sctp_end_cksum(__u32 crc32)
 {
index 658476c..c377e4e 100644 (file)
@@ -1513,10 +1513,7 @@ static sctp_cookie_param_t *sctp_pack_cookie(const struct sctp_endpoint *ep,
                struct hash_desc desc;
 
                /* Sign the message.  */
-               sg_init_table(&sg, 1);
-               sg_set_page(&sg, virt_to_page(&cookie->c));
-               sg.offset = (unsigned long)(&cookie->c) % PAGE_SIZE;
-               sg.length = bodysize;
+               sg_init_one(&sg, &cookie->c, bodysize);
                keylen = SCTP_SECRET_SIZE;
                key = (char *)ep->secret_key[ep->current_key];
                desc.tfm = sctp_sk(ep->base.sk)->hmac;
@@ -1586,10 +1583,7 @@ struct sctp_association *sctp_unpack_cookie(
 
        /* Check the signature.  */
        keylen = SCTP_SECRET_SIZE;
-       sg_init_table(&sg, 1);
-       sg_set_page(&sg, virt_to_page(bear_cookie));
-       sg.offset = (unsigned long)(bear_cookie) % PAGE_SIZE;
-       sg.length = bodysize;
+       sg_init_one(&sg, bear_cookie, bodysize);
        key = (char *)ep->secret_key[ep->current_key];
        desc.tfm = sctp_sk(ep->base.sk)->hmac;
        desc.flags = 0;
index b937095..4be92d0 100644 (file)
@@ -908,8 +908,8 @@ void sctp_ulpq_skip(struct sctp_ulpq *ulpq, __u16 sid, __u16 ssn)
        return;
 }
 
-/* Renege 'needed' bytes from the ordering queue. */
-static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed)
+static __u16 sctp_ulpq_renege_list(struct sctp_ulpq *ulpq,
+               struct sk_buff_head *list, __u16 needed)
 {
        __u16 freed = 0;
        __u32 tsn;
@@ -919,7 +919,7 @@ static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed)
 
        tsnmap = &ulpq->asoc->peer.tsn_map;
 
-       while ((skb = __skb_dequeue_tail(&ulpq->lobby)) != NULL) {
+       while ((skb = __skb_dequeue_tail(list)) != NULL) {
                freed += skb_headlen(skb);
                event = sctp_skb2event(skb);
                tsn = event->tsn;
@@ -933,30 +933,16 @@ static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed)
        return freed;
 }
 
+/* Renege 'needed' bytes from the ordering queue. */
+static __u16 sctp_ulpq_renege_order(struct sctp_ulpq *ulpq, __u16 needed)
+{
+       return sctp_ulpq_renege_list(ulpq, &ulpq->lobby, needed);
+}
+
 /* Renege 'needed' bytes from the reassembly queue. */
 static __u16 sctp_ulpq_renege_frags(struct sctp_ulpq *ulpq, __u16 needed)
 {
-       __u16 freed = 0;
-       __u32 tsn;
-       struct sk_buff *skb;
-       struct sctp_ulpevent *event;
-       struct sctp_tsnmap *tsnmap;
-
-       tsnmap = &ulpq->asoc->peer.tsn_map;
-
-       /* Walk backwards through the list, reneges the newest tsns. */
-       while ((skb = __skb_dequeue_tail(&ulpq->reasm)) != NULL) {
-               freed += skb_headlen(skb);
-               event = sctp_skb2event(skb);
-               tsn = event->tsn;
-
-               sctp_ulpevent_free(event);
-               sctp_tsnmap_renege(tsnmap, tsn);
-               if (freed >= needed)
-                       return freed;
-       }
-
-       return freed;
+       return sctp_ulpq_renege_list(ulpq, &ulpq->reasm, needed);
 }
 
 /* Partial deliver the first message as there is pressure on rwnd. */
index 32be431..91cd8f0 100644 (file)
@@ -75,7 +75,7 @@ krb5_encrypt(
                memcpy(local_iv, iv, crypto_blkcipher_ivsize(tfm));
 
        memcpy(out, in, length);
-       sg_set_buf(sg, out, length);
+       sg_init_one(sg, out, length);
 
        ret = crypto_blkcipher_encrypt_iv(&desc, sg, sg, length);
 out:
@@ -110,7 +110,7 @@ krb5_decrypt(
                memcpy(local_iv,iv, crypto_blkcipher_ivsize(tfm));
 
        memcpy(out, in, length);
-       sg_set_buf(sg, out, length);
+       sg_init_one(sg, out, length);
 
        ret = crypto_blkcipher_decrypt_iv(&desc, sg, sg, length);
 out:
@@ -146,7 +146,7 @@ make_checksum(char *cksumname, char *header, int hdrlen, struct xdr_buf *body,
        err = crypto_hash_init(&desc);
        if (err)
                goto out;
-       sg_set_buf(sg, header, hdrlen);
+       sg_init_one(sg, header, hdrlen);
        err = crypto_hash_update(&desc, sg, hdrlen);
        if (err)
                goto out;
@@ -188,8 +188,6 @@ encryptor(struct scatterlist *sg, void *data)
        /* Worst case is 4 fragments: head, end of page 1, start
         * of page 2, tail.  Anything more is a bug. */
        BUG_ON(desc->fragno > 3);
-       desc->infrags[desc->fragno] = *sg;
-       desc->outfrags[desc->fragno] = *sg;
 
        page_pos = desc->pos - outbuf->head[0].iov_len;
        if (page_pos >= 0 && page_pos < outbuf->page_len) {
@@ -199,7 +197,10 @@ encryptor(struct scatterlist *sg, void *data)
        } else {
                in_page = sg_page(sg);
        }
-       sg_set_page(&desc->infrags[desc->fragno], in_page);
+       sg_set_page(&desc->infrags[desc->fragno], in_page, sg->length,
+                   sg->offset);
+       sg_set_page(&desc->outfrags[desc->fragno], sg_page(sg), sg->length,
+                   sg->offset);
        desc->fragno++;
        desc->fraglen += sg->length;
        desc->pos += sg->length;
@@ -210,16 +211,22 @@ encryptor(struct scatterlist *sg, void *data)
        if (thislen == 0)
                return 0;
 
+       sg_mark_end(desc->infrags, desc->fragno);
+       sg_mark_end(desc->outfrags, desc->fragno);
+
        ret = crypto_blkcipher_encrypt_iv(&desc->desc, desc->outfrags,
                                          desc->infrags, thislen);
        if (ret)
                return ret;
+
+       sg_init_table(desc->infrags, 4);
+       sg_init_table(desc->outfrags, 4);
+
        if (fraglen) {
-               sg_set_page(&desc->outfrags[0], sg_page(sg));
-               desc->outfrags[0].offset = sg->offset + sg->length - fraglen;
-               desc->outfrags[0].length = fraglen;
+               sg_set_page(&desc->outfrags[0], sg_page(sg), fraglen,
+                               sg->offset + sg->length - fraglen);
                desc->infrags[0] = desc->outfrags[0];
-               sg_set_page(&desc->infrags[0], in_page);
+               sg_assign_page(&desc->infrags[0], in_page);
                desc->fragno = 1;
                desc->fraglen = fraglen;
        } else {
@@ -248,6 +255,9 @@ gss_encrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
        desc.fragno = 0;
        desc.fraglen = 0;
 
+       sg_init_table(desc.infrags, 4);
+       sg_init_table(desc.outfrags, 4);
+
        ret = xdr_process_buf(buf, offset, buf->len - offset, encryptor, &desc);
        return ret;
 }
@@ -272,7 +282,8 @@ decryptor(struct scatterlist *sg, void *data)
        /* Worst case is 4 fragments: head, end of page 1, start
         * of page 2, tail.  Anything more is a bug. */
        BUG_ON(desc->fragno > 3);
-       desc->frags[desc->fragno] = *sg;
+       sg_set_page(&desc->frags[desc->fragno], sg_page(sg), sg->length,
+                   sg->offset);
        desc->fragno++;
        desc->fraglen += sg->length;
 
@@ -282,14 +293,18 @@ decryptor(struct scatterlist *sg, void *data)
        if (thislen == 0)
                return 0;
 
+       sg_mark_end(desc->frags, desc->fragno);
+
        ret = crypto_blkcipher_decrypt_iv(&desc->desc, desc->frags,
                                          desc->frags, thislen);
        if (ret)
                return ret;
+
+       sg_init_table(desc->frags, 4);
+
        if (fraglen) {
-               sg_set_page(&desc->frags[0], sg_page(sg));
-               desc->frags[0].offset = sg->offset + sg->length - fraglen;
-               desc->frags[0].length = fraglen;
+               sg_set_page(&desc->frags[0], sg_page(sg), fraglen,
+                               sg->offset + sg->length - fraglen);
                desc->fragno = 1;
                desc->fraglen = fraglen;
        } else {
@@ -314,6 +329,9 @@ gss_decrypt_xdr_buf(struct crypto_blkcipher *tfm, struct xdr_buf *buf,
        desc.desc.flags = 0;
        desc.fragno = 0;
        desc.fraglen = 0;
+
+       sg_init_table(desc.frags, 4);
+
        return xdr_process_buf(buf, offset, buf->len - offset, decryptor, &desc);
 }
 
index d158635..abf17ce 100644 (file)
@@ -173,7 +173,7 @@ make_spkm3_checksum(s32 cksumtype, struct xdr_netobj *key, char *header,
        if (err)
                goto out;
 
-       sg_set_buf(sg, header, hdrlen);
+       sg_init_one(sg, header, hdrlen);
        crypto_hash_update(&desc, sg, sg->length);
 
        xdr_process_buf(body, body_offset, body->len - body_offset,
index 3d1f7cd..fdc5e6d 100644 (file)
@@ -1030,6 +1030,8 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
        unsigned page_len, thislen, page_offset;
        struct scatterlist      sg[1];
 
+       sg_init_table(sg, 1);
+
        if (offset >= buf->head[0].iov_len) {
                offset -= buf->head[0].iov_len;
        } else {
@@ -1059,9 +1061,7 @@ xdr_process_buf(struct xdr_buf *buf, unsigned int offset, unsigned int len,
                do {
                        if (thislen > page_len)
                                thislen = page_len;
-                       sg_set_page(sg, buf->pages[i]);
-                       sg->offset = page_offset;
-                       sg->length = thislen;
+                       sg_set_page(sg, buf->pages[i], thislen, page_offset);
                        ret = actor(sg, data);
                        if (ret)
                                goto out;
index 12db635..f877b88 100644 (file)
@@ -181,7 +181,7 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
        struct rpcrdma_read_chunk *cur_rchunk = NULL;
        struct rpcrdma_write_array *warray = NULL;
        struct rpcrdma_write_chunk *cur_wchunk = NULL;
-       u32 *iptr = headerp->rm_body.rm_chunks;
+       __be32 *iptr = headerp->rm_body.rm_chunks;
 
        if (type == rpcrdma_readch || type == rpcrdma_areadch) {
                /* a read chunk - server will RDMA Read our memory */
@@ -217,7 +217,7 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
                        cur_rchunk->rc_target.rs_handle = htonl(seg->mr_rkey);
                        cur_rchunk->rc_target.rs_length = htonl(seg->mr_len);
                        xdr_encode_hyper(
-                                       (u32 *)&cur_rchunk->rc_target.rs_offset,
+                                       (__be32 *)&cur_rchunk->rc_target.rs_offset,
                                        seg->mr_base);
                        dprintk("RPC:       %s: read chunk "
                                "elem %d@0x%llx:0x%x pos %d (%s)\n", __func__,
@@ -229,7 +229,7 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
                        cur_wchunk->wc_target.rs_handle = htonl(seg->mr_rkey);
                        cur_wchunk->wc_target.rs_length = htonl(seg->mr_len);
                        xdr_encode_hyper(
-                                       (u32 *)&cur_wchunk->wc_target.rs_offset,
+                                       (__be32 *)&cur_wchunk->wc_target.rs_offset,
                                        seg->mr_base);
                        dprintk("RPC:       %s: %s chunk "
                                "elem %d@0x%llx:0x%x (%s)\n", __func__,
@@ -257,14 +257,14 @@ rpcrdma_create_chunks(struct rpc_rqst *rqst, struct xdr_buf *target,
         * finish off header. If write, marshal discrim and nchunks.
         */
        if (cur_rchunk) {
-               iptr = (u32 *) cur_rchunk;
+               iptr = (__be32 *) cur_rchunk;
                *iptr++ = xdr_zero;     /* finish the read chunk list */
                *iptr++ = xdr_zero;     /* encode a NULL write chunk list */
                *iptr++ = xdr_zero;     /* encode a NULL reply chunk */
        } else {
                warray->wc_discrim = xdr_one;
                warray->wc_nchunks = htonl(nchunks);
-               iptr = (u32 *) cur_wchunk;
+               iptr = (__be32 *) cur_wchunk;
                if (type == rpcrdma_writech) {
                        *iptr++ = xdr_zero; /* finish the write chunk list */
                        *iptr++ = xdr_zero; /* encode a NULL reply chunk */
@@ -559,7 +559,7 @@ rpcrdma_marshal_req(struct rpc_rqst *rqst)
  * RDMA'd by server. See map at rpcrdma_create_chunks()! :-)
  */
 static int
-rpcrdma_count_chunks(struct rpcrdma_rep *rep, int max, int wrchunk, u32 **iptrp)
+rpcrdma_count_chunks(struct rpcrdma_rep *rep, int max, int wrchunk, __be32 **iptrp)
 {
        unsigned int i, total_len;
        struct rpcrdma_write_chunk *cur_wchunk;
@@ -573,7 +573,7 @@ rpcrdma_count_chunks(struct rpcrdma_rep *rep, int max, int wrchunk, u32 **iptrp)
                struct rpcrdma_segment *seg = &cur_wchunk->wc_target;
                ifdebug(FACILITY) {
                        u64 off;
-                       xdr_decode_hyper((u32 *)&seg->rs_offset, &off);
+                       xdr_decode_hyper((__be32 *)&seg->rs_offset, &off);
                        dprintk("RPC:       %s: chunk %d@0x%llx:0x%x\n",
                                __func__,
                                ntohl(seg->rs_length),
@@ -585,7 +585,7 @@ rpcrdma_count_chunks(struct rpcrdma_rep *rep, int max, int wrchunk, u32 **iptrp)
        }
        /* check and adjust for properly terminated write chunk */
        if (wrchunk) {
-               u32 *w = (u32 *) cur_wchunk;
+               __be32 *w = (__be32 *) cur_wchunk;
                if (*w++ != xdr_zero)
                        return -1;
                cur_wchunk = (struct rpcrdma_write_chunk *) w;
@@ -593,7 +593,7 @@ rpcrdma_count_chunks(struct rpcrdma_rep *rep, int max, int wrchunk, u32 **iptrp)
        if ((char *) cur_wchunk > rep->rr_base + rep->rr_len)
                return -1;
 
-       *iptrp = (u32 *) cur_wchunk;
+       *iptrp = (__be32 *) cur_wchunk;
        return total_len;
 }
 
@@ -721,7 +721,7 @@ rpcrdma_reply_handler(struct rpcrdma_rep *rep)
        struct rpc_rqst *rqst;
        struct rpc_xprt *xprt = rep->rr_xprt;
        struct rpcrdma_xprt *r_xprt = rpcx_to_rdmax(xprt);
-       u32 *iptr;
+       __be32 *iptr;
        int i, rdmalen, status;
 
        /* Check status. If bad, signal disconnect and return rep to pool */
@@ -801,7 +801,7 @@ repost:
                        r_xprt->rx_stats.total_rdma_reply += rdmalen;
                } else {
                        /* else ordinary inline */
-                       iptr = (u32 *)((unsigned char *)headerp + 28);
+                       iptr = (__be32 *)((unsigned char *)headerp + 28);
                        rep->rr_len -= 28; /*sizeof *headerp;*/
                        status = rep->rr_len;
                }
@@ -816,7 +816,7 @@ repost:
                    headerp->rm_body.rm_chunks[2] != xdr_one ||
                    req->rl_nchunks == 0)
                        goto badheader;
-               iptr = (u32 *)((unsigned char *)headerp + 28);
+               iptr = (__be32 *)((unsigned char *)headerp + 28);
                rdmalen = rpcrdma_count_chunks(rep, req->rl_nchunks, 0, &iptr);
                if (rdmalen < 0)
                        goto badheader;
index 313d4be..0426388 100644 (file)
@@ -553,9 +553,7 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
                if (copy > len)
                        copy = len;
 
-               sg_set_page(&sg, virt_to_page(skb->data + offset));
-               sg.offset = (unsigned long)(skb->data + offset) % PAGE_SIZE;
-               sg.length = copy;
+               sg_init_one(&sg, skb->data + offset, copy);
 
                err = icv_update(desc, &sg, copy);
                if (unlikely(err))
@@ -578,9 +576,9 @@ int skb_icv_walk(const struct sk_buff *skb, struct hash_desc *desc,
                        if (copy > len)
                                copy = len;
 
-                       sg_set_page(&sg, frag->page);
-                       sg.offset = frag->page_offset + offset-start;
-                       sg.length = copy;
+                       sg_init_table(&sg, 1);
+                       sg_set_page(&sg, frag->page, copy,
+                                   frag->page_offset + offset-start);
 
                        err = icv_update(desc, &sg, copy);
                        if (unlikely(err))
index 83c5e76..5959412 100644 (file)
@@ -4,23 +4,30 @@
 
 PHONY += oldconfig xconfig gconfig menuconfig config silentoldconfig update-po-config
 
+# If a arch/$(SRCARCH)/Kconfig.$(ARCH) file exist use it
+ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/Kconfig.$(ARCH)),)
+        Kconfig := arch/$(SRCARCH)/Kconfig.$(ARCH)
+else
+        Kconfig := arch/$(SRCARCH)/Kconfig
+endif
+
 xconfig: $(obj)/qconf
-       $< arch/$(ARCH)/Kconfig
+       $< $(Kconfig)
 
 gconfig: $(obj)/gconf
-       $< arch/$(ARCH)/Kconfig
+       $< $(Kconfig)
 
 menuconfig: $(obj)/mconf
-       $< arch/$(ARCH)/Kconfig
+       $< $(Kconfig)
 
 config: $(obj)/conf
-       $< arch/$(ARCH)/Kconfig
+       $< $(Kconfig)
 
 oldconfig: $(obj)/conf
-       $< -o arch/$(ARCH)/Kconfig
+       $< -o $(Kconfig)
 
 silentoldconfig: $(obj)/conf
-       $< -s arch/$(ARCH)/Kconfig
+       $< -s $(Kconfig)
 
 # Create new linux.po file
 # Adjust charset to UTF-8 in .po file to accept UTF-8 in Kconfig files
@@ -45,27 +52,27 @@ update-po-config: $(obj)/kxgettext
 PHONY += randconfig allyesconfig allnoconfig allmodconfig defconfig
 
 randconfig: $(obj)/conf
-       $< -r arch/$(ARCH)/Kconfig
+       $< -r $(Kconfig)
 
 allyesconfig: $(obj)/conf
-       $< -y arch/$(ARCH)/Kconfig
+       $< -y $(Kconfig)
 
 allnoconfig: $(obj)/conf
-       $< -n arch/$(ARCH)/Kconfig
+       $< -n $(Kconfig)
 
 allmodconfig: $(obj)/conf
-       $< -m arch/$(ARCH)/Kconfig
+       $< -m $(Kconfig)
 
 defconfig: $(obj)/conf
 ifeq ($(KBUILD_DEFCONFIG),)
-       $< -d arch/$(ARCH)/Kconfig
+       $< -d $(Kconfig)
 else
-       @echo *** Default configuration is based on '$(KBUILD_DEFCONFIG)'
-       $(Q)$< -D arch/$(ARCH)/configs/$(KBUILD_DEFCONFIG) arch/$(ARCH)/Kconfig
+       @echo "*** Default configuration is based on '$(KBUILD_DEFCONFIG)'"
+       $(Q)$< -D arch/$(SRCARCH)/configs/$(KBUILD_DEFCONFIG) $(Kconfig)
 endif
 
 %_defconfig: $(obj)/conf
-       $(Q)$< -D arch/$(ARCH)/configs/$@ arch/$(ARCH)/Kconfig
+       $(Q)$< -D arch/$(SRCARCH)/configs/$@ $(Kconfig)
 
 # Help text used by make help
 help:
index d9f78c8..1c50278 100644 (file)
@@ -9299,7 +9299,6 @@ static struct alc_config_preset alc268_presets[] = {
                .num_channel_mode = ARRAY_SIZE(alc268_modes),
                .channel_mode = alc268_modes,
                .input_mux = &alc268_capture_source,
-               .input_mux = &alc268_capture_source,
                .unsol_event = alc268_toshiba_unsol_event,
                .init_hook = alc268_toshiba_automute,
        },