OSDN Git Service

Pull miscellaneous into release branch
authorTony Luck <tony.luck@intel.com>
Thu, 17 Apr 2008 17:14:51 +0000 (10:14 -0700)
committerTony Luck <tony.luck@intel.com>
Thu, 17 Apr 2008 17:14:51 +0000 (10:14 -0700)
Conflicts:

arch/ia64/kernel/mca.c

356 files changed:
Documentation/00-INDEX
Documentation/SubmittingPatches
Documentation/filesystems/00-INDEX
Documentation/filesystems/nfsroot.txt [moved from Documentation/nfsroot.txt with 100% similarity]
Documentation/filesystems/rpc-cache.txt [moved from Documentation/rpc-cache.txt with 100% similarity]
Documentation/filesystems/seq_file.txt [new file with mode: 0644]
Documentation/hrtimers/highres.txt
Documentation/kernel-parameters.txt
Documentation/networking/can.txt
Documentation/scheduler/00-INDEX
Documentation/scheduler/sched-rt-group.txt [moved from Documentation/sched-rt-group.txt with 100% similarity]
Documentation/spi/spi-summary
Documentation/spinlocks.txt
Documentation/vm/hugetlbpage.txt
MAINTAINERS
Makefile
arch/avr32/Kconfig
arch/frv/kernel/entry-table.S
arch/frv/kernel/entry.S
arch/frv/kernel/head.inc
arch/frv/kernel/switch_to.S
arch/frv/kernel/traps.c
arch/ia64/Kconfig
arch/ia64/ia32/elfcore32.h
arch/ia64/ia32/sys_ia32.c
arch/ia64/kernel/acpi.c
arch/ia64/kernel/asm-offsets.c
arch/ia64/kernel/efi.c
arch/ia64/kernel/entry.S
arch/ia64/kernel/fsys.S
arch/ia64/kernel/head.S
arch/ia64/kernel/ivt.S
arch/ia64/kernel/mca.c
arch/ia64/kernel/mca_asm.S
arch/ia64/kernel/minstate.h
arch/ia64/kernel/numa.c
arch/ia64/kernel/patch.c
arch/ia64/kernel/process.c
arch/ia64/kernel/ptrace.c
arch/ia64/kernel/setup.c
arch/ia64/kernel/smp.c
arch/ia64/kernel/time.c
arch/ia64/mm/discontig.c
arch/ia64/mm/numa.c
arch/ia64/mm/tlb.c
arch/ia64/pci/pci.c
arch/mips/au1000/common/platform.c
arch/parisc/kernel/signal.c
arch/sh/boot/compressed/head_32.S
arch/sh/boot/compressed/head_64.S
arch/sh/kernel/process_64.c
arch/sh/kernel/ptrace_64.c
arch/sh/kernel/sh_ksyms_32.c
arch/sh/kernel/sh_ksyms_64.c
arch/sh/kernel/signal_64.c
arch/sh/kernel/traps_32.c
arch/sh/kernel/traps_64.c
arch/sparc/kernel/ptrace.c
arch/sparc64/kernel/ptrace.c
arch/x86/kernel/alternative.c
arch/x86/kernel/process_32.c
arch/x86/kernel/process_64.c
arch/x86/kernel/tls.c
arch/x86/pci/acpi.c
block/Kconfig
block/cfq-iosched.c
drivers/acpi/bus.c
drivers/acpi/processor_core.c
drivers/acpi/thermal.c
drivers/ata/pata_ali.c
drivers/ata/pata_sil680.c
drivers/ata/sata_fsl.c
drivers/ata/sata_svw.c
drivers/block/cciss.c
drivers/block/ub.c
drivers/i2c/busses/i2c-davinci.c
drivers/i2c/busses/i2c-ibm_iic.c
drivers/i2c/busses/i2c-tiny-usb.c
drivers/ide/mips/au1xxx-ide.c
drivers/ide/pci/it821x.c
drivers/isdn/i4l/isdn_net.c
drivers/leds/leds-ams-delta.c
drivers/leds/leds-atmel-pwm.c
drivers/leds/leds-clevo-mail.c
drivers/leds/leds-cm-x270.c
drivers/leds/leds-cobalt-qube.c
drivers/leds/leds-corgi.c
drivers/leds/leds-gpio.c
drivers/leds/leds-h1940.c
drivers/leds/leds-hp6xx.c
drivers/leds/leds-s3c24xx.c
drivers/leds/leds-spitz.c
drivers/leds/leds-tosa.c
drivers/md/raid5.c
drivers/misc/atmel-ssc.c
drivers/misc/atmel_pwm.c
drivers/misc/hdpuftrs/hdpu_cpustate.c
drivers/misc/hdpuftrs/hdpu_nexus.c
drivers/mmc/host/at91_mci.c
drivers/mmc/host/au1xmmc.c
drivers/mmc/host/imxmmc.c
drivers/mmc/host/omap.c
drivers/mmc/host/pxamci.c
drivers/mmc/host/wbsd.c
drivers/mtd/chips/cfi_cmdset_0002.c
drivers/mtd/chips/cfi_cmdset_0020.c
drivers/net/b44.c
drivers/net/bnx2x.c
drivers/net/ehea/ehea.h
drivers/net/ehea/ehea_main.c
drivers/net/forcedeth.c
drivers/net/fs_enet/fs_enet-main.c
drivers/net/macb.c
drivers/net/netconsole.c
drivers/net/ps3_gelic_wireless.c
drivers/net/sc92031.c
drivers/net/sky2.c
drivers/net/smc91x.c
drivers/net/starfire.c
drivers/net/tg3.c
drivers/net/tokenring/olympic.c
drivers/net/tun.c
drivers/net/ucc_geth.c
drivers/net/virtio_net.c
drivers/net/wan/Kconfig
drivers/net/wireless/b43/dma.c
drivers/net/wireless/b43legacy/dma.c
drivers/net/wireless/b43legacy/main.c
drivers/net/wireless/hostap/hostap_80211_rx.c
drivers/net/wireless/hostap/hostap_80211_tx.c
drivers/net/wireless/hostap/hostap_ap.c
drivers/net/wireless/ipw2200.c
drivers/net/wireless/iwlwifi/Kconfig
drivers/net/wireless/libertas/assoc.c
drivers/net/wireless/rt2x00/rt61pci.c
drivers/net/wireless/rtl8187_dev.c
drivers/pcmcia/at91_cf.c
drivers/pcmcia/omap_cf.c
drivers/pcmcia/pxa2xx_base.c
drivers/rtc/Kconfig
drivers/rtc/rtc-at32ap700x.c
drivers/rtc/rtc-at91rm9200.c
drivers/rtc/rtc-bfin.c
drivers/rtc/rtc-cmos.c
drivers/rtc/rtc-ds1216.c
drivers/rtc/rtc-ds1511.c
drivers/rtc/rtc-ds1553.c
drivers/rtc/rtc-ds1742.c
drivers/rtc/rtc-ep93xx.c
drivers/rtc/rtc-m48t59.c
drivers/rtc/rtc-m48t86.c
drivers/rtc/rtc-omap.c
drivers/rtc/rtc-rs5c313.c
drivers/rtc/rtc-s3c.c
drivers/rtc/rtc-sa1100.c
drivers/rtc/rtc-sh.c
drivers/rtc/rtc-stk17ta8.c
drivers/rtc/rtc-v3020.c
drivers/rtc/rtc-vr41xx.c
drivers/serial/atmel_serial.c
drivers/serial/bfin_5xx.c
drivers/serial/imx.c
drivers/serial/mcf.c
drivers/serial/mpc52xx_uart.c
drivers/serial/mpsc.c
drivers/serial/netx-serial.c
drivers/serial/pnx8xxx_uart.c
drivers/serial/pxa.c
drivers/serial/s3c2410.c
drivers/serial/sa1100.c
drivers/serial/sc26xx.c
drivers/serial/sh-sci.c
drivers/serial/uartlite.c
drivers/serial/vr41xx_siu.c
drivers/spi/atmel_spi.c
drivers/spi/au1550_spi.c
drivers/spi/mpc52xx_psc_spi.c
drivers/spi/omap2_mcspi.c
drivers/spi/omap_uwire.c
drivers/spi/pxa2xx_spi.c
drivers/spi/spi_bfin5xx.c
drivers/spi/spi_imx.c
drivers/spi/spi_mpc83xx.c
drivers/spi/spi_s3c24xx.c
drivers/spi/spi_s3c24xx_gpio.c
drivers/spi/spi_sh_sci.c
drivers/spi/spi_txx9.c
drivers/spi/xilinx_spi.c
drivers/ssb/driver_mipscore.c
drivers/ssb/driver_pcicore.c
drivers/ssb/main.c
drivers/thermal/thermal.c
drivers/usb/gadget/at91_udc.c
drivers/usb/gadget/atmel_usba_udc.c
drivers/usb/gadget/fsl_usb2_udc.c
drivers/usb/gadget/lh7a40x_udc.c
drivers/usb/gadget/m66592-udc.c
drivers/usb/gadget/omap_udc.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/gadget/s3c2410_udc.c
drivers/usb/host/isp116x-hcd.c
drivers/usb/host/ohci-at91.c
drivers/usb/host/ohci-au1xxx.c
drivers/usb/host/ohci-ep93xx.c
drivers/usb/host/ohci-lh7a404.c
drivers/usb/host/ohci-omap.c
drivers/usb/host/ohci-pnx4008.c
drivers/usb/host/ohci-pnx8550.c
drivers/usb/host/ohci-ppc-soc.c
drivers/usb/host/ohci-pxa27x.c
drivers/usb/host/ohci-s3c2410.c
drivers/usb/host/ohci-sh.c
drivers/usb/host/ohci-sm501.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/sl811-hcd.c
drivers/usb/host/u132-hcd.c
drivers/usb/serial/option.c
drivers/usb/serial/usb-serial.c
drivers/usb/storage/unusual_devs.h
drivers/video/fbmem.c
drivers/watchdog/at32ap700x_wdt.c
drivers/watchdog/at91rm9200_wdt.c
drivers/watchdog/davinci_wdt.c
drivers/watchdog/ks8695_wdt.c
drivers/watchdog/mpc83xx_wdt.c
drivers/watchdog/mpcore_wdt.c
drivers/watchdog/mtx-1_wdt.c
drivers/watchdog/mv64x60_wdt.c
drivers/watchdog/omap_wdt.c
drivers/watchdog/pnx4008_wdt.c
drivers/watchdog/s3c2410_wdt.c
drivers/watchdog/txx9wdt.c
fs/Kconfig
fs/afs/main.c
fs/aio.c
fs/ext2/xattr.c
fs/ext3/xattr.c
fs/ext4/xattr.c
fs/hfsplus/dir.c
fs/jffs2/file.c
fs/locks.c
fs/mbcache.c
fs/nfs/file.c
fs/nfs/inode.c
fs/open.c
fs/signalfd.c
fs/splice.c
fs/xfs/linux-2.6/xfs_ioctl.c
fs/xfs/quota/xfs_qm.c
fs/xfs/quota/xfs_qm_bhv.c
fs/xfs/quota/xfs_qm_syscalls.c
fs/xfs/xfs_attr_leaf.c
fs/xfs/xfs_bmap.c
fs/xfs/xfs_bmap_btree.h
fs/xfs/xfs_dir2.c
fs/xfs/xfs_fsops.c
fs/xfs/xfs_ialloc.c
fs/xfs/xfs_inode.c
fs/xfs/xfs_inode_item.c
fs/xfs/xfs_itable.c
fs/xfs/xfs_log.c
fs/xfs/xfs_log_priv.h
fs/xfs/xfs_log_recover.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_sb.h
fs/xfs/xfs_utils.c
fs/xfs/xfs_vfsops.c
fs/xfs/xfs_vnodeops.c
include/asm-arm/arch-s3c2410/spi.h
include/asm-frv/mem-layout.h
include/asm-frv/pgtable.h
include/asm-frv/spr-regs.h
include/asm-frv/system.h
include/asm-ia64/acpi.h
include/asm-ia64/cputime.h
include/asm-ia64/elf.h
include/asm-ia64/kregs.h
include/asm-ia64/numa.h
include/asm-ia64/sal.h
include/asm-ia64/smp.h
include/asm-ia64/system.h
include/asm-ia64/thread_info.h
include/asm-ia64/tlb.h
include/asm-ia64/tlbflush.h
include/asm-mips/mach-au1x00/au1xxx_ide.h
include/asm-mips/mach-db1x00/db1200.h
include/asm-mips/mach-pb1x00/pb1200.h
include/asm-um/tlb.h
include/asm-x86/linkage.h
include/linux/Kbuild
include/linux/if_tun.h
include/linux/iocontext.h
include/linux/ipv6.h
include/linux/linkage.h
include/linux/mbcache.h
include/linux/pnp.h
include/linux/spinlock.h
include/linux/ssb/ssb.h
include/linux/thermal.h
include/net/inet_ecn.h
include/net/sctp/command.h
include/net/sctp/ulpevent.h
include/net/tcp.h
kernel/cgroup.c
kernel/exit.c
kernel/printk.c
kernel/sched_fair.c
kernel/uid16.c
lib/lzo/lzo1x_decompress.c
mm/memcontrol.c
mm/oom_kill.c
mm/sparse.c
mm/vmstat.c
net/atm/lec.c
net/ax25/ax25_uid.c
net/bridge/br_netfilter.c
net/core/skbuff.c
net/core/sock.c
net/dccp/dccp.h
net/dccp/ipv4.c
net/dccp/output.c
net/dccp/proto.c
net/ethernet/eth.c
net/ieee80211/ieee80211_rx.c
net/ipv4/Kconfig
net/ipv4/inet_timewait_sock.c
net/ipv4/ip_sockglue.c
net/ipv4/ipconfig.c
net/ipv4/netfilter/ipt_CLUSTERIP.c
net/ipv4/netfilter/nf_nat_core.c
net/ipv4/tcp_input.c
net/ipv4/tcp_output.c
net/ipv6/addrconf.c
net/ipv6/raw.c
net/mac80211/ieee80211_sta.c
net/mac80211/rx.c
net/netfilter/xt_hashlimit.c
net/rfkill/rfkill.c
net/rxrpc/af_rxrpc.c
net/rxrpc/rxkad.c
net/sched/cls_u32.c
net/sched/sch_api.c
net/sctp/ipv6.c
net/sctp/outqueue.c
net/sctp/protocol.c
net/sctp/sm_make_chunk.c
net/sctp/sm_sideeffect.c
net/sctp/sm_statefuns.c
net/sctp/socket.c
net/sctp/ulpevent.c
net/sunrpc/clnt.c
net/sunrpc/xdr.c
net/wireless/nl80211.c
net/xfrm/xfrm_user.c
security/selinux/hooks.c
sound/pci/es1968.c

index fc8e7c7..e8fb246 100644 (file)
@@ -271,8 +271,6 @@ netlabel/
        - directory with information on the NetLabel subsystem.
 networking/
        - directory with info on various aspects of networking with Linux.
-nfsroot.txt
-       - short guide on setting up a diskless box with NFS root filesystem.
 nmi_watchdog.txt
        - info on NMI watchdog for SMP systems.
 nommu-mmap.txt
@@ -321,8 +319,6 @@ robust-futexes.txt
        - a description of what robust futexes are.
 rocket.txt
        - info on the Comtrol RocketPort multiport serial driver.
-rpc-cache.txt
-       - introduction to the caching mechanisms in the sunrpc layer.
 rt-mutex-design.txt
        - description of the RealTime mutex implementation design.
 rt-mutex.txt
index 47a539c..1fc4e71 100644 (file)
@@ -328,7 +328,7 @@ now, but you can do this to mark internal company procedures or just
 point out some special detail about the sign-off. 
 
 
-13) When to use Acked-by:
+13) When to use Acked-by: and Cc:
 
 The Signed-off-by: tag indicates that the signer was involved in the
 development of the patch, or that he/she was in the patch's delivery path.
@@ -349,11 +349,59 @@ Acked-by: does not necessarily indicate acknowledgement of the entire patch.
 For example, if a patch affects multiple subsystems and has an Acked-by: from
 one subsystem maintainer then this usually indicates acknowledgement of just
 the part which affects that maintainer's code.  Judgement should be used here.
- When in doubt people should refer to the original discussion in the mailing
+When in doubt people should refer to the original discussion in the mailing
 list archives.
 
+If a person has had the opportunity to comment on a patch, but has not
+provided such comments, you may optionally add a "Cc:" tag to the patch.
+This is the only tag which might be added without an explicit action by the
+person it names.  This tag documents that potentially interested parties
+have been included in the discussion
 
-14) The canonical patch format
+
+14) Using Test-by: and Reviewed-by:
+
+A Tested-by: tag indicates that the patch has been successfully tested (in
+some environment) by the person named.  This tag informs maintainers that
+some testing has been performed, provides a means to locate testers for
+future patches, and ensures credit for the testers.
+
+Reviewed-by:, instead, indicates that the patch has been reviewed and found
+acceptable according to the Reviewer's Statement:
+
+       Reviewer's statement of oversight
+
+       By offering my Reviewed-by: tag, I state that:
+
+        (a) I have carried out a technical review of this patch to
+            evaluate its appropriateness and readiness for inclusion into
+            the mainline kernel.
+
+        (b) Any problems, concerns, or questions relating to the patch
+            have been communicated back to the submitter.  I am satisfied
+            with the submitter's response to my comments.
+
+        (c) While there may be things that could be improved with this
+            submission, I believe that it is, at this time, (1) a
+            worthwhile modification to the kernel, and (2) free of known
+            issues which would argue against its inclusion.
+
+        (d) While I have reviewed the patch and believe it to be sound, I
+            do not (unless explicitly stated elsewhere) make any
+            warranties or guarantees that it will achieve its stated
+            purpose or function properly in any given situation.
+
+A Reviewed-by tag is a statement of opinion that the patch is an
+appropriate modification of the kernel without any remaining serious
+technical issues.  Any interested reviewer (who has done the work) can
+offer a Reviewed-by tag for a patch.  This tag serves to give credit to
+reviewers and to inform maintainers of the degree of review which has been
+done on the patch.  Reviewed-by: tags, when supplied by reviewers known to
+understand the subject area and to perform thorough reviews, will normally
+increase the liklihood of your patch getting into the kernel.
+
+
+15) The canonical patch format
 
 The canonical patch subject line is:
 
index e68021c..52cd611 100644 (file)
@@ -66,6 +66,8 @@ mandatory-locking.txt
        - info on the Linux implementation of Sys V mandatory file locking.
 ncpfs.txt
        - info on Novell Netware(tm) filesystem using NCP protocol.
+nfsroot.txt
+       - short guide on setting up a diskless box with NFS root filesystem.
 ntfs.txt
        - info and mount options for the NTFS filesystem (Windows NT).
 ocfs2.txt
@@ -82,6 +84,10 @@ relay.txt
        - info on relay, for efficient streaming from kernel to user space.
 romfs.txt
        - description of the ROMFS filesystem.
+rpc-cache.txt
+       - introduction to the caching mechanisms in the sunrpc layer.
+seq_file.txt
+       - how to use the seq_file API
 sharedsubtree.txt
        - a description of shared subtrees for namespaces.
 smbfs.txt
diff --git a/Documentation/filesystems/seq_file.txt b/Documentation/filesystems/seq_file.txt
new file mode 100644 (file)
index 0000000..7fb8e6d
--- /dev/null
@@ -0,0 +1,283 @@
+The seq_file interface
+
+       Copyright 2003 Jonathan Corbet <corbet@lwn.net>
+       This file is originally from the LWN.net Driver Porting series at
+       http://lwn.net/Articles/driver-porting/
+
+
+There are numerous ways for a device driver (or other kernel component) to
+provide information to the user or system administrator.  One useful
+technique is the creation of virtual files, in debugfs, /proc or elsewhere.
+Virtual files can provide human-readable output that is easy to get at
+without any special utility programs; they can also make life easier for
+script writers. It is not surprising that the use of virtual files has
+grown over the years.
+
+Creating those files correctly has always been a bit of a challenge,
+however. It is not that hard to make a virtual file which returns a
+string. But life gets trickier if the output is long - anything greater
+than an application is likely to read in a single operation.  Handling
+multiple reads (and seeks) requires careful attention to the reader's
+position within the virtual file - that position is, likely as not, in the
+middle of a line of output. The kernel has traditionally had a number of
+implementations that got this wrong.
+
+The 2.6 kernel contains a set of functions (implemented by Alexander Viro)
+which are designed to make it easy for virtual file creators to get it
+right.
+
+The seq_file interface is available via <linux/seq_file.h>. There are
+three aspects to seq_file:
+
+     * An iterator interface which lets a virtual file implementation
+       step through the objects it is presenting.
+
+     * Some utility functions for formatting objects for output without
+       needing to worry about things like output buffers.
+
+     * A set of canned file_operations which implement most operations on
+       the virtual file.
+
+We'll look at the seq_file interface via an extremely simple example: a
+loadable module which creates a file called /proc/sequence. The file, when
+read, simply produces a set of increasing integer values, one per line. The
+sequence will continue until the user loses patience and finds something
+better to do. The file is seekable, in that one can do something like the
+following:
+
+    dd if=/proc/sequence of=out1 count=1
+    dd if=/proc/sequence skip=1 out=out2 count=1
+
+Then concatenate the output files out1 and out2 and get the right
+result. Yes, it is a thoroughly useless module, but the point is to show
+how the mechanism works without getting lost in other details.  (Those
+wanting to see the full source for this module can find it at
+http://lwn.net/Articles/22359/).
+
+
+The iterator interface
+
+Modules implementing a virtual file with seq_file must implement a simple
+iterator object that allows stepping through the data of interest.
+Iterators must be able to move to a specific position - like the file they
+implement - but the interpretation of that position is up to the iterator
+itself. A seq_file implementation that is formatting firewall rules, for
+example, could interpret position N as the Nth rule in the chain.
+Positioning can thus be done in whatever way makes the most sense for the
+generator of the data, which need not be aware of how a position translates
+to an offset in the virtual file. The one obvious exception is that a
+position of zero should indicate the beginning of the file.
+
+The /proc/sequence iterator just uses the count of the next number it
+will output as its position.
+
+Four functions must be implemented to make the iterator work. The first,
+called start() takes a position as an argument and returns an iterator
+which will start reading at that position. For our simple sequence example,
+the start() function looks like:
+
+       static void *ct_seq_start(struct seq_file *s, loff_t *pos)
+       {
+               loff_t *spos = kmalloc(sizeof(loff_t), GFP_KERNEL);
+               if (! spos)
+                       return NULL;
+               *spos = *pos;
+               return spos;
+       }
+
+The entire data structure for this iterator is a single loff_t value
+holding the current position. There is no upper bound for the sequence
+iterator, but that will not be the case for most other seq_file
+implementations; in most cases the start() function should check for a
+"past end of file" condition and return NULL if need be.
+
+For more complicated applications, the private field of the seq_file
+structure can be used. There is also a special value which can be returned
+by the start() function called SEQ_START_TOKEN; it can be used if you wish
+to instruct your show() function (described below) to print a header at the
+top of the output. SEQ_START_TOKEN should only be used if the offset is
+zero, however.
+
+The next function to implement is called, amazingly, next(); its job is to
+move the iterator forward to the next position in the sequence.  The
+example module can simply increment the position by one; more useful
+modules will do what is needed to step through some data structure. The
+next() function returns a new iterator, or NULL if the sequence is
+complete. Here's the example version:
+
+       static void *ct_seq_next(struct seq_file *s, void *v, loff_t *pos)
+       {
+               loff_t *spos = v;
+               *pos = ++*spos;
+               return spos;
+       }
+
+The stop() function is called when iteration is complete; its job, of
+course, is to clean up. If dynamic memory is allocated for the iterator,
+stop() is the place to free it.
+
+       static void ct_seq_stop(struct seq_file *s, void *v)
+       {
+               kfree(v);
+       }
+
+Finally, the show() function should format the object currently pointed to
+by the iterator for output. It should return zero, or an error code if
+something goes wrong. The example module's show() function is:
+
+       static int ct_seq_show(struct seq_file *s, void *v)
+       {
+               loff_t *spos = v;
+               seq_printf(s, "%lld\n", (long long)*spos);
+               return 0;
+       }
+
+We will look at seq_printf() in a moment. But first, the definition of the
+seq_file iterator is finished by creating a seq_operations structure with
+the four functions we have just defined:
+
+       static const struct seq_operations ct_seq_ops = {
+               .start = ct_seq_start,
+               .next  = ct_seq_next,
+               .stop  = ct_seq_stop,
+               .show  = ct_seq_show
+       };
+
+This structure will be needed to tie our iterator to the /proc file in
+a little bit.
+
+It's worth noting that the iterator value returned by start() and
+manipulated by the other functions is considered to be completely opaque by
+the seq_file code. It can thus be anything that is useful in stepping
+through the data to be output. Counters can be useful, but it could also be
+a direct pointer into an array or linked list. Anything goes, as long as
+the programmer is aware that things can happen between calls to the
+iterator function. However, the seq_file code (by design) will not sleep
+between the calls to start() and stop(), so holding a lock during that time
+is a reasonable thing to do. The seq_file code will also avoid taking any
+other locks while the iterator is active.
+
+
+Formatted output
+
+The seq_file code manages positioning within the output created by the
+iterator and getting it into the user's buffer. But, for that to work, that
+output must be passed to the seq_file code. Some utility functions have
+been defined which make this task easy.
+
+Most code will simply use seq_printf(), which works pretty much like
+printk(), but which requires the seq_file pointer as an argument. It is
+common to ignore the return value from seq_printf(), but a function
+producing complicated output may want to check that value and quit if
+something non-zero is returned; an error return means that the seq_file
+buffer has been filled and further output will be discarded.
+
+For straight character output, the following functions may be used:
+
+       int seq_putc(struct seq_file *m, char c);
+       int seq_puts(struct seq_file *m, const char *s);
+       int seq_escape(struct seq_file *m, const char *s, const char *esc);
+
+The first two output a single character and a string, just like one would
+expect. seq_escape() is like seq_puts(), except that any character in s
+which is in the string esc will be represented in octal form in the output.
+
+There is also a function for printing filenames:
+
+       int seq_path(struct seq_file *m, struct path *path, char *esc);
+
+Here, path indicates the file of interest, and esc is a set of characters
+which should be escaped in the output.
+
+
+Making it all work
+
+So far, we have a nice set of functions which can produce output within the
+seq_file system, but we have not yet turned them into a file that a user
+can see. Creating a file within the kernel requires, of course, the
+creation of a set of file_operations which implement the operations on that
+file. The seq_file interface provides a set of canned operations which do
+most of the work. The virtual file author still must implement the open()
+method, however, to hook everything up. The open function is often a single
+line, as in the example module:
+
+       static int ct_open(struct inode *inode, struct file *file)
+       {
+               return seq_open(file, &ct_seq_ops);
+       }
+
+Here, the call to seq_open() takes the seq_operations structure we created
+before, and gets set up to iterate through the virtual file.
+
+On a successful open, seq_open() stores the struct seq_file pointer in
+file->private_data. If you have an application where the same iterator can
+be used for more than one file, you can store an arbitrary pointer in the
+private field of the seq_file structure; that value can then be retrieved
+by the iterator functions.
+
+The other operations of interest - read(), llseek(), and release() - are
+all implemented by the seq_file code itself. So a virtual file's
+file_operations structure will look like:
+
+       static const struct file_operations ct_file_ops = {
+               .owner   = THIS_MODULE,
+               .open    = ct_open,
+               .read    = seq_read,
+               .llseek  = seq_lseek,
+               .release = seq_release
+       };
+
+There is also a seq_release_private() which passes the contents of the
+seq_file private field to kfree() before releasing the structure.
+
+The final step is the creation of the /proc file itself. In the example
+code, that is done in the initialization code in the usual way:
+
+       static int ct_init(void)
+       {
+               struct proc_dir_entry *entry;
+
+               entry = create_proc_entry("sequence", 0, NULL);
+               if (entry)
+                       entry->proc_fops = &ct_file_ops;
+               return 0;
+       }
+
+       module_init(ct_init);
+
+And that is pretty much it.
+
+
+seq_list
+
+If your file will be iterating through a linked list, you may find these
+routines useful:
+
+       struct list_head *seq_list_start(struct list_head *head,
+                                        loff_t pos);
+       struct list_head *seq_list_start_head(struct list_head *head,
+                                             loff_t pos);
+       struct list_head *seq_list_next(void *v, struct list_head *head,
+                                       loff_t *ppos);
+
+These helpers will interpret pos as a position within the list and iterate
+accordingly.  Your start() and next() functions need only invoke the
+seq_list_* helpers with a pointer to the appropriate list_head structure.
+
+
+The extra-simple version
+
+For extremely simple virtual files, there is an even easier interface.  A
+module can define only the show() function, which should create all the
+output that the virtual file will contain. The file's open() method then
+calls:
+
+       int single_open(struct file *file,
+                       int (*show)(struct seq_file *m, void *p),
+                       void *data);
+
+When output time comes, the show() function will be called once. The data
+value given to single_open() can be found in the private field of the
+seq_file structure. When using single_open(), the programmer should use
+single_release() instead of seq_release() in the file_operations structure
+to avoid a memory leak.
index ce0e9a9..a73ecf5 100644 (file)
@@ -98,7 +98,7 @@ System-level global event devices are used for the Linux periodic tick. Per-CPU
 event devices are used to provide local CPU functionality such as process
 accounting, profiling, and high resolution timers.
 
-The management layer assignes one or more of the folliwing functions to a clock
+The management layer assigns one or more of the following functions to a clock
 event device:
       - system global periodic tick (jiffies update)
       - cpu local update_process_times
index 32e9297..5389acf 100644 (file)
@@ -844,7 +844,7 @@ and is between 256 and 4096 characters. It is defined in the file
                        arch/alpha/kernel/core_marvel.c.
 
        ip=             [IP_PNP]
-                       See Documentation/nfsroot.txt.
+                       See Documentation/filesystems/nfsroot.txt.
 
        ip2=            [HW] Set IO/IRQ pairs for up to 4 IntelliPort boards
                        See comment before ip2_setup() in
@@ -1198,10 +1198,10 @@ and is between 256 and 4096 characters. It is defined in the file
                        file if at all.
 
        nfsaddrs=       [NFS]
-                       See Documentation/nfsroot.txt.
+                       See Documentation/filesystems/nfsroot.txt.
 
        nfsroot=        [NFS] nfs root filesystem for disk-less boxes.
-                       See Documentation/nfsroot.txt.
+                       See Documentation/filesystems/nfsroot.txt.
 
        nfs.callback_tcpport=
                        [NFS] set the TCP port on which the NFSv4 callback
@@ -1339,6 +1339,10 @@ and is between 256 and 4096 characters. It is defined in the file
 
        nowb            [ARM]
 
+       nptcg=          [IA64] Override max number of concurrent global TLB
+                       purges which is reported from either PAL_VM_SUMMARY or
+                       SAL PALO.
+
        numa_zonelist_order= [KNL, BOOT] Select zonelist order for NUMA.
                        one of ['zone', 'node', 'default'] can be specified
                        This can be set from sysctl after boot.
index f1b2de1..641d2af 100644 (file)
@@ -281,10 +281,10 @@ solution for a couple of reasons:
             sa_family_t can_family;
             int         can_ifindex;
             union {
-                    struct { canid_t rx_id, tx_id; } tp16;
-                    struct { canid_t rx_id, tx_id; } tp20;
-                    struct { canid_t rx_id, tx_id; } mcnet;
-                    struct { canid_t rx_id, tx_id; } isotp;
+                    /* transport protocol class address info (e.g. ISOTP) */
+                    struct { canid_t rx_id, tx_id; } tp;
+
+                    /* reserved for future CAN protocols address information */
             } can_addr;
     };
 
index b5f5ca0..fc234d0 100644 (file)
@@ -12,5 +12,7 @@ sched-domains.txt
        - information on scheduling domains.
 sched-nice-design.txt
        - How and why the scheduler's nice levels are implemented.
+sched-rt-group.txt
+       - real-time group scheduling.
 sched-stats.txt
        - information on schedstats (Linux Scheduler Statistics).
index 8861e47..6d5f181 100644 (file)
@@ -116,6 +116,13 @@ low order bit.  So when a chip's timing diagram shows the clock
 starting low (CPOL=0) and data stabilized for sampling during the
 trailing clock edge (CPHA=1), that's SPI mode 1.
 
+Note that the clock mode is relevant as soon as the chipselect goes
+active.  So the master must set the clock to inactive before selecting
+a slave, and the slave can tell the chosen polarity by sampling the
+clock level when its select line goes active.  That's why many devices
+support for example both modes 0 and 3:  they don't care about polarity,
+and alway clock data in/out on rising clock edges.
+
 
 How do these driver programming interfaces work?
 ------------------------------------------------
@@ -379,8 +386,14 @@ any more such messages.
       + when bidirectional reads and writes start ... by how its
         sequence of spi_transfer requests is arranged;
 
+      + which I/O buffers are used ... each spi_transfer wraps a
+        buffer for each transfer direction, supporting full duplex
+        (two pointers, maybe the same one in both cases) and half
+        duplex (one pointer is NULL) transfers;
+
       + optionally defining short delays after transfers ... using
-        the spi_transfer.delay_usecs setting;
+        the spi_transfer.delay_usecs setting (this delay can be the
+        only protocol effect, if the buffer length is zero);
 
       + whether the chipselect becomes inactive after a transfer and
         any delay ... by using the spi_transfer.cs_change flag;
index 471e753..619699d 100644 (file)
@@ -5,6 +5,28 @@ Please use DEFINE_SPINLOCK()/DEFINE_RWLOCK() or
 __SPIN_LOCK_UNLOCKED()/__RW_LOCK_UNLOCKED() as appropriate for static
 initialization.
 
+Most of the time, you can simply turn:
+
+       static spinlock_t xxx_lock = SPIN_LOCK_UNLOCKED;
+
+into:
+
+       static DEFINE_SPINLOCK(xxx_lock);
+
+Static structure member variables go from:
+
+       struct foo bar {
+               .lock   =       SPIN_LOCK_UNLOCKED;
+       };
+
+to:
+
+       struct foo bar {
+               .lock   =       __SPIN_LOCK_UNLOCKED(bar.lock);
+       };
+
+Declaration of static rw_locks undergo a similar transformation.
+
 Dynamic initialization, when necessary, may be performed as
 demonstrated below.
 
index f962d01..3102b81 100644 (file)
@@ -88,10 +88,9 @@ hugepages from the buddy allocator, if the normal pool is exhausted. As
 these surplus hugepages go out of use, they are freed back to the buddy
 allocator.
 
-Caveat: Shrinking the pool via nr_hugepages while a surplus is in effect
-will allow the number of surplus huge pages to exceed the overcommit
-value, as the pool hugepages (which must have been in use for a surplus
-hugepages to be allocated) will become surplus hugepages.  As long as
+Caveat: Shrinking the pool via nr_hugepages such that it becomes less
+than the number of hugepages in use will convert the balance to surplus
+huge pages even if it would exceed the overcommit value.  As long as
 this condition holds, however, no more surplus huge pages will be
 allowed on the system until one of the two sysctls are increased
 sufficiently, or the surplus huge pages go out of use and are freed.
index 90dcbbc..e467758 100644 (file)
@@ -2116,7 +2116,7 @@ M:        reinette.chatre@intel.com
 L:     linux-wireless@vger.kernel.org
 L:     ipw3945-devel@lists.sourceforge.net
 W:     http://intellinuxwireless.org
-T:     git git://git.kernel.org/pub/scm/linux/kernel/git/rchatre/iwlwifi-2.6.git
+T:     git kernel.org:/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6.git
 S:     Supported
 
 IOC3 ETHERNET DRIVER
@@ -2197,7 +2197,7 @@ S:        Maintained
 ISDN SUBSYSTEM
 P:     Karsten Keil
 M:     kkeil@suse.de
-L:     isdn4linux@listserv.isdn4linux.de
+L:     isdn4linux@listserv.isdn4linux.de (subscribers-only)
 W:     http://www.isdn4linux.de
 T:     git kernel.org:/pub/scm/linux/kernel/kkeil/isdn-2.6.git
 S:     Maintained
@@ -2205,7 +2205,7 @@ S:        Maintained
 ISDN SUBSYSTEM (Eicon active card driver)
 P:     Armin Schindler
 M:     mac@melware.de
-L:     isdn4linux@listserv.isdn4linux.de
+L:     isdn4linux@listserv.isdn4linux.de (subscribers-only)
 W:     http://www.melware.de
 S:     Maintained
 
@@ -3280,6 +3280,7 @@ L:        linux-wireless@vger.kernel.org
 L:     rt2400-devel@lists.sourceforge.net
 W:     http://rt2x00.serialmonkey.com/
 S:     Maintained
+T:     git kernel.org:/pub/scm/linux/kernel/git/ivd/rt2x00.git
 F:     drivers/net/wireless/rt2x00/
 
 RAMDISK RAM BLOCK DEVICE DRIVER
@@ -3342,6 +3343,13 @@ L:       reiserfs-devel@vger.kernel.org
 W:     http://www.namesys.com
 S:     Supported
 
+RFKILL
+P:     Ivo van Doorn
+M:     IvDoorn@gmail.com
+L:     netdev@vger.kernel.org
+S:     Maintained
+F:     net/rfkill
+
 ROCKETPORT DRIVER
 P:     Comtrol Corp.
 W:     http://www.comtrol.com
index fec2a12..39516bf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 6
 SUBLEVEL = 25
-EXTRAVERSION = -rc8
+EXTRAVERSION =
 NAME = Funky Weasel is Jiggy wit it
 
 # *DOCUMENTATION*
index c75d708..28e0caf 100644 (file)
@@ -10,7 +10,6 @@ config AVR32
        # With EMBEDDED=n, we get lots of stuff automatically selected
        # that we usually don't need on AVR32.
        select EMBEDDED
-       select HAVE_IDE
        select HAVE_OPROFILE
        select HAVE_KPROBES
        help
index d3b9253..bf35f33 100644 (file)
@@ -316,8 +316,14 @@ __trap_fixup_kernel_data_tlb_miss:
        .section        .trap.vector
        .org            TBR_TT_TRAP0 >> 2
        .long           system_call
-       .rept           126
+       .rept           119
        .long           __entry_unsupported_trap
        .endr
+
+       # userspace atomic op emulation, traps 120-126
+       .rept           7
+       .long           __entry_atomic_op
+       .endr
+       
        .org            TBR_TT_BREAK >> 2
        .long           __entry_debug_exception
index f36d7f4..b8a4b94 100644 (file)
@@ -656,6 +656,26 @@ __entry_debug_exception:
 
 ###############################################################################
 #
+# handle atomic operation emulation for userspace
+#
+###############################################################################
+       .globl          __entry_atomic_op
+__entry_atomic_op:
+       LEDS            0x6012
+       sethi.p         %hi(atomic_operation),gr5
+       setlo           %lo(atomic_operation),gr5
+       movsg           esfr1,gr8
+       movsg           epcr0,gr9
+       movsg           esr0,gr10
+
+       # now that we've accessed the exception regs, we can enable exceptions
+       movsg           psr,gr4
+       ori             gr4,#PSR_ET,gr4
+       movgs           gr4,psr
+       jmpl            @(gr5,gr0)      ; call atomic_operation(esfr1,epcr0,esr0)
+
+###############################################################################
+#
 # handle media exception
 #
 ###############################################################################
index d424cd2..bff6662 100644 (file)
@@ -46,5 +46,5 @@
 #ifdef CONFIG_MMU
 __sdram_base = 0x00000000              /* base address to which SDRAM relocated */
 #else
-__sdram_base = 0xc0000000              /* base address to which SDRAM relocated */
+__sdram_base = __page_offset           /* base address to which SDRAM relocated */
 #endif
index b5275fa..b066686 100644 (file)
@@ -102,13 +102,6 @@ __switch_to:
        movgs           gr14,lr
        bar
 
-       srli            gr15,#28,gr5
-       subicc          gr5,#0xc,gr0,icc0
-       beq             icc0,#0,111f
-       break
-       nop
-111:
-
        # jump to __switch_back or ret_from_fork as appropriate
        # - move prev to GR8
        movgs           gr4,psr
index 2e6098c..7089c24 100644 (file)
@@ -73,7 +73,7 @@ asmlinkage void illegal_instruction(unsigned long esfr1, unsigned long epcr0, un
                      epcr0, esr0, esfr1);
 
        info.si_errno   = 0;
-       info.si_addr    = (void *) ((epcr0 & EPCR0_PC) ? (epcr0 & EPCR0_PC) : __frame->pc);
+       info.si_addr    = (void *) ((epcr0 & EPCR0_V) ? (epcr0 & EPCR0_PC) : __frame->pc);
 
        switch (__frame->tbr & TBR_TT) {
        case TBR_TT_ILLEGAL_INSTR:
@@ -102,6 +102,233 @@ asmlinkage void illegal_instruction(unsigned long esfr1, unsigned long epcr0, un
 
 /*****************************************************************************/
 /*
+ * handle atomic operations with errors
+ * - arguments in gr8, gr9, gr10
+ * - original memory value placed in gr5
+ * - replacement memory value placed in gr9
+ */
+asmlinkage void atomic_operation(unsigned long esfr1, unsigned long epcr0,
+                                unsigned long esr0)
+{
+       static DEFINE_SPINLOCK(atomic_op_lock);
+       unsigned long x, y, z, *p;
+       mm_segment_t oldfs;
+       siginfo_t info;
+       int ret;
+
+       y = 0;
+       z = 0;
+
+       oldfs = get_fs();
+       if (!user_mode(__frame))
+               set_fs(KERNEL_DS);
+
+       switch (__frame->tbr & TBR_TT) {
+               /* TIRA gr0,#120
+                * u32 __atomic_user_cmpxchg32(u32 *ptr, u32 test, u32 new)
+                */
+       case TBR_TT_ATOMIC_CMPXCHG32:
+               p = (unsigned long *) __frame->gr8;
+               x = __frame->gr9;
+               y = __frame->gr10;
+
+               for (;;) {
+                       ret = get_user(z, p);
+                       if (ret < 0)
+                               goto error;
+
+                       if (z != x)
+                               goto done;
+
+                       spin_lock_irq(&atomic_op_lock);
+
+                       if (__get_user(z, p) == 0) {
+                               if (z != x)
+                                       goto done2;
+
+                               if (__put_user(y, p) == 0)
+                                       goto done2;
+                               goto error2;
+                       }
+
+                       spin_unlock_irq(&atomic_op_lock);
+               }
+
+               /* TIRA gr0,#121
+                * u32 __atomic_kernel_xchg32(void *v, u32 new)
+                */
+       case TBR_TT_ATOMIC_XCHG32:
+               p = (unsigned long *) __frame->gr8;
+               y = __frame->gr9;
+
+               for (;;) {
+                       ret = get_user(z, p);
+                       if (ret < 0)
+                               goto error;
+
+                       spin_lock_irq(&atomic_op_lock);
+
+                       if (__get_user(z, p) == 0) {
+                               if (__put_user(y, p) == 0)
+                                       goto done2;
+                               goto error2;
+                       }
+
+                       spin_unlock_irq(&atomic_op_lock);
+               }
+
+               /* TIRA gr0,#122
+                * ulong __atomic_kernel_XOR_return(ulong i, ulong *v)
+                */
+       case TBR_TT_ATOMIC_XOR:
+               p = (unsigned long *) __frame->gr8;
+               x = __frame->gr9;
+
+               for (;;) {
+                       ret = get_user(z, p);
+                       if (ret < 0)
+                               goto error;
+
+                       spin_lock_irq(&atomic_op_lock);
+
+                       if (__get_user(z, p) == 0) {
+                               y = x ^ z;
+                               if (__put_user(y, p) == 0)
+                                       goto done2;
+                               goto error2;
+                       }
+
+                       spin_unlock_irq(&atomic_op_lock);
+               }
+
+               /* TIRA gr0,#123
+                * ulong __atomic_kernel_OR_return(ulong i, ulong *v)
+                */
+       case TBR_TT_ATOMIC_OR:
+               p = (unsigned long *) __frame->gr8;
+               x = __frame->gr9;
+
+               for (;;) {
+                       ret = get_user(z, p);
+                       if (ret < 0)
+                               goto error;
+
+                       spin_lock_irq(&atomic_op_lock);
+
+                       if (__get_user(z, p) == 0) {
+                               y = x ^ z;
+                               if (__put_user(y, p) == 0)
+                                       goto done2;
+                               goto error2;
+                       }
+
+                       spin_unlock_irq(&atomic_op_lock);
+               }
+
+               /* TIRA gr0,#124
+                * ulong __atomic_kernel_AND_return(ulong i, ulong *v)
+                */
+       case TBR_TT_ATOMIC_AND:
+               p = (unsigned long *) __frame->gr8;
+               x = __frame->gr9;
+
+               for (;;) {
+                       ret = get_user(z, p);
+                       if (ret < 0)
+                               goto error;
+
+                       spin_lock_irq(&atomic_op_lock);
+
+                       if (__get_user(z, p) == 0) {
+                               y = x & z;
+                               if (__put_user(y, p) == 0)
+                                       goto done2;
+                               goto error2;
+                       }
+
+                       spin_unlock_irq(&atomic_op_lock);
+               }
+
+               /* TIRA gr0,#125
+                * int __atomic_user_sub_return(atomic_t *v, int i)
+                */
+       case TBR_TT_ATOMIC_SUB:
+               p = (unsigned long *) __frame->gr8;
+               x = __frame->gr9;
+
+               for (;;) {
+                       ret = get_user(z, p);
+                       if (ret < 0)
+                               goto error;
+
+                       spin_lock_irq(&atomic_op_lock);
+
+                       if (__get_user(z, p) == 0) {
+                               y = z - x;
+                               if (__put_user(y, p) == 0)
+                                       goto done2;
+                               goto error2;
+                       }
+
+                       spin_unlock_irq(&atomic_op_lock);
+               }
+
+               /* TIRA gr0,#126
+                * int __atomic_user_add_return(atomic_t *v, int i)
+                */
+       case TBR_TT_ATOMIC_ADD:
+               p = (unsigned long *) __frame->gr8;
+               x = __frame->gr9;
+
+               for (;;) {
+                       ret = get_user(z, p);
+                       if (ret < 0)
+                               goto error;
+
+                       spin_lock_irq(&atomic_op_lock);
+
+                       if (__get_user(z, p) == 0) {
+                               y = z + x;
+                               if (__put_user(y, p) == 0)
+                                       goto done2;
+                               goto error2;
+                       }
+
+                       spin_unlock_irq(&atomic_op_lock);
+               }
+
+       default:
+               BUG();
+       }
+
+done2:
+       spin_unlock_irq(&atomic_op_lock);
+done:
+       if (!user_mode(__frame))
+               set_fs(oldfs);
+       __frame->gr5 = z;
+       __frame->gr9 = y;
+       return;
+
+error2:
+       spin_unlock_irq(&atomic_op_lock);
+error:
+       if (!user_mode(__frame))
+               set_fs(oldfs);
+       __frame->pc -= 4;
+
+       die_if_kernel("-- Atomic Op Error --\n");
+
+       info.si_signo   = SIGSEGV;
+       info.si_code    = SEGV_ACCERR;
+       info.si_errno   = 0;
+       info.si_addr    = (void *) __frame->pc;
+
+       force_sig_info(info.si_signo, &info, current);
+}
+
+/*****************************************************************************/
+/*
  *
  */
 asmlinkage void media_exception(unsigned long msr0, unsigned long msr1)
index 1b73ffe..ed21737 100644 (file)
@@ -283,6 +283,17 @@ config FORCE_MAX_ZONEORDER
        default "17" if HUGETLB_PAGE
        default "11"
 
+config VIRT_CPU_ACCOUNTING
+       bool "Deterministic task and CPU time accounting"
+       default n
+       help
+         Select this option to enable more accurate task and CPU time
+         accounting.  This is done by reading a CPU counter on each
+         kernel entry and exit and on transitions within the kernel
+         between system, softirq and hardirq state, so there is a
+         small performance impact.
+         If in doubt, say N here.
+
 config SMP
        bool "Symmetric multi-processing support"
        help
index 446c9aa..9a3abf5 100644 (file)
@@ -30,7 +30,19 @@ struct elf_siginfo
        int     si_errno;                       /* errno */
 };
 
-#define jiffies_to_timeval(a,b) do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; }while(0)
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+/*
+ * Hacks are here since types between compat_timeval (= pair of s32) and
+ * ia64-native timeval (= pair of s64) are not compatible, at least a file
+ * arch/ia64/ia32/../../../fs/binfmt_elf.c will get warnings from compiler on
+ * use of cputime_to_timeval(), which usually an alias of jiffies_to_timeval().
+ */
+#define cputime_to_timeval(a,b) \
+       do { (b)->tv_usec = 0; (b)->tv_sec = (a)/NSEC_PER_SEC; } while(0)
+#else
+#define jiffies_to_timeval(a,b) \
+       do { (b)->tv_usec = 0; (b)->tv_sec = (a)/HZ; } while(0)
+#endif
 
 struct elf_prstatus
 {
index b1bf51f..7e028ce 100644 (file)
@@ -38,6 +38,7 @@
 #include <linux/eventpoll.h>
 #include <linux/personality.h>
 #include <linux/ptrace.h>
+#include <linux/regset.h>
 #include <linux/stat.h>
 #include <linux/ipc.h>
 #include <linux/capability.h>
@@ -2387,16 +2388,45 @@ get_free_idx (void)
        return -ESRCH;
 }
 
+static void set_tls_desc(struct task_struct *p, int idx,
+               const struct ia32_user_desc *info, int n)
+{
+       struct thread_struct *t = &p->thread;
+       struct desc_struct *desc = &t->tls_array[idx - GDT_ENTRY_TLS_MIN];
+       int cpu;
+
+       /*
+        * We must not get preempted while modifying the TLS.
+        */
+       cpu = get_cpu();
+
+       while (n-- > 0) {
+               if (LDT_empty(info)) {
+                       desc->a = 0;
+                       desc->b = 0;
+               } else {
+                       desc->a = LDT_entry_a(info);
+                       desc->b = LDT_entry_b(info);
+               }
+
+               ++info;
+               ++desc;
+       }
+
+       if (t == &current->thread)
+               load_TLS(t, cpu);
+
+       put_cpu();
+}
+
 /*
  * Set a given TLS descriptor:
  */
 asmlinkage int
 sys32_set_thread_area (struct ia32_user_desc __user *u_info)
 {
-       struct thread_struct *t = &current->thread;
        struct ia32_user_desc info;
-       struct desc_struct *desc;
-       int cpu, idx;
+       int idx;
 
        if (copy_from_user(&info, u_info, sizeof(info)))
                return -EFAULT;
@@ -2416,18 +2446,7 @@ sys32_set_thread_area (struct ia32_user_desc __user *u_info)
        if (idx < GDT_ENTRY_TLS_MIN || idx > GDT_ENTRY_TLS_MAX)
                return -EINVAL;
 
-       desc = t->tls_array + idx - GDT_ENTRY_TLS_MIN;
-
-       cpu = smp_processor_id();
-
-       if (LDT_empty(&info)) {
-               desc->a = 0;
-               desc->b = 0;
-       } else {
-               desc->a = LDT_entry_a(&info);
-               desc->b = LDT_entry_b(&info);
-       }
-       load_TLS(t, cpu);
+       set_tls_desc(current, idx, &info, 1);
        return 0;
 }
 
@@ -2451,6 +2470,20 @@ sys32_set_thread_area (struct ia32_user_desc __user *u_info)
 #define GET_PRESENT(desc)      (((desc)->b >> 15) & 1)
 #define GET_USEABLE(desc)      (((desc)->b >> 20) & 1)
 
+static void fill_user_desc(struct ia32_user_desc *info, int idx,
+               const struct desc_struct *desc)
+{
+       info->entry_number = idx;
+       info->base_addr = GET_BASE(desc);
+       info->limit = GET_LIMIT(desc);
+       info->seg_32bit = GET_32BIT(desc);
+       info->contents = GET_CONTENTS(desc);
+       info->read_exec_only = !GET_WRITABLE(desc);
+       info->limit_in_pages = GET_LIMIT_PAGES(desc);
+       info->seg_not_present = !GET_PRESENT(desc);
+       info->useable = GET_USEABLE(desc);
+}
+
 asmlinkage int
 sys32_get_thread_area (struct ia32_user_desc __user *u_info)
 {
@@ -2464,22 +2497,588 @@ sys32_get_thread_area (struct ia32_user_desc __user *u_info)
                return -EINVAL;
 
        desc = current->thread.tls_array + idx - GDT_ENTRY_TLS_MIN;
-
-       info.entry_number = idx;
-       info.base_addr = GET_BASE(desc);
-       info.limit = GET_LIMIT(desc);
-       info.seg_32bit = GET_32BIT(desc);
-       info.contents = GET_CONTENTS(desc);
-       info.read_exec_only = !GET_WRITABLE(desc);
-       info.limit_in_pages = GET_LIMIT_PAGES(desc);
-       info.seg_not_present = !GET_PRESENT(desc);
-       info.useable = GET_USEABLE(desc);
+       fill_user_desc(&info, idx, desc);
 
        if (copy_to_user(u_info, &info, sizeof(info)))
                return -EFAULT;
        return 0;
 }
 
+struct regset_get {
+       void *kbuf;
+       void __user *ubuf;
+};
+
+struct regset_set {
+       const void *kbuf;
+       const void __user *ubuf;
+};
+
+struct regset_getset {
+       struct task_struct *target;
+       const struct user_regset *regset;
+       union {
+               struct regset_get get;
+               struct regset_set set;
+       } u;
+       unsigned int pos;
+       unsigned int count;
+       int ret;
+};
+
+static void getfpreg(struct task_struct *task, int regno, int *val)
+{
+       switch (regno / sizeof(int)) {
+       case 0:
+               *val = task->thread.fcr & 0xffff;
+               break;
+       case 1:
+               *val = task->thread.fsr & 0xffff;
+               break;
+       case 2:
+               *val = (task->thread.fsr>>16) & 0xffff;
+               break;
+       case 3:
+               *val = task->thread.fir;
+               break;
+       case 4:
+               *val = (task->thread.fir>>32) & 0xffff;
+               break;
+       case 5:
+               *val = task->thread.fdr;
+               break;
+       case 6:
+               *val = (task->thread.fdr >> 32) & 0xffff;
+               break;
+       }
+}
+
+static void setfpreg(struct task_struct *task, int regno, int val)
+{
+       switch (regno / sizeof(int)) {
+       case 0:
+               task->thread.fcr = (task->thread.fcr & (~0x1f3f))
+                       | (val & 0x1f3f);
+               break;
+       case 1:
+               task->thread.fsr = (task->thread.fsr & (~0xffff)) | val;
+               break;
+       case 2:
+               task->thread.fsr = (task->thread.fsr & (~0xffff0000))
+                       | (val << 16);
+               break;
+       case 3:
+               task->thread.fir = (task->thread.fir & (~0xffffffff)) | val;
+               break;
+       case 5:
+               task->thread.fdr = (task->thread.fdr & (~0xffffffff)) | val;
+               break;
+       }
+}
+
+static void access_fpreg_ia32(int regno, void *reg,
+               struct pt_regs *pt, struct switch_stack *sw,
+               int tos, int write)
+{
+       void *f;
+
+       if ((regno += tos) >= 8)
+               regno -= 8;
+       if (regno < 4)
+               f = &pt->f8 + regno;
+       else if (regno <= 7)
+               f = &sw->f12 + (regno - 4);
+       else {
+               printk(KERN_ERR "regno must be less than 7 \n");
+                return;
+       }
+
+       if (write)
+               memcpy(f, reg, sizeof(struct _fpreg_ia32));
+       else
+               memcpy(reg, f, sizeof(struct _fpreg_ia32));
+}
+
+static void do_fpregs_get(struct unw_frame_info *info, void *arg)
+{
+       struct regset_getset *dst = arg;
+       struct task_struct *task = dst->target;
+       struct pt_regs *pt;
+       int start, end, tos;
+       char buf[80];
+
+       if (dst->count == 0 || unw_unwind_to_user(info) < 0)
+               return;
+       if (dst->pos < 7 * sizeof(int)) {
+               end = min((dst->pos + dst->count),
+                       (unsigned int)(7 * sizeof(int)));
+               for (start = dst->pos; start < end; start += sizeof(int))
+                       getfpreg(task, start, (int *)(buf + start));
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf, buf,
+                               0, 7 * sizeof(int));
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+       if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
+               pt = task_pt_regs(task);
+               tos = (task->thread.fsr >> 11) & 7;
+               end = min(dst->pos + dst->count,
+                       (unsigned int)(sizeof(struct ia32_user_i387_struct)));
+               start = (dst->pos - 7 * sizeof(int)) /
+                       sizeof(struct _fpreg_ia32);
+               end = (end - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
+               for (; start < end; start++)
+                       access_fpreg_ia32(start,
+                               (struct _fpreg_ia32 *)buf + start,
+                               pt, info->sw, tos, 0);
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf,
+                               buf, 7 * sizeof(int),
+                               sizeof(struct ia32_user_i387_struct));
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+}
+
+static void do_fpregs_set(struct unw_frame_info *info, void *arg)
+{
+       struct regset_getset *dst = arg;
+       struct task_struct *task = dst->target;
+       struct pt_regs *pt;
+       char buf[80];
+       int end, start, tos;
+
+       if (dst->count == 0 || unw_unwind_to_user(info) < 0)
+               return;
+
+       if (dst->pos < 7 * sizeof(int)) {
+               start = dst->pos;
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf, buf,
+                               0, 7 * sizeof(int));
+               if (dst->ret)
+                       return;
+               for (; start < dst->pos; start += sizeof(int))
+                       setfpreg(task, start, *((int *)(buf + start)));
+               if (dst->count == 0)
+                       return;
+       }
+       if (dst->pos < sizeof(struct ia32_user_i387_struct)) {
+               start = (dst->pos - 7 * sizeof(int)) /
+                       sizeof(struct _fpreg_ia32);
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf,
+                               buf, 7 * sizeof(int),
+                               sizeof(struct ia32_user_i387_struct));
+               if (dst->ret)
+                       return;
+               pt = task_pt_regs(task);
+               tos = (task->thread.fsr >> 11) & 7;
+               end = (dst->pos - 7 * sizeof(int)) / sizeof(struct _fpreg_ia32);
+               for (; start < end; start++)
+                       access_fpreg_ia32(start,
+                               (struct _fpreg_ia32 *)buf + start,
+                               pt, info->sw, tos, 1);
+               if (dst->count == 0)
+                       return;
+       }
+}
+
+#define OFFSET(member) ((int)(offsetof(struct ia32_user_fxsr_struct, member)))
+static void getfpxreg(struct task_struct *task, int start, int end, char *buf)
+{
+       int min_val;
+
+       min_val = min(end, OFFSET(fop));
+       while (start < min_val) {
+               if (start == OFFSET(cwd))
+                       *((short *)buf) = task->thread.fcr & 0xffff;
+               else if (start == OFFSET(swd))
+                       *((short *)buf) = task->thread.fsr & 0xffff;
+               else if (start == OFFSET(twd))
+                       *((short *)buf) = (task->thread.fsr>>16) & 0xffff;
+               buf += 2;
+               start += 2;
+       }
+       /* skip fop element */
+       if (start == OFFSET(fop)) {
+               start += 2;
+               buf += 2;
+       }
+       while (start < end) {
+               if (start == OFFSET(fip))
+                       *((int *)buf) = task->thread.fir;
+               else if (start == OFFSET(fcs))
+                       *((int *)buf) = (task->thread.fir>>32) & 0xffff;
+               else if (start == OFFSET(foo))
+                       *((int *)buf) = task->thread.fdr;
+               else if (start == OFFSET(fos))
+                       *((int *)buf) = (task->thread.fdr>>32) & 0xffff;
+               else if (start == OFFSET(mxcsr))
+                       *((int *)buf) = ((task->thread.fcr>>32) & 0xff80)
+                                        | ((task->thread.fsr>>32) & 0x3f);
+               buf += 4;
+               start += 4;
+       }
+}
+
+static void setfpxreg(struct task_struct *task, int start, int end, char *buf)
+{
+       int min_val, num32;
+       short num;
+       unsigned long num64;
+
+       min_val = min(end, OFFSET(fop));
+       while (start < min_val) {
+               num = *((short *)buf);
+               if (start == OFFSET(cwd)) {
+                       task->thread.fcr = (task->thread.fcr & (~0x1f3f))
+                                               | (num & 0x1f3f);
+               } else if (start == OFFSET(swd)) {
+                       task->thread.fsr = (task->thread.fsr & (~0xffff)) | num;
+               } else if (start == OFFSET(twd)) {
+                       task->thread.fsr = (task->thread.fsr & (~0xffff0000))
+                               | (((int)num) << 16);
+               }
+               buf += 2;
+               start += 2;
+       }
+       /* skip fop element */
+       if (start == OFFSET(fop)) {
+               start += 2;
+               buf += 2;
+       }
+       while (start < end) {
+               num32 = *((int *)buf);
+               if (start == OFFSET(fip))
+                       task->thread.fir = (task->thread.fir & (~0xffffffff))
+                                                | num32;
+               else if (start == OFFSET(foo))
+                       task->thread.fdr = (task->thread.fdr & (~0xffffffff))
+                                                | num32;
+               else if (start == OFFSET(mxcsr)) {
+                       num64 = num32 & 0xff10;
+                       task->thread.fcr = (task->thread.fcr &
+                               (~0xff1000000000UL)) | (num64<<32);
+                       num64 = num32 & 0x3f;
+                       task->thread.fsr = (task->thread.fsr &
+                               (~0x3f00000000UL)) | (num64<<32);
+               }
+               buf += 4;
+               start += 4;
+       }
+}
+
+static void do_fpxregs_get(struct unw_frame_info *info, void *arg)
+{
+       struct regset_getset *dst = arg;
+       struct task_struct *task = dst->target;
+       struct pt_regs *pt;
+       char buf[128];
+       int start, end, tos;
+
+       if (dst->count == 0 || unw_unwind_to_user(info) < 0)
+               return;
+       if (dst->pos < OFFSET(st_space[0])) {
+               end = min(dst->pos + dst->count, (unsigned int)32);
+               getfpxreg(task, dst->pos, end, buf);
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf, buf,
+                               0, OFFSET(st_space[0]));
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+       if (dst->pos < OFFSET(xmm_space[0])) {
+               pt = task_pt_regs(task);
+               tos = (task->thread.fsr >> 11) & 7;
+               end = min(dst->pos + dst->count,
+                               (unsigned int)OFFSET(xmm_space[0]));
+               start = (dst->pos - OFFSET(st_space[0])) / 16;
+               end = (end - OFFSET(st_space[0])) / 16;
+               for (; start < end; start++)
+                       access_fpreg_ia32(start, buf + 16 * start, pt,
+                                               info->sw, tos, 0);
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf,
+                               buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+       if (dst->pos < OFFSET(padding[0]))
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf,
+                               &info->sw->f16, OFFSET(xmm_space[0]),
+                               OFFSET(padding[0]));
+}
+
+static void do_fpxregs_set(struct unw_frame_info *info, void *arg)
+{
+       struct regset_getset *dst = arg;
+       struct task_struct *task = dst->target;
+       char buf[128];
+       int start, end;
+
+       if (dst->count == 0 || unw_unwind_to_user(info) < 0)
+               return;
+
+       if (dst->pos < OFFSET(st_space[0])) {
+               start = dst->pos;
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf,
+                               buf, 0, OFFSET(st_space[0]));
+               if (dst->ret)
+                       return;
+               setfpxreg(task, start, dst->pos, buf);
+               if (dst->count == 0)
+                       return;
+       }
+       if (dst->pos < OFFSET(xmm_space[0])) {
+               struct pt_regs *pt;
+               int tos;
+               pt = task_pt_regs(task);
+               tos = (task->thread.fsr >> 11) & 7;
+               start = (dst->pos - OFFSET(st_space[0])) / 16;
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf,
+                               buf, OFFSET(st_space[0]), OFFSET(xmm_space[0]));
+               if (dst->ret)
+                       return;
+               end = (dst->pos - OFFSET(st_space[0])) / 16;
+               for (; start < end; start++)
+                       access_fpreg_ia32(start, buf + 16 * start, pt, info->sw,
+                                                tos, 1);
+               if (dst->count == 0)
+                       return;
+       }
+       if (dst->pos < OFFSET(padding[0]))
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf,
+                               &info->sw->f16, OFFSET(xmm_space[0]),
+                                OFFSET(padding[0]));
+}
+#undef OFFSET
+
+static int do_regset_call(void (*call)(struct unw_frame_info *, void *),
+               struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               const void *kbuf, const void __user *ubuf)
+{
+       struct regset_getset info = { .target = target, .regset = regset,
+               .pos = pos, .count = count,
+               .u.set = { .kbuf = kbuf, .ubuf = ubuf },
+               .ret = 0 };
+
+       if (target == current)
+               unw_init_running(call, &info);
+       else {
+               struct unw_frame_info ufi;
+               memset(&ufi, 0, sizeof(ufi));
+               unw_init_from_blocked_task(&ufi, target);
+               (*call)(&ufi, &info);
+       }
+
+       return info.ret;
+}
+
+static int ia32_fpregs_get(struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               void *kbuf, void __user *ubuf)
+{
+       return do_regset_call(do_fpregs_get, target, regset, pos, count,
+               kbuf, ubuf);
+}
+
+static int ia32_fpregs_set(struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               const void *kbuf, const void __user *ubuf)
+{
+       return do_regset_call(do_fpregs_set, target, regset, pos, count,
+               kbuf, ubuf);
+}
+
+static int ia32_fpxregs_get(struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               void *kbuf, void __user *ubuf)
+{
+       return do_regset_call(do_fpxregs_get, target, regset, pos, count,
+               kbuf, ubuf);
+}
+
+static int ia32_fpxregs_set(struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               const void *kbuf, const void __user *ubuf)
+{
+       return do_regset_call(do_fpxregs_set, target, regset, pos, count,
+               kbuf, ubuf);
+}
+
+static int ia32_genregs_get(struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               void *kbuf, void __user *ubuf)
+{
+       if (kbuf) {
+               u32 *kp = kbuf;
+               while (count > 0) {
+                       *kp++ = getreg(target, pos);
+                       pos += 4;
+                       count -= 4;
+               }
+       } else {
+               u32 __user *up = ubuf;
+               while (count > 0) {
+                       if (__put_user(getreg(target, pos), up++))
+                               return -EFAULT;
+                       pos += 4;
+                       count -= 4;
+               }
+       }
+       return 0;
+}
+
+static int ia32_genregs_set(struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               const void *kbuf, const void __user *ubuf)
+{
+       int ret = 0;
+
+       if (kbuf) {
+               const u32 *kp = kbuf;
+               while (!ret && count > 0) {
+                       putreg(target, pos, *kp++);
+                       pos += 4;
+                       count -= 4;
+               }
+       } else {
+               const u32 __user *up = ubuf;
+               u32 val;
+               while (!ret && count > 0) {
+                       ret = __get_user(val, up++);
+                       if (!ret)
+                               putreg(target, pos, val);
+                       pos += 4;
+                       count -= 4;
+               }
+       }
+       return ret;
+}
+
+static int ia32_tls_active(struct task_struct *target,
+               const struct user_regset *regset)
+{
+       struct thread_struct *t = &target->thread;
+       int n = GDT_ENTRY_TLS_ENTRIES;
+       while (n > 0 && desc_empty(&t->tls_array[n -1]))
+               --n;
+       return n;
+}
+
+static int ia32_tls_get(struct task_struct *target,
+               const struct user_regset *regset, unsigned int pos,
+               unsigned int count, void *kbuf, void __user *ubuf)
+{
+       const struct desc_struct *tls;
+
+       if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct ia32_user_desc) ||
+                       (pos % sizeof(struct ia32_user_desc)) != 0 ||
+                       (count % sizeof(struct ia32_user_desc)) != 0)
+               return -EINVAL;
+
+       pos /= sizeof(struct ia32_user_desc);
+       count /= sizeof(struct ia32_user_desc);
+
+       tls = &target->thread.tls_array[pos];
+
+       if (kbuf) {
+               struct ia32_user_desc *info = kbuf;
+               while (count-- > 0)
+                       fill_user_desc(info++, GDT_ENTRY_TLS_MIN + pos++,
+                                       tls++);
+       } else {
+               struct ia32_user_desc __user *u_info = ubuf;
+               while (count-- > 0) {
+                       struct ia32_user_desc info;
+                       fill_user_desc(&info, GDT_ENTRY_TLS_MIN + pos++, tls++);
+                       if (__copy_to_user(u_info++, &info, sizeof(info)))
+                               return -EFAULT;
+               }
+       }
+
+       return 0;
+}
+
+static int ia32_tls_set(struct task_struct *target,
+               const struct user_regset *regset, unsigned int pos,
+               unsigned int count, const void *kbuf, const void __user *ubuf)
+{
+       struct ia32_user_desc infobuf[GDT_ENTRY_TLS_ENTRIES];
+       const struct ia32_user_desc *info;
+
+       if (pos > GDT_ENTRY_TLS_ENTRIES * sizeof(struct ia32_user_desc) ||
+                       (pos % sizeof(struct ia32_user_desc)) != 0 ||
+                       (count % sizeof(struct ia32_user_desc)) != 0)
+               return -EINVAL;
+
+       if (kbuf)
+               info = kbuf;
+       else if (__copy_from_user(infobuf, ubuf, count))
+               return -EFAULT;
+       else
+               info = infobuf;
+
+       set_tls_desc(target,
+               GDT_ENTRY_TLS_MIN + (pos / sizeof(struct ia32_user_desc)),
+               info, count / sizeof(struct ia32_user_desc));
+
+       return 0;
+}
+
+/*
+ * This should match arch/i386/kernel/ptrace.c:native_regsets.
+ * XXX ioperm? vm86?
+ */
+static const struct user_regset ia32_regsets[] = {
+       {
+               .core_note_type = NT_PRSTATUS,
+               .n = sizeof(struct user_regs_struct32)/4,
+               .size = 4, .align = 4,
+               .get = ia32_genregs_get, .set = ia32_genregs_set
+       },
+       {
+               .core_note_type = NT_PRFPREG,
+               .n = sizeof(struct ia32_user_i387_struct) / 4,
+               .size = 4, .align = 4,
+               .get = ia32_fpregs_get, .set = ia32_fpregs_set
+       },
+       {
+               .core_note_type = NT_PRXFPREG,
+               .n = sizeof(struct ia32_user_fxsr_struct) / 4,
+               .size = 4, .align = 4,
+               .get = ia32_fpxregs_get, .set = ia32_fpxregs_set
+       },
+       {
+               .core_note_type = NT_386_TLS,
+               .n = GDT_ENTRY_TLS_ENTRIES,
+               .bias = GDT_ENTRY_TLS_MIN,
+               .size = sizeof(struct ia32_user_desc),
+               .align = sizeof(struct ia32_user_desc),
+               .active = ia32_tls_active,
+               .get = ia32_tls_get, .set = ia32_tls_set,
+       },
+};
+
+const struct user_regset_view user_ia32_view = {
+       .name = "i386", .e_machine = EM_386,
+       .regsets = ia32_regsets, .n = ARRAY_SIZE(ia32_regsets)
+};
+
 long sys32_fadvise64_64(int fd, __u32 offset_low, __u32 offset_high, 
                        __u32 len_low, __u32 len_high, int advice)
 { 
index 78f28d8..c7467f8 100644 (file)
@@ -423,6 +423,7 @@ static u32 __devinitdata pxm_flag[PXM_FLAG_LEN];
 #define pxm_bit_set(bit)       (set_bit(bit,(void *)pxm_flag))
 #define pxm_bit_test(bit)      (test_bit(bit,(void *)pxm_flag))
 static struct acpi_table_slit __initdata *slit_table;
+cpumask_t early_cpu_possible_map = CPU_MASK_NONE;
 
 static int get_processor_proximity_domain(struct acpi_srat_cpu_affinity *pa)
 {
@@ -482,6 +483,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa)
            (pa->apic_id << 8) | (pa->local_sapic_eid);
        /* nid should be overridden as logical node id later */
        node_cpuid[srat_num_cpus].nid = pxm;
+       cpu_set(srat_num_cpus, early_cpu_possible_map);
        srat_num_cpus++;
 }
 
@@ -559,7 +561,7 @@ void __init acpi_numa_arch_fixup(void)
        }
 
        /* set logical node id in cpu structure */
-       for (i = 0; i < srat_num_cpus; i++)
+       for_each_possible_early_cpu(i)
                node_cpuid[i].nid = pxm_to_node(node_cpuid[i].nid);
 
        printk(KERN_INFO "Number of logical nodes in system = %d\n",
index f7bc40d..230a6f9 100644 (file)
@@ -43,6 +43,12 @@ void foo(void)
        DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
        DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
        DEFINE(TI_PRE_COUNT, offsetof(struct thread_info, preempt_count));
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       DEFINE(TI_AC_STAMP, offsetof(struct thread_info, ac_stamp));
+       DEFINE(TI_AC_LEAVE, offsetof(struct thread_info, ac_leave));
+       DEFINE(TI_AC_STIME, offsetof(struct thread_info, ac_stime));
+       DEFINE(TI_AC_UTIME, offsetof(struct thread_info, ac_utime));
+#endif
 
        BLANK();
 
index 728d724..d45f215 100644 (file)
@@ -37,6 +37,7 @@
 #include <asm/pgtable.h>
 #include <asm/processor.h>
 #include <asm/mca.h>
+#include <asm/tlbflush.h>
 
 #define EFI_DEBUG      0
 
@@ -403,6 +404,41 @@ efi_get_pal_addr (void)
        return NULL;
 }
 
+
+static u8 __init palo_checksum(u8 *buffer, u32 length)
+{
+       u8 sum = 0;
+       u8 *end = buffer + length;
+
+       while (buffer < end)
+               sum = (u8) (sum + *(buffer++));
+
+       return sum;
+}
+
+/*
+ * Parse and handle PALO table which is published at:
+ * http://www.dig64.org/home/DIG64_PALO_R1_0.pdf
+ */
+static void __init handle_palo(unsigned long palo_phys)
+{
+       struct palo_table *palo = __va(palo_phys);
+       u8  checksum;
+
+       if (strncmp(palo->signature, PALO_SIG, sizeof(PALO_SIG) - 1)) {
+               printk(KERN_INFO "PALO signature incorrect.\n");
+               return;
+       }
+
+       checksum = palo_checksum((u8 *)palo, palo->length);
+       if (checksum) {
+               printk(KERN_INFO "PALO checksum incorrect.\n");
+               return;
+       }
+
+       setup_ptcg_sem(palo->max_tlb_purges, NPTCG_FROM_PALO);
+}
+
 void
 efi_map_pal_code (void)
 {
@@ -432,6 +468,7 @@ efi_init (void)
        u64 efi_desc_size;
        char *cp, vendor[100] = "unknown";
        int i;
+       unsigned long palo_phys;
 
        /*
         * It's too early to be able to use the standard kernel command line
@@ -496,6 +533,8 @@ efi_init (void)
        efi.hcdp       = EFI_INVALID_TABLE_ADDR;
        efi.uga        = EFI_INVALID_TABLE_ADDR;
 
+       palo_phys      = EFI_INVALID_TABLE_ADDR;
+
        for (i = 0; i < (int) efi.systab->nr_tables; i++) {
                if (efi_guidcmp(config_tables[i].guid, MPS_TABLE_GUID) == 0) {
                        efi.mps = config_tables[i].table;
@@ -515,10 +554,17 @@ efi_init (void)
                } else if (efi_guidcmp(config_tables[i].guid, HCDP_TABLE_GUID) == 0) {
                        efi.hcdp = config_tables[i].table;
                        printk(" HCDP=0x%lx", config_tables[i].table);
+               } else if (efi_guidcmp(config_tables[i].guid,
+                        PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID) == 0) {
+                       palo_phys = config_tables[i].table;
+                       printk(" PALO=0x%lx", config_tables[i].table);
                }
        }
        printk("\n");
 
+       if (palo_phys != EFI_INVALID_TABLE_ADDR)
+               handle_palo(palo_phys);
+
        runtime = __va(efi.systab->runtime);
        efi.get_time = phys_get_time;
        efi.set_time = phys_set_time;
index 3c331c4..b0be4a2 100644 (file)
@@ -710,6 +710,16 @@ ENTRY(ia64_leave_syscall)
 (pUStk)        cmp.eq.unc p6,p0=r0,r0          // p6 <- pUStk
 #endif
 .work_processed_syscall:
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       adds r2=PT(LOADRS)+16,r12
+(pUStk)        mov.m r22=ar.itc                        // fetch time at leave
+       adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
+       ;;
+(p6)   ld4 r31=[r18]                           // load current_thread_info()->flags
+       ld8 r19=[r2],PT(B6)-PT(LOADRS)          // load ar.rsc value for "loadrs"
+       adds r3=PT(AR_BSPSTORE)+16,r12          // deferred
+       ;;
+#else
        adds r2=PT(LOADRS)+16,r12
        adds r3=PT(AR_BSPSTORE)+16,r12
        adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
@@ -718,6 +728,7 @@ ENTRY(ia64_leave_syscall)
        ld8 r19=[r2],PT(B6)-PT(LOADRS)          // load ar.rsc value for "loadrs"
        nop.i 0
        ;;
+#endif
        mov r16=ar.bsp                          // M2  get existing backing store pointer
        ld8 r18=[r2],PT(R9)-PT(B6)              // load b6
 (p6)   and r15=TIF_WORK_MASK,r31               // any work other than TIF_SYSCALL_TRACE?
@@ -737,12 +748,21 @@ ENTRY(ia64_leave_syscall)
 
        ld8 r29=[r2],16         // M0|1 load cr.ipsr
        ld8 r28=[r3],16         // M0|1 load cr.iip
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+(pUStk) add r14=TI_AC_LEAVE+IA64_TASK_SIZE,r13
+       ;;
+       ld8 r30=[r2],16         // M0|1 load cr.ifs
+       ld8 r25=[r3],16         // M0|1 load ar.unat
+(pUStk) add r15=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+       ;;
+#else
        mov r22=r0              // A    clear r22
        ;;
        ld8 r30=[r2],16         // M0|1 load cr.ifs
        ld8 r25=[r3],16         // M0|1 load ar.unat
 (pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
        ;;
+#endif
        ld8 r26=[r2],PT(B0)-PT(AR_PFS)  // M0|1 load ar.pfs
 (pKStk)        mov r22=psr                     // M2   read PSR now that interrupts are disabled
        nop 0
@@ -759,7 +779,11 @@ ENTRY(ia64_leave_syscall)
        ld8.fill r1=[r3],16                     // M0|1 load r1
 (pUStk) mov r17=1                              // A
        ;;
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+(pUStk) st1 [r15]=r17                          // M2|3
+#else
 (pUStk) st1 [r14]=r17                          // M2|3
+#endif
        ld8.fill r13=[r3],16                    // M0|1
        mov f8=f0                               // F    clear f8
        ;;
@@ -775,12 +799,22 @@ ENTRY(ia64_leave_syscall)
        shr.u r18=r19,16                // I0|1 get byte size of existing "dirty" partition
        cover                           // B    add current frame into dirty partition & set cr.ifs
        ;;
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       mov r19=ar.bsp                  // M2   get new backing store pointer
+       st8 [r14]=r22                   // M    save time at leave
+       mov f10=f0                      // F    clear f10
+
+       mov r22=r0                      // A    clear r22
+       movl r14=__kernel_syscall_via_epc // X
+       ;;
+#else
        mov r19=ar.bsp                  // M2   get new backing store pointer
        mov f10=f0                      // F    clear f10
 
        nop.m 0
        movl r14=__kernel_syscall_via_epc // X
        ;;
+#endif
        mov.m ar.csd=r0                 // M2   clear ar.csd
        mov.m ar.ccv=r0                 // M2   clear ar.ccv
        mov b7=r14                      // I0   clear b7 (hint with __kernel_syscall_via_epc)
@@ -913,10 +947,18 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        adds r16=PT(CR_IPSR)+16,r12
        adds r17=PT(CR_IIP)+16,r12
 
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       .pred.rel.mutex pUStk,pKStk
+(pKStk)        mov r22=psr             // M2 read PSR now that interrupts are disabled
+(pUStk)        mov.m r22=ar.itc        // M  fetch time at leave
+       nop.i 0
+       ;;
+#else
 (pKStk)        mov r22=psr             // M2 read PSR now that interrupts are disabled
        nop.i 0
        nop.i 0
        ;;
+#endif
        ld8 r29=[r16],16        // load cr.ipsr
        ld8 r28=[r17],16        // load cr.iip
        ;;
@@ -938,15 +980,37 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        ;;
        ld8.fill r12=[r16],16
        ld8.fill r13=[r17],16
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+(pUStk)        adds r3=TI_AC_LEAVE+IA64_TASK_SIZE,r18
+#else
 (pUStk)        adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
+#endif
        ;;
        ld8 r20=[r16],16        // ar.fpsr
        ld8.fill r15=[r17],16
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+(pUStk)        adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18  // deferred
+#endif
        ;;
        ld8.fill r14=[r16],16
        ld8.fill r2=[r17]
 (pUStk)        mov r17=1
        ;;
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       //  mmi_ :  ld8 st1 shr;;         mmi_ : st8 st1 shr;;
+       //  mib  :  mov add br        ->  mib  : ld8 add br
+       //  bbb_ :  br  nop cover;;       mbb_ : mov br  cover;;
+       //
+       //  no one require bsp in r16 if (pKStk) branch is selected.
+(pUStk)        st8 [r3]=r22            // save time at leave
+(pUStk)        st1 [r18]=r17           // restore current->thread.on_ustack
+       shr.u r18=r19,16        // get byte size of existing "dirty" partition
+       ;;
+       ld8.fill r3=[r16]       // deferred
+       LOAD_PHYS_STACK_REG_SIZE(r17)
+(pKStk)        br.cond.dpnt skip_rbs_switch
+       mov r16=ar.bsp          // get existing backing store pointer
+#else
        ld8.fill r3=[r16]
 (pUStk)        st1 [r18]=r17           // restore current->thread.on_ustack
        shr.u r18=r19,16        // get byte size of existing "dirty" partition
@@ -954,6 +1018,7 @@ GLOBAL_ENTRY(ia64_leave_kernel)
        mov r16=ar.bsp          // get existing backing store pointer
        LOAD_PHYS_STACK_REG_SIZE(r17)
 (pKStk)        br.cond.dpnt skip_rbs_switch
+#endif
 
        /*
         * Restore user backing store.
index 3f570e6..c1625c7 100644 (file)
@@ -236,27 +236,25 @@ ENTRY(fsys_gettimeofday)
        // Note that instructions are optimized for McKinley. McKinley can
        // process two bundles simultaneously and therefore we continuously
        // try to feed the CPU two bundles and then a stop.
-       //
-       // Additional note that code has changed a lot. Optimization is TBD.
-       // Comments begin with "?" are maybe outdated.
-       tnat.nz p6,p0 = r31     // ? branch deferred to fit later bundle
-       mov pr = r30,0xc000     // Set predicates according to function
+
        add r2 = TI_FLAGS+IA64_TASK_SIZE,r16
+       tnat.nz p6,p0 = r31             // guard against Nat argument
+(p6)   br.cond.spnt.few .fail_einval
        movl r20 = fsyscall_gtod_data // load fsyscall gettimeofday data address
        ;;
+       ld4 r2 = [r2]                   // process work pending flags
        movl r29 = itc_jitter_data      // itc_jitter
        add r22 = IA64_GTOD_WALL_TIME_OFFSET,r20        // wall_time
-       ld4 r2 = [r2]           // process work pending flags
-       ;;
-(p15)  add r22 = IA64_GTOD_MONO_TIME_OFFSET,r20        // monotonic_time
        add r21 = IA64_CLKSRC_MMIO_OFFSET,r20
-       add r19 = IA64_ITC_LASTCYCLE_OFFSET,r29
+       mov pr = r30,0xc000     // Set predicates according to function
+       ;;
        and r2 = TIF_ALLWORK_MASK,r2
-(p6)    br.cond.spnt.few .fail_einval  // ? deferred branch
+       add r19 = IA64_ITC_LASTCYCLE_OFFSET,r29
+(p15)  add r22 = IA64_GTOD_MONO_TIME_OFFSET,r20        // monotonic_time
        ;;
-       add r26 = IA64_CLKSRC_CYCLE_LAST_OFFSET,r20 // clksrc_cycle_last
+       add r26 = IA64_CLKSRC_CYCLE_LAST_OFFSET,r20     // clksrc_cycle_last
        cmp.ne p6, p0 = 0, r2   // Fallback if work is scheduled
-(p6)    br.cond.spnt.many fsys_fallback_syscall
+(p6)   br.cond.spnt.many fsys_fallback_syscall
        ;;
        // Begin critical section
 .time_redo:
@@ -284,7 +282,6 @@ ENTRY(fsys_gettimeofday)
 (p8)   mov r2 = ar.itc         // CPU_TIMER. 36 clocks latency!!!
 (p9)   ld8 r2 = [r30]          // MMIO_TIMER. Could also have latency issues..
 (p13)  ld8 r25 = [r19]         // get itc_lastcycle value
-       ;;              // ? could be removed by moving the last add upward
        ld8 r9 = [r22],IA64_TIMESPEC_TV_NSEC_OFFSET     // tv_sec
        ;;
        ld8 r8 = [r22],-IA64_TIMESPEC_TV_NSEC_OFFSET    // tv_nsec
@@ -311,13 +308,12 @@ ENTRY(fsys_gettimeofday)
 EX(.fail_efault, probe.w.fault r31, 3)
        xmpy.l f8 = f8,f7       // nsec_per_cyc*(counter-last_counter)
        ;;
-       // ? simulate tbit.nz.or p7,p0 = r28,0
        getf.sig r2 = f8
        mf
        ;;
        ld4 r10 = [r20]         // gtod_lock.sequence
        shr.u r2 = r2,r23       // shift by factor
-       ;;              // ? overloaded 3 bundles!
+       ;;
        add r8 = r8,r2          // Add xtime.nsecs
        cmp4.ne p7,p0 = r28,r10
 (p7)   br.cond.dpnt.few .time_redo     // sequence number changed, redo
@@ -345,9 +341,9 @@ EX(.fail_efault, probe.w.fault r31, 3)
 EX(.fail_efault, probe.w.fault r23, 3) // This also costs 5 cycles
 (p14)  xmpy.hu f8 = f8, f7             // xmpy has 5 cycles latency so use it
        ;;
-       mov r8 = r0
 (p14)  getf.sig r2 = f8
        ;;
+       mov r8 = r0
 (p14)  shr.u r21 = r2, 4
        ;;
 EX(.fail_efault, st8 [r31] = r9)
@@ -686,7 +682,11 @@ GLOBAL_ENTRY(fsys_bubble_down)
        nop.i 0
        ;;
        mov ar.rsc=0                            // M2   set enforced lazy mode, pl 0, LE, loadrs=0
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       mov.m r30=ar.itc                        // M    get cycle for accounting
+#else
        nop.m 0
+#endif
        nop.i 0
        ;;
        mov r23=ar.bspstore                     // M2 (12 cyc) save ar.bspstore
@@ -708,6 +708,28 @@ GLOBAL_ENTRY(fsys_bubble_down)
        cmp.ne pKStk,pUStk=r0,r0                // A    set pKStk <- 0, pUStk <- 1
        br.call.sptk.many b7=ia64_syscall_setup // B
        ;;
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       // mov.m r30=ar.itc is called in advance
+       add r16=TI_AC_STAMP+IA64_TASK_SIZE,r2
+       add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r2
+       ;;
+       ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP   // time at last check in kernel
+       ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE   // time at leave kernel
+       ;;
+       ld8 r20=[r16],TI_AC_STAMP-TI_AC_STIME   // cumulated stime
+       ld8 r21=[r17]                           // cumulated utime
+       sub r22=r19,r18                         // stime before leave kernel
+       ;;
+       st8 [r16]=r30,TI_AC_STIME-TI_AC_STAMP   // update stamp
+       sub r18=r30,r19                         // elapsed time in user mode
+       ;;
+       add r20=r20,r22                         // sum stime
+       add r21=r21,r18                         // sum utime
+       ;;
+       st8 [r16]=r20                           // update stime
+       st8 [r17]=r21                           // update utime
+       ;;
+#endif
        mov ar.rsc=0x3                          // M2   set eager mode, pl 0, LE, loadrs=0
        mov rp=r14                              // I0   set the real return addr
        and r3=_TIF_SYSCALL_TRACEAUDIT,r3       // A
index d3a41d5..ddeab4e 100644 (file)
@@ -1002,6 +1002,26 @@ GLOBAL_ENTRY(sched_clock)
        br.ret.sptk.many rp
 END(sched_clock)
 
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+GLOBAL_ENTRY(cycle_to_cputime)
+       alloc r16=ar.pfs,1,0,0,0
+       addl r8=THIS_CPU(cpu_info) + IA64_CPUINFO_NSEC_PER_CYC_OFFSET,r0
+       ;;
+       ldf8 f8=[r8]
+       ;;
+       setf.sig f9=r32
+       ;;
+       xmpy.lu f10=f9,f8       // calculate low 64 bits of 128-bit product     (4 cyc)
+       xmpy.hu f11=f9,f8       // calculate high 64 bits of 128-bit product
+       ;;
+       getf.sig r8=f10         //                                              (5 cyc)
+       getf.sig r9=f11
+       ;;
+       shrp r8=r9,r8,IA64_NSEC_PER_CYC_SHIFT
+       br.ret.sptk.many rp
+END(cycle_to_cputime)
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
+
 GLOBAL_ENTRY(start_kernel_thread)
        .prologue
        .save rp, r0                            // this is the end of the call-chain
index 34f44d8..6678c49 100644 (file)
@@ -805,8 +805,13 @@ ENTRY(break_fault)
 
 (p8)   adds r28=16,r28                         // A    switch cr.iip to next bundle
 (p9)   adds r8=1,r8                            // A    increment ei to next slot
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       ;;
+       mov b6=r30                              // I0   setup syscall handler branch reg early
+#else
        nop.i 0
        ;;
+#endif
 
        mov.m r25=ar.unat                       // M2 (5 cyc)
        dep r29=r8,r29,41,2                     // I0   insert new ei into cr.ipsr
@@ -817,7 +822,11 @@ ENTRY(break_fault)
        //
 ///////////////////////////////////////////////////////////////////////
        st1 [r16]=r0                            // M2|3 clear current->thread.on_ustack flag
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       mov.m r30=ar.itc                        // M    get cycle for accounting
+#else
        mov b6=r30                              // I0   setup syscall handler branch reg early
+#endif
        cmp.eq pKStk,pUStk=r0,r17               // A    were we on kernel stacks already?
 
        and r9=_TIF_SYSCALL_TRACEAUDIT,r9       // A    mask trace or audit
@@ -829,6 +838,30 @@ ENTRY(break_fault)
        cmp.eq p14,p0=r9,r0                     // A    are syscalls being traced/audited?
        br.call.sptk.many b7=ia64_syscall_setup // B
 1:
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       // mov.m r30=ar.itc is called in advance, and r13 is current
+       add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13  // A
+       add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13  // A
+(pKStk)        br.cond.spnt .skip_accounting           // B    unlikely skip
+       ;;
+       ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP   // M  get last stamp
+       ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE   // M  time at leave
+       ;;
+       ld8 r20=[r16],TI_AC_STAMP-TI_AC_STIME   // M  cumulated stime
+       ld8 r21=[r17]                           // M  cumulated utime
+       sub r22=r19,r18                         // A  stime before leave
+       ;;
+       st8 [r16]=r30,TI_AC_STIME-TI_AC_STAMP   // M  update stamp
+       sub r18=r30,r19                         // A  elapsed time in user
+       ;;
+       add r20=r20,r22                         // A  sum stime
+       add r21=r21,r18                         // A  sum utime
+       ;;
+       st8 [r16]=r20                           // M  update stime
+       st8 [r17]=r21                           // M  update utime
+       ;;
+.skip_accounting:
+#endif
        mov ar.rsc=0x3                          // M2   set eager mode, pl 0, LE, loadrs=0
        nop 0
        bsw.1                                   // B (6 cyc) regs are saved, switch to bank 1
@@ -928,6 +961,7 @@ END(interrupt)
         *      - r27: saved ar.rsc
         *      - r28: saved cr.iip
         *      - r29: saved cr.ipsr
+        *      - r30: ar.itc for accounting (don't touch)
         *      - r31: saved pr
         *      -  b0: original contents (to be saved)
         * On exit:
@@ -1090,6 +1124,41 @@ END(dispatch_illegal_op_fault)
        DBG_FAULT(16)
        FAULT(16)
 
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       /*
+        * There is no particular reason for this code to be here, other than
+        * that there happens to be space here that would go unused otherwise.
+        * If this fault ever gets "unreserved", simply moved the following
+        * code to a more suitable spot...
+        *
+        * account_sys_enter is called from SAVE_MIN* macros if accounting is
+        * enabled and if the macro is entered from user mode.
+        */
+ENTRY(account_sys_enter)
+       // mov.m r20=ar.itc is called in advance, and r13 is current
+       add r16=TI_AC_STAMP+IA64_TASK_SIZE,r13
+       add r17=TI_AC_LEAVE+IA64_TASK_SIZE,r13
+       ;;
+       ld8 r18=[r16],TI_AC_STIME-TI_AC_STAMP   // time at last check in kernel
+       ld8 r19=[r17],TI_AC_UTIME-TI_AC_LEAVE   // time at left from kernel
+        ;;
+       ld8 r23=[r16],TI_AC_STAMP-TI_AC_STIME   // cumulated stime
+       ld8 r21=[r17]                           // cumulated utime
+       sub r22=r19,r18                         // stime before leave kernel
+       ;;
+       st8 [r16]=r20,TI_AC_STIME-TI_AC_STAMP   // update stamp
+       sub r18=r20,r19                         // elapsed time in user mode
+       ;;
+       add r23=r23,r22                         // sum stime
+       add r21=r21,r18                         // sum utime
+       ;;
+       st8 [r16]=r23                           // update stime
+       st8 [r17]=r21                           // update utime
+       ;;
+       br.ret.sptk.many rp
+END(account_sys_enter)
+#endif
+
        .org ia64_ivt+0x4400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4400 Entry 17 (size 64 bundles) Reserved
index 1ae5129..e51bced 100644 (file)
@@ -98,6 +98,7 @@
 
 #include <asm/irq.h>
 #include <asm/hw_irq.h>
+#include <asm/tlb.h>
 
 #include "mca_drv.h"
 #include "entry.h"
@@ -113,6 +114,7 @@ DEFINE_PER_CPU(u64, ia64_mca_data); /* == __per_cpu_mca[smp_processor_id()] */
 DEFINE_PER_CPU(u64, ia64_mca_per_cpu_pte); /* PTE to map per-CPU area */
 DEFINE_PER_CPU(u64, ia64_mca_pal_pte);     /* PTE to map PAL code */
 DEFINE_PER_CPU(u64, ia64_mca_pal_base);    /* vaddr PAL code granule */
+DEFINE_PER_CPU(u64, ia64_mca_tr_reload);   /* Flag for TR reload */
 
 unsigned long __per_cpu_mca[NR_CPUS];
 
@@ -1184,6 +1186,49 @@ all_in:
        return;
 }
 
+/*  mca_insert_tr
+ *
+ *  Switch rid when TR reload and needed!
+ *  iord: 1: itr, 2: itr;
+ *
+*/
+static void mca_insert_tr(u64 iord)
+{
+
+       int i;
+       u64 old_rr;
+       struct ia64_tr_entry *p;
+       unsigned long psr;
+       int cpu = smp_processor_id();
+
+       psr = ia64_clear_ic();
+       for (i = IA64_TR_ALLOC_BASE; i < IA64_TR_ALLOC_MAX; i++) {
+               p = &__per_cpu_idtrs[cpu][iord-1][i];
+               if (p->pte & 0x1) {
+                       old_rr = ia64_get_rr(p->ifa);
+                       if (old_rr != p->rr) {
+                               ia64_set_rr(p->ifa, p->rr);
+                               ia64_srlz_d();
+                       }
+                       ia64_ptr(iord, p->ifa, p->itir >> 2);
+                       ia64_srlz_i();
+                       if (iord & 0x1) {
+                               ia64_itr(0x1, i, p->ifa, p->pte, p->itir >> 2);
+                               ia64_srlz_i();
+                       }
+                       if (iord & 0x2) {
+                               ia64_itr(0x2, i, p->ifa, p->pte, p->itir >> 2);
+                               ia64_srlz_i();
+                       }
+                       if (old_rr != p->rr) {
+                               ia64_set_rr(p->ifa, old_rr);
+                               ia64_srlz_d();
+                       }
+               }
+       }
+       ia64_set_psr(psr);
+}
+
 /*
  * ia64_mca_handler
  *
@@ -1270,6 +1315,11 @@ ia64_mca_handler(struct pt_regs *regs, struct switch_stack *sw,
                ia64_mlogbuf_finish(1);
        }
 
+       if (__get_cpu_var(ia64_mca_tr_reload)) {
+               mca_insert_tr(0x1); /*Reload dynamic itrs*/
+               mca_insert_tr(0x2); /*Reload dynamic itrs*/
+       }
+
        if (notify_die(DIE_MCA_MONARCH_LEAVE, "MCA", regs, (long)&nd, 0, recover)
                        == NOTIFY_STOP)
                ia64_mca_spin(__func__);
index 8bc7d25..a06d465 100644 (file)
@@ -219,8 +219,13 @@ ia64_reload_tr:
        mov r20=IA64_TR_CURRENT_STACK
        ;;
        itr.d dtr[r20]=r16
+       GET_THIS_PADDR(r2, ia64_mca_tr_reload)
+       mov r18 = 1
        ;;
        srlz.d
+       ;;
+       st8 [r2] =r18
+       ;;
 
 done_tlb_purge_and_reload:
 
index c9ac8ba..7c548ac 100644 (file)
@@ -3,6 +3,18 @@
 
 #include "entry.h"
 
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+/* read ar.itc in advance, and use it before leaving bank 0 */
+#define ACCOUNT_GET_STAMP                              \
+(pUStk) mov.m r20=ar.itc;
+#define ACCOUNT_SYS_ENTER                              \
+(pUStk) br.call.spnt rp=account_sys_enter              \
+       ;;
+#else
+#define ACCOUNT_GET_STAMP
+#define ACCOUNT_SYS_ENTER
+#endif
+
 /*
  * DO_SAVE_MIN switches to the kernel stacks (if necessary) and saves
  * the minimum state necessary that allows us to turn psr.ic back
        ;;                                                                                      \
 .mem.offset 0,0; st8.spill [r16]=r2,16;                                                                \
 .mem.offset 8,0; st8.spill [r17]=r3,16;                                                                \
+       ACCOUNT_GET_STAMP                                                                       \
        adds r2=IA64_PT_REGS_R16_OFFSET,r1;                                                     \
        ;;                                                                                      \
        EXTRA;                                                                                  \
        movl r1=__gp;           /* establish kernel global pointer */                           \
        ;;                                                                                      \
+       ACCOUNT_SYS_ENTER                                                                       \
        bsw.1;                  /* switch back to bank 1 (must be last in insn group) */        \
        ;;
 
index a78b45f..c93420c 100644 (file)
@@ -73,7 +73,7 @@ void __init build_cpu_to_node_map(void)
        for(node=0; node < MAX_NUMNODES; node++)
                cpus_clear(node_to_cpu_mask[node]);
 
-       for(cpu = 0; cpu < NR_CPUS; ++cpu) {
+       for_each_possible_early_cpu(cpu) {
                node = -1;
                for (i = 0; i < NR_CPUS; ++i)
                        if (cpu_physical_id(cpu) == node_cpuid[i].phys_id) {
index 2cb9425..e0dca87 100644 (file)
@@ -135,10 +135,10 @@ ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
 
        while (offp < (s32 *) end) {
                wp = (u64 *) ia64_imva((char *) offp + *offp);
-               wp[0] = 0x0000000100000000UL; /* nop.m 0; nop.i 0; nop.i 0 */
-               wp[1] = 0x0004000000000200UL;
-               wp[2] = 0x0000000100000011UL; /* nop.m 0; nop.i 0; br.ret.sptk.many b6 */
-               wp[3] = 0x0084006880000200UL;
+               wp[0] = 0x0000000100000011UL; /* nop.m 0; nop.i 0; br.ret.sptk.many b6 */
+               wp[1] = 0x0084006880000200UL;
+               wp[2] = 0x0000000100000000UL; /* nop.m 0; nop.i 0; nop.i 0 */
+               wp[3] = 0x0004000000000200UL;
                ia64_fc(wp); ia64_fc(wp + 2);
                ++offp;
        }
index 49937a3..a5ea817 100644 (file)
@@ -625,21 +625,6 @@ do_dump_fpu (struct unw_frame_info *info, void *arg)
        do_dump_task_fpu(current, info, arg);
 }
 
-int
-dump_task_regs(struct task_struct *task, elf_gregset_t *regs)
-{
-       struct unw_frame_info tcore_info;
-
-       if (current == task) {
-               unw_init_running(do_copy_regs, regs);
-       } else {
-               memset(&tcore_info, 0, sizeof(tcore_info));
-               unw_init_from_blocked_task(&tcore_info, task);
-               do_copy_task_regs(task, &tcore_info, regs);
-       }
-       return 1;
-}
-
 void
 ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
 {
@@ -647,21 +632,6 @@ ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
 }
 
 int
-dump_task_fpu (struct task_struct *task, elf_fpregset_t *dst)
-{
-       struct unw_frame_info tcore_info;
-
-       if (current == task) {
-               unw_init_running(do_dump_fpu, dst);
-       } else {
-               memset(&tcore_info, 0, sizeof(tcore_info));
-               unw_init_from_blocked_task(&tcore_info, task);
-               do_dump_task_fpu(task, &tcore_info, dst);
-       }
-       return 1;
-}
-
-int
 dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
 {
        unw_init_running(do_dump_fpu, dst);
index ab784ec..2a9943b 100644 (file)
@@ -3,6 +3,9 @@
  *
  * Copyright (C) 1999-2005 Hewlett-Packard Co
  *     David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2006 Intel Co
+ *  2006-08-12 - IA64 Native Utrace implementation support added by
+ *     Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
  *
  * Derived from the x86 and Alpha versions.
  */
@@ -17,6 +20,8 @@
 #include <linux/security.h>
 #include <linux/audit.h>
 #include <linux/signal.h>
+#include <linux/regset.h>
+#include <linux/elf.h>
 
 #include <asm/pgtable.h>
 #include <asm/processor.h>
@@ -740,25 +745,6 @@ ia64_sync_fph (struct task_struct *task)
        psr->dfh = 1;
 }
 
-static int
-access_fr (struct unw_frame_info *info, int regnum, int hi,
-          unsigned long *data, int write_access)
-{
-       struct ia64_fpreg fpval;
-       int ret;
-
-       ret = unw_get_fr(info, regnum, &fpval);
-       if (ret < 0)
-               return ret;
-
-       if (write_access) {
-               fpval.u.bits[hi] = *data;
-               ret = unw_set_fr(info, regnum, fpval);
-       } else
-               *data = fpval.u.bits[hi];
-       return ret;
-}
-
 /*
  * Change the machine-state of CHILD such that it will return via the normal
  * kernel exit-path, rather than the syscall-exit path.
@@ -860,309 +846,7 @@ access_nat_bits (struct task_struct *child, struct pt_regs *pt,
 
 static int
 access_uarea (struct task_struct *child, unsigned long addr,
-             unsigned long *data, int write_access)
-{
-       unsigned long *ptr, regnum, urbs_end, cfm;
-       struct switch_stack *sw;
-       struct pt_regs *pt;
-#      define pt_reg_addr(pt, reg)     ((void *)                           \
-                                        ((unsigned long) (pt)              \
-                                         + offsetof(struct pt_regs, reg)))
-
-
-       pt = task_pt_regs(child);
-       sw = (struct switch_stack *) (child->thread.ksp + 16);
-
-       if ((addr & 0x7) != 0) {
-               dprintk("ptrace: unaligned register address 0x%lx\n", addr);
-               return -1;
-       }
-
-       if (addr < PT_F127 + 16) {
-               /* accessing fph */
-               if (write_access)
-                       ia64_sync_fph(child);
-               else
-                       ia64_flush_fph(child);
-               ptr = (unsigned long *)
-                       ((unsigned long) &child->thread.fph + addr);
-       } else if ((addr >= PT_F10) && (addr < PT_F11 + 16)) {
-               /* scratch registers untouched by kernel (saved in pt_regs) */
-               ptr = pt_reg_addr(pt, f10) + (addr - PT_F10);
-       } else if (addr >= PT_F12 && addr < PT_F15 + 16) {
-               /*
-                * Scratch registers untouched by kernel (saved in
-                * switch_stack).
-                */
-               ptr = (unsigned long *) ((long) sw
-                                        + (addr - PT_NAT_BITS - 32));
-       } else if (addr < PT_AR_LC + 8) {
-               /* preserved state: */
-               struct unw_frame_info info;
-               char nat = 0;
-               int ret;
-
-               unw_init_from_blocked_task(&info, child);
-               if (unw_unwind_to_user(&info) < 0)
-                       return -1;
-
-               switch (addr) {
-                     case PT_NAT_BITS:
-                       return access_nat_bits(child, pt, &info,
-                                              data, write_access);
-
-                     case PT_R4: case PT_R5: case PT_R6: case PT_R7:
-                       if (write_access) {
-                               /* read NaT bit first: */
-                               unsigned long dummy;
-
-                               ret = unw_get_gr(&info, (addr - PT_R4)/8 + 4,
-                                                &dummy, &nat);
-                               if (ret < 0)
-                                       return ret;
-                       }
-                       return unw_access_gr(&info, (addr - PT_R4)/8 + 4, data,
-                                            &nat, write_access);
-
-                     case PT_B1: case PT_B2: case PT_B3:
-                     case PT_B4: case PT_B5:
-                       return unw_access_br(&info, (addr - PT_B1)/8 + 1, data,
-                                            write_access);
-
-                     case PT_AR_EC:
-                       return unw_access_ar(&info, UNW_AR_EC, data,
-                                            write_access);
-
-                     case PT_AR_LC:
-                       return unw_access_ar(&info, UNW_AR_LC, data,
-                                            write_access);
-
-                     default:
-                       if (addr >= PT_F2 && addr < PT_F5 + 16)
-                               return access_fr(&info, (addr - PT_F2)/16 + 2,
-                                                (addr & 8) != 0, data,
-                                                write_access);
-                       else if (addr >= PT_F16 && addr < PT_F31 + 16)
-                               return access_fr(&info,
-                                                (addr - PT_F16)/16 + 16,
-                                                (addr & 8) != 0,
-                                                data, write_access);
-                       else {
-                               dprintk("ptrace: rejecting access to register "
-                                       "address 0x%lx\n", addr);
-                               return -1;
-                       }
-               }
-       } else if (addr < PT_F9+16) {
-               /* scratch state */
-               switch (addr) {
-                     case PT_AR_BSP:
-                       /*
-                        * By convention, we use PT_AR_BSP to refer to
-                        * the end of the user-level backing store.
-                        * Use ia64_rse_skip_regs(PT_AR_BSP, -CFM.sof)
-                        * to get the real value of ar.bsp at the time
-                        * the kernel was entered.
-                        *
-                        * Furthermore, when changing the contents of
-                        * PT_AR_BSP (or PT_CFM) while the task is
-                        * blocked in a system call, convert the state
-                        * so that the non-system-call exit
-                        * path is used.  This ensures that the proper
-                        * state will be picked up when resuming
-                        * execution.  However, it *also* means that
-                        * once we write PT_AR_BSP/PT_CFM, it won't be
-                        * possible to modify the syscall arguments of
-                        * the pending system call any longer.  This
-                        * shouldn't be an issue because modifying
-                        * PT_AR_BSP/PT_CFM generally implies that
-                        * we're either abandoning the pending system
-                        * call or that we defer it's re-execution
-                        * (e.g., due to GDB doing an inferior
-                        * function call).
-                        */
-                       urbs_end = ia64_get_user_rbs_end(child, pt, &cfm);
-                       if (write_access) {
-                               if (*data != urbs_end) {
-                                       if (in_syscall(pt))
-                                               convert_to_non_syscall(child,
-                                                                      pt,
-                                                                      cfm);
-                                       /*
-                                        * Simulate user-level write
-                                        * of ar.bsp:
-                                        */
-                                       pt->loadrs = 0;
-                                       pt->ar_bspstore = *data;
-                               }
-                       } else
-                               *data = urbs_end;
-                       return 0;
-
-                     case PT_CFM:
-                       urbs_end = ia64_get_user_rbs_end(child, pt, &cfm);
-                       if (write_access) {
-                               if (((cfm ^ *data) & PFM_MASK) != 0) {
-                                       if (in_syscall(pt))
-                                               convert_to_non_syscall(child,
-                                                                      pt,
-                                                                      cfm);
-                                       pt->cr_ifs = ((pt->cr_ifs & ~PFM_MASK)
-                                                     | (*data & PFM_MASK));
-                               }
-                       } else
-                               *data = cfm;
-                       return 0;
-
-                     case PT_CR_IPSR:
-                       if (write_access) {
-                               unsigned long tmp = *data;
-                               /* psr.ri==3 is a reserved value: SDM 2:25 */
-                               if ((tmp & IA64_PSR_RI) == IA64_PSR_RI)
-                                       tmp &= ~IA64_PSR_RI;
-                               pt->cr_ipsr = ((tmp & IPSR_MASK)
-                                              | (pt->cr_ipsr & ~IPSR_MASK));
-                       } else
-                               *data = (pt->cr_ipsr & IPSR_MASK);
-                       return 0;
-
-                     case PT_AR_RSC:
-                       if (write_access)
-                               pt->ar_rsc = *data | (3 << 2); /* force PL3 */
-                       else
-                               *data = pt->ar_rsc;
-                       return 0;
-
-                     case PT_AR_RNAT:
-                       ptr = pt_reg_addr(pt, ar_rnat);
-                       break;
-                     case PT_R1:
-                       ptr = pt_reg_addr(pt, r1);
-                       break;
-                     case PT_R2:  case PT_R3:
-                       ptr = pt_reg_addr(pt, r2) + (addr - PT_R2);
-                       break;
-                     case PT_R8:  case PT_R9:  case PT_R10: case PT_R11:
-                       ptr = pt_reg_addr(pt, r8) + (addr - PT_R8);
-                       break;
-                     case PT_R12: case PT_R13:
-                       ptr = pt_reg_addr(pt, r12) + (addr - PT_R12);
-                       break;
-                     case PT_R14:
-                       ptr = pt_reg_addr(pt, r14);
-                       break;
-                     case PT_R15:
-                       ptr = pt_reg_addr(pt, r15);
-                       break;
-                     case PT_R16: case PT_R17: case PT_R18: case PT_R19:
-                     case PT_R20: case PT_R21: case PT_R22: case PT_R23:
-                     case PT_R24: case PT_R25: case PT_R26: case PT_R27:
-                     case PT_R28: case PT_R29: case PT_R30: case PT_R31:
-                       ptr = pt_reg_addr(pt, r16) + (addr - PT_R16);
-                       break;
-                     case PT_B0:
-                       ptr = pt_reg_addr(pt, b0);
-                       break;
-                     case PT_B6:
-                       ptr = pt_reg_addr(pt, b6);
-                       break;
-                     case PT_B7:
-                       ptr = pt_reg_addr(pt, b7);
-                       break;
-                     case PT_F6:  case PT_F6+8: case PT_F7: case PT_F7+8:
-                     case PT_F8:  case PT_F8+8: case PT_F9: case PT_F9+8:
-                       ptr = pt_reg_addr(pt, f6) + (addr - PT_F6);
-                       break;
-                     case PT_AR_BSPSTORE:
-                       ptr = pt_reg_addr(pt, ar_bspstore);
-                       break;
-                     case PT_AR_UNAT:
-                       ptr = pt_reg_addr(pt, ar_unat);
-                       break;
-                     case PT_AR_PFS:
-                       ptr = pt_reg_addr(pt, ar_pfs);
-                       break;
-                     case PT_AR_CCV:
-                       ptr = pt_reg_addr(pt, ar_ccv);
-                       break;
-                     case PT_AR_FPSR:
-                       ptr = pt_reg_addr(pt, ar_fpsr);
-                       break;
-                     case PT_CR_IIP:
-                       ptr = pt_reg_addr(pt, cr_iip);
-                       break;
-                     case PT_PR:
-                       ptr = pt_reg_addr(pt, pr);
-                       break;
-                       /* scratch register */
-
-                     default:
-                       /* disallow accessing anything else... */
-                       dprintk("ptrace: rejecting access to register "
-                               "address 0x%lx\n", addr);
-                       return -1;
-               }
-       } else if (addr <= PT_AR_SSD) {
-               ptr = pt_reg_addr(pt, ar_csd) + (addr - PT_AR_CSD);
-       } else {
-               /* access debug registers */
-
-               if (addr >= PT_IBR) {
-                       regnum = (addr - PT_IBR) >> 3;
-                       ptr = &child->thread.ibr[0];
-               } else {
-                       regnum = (addr - PT_DBR) >> 3;
-                       ptr = &child->thread.dbr[0];
-               }
-
-               if (regnum >= 8) {
-                       dprintk("ptrace: rejecting access to register "
-                               "address 0x%lx\n", addr);
-                       return -1;
-               }
-#ifdef CONFIG_PERFMON
-               /*
-                * Check if debug registers are used by perfmon. This
-                * test must be done once we know that we can do the
-                * operation, i.e. the arguments are all valid, but
-                * before we start modifying the state.
-                *
-                * Perfmon needs to keep a count of how many processes
-                * are trying to modify the debug registers for system
-                * wide monitoring sessions.
-                *
-                * We also include read access here, because they may
-                * cause the PMU-installed debug register state
-                * (dbr[], ibr[]) to be reset. The two arrays are also
-                * used by perfmon, but we do not use
-                * IA64_THREAD_DBG_VALID. The registers are restored
-                * by the PMU context switch code.
-                */
-               if (pfm_use_debug_registers(child)) return -1;
-#endif
-
-               if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
-                       child->thread.flags |= IA64_THREAD_DBG_VALID;
-                       memset(child->thread.dbr, 0,
-                              sizeof(child->thread.dbr));
-                       memset(child->thread.ibr, 0,
-                              sizeof(child->thread.ibr));
-               }
-
-               ptr += regnum;
-
-               if ((regnum & 1) && write_access) {
-                       /* don't let the user set kernel-level breakpoints: */
-                       *ptr = *data & ~(7UL << 56);
-                       return 0;
-               }
-       }
-       if (write_access)
-               *ptr = *data;
-       else
-               *data = *ptr;
-       return 0;
-}
+             unsigned long *data, int write_access);
 
 static long
 ptrace_getregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
@@ -1626,3 +1310,892 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
        if (test_thread_flag(TIF_RESTORE_RSE))
                ia64_sync_krbs();
 }
+
+/* Utrace implementation starts here */
+struct regset_get {
+       void *kbuf;
+       void __user *ubuf;
+};
+
+struct regset_set {
+       const void *kbuf;
+       const void __user *ubuf;
+};
+
+struct regset_getset {
+       struct task_struct *target;
+       const struct user_regset *regset;
+       union {
+               struct regset_get get;
+               struct regset_set set;
+       } u;
+       unsigned int pos;
+       unsigned int count;
+       int ret;
+};
+
+static int
+access_elf_gpreg(struct task_struct *target, struct unw_frame_info *info,
+               unsigned long addr, unsigned long *data, int write_access)
+{
+       struct pt_regs *pt;
+       unsigned long *ptr = NULL;
+       int ret;
+       char nat = 0;
+
+       pt = task_pt_regs(target);
+       switch (addr) {
+       case ELF_GR_OFFSET(1):
+               ptr = &pt->r1;
+               break;
+       case ELF_GR_OFFSET(2):
+       case ELF_GR_OFFSET(3):
+               ptr = (void *)&pt->r2 + (addr - ELF_GR_OFFSET(2));
+               break;
+       case ELF_GR_OFFSET(4) ... ELF_GR_OFFSET(7):
+               if (write_access) {
+                       /* read NaT bit first: */
+                       unsigned long dummy;
+
+                       ret = unw_get_gr(info, addr/8, &dummy, &nat);
+                       if (ret < 0)
+                               return ret;
+               }
+               return unw_access_gr(info, addr/8, data, &nat, write_access);
+       case ELF_GR_OFFSET(8) ... ELF_GR_OFFSET(11):
+               ptr = (void *)&pt->r8 + addr - ELF_GR_OFFSET(8);
+               break;
+       case ELF_GR_OFFSET(12):
+       case ELF_GR_OFFSET(13):
+               ptr = (void *)&pt->r12 + addr - ELF_GR_OFFSET(12);
+               break;
+       case ELF_GR_OFFSET(14):
+               ptr = &pt->r14;
+               break;
+       case ELF_GR_OFFSET(15):
+               ptr = &pt->r15;
+       }
+       if (write_access)
+               *ptr = *data;
+       else
+               *data = *ptr;
+       return 0;
+}
+
+static int
+access_elf_breg(struct task_struct *target, struct unw_frame_info *info,
+               unsigned long addr, unsigned long *data, int write_access)
+{
+       struct pt_regs *pt;
+       unsigned long *ptr = NULL;
+
+       pt = task_pt_regs(target);
+       switch (addr) {
+       case ELF_BR_OFFSET(0):
+               ptr = &pt->b0;
+               break;
+       case ELF_BR_OFFSET(1) ... ELF_BR_OFFSET(5):
+               return unw_access_br(info, (addr - ELF_BR_OFFSET(0))/8,
+                                    data, write_access);
+       case ELF_BR_OFFSET(6):
+               ptr = &pt->b6;
+               break;
+       case ELF_BR_OFFSET(7):
+               ptr = &pt->b7;
+       }
+       if (write_access)
+               *ptr = *data;
+       else
+               *data = *ptr;
+       return 0;
+}
+
+static int
+access_elf_areg(struct task_struct *target, struct unw_frame_info *info,
+               unsigned long addr, unsigned long *data, int write_access)
+{
+       struct pt_regs *pt;
+       unsigned long cfm, urbs_end;
+       unsigned long *ptr = NULL;
+
+       pt = task_pt_regs(target);
+       if (addr >= ELF_AR_RSC_OFFSET && addr <= ELF_AR_SSD_OFFSET) {
+               switch (addr) {
+               case ELF_AR_RSC_OFFSET:
+                       /* force PL3 */
+                       if (write_access)
+                               pt->ar_rsc = *data | (3 << 2);
+                       else
+                               *data = pt->ar_rsc;
+                       return 0;
+               case ELF_AR_BSP_OFFSET:
+                       /*
+                        * By convention, we use PT_AR_BSP to refer to
+                        * the end of the user-level backing store.
+                        * Use ia64_rse_skip_regs(PT_AR_BSP, -CFM.sof)
+                        * to get the real value of ar.bsp at the time
+                        * the kernel was entered.
+                        *
+                        * Furthermore, when changing the contents of
+                        * PT_AR_BSP (or PT_CFM) while the task is
+                        * blocked in a system call, convert the state
+                        * so that the non-system-call exit
+                        * path is used.  This ensures that the proper
+                        * state will be picked up when resuming
+                        * execution.  However, it *also* means that
+                        * once we write PT_AR_BSP/PT_CFM, it won't be
+                        * possible to modify the syscall arguments of
+                        * the pending system call any longer.  This
+                        * shouldn't be an issue because modifying
+                        * PT_AR_BSP/PT_CFM generally implies that
+                        * we're either abandoning the pending system
+                        * call or that we defer it's re-execution
+                        * (e.g., due to GDB doing an inferior
+                        * function call).
+                        */
+                       urbs_end = ia64_get_user_rbs_end(target, pt, &cfm);
+                       if (write_access) {
+                               if (*data != urbs_end) {
+                                       if (in_syscall(pt))
+                                               convert_to_non_syscall(target,
+                                                                      pt,
+                                                                      cfm);
+                                       /*
+                                        * Simulate user-level write
+                                        * of ar.bsp:
+                                        */
+                                       pt->loadrs = 0;
+                                       pt->ar_bspstore = *data;
+                               }
+                       } else
+                               *data = urbs_end;
+                       return 0;
+               case ELF_AR_BSPSTORE_OFFSET:
+                       ptr = &pt->ar_bspstore;
+                       break;
+               case ELF_AR_RNAT_OFFSET:
+                       ptr = &pt->ar_rnat;
+                       break;
+               case ELF_AR_CCV_OFFSET:
+                       ptr = &pt->ar_ccv;
+                       break;
+               case ELF_AR_UNAT_OFFSET:
+                       ptr = &pt->ar_unat;
+                       break;
+               case ELF_AR_FPSR_OFFSET:
+                       ptr = &pt->ar_fpsr;
+                       break;
+               case ELF_AR_PFS_OFFSET:
+                       ptr = &pt->ar_pfs;
+                       break;
+               case ELF_AR_LC_OFFSET:
+                       return unw_access_ar(info, UNW_AR_LC, data,
+                                            write_access);
+               case ELF_AR_EC_OFFSET:
+                       return unw_access_ar(info, UNW_AR_EC, data,
+                                            write_access);
+               case ELF_AR_CSD_OFFSET:
+                       ptr = &pt->ar_csd;
+                       break;
+               case ELF_AR_SSD_OFFSET:
+                       ptr = &pt->ar_ssd;
+               }
+       } else if (addr >= ELF_CR_IIP_OFFSET && addr <= ELF_CR_IPSR_OFFSET) {
+               switch (addr) {
+               case ELF_CR_IIP_OFFSET:
+                       ptr = &pt->cr_iip;
+                       break;
+               case ELF_CFM_OFFSET:
+                       urbs_end = ia64_get_user_rbs_end(target, pt, &cfm);
+                       if (write_access) {
+                               if (((cfm ^ *data) & PFM_MASK) != 0) {
+                                       if (in_syscall(pt))
+                                               convert_to_non_syscall(target,
+                                                                      pt,
+                                                                      cfm);
+                                       pt->cr_ifs = ((pt->cr_ifs & ~PFM_MASK)
+                                                     | (*data & PFM_MASK));
+                               }
+                       } else
+                               *data = cfm;
+                       return 0;
+               case ELF_CR_IPSR_OFFSET:
+                       if (write_access) {
+                               unsigned long tmp = *data;
+                               /* psr.ri==3 is a reserved value: SDM 2:25 */
+                               if ((tmp & IA64_PSR_RI) == IA64_PSR_RI)
+                                       tmp &= ~IA64_PSR_RI;
+                               pt->cr_ipsr = ((tmp & IPSR_MASK)
+                                              | (pt->cr_ipsr & ~IPSR_MASK));
+                       } else
+                               *data = (pt->cr_ipsr & IPSR_MASK);
+                       return 0;
+               }
+       } else if (addr == ELF_NAT_OFFSET)
+               return access_nat_bits(target, pt, info,
+                                      data, write_access);
+       else if (addr == ELF_PR_OFFSET)
+               ptr = &pt->pr;
+       else
+               return -1;
+
+       if (write_access)
+               *ptr = *data;
+       else
+               *data = *ptr;
+
+       return 0;
+}
+
+static int
+access_elf_reg(struct task_struct *target, struct unw_frame_info *info,
+               unsigned long addr, unsigned long *data, int write_access)
+{
+       if (addr >= ELF_GR_OFFSET(1) && addr <= ELF_GR_OFFSET(15))
+               return access_elf_gpreg(target, info, addr, data, write_access);
+       else if (addr >= ELF_BR_OFFSET(0) && addr <= ELF_BR_OFFSET(7))
+               return access_elf_breg(target, info, addr, data, write_access);
+       else
+               return access_elf_areg(target, info, addr, data, write_access);
+}
+
+void do_gpregs_get(struct unw_frame_info *info, void *arg)
+{
+       struct pt_regs *pt;
+       struct regset_getset *dst = arg;
+       elf_greg_t tmp[16];
+       unsigned int i, index, min_copy;
+
+       if (unw_unwind_to_user(info) < 0)
+               return;
+
+       /*
+        * coredump format:
+        *      r0-r31
+        *      NaT bits (for r0-r31; bit N == 1 iff rN is a NaT)
+        *      predicate registers (p0-p63)
+        *      b0-b7
+        *      ip cfm user-mask
+        *      ar.rsc ar.bsp ar.bspstore ar.rnat
+        *      ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec
+        */
+
+
+       /* Skip r0 */
+       if (dst->count > 0 && dst->pos < ELF_GR_OFFSET(1)) {
+               dst->ret = user_regset_copyout_zero(&dst->pos, &dst->count,
+                                                     &dst->u.get.kbuf,
+                                                     &dst->u.get.ubuf,
+                                                     0, ELF_GR_OFFSET(1));
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+
+       /* gr1 - gr15 */
+       if (dst->count > 0 && dst->pos < ELF_GR_OFFSET(16)) {
+               index = (dst->pos - ELF_GR_OFFSET(1)) / sizeof(elf_greg_t);
+               min_copy = ELF_GR_OFFSET(16) > (dst->pos + dst->count) ?
+                        (dst->pos + dst->count) : ELF_GR_OFFSET(16);
+               for (i = dst->pos; i < min_copy; i += sizeof(elf_greg_t),
+                               index++)
+                       if (access_elf_reg(dst->target, info, i,
+                                               &tmp[index], 0) < 0) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf, tmp,
+                               ELF_GR_OFFSET(1), ELF_GR_OFFSET(16));
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+
+       /* r16-r31 */
+       if (dst->count > 0 && dst->pos < ELF_NAT_OFFSET) {
+               pt = task_pt_regs(dst->target);
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf, &pt->r16,
+                               ELF_GR_OFFSET(16), ELF_NAT_OFFSET);
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+
+       /* nat, pr, b0 - b7 */
+       if (dst->count > 0 && dst->pos < ELF_CR_IIP_OFFSET) {
+               index = (dst->pos - ELF_NAT_OFFSET) / sizeof(elf_greg_t);
+               min_copy = ELF_CR_IIP_OFFSET > (dst->pos + dst->count) ?
+                        (dst->pos + dst->count) : ELF_CR_IIP_OFFSET;
+               for (i = dst->pos; i < min_copy; i += sizeof(elf_greg_t),
+                               index++)
+                       if (access_elf_reg(dst->target, info, i,
+                                               &tmp[index], 0) < 0) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf, tmp,
+                               ELF_NAT_OFFSET, ELF_CR_IIP_OFFSET);
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+
+       /* ip cfm psr ar.rsc ar.bsp ar.bspstore ar.rnat
+        * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
+        */
+       if (dst->count > 0 && dst->pos < (ELF_AR_END_OFFSET)) {
+               index = (dst->pos - ELF_CR_IIP_OFFSET) / sizeof(elf_greg_t);
+               min_copy = ELF_AR_END_OFFSET > (dst->pos + dst->count) ?
+                        (dst->pos + dst->count) : ELF_AR_END_OFFSET;
+               for (i = dst->pos; i < min_copy; i += sizeof(elf_greg_t),
+                               index++)
+                       if (access_elf_reg(dst->target, info, i,
+                                               &tmp[index], 0) < 0) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf, tmp,
+                               ELF_CR_IIP_OFFSET, ELF_AR_END_OFFSET);
+       }
+}
+
+void do_gpregs_set(struct unw_frame_info *info, void *arg)
+{
+       struct pt_regs *pt;
+       struct regset_getset *dst = arg;
+       elf_greg_t tmp[16];
+       unsigned int i, index;
+
+       if (unw_unwind_to_user(info) < 0)
+               return;
+
+       /* Skip r0 */
+       if (dst->count > 0 && dst->pos < ELF_GR_OFFSET(1)) {
+               dst->ret = user_regset_copyin_ignore(&dst->pos, &dst->count,
+                                                      &dst->u.set.kbuf,
+                                                      &dst->u.set.ubuf,
+                                                      0, ELF_GR_OFFSET(1));
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+
+       /* gr1-gr15 */
+       if (dst->count > 0 && dst->pos < ELF_GR_OFFSET(16)) {
+               i = dst->pos;
+               index = (dst->pos - ELF_GR_OFFSET(1)) / sizeof(elf_greg_t);
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
+                               ELF_GR_OFFSET(1), ELF_GR_OFFSET(16));
+               if (dst->ret)
+                       return;
+               for ( ; i < dst->pos; i += sizeof(elf_greg_t), index++)
+                       if (access_elf_reg(dst->target, info, i,
+                                               &tmp[index], 1) < 0) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+               if (dst->count == 0)
+                       return;
+       }
+
+       /* gr16-gr31 */
+       if (dst->count > 0 && dst->pos < ELF_NAT_OFFSET) {
+               pt = task_pt_regs(dst->target);
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf, &pt->r16,
+                               ELF_GR_OFFSET(16), ELF_NAT_OFFSET);
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+
+       /* nat, pr, b0 - b7 */
+       if (dst->count > 0 && dst->pos < ELF_CR_IIP_OFFSET) {
+               i = dst->pos;
+               index = (dst->pos - ELF_NAT_OFFSET) / sizeof(elf_greg_t);
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
+                               ELF_NAT_OFFSET, ELF_CR_IIP_OFFSET);
+               if (dst->ret)
+                       return;
+               for (; i < dst->pos; i += sizeof(elf_greg_t), index++)
+                       if (access_elf_reg(dst->target, info, i,
+                                               &tmp[index], 1) < 0) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+               if (dst->count == 0)
+                       return;
+       }
+
+       /* ip cfm psr ar.rsc ar.bsp ar.bspstore ar.rnat
+        * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
+        */
+       if (dst->count > 0 && dst->pos < (ELF_AR_END_OFFSET)) {
+               i = dst->pos;
+               index = (dst->pos - ELF_CR_IIP_OFFSET) / sizeof(elf_greg_t);
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
+                               ELF_CR_IIP_OFFSET, ELF_AR_END_OFFSET);
+               if (dst->ret)
+                       return;
+               for ( ; i < dst->pos; i += sizeof(elf_greg_t), index++)
+                       if (access_elf_reg(dst->target, info, i,
+                                               &tmp[index], 1) < 0) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+       }
+}
+
+#define ELF_FP_OFFSET(i)       (i * sizeof(elf_fpreg_t))
+
+void do_fpregs_get(struct unw_frame_info *info, void *arg)
+{
+       struct regset_getset *dst = arg;
+       struct task_struct *task = dst->target;
+       elf_fpreg_t tmp[30];
+       int index, min_copy, i;
+
+       if (unw_unwind_to_user(info) < 0)
+               return;
+
+       /* Skip pos 0 and 1 */
+       if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(2)) {
+               dst->ret = user_regset_copyout_zero(&dst->pos, &dst->count,
+                                                     &dst->u.get.kbuf,
+                                                     &dst->u.get.ubuf,
+                                                     0, ELF_FP_OFFSET(2));
+               if (dst->count == 0 || dst->ret)
+                       return;
+       }
+
+       /* fr2-fr31 */
+       if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(32)) {
+               index = (dst->pos - ELF_FP_OFFSET(2)) / sizeof(elf_fpreg_t);
+
+               min_copy = min(((unsigned int)ELF_FP_OFFSET(32)),
+                               dst->pos + dst->count);
+               for (i = dst->pos; i < min_copy; i += sizeof(elf_fpreg_t),
+                               index++)
+                       if (unw_get_fr(info, i / sizeof(elf_fpreg_t),
+                                        &tmp[index])) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+               dst->ret = user_regset_copyout(&dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf, tmp,
+                               ELF_FP_OFFSET(2), ELF_FP_OFFSET(32));
+               if (dst->count == 0 || dst->ret)
+                       return;
+       }
+
+       /* fph */
+       if (dst->count > 0) {
+               ia64_flush_fph(dst->target);
+               if (task->thread.flags & IA64_THREAD_FPH_VALID)
+                       dst->ret = user_regset_copyout(
+                               &dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf,
+                               &dst->target->thread.fph,
+                               ELF_FP_OFFSET(32), -1);
+               else
+                       /* Zero fill instead.  */
+                       dst->ret = user_regset_copyout_zero(
+                               &dst->pos, &dst->count,
+                               &dst->u.get.kbuf, &dst->u.get.ubuf,
+                               ELF_FP_OFFSET(32), -1);
+       }
+}
+
+void do_fpregs_set(struct unw_frame_info *info, void *arg)
+{
+       struct regset_getset *dst = arg;
+       elf_fpreg_t fpreg, tmp[30];
+       int index, start, end;
+
+       if (unw_unwind_to_user(info) < 0)
+               return;
+
+       /* Skip pos 0 and 1 */
+       if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(2)) {
+               dst->ret = user_regset_copyin_ignore(&dst->pos, &dst->count,
+                                                      &dst->u.set.kbuf,
+                                                      &dst->u.set.ubuf,
+                                                      0, ELF_FP_OFFSET(2));
+               if (dst->count == 0 || dst->ret)
+                       return;
+       }
+
+       /* fr2-fr31 */
+       if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(32)) {
+               start = dst->pos;
+               end = min(((unsigned int)ELF_FP_OFFSET(32)),
+                        dst->pos + dst->count);
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                               &dst->u.set.kbuf, &dst->u.set.ubuf, tmp,
+                               ELF_FP_OFFSET(2), ELF_FP_OFFSET(32));
+               if (dst->ret)
+                       return;
+
+               if (start & 0xF) { /* only write high part */
+                       if (unw_get_fr(info, start / sizeof(elf_fpreg_t),
+                                        &fpreg)) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+                       tmp[start / sizeof(elf_fpreg_t) - 2].u.bits[0]
+                               = fpreg.u.bits[0];
+                       start &= ~0xFUL;
+               }
+               if (end & 0xF) { /* only write low part */
+                       if (unw_get_fr(info, end / sizeof(elf_fpreg_t),
+                                       &fpreg)) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+                       tmp[end / sizeof(elf_fpreg_t) - 2].u.bits[1]
+                               = fpreg.u.bits[1];
+                       end = (end + 0xF) & ~0xFUL;
+               }
+
+               for ( ; start < end ; start += sizeof(elf_fpreg_t)) {
+                       index = start / sizeof(elf_fpreg_t);
+                       if (unw_set_fr(info, index, tmp[index - 2])) {
+                               dst->ret = -EIO;
+                               return;
+                       }
+               }
+               if (dst->ret || dst->count == 0)
+                       return;
+       }
+
+       /* fph */
+       if (dst->count > 0 && dst->pos < ELF_FP_OFFSET(128)) {
+               ia64_sync_fph(dst->target);
+               dst->ret = user_regset_copyin(&dst->pos, &dst->count,
+                                               &dst->u.set.kbuf,
+                                               &dst->u.set.ubuf,
+                                               &dst->target->thread.fph,
+                                               ELF_FP_OFFSET(32), -1);
+       }
+}
+
+static int
+do_regset_call(void (*call)(struct unw_frame_info *, void *),
+              struct task_struct *target,
+              const struct user_regset *regset,
+              unsigned int pos, unsigned int count,
+              const void *kbuf, const void __user *ubuf)
+{
+       struct regset_getset info = { .target = target, .regset = regset,
+                                .pos = pos, .count = count,
+                                .u.set = { .kbuf = kbuf, .ubuf = ubuf },
+                                .ret = 0 };
+
+       if (target == current)
+               unw_init_running(call, &info);
+       else {
+               struct unw_frame_info ufi;
+               memset(&ufi, 0, sizeof(ufi));
+               unw_init_from_blocked_task(&ufi, target);
+               (*call)(&ufi, &info);
+       }
+
+       return info.ret;
+}
+
+static int
+gpregs_get(struct task_struct *target,
+          const struct user_regset *regset,
+          unsigned int pos, unsigned int count,
+          void *kbuf, void __user *ubuf)
+{
+       return do_regset_call(do_gpregs_get, target, regset, pos, count,
+               kbuf, ubuf);
+}
+
+static int gpregs_set(struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               const void *kbuf, const void __user *ubuf)
+{
+       return do_regset_call(do_gpregs_set, target, regset, pos, count,
+               kbuf, ubuf);
+}
+
+static void do_gpregs_writeback(struct unw_frame_info *info, void *arg)
+{
+       do_sync_rbs(info, ia64_sync_user_rbs);
+}
+
+/*
+ * This is called to write back the register backing store.
+ * ptrace does this before it stops, so that a tracer reading the user
+ * memory after the thread stops will get the current register data.
+ */
+static int
+gpregs_writeback(struct task_struct *target,
+                const struct user_regset *regset,
+                int now)
+{
+       if (test_and_set_tsk_thread_flag(target, TIF_RESTORE_RSE))
+               return 0;
+       tsk_set_notify_resume(target);
+       return do_regset_call(do_gpregs_writeback, target, regset, 0, 0,
+               NULL, NULL);
+}
+
+static int
+fpregs_active(struct task_struct *target, const struct user_regset *regset)
+{
+       return (target->thread.flags & IA64_THREAD_FPH_VALID) ? 128 : 32;
+}
+
+static int fpregs_get(struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               void *kbuf, void __user *ubuf)
+{
+       return do_regset_call(do_fpregs_get, target, regset, pos, count,
+               kbuf, ubuf);
+}
+
+static int fpregs_set(struct task_struct *target,
+               const struct user_regset *regset,
+               unsigned int pos, unsigned int count,
+               const void *kbuf, const void __user *ubuf)
+{
+       return do_regset_call(do_fpregs_set, target, regset, pos, count,
+               kbuf, ubuf);
+}
+
+static int
+access_uarea(struct task_struct *child, unsigned long addr,
+             unsigned long *data, int write_access)
+{
+       unsigned int pos = -1; /* an invalid value */
+       int ret;
+       unsigned long *ptr, regnum;
+
+       if ((addr & 0x7) != 0) {
+               dprintk("ptrace: unaligned register address 0x%lx\n", addr);
+               return -1;
+       }
+       if ((addr >= PT_NAT_BITS + 8 && addr < PT_F2) ||
+               (addr >= PT_R7 + 8 && addr < PT_B1) ||
+               (addr >= PT_AR_LC + 8 && addr < PT_CR_IPSR) ||
+               (addr >= PT_AR_SSD + 8 && addr < PT_DBR)) {
+               dprintk("ptrace: rejecting access to register "
+                                       "address 0x%lx\n", addr);
+               return -1;
+       }
+
+       switch (addr) {
+       case PT_F32 ... (PT_F127 + 15):
+               pos = addr - PT_F32 + ELF_FP_OFFSET(32);
+               break;
+       case PT_F2 ... (PT_F5 + 15):
+               pos = addr - PT_F2 + ELF_FP_OFFSET(2);
+               break;
+       case PT_F10 ... (PT_F31 + 15):
+               pos = addr - PT_F10 + ELF_FP_OFFSET(10);
+               break;
+       case PT_F6 ... (PT_F9 + 15):
+               pos = addr - PT_F6 + ELF_FP_OFFSET(6);
+               break;
+       }
+
+       if (pos != -1) {
+               if (write_access)
+                       ret = fpregs_set(child, NULL, pos,
+                               sizeof(unsigned long), data, NULL);
+               else
+                       ret = fpregs_get(child, NULL, pos,
+                               sizeof(unsigned long), data, NULL);
+               if (ret != 0)
+                       return -1;
+               return 0;
+       }
+
+       switch (addr) {
+       case PT_NAT_BITS:
+               pos = ELF_NAT_OFFSET;
+               break;
+       case PT_R4 ... PT_R7:
+               pos = addr - PT_R4 + ELF_GR_OFFSET(4);
+               break;
+       case PT_B1 ... PT_B5:
+               pos = addr - PT_B1 + ELF_BR_OFFSET(1);
+               break;
+       case PT_AR_EC:
+               pos = ELF_AR_EC_OFFSET;
+               break;
+       case PT_AR_LC:
+               pos = ELF_AR_LC_OFFSET;
+               break;
+       case PT_CR_IPSR:
+               pos = ELF_CR_IPSR_OFFSET;
+               break;
+       case PT_CR_IIP:
+               pos = ELF_CR_IIP_OFFSET;
+               break;
+       case PT_CFM:
+               pos = ELF_CFM_OFFSET;
+               break;
+       case PT_AR_UNAT:
+               pos = ELF_AR_UNAT_OFFSET;
+               break;
+       case PT_AR_PFS:
+               pos = ELF_AR_PFS_OFFSET;
+               break;
+       case PT_AR_RSC:
+               pos = ELF_AR_RSC_OFFSET;
+               break;
+       case PT_AR_RNAT:
+               pos = ELF_AR_RNAT_OFFSET;
+               break;
+       case PT_AR_BSPSTORE:
+               pos = ELF_AR_BSPSTORE_OFFSET;
+               break;
+       case PT_PR:
+               pos = ELF_PR_OFFSET;
+               break;
+       case PT_B6:
+               pos = ELF_BR_OFFSET(6);
+               break;
+       case PT_AR_BSP:
+               pos = ELF_AR_BSP_OFFSET;
+               break;
+       case PT_R1 ... PT_R3:
+               pos = addr - PT_R1 + ELF_GR_OFFSET(1);
+               break;
+       case PT_R12 ... PT_R15:
+               pos = addr - PT_R12 + ELF_GR_OFFSET(12);
+               break;
+       case PT_R8 ... PT_R11:
+               pos = addr - PT_R8 + ELF_GR_OFFSET(8);
+               break;
+       case PT_R16 ... PT_R31:
+               pos = addr - PT_R16 + ELF_GR_OFFSET(16);
+               break;
+       case PT_AR_CCV:
+               pos = ELF_AR_CCV_OFFSET;
+               break;
+       case PT_AR_FPSR:
+               pos = ELF_AR_FPSR_OFFSET;
+               break;
+       case PT_B0:
+               pos = ELF_BR_OFFSET(0);
+               break;
+       case PT_B7:
+               pos = ELF_BR_OFFSET(7);
+               break;
+       case PT_AR_CSD:
+               pos = ELF_AR_CSD_OFFSET;
+               break;
+       case PT_AR_SSD:
+               pos = ELF_AR_SSD_OFFSET;
+               break;
+       }
+
+       if (pos != -1) {
+               if (write_access)
+                       ret = gpregs_set(child, NULL, pos,
+                               sizeof(unsigned long), data, NULL);
+               else
+                       ret = gpregs_get(child, NULL, pos,
+                               sizeof(unsigned long), data, NULL);
+               if (ret != 0)
+                       return -1;
+               return 0;
+       }
+
+       /* access debug registers */
+       if (addr >= PT_IBR) {
+               regnum = (addr - PT_IBR) >> 3;
+               ptr = &child->thread.ibr[0];
+       } else {
+               regnum = (addr - PT_DBR) >> 3;
+               ptr = &child->thread.dbr[0];
+       }
+
+       if (regnum >= 8) {
+               dprintk("ptrace: rejecting access to register "
+                               "address 0x%lx\n", addr);
+               return -1;
+       }
+#ifdef CONFIG_PERFMON
+       /*
+        * Check if debug registers are used by perfmon. This
+        * test must be done once we know that we can do the
+        * operation, i.e. the arguments are all valid, but
+        * before we start modifying the state.
+        *
+        * Perfmon needs to keep a count of how many processes
+        * are trying to modify the debug registers for system
+        * wide monitoring sessions.
+        *
+        * We also include read access here, because they may
+        * cause the PMU-installed debug register state
+        * (dbr[], ibr[]) to be reset. The two arrays are also
+        * used by perfmon, but we do not use
+        * IA64_THREAD_DBG_VALID. The registers are restored
+        * by the PMU context switch code.
+        */
+       if (pfm_use_debug_registers(child))
+               return -1;
+#endif
+
+       if (!(child->thread.flags & IA64_THREAD_DBG_VALID)) {
+               child->thread.flags |= IA64_THREAD_DBG_VALID;
+               memset(child->thread.dbr, 0,
+                               sizeof(child->thread.dbr));
+               memset(child->thread.ibr, 0,
+                               sizeof(child->thread.ibr));
+       }
+
+       ptr += regnum;
+
+       if ((regnum & 1) && write_access) {
+               /* don't let the user set kernel-level breakpoints: */
+               *ptr = *data & ~(7UL << 56);
+               return 0;
+       }
+       if (write_access)
+               *ptr = *data;
+       else
+               *data = *ptr;
+       return 0;
+}
+
+static const struct user_regset native_regsets[] = {
+       {
+               .core_note_type = NT_PRSTATUS,
+               .n = ELF_NGREG,
+               .size = sizeof(elf_greg_t), .align = sizeof(elf_greg_t),
+               .get = gpregs_get, .set = gpregs_set,
+               .writeback = gpregs_writeback
+       },
+       {
+               .core_note_type = NT_PRFPREG,
+               .n = ELF_NFPREG,
+               .size = sizeof(elf_fpreg_t), .align = sizeof(elf_fpreg_t),
+               .get = fpregs_get, .set = fpregs_set, .active = fpregs_active
+       },
+};
+
+static const struct user_regset_view user_ia64_view = {
+       .name = "ia64",
+       .e_machine = EM_IA_64,
+       .regsets = native_regsets, .n = ARRAY_SIZE(native_regsets)
+};
+
+const struct user_regset_view *task_user_regset_view(struct task_struct *tsk)
+{
+#ifdef CONFIG_IA32_SUPPORT
+       extern const struct user_regset_view user_ia32_view;
+       if (IS_IA32_PROCESS(task_pt_regs(tsk)))
+               return &user_ia32_view;
+#endif
+       return &user_ia64_view;
+}
index c85b7dd..5015ca1 100644 (file)
@@ -59,6 +59,7 @@
 #include <asm/setup.h>
 #include <asm/smp.h>
 #include <asm/system.h>
+#include <asm/tlbflush.h>
 #include <asm/unistd.h>
 #include <asm/hpsim.h>
 
@@ -516,6 +517,8 @@ setup_arch (char **cmdline_p)
        acpi_table_init();
 # ifdef CONFIG_ACPI_NUMA
        acpi_numa_init();
+       per_cpu_scan_finalize((cpus_weight(early_cpu_possible_map) == 0 ?
+               32 : cpus_weight(early_cpu_possible_map)), additional_cpus);
 # endif
 #else
 # ifdef CONFIG_SMP
@@ -969,9 +972,10 @@ cpu_init (void)
 #endif
 
        /* set ia64_ctx.max_rid to the maximum RID that is supported by all CPUs: */
-       if (ia64_pal_vm_summary(NULL, &vmi) == 0)
+       if (ia64_pal_vm_summary(NULL, &vmi) == 0) {
                max_ctx = (1U << (vmi.pal_vm_info_2_s.rid_size - 3)) - 1;
-       else {
+               setup_ptcg_sem(vmi.pal_vm_info_2_s.max_purges, NPTCG_FROM_PAL);
+       } else {
                printk(KERN_WARNING "cpu_init: PAL VM summary failed, assuming 18 RID bits\n");
                max_ctx = (1U << 15) - 1;       /* use architected minimum */
        }
index 4e446aa..9a9d4c4 100644 (file)
@@ -213,6 +213,19 @@ send_IPI_allbutself (int op)
  * Called with preemption disabled.
  */
 static inline void
+send_IPI_mask(cpumask_t mask, int op)
+{
+       unsigned int cpu;
+
+       for_each_cpu_mask(cpu, mask) {
+                       send_IPI_single(cpu, op);
+       }
+}
+
+/*
+ * Called with preemption disabled.
+ */
+static inline void
 send_IPI_all (int op)
 {
        int i;
@@ -401,6 +414,75 @@ smp_call_function_single (int cpuid, void (*func) (void *info), void *info, int
 }
 EXPORT_SYMBOL(smp_call_function_single);
 
+/**
+ * smp_call_function_mask(): Run a function on a set of other CPUs.
+ * <mask>      The set of cpus to run on.  Must not include the current cpu.
+ * <func>      The function to run. This must be fast and non-blocking.
+ * <info>      An arbitrary pointer to pass to the function.
+ * <wait>      If true, wait (atomically) until function
+ *             has completed on other CPUs.
+ *
+ * Returns 0 on success, else a negative status code.
+ *
+ * If @wait is true, then returns once @func has returned; otherwise
+ * it returns just before the target cpu calls @func.
+ *
+ * You must not call this function with disabled interrupts or from a
+ * hardware interrupt handler or from a bottom half handler.
+ */
+int smp_call_function_mask(cpumask_t mask,
+                          void (*func)(void *), void *info,
+                          int wait)
+{
+       struct call_data_struct data;
+       cpumask_t allbutself;
+       int cpus;
+
+       spin_lock(&call_lock);
+       allbutself = cpu_online_map;
+       cpu_clear(smp_processor_id(), allbutself);
+
+       cpus_and(mask, mask, allbutself);
+       cpus = cpus_weight(mask);
+       if (!cpus) {
+               spin_unlock(&call_lock);
+               return 0;
+       }
+
+       /* Can deadlock when called with interrupts disabled */
+       WARN_ON(irqs_disabled());
+
+       data.func = func;
+       data.info = info;
+       atomic_set(&data.started, 0);
+       data.wait = wait;
+       if (wait)
+               atomic_set(&data.finished, 0);
+
+       call_data = &data;
+       mb(); /* ensure store to call_data precedes setting of IPI_CALL_FUNC*/
+
+       /* Send a message to other CPUs */
+       if (cpus_equal(mask, allbutself))
+               send_IPI_allbutself(IPI_CALL_FUNC);
+       else
+               send_IPI_mask(mask, IPI_CALL_FUNC);
+
+       /* Wait for response */
+       while (atomic_read(&data.started) != cpus)
+               cpu_relax();
+
+       if (wait)
+               while (atomic_read(&data.finished) != cpus)
+                       cpu_relax();
+       call_data = NULL;
+
+       spin_unlock(&call_lock);
+       return 0;
+
+}
+EXPORT_SYMBOL(smp_call_function_mask);
+
 /*
  * this function sends a 'generic call function' IPI to all other CPUs
  * in the system.
index 17fda52..48e15a5 100644 (file)
@@ -59,6 +59,84 @@ static struct clocksource clocksource_itc = {
 };
 static struct clocksource *itc_clocksource;
 
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+
+#include <linux/kernel_stat.h>
+
+extern cputime_t cycle_to_cputime(u64 cyc);
+
+/*
+ * Called from the context switch with interrupts disabled, to charge all
+ * accumulated times to the current process, and to prepare accounting on
+ * the next process.
+ */
+void ia64_account_on_switch(struct task_struct *prev, struct task_struct *next)
+{
+       struct thread_info *pi = task_thread_info(prev);
+       struct thread_info *ni = task_thread_info(next);
+       cputime_t delta_stime, delta_utime;
+       __u64 now;
+
+       now = ia64_get_itc();
+
+       delta_stime = cycle_to_cputime(pi->ac_stime + (now - pi->ac_stamp));
+       account_system_time(prev, 0, delta_stime);
+       account_system_time_scaled(prev, delta_stime);
+
+       if (pi->ac_utime) {
+               delta_utime = cycle_to_cputime(pi->ac_utime);
+               account_user_time(prev, delta_utime);
+               account_user_time_scaled(prev, delta_utime);
+       }
+
+       pi->ac_stamp = ni->ac_stamp = now;
+       ni->ac_stime = ni->ac_utime = 0;
+}
+
+/*
+ * Account time for a transition between system, hard irq or soft irq state.
+ * Note that this function is called with interrupts enabled.
+ */
+void account_system_vtime(struct task_struct *tsk)
+{
+       struct thread_info *ti = task_thread_info(tsk);
+       unsigned long flags;
+       cputime_t delta_stime;
+       __u64 now;
+
+       local_irq_save(flags);
+
+       now = ia64_get_itc();
+
+       delta_stime = cycle_to_cputime(ti->ac_stime + (now - ti->ac_stamp));
+       account_system_time(tsk, 0, delta_stime);
+       account_system_time_scaled(tsk, delta_stime);
+       ti->ac_stime = 0;
+
+       ti->ac_stamp = now;
+
+       local_irq_restore(flags);
+}
+
+/*
+ * Called from the timer interrupt handler to charge accumulated user time
+ * to the current process.  Must be called with interrupts disabled.
+ */
+void account_process_tick(struct task_struct *p, int user_tick)
+{
+       struct thread_info *ti = task_thread_info(p);
+       cputime_t delta_utime;
+
+       if (ti->ac_utime) {
+               delta_utime = cycle_to_cputime(ti->ac_utime);
+               account_user_time(p, delta_utime);
+               account_user_time_scaled(p, delta_utime);
+               ti->ac_utime = 0;
+       }
+}
+
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
+
 static irqreturn_t
 timer_interrupt (int irq, void *dev_id)
 {
index 96d5fbf..544dc42 100644 (file)
@@ -104,7 +104,7 @@ static int __meminit early_nr_cpus_node(int node)
 {
        int cpu, n = 0;
 
-       for (cpu = 0; cpu < NR_CPUS; cpu++)
+       for_each_possible_early_cpu(cpu)
                if (node == node_cpuid[cpu].nid)
                        n++;
 
@@ -124,6 +124,7 @@ static unsigned long __meminit compute_pernodesize(int node)
        pernodesize += node * L1_CACHE_BYTES;
        pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
        pernodesize += L1_CACHE_ALIGN(sizeof(struct ia64_node_data));
+       pernodesize += L1_CACHE_ALIGN(sizeof(pg_data_t));
        pernodesize = PAGE_ALIGN(pernodesize);
        return pernodesize;
 }
@@ -142,7 +143,7 @@ static void *per_cpu_node_setup(void *cpu_data, int node)
 #ifdef CONFIG_SMP
        int cpu;
 
-       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+       for_each_possible_early_cpu(cpu) {
                if (node == node_cpuid[cpu].nid) {
                        memcpy(__va(cpu_data), __phys_per_cpu_start,
                               __per_cpu_end - __per_cpu_start);
@@ -345,7 +346,7 @@ static void __init initialize_pernode_data(void)
 
 #ifdef CONFIG_SMP
        /* Set the node_data pointer for each per-cpu struct */
-       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+       for_each_possible_early_cpu(cpu) {
                node = node_cpuid[cpu].nid;
                per_cpu(cpu_info, cpu).node_data = mem_data[node].node_data;
        }
@@ -493,13 +494,9 @@ void __cpuinit *per_cpu_init(void)
        int cpu;
        static int first_time = 1;
 
-
-       if (smp_processor_id() != 0)
-               return __per_cpu_start + __per_cpu_offset[smp_processor_id()];
-
        if (first_time) {
                first_time = 0;
-               for (cpu = 0; cpu < NR_CPUS; cpu++)
+               for_each_possible_early_cpu(cpu)
                        per_cpu(local_per_cpu_offset, cpu) = __per_cpu_offset[cpu];
        }
 
index 7807fc5..b73bf18 100644 (file)
@@ -27,7 +27,9 @@
  */
 int num_node_memblks;
 struct node_memblk_s node_memblk[NR_NODE_MEMBLKS];
-struct node_cpuid_s node_cpuid[NR_CPUS];
+struct node_cpuid_s node_cpuid[NR_CPUS] =
+       { [0 ... NR_CPUS-1] = { .phys_id = 0, .nid = NUMA_NO_NODE } };
+
 /*
  * This is a matrix with "distances" between nodes, they should be
  * proportional to the memory access latency ratios.
index 655da24..d52ec4e 100644 (file)
@@ -11,6 +11,9 @@
  * Rohit Seth <rohit.seth@intel.com>
  * Ken Chen <kenneth.w.chen@intel.com>
  * Christophe de Dinechin <ddd@hp.com>: Avoid ptc.e on memory allocation
+ * Copyright (C) 2007 Intel Corp
+ *     Fenghua Yu <fenghua.yu@intel.com>
+ *     Add multiple ptc.g/ptc.ga instruction support in global tlb purge.
  */
 #include <linux/module.h>
 #include <linux/init.h>
@@ -26,6 +29,9 @@
 #include <asm/pal.h>
 #include <asm/tlbflush.h>
 #include <asm/dma.h>
+#include <asm/processor.h>
+#include <asm/sal.h>
+#include <asm/tlb.h>
 
 static struct {
        unsigned long mask;     /* mask of supported purge page-sizes */
@@ -39,6 +45,10 @@ struct ia64_ctx ia64_ctx = {
 };
 
 DEFINE_PER_CPU(u8, ia64_need_tlb_flush);
+DEFINE_PER_CPU(u8, ia64_tr_num);  /*Number of TR slots in current processor*/
+DEFINE_PER_CPU(u8, ia64_tr_used); /*Max Slot number used by kernel*/
+
+struct ia64_tr_entry __per_cpu_idtrs[NR_CPUS][2][IA64_TR_ALLOC_MAX];
 
 /*
  * Initializes the ia64_ctx.bitmap array based on max_ctx+1.
@@ -84,14 +94,140 @@ wrap_mmu_context (struct mm_struct *mm)
        local_flush_tlb_all();
 }
 
+/*
+ * Implement "spinaphores" ... like counting semaphores, but they
+ * spin instead of sleeping.  If there are ever any other users for
+ * this primitive it can be moved up to a spinaphore.h header.
+ */
+struct spinaphore {
+       atomic_t        cur;
+};
+
+static inline void spinaphore_init(struct spinaphore *ss, int val)
+{
+       atomic_set(&ss->cur, val);
+}
+
+static inline void down_spin(struct spinaphore *ss)
+{
+       while (unlikely(!atomic_add_unless(&ss->cur, -1, 0)))
+               while (atomic_read(&ss->cur) == 0)
+                       cpu_relax();
+}
+
+static inline void up_spin(struct spinaphore *ss)
+{
+       atomic_add(1, &ss->cur);
+}
+
+static struct spinaphore ptcg_sem;
+static u16 nptcg = 1;
+static int need_ptcg_sem = 1;
+static int toolatetochangeptcgsem = 0;
+
+/*
+ * Kernel parameter "nptcg=" overrides max number of concurrent global TLB
+ * purges which is reported from either PAL or SAL PALO.
+ *
+ * We don't have sanity checking for nptcg value. It's the user's responsibility
+ * for valid nptcg value on the platform. Otherwise, kernel may hang in some
+ * cases.
+ */
+static int __init
+set_nptcg(char *str)
+{
+       int value = 0;
+
+       get_option(&str, &value);
+       setup_ptcg_sem(value, NPTCG_FROM_KERNEL_PARAMETER);
+
+       return 1;
+}
+
+__setup("nptcg=", set_nptcg);
+
+/*
+ * Maximum number of simultaneous ptc.g purges in the system can
+ * be defined by PAL_VM_SUMMARY (in which case we should take
+ * the smallest value for any cpu in the system) or by the PAL
+ * override table (in which case we should ignore the value from
+ * PAL_VM_SUMMARY).
+ *
+ * Kernel parameter "nptcg=" overrides maximum number of simultanesous ptc.g
+ * purges defined in either PAL_VM_SUMMARY or PAL override table. In this case,
+ * we should ignore the value from either PAL_VM_SUMMARY or PAL override table.
+ *
+ * Complicating the logic here is the fact that num_possible_cpus()
+ * isn't fully setup until we start bringing cpus online.
+ */
+void
+setup_ptcg_sem(int max_purges, int nptcg_from)
+{
+       static int kp_override;
+       static int palo_override;
+       static int firstcpu = 1;
+
+       if (toolatetochangeptcgsem) {
+               BUG_ON(max_purges < nptcg);
+               return;
+       }
+
+       if (nptcg_from == NPTCG_FROM_KERNEL_PARAMETER) {
+               kp_override = 1;
+               nptcg = max_purges;
+               goto resetsema;
+       }
+       if (kp_override) {
+               need_ptcg_sem = num_possible_cpus() > nptcg;
+               return;
+       }
+
+       if (nptcg_from == NPTCG_FROM_PALO) {
+               palo_override = 1;
+
+               /* In PALO max_purges == 0 really means it! */
+               if (max_purges == 0)
+                       panic("Whoa! Platform does not support global TLB purges.\n");
+               nptcg = max_purges;
+               if (nptcg == PALO_MAX_TLB_PURGES) {
+                       need_ptcg_sem = 0;
+                       return;
+               }
+               goto resetsema;
+       }
+       if (palo_override) {
+               if (nptcg != PALO_MAX_TLB_PURGES)
+                       need_ptcg_sem = (num_possible_cpus() > nptcg);
+               return;
+       }
+
+       /* In PAL_VM_SUMMARY max_purges == 0 actually means 1 */
+       if (max_purges == 0) max_purges = 1;
+
+       if (firstcpu) {
+               nptcg = max_purges;
+               firstcpu = 0;
+       }
+       if (max_purges < nptcg)
+               nptcg = max_purges;
+       if (nptcg == PAL_MAX_PURGES) {
+               need_ptcg_sem = 0;
+               return;
+       } else
+               need_ptcg_sem = (num_possible_cpus() > nptcg);
+
+resetsema:
+       spinaphore_init(&ptcg_sem, max_purges);
+}
+
 void
 ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
                       unsigned long end, unsigned long nbits)
 {
-       static DEFINE_SPINLOCK(ptcg_lock);
-
        struct mm_struct *active_mm = current->active_mm;
 
+       toolatetochangeptcgsem = 1;
+
        if (mm != active_mm) {
                /* Restore region IDs for mm */
                if (mm && active_mm) {
@@ -102,19 +238,20 @@ ia64_global_tlb_purge (struct mm_struct *mm, unsigned long start,
                }
        }
 
-       /* HW requires global serialization of ptc.ga.  */
-       spin_lock(&ptcg_lock);
-       {
-               do {
-                       /*
-                        * Flush ALAT entries also.
-                        */
-                       ia64_ptcga(start, (nbits<<2));
-                       ia64_srlz_i();
-                       start += (1UL << nbits);
-               } while (start < end);
-       }
-       spin_unlock(&ptcg_lock);
+       if (need_ptcg_sem)
+               down_spin(&ptcg_sem);
+
+       do {
+               /*
+                * Flush ALAT entries also.
+                */
+               ia64_ptcga(start, (nbits << 2));
+               ia64_srlz_i();
+               start += (1UL << nbits);
+       } while (start < end);
+
+       if (need_ptcg_sem)
+               up_spin(&ptcg_sem);
 
         if (mm != active_mm) {
                 activate_context(active_mm);
@@ -190,6 +327,9 @@ ia64_tlb_init (void)
        ia64_ptce_info_t uninitialized_var(ptce_info); /* GCC be quiet */
        unsigned long tr_pgbits;
        long status;
+       pal_vm_info_1_u_t vm_info_1;
+       pal_vm_info_2_u_t vm_info_2;
+       int cpu = smp_processor_id();
 
        if ((status = ia64_pal_vm_page_size(&tr_pgbits, &purge.mask)) != 0) {
                printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld; "
@@ -206,4 +346,191 @@ ia64_tlb_init (void)
        local_cpu_data->ptce_stride[1] = ptce_info.stride[1];
 
        local_flush_tlb_all();  /* nuke left overs from bootstrapping... */
+       status = ia64_pal_vm_summary(&vm_info_1, &vm_info_2);
+
+       if (status) {
+               printk(KERN_ERR "ia64_pal_vm_summary=%ld\n", status);
+               per_cpu(ia64_tr_num, cpu) = 8;
+               return;
+       }
+       per_cpu(ia64_tr_num, cpu) = vm_info_1.pal_vm_info_1_s.max_itr_entry+1;
+       if (per_cpu(ia64_tr_num, cpu) >
+                               (vm_info_1.pal_vm_info_1_s.max_dtr_entry+1))
+               per_cpu(ia64_tr_num, cpu) =
+                               vm_info_1.pal_vm_info_1_s.max_dtr_entry+1;
+       if (per_cpu(ia64_tr_num, cpu) > IA64_TR_ALLOC_MAX) {
+               per_cpu(ia64_tr_num, cpu) = IA64_TR_ALLOC_MAX;
+               printk(KERN_DEBUG "TR register number exceeds IA64_TR_ALLOC_MAX!"
+                       "IA64_TR_ALLOC_MAX should be extended\n");
+       }
+}
+
+/*
+ * is_tr_overlap
+ *
+ * Check overlap with inserted TRs.
+ */
+static int is_tr_overlap(struct ia64_tr_entry *p, u64 va, u64 log_size)
+{
+       u64 tr_log_size;
+       u64 tr_end;
+       u64 va_rr = ia64_get_rr(va);
+       u64 va_rid = RR_TO_RID(va_rr);
+       u64 va_end = va + (1<<log_size) - 1;
+
+       if (va_rid != RR_TO_RID(p->rr))
+               return 0;
+       tr_log_size = (p->itir & 0xff) >> 2;
+       tr_end = p->ifa + (1<<tr_log_size) - 1;
+
+       if (va > tr_end || p->ifa > va_end)
+               return 0;
+       return 1;
+
+}
+
+/*
+ * ia64_insert_tr in virtual mode. Allocate a TR slot
+ *
+ * target_mask : 0x1 : itr, 0x2 : dtr, 0x3 : idtr
+ *
+ * va  : virtual address.
+ * pte         : pte entries inserted.
+ * log_size: range to be covered.
+ *
+ * Return value:  <0 :  error No.
+ *
+ *               >=0 : slot number allocated for TR.
+ * Must be called with preemption disabled.
+ */
+int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size)
+{
+       int i, r;
+       unsigned long psr;
+       struct ia64_tr_entry *p;
+       int cpu = smp_processor_id();
+
+       r = -EINVAL;
+       /*Check overlap with existing TR entries*/
+       if (target_mask & 0x1) {
+               p = &__per_cpu_idtrs[cpu][0][0];
+               for (i = IA64_TR_ALLOC_BASE; i <= per_cpu(ia64_tr_used, cpu);
+                                                               i++, p++) {
+                       if (p->pte & 0x1)
+                               if (is_tr_overlap(p, va, log_size)) {
+                                       printk(KERN_DEBUG "Overlapped Entry"
+                                               "Inserted for TR Reigster!!\n");
+                                       goto out;
+                       }
+               }
+       }
+       if (target_mask & 0x2) {
+               p = &__per_cpu_idtrs[cpu][1][0];
+               for (i = IA64_TR_ALLOC_BASE; i <= per_cpu(ia64_tr_used, cpu);
+                                                               i++, p++) {
+                       if (p->pte & 0x1)
+                               if (is_tr_overlap(p, va, log_size)) {
+                                       printk(KERN_DEBUG "Overlapped Entry"
+                                               "Inserted for TR Reigster!!\n");
+                                       goto out;
+                               }
+               }
+       }
+
+       for (i = IA64_TR_ALLOC_BASE; i < per_cpu(ia64_tr_num, cpu); i++) {
+               switch (target_mask & 0x3) {
+               case 1:
+                       if (!(__per_cpu_idtrs[cpu][0][i].pte & 0x1))
+                               goto found;
+                       continue;
+               case 2:
+                       if (!(__per_cpu_idtrs[cpu][1][i].pte & 0x1))
+                               goto found;
+                       continue;
+               case 3:
+                       if (!(__per_cpu_idtrs[cpu][0][i].pte & 0x1) &&
+                               !(__per_cpu_idtrs[cpu][1][i].pte & 0x1))
+                               goto found;
+                       continue;
+               default:
+                       r = -EINVAL;
+                       goto out;
+               }
+       }
+found:
+       if (i >= per_cpu(ia64_tr_num, cpu))
+               return -EBUSY;
+
+       /*Record tr info for mca hander use!*/
+       if (i > per_cpu(ia64_tr_used, cpu))
+               per_cpu(ia64_tr_used, cpu) = i;
+
+       psr = ia64_clear_ic();
+       if (target_mask & 0x1) {
+               ia64_itr(0x1, i, va, pte, log_size);
+               ia64_srlz_i();
+               p = &__per_cpu_idtrs[cpu][0][i];
+               p->ifa = va;
+               p->pte = pte;
+               p->itir = log_size << 2;
+               p->rr = ia64_get_rr(va);
+       }
+       if (target_mask & 0x2) {
+               ia64_itr(0x2, i, va, pte, log_size);
+               ia64_srlz_i();
+               p = &__per_cpu_idtrs[cpu][1][i];
+               p->ifa = va;
+               p->pte = pte;
+               p->itir = log_size << 2;
+               p->rr = ia64_get_rr(va);
+       }
+       ia64_set_psr(psr);
+       r = i;
+out:
+       return r;
+}
+EXPORT_SYMBOL_GPL(ia64_itr_entry);
+
+/*
+ * ia64_purge_tr
+ *
+ * target_mask: 0x1: purge itr, 0x2 : purge dtr, 0x3 purge idtr.
+ * slot: slot number to be freed.
+ *
+ * Must be called with preemption disabled.
+ */
+void ia64_ptr_entry(u64 target_mask, int slot)
+{
+       int cpu = smp_processor_id();
+       int i;
+       struct ia64_tr_entry *p;
+
+       if (slot < IA64_TR_ALLOC_BASE || slot >= per_cpu(ia64_tr_num, cpu))
+               return;
+
+       if (target_mask & 0x1) {
+               p = &__per_cpu_idtrs[cpu][0][slot];
+               if ((p->pte&0x1) && is_tr_overlap(p, p->ifa, p->itir>>2)) {
+                       p->pte = 0;
+                       ia64_ptr(0x1, p->ifa, p->itir>>2);
+                       ia64_srlz_i();
+               }
+       }
+
+       if (target_mask & 0x2) {
+               p = &__per_cpu_idtrs[cpu][1][slot];
+               if ((p->pte & 0x1) && is_tr_overlap(p, p->ifa, p->itir>>2)) {
+                       p->pte = 0;
+                       ia64_ptr(0x2, p->ifa, p->itir>>2);
+                       ia64_srlz_i();
+               }
+       }
+
+       for (i = per_cpu(ia64_tr_used, cpu); i >= IA64_TR_ALLOC_BASE; i--) {
+               if ((__per_cpu_idtrs[cpu][0][i].pte & 0x1) ||
+                               (__per_cpu_idtrs[cpu][1][i].pte & 0x1))
+                       break;
+       }
+       per_cpu(ia64_tr_used, cpu) = i;
 }
+EXPORT_SYMBOL_GPL(ia64_ptr_entry);
index e282c34..53d0a8e 100644 (file)
@@ -362,7 +362,12 @@ pci_acpi_scan_root(struct acpi_device *device, int domain, int bus)
        info.name = name;
        acpi_walk_resources(device->handle, METHOD_NAME__CRS, add_window,
                        &info);
-
+       /*
+        * See arch/x86/pci/acpi.c.
+        * The desired pci bus might already be scanned in a quirk. We
+        * should handle the case here, but it appears that IA64 hasn't
+        * such quirk. So we just ignore the case now.
+        */
        pbus = pci_scan_bus_parented(NULL, bus, &pci_root_ops, controller);
        if (pbus)
                pcibios_setup_root_windows(pbus, controller);
index 841904c..39d6812 100644 (file)
@@ -189,7 +189,7 @@ static struct resource au1200_lcd_resources[] = {
 static struct resource au1200_ide0_resources[] = {
        [0] = {
                .start          = AU1XXX_ATA_PHYS_ADDR,
-               .end            = AU1XXX_ATA_PHYS_ADDR + AU1XXX_ATA_PHYS_LEN,
+               .end            = AU1XXX_ATA_PHYS_ADDR + AU1XXX_ATA_PHYS_LEN - 1,
                .flags          = IORESOURCE_MEM,
        },
        [1] = {
index 58fccc9..06213d1 100644 (file)
@@ -534,7 +534,8 @@ insert_restart_trampoline(struct pt_regs *regs)
                 * Flushing one cacheline is cheap.
                 * "sync" on bigger (> 4 way) boxes is not.
                 */
-               flush_icache_range(regs->gr[30], regs->gr[30] + 4);
+               flush_user_dcache_range(regs->gr[30], regs->gr[30] + 4);
+               flush_user_icache_range(regs->gr[30], regs->gr[30] + 4);
 
                regs->gr[31] = regs->gr[30] + 8;
                /* Preserve original r28. */
index a8399b0..06ac31f 100644 (file)
@@ -7,7 +7,6 @@
 
 .text
 
-#include <linux/linkage.h>
 #include <asm/page.h>
 
        .global startup
index 1d4ecbf..f72c198 100644 (file)
@@ -13,7 +13,6 @@
  * Modification for compressed loader:
  *   Copyright (C) 2002 Stuart Menefy (stuart.menefy@st.com)
  */
-#include <linux/linkage.h>
 #include <asm/cache.h>
 #include <asm/cpu/mmu_context.h>
 #include <asm/cpu/registers.h>
index 046999b..0283d81 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/mmu_context.h>
+#include <asm/fpu.h>
 
 struct task_struct *last_task_used_math = NULL;
 
index f6fbdfa..d453c47 100644 (file)
@@ -33,6 +33,7 @@
 #include <asm/system.h>
 #include <asm/processor.h>
 #include <asm/mmu_context.h>
+#include <asm/fpu.h>
 
 /* This mask defines the bits of the SR which the user is not allowed to
    change, which are everything except S, Q, M, PR, SZ, FR. */
index d80de39..45bb333 100644 (file)
@@ -149,3 +149,4 @@ EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__clear_user);
 EXPORT_SYMBOL(_ebss);
+EXPORT_SYMBOL(empty_zero_page);
index dd38a68..b6410ce 100644 (file)
@@ -44,6 +44,7 @@ EXPORT_SYMBOL(__put_user_asm_l);
 EXPORT_SYMBOL(__get_user_asm_l);
 EXPORT_SYMBOL(copy_page);
 EXPORT_SYMBOL(__copy_user);
+EXPORT_SYMBOL(empty_zero_page);
 EXPORT_SYMBOL(memcpy);
 EXPORT_SYMBOL(__udelay);
 EXPORT_SYMBOL(__ndelay);
index 80bde19..552eb81 100644 (file)
@@ -26,6 +26,7 @@
 #include <asm/uaccess.h>
 #include <asm/pgtable.h>
 #include <asm/cacheflush.h>
+#include <asm/fpu.h>
 
 #define REG_RET 9
 #define REG_ARG1 2
index baa4fa3..e08b3bf 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/limits.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
+#include <asm/fpu.h>
 
 #ifdef CONFIG_SH_KGDB
 #include <asm/kgdb.h>
index 1b58a74..a85831c 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/atomic.h>
 #include <asm/processor.h>
 #include <asm/pgtable.h>
+#include <asm/fpu.h>
 
 #undef DEBUG_EXCEPTION
 #ifdef DEBUG_EXCEPTION
index 5b54f11..7f44ae6 100644 (file)
@@ -325,7 +325,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
        const struct user_regset_view *view;
        int ret;
 
-       view = task_user_regset_view(child);
+       view = task_user_regset_view(current);
 
        switch(request) {
        case PTRACE_GETREGS: {
index 7963595..e9fc0aa 100644 (file)
@@ -114,6 +114,85 @@ void flush_ptrace_access(struct vm_area_struct *vma, struct page *page,
        preempt_enable();
 }
 
+static int get_from_target(struct task_struct *target, unsigned long uaddr,
+                          void *kbuf, int len)
+{
+       if (target == current) {
+               if (copy_from_user(kbuf, (void __user *) uaddr, len))
+                       return -EFAULT;
+       } else {
+               int len2 = access_process_vm(target, uaddr, kbuf, len, 0);
+               if (len2 != len)
+                       return -EFAULT;
+       }
+       return 0;
+}
+
+static int set_to_target(struct task_struct *target, unsigned long uaddr,
+                        void *kbuf, int len)
+{
+       if (target == current) {
+               if (copy_to_user((void __user *) uaddr, kbuf, len))
+                       return -EFAULT;
+       } else {
+               int len2 = access_process_vm(target, uaddr, kbuf, len, 1);
+               if (len2 != len)
+                       return -EFAULT;
+       }
+       return 0;
+}
+
+static int regwindow64_get(struct task_struct *target,
+                          const struct pt_regs *regs,
+                          struct reg_window *wbuf)
+{
+       unsigned long rw_addr = regs->u_regs[UREG_I6];
+
+       if (test_tsk_thread_flag(current, TIF_32BIT)) {
+               struct reg_window32 win32;
+               int i;
+
+               if (get_from_target(target, rw_addr, &win32, sizeof(win32)))
+                       return -EFAULT;
+               for (i = 0; i < 8; i++)
+                       wbuf->locals[i] = win32.locals[i];
+               for (i = 0; i < 8; i++)
+                       wbuf->ins[i] = win32.ins[i];
+       } else {
+               rw_addr += STACK_BIAS;
+               if (get_from_target(target, rw_addr, wbuf, sizeof(*wbuf)))
+                       return -EFAULT;
+       }
+
+       return 0;
+}
+
+static int regwindow64_set(struct task_struct *target,
+                          const struct pt_regs *regs,
+                          struct reg_window *wbuf)
+{
+       unsigned long rw_addr = regs->u_regs[UREG_I6];
+
+       if (test_tsk_thread_flag(current, TIF_32BIT)) {
+               struct reg_window32 win32;
+               int i;
+
+               for (i = 0; i < 8; i++)
+                       win32.locals[i] = wbuf->locals[i];
+               for (i = 0; i < 8; i++)
+                       win32.ins[i] = wbuf->ins[i];
+
+               if (set_to_target(target, rw_addr, &win32, sizeof(win32)))
+                       return -EFAULT;
+       } else {
+               rw_addr += STACK_BIAS;
+               if (set_to_target(target, rw_addr, wbuf, sizeof(*wbuf)))
+                       return -EFAULT;
+       }
+
+       return 0;
+}
+
 enum sparc_regset {
        REGSET_GENERAL,
        REGSET_FP,
@@ -133,25 +212,13 @@ static int genregs64_get(struct task_struct *target,
        ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
                                  regs->u_regs,
                                  0, 16 * sizeof(u64));
-       if (!ret) {
-               unsigned long __user *reg_window = (unsigned long __user *)
-                       (regs->u_regs[UREG_I6] + STACK_BIAS);
-               unsigned long window[16];
-
-               if (target == current) {
-                       if (copy_from_user(window, reg_window, sizeof(window)))
-                               return -EFAULT;
-               } else {
-                       if (access_process_vm(target,
-                                             (unsigned long) reg_window,
-                                             window,
-                                             sizeof(window), 0) !=
-                           sizeof(window))
-                               return -EFAULT;
-               }
+       if (!ret && count && pos < (32 * sizeof(u64))) {
+               struct reg_window window;
 
+               if (regwindow64_get(target, regs, &window))
+                       return -EFAULT;
                ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
-                                         window,
+                                         &window,
                                          16 * sizeof(u64),
                                          32 * sizeof(u64));
        }
@@ -173,10 +240,11 @@ static int genregs64_get(struct task_struct *target,
                                          36 * sizeof(u64));
        }
 
-       if (!ret)
+       if (!ret) {
                ret = user_regset_copyout_zero(&pos, &count, &kbuf, &ubuf,
                                               36 * sizeof(u64), -1);
 
+       }
        return ret;
 }
 
@@ -194,42 +262,20 @@ static int genregs64_set(struct task_struct *target,
        ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
                                 regs->u_regs,
                                 0, 16 * sizeof(u64));
-       if (!ret && count > 0) {
-               unsigned long __user *reg_window = (unsigned long __user *)
-                       (regs->u_regs[UREG_I6] + STACK_BIAS);
-               unsigned long window[16];
+       if (!ret && count && pos < (32 * sizeof(u64))) {
+               struct reg_window window;
 
-               if (target == current) {
-                       if (copy_from_user(window, reg_window, sizeof(window)))
-                               return -EFAULT;
-               } else {
-                       if (access_process_vm(target,
-                                             (unsigned long) reg_window,
-                                             window,
-                                             sizeof(window), 0) !=
-                           sizeof(window))
-                               return -EFAULT;
-               }
+               if (regwindow64_get(target, regs, &window))
+                       return -EFAULT;
 
                ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
-                                        window,
+                                        &window,
                                         16 * sizeof(u64),
                                         32 * sizeof(u64));
-               if (!ret) {
-                       if (target == current) {
-                               if (copy_to_user(reg_window, window,
-                                                sizeof(window)))
-                                       return -EFAULT;
-                       } else {
-                               if (access_process_vm(target,
-                                                     (unsigned long)
-                                                     reg_window,
-                                                     window,
-                                                     sizeof(window), 1) !=
-                                   sizeof(window))
-                                       return -EFAULT;
-                       }
-               }
+
+               if (!ret &&
+                   regwindow64_set(target, regs, &window))
+                       return -EFAULT;
        }
 
        if (!ret && count > 0) {
@@ -805,7 +851,7 @@ struct compat_fps {
 long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        compat_ulong_t caddr, compat_ulong_t cdata)
 {
-       const struct user_regset_view *view = task_user_regset_view(child);
+       const struct user_regset_view *view = task_user_regset_view(current);
        compat_ulong_t caddr2 = task_pt_regs(current)->u_regs[UREG_I4];
        struct pt_regs32 __user *pregs;
        struct compat_fps __user *fps;
@@ -913,7 +959,7 @@ struct fps {
 
 long arch_ptrace(struct task_struct *child, long request, long addr, long data)
 {
-       const struct user_regset_view *view = task_user_regset_view(child);
+       const struct user_regset_view *view = task_user_regset_view(current);
        unsigned long addr2 = task_pt_regs(current)->u_regs[UREG_I4];
        struct pt_regs __user *pregs;
        struct fps __user *fps;
index 45d79ea..5fed98c 100644 (file)
@@ -65,7 +65,8 @@ __setup("noreplace-paravirt", setup_noreplace_paravirt);
    get them easily into strings. */
 asm("\t.section .rodata, \"a\"\nintelnops: "
        GENERIC_NOP1 GENERIC_NOP2 GENERIC_NOP3 GENERIC_NOP4 GENERIC_NOP5 GENERIC_NOP6
-       GENERIC_NOP7 GENERIC_NOP8);
+       GENERIC_NOP7 GENERIC_NOP8
+    "\t.previous");
 extern const unsigned char intelnops[];
 static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
        NULL,
@@ -83,7 +84,8 @@ static const unsigned char *const intel_nops[ASM_NOP_MAX+1] = {
 #ifdef K8_NOP1
 asm("\t.section .rodata, \"a\"\nk8nops: "
        K8_NOP1 K8_NOP2 K8_NOP3 K8_NOP4 K8_NOP5 K8_NOP6
-       K8_NOP7 K8_NOP8);
+       K8_NOP7 K8_NOP8
+    "\t.previous");
 extern const unsigned char k8nops[];
 static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
        NULL,
@@ -101,7 +103,8 @@ static const unsigned char *const k8_nops[ASM_NOP_MAX+1] = {
 #ifdef K7_NOP1
 asm("\t.section .rodata, \"a\"\nk7nops: "
        K7_NOP1 K7_NOP2 K7_NOP3 K7_NOP4 K7_NOP5 K7_NOP6
-       K7_NOP7 K7_NOP8);
+       K7_NOP7 K7_NOP8
+    "\t.previous");
 extern const unsigned char k7nops[];
 static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
        NULL,
@@ -119,7 +122,8 @@ static const unsigned char *const k7_nops[ASM_NOP_MAX+1] = {
 #ifdef P6_NOP1
 asm("\t.section .rodata, \"a\"\np6nops: "
        P6_NOP1 P6_NOP2 P6_NOP3 P6_NOP4 P6_NOP5 P6_NOP6
-       P6_NOP7 P6_NOP8);
+       P6_NOP7 P6_NOP8
+    "\t.previous");
 extern const unsigned char p6nops[];
 static const unsigned char *const p6_nops[ASM_NOP_MAX+1] = {
        NULL,
index be3c7a2..43930e7 100644 (file)
@@ -82,7 +82,6 @@ unsigned long thread_saved_pc(struct task_struct *tsk)
  */
 void (*pm_idle)(void);
 EXPORT_SYMBOL(pm_idle);
-static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
 
 void disable_hlt(void)
 {
@@ -190,9 +189,6 @@ void cpu_idle(void)
                while (!need_resched()) {
                        void (*idle)(void);
 
-                       if (__get_cpu_var(cpu_idle_state))
-                               __get_cpu_var(cpu_idle_state) = 0;
-
                        check_pgt_cache();
                        rmb();
                        idle = pm_idle;
@@ -220,40 +216,19 @@ static void do_nothing(void *unused)
 {
 }
 
+/*
+ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
+ * pm_idle and update to new pm_idle value. Required while changing pm_idle
+ * handler on SMP systems.
+ *
+ * Caller must have changed pm_idle to the new value before the call. Old
+ * pm_idle value will not be used by any CPU after the return of this function.
+ */
 void cpu_idle_wait(void)
 {
-       unsigned int cpu, this_cpu = get_cpu();
-       cpumask_t map, tmp = current->cpus_allowed;
-
-       set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
-       put_cpu();
-
-       cpus_clear(map);
-       for_each_online_cpu(cpu) {
-               per_cpu(cpu_idle_state, cpu) = 1;
-               cpu_set(cpu, map);
-       }
-
-       __get_cpu_var(cpu_idle_state) = 0;
-
-       wmb();
-       do {
-               ssleep(1);
-               for_each_online_cpu(cpu) {
-                       if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
-                               cpu_clear(cpu, map);
-               }
-               cpus_and(map, map, cpu_online_map);
-               /*
-                * We waited 1 sec, if a CPU still did not call idle
-                * it may be because it is in idle and not waking up
-                * because it has nothing to do.
-                * Give all the remaining CPUS a kick.
-                */
-               smp_call_function_mask(map, do_nothing, NULL, 0);
-       } while (!cpus_empty(map));
-
-       set_cpus_allowed(current, tmp);
+       smp_mb();
+       /* kick all the CPUs so that they exit out of pm_idle */
+       smp_call_function(do_nothing, NULL, 0, 1);
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
index 3baf9b9..46c4c54 100644 (file)
@@ -63,7 +63,6 @@ EXPORT_SYMBOL(boot_option_idle_override);
  */
 void (*pm_idle)(void);
 EXPORT_SYMBOL(pm_idle);
-static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
 
 static ATOMIC_NOTIFIER_HEAD(idle_notifier);
 
@@ -173,9 +172,6 @@ void cpu_idle(void)
                while (!need_resched()) {
                        void (*idle)(void);
 
-                       if (__get_cpu_var(cpu_idle_state))
-                               __get_cpu_var(cpu_idle_state) = 0;
-
                        rmb();
                        idle = pm_idle;
                        if (!idle)
@@ -207,40 +203,19 @@ static void do_nothing(void *unused)
 {
 }
 
+/*
+ * cpu_idle_wait - Used to ensure that all the CPUs discard old value of
+ * pm_idle and update to new pm_idle value. Required while changing pm_idle
+ * handler on SMP systems.
+ *
+ * Caller must have changed pm_idle to the new value before the call. Old
+ * pm_idle value will not be used by any CPU after the return of this function.
+ */
 void cpu_idle_wait(void)
 {
-       unsigned int cpu, this_cpu = get_cpu();
-       cpumask_t map, tmp = current->cpus_allowed;
-
-       set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
-       put_cpu();
-
-       cpus_clear(map);
-       for_each_online_cpu(cpu) {
-               per_cpu(cpu_idle_state, cpu) = 1;
-               cpu_set(cpu, map);
-       }
-
-       __get_cpu_var(cpu_idle_state) = 0;
-
-       wmb();
-       do {
-               ssleep(1);
-               for_each_online_cpu(cpu) {
-                       if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
-                               cpu_clear(cpu, map);
-               }
-               cpus_and(map, map, cpu_online_map);
-               /*
-                * We waited 1 sec, if a CPU still did not call idle
-                * it may be because it is in idle and not waking up
-                * because it has nothing to do.
-                * Give all the remaining CPUS a kick.
-                */
-               smp_call_function_mask(map, do_nothing, 0, 0);
-       } while (!cpus_empty(map));
-
-       set_cpus_allowed(current, tmp);
+       smp_mb();
+       /* kick all the CPUs so that they exit out of pm_idle */
+       smp_call_function(do_nothing, NULL, 0, 1);
 }
 EXPORT_SYMBOL_GPL(cpu_idle_wait);
 
index 022bcaa..ab6bf37 100644 (file)
@@ -92,7 +92,7 @@ int do_set_thread_area(struct task_struct *p, int idx,
 asmlinkage int sys_set_thread_area(struct user_desc __user *u_info)
 {
        int ret = do_set_thread_area(current, -1, u_info, 1);
-       prevent_tail_call(ret);
+       asmlinkage_protect(1, ret, u_info);
        return ret;
 }
 
@@ -142,7 +142,7 @@ int do_get_thread_area(struct task_struct *p, int idx,
 asmlinkage int sys_get_thread_area(struct user_desc __user *u_info)
 {
        int ret = do_get_thread_area(current, -1, u_info);
-       prevent_tail_call(ret);
+       asmlinkage_protect(1, ret, u_info);
        return ret;
 }
 
index 0234f28..378136f 100644 (file)
@@ -219,8 +219,21 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
        if (pxm >= 0)
                sd->node = pxm_to_node(pxm);
 #endif
+       /*
+        * Maybe the desired pci bus has been already scanned. In such case
+        * it is unnecessary to scan the pci bus with the given domain,busnum.
+        */
+       bus = pci_find_bus(domain, busnum);
+       if (bus) {
+               /*
+                * If the desired bus exits, the content of bus->sysdata will
+                * be replaced by sd.
+                */
+               memcpy(bus->sysdata, sd, sizeof(*sd));
+               kfree(sd);
+       } else
+               bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
 
-       bus = pci_scan_bus_parented(NULL, busnum, &pci_root_ops, sd);
        if (!bus)
                kfree(sd);
 
@@ -228,7 +241,7 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_device *device, int do
        if (bus != NULL) {
                if (pxm >= 0) {
                        printk("bus %d -> pxm %d -> node %d\n",
-                               busnum, pxm, sd->node);
+                               busnum, pxm, pxm_to_node(pxm));
                }
        }
 #endif
index 9bda7bc..7db9a41 100644 (file)
@@ -38,7 +38,7 @@ config BLK_DEV_IO_TRACE
          on a block device queue. For more information (and the user space
          support tools needed), fetch the blktrace app from:
 
-         git://brick.kernel.dk/data/git/blktrace.git
+         git://git.kernel.dk/blktrace.git
 
 config LSF
        bool "Support for Large Single Files"
index f26da2b..f4e1006 100644 (file)
@@ -1214,6 +1214,8 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq)
 static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
                                         struct cfq_io_context *cic)
 {
+       struct io_context *ioc = cic->ioc;
+
        list_del_init(&cic->queue_list);
 
        /*
@@ -1223,6 +1225,9 @@ static void __cfq_exit_single_io_context(struct cfq_data *cfqd,
        cic->dead_key = (unsigned long) cic->key;
        cic->key = NULL;
 
+       if (ioc->ioc_data == cic)
+               rcu_assign_pointer(ioc->ioc_data, NULL);
+
        if (cic->cfqq[ASYNC]) {
                cfq_exit_cfqq(cfqd, cic->cfqq[ASYNC]);
                cic->cfqq[ASYNC] = NULL;
@@ -1255,7 +1260,6 @@ static void cfq_exit_single_io_context(struct io_context *ioc,
  */
 static void cfq_exit_io_context(struct io_context *ioc)
 {
-       rcu_assign_pointer(ioc->ioc_data, NULL);
        call_for_each_cic(ioc, cfq_exit_single_io_context);
 }
 
@@ -1478,8 +1482,7 @@ cfq_drop_dead_cic(struct cfq_data *cfqd, struct io_context *ioc,
 
        spin_lock_irqsave(&ioc->lock, flags);
 
-       if (ioc->ioc_data == cic)
-               rcu_assign_pointer(ioc->ioc_data, NULL);
+       BUG_ON(ioc->ioc_data == cic);
 
        radix_tree_delete(&ioc->radix_root, (unsigned long) cfqd);
        hlist_del_rcu(&cic->cic_list);
index 5b6760e..2d1955c 100644 (file)
@@ -373,10 +373,11 @@ int acpi_bus_receive_event(struct acpi_bus_event *event)
        }
 
        spin_lock_irqsave(&acpi_bus_event_lock, flags);
-       entry =
-           list_entry(acpi_bus_event_list.next, struct acpi_bus_event, node);
-       if (entry)
+       if (!list_empty(&acpi_bus_event_list)) {
+               entry = list_entry(acpi_bus_event_list.next,
+                                  struct acpi_bus_event, node);
                list_del(&entry->node);
+       }
        spin_unlock_irqrestore(&acpi_bus_event_lock, flags);
 
        if (!entry)
index 36a68fa..a825b43 100644 (file)
@@ -822,7 +822,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type)
        }
 
        processors[pr->id] = NULL;
-
+       processor_device_array[pr->id] = NULL;
        kfree(pr);
 
        return 0;
index c4e00ac..1bcecc7 100644 (file)
@@ -1125,7 +1125,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
                        tz->trips.active[i].flags.valid; i++, trips++);
        tz->thermal_zone = thermal_zone_device_register("ACPI thermal zone",
                                        trips, tz, &acpi_thermal_zone_ops);
-       if (!tz->thermal_zone)
+       if (IS_ERR(tz->thermal_zone))
                return -ENODEV;
 
        result = sysfs_create_link(&tz->device->dev.kobj,
index ce830fe..511a830 100644 (file)
@@ -36,7 +36,7 @@
 #define DRV_NAME "pata_ali"
 #define DRV_VERSION "0.7.5"
 
-int ali_atapi_dma = 0;
+static int ali_atapi_dma = 0;
 module_param_named(atapi_dma, ali_atapi_dma, int, 0644);
 MODULE_PARM_DESC(atapi_dma, "Enable ATAPI DMA (0=disable, 1=enable)");
 
index 3988e44..7c5b2dd 100644 (file)
@@ -270,7 +270,7 @@ static u8 sil680_init_chip(struct pci_dev *pdev, int *try_mmio)
                tmpbyte & 1, tmpbyte & 0x30);
 
        *try_mmio = 0;
-#ifdef CONFIG_PPC
+#ifdef CONFIG_PPC_MERGE
        if (machine_is(cell))
                *try_mmio = (tmpbyte & 1) || pci_resource_start(pdev, 5);
 #endif
index 4c19855..9d1e3ca 100644 (file)
@@ -1256,7 +1256,6 @@ static int sata_fsl_probe(struct of_device *ofdev,
        void __iomem *ssr_base = NULL;
        void __iomem *csr_base = NULL;
        struct sata_fsl_host_priv *host_priv = NULL;
-       struct resource *r;
        int irq;
        struct ata_host *host;
 
@@ -1266,8 +1265,6 @@ static int sata_fsl_probe(struct of_device *ofdev,
        dev_printk(KERN_INFO, &ofdev->dev,
                   "Sata FSL Platform/CSB Driver init\n");
 
-       r = kmalloc(sizeof(struct resource), GFP_KERNEL);
-
        hcr_base = of_iomap(ofdev->node, 0);
        if (!hcr_base)
                goto error_exit_with_cleanup;
index 840d1c4..019e367 100644 (file)
@@ -531,8 +531,8 @@ static int k2_sata_init_one(struct pci_dev *pdev, const struct pci_device_id *en
  * */
 static const struct pci_device_id k2_sata_pci_tbl[] = {
        { PCI_VDEVICE(SERVERWORKS, 0x0240), chip_svw4 },
-       { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw4 },
-       { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw8 },
+       { PCI_VDEVICE(SERVERWORKS, 0x0241), chip_svw8 },
+       { PCI_VDEVICE(SERVERWORKS, 0x0242), chip_svw4 },
        { PCI_VDEVICE(SERVERWORKS, 0x024a), chip_svw4 },
        { PCI_VDEVICE(SERVERWORKS, 0x024b), chip_svw4 },
        { PCI_VDEVICE(SERVERWORKS, 0x0410), chip_svw42 },
index 55bd35c..9c9627e 100644 (file)
@@ -50,6 +50,7 @@
 #include <scsi/sg.h>
 #include <scsi/scsi_ioctl.h>
 #include <linux/cdrom.h>
+#include <linux/scatterlist.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
 #define DRIVER_NAME "HP CISS Driver (v 3.6.14)"
index c452e2d..27bfe72 100644 (file)
@@ -8,6 +8,7 @@
  * and is not licensed separately. See file COPYING for details.
  *
  * TODO (sorted by decreasing priority)
+ *  -- Return sense now that rq allows it (we always auto-sense anyway).
  *  -- set readonly flag for CDs, set removable flag for CF readers
  *  -- do inquiry and verify we got a disk and not a tape (for LUN mismatch)
  *  -- verify the 13 conditions and do bulk resets
@@ -359,7 +360,8 @@ static void ub_cmd_build_block(struct ub_dev *sc, struct ub_lun *lun,
 static void ub_cmd_build_packet(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_scsi_cmd *cmd, struct ub_request *urq);
 static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
-static void ub_end_rq(struct request *rq, unsigned int status);
+static void ub_end_rq(struct request *rq, unsigned int status,
+    unsigned int cmd_len);
 static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
     struct ub_request *urq, struct ub_scsi_cmd *cmd);
 static int ub_submit_scsi(struct ub_dev *sc, struct ub_scsi_cmd *cmd);
@@ -642,13 +644,13 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 
        if (atomic_read(&sc->poison)) {
                blkdev_dequeue_request(rq);
-               ub_end_rq(rq, DID_NO_CONNECT << 16);
+               ub_end_rq(rq, DID_NO_CONNECT << 16, blk_rq_bytes(rq));
                return 0;
        }
 
        if (lun->changed && !blk_pc_request(rq)) {
                blkdev_dequeue_request(rq);
-               ub_end_rq(rq, SAM_STAT_CHECK_CONDITION);
+               ub_end_rq(rq, SAM_STAT_CHECK_CONDITION, blk_rq_bytes(rq));
                return 0;
        }
 
@@ -701,7 +703,7 @@ static int ub_request_fn_1(struct ub_lun *lun, struct request *rq)
 
 drop:
        ub_put_cmd(lun, cmd);
-       ub_end_rq(rq, DID_ERROR << 16);
+       ub_end_rq(rq, DID_ERROR << 16, blk_rq_bytes(rq));
        return 0;
 }
 
@@ -770,6 +772,7 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
        struct ub_request *urq = cmd->back;
        struct request *rq;
        unsigned int scsi_status;
+       unsigned int cmd_len;
 
        rq = urq->rq;
 
@@ -779,8 +782,18 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
                                rq->data_len = 0;
                        else
                                rq->data_len -= cmd->act_len;
+                       scsi_status = 0;
+               } else {
+                       if (cmd->act_len != cmd->len) {
+                               if ((cmd->key == MEDIUM_ERROR ||
+                                    cmd->key == UNIT_ATTENTION) &&
+                                   ub_rw_cmd_retry(sc, lun, urq, cmd) == 0)
+                                       return;
+                               scsi_status = SAM_STAT_CHECK_CONDITION;
+                       } else {
+                               scsi_status = 0;
+                       }
                }
-               scsi_status = 0;
        } else {
                if (blk_pc_request(rq)) {
                        /* UB_SENSE_SIZE is smaller than SCSI_SENSE_BUFFERSIZE */
@@ -801,14 +814,17 @@ static void ub_rw_cmd_done(struct ub_dev *sc, struct ub_scsi_cmd *cmd)
 
        urq->rq = NULL;
 
+       cmd_len = cmd->len;
        ub_put_cmd(lun, cmd);
-       ub_end_rq(rq, scsi_status);
+       ub_end_rq(rq, scsi_status, cmd_len);
        blk_start_queue(lun->disk->queue);
 }
 
-static void ub_end_rq(struct request *rq, unsigned int scsi_status)
+static void ub_end_rq(struct request *rq, unsigned int scsi_status,
+    unsigned int cmd_len)
 {
        int error;
+       long rqlen;
 
        if (scsi_status == 0) {
                error = 0;
@@ -816,8 +832,12 @@ static void ub_end_rq(struct request *rq, unsigned int scsi_status)
                error = -EIO;
                rq->errors = scsi_status;
        }
-       if (__blk_end_request(rq, error, blk_rq_bytes(rq)))
-               BUG();
+       rqlen = blk_rq_bytes(rq);    /* Oddly enough, this is the residue. */
+       if (__blk_end_request(rq, error, cmd_len)) {
+               printk(KERN_WARNING DRV_NAME
+                   ": __blk_end_request blew, %s-cmd total %u rqlen %ld\n",
+                   blk_pc_request(rq)? "pc": "fs", cmd_len, rqlen);
+       }
 }
 
 static int ub_rw_cmd_retry(struct ub_dev *sc, struct ub_lun *lun,
index cce5a61..fde2634 100644 (file)
@@ -382,9 +382,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
                        break;
 
                case DAVINCI_I2C_IVR_ARDY:
-                       w = davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG);
-                       MOD_REG_BIT(w, DAVINCI_I2C_STR_ARDY, 1);
-                       davinci_i2c_write_reg(dev, DAVINCI_I2C_STR_REG, w);
+                       davinci_i2c_write_reg(dev,
+                               DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY);
                        complete(&dev->cmd_complete);
                        break;
 
@@ -397,12 +396,9 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
                                if (dev->buf_len)
                                        continue;
 
-                               w = davinci_i2c_read_reg(dev,
-                                                        DAVINCI_I2C_STR_REG);
-                               MOD_REG_BIT(w, DAVINCI_I2C_IMR_RRDY, 0);
                                davinci_i2c_write_reg(dev,
-                                                     DAVINCI_I2C_STR_REG,
-                                                     w);
+                                       DAVINCI_I2C_STR_REG,
+                                       DAVINCI_I2C_IMR_RRDY);
                        } else
                                dev_err(dev->dev, "RDR IRQ while no "
                                        "data requested\n");
@@ -428,9 +424,8 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
                        break;
 
                case DAVINCI_I2C_IVR_SCD:
-                       w = davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG);
-                       MOD_REG_BIT(w, DAVINCI_I2C_STR_SCD, 1);
-                       davinci_i2c_write_reg(dev, DAVINCI_I2C_STR_REG, w);
+                       davinci_i2c_write_reg(dev,
+                               DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_SCD);
                        complete(&dev->cmd_complete);
                        break;
 
index 7c7eb0c..22bb247 100644 (file)
@@ -55,7 +55,7 @@ MODULE_PARM_DESC(iic_force_poll, "Force polling mode");
 
 static int iic_force_fast;
 module_param(iic_force_fast, bool, 0);
-MODULE_PARM_DESC(iic_fast_poll, "Force fast mode (400 kHz)");
+MODULE_PARM_DESC(iic_force_fast, "Force fast mode (400 kHz)");
 
 #define DBG_LEVEL 0
 
index cb9abe7..b1c050f 100644 (file)
@@ -131,11 +131,15 @@ static const struct i2c_algorithm usb_algorithm = {
 
 /* ----- begin of usb layer ---------------------------------------------- */
 
-/* The usb i2c interface uses a vid/pid pair donated by */
-/* Future Technology Devices International Ltd. */
+/*
+ * Initially the usb i2c interface uses a vid/pid pair donated by
+ * Future Technology Devices International Ltd., later a pair was
+ * bought from EZPrototypes
+ */
 static struct usb_device_id i2c_tiny_usb_table [] = {
-       { USB_DEVICE(0x0403, 0xc631) },
-       { }                     /* Terminating entry */
+       { USB_DEVICE(0x0403, 0xc631) },   /* FTDI */
+       { USB_DEVICE(0x1c40, 0x0534) },   /* EZPrototypes */
+       { }                               /* Terminating entry */
 };
 
 MODULE_DEVICE_TABLE(usb, i2c_tiny_usb_table);
index 0f4bf5d..85c016b 100644 (file)
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/platform_device.h>
-
 #include <linux/init.h>
 #include <linux/ide.h>
-#include <linux/sysdev.h>
-
-#include <linux/dma-mapping.h>
-
-#include "ide-timing.h"
+#include <linux/scatterlist.h>
 
-#include <asm/io.h>
 #include <asm/mach-au1x00/au1xxx.h>
 #include <asm/mach-au1x00/au1xxx_dbdma.h>
-
 #include <asm/mach-au1x00/au1xxx_ide.h>
 
 #define DRV_NAME       "au1200-ide"
@@ -56,6 +49,8 @@
 static _auide_hwif auide_hwif;
 static int dbdma_init_done;
 
+static int auide_ddma_init(_auide_hwif *auide);
+
 #if defined(CONFIG_BLK_DEV_IDE_AU1XXX_PIO_DBDMA)
 
 void auide_insw(unsigned long port, void *addr, u32 count)
@@ -591,13 +586,14 @@ static int au_ide_probe(struct device *dev)
                goto out;
        }
 
-       if (!request_mem_region (res->start, res->end-res->start, pdev->name)) {
+       if (!request_mem_region(res->start, res->end - res->start + 1,
+                               pdev->name)) {
                pr_debug("%s: request_mem_region failed\n", DRV_NAME);
                ret =  -EBUSY;
                goto out;
        }
 
-       ahwif->regbase = (u32)ioremap(res->start, res->end-res->start);
+       ahwif->regbase = (u32)ioremap(res->start, res->end - res->start + 1);
        if (ahwif->regbase == 0) {
                ret = -ENOMEM;
                goto out;
@@ -682,7 +678,7 @@ static int au_ide_remove(struct device *dev)
        iounmap((void *)ahwif->regbase);
 
        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-       release_mem_region(res->start, res->end - res->start);
+       release_mem_region(res->start, res->end - res->start + 1);
 
        return 0;
 }
index 1597f0c..d8a1674 100644 (file)
@@ -667,7 +667,7 @@ static int __init it821x_ide_init(void)
 module_init(it821x_ide_init);
 
 module_param_named(noraid, it8212_noraid, int, S_IRUGO);
-MODULE_PARM_DESC(it8212_noraid, "Force card into bypass mode");
+MODULE_PARM_DESC(noraid, "Force card into bypass mode");
 
 MODULE_AUTHOR("Alan Cox");
 MODULE_DESCRIPTION("PCI driver module for the ITE 821x");
index ced83c2..ef1a300 100644 (file)
@@ -2010,6 +2010,7 @@ isdn_net_init(struct net_device *ndev)
        ndev->flags = IFF_NOARP|IFF_POINTOPOINT;
        ndev->type = ARPHRD_ETHER;
        ndev->addr_len = ETH_ALEN;
+       ndev->validate_addr = NULL;
 
        /* for clients with MPPP maybe higher values better */
        ndev->tx_queue_len = 30;
index 9e30774..c37bb0d 100644 (file)
@@ -140,6 +140,7 @@ static struct platform_driver ams_delta_led_driver = {
        .resume         = ams_delta_led_resume,
        .driver         = {
                .name = "ams-delta-led",
+               .owner = THIS_MODULE,
        },
 };
 
@@ -159,3 +160,4 @@ module_exit(ams_delta_led_exit);
 MODULE_AUTHOR("Jonathan McDowell <noodles@earth.li>");
 MODULE_DESCRIPTION("Amstrad Delta LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ams-delta-led");
index af61f55..28db6c1 100644 (file)
@@ -132,6 +132,9 @@ static int __exit pwmled_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:leds-atmel-pwm");
+
 static struct platform_driver pwmled_driver = {
        .driver = {
                .name =         "leds-atmel-pwm",
index 6c3d33b..5750b08 100644 (file)
@@ -170,6 +170,7 @@ static struct platform_driver clevo_mail_led_driver = {
        .resume         = clevo_mail_led_resume,
        .driver         = {
                .name           = KBUILD_MODNAME,
+               .owner          = THIS_MODULE,
        },
 };
 
index 9aebef0..accc7ed 100644 (file)
@@ -101,6 +101,7 @@ static struct platform_driver cmx270led_driver = {
 #endif
        .driver         = {
                .name           = "cm-x270-led",
+               .owner          = THIS_MODULE,
        },
 };
 
@@ -120,3 +121,4 @@ module_exit(cmx270led_exit);
 MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>");
 MODULE_DESCRIPTION("CM-x270 LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:cm-x270-led");
index d2b54b5..096881a 100644 (file)
@@ -75,6 +75,9 @@ static int __devexit cobalt_qube_led_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:cobalt-qube-leds");
+
 static struct platform_driver cobalt_qube_led_driver = {
        .probe  = cobalt_qube_led_probe,
        .remove = __devexit_p(cobalt_qube_led_remove),
index e45f6c4..29e931f 100644 (file)
@@ -99,6 +99,7 @@ static struct platform_driver corgiled_driver = {
 #endif
        .driver         = {
                .name           = "corgi-led",
+               .owner          = THIS_MODULE,
        },
 };
 
@@ -118,3 +119,4 @@ module_exit(corgiled_exit);
 MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
 MODULE_DESCRIPTION("Corgi LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:corgi-led");
index 4c0b058..1aae8b3 100644 (file)
@@ -199,3 +199,4 @@ module_exit(gpio_led_exit);
 MODULE_AUTHOR("Raphael Assenat <raph@8d.com>");
 MODULE_DESCRIPTION("GPIO LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:leds-gpio");
index 677c993..6e51c9b 100644 (file)
@@ -139,6 +139,7 @@ static int h1940leds_remove(struct platform_device *pdev)
 static struct platform_driver h1940leds_driver = {
        .driver         = {
                .name   = "h1940-leds",
+               .owner  = THIS_MODULE,
        },
        .probe          = h1940leds_probe,
        .remove         = h1940leds_remove,
@@ -161,3 +162,4 @@ module_exit(h1940leds_exit);
 MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>");
 MODULE_DESCRIPTION("LED driver for the iPAQ H1940");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:h1940-leds");
index 82d4ec3..870f5a3 100644 (file)
@@ -90,6 +90,9 @@ static int hp6xxled_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:hp6xx-led");
+
 static struct platform_driver hp6xxled_driver = {
        .probe          = hp6xxled_probe,
        .remove         = hp6xxled_remove,
@@ -99,6 +102,7 @@ static struct platform_driver hp6xxled_driver = {
 #endif
        .driver         = {
                .name           = "hp6xx-led",
+               .owner          = THIS_MODULE,
        },
 };
 
index 0fd6407..0d10e11 100644 (file)
@@ -160,3 +160,4 @@ module_exit(s3c24xx_led_exit);
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("S3C24XX LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s3c24xx_led");
index 93e1012..87007cc 100644 (file)
@@ -105,6 +105,7 @@ static struct platform_driver spitzled_driver = {
 #endif
        .driver         = {
                .name           = "spitz-led",
+               .owner          = THIS_MODULE,
        },
 };
 
@@ -124,3 +125,4 @@ module_exit(spitzled_exit);
 MODULE_AUTHOR("Richard Purdie <rpurdie@openedhand.com>");
 MODULE_DESCRIPTION("Spitz LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:spitz-led");
index 9e0a188..7ebecc4 100644 (file)
@@ -109,6 +109,7 @@ static struct platform_driver tosaled_driver = {
        .resume         = tosaled_resume,
        .driver         = {
                .name           = "tosa-led",
+               .owner          = THIS_MODULE,
        },
 };
 
@@ -128,3 +129,4 @@ module_exit(tosaled_exit);
 MODULE_AUTHOR("Dirk Opfer <Dirk@Opfer-Online.de>");
 MODULE_DESCRIPTION("Tosa LED driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:tosa-led");
index c574cf5..b162b83 100644 (file)
@@ -2348,25 +2348,15 @@ static void handle_issuing_new_write_requests6(raid5_conf_t *conf,
 static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
                                struct stripe_head_state *s, int disks)
 {
+       int canceled_check = 0;
+
        set_bit(STRIPE_HANDLE, &sh->state);
-       /* Take one of the following actions:
-        * 1/ start a check parity operation if (uptodate == disks)
-        * 2/ finish a check parity operation and act on the result
-        * 3/ skip to the writeback section if we previously
-        *    initiated a recovery operation
-        */
-       if (s->failed == 0 &&
-           !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
-               if (!test_and_set_bit(STRIPE_OP_CHECK, &sh->ops.pending)) {
-                       BUG_ON(s->uptodate != disks);
-                       clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags);
-                       sh->ops.count++;
-                       s->uptodate--;
-               } else if (
-                      test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) {
-                       clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
-                       clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
 
+       /* complete a check operation */
+       if (test_and_clear_bit(STRIPE_OP_CHECK, &sh->ops.complete)) {
+           clear_bit(STRIPE_OP_CHECK, &sh->ops.ack);
+           clear_bit(STRIPE_OP_CHECK, &sh->ops.pending);
+               if (s->failed == 0) {
                        if (sh->ops.zero_sum_result == 0)
                                /* parity is correct (on disc,
                                 * not in buffer any more)
@@ -2391,7 +2381,8 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
                                        s->uptodate++;
                                }
                        }
-               }
+               } else
+                       canceled_check = 1; /* STRIPE_INSYNC is not set */
        }
 
        /* check if we can clear a parity disk reconstruct */
@@ -2404,12 +2395,28 @@ static void handle_parity_checks5(raid5_conf_t *conf, struct stripe_head *sh,
                clear_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending);
        }
 
+       /* start a new check operation if there are no failures, the stripe is
+        * not insync, and a repair is not in flight
+        */
+       if (s->failed == 0 &&
+           !test_bit(STRIPE_INSYNC, &sh->state) &&
+           !test_bit(STRIPE_OP_MOD_REPAIR_PD, &sh->ops.pending)) {
+               if (!test_and_set_bit(STRIPE_OP_CHECK, &sh->ops.pending)) {
+                       BUG_ON(s->uptodate != disks);
+                       clear_bit(R5_UPTODATE, &sh->dev[sh->pd_idx].flags);
+                       sh->ops.count++;
+                       s->uptodate--;
+               }
+       }
+
        /* Wait for check parity and compute block operations to complete
-        * before write-back
+        * before write-back.  If a failure occurred while the check operation
+        * was in flight we need to cycle this stripe through handle_stripe
+        * since the parity block may not be uptodate
         */
-       if (!test_bit(STRIPE_INSYNC, &sh->state) &&
-               !test_bit(STRIPE_OP_CHECK, &sh->ops.pending) &&
-               !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) {
+       if (!canceled_check && !test_bit(STRIPE_INSYNC, &sh->state) &&
+           !test_bit(STRIPE_OP_CHECK, &sh->ops.pending) &&
+           !test_bit(STRIPE_OP_COMPUTE_BLK, &sh->ops.pending)) {
                struct r5dev *dev;
                /* either failed parity check, or recovery is happening */
                if (s->failed == 0)
index 058ccac..e171650 100644 (file)
@@ -154,6 +154,7 @@ static struct platform_driver ssc_driver = {
        .remove         = __devexit_p(ssc_remove),
        .driver         = {
                .name           = "ssc",
+               .owner          = THIS_MODULE,
        },
 };
 
@@ -172,3 +173,4 @@ module_exit(ssc_exit);
 MODULE_AUTHOR("Hans-Christian Egtvedt <hcegtvedt@atmel.com>");
 MODULE_DESCRIPTION("SSC driver for Atmel AVR32 and AT91");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:ssc");
index f8d3b9a..0d5ce03 100644 (file)
@@ -407,3 +407,4 @@ module_exit(pwm_exit);
 
 MODULE_DESCRIPTION("Driver for AT32/AT91 PWM module");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:atmel_pwm");
index aa8ce7a..302e924 100644 (file)
@@ -164,6 +164,7 @@ static struct platform_driver hdpu_cpustate_driver = {
        .remove = hdpu_cpustate_remove,
        .driver = {
                .name = HDPU_CPUSTATE_NAME,
+               .owner = THIS_MODULE,
        },
 };
 
@@ -248,3 +249,4 @@ module_exit(cpustate_exit);
 
 MODULE_AUTHOR("Brian Waite");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" HDPU_CPUSTATE_NAME);
index 2887b21..2fa36f7 100644 (file)
@@ -55,6 +55,7 @@ static struct platform_driver hdpu_nexus_driver = {
        .remove = hdpu_nexus_remove,
        .driver = {
                .name = HDPU_NEXUS_NAME,
+               .owner = THIS_MODULE,
        },
 };
 
@@ -151,3 +152,4 @@ module_exit(nexus_exit);
 
 MODULE_AUTHOR("Brian Waite");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" HDPU_NEXUS_NAME);
index 21acecc..a28fc2f 100644 (file)
@@ -1075,3 +1075,4 @@ module_exit(at91_mci_exit);
 MODULE_DESCRIPTION("AT91 Multimedia Card Interface driver");
 MODULE_AUTHOR("Nick Randell");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_mci");
index c3926eb..cc5f7bc 100644 (file)
@@ -998,6 +998,7 @@ static struct platform_driver au1xmmc_driver = {
        .resume        = NULL,
        .driver        = {
                .name  = DRIVER_NAME,
+               .owner = THIS_MODULE,
        },
 };
 
@@ -1018,5 +1019,6 @@ module_exit(au1xmmc_exit);
 MODULE_AUTHOR("Advanced Micro Devices, Inc");
 MODULE_DESCRIPTION("MMC/SD driver for the Alchemy Au1XXX");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:au1xxx-mmc");
 #endif
 
index f2070a1..95f33e8 100644 (file)
@@ -1128,6 +1128,7 @@ static struct platform_driver imxmci_driver = {
        .resume         = imxmci_resume,
        .driver         = {
                .name           = DRIVER_NAME,
+               .owner          = THIS_MODULE,
        }
 };
 
@@ -1147,3 +1148,4 @@ module_exit(imxmci_exit);
 MODULE_DESCRIPTION("i.MX Multimedia Card Interface Driver");
 MODULE_AUTHOR("Sascha Hauer, Pengutronix");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-mmc");
index c9dfeb1..90c358b 100644 (file)
@@ -1255,6 +1255,7 @@ static struct platform_driver mmc_omap_driver = {
        .resume         = mmc_omap_resume,
        .driver         = {
                .name   = DRIVER_NAME,
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -1273,5 +1274,5 @@ module_exit(mmc_omap_exit);
 
 MODULE_DESCRIPTION("OMAP Multimedia Card driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS(DRIVER_NAME);
+MODULE_ALIAS("platform:" DRIVER_NAME);
 MODULE_AUTHOR("Juha Yrjölä");
index 1ea8482..65210fc 100644 (file)
@@ -693,6 +693,7 @@ static struct platform_driver pxamci_driver = {
        .resume         = pxamci_resume,
        .driver         = {
                .name   = DRIVER_NAME,
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -711,3 +712,4 @@ module_exit(pxamci_exit);
 
 MODULE_DESCRIPTION("PXA Multimedia Card Interface Driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa2xx-mci");
index 4d5f374..be624a0 100644 (file)
@@ -1948,6 +1948,7 @@ static struct platform_driver wbsd_driver = {
        .resume         = wbsd_platform_resume,
        .driver         = {
                .name   = DRIVER_NAME,
+               .owner  = THIS_MODULE,
        },
 };
 
index d072e87..458d477 100644 (file)
@@ -1763,6 +1763,7 @@ static void cfi_amdstd_sync (struct mtd_info *mtd)
 
                default:
                        /* Not an idle state */
+                       set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
 
                        spin_unlock(chip->mutex);
index b344ff8..492e2ab 100644 (file)
@@ -1015,6 +1015,7 @@ static void cfi_staa_sync (struct mtd_info *mtd)
 
                default:
                        /* Not an idle state */
+                       set_current_state(TASK_UNINTERRUPTIBLE);
                        add_wait_queue(&chip->wq, &wait);
 
                        spin_unlock_bh(chip->mutex);
index 25f1337..59dce6a 100644 (file)
@@ -148,7 +148,7 @@ static inline void b44_sync_dma_desc_for_device(struct ssb_device *sdev,
                                                unsigned long offset,
                                                enum dma_data_direction dir)
 {
-       dma_sync_single_range_for_device(sdev->dev, dma_base,
+       dma_sync_single_range_for_device(sdev->dma_dev, dma_base,
                                         offset & dma_desc_align_mask,
                                         dma_desc_sync_size, dir);
 }
@@ -158,7 +158,7 @@ static inline void b44_sync_dma_desc_for_cpu(struct ssb_device *sdev,
                                             unsigned long offset,
                                             enum dma_data_direction dir)
 {
-       dma_sync_single_range_for_cpu(sdev->dev, dma_base,
+       dma_sync_single_range_for_cpu(sdev->dma_dev, dma_base,
                                      offset & dma_desc_align_mask,
                                      dma_desc_sync_size, dir);
 }
@@ -613,7 +613,7 @@ static void b44_tx(struct b44 *bp)
 
                BUG_ON(skb == NULL);
 
-               dma_unmap_single(bp->sdev->dev,
+               dma_unmap_single(bp->sdev->dma_dev,
                                 rp->mapping,
                                 skb->len,
                                 DMA_TO_DEVICE);
@@ -653,7 +653,7 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
        if (skb == NULL)
                return -ENOMEM;
 
-       mapping = dma_map_single(bp->sdev->dev, skb->data,
+       mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
                                 RX_PKT_BUF_SZ,
                                 DMA_FROM_DEVICE);
 
@@ -663,19 +663,19 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
                mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
                /* Sigh... */
                if (!dma_mapping_error(mapping))
-                       dma_unmap_single(bp->sdev->dev, mapping,
+                       dma_unmap_single(bp->sdev->dma_dev, mapping,
                                        RX_PKT_BUF_SZ, DMA_FROM_DEVICE);
                dev_kfree_skb_any(skb);
                skb = __netdev_alloc_skb(bp->dev, RX_PKT_BUF_SZ, GFP_ATOMIC|GFP_DMA);
                if (skb == NULL)
                        return -ENOMEM;
-               mapping = dma_map_single(bp->sdev->dev, skb->data,
+               mapping = dma_map_single(bp->sdev->dma_dev, skb->data,
                                         RX_PKT_BUF_SZ,
                                         DMA_FROM_DEVICE);
                if (dma_mapping_error(mapping) ||
                        mapping + RX_PKT_BUF_SZ > DMA_30BIT_MASK) {
                        if (!dma_mapping_error(mapping))
-                               dma_unmap_single(bp->sdev->dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
+                               dma_unmap_single(bp->sdev->dma_dev, mapping, RX_PKT_BUF_SZ,DMA_FROM_DEVICE);
                        dev_kfree_skb_any(skb);
                        return -ENOMEM;
                }
@@ -750,7 +750,7 @@ static void b44_recycle_rx(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
                                             dest_idx * sizeof(dest_desc),
                                             DMA_BIDIRECTIONAL);
 
-       dma_sync_single_for_device(bp->sdev->dev, le32_to_cpu(src_desc->addr),
+       dma_sync_single_for_device(bp->sdev->dma_dev, le32_to_cpu(src_desc->addr),
                                   RX_PKT_BUF_SZ,
                                   DMA_FROM_DEVICE);
 }
@@ -772,7 +772,7 @@ static int b44_rx(struct b44 *bp, int budget)
                struct rx_header *rh;
                u16 len;
 
-               dma_sync_single_for_cpu(bp->sdev->dev, map,
+               dma_sync_single_for_cpu(bp->sdev->dma_dev, map,
                                            RX_PKT_BUF_SZ,
                                            DMA_FROM_DEVICE);
                rh = (struct rx_header *) skb->data;
@@ -806,7 +806,7 @@ static int b44_rx(struct b44 *bp, int budget)
                        skb_size = b44_alloc_rx_skb(bp, cons, bp->rx_prod);
                        if (skb_size < 0)
                                goto drop_it;
-                       dma_unmap_single(bp->sdev->dev, map,
+                       dma_unmap_single(bp->sdev->dma_dev, map,
                                         skb_size, DMA_FROM_DEVICE);
                        /* Leave out rx_header */
                        skb_put(skb, len + RX_PKT_OFFSET);
@@ -966,24 +966,24 @@ static int b44_start_xmit(struct sk_buff *skb, struct net_device *dev)
                goto err_out;
        }
 
-       mapping = dma_map_single(bp->sdev->dev, skb->data, len, DMA_TO_DEVICE);
+       mapping = dma_map_single(bp->sdev->dma_dev, skb->data, len, DMA_TO_DEVICE);
        if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
                struct sk_buff *bounce_skb;
 
                /* Chip can't handle DMA to/from >1GB, use bounce buffer */
                if (!dma_mapping_error(mapping))
-                       dma_unmap_single(bp->sdev->dev, mapping, len,
+                       dma_unmap_single(bp->sdev->dma_dev, mapping, len,
                                        DMA_TO_DEVICE);
 
                bounce_skb = __dev_alloc_skb(len, GFP_ATOMIC | GFP_DMA);
                if (!bounce_skb)
                        goto err_out;
 
-               mapping = dma_map_single(bp->sdev->dev, bounce_skb->data,
+               mapping = dma_map_single(bp->sdev->dma_dev, bounce_skb->data,
                                         len, DMA_TO_DEVICE);
                if (dma_mapping_error(mapping) || mapping + len > DMA_30BIT_MASK) {
                        if (!dma_mapping_error(mapping))
-                               dma_unmap_single(bp->sdev->dev, mapping,
+                               dma_unmap_single(bp->sdev->dma_dev, mapping,
                                         len, DMA_TO_DEVICE);
                        dev_kfree_skb_any(bounce_skb);
                        goto err_out;
@@ -1082,7 +1082,7 @@ static void b44_free_rings(struct b44 *bp)
 
                if (rp->skb == NULL)
                        continue;
-               dma_unmap_single(bp->sdev->dev, rp->mapping, RX_PKT_BUF_SZ,
+               dma_unmap_single(bp->sdev->dma_dev, rp->mapping, RX_PKT_BUF_SZ,
                                        DMA_FROM_DEVICE);
                dev_kfree_skb_any(rp->skb);
                rp->skb = NULL;
@@ -1094,7 +1094,7 @@ static void b44_free_rings(struct b44 *bp)
 
                if (rp->skb == NULL)
                        continue;
-               dma_unmap_single(bp->sdev->dev, rp->mapping, rp->skb->len,
+               dma_unmap_single(bp->sdev->dma_dev, rp->mapping, rp->skb->len,
                                        DMA_TO_DEVICE);
                dev_kfree_skb_any(rp->skb);
                rp->skb = NULL;
@@ -1117,12 +1117,12 @@ static void b44_init_rings(struct b44 *bp)
        memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
 
        if (bp->flags & B44_FLAG_RX_RING_HACK)
-               dma_sync_single_for_device(bp->sdev->dev, bp->rx_ring_dma,
+               dma_sync_single_for_device(bp->sdev->dma_dev, bp->rx_ring_dma,
                                          DMA_TABLE_BYTES,
                                          DMA_BIDIRECTIONAL);
 
        if (bp->flags & B44_FLAG_TX_RING_HACK)
-               dma_sync_single_for_device(bp->sdev->dev, bp->tx_ring_dma,
+               dma_sync_single_for_device(bp->sdev->dma_dev, bp->tx_ring_dma,
                                          DMA_TABLE_BYTES,
                                          DMA_TO_DEVICE);
 
@@ -1144,24 +1144,24 @@ static void b44_free_consistent(struct b44 *bp)
        bp->tx_buffers = NULL;
        if (bp->rx_ring) {
                if (bp->flags & B44_FLAG_RX_RING_HACK) {
-                       dma_unmap_single(bp->sdev->dev, bp->rx_ring_dma,
+                       dma_unmap_single(bp->sdev->dma_dev, bp->rx_ring_dma,
                                        DMA_TABLE_BYTES,
                                        DMA_BIDIRECTIONAL);
                        kfree(bp->rx_ring);
                } else
-                       dma_free_coherent(bp->sdev->dev, DMA_TABLE_BYTES,
+                       dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
                                            bp->rx_ring, bp->rx_ring_dma);
                bp->rx_ring = NULL;
                bp->flags &= ~B44_FLAG_RX_RING_HACK;
        }
        if (bp->tx_ring) {
                if (bp->flags & B44_FLAG_TX_RING_HACK) {
-                       dma_unmap_single(bp->sdev->dev, bp->tx_ring_dma,
+                       dma_unmap_single(bp->sdev->dma_dev, bp->tx_ring_dma,
                                        DMA_TABLE_BYTES,
                                        DMA_TO_DEVICE);
                        kfree(bp->tx_ring);
                } else
-                       dma_free_coherent(bp->sdev->dev, DMA_TABLE_BYTES,
+                       dma_free_coherent(bp->sdev->dma_dev, DMA_TABLE_BYTES,
                                            bp->tx_ring, bp->tx_ring_dma);
                bp->tx_ring = NULL;
                bp->flags &= ~B44_FLAG_TX_RING_HACK;
@@ -1187,7 +1187,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
                goto out_err;
 
        size = DMA_TABLE_BYTES;
-       bp->rx_ring = dma_alloc_coherent(bp->sdev->dev, size, &bp->rx_ring_dma, gfp);
+       bp->rx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size, &bp->rx_ring_dma, gfp);
        if (!bp->rx_ring) {
                /* Allocation may have failed due to pci_alloc_consistent
                   insisting on use of GFP_DMA, which is more restrictive
@@ -1199,7 +1199,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
                if (!rx_ring)
                        goto out_err;
 
-               rx_ring_dma = dma_map_single(bp->sdev->dev, rx_ring,
+               rx_ring_dma = dma_map_single(bp->sdev->dma_dev, rx_ring,
                                            DMA_TABLE_BYTES,
                                            DMA_BIDIRECTIONAL);
 
@@ -1214,7 +1214,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
                bp->flags |= B44_FLAG_RX_RING_HACK;
        }
 
-       bp->tx_ring = dma_alloc_coherent(bp->sdev->dev, size, &bp->tx_ring_dma, gfp);
+       bp->tx_ring = dma_alloc_coherent(bp->sdev->dma_dev, size, &bp->tx_ring_dma, gfp);
        if (!bp->tx_ring) {
                /* Allocation may have failed due to dma_alloc_coherent
                   insisting on use of GFP_DMA, which is more restrictive
@@ -1226,7 +1226,7 @@ static int b44_alloc_consistent(struct b44 *bp, gfp_t gfp)
                if (!tx_ring)
                        goto out_err;
 
-               tx_ring_dma = dma_map_single(bp->sdev->dev, tx_ring,
+               tx_ring_dma = dma_map_single(bp->sdev->dma_dev, tx_ring,
                                            DMA_TABLE_BYTES,
                                            DMA_TO_DEVICE);
 
index de32b3f..7bdb5af 100644 (file)
@@ -63,8 +63,8 @@
 #include "bnx2x.h"
 #include "bnx2x_init.h"
 
-#define DRV_MODULE_VERSION      "1.42.3"
-#define DRV_MODULE_RELDATE      "2008/3/9"
+#define DRV_MODULE_VERSION      "1.42.4"
+#define DRV_MODULE_RELDATE      "2008/4/9"
 #define BNX2X_BC_VER           0x040200
 
 /* Time in jiffies before concluding the transmitter is hung. */
@@ -6153,7 +6153,7 @@ static int bnx2x_function_init(struct bnx2x *bp, int mode)
                   func, mode);
                REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
                       0xffffffff);
-               REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_1_SET,
+               REG_WR(bp, GRCBASE_MISC + MISC_REGISTERS_RESET_REG_2_SET,
                       0xfffc);
                bnx2x_init_block(bp, MISC_COMMON_START, MISC_COMMON_END);
 
index 93b7fb2..a8d3280 100644 (file)
@@ -40,7 +40,7 @@
 #include <asm/io.h>
 
 #define DRV_NAME       "ehea"
-#define DRV_VERSION    "EHEA_0089"
+#define DRV_VERSION    "EHEA_0090"
 
 /* eHEA capability flags */
 #define DLPAR_PORT_ADD_REM 1
@@ -371,6 +371,7 @@ struct ehea_port_res {
        struct ehea_q_skb_arr rq2_skba;
        struct ehea_q_skb_arr rq3_skba;
        struct ehea_q_skb_arr sq_skba;
+       int sq_skba_size;
        spinlock_t netif_queue;
        int queue_stopped;
        int swqe_refill_th;
index 07c742d..f460b62 100644 (file)
@@ -349,7 +349,8 @@ static void ehea_refill_rq1(struct ehea_port_res *pr, int index, int nr_of_wqes)
        pr->rq1_skba.os_skbs = 0;
 
        if (unlikely(test_bit(__EHEA_STOP_XFER, &ehea_driver_flags))) {
-               pr->rq1_skba.index = index;
+               if (nr_of_wqes > 0)
+                       pr->rq1_skba.index = index;
                pr->rq1_skba.os_skbs = fill_wqes;
                return;
        }
@@ -1464,7 +1465,9 @@ static int ehea_init_port_res(struct ehea_port *port, struct ehea_port_res *pr,
                          init_attr->act_nr_rwqes_rq2,
                          init_attr->act_nr_rwqes_rq3);
 
-       ret = ehea_init_q_skba(&pr->sq_skba, init_attr->act_nr_send_wqes + 1);
+       pr->sq_skba_size = init_attr->act_nr_send_wqes + 1;
+
+       ret = ehea_init_q_skba(&pr->sq_skba, pr->sq_skba_size);
        ret |= ehea_init_q_skba(&pr->rq1_skba, init_attr->act_nr_rwqes_rq1 + 1);
        ret |= ehea_init_q_skba(&pr->rq2_skba, init_attr->act_nr_rwqes_rq2 + 1);
        ret |= ehea_init_q_skba(&pr->rq3_skba, init_attr->act_nr_rwqes_rq3 + 1);
@@ -2621,6 +2624,22 @@ void ehea_purge_sq(struct ehea_qp *orig_qp)
        }
 }
 
+void ehea_flush_sq(struct ehea_port *port)
+{
+       int i;
+
+       for (i = 0; i < port->num_def_qps + port->num_add_tx_qps; i++) {
+               struct ehea_port_res *pr = &port->port_res[i];
+               int swqe_max = pr->sq_skba_size - 2 - pr->swqe_ll_count;
+               int k = 0;
+               while (atomic_read(&pr->swqe_avail) < swqe_max) {
+                       msleep(5);
+                       if (++k == 20)
+                               break;
+               }
+       }
+}
+
 int ehea_stop_qps(struct net_device *dev)
 {
        struct ehea_port *port = netdev_priv(dev);
@@ -2845,6 +2864,7 @@ static void ehea_rereg_mrs(struct work_struct *work)
                                        if (dev->flags & IFF_UP) {
                                                down(&port->port_lock);
                                                netif_stop_queue(dev);
+                                               ehea_flush_sq(port);
                                                ret = ehea_stop_qps(dev);
                                                if (ret) {
                                                        up(&port->port_lock);
index 419f533..9f088a4 100644 (file)
@@ -5316,8 +5316,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
 
        /* check the workaround bit for correct mac address order */
        txreg = readl(base + NvRegTransmitPoll);
-       if ((txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) ||
-           (id->driver_data & DEV_HAS_CORRECT_MACADDR)) {
+       if (id->driver_data & DEV_HAS_CORRECT_MACADDR) {
                /* mac address is already in correct order */
                dev->dev_addr[0] = (np->orig_mac[0] >>  0) & 0xff;
                dev->dev_addr[1] = (np->orig_mac[0] >>  8) & 0xff;
@@ -5325,6 +5324,22 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
                dev->dev_addr[3] = (np->orig_mac[0] >> 24) & 0xff;
                dev->dev_addr[4] = (np->orig_mac[1] >>  0) & 0xff;
                dev->dev_addr[5] = (np->orig_mac[1] >>  8) & 0xff;
+       } else if (txreg & NVREG_TRANSMITPOLL_MAC_ADDR_REV) {
+               /* mac address is already in correct order */
+               dev->dev_addr[0] = (np->orig_mac[0] >>  0) & 0xff;
+               dev->dev_addr[1] = (np->orig_mac[0] >>  8) & 0xff;
+               dev->dev_addr[2] = (np->orig_mac[0] >> 16) & 0xff;
+               dev->dev_addr[3] = (np->orig_mac[0] >> 24) & 0xff;
+               dev->dev_addr[4] = (np->orig_mac[1] >>  0) & 0xff;
+               dev->dev_addr[5] = (np->orig_mac[1] >>  8) & 0xff;
+               /*
+                * Set orig mac address back to the reversed version.
+                * This flag will be cleared during low power transition.
+                * Therefore, we should always put back the reversed address.
+                */
+               np->orig_mac[0] = (dev->dev_addr[5] << 0) + (dev->dev_addr[4] << 8) +
+                       (dev->dev_addr[3] << 16) + (dev->dev_addr[2] << 24);
+               np->orig_mac[1] = (dev->dev_addr[1] << 0) + (dev->dev_addr[0] << 8);
        } else {
                /* need to reverse mac address to correct order */
                dev->dev_addr[0] = (np->orig_mac[1] >>  8) & 0xff;
@@ -5595,7 +5610,9 @@ out:
 static int nv_resume(struct pci_dev *pdev)
 {
        struct net_device *dev = pci_get_drvdata(pdev);
+       u8 __iomem *base = get_hwbase(dev);
        int rc = 0;
+       u32 txreg;
 
        if (!netif_running(dev))
                goto out;
@@ -5606,6 +5623,11 @@ static int nv_resume(struct pci_dev *pdev)
        pci_restore_state(pdev);
        pci_enable_wake(pdev, PCI_D0, 0);
 
+       /* restore mac address reverse flag */
+       txreg = readl(base + NvRegTransmitPoll);
+       txreg |= NVREG_TRANSMITPOLL_MAC_ADDR_REV;
+       writel(txreg, base + NvRegTransmitPoll);
+
        rc = nv_open(dev);
 out:
        return rc;
index af869cf..940e204 100644 (file)
@@ -835,7 +835,8 @@ static int fs_enet_close(struct net_device *dev)
 
        netif_stop_queue(dev);
        netif_carrier_off(dev);
-       napi_disable(&fep->napi);
+       if (fep->fpi->use_napi)
+               napi_disable(&fep->napi);
        phy_stop(fep->phydev);
 
        spin_lock_irqsave(&fep->lock, flags);
index 1d210ed..489c7c3 100644 (file)
@@ -242,12 +242,12 @@ static int macb_mii_init(struct macb *bp)
        /* Enable managment port */
        macb_writel(bp, NCR, MACB_BIT(MPE));
 
-       bp->mii_bus.name = "MACB_mii_bus",
-       bp->mii_bus.read = &macb_mdio_read,
-       bp->mii_bus.write = &macb_mdio_write,
-       bp->mii_bus.reset = &macb_mdio_reset,
-       bp->mii_bus.id = bp->pdev->id,
-       bp->mii_bus.priv = bp,
+       bp->mii_bus.name = "MACB_mii_bus";
+       bp->mii_bus.read = &macb_mdio_read;
+       bp->mii_bus.write = &macb_mdio_write;
+       bp->mii_bus.reset = &macb_mdio_reset;
+       bp->mii_bus.id = bp->pdev->id;
+       bp->mii_bus.priv = bp;
        bp->mii_bus.dev = &bp->dev->dev;
        pdata = bp->pdev->dev.platform_data;
 
@@ -1257,6 +1257,8 @@ static int __exit macb_remove(struct platform_device *pdev)
 
        if (dev) {
                bp = netdev_priv(dev);
+               if (bp->phy_dev)
+                       phy_disconnect(bp->phy_dev);
                mdiobus_unregister(&bp->mii_bus);
                kfree(bp->mii_bus.irq);
                unregister_netdev(dev);
index 501e451..665341e 100644 (file)
@@ -730,7 +730,7 @@ static void write_msg(struct console *con, const char *msg, unsigned int len)
 
 static struct console netconsole = {
        .name   = "netcon",
-       .flags  = CON_ENABLED | CON_PRINTBUFFER,
+       .flags  = CON_ENABLED,
        .write  = write_msg,
 };
 
@@ -749,6 +749,9 @@ static int __init init_netconsole(void)
                                err = PTR_ERR(nt);
                                goto fail;
                        }
+                       /* Dump existing printks when we register */
+                       netconsole.flags |= CON_PRINTBUFFER;
+
                        spin_lock_irqsave(&target_list_lock, flags);
                        list_add(&nt->list, &target_list);
                        spin_unlock_irqrestore(&target_list_lock, flags);
index ddbc6e4..c16de51 100644 (file)
@@ -512,13 +512,18 @@ static void gelic_wl_parse_ie(u8 *data, size_t len,
                 data, len);
        memset(ie_info, 0, sizeof(struct ie_info));
 
-       while (0 < data_left) {
+       while (2 <= data_left) {
                item_id = *pos++;
                item_len = *pos++;
+               data_left -= 2;
+
+               if (data_left < item_len)
+                       break;
 
                switch (item_id) {
                case MFIE_TYPE_GENERIC:
-                       if (!memcmp(pos, wpa_oui, OUI_LEN) &&
+                       if ((OUI_LEN + 1 <= item_len) &&
+                           !memcmp(pos, wpa_oui, OUI_LEN) &&
                            pos[OUI_LEN] == 0x01) {
                                ie_info->wpa.data = pos - 2;
                                ie_info->wpa.len = item_len + 2;
@@ -535,7 +540,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len,
                        break;
                }
                pos += item_len;
-               data_left -= item_len + 2;
+               data_left -= item_len;
        }
        pr_debug("%s: wpa=%p,%d wpa2=%p,%d\n", __func__,
                 ie_info->wpa.data, ie_info->wpa.len,
index 37b4239..15fcee5 100644 (file)
@@ -1446,6 +1446,7 @@ static int __devinit sc92031_probe(struct pci_dev *pdev,
        }
 
        pci_set_drvdata(pdev, dev);
+       SET_NETDEV_DEV(dev, &pdev->dev);
 
 #if SC92031_USE_BAR == 0
        dev->mem_start = pci_resource_start(pdev, SC92031_USE_BAR);
index 853bce0..f226bca 100644 (file)
@@ -154,6 +154,7 @@ static const char *yukon2_name[] = {
        "EC",           /* 0xb6 */
        "FE",           /* 0xb7 */
        "FE+",          /* 0xb8 */
+       "Supreme",      /* 0xb9 */
 };
 
 static void sky2_set_multicast(struct net_device *dev);
index 4020e9e..63a54e2 100644 (file)
@@ -1326,9 +1326,11 @@ static irqreturn_t smc_interrupt(int irq, void *dev_id)
        SMC_SET_INT_MASK(mask);
        spin_unlock(&lp->lock);
 
+#ifndef CONFIG_NET_POLL_CONTROLLER
        if (timeout == MAX_IRQ_LOOPS)
                PRINTK("%s: spurious interrupt (mask = 0x%02x)\n",
                       dev->name, mask);
+#endif
        DBG(3, "%s: Interrupt done (%d loops)\n",
               dev->name, MAX_IRQ_LOOPS - timeout);
 
index c49214f..7b7b171 100644 (file)
@@ -1472,13 +1472,12 @@ static int __netdev_rx(struct net_device *dev, int *quota)
 #ifndef final_version                  /* Remove after testing. */
                /* You will want this info for the initial debug. */
                if (debug > 5) {
-                       DECLARE_MAC_BUF(mac);
-                       DECLARE_MAC_BUF(mac2);
-
-                       printk(KERN_DEBUG "  Rx data %s %s"
+                       printk(KERN_DEBUG "  Rx data " MAC_FMT " " MAC_FMT
                               " %2.2x%2.2x.\n",
-                              print_mac(mac, &skb->data[0]),
-                              print_mac(mac2, &skb->data[6]),
+                              skb->data[0], skb->data[1], skb->data[2],
+                              skb->data[3], skb->data[4], skb->data[5],
+                              skb->data[6], skb->data[7], skb->data[8],
+                              skb->data[9], skb->data[10], skb->data[11],
                               skb->data[12], skb->data[13]);
                }
 #endif
index d4655b2..96043c5 100644 (file)
@@ -64,8 +64,8 @@
 
 #define DRV_MODULE_NAME                "tg3"
 #define PFX DRV_MODULE_NAME    ": "
-#define DRV_MODULE_VERSION     "3.89"
-#define DRV_MODULE_RELDATE     "April 03, 2008"
+#define DRV_MODULE_VERSION     "3.90"
+#define DRV_MODULE_RELDATE     "April 12, 2008"
 
 #define TG3_DEF_MAC_MODE       0
 #define TG3_DEF_RX_MODE                0
@@ -12578,7 +12578,8 @@ static int __devinit tg3_init_one(struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
        static int tg3_version_printed = 0;
-       unsigned long tg3reg_base, tg3reg_len;
+       resource_size_t tg3reg_base;
+       unsigned long tg3reg_len;
        struct net_device *dev;
        struct tg3 *tp;
        int err, pm_cap;
index db4ca4f..0ab51a0 100644 (file)
@@ -1438,13 +1438,18 @@ static void olympic_arb_cmd(struct net_device *dev)
 
                if (olympic_priv->olympic_network_monitor) { 
                        struct trh_hdr *mac_hdr;
-                       DECLARE_MAC_BUF(mac);
                        printk(KERN_WARNING "%s: Received MAC Frame, details: \n",dev->name);
                        mac_hdr = tr_hdr(mac_frame);
-                       printk(KERN_WARNING "%s: MAC Frame Dest. Addr: %s\n",
-                              dev->name, print_mac(mac, mac_hdr->daddr));
-                       printk(KERN_WARNING "%s: MAC Frame Srce. Addr: %s\n",
-                              dev->name, print_mac(mac, mac_hdr->saddr));
+                       printk(KERN_WARNING "%s: MAC Frame Dest. Addr: "
+                              MAC_FMT " \n", dev->name,
+                              mac_hdr->daddr[0], mac_hdr->daddr[1],
+                              mac_hdr->daddr[2], mac_hdr->daddr[3],
+                              mac_hdr->daddr[4], mac_hdr->daddr[5]);
+                       printk(KERN_WARNING "%s: MAC Frame Srce. Addr: "
+                              MAC_FMT " \n", dev->name,
+                              mac_hdr->saddr[0], mac_hdr->saddr[1],
+                              mac_hdr->saddr[2], mac_hdr->saddr[3],
+                              mac_hdr->saddr[4], mac_hdr->saddr[5]);
                }
                netif_rx(mac_frame);
                dev->last_rx = jiffies;
index 7b816a0..5b5d875 100644 (file)
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
+/* Uncomment to enable debugging */
+/* #define TUN_DEBUG 1 */
+
 #ifdef TUN_DEBUG
 static int debug;
+
+#define DBG  if(tun->debug)printk
+#define DBG1 if(debug==2)printk
+#else
+#define DBG( a... )
+#define DBG1( a... )
+#endif
+
+struct tun_struct {
+       struct list_head        list;
+       unsigned long           flags;
+       int                     attached;
+       uid_t                   owner;
+       gid_t                   group;
+
+       wait_queue_head_t       read_wait;
+       struct sk_buff_head     readq;
+
+       struct net_device       *dev;
+
+       struct fasync_struct    *fasync;
+
+       unsigned long if_flags;
+       u8 dev_addr[ETH_ALEN];
+       u32 chr_filter[2];
+       u32 net_filter[2];
+
+#ifdef TUN_DEBUG
+       int debug;
 #endif
+};
 
 /* Network device part of the driver */
 
@@ -253,8 +286,11 @@ static __inline__ ssize_t tun_get_user(struct tun_struct *tun, struct iovec *iv,
                        return -EFAULT;
        }
 
-       if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV)
+       if ((tun->flags & TUN_TYPE_MASK) == TUN_TAP_DEV) {
                align = NET_IP_ALIGN;
+               if (unlikely(len < ETH_HLEN))
+                       return -EINVAL;
+       }
 
        if (!(skb = alloc_skb(len + align, GFP_KERNEL))) {
                tun->dev->stats.rx_dropped++;
index 8cc3166..0ee4c16 100644 (file)
@@ -3833,6 +3833,7 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
        struct device_node *phy;
        int err, ucc_num, max_speed = 0;
        const phandle *ph;
+       const u32 *fixed_link;
        const unsigned int *prop;
        const char *sprop;
        const void *mac_addr;
@@ -3923,18 +3924,38 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
 
        ug_info->uf_info.regs = res.start;
        ug_info->uf_info.irq = irq_of_parse_and_map(np, 0);
+       fixed_link = of_get_property(np, "fixed-link", NULL);
+       if (fixed_link) {
+               ug_info->mdio_bus = 0;
+               ug_info->phy_address = fixed_link[0];
+               phy = NULL;
+       } else {
+               ph = of_get_property(np, "phy-handle", NULL);
+               phy = of_find_node_by_phandle(*ph);
 
-       ph = of_get_property(np, "phy-handle", NULL);
-       phy = of_find_node_by_phandle(*ph);
+               if (phy == NULL)
+                       return -ENODEV;
 
-       if (phy == NULL)
-               return -ENODEV;
+               /* set the PHY address */
+               prop = of_get_property(phy, "reg", NULL);
+               if (prop == NULL)
+                       return -1;
+               ug_info->phy_address = *prop;
+
+               /* Set the bus id */
+               mdio = of_get_parent(phy);
+
+               if (mdio == NULL)
+                       return -1;
 
-       /* set the PHY address */
-       prop = of_get_property(phy, "reg", NULL);
-       if (prop == NULL)
-               return -1;
-       ug_info->phy_address = *prop;
+               err = of_address_to_resource(mdio, 0, &res);
+               of_node_put(mdio);
+
+               if (err)
+                       return -1;
+
+               ug_info->mdio_bus = res.start;
+       }
 
        /* get the phy interface type, or default to MII */
        prop = of_get_property(np, "phy-connection-type", NULL);
@@ -3979,20 +4000,6 @@ static int ucc_geth_probe(struct of_device* ofdev, const struct of_device_id *ma
                ug_info->numThreadsRx = UCC_GETH_NUM_OF_THREADS_4;
        }
 
-       /* Set the bus id */
-       mdio = of_get_parent(phy);
-
-       if (mdio == NULL)
-               return -1;
-
-       err = of_address_to_resource(mdio, 0, &res);
-       of_node_put(mdio);
-
-       if (err)
-               return -1;
-
-       ug_info->mdio_bus = res.start;
-
        if (netif_msg_probe(&debug))
                printk(KERN_INFO "ucc_geth: UCC%1d at 0x%8x (irq = %d) \n",
                        ug_info->uf_info.ucc_num + 1, ug_info->uf_info.regs,
index d1a200f..555b70c 100644 (file)
@@ -234,11 +234,12 @@ static int start_xmit(struct sk_buff *skb, struct net_device *dev)
        struct scatterlist sg[1+MAX_SKB_FRAGS];
        struct virtio_net_hdr *hdr;
        const unsigned char *dest = ((struct ethhdr *)skb->data)->h_dest;
-       DECLARE_MAC_BUF(mac);
 
        sg_init_table(sg, 1+MAX_SKB_FRAGS);
 
-       pr_debug("%s: xmit %p %s\n", dev->name, skb, print_mac(mac, dest));
+       pr_debug("%s: xmit %p " MAC_FMT "\n", dev->name, skb,
+                dest[0], dest[1], dest[2],
+                dest[3], dest[4], dest[5]);
 
        /* Encode metadata header at front. */
        hdr = skb_vnet_hdr(skb);
index a3df09e..8005dd1 100644 (file)
@@ -150,9 +150,13 @@ config HDLC_FR
 
 config HDLC_PPP
        tristate "Synchronous Point-to-Point Protocol (PPP) support"
-       depends on HDLC
+       depends on HDLC && BROKEN
        help
          Generic HDLC driver supporting PPP over WAN connections.
+         This module is currently broken and will cause a kernel panic
+         when a device configured in PPP mode is activated.
+
+         It will be replaced by new PPP implementation in Linux 2.6.26.
 
          If unsure, say N.
 
index 948eb1f..48e9124 100644 (file)
@@ -373,10 +373,10 @@ static inline
        dma_addr_t dmaaddr;
 
        if (tx) {
-               dmaaddr = dma_map_single(ring->dev->dev->dev,
+               dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
                                         buf, len, DMA_TO_DEVICE);
        } else {
-               dmaaddr = dma_map_single(ring->dev->dev->dev,
+               dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
                                         buf, len, DMA_FROM_DEVICE);
        }
 
@@ -388,9 +388,10 @@ static inline
                          dma_addr_t addr, size_t len, int tx)
 {
        if (tx) {
-               dma_unmap_single(ring->dev->dev->dev, addr, len, DMA_TO_DEVICE);
+               dma_unmap_single(ring->dev->dev->dma_dev,
+                                addr, len, DMA_TO_DEVICE);
        } else {
-               dma_unmap_single(ring->dev->dev->dev,
+               dma_unmap_single(ring->dev->dev->dma_dev,
                                 addr, len, DMA_FROM_DEVICE);
        }
 }
@@ -400,7 +401,7 @@ static inline
                                 dma_addr_t addr, size_t len)
 {
        B43_WARN_ON(ring->tx);
-       dma_sync_single_for_cpu(ring->dev->dev->dev,
+       dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
                                addr, len, DMA_FROM_DEVICE);
 }
 
@@ -409,7 +410,7 @@ static inline
                                    dma_addr_t addr, size_t len)
 {
        B43_WARN_ON(ring->tx);
-       dma_sync_single_for_device(ring->dev->dev->dev,
+       dma_sync_single_for_device(ring->dev->dev->dma_dev,
                                   addr, len, DMA_FROM_DEVICE);
 }
 
@@ -425,7 +426,7 @@ static inline
 
 static int alloc_ringmemory(struct b43_dmaring *ring)
 {
-       struct device *dev = ring->dev->dev->dev;
+       struct device *dma_dev = ring->dev->dev->dma_dev;
        gfp_t flags = GFP_KERNEL;
 
        /* The specs call for 4K buffers for 30- and 32-bit DMA with 4K
@@ -439,7 +440,7 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
         */
        if (ring->type == B43_DMA_64BIT)
                flags |= GFP_DMA;
-       ring->descbase = dma_alloc_coherent(dev, B43_DMA_RINGMEMSIZE,
+       ring->descbase = dma_alloc_coherent(dma_dev, B43_DMA_RINGMEMSIZE,
                                            &(ring->dmabase), flags);
        if (!ring->descbase) {
                b43err(ring->dev->wl, "DMA ringmemory allocation failed\n");
@@ -452,9 +453,9 @@ static int alloc_ringmemory(struct b43_dmaring *ring)
 
 static void free_ringmemory(struct b43_dmaring *ring)
 {
-       struct device *dev = ring->dev->dev->dev;
+       struct device *dma_dev = ring->dev->dev->dma_dev;
 
-       dma_free_coherent(dev, B43_DMA_RINGMEMSIZE,
+       dma_free_coherent(dma_dev, B43_DMA_RINGMEMSIZE,
                          ring->descbase, ring->dmabase);
 }
 
@@ -854,7 +855,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                        goto err_kfree_meta;
 
                /* test for ability to dma to txhdr_cache */
-               dma_test = dma_map_single(dev->dev->dev,
+               dma_test = dma_map_single(dev->dev->dma_dev,
                                          ring->txhdr_cache,
                                          b43_txhdr_size(dev),
                                          DMA_TO_DEVICE);
@@ -869,7 +870,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                        if (!ring->txhdr_cache)
                                goto err_kfree_meta;
 
-                       dma_test = dma_map_single(dev->dev->dev,
+                       dma_test = dma_map_single(dev->dev->dma_dev,
                                                  ring->txhdr_cache,
                                                  b43_txhdr_size(dev),
                                                  DMA_TO_DEVICE);
@@ -883,7 +884,7 @@ struct b43_dmaring *b43_setup_dmaring(struct b43_wldev *dev,
                        }
                }
 
-               dma_unmap_single(dev->dev->dev,
+               dma_unmap_single(dev->dev->dma_dev,
                                 dma_test, b43_txhdr_size(dev),
                                 DMA_TO_DEVICE);
        }
index e87b427..c990f87 100644 (file)
@@ -393,11 +393,11 @@ dma_addr_t map_descbuffer(struct b43legacy_dmaring *ring,
        dma_addr_t dmaaddr;
 
        if (tx)
-               dmaaddr = dma_map_single(ring->dev->dev->dev,
+               dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
                                         buf, len,
                                         DMA_TO_DEVICE);
        else
-               dmaaddr = dma_map_single(ring->dev->dev->dev,
+               dmaaddr = dma_map_single(ring->dev->dev->dma_dev,
                                         buf, len,
                                         DMA_FROM_DEVICE);
 
@@ -411,11 +411,11 @@ void unmap_descbuffer(struct b43legacy_dmaring *ring,
                      int tx)
 {
        if (tx)
-               dma_unmap_single(ring->dev->dev->dev,
+               dma_unmap_single(ring->dev->dev->dma_dev,
                                 addr, len,
                                 DMA_TO_DEVICE);
        else
-               dma_unmap_single(ring->dev->dev->dev,
+               dma_unmap_single(ring->dev->dev->dma_dev,
                                 addr, len,
                                 DMA_FROM_DEVICE);
 }
@@ -427,7 +427,7 @@ void sync_descbuffer_for_cpu(struct b43legacy_dmaring *ring,
 {
        B43legacy_WARN_ON(ring->tx);
 
-       dma_sync_single_for_cpu(ring->dev->dev->dev,
+       dma_sync_single_for_cpu(ring->dev->dev->dma_dev,
                                addr, len, DMA_FROM_DEVICE);
 }
 
@@ -438,7 +438,7 @@ void sync_descbuffer_for_device(struct b43legacy_dmaring *ring,
 {
        B43legacy_WARN_ON(ring->tx);
 
-       dma_sync_single_for_device(ring->dev->dev->dev,
+       dma_sync_single_for_device(ring->dev->dev->dma_dev,
                                   addr, len, DMA_FROM_DEVICE);
 }
 
@@ -458,9 +458,9 @@ void free_descriptor_buffer(struct b43legacy_dmaring *ring,
 
 static int alloc_ringmemory(struct b43legacy_dmaring *ring)
 {
-       struct device *dev = ring->dev->dev->dev;
+       struct device *dma_dev = ring->dev->dev->dma_dev;
 
-       ring->descbase = dma_alloc_coherent(dev, B43legacy_DMA_RINGMEMSIZE,
+       ring->descbase = dma_alloc_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE,
                                            &(ring->dmabase), GFP_KERNEL);
        if (!ring->descbase) {
                b43legacyerr(ring->dev->wl, "DMA ringmemory allocation"
@@ -474,9 +474,9 @@ static int alloc_ringmemory(struct b43legacy_dmaring *ring)
 
 static void free_ringmemory(struct b43legacy_dmaring *ring)
 {
-       struct device *dev = ring->dev->dev->dev;
+       struct device *dma_dev = ring->dev->dev->dma_dev;
 
-       dma_free_coherent(dev, B43legacy_DMA_RINGMEMSIZE,
+       dma_free_coherent(dma_dev, B43legacy_DMA_RINGMEMSIZE,
                          ring->descbase, ring->dmabase);
 }
 
@@ -585,8 +585,9 @@ static int b43legacy_dmacontroller_tx_reset(struct b43legacy_wldev *dev,
 
 /* Check if a DMA mapping address is invalid. */
 static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
-                                       dma_addr_t addr,
-                                       size_t buffersize)
+                                        dma_addr_t addr,
+                                        size_t buffersize,
+                                        bool dma_to_device)
 {
        if (unlikely(dma_mapping_error(addr)))
                return 1;
@@ -594,11 +595,11 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
        switch (ring->type) {
        case B43legacy_DMA_30BIT:
                if ((u64)addr + buffersize > (1ULL << 30))
-                       return 1;
+                       goto address_error;
                break;
        case B43legacy_DMA_32BIT:
                if ((u64)addr + buffersize > (1ULL << 32))
-                       return 1;
+                       goto address_error;
                break;
        case B43legacy_DMA_64BIT:
                /* Currently we can't have addresses beyond 64 bits in the kernel. */
@@ -607,6 +608,12 @@ static bool b43legacy_dma_mapping_error(struct b43legacy_dmaring *ring,
 
        /* The address is OK. */
        return 0;
+
+address_error:
+       /* We can't support this address. Unmap it again. */
+       unmap_descbuffer(ring, addr, buffersize, dma_to_device);
+
+       return 1;
 }
 
 static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
@@ -626,7 +633,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
                return -ENOMEM;
        dmaaddr = map_descbuffer(ring, skb->data,
                                 ring->rx_buffersize, 0);
-       if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) {
+       if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
                /* ugh. try to realloc in zone_dma */
                gfp_flags |= GFP_DMA;
 
@@ -639,7 +646,7 @@ static int setup_rx_descbuffer(struct b43legacy_dmaring *ring,
                                         ring->rx_buffersize, 0);
        }
 
-       if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize)) {
+       if (b43legacy_dma_mapping_error(ring, dmaaddr, ring->rx_buffersize, 0)) {
                dev_kfree_skb_any(skb);
                return -EIO;
        }
@@ -886,12 +893,12 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
                        goto err_kfree_meta;
 
                /* test for ability to dma to txhdr_cache */
-               dma_test = dma_map_single(dev->dev->dev, ring->txhdr_cache,
+               dma_test = dma_map_single(dev->dev->dma_dev, ring->txhdr_cache,
                                          sizeof(struct b43legacy_txhdr_fw3),
                                          DMA_TO_DEVICE);
 
                if (b43legacy_dma_mapping_error(ring, dma_test,
-                                       sizeof(struct b43legacy_txhdr_fw3))) {
+                                       sizeof(struct b43legacy_txhdr_fw3), 1)) {
                        /* ugh realloc */
                        kfree(ring->txhdr_cache);
                        ring->txhdr_cache = kcalloc(nr_slots,
@@ -900,17 +907,17 @@ struct b43legacy_dmaring *b43legacy_setup_dmaring(struct b43legacy_wldev *dev,
                        if (!ring->txhdr_cache)
                                goto err_kfree_meta;
 
-                       dma_test = dma_map_single(dev->dev->dev,
+                       dma_test = dma_map_single(dev->dev->dma_dev,
                                        ring->txhdr_cache,
                                        sizeof(struct b43legacy_txhdr_fw3),
                                        DMA_TO_DEVICE);
 
                        if (b43legacy_dma_mapping_error(ring, dma_test,
-                                       sizeof(struct b43legacy_txhdr_fw3)))
+                                       sizeof(struct b43legacy_txhdr_fw3), 1))
                                goto err_kfree_txhdr_cache;
                }
 
-               dma_unmap_single(dev->dev->dev,
+               dma_unmap_single(dev->dev->dma_dev,
                                 dma_test, sizeof(struct b43legacy_txhdr_fw3),
                                 DMA_TO_DEVICE);
        }
@@ -1235,7 +1242,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
        meta_hdr->dmaaddr = map_descbuffer(ring, (unsigned char *)header,
                                           sizeof(struct b43legacy_txhdr_fw3), 1);
        if (b43legacy_dma_mapping_error(ring, meta_hdr->dmaaddr,
-                                       sizeof(struct b43legacy_txhdr_fw3))) {
+                                       sizeof(struct b43legacy_txhdr_fw3), 1)) {
                ring->current_slot = old_top_slot;
                ring->used_slots = old_used_slots;
                return -EIO;
@@ -1254,7 +1261,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
 
        meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
        /* create a bounce buffer in zone_dma on mapping failure. */
-       if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) {
+       if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
                bounce_skb = __dev_alloc_skb(skb->len, GFP_ATOMIC | GFP_DMA);
                if (!bounce_skb) {
                        ring->current_slot = old_top_slot;
@@ -1268,7 +1275,7 @@ static int dma_tx_fragment(struct b43legacy_dmaring *ring,
                skb = bounce_skb;
                meta->skb = skb;
                meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
-               if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len)) {
+               if (b43legacy_dma_mapping_error(ring, meta->dmaaddr, skb->len, 1)) {
                        ring->current_slot = old_top_slot;
                        ring->used_slots = old_used_slots;
                        err = -EIO;
index 5f3f34e..0f7a6e7 100644 (file)
@@ -1488,6 +1488,7 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
        }
        if (!fw->initvals) {
                switch (dev->phy.type) {
+               case B43legacy_PHYTYPE_B:
                case B43legacy_PHYTYPE_G:
                        if ((rev >= 5) && (rev <= 10))
                                filename = "b0g0initvals5";
@@ -1505,6 +1506,7 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
        }
        if (!fw->initvals_band) {
                switch (dev->phy.type) {
+               case B43legacy_PHYTYPE_B:
                case B43legacy_PHYTYPE_G:
                        if ((rev >= 5) && (rev <= 10))
                                filename = "b0g0bsinitvals5";
index 49978bd..4fd7380 100644 (file)
@@ -635,7 +635,6 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
 {
        struct ieee80211_hdr_4addr *hdr;
        int res, hdrlen;
-       DECLARE_MAC_BUF(mac);
 
        if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
                return 0;
@@ -647,8 +646,10 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
            strcmp(crypt->ops->name, "TKIP") == 0) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-                              "received packet from %s\n",
-                              local->dev->name, print_mac(mac, hdr->addr2));
+                              "received packet from " MAC_FMT "\n",
+                              local->dev->name,
+                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
                }
                return -1;
        }
@@ -657,9 +658,12 @@ hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
        res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
-               printk(KERN_DEBUG "%s: decryption failed (SA=%s"
+               printk(KERN_DEBUG "%s: decryption failed (SA=" MAC_FMT
                       ") res=%d\n",
-                      local->dev->name, print_mac(mac, hdr->addr2), res);
+                      local->dev->name,
+                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+                      res);
                local->comm_tallies.rx_discards_wep_undecryptable++;
                return -1;
        }
@@ -721,7 +725,6 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
        struct ieee80211_crypt_data *crypt = NULL;
        void *sta = NULL;
        int keyidx = 0;
-       DECLARE_MAC_BUF(mac);
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -798,8 +801,10 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                         * frames silently instead of filling system log with
                         * these reports. */
                        printk(KERN_DEBUG "%s: WEP decryption failed (not set)"
-                              " (SA=%s)\n",
-                              local->dev->name, print_mac(mac, hdr->addr2));
+                              " (SA=" MAC_FMT ")\n",
+                              local->dev->name,
+                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
 #endif
                        local->comm_tallies.rx_discards_wep_undecryptable++;
                        goto rx_dropped;
@@ -813,8 +818,9 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                    (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
                {
                        printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
-                              "from %s\n", dev->name,
-                              print_mac(mac, hdr->addr2));
+                              "from " MAC_FMT "\n", dev->name,
+                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
                        /* TODO: could inform hostapd about this so that it
                         * could send auth failure report */
                        goto rx_dropped;
@@ -982,8 +988,10 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
                               "unencrypted EAPOL frame\n", local->dev->name);
                } else {
                        printk(KERN_DEBUG "%s: encryption configured, but RX "
-                              "frame not encrypted (SA=%s)\n",
-                              local->dev->name, print_mac(mac, hdr->addr2));
+                              "frame not encrypted (SA=" MAC_FMT ")\n",
+                              local->dev->name,
+                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
                        goto rx_dropped;
                }
        }
@@ -992,9 +1000,10 @@ void hostap_80211_rx(struct net_device *dev, struct sk_buff *skb,
            !hostap_is_eapol_frame(local, skb)) {
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: dropped unencrypted RX data "
-                              "frame from %s"
-                              " (drop_unencrypted=1)\n",
-                              dev->name, print_mac(mac, hdr->addr2));
+                              "frame from " MAC_FMT " (drop_unencrypted=1)\n",
+                              dev->name,
+                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
                }
                goto rx_dropped;
        }
index e7afc3e..921c984 100644 (file)
@@ -314,7 +314,6 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
        struct ieee80211_hdr_4addr *hdr;
        u16 fc;
        int prefix_len, postfix_len, hdr_len, res;
-       DECLARE_MAC_BUF(mac);
 
        iface = netdev_priv(skb->dev);
        local = iface->local;
@@ -329,8 +328,10 @@ static struct sk_buff * hostap_tx_encrypt(struct sk_buff *skb,
                hdr = (struct ieee80211_hdr_4addr *) skb->data;
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
-                              "TX packet to %s\n",
-                              local->dev->name, print_mac(mac, hdr->addr1));
+                              "TX packet to " MAC_FMT "\n",
+                              local->dev->name,
+                              hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+                              hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
                }
                kfree_skb(skb);
                return NULL;
index ad040a3..0acd958 100644 (file)
@@ -632,7 +632,6 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
        __le16 *pos;
        struct sta_info *sta = NULL;
        char *txt = NULL;
-       DECLARE_MAC_BUF(mac);
 
        if (ap->local->hostapd) {
                dev_kfree_skb(skb);
@@ -684,10 +683,12 @@ static void hostap_ap_tx_cb_auth(struct sk_buff *skb, int ok, void *data)
        if (sta)
                atomic_dec(&sta->users);
        if (txt) {
-               PDEBUG(DEBUG_AP, "%s: %s auth_cb - alg=%d "
+               PDEBUG(DEBUG_AP, "%s: " MAC_FMT " auth_cb - alg=%d "
                       "trans#=%d status=%d - %s\n",
-                      dev->name, print_mac(mac, hdr->addr1), auth_alg,
-                      auth_transaction, status, txt);
+                      dev->name,
+                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
+                      auth_alg, auth_transaction, status, txt);
        }
        dev_kfree_skb(skb);
 }
@@ -703,7 +704,6 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
        __le16 *pos;
        struct sta_info *sta = NULL;
        char *txt = NULL;
-       DECLARE_MAC_BUF(mac);
 
        if (ap->local->hostapd) {
                dev_kfree_skb(skb);
@@ -754,8 +754,11 @@ static void hostap_ap_tx_cb_assoc(struct sk_buff *skb, int ok, void *data)
        if (sta)
                atomic_dec(&sta->users);
        if (txt) {
-               PDEBUG(DEBUG_AP, "%s: %s assoc_cb - %s\n",
-                      dev->name, print_mac(mac, hdr->addr1), txt);
+               PDEBUG(DEBUG_AP, "%s: " MAC_FMT " assoc_cb - %s\n",
+                      dev->name,
+                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
+                      txt);
        }
        dev_kfree_skb(skb);
 }
@@ -767,7 +770,6 @@ static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
        struct ap_data *ap = data;
        struct ieee80211_hdr_4addr *hdr;
        struct sta_info *sta;
-       DECLARE_MAC_BUF(mac);
 
        if (skb->len < 24)
                goto fail;
@@ -779,9 +781,11 @@ static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
                        sta->flags &= ~WLAN_STA_PENDING_POLL;
                spin_unlock(&ap->sta_table_lock);
        } else {
-               PDEBUG(DEBUG_AP, "%s: STA %s"
+               PDEBUG(DEBUG_AP, "%s: STA " MAC_FMT
                       " did not ACK activity poll frame\n",
-                      ap->local->dev->name, print_mac(mac, hdr->addr1));
+                      ap->local->dev->name,
+                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
        }
 
  fail:
@@ -1306,7 +1310,6 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
        struct sta_info *sta = NULL;
        struct ieee80211_crypt_data *crypt;
        char *txt = "";
-       DECLARE_MAC_BUF(mac);
 
        len = skb->len - IEEE80211_MGMT_HDR_LEN;
 
@@ -1315,8 +1318,9 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
 
        if (len < 6) {
                PDEBUG(DEBUG_AP, "%s: handle_authen - too short payload "
-                      "(len=%d) from %s\n", dev->name, len,
-                      print_mac(mac, hdr->addr2));
+                      "(len=%d) from " MAC_FMT "\n", dev->name, len,
+                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
                return;
        }
 
@@ -1381,8 +1385,10 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
                if (time_after(jiffies, sta->u.ap.last_beacon +
                               (10 * sta->listen_interval * HZ) / 1024)) {
                        PDEBUG(DEBUG_AP, "%s: no beacons received for a while,"
-                              " assuming AP %s is now STA\n",
-                              dev->name, print_mac(mac, sta->addr));
+                              " assuming AP " MAC_FMT " is now STA\n",
+                              dev->name,
+                              sta->addr[0], sta->addr[1], sta->addr[2],
+                              sta->addr[3], sta->addr[4], sta->addr[5]);
                        sta->ap = 0;
                        sta->flags = 0;
                        sta->u.sta.challenge = NULL;
@@ -1497,10 +1503,13 @@ static void handle_authen(local_info_t *local, struct sk_buff *skb,
        }
 
        if (resp) {
-               PDEBUG(DEBUG_AP, "%s: %s auth (alg=%d "
+               PDEBUG(DEBUG_AP, "%s: " MAC_FMT " auth (alg=%d "
                       "trans#=%d stat=%d len=%d fc=%04x) ==> %d (%s)\n",
-                      dev->name, print_mac(mac, hdr->addr2), auth_alg,
-                      auth_transaction, status_code, len, fc, resp, txt);
+                      dev->name,
+                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+                      auth_alg, auth_transaction, status_code, len,
+                      fc, resp, txt);
        }
 }
 
@@ -1519,14 +1528,15 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
        int send_deauth = 0;
        char *txt = "";
        u8 prev_ap[ETH_ALEN];
-       DECLARE_MAC_BUF(mac);
 
        left = len = skb->len - IEEE80211_MGMT_HDR_LEN;
 
        if (len < (reassoc ? 10 : 4)) {
                PDEBUG(DEBUG_AP, "%s: handle_assoc - too short payload "
-                      "(len=%d, reassoc=%d) from %s\n",
-                      dev->name, len, reassoc, print_mac(mac, hdr->addr2));
+                      "(len=%d, reassoc=%d) from " MAC_FMT "\n",
+                      dev->name, len, reassoc,
+                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5]);
                return;
        }
 
@@ -1603,9 +1613,12 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
                }
 
                if (left > 0) {
-                       PDEBUG(DEBUG_AP, "%s: assoc from %s"
+                       PDEBUG(DEBUG_AP, "%s: assoc from " MAC_FMT
                               " with extra data (%d bytes) [",
-                              dev->name, print_mac(mac, hdr->addr2), left);
+                              dev->name,
+                              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+                              left);
                        while (left > 0) {
                                PDEBUG2(DEBUG_AP, "<%02x>", *u);
                                u++; left--;
@@ -1704,10 +1717,15 @@ static void handle_assoc(local_info_t *local, struct sk_buff *skb,
        }
 
 #if 0
-       PDEBUG(DEBUG_AP, "%s: %s %sassoc (len=%d "
-              "prev_ap=%s) => %d(%d) (%s)\n",
-              dev->name, print_mac(mac, hdr->addr2), reassoc ? "re" : "", len,
-              print_mac(mac, prev_ap), resp, send_deauth, txt);
+       PDEBUG(DEBUG_AP, "%s: " MAC_FMT" %sassoc (len=%d "
+              "prev_ap=" MAC_FMT") => %d(%d) (%s)\n",
+              dev->name,
+              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+              reassoc ? "re" : "", len,
+              prev_ap[0], prev_ap[1], prev_ap[2],
+              prev_ap[3], prev_ap[4], prev_ap[5],
+              resp, send_deauth, txt);
 #endif
 }
 
@@ -1735,9 +1753,11 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
        pos = (__le16 *) body;
        reason_code = le16_to_cpu(*pos);
 
-       PDEBUG(DEBUG_AP, "%s: deauthentication: %s len=%d, "
-              "reason_code=%d\n", dev->name, print_mac(mac, hdr->addr2), len,
-              reason_code);
+       PDEBUG(DEBUG_AP, "%s: deauthentication: " MAC_FMT " len=%d, "
+              "reason_code=%d\n", dev->name,
+              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+              len, reason_code);
 
        spin_lock_bh(&local->ap->sta_table_lock);
        sta = ap_get_sta(local->ap, hdr->addr2);
@@ -1748,9 +1768,11 @@ static void handle_deauth(local_info_t *local, struct sk_buff *skb,
        }
        spin_unlock_bh(&local->ap->sta_table_lock);
        if (sta == NULL) {
-               printk("%s: deauthentication from %s, "
+               printk("%s: deauthentication from " MAC_FMT ", "
               "reason_code=%d, but STA not authenticated\n", dev->name,
-                      print_mac(mac, hdr->addr2), reason_code);
+                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+                      reason_code);
        }
 }
 
@@ -1766,7 +1788,6 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
        u16 reason_code;
        __le16 *pos;
        struct sta_info *sta = NULL;
-       DECLARE_MAC_BUF(mac);
 
        len = skb->len - IEEE80211_MGMT_HDR_LEN;
 
@@ -1778,9 +1799,11 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
        pos = (__le16 *) body;
        reason_code = le16_to_cpu(*pos);
 
-       PDEBUG(DEBUG_AP, "%s: disassociation: %s len=%d, "
-              "reason_code=%d\n", dev->name, print_mac(mac, hdr->addr2), len,
-              reason_code);
+       PDEBUG(DEBUG_AP, "%s: disassociation: " MAC_FMT " len=%d, "
+              "reason_code=%d\n", dev->name,
+              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+              len, reason_code);
 
        spin_lock_bh(&local->ap->sta_table_lock);
        sta = ap_get_sta(local->ap, hdr->addr2);
@@ -1791,9 +1814,12 @@ static void handle_disassoc(local_info_t *local, struct sk_buff *skb,
        }
        spin_unlock_bh(&local->ap->sta_table_lock);
        if (sta == NULL) {
-               printk("%s: disassociation from %s, "
+               printk("%s: disassociation from " MAC_FMT ", "
                       "reason_code=%d, but STA not authenticated\n",
-                      dev->name, print_mac(mac, hdr->addr2), reason_code);
+                      dev->name,
+                      hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+                      hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
+                      reason_code);
        }
 }
 
@@ -1882,16 +1908,20 @@ static void handle_pspoll(local_info_t *local,
        struct sta_info *sta;
        u16 aid;
        struct sk_buff *skb;
-       DECLARE_MAC_BUF(mac);
 
-       PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=%s"
-              ", TA=%s PWRMGT=%d\n",
-              print_mac(mac, hdr->addr1), print_mac(mac, hdr->addr2),
+       PDEBUG(DEBUG_PS2, "handle_pspoll: BSSID=" MAC_FMT
+              ", TA=" MAC_FMT " PWRMGT=%d\n",
+              hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+              hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
+              hdr->addr2[0], hdr->addr2[1], hdr->addr2[2],
+              hdr->addr2[3], hdr->addr2[4], hdr->addr2[5],
               !!(le16_to_cpu(hdr->frame_ctl) & IEEE80211_FCTL_PM));
 
        if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
-               PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=%s"
-                      " not own MAC\n", print_mac(mac, hdr->addr1));
+               PDEBUG(DEBUG_AP, "handle_pspoll - addr1(BSSID)=" MAC_FMT
+                      " not own MAC\n",
+                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
                return;
        }
 
@@ -1969,7 +1999,6 @@ static void handle_wds_oper_queue(struct work_struct *work)
                                          wds_oper_queue);
        local_info_t *local = ap->local;
        struct wds_oper_data *entry, *prev;
-       DECLARE_MAC_BUF(mac);
 
        spin_lock_bh(&local->lock);
        entry = local->ap->wds_oper_entries;
@@ -1978,10 +2007,11 @@ static void handle_wds_oper_queue(struct work_struct *work)
 
        while (entry) {
                PDEBUG(DEBUG_AP, "%s: %s automatic WDS connection "
-                      "to AP %s\n",
+                      "to AP " MAC_FMT "\n",
                       local->dev->name,
                       entry->type == WDS_ADD ? "adding" : "removing",
-                      print_mac(mac, entry->addr));
+                      entry->addr[0], entry->addr[1], entry->addr[2],
+                      entry->addr[3], entry->addr[4], entry->addr[5]);
                if (entry->type == WDS_ADD)
                        prism2_wds_add(local, entry->addr, 0);
                else if (entry->type == WDS_DEL)
@@ -2158,7 +2188,6 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
        u16 fc, type, stype;
        struct ieee80211_hdr_4addr *hdr;
-       DECLARE_MAC_BUF(mac);
 
        /* FIX: should give skb->len to handler functions and check that the
         * buffer is long enough */
@@ -2187,8 +2216,9 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
 
                if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
                        PDEBUG(DEBUG_AP, "handle_ap_item - addr1(BSSID)="
-                              "%s not own MAC\n",
-                              print_mac(mac, hdr->addr1));
+                              MAC_FMT " not own MAC\n",
+                              hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+                              hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
                        goto done;
                }
 
@@ -2224,14 +2254,18 @@ static void handle_ap_item(local_info_t *local, struct sk_buff *skb,
        }
 
        if (memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN)) {
-               PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=%s"
-                      " not own MAC\n", print_mac(mac, hdr->addr1));
+               PDEBUG(DEBUG_AP, "handle_ap_item - addr1(DA)=" MAC_FMT
+                      " not own MAC\n",
+                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
                goto done;
        }
 
        if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN)) {
-               PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=%s"
-                      " not own MAC\n", print_mac(mac, hdr->addr3));
+               PDEBUG(DEBUG_AP, "handle_ap_item - addr3(BSSID)=" MAC_FMT
+                      " not own MAC\n",
+                      hdr->addr3[0], hdr->addr3[1], hdr->addr3[2],
+                      hdr->addr3[3], hdr->addr3[4], hdr->addr3[5]);
                goto done;
        }
 
@@ -2312,7 +2346,6 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
        struct sk_buff *skb;
        struct ieee80211_hdr_4addr *hdr;
        struct hostap_80211_rx_status rx_stats;
-       DECLARE_MAC_BUF(mac);
 
        if (skb_queue_empty(&sta->tx_buf))
                return;
@@ -2334,7 +2367,9 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
        hdr->duration_id = cpu_to_le16(sta->aid | BIT(15) | BIT(14));
 
        PDEBUG(DEBUG_PS2, "%s: Scheduling buffered packet delivery for STA "
-              "%s\n", local->dev->name, print_mac(mac, sta->addr));
+              MAC_FMT "\n", local->dev->name,
+              sta->addr[0], sta->addr[1], sta->addr[2],
+              sta->addr[3], sta->addr[4], sta->addr[5]);
 
        skb->dev = local->dev;
 
@@ -2661,7 +2696,6 @@ static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev)
        int ret = sta->tx_rate;
        struct hostap_interface *iface;
        local_info_t *local;
-       DECLARE_MAC_BUF(mac);
 
        iface = netdev_priv(dev);
        local = iface->local;
@@ -2689,9 +2723,12 @@ static int ap_update_sta_tx_rate(struct sta_info *sta, struct net_device *dev)
                        case 3: sta->tx_rate = 110; break;
                        default: sta->tx_rate = 0; break;
                        }
-                       PDEBUG(DEBUG_AP, "%s: STA %s"
+                       PDEBUG(DEBUG_AP, "%s: STA " MAC_FMT
                               " TX rate raised to %d\n",
-                              dev->name, print_mac(mac, sta->addr), sta->tx_rate);
+                              dev->name,
+                              sta->addr[0], sta->addr[1], sta->addr[2],
+                              sta->addr[3], sta->addr[4], sta->addr[5],
+                              sta->tx_rate);
                }
                sta->tx_since_last_failure = 0;
        }
@@ -2709,7 +2746,6 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
        int set_tim, ret;
        struct ieee80211_hdr_4addr *hdr;
        struct hostap_skb_tx_data *meta;
-       DECLARE_MAC_BUF(mac);
 
        meta = (struct hostap_skb_tx_data *) skb->cb;
        ret = AP_TX_CONTINUE;
@@ -2745,8 +2781,9 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
                 * print out any errors here. */
                if (net_ratelimit()) {
                        printk(KERN_DEBUG "AP: drop packet to non-associated "
-                              "STA %s\n",
-                              print_mac(mac, hdr->addr1));
+                              "STA " MAC_FMT "\n",
+                              hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+                              hdr->addr1[3], hdr->addr1[4], hdr->addr1[5]);
                }
 #endif
                local->ap->tx_drop_nonassoc++;
@@ -2784,9 +2821,11 @@ ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx)
        }
 
        if (skb_queue_len(&sta->tx_buf) >= STA_MAX_TX_BUFFER) {
-               PDEBUG(DEBUG_PS, "%s: No more space in STA (%s"
+               PDEBUG(DEBUG_PS, "%s: No more space in STA (" MAC_FMT
                       ")'s PS mode buffer\n",
-                      local->dev->name, print_mac(mac, sta->addr));
+                      local->dev->name,
+                      sta->addr[0], sta->addr[1], sta->addr[2],
+                      sta->addr[3], sta->addr[4], sta->addr[5]);
                /* Make sure that TIM is set for the station (it might not be
                 * after AP wlan hw reset). */
                /* FIX: should fix hw reset to restore bits based on STA
@@ -2850,7 +2889,6 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
        struct sta_info *sta;
        struct ieee80211_hdr_4addr *hdr;
        struct hostap_skb_tx_data *meta;
-       DECLARE_MAC_BUF(mac);
 
        hdr = (struct ieee80211_hdr_4addr *) skb->data;
        meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -2859,9 +2897,12 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
        sta = ap_get_sta(local->ap, hdr->addr1);
        if (!sta) {
                spin_unlock(&local->ap->sta_table_lock);
-               PDEBUG(DEBUG_AP, "%s: Could not find STA %s"
+               PDEBUG(DEBUG_AP, "%s: Could not find STA " MAC_FMT
                       " for this TX error (@%lu)\n",
-                      local->dev->name, print_mac(mac, hdr->addr1), jiffies);
+                      local->dev->name,
+                      hdr->addr1[0], hdr->addr1[1], hdr->addr1[2],
+                      hdr->addr1[3], hdr->addr1[4], hdr->addr1[5],
+                      jiffies);
                return;
        }
 
@@ -2888,9 +2929,11 @@ void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
                        case 3: sta->tx_rate = 110; break;
                        default: sta->tx_rate = 0; break;
                        }
-                       PDEBUG(DEBUG_AP, "%s: STA %s"
+                       PDEBUG(DEBUG_AP, "%s: STA " MAC_FMT
                               " TX rate lowered to %d\n",
-                              local->dev->name, print_mac(mac, sta->addr),
+                              local->dev->name,
+                              sta->addr[0], sta->addr[1], sta->addr[2],
+                              sta->addr[3], sta->addr[4], sta->addr[5],
                               sta->tx_rate);
                }
                sta->tx_consecutive_exc = 0;
@@ -2956,7 +2999,6 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
        struct sta_info *sta;
        u16 fc, type, stype;
        struct ieee80211_hdr_4addr *hdr;
-       DECLARE_MAC_BUF(mac);
 
        if (local->ap == NULL)
                return AP_RX_CONTINUE;
@@ -2988,9 +3030,12 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                        } else {
                                printk(KERN_DEBUG "%s: dropped received packet"
                                       " from non-associated STA "
-                                      "%s"
+                                      MAC_FMT
                                       " (type=0x%02x, subtype=0x%02x)\n",
-                                      dev->name, print_mac(mac, hdr->addr2),
+                                      dev->name,
+                                      hdr->addr2[0], hdr->addr2[1],
+                                      hdr->addr2[2], hdr->addr2[3],
+                                      hdr->addr2[4], hdr->addr2[5],
                                       type >> 2, stype >> 4);
                                hostap_rx(dev, skb, rx_stats);
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
@@ -3025,8 +3070,11 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                         * being associated. */
                        printk(KERN_DEBUG "%s: rejected received nullfunc "
                               "frame without ToDS from not associated STA "
-                              "%s\n",
-                              dev->name, print_mac(mac, hdr->addr2));
+                              MAC_FMT "\n",
+                              dev->name,
+                              hdr->addr2[0], hdr->addr2[1],
+                              hdr->addr2[2], hdr->addr2[3],
+                              hdr->addr2[4], hdr->addr2[5]);
                        hostap_rx(dev, skb, rx_stats);
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
                }
@@ -3043,9 +3091,12 @@ ap_rx_ret hostap_handle_sta_rx(local_info_t *local, struct net_device *dev,
                 * If BSSID is own, report the dropping of this frame. */
                if (memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
                        printk(KERN_DEBUG "%s: dropped received packet from "
-                              "%s with no ToDS flag "
+                              MAC_FMT " with no ToDS flag "
                               "(type=0x%02x, subtype=0x%02x)\n", dev->name,
-                              print_mac(mac, hdr->addr2), type >> 2, stype >> 4);
+                              hdr->addr2[0], hdr->addr2[1],
+                              hdr->addr2[2], hdr->addr2[3],
+                              hdr->addr2[4], hdr->addr2[5],
+                              type >> 2, stype >> 4);
                        hostap_dump_rx_80211(dev->name, skb, rx_stats);
                }
                ret = AP_RX_DROP;
index a56d9fc..98d6ff6 100644 (file)
@@ -10192,7 +10192,6 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
        u8 id, hdr_len, unicast;
        u16 remaining_bytes;
        int fc;
-       DECLARE_MAC_BUF(mac);
 
        hdr_len = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
        switch (priv->ieee->iw_mode) {
@@ -10203,8 +10202,10 @@ static int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
                        id = ipw_add_station(priv, hdr->addr1);
                        if (id == IPW_INVALID_STATION) {
                                IPW_WARNING("Attempt to send data to "
-                                           "invalid cell: %s\n",
-                                           print_mac(mac, hdr->addr1));
+                                           "invalid cell: " MAC_FMT "\n",
+                                           hdr->addr1[0], hdr->addr1[1],
+                                           hdr->addr1[2], hdr->addr1[3],
+                                           hdr->addr1[4], hdr->addr1[5]);
                                goto drop;
                        }
                }
@@ -11576,6 +11577,7 @@ static int ipw_prom_alloc(struct ipw_priv *priv)
        priv->prom_priv->priv = priv;
 
        strcpy(priv->prom_net_dev->name, "rtap%d");
+       memcpy(priv->prom_net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
 
        priv->prom_net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
        priv->prom_net_dev->open = ipw_prom_open;
index b79a35a..b54ff71 100644 (file)
@@ -35,7 +35,6 @@ config IWL4965_HT
        bool "Enable 802.11n HT features in iwl4965 driver"
        depends on EXPERIMENTAL
        depends on IWL4965 && IWL4965_QOS
-       depends on n
        ---help---
          This option enables IEEE 802.11n High Throughput features
          for the iwl4965 driver.
index 87e145f..6a24ed6 100644 (file)
@@ -541,7 +541,7 @@ void lbs_association_worker(struct work_struct *work)
        }
 
        if (find_any_ssid) {
-               u8 new_mode;
+               u8 new_mode = assoc_req->mode;
 
                ret = lbs_find_best_network_ssid(priv, assoc_req->ssid,
                                &assoc_req->ssid_len, assoc_req->mode, &new_mode);
index 93ea212..ad2e7d5 100644 (file)
@@ -2399,10 +2399,8 @@ static int rt61pci_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
         * beacon frame.
         */
        if (skb_headroom(skb) < TXD_DESC_SIZE) {
-               if (pskb_expand_head(skb, TXD_DESC_SIZE, 0, GFP_ATOMIC)) {
-                       dev_kfree_skb(skb);
+               if (pskb_expand_head(skb, TXD_DESC_SIZE, 0, GFP_ATOMIC))
                        return -ENOMEM;
-               }
        }
 
        /*
index f445059..133b3f3 100644 (file)
@@ -509,6 +509,8 @@ static int rtl8187_add_interface(struct ieee80211_hw *dev,
                return -EOPNOTSUPP;
        }
 
+       priv->vif = conf->vif;
+
        rtl818x_iowrite8(priv, &priv->map->EEPROM_CMD, RTL818X_EEPROM_CMD_CONFIG);
        for (i = 0; i < ETH_ALEN; i++)
                rtl818x_iowrite8(priv, &priv->map->MAC[i],
@@ -523,6 +525,7 @@ static void rtl8187_remove_interface(struct ieee80211_hw *dev,
 {
        struct rtl8187_priv *priv = dev->priv;
        priv->mode = IEEE80211_IF_TYPE_MNTR;
+       priv->vif = NULL;
 }
 
 static int rtl8187_config(struct ieee80211_hw *dev, struct ieee80211_conf *conf)
index 385e145..6849685 100644 (file)
@@ -419,3 +419,4 @@ module_exit(at91_cf_exit);
 MODULE_DESCRIPTION("AT91 Compact Flash Driver");
 MODULE_AUTHOR("David Brownell");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_cf");
index 2df216b..bb6db3a 100644 (file)
@@ -344,6 +344,7 @@ static int omap_cf_resume(struct platform_device *pdev)
 static struct platform_driver omap_cf_driver = {
        .driver = {
                .name   = (char *) driver_name,
+               .owner  = THIS_MODULE,
        },
        .remove         = __exit_p(omap_cf_remove),
        .suspend        = omap_cf_suspend,
@@ -368,3 +369,4 @@ module_exit(omap_cf_exit);
 
 MODULE_DESCRIPTION("OMAP CF Driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:omap_cf");
index e439044..9414163 100644 (file)
@@ -239,6 +239,7 @@ static struct platform_driver pxa2xx_pcmcia_driver = {
        .resume         = pxa2xx_drv_pcmcia_resume,
        .driver         = {
                .name   = "pxa2xx-pcmcia",
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -258,3 +259,4 @@ module_exit(pxa2xx_pcmcia_exit);
 MODULE_AUTHOR("Stefan Eletzhofer <stefan.eletzhofer@inquant.de> and Ian Molton <spyro@f2s.com>");
 MODULE_DESCRIPTION("Linux PCMCIA Card Services: PXA2xx core socket driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa2xx-pcmcia");
index 9e7de63..02a4c8c 100644 (file)
@@ -252,6 +252,7 @@ config RTC_DRV_TWL92330
 
 config RTC_DRV_S35390A
        tristate "Seiko Instruments S-35390A"
+       select BITREVERSE
        help
          If you say yes here you will get support for the Seiko
          Instruments S-35390A.
index d3b9b14..42244f1 100644 (file)
@@ -290,7 +290,7 @@ static int __exit at32_rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
-MODULE_ALIAS("at32ap700x_rtc");
+MODULE_ALIAS("platform:at32ap700x_rtc");
 
 static struct platform_driver at32_rtc_driver = {
        .remove         = __exit_p(at32_rtc_remove),
index 33795e5..52abffc 100644 (file)
@@ -407,3 +407,4 @@ module_exit(at91_rtc_exit);
 MODULE_AUTHOR("Rick Bronson");
 MODULE_DESCRIPTION("RTC driver for Atmel AT91RM9200");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_rtc");
index d90ba86..4f28045 100644 (file)
@@ -470,3 +470,4 @@ module_exit(bfin_rtc_exit);
 MODULE_DESCRIPTION("Blackfin On-Chip Real Time Clock Driver");
 MODULE_AUTHOR("Mike Frysinger <vapier@gentoo.org>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:rtc-bfin");
index f3ee2ad..dcdc142 100644 (file)
@@ -198,9 +198,8 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t)
 
        /* Writing 0xff means "don't care" or "match all".  */
 
-       mon = t->time.tm_mon;
-       mon = (mon < 12) ? BIN2BCD(mon) : 0xff;
-       mon++;
+       mon = t->time.tm_mon + 1;
+       mon = (mon <= 12) ? BIN2BCD(mon) : 0xff;
 
        mday = t->time.tm_mday;
        mday = (mday >= 1 && mday <= 31) ? BIN2BCD(mday) : 0xff;
@@ -943,6 +942,9 @@ static void cmos_platform_shutdown(struct platform_device *pdev)
        cmos_do_shutdown();
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:rtc_cmos");
+
 static struct platform_driver cmos_platform_driver = {
        .remove         = __exit_p(cmos_platform_remove),
        .shutdown       = cmos_platform_shutdown,
index 83efb88..0b17770 100644 (file)
@@ -221,6 +221,7 @@ MODULE_AUTHOR("Thomas Bogendoerfer <tsbogend@alpha.franken.de>");
 MODULE_DESCRIPTION("DS1216 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:rtc-ds1216");
 
 module_init(ds1216_rtc_init);
 module_exit(ds1216_rtc_exit);
index d74b808..d08912f 100644 (file)
@@ -626,6 +626,9 @@ ds1511_rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:ds1511");
+
 static struct platform_driver ds1511_rtc_driver = {
        .probe          = ds1511_rtc_probe,
        .remove         = __devexit_p(ds1511_rtc_remove),
index d9e848d..a19f114 100644 (file)
@@ -391,6 +391,9 @@ static int __devexit ds1553_rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:rtc-ds1553");
+
 static struct platform_driver ds1553_rtc_driver = {
        .probe          = ds1553_rtc_probe,
        .remove         = __devexit_p(ds1553_rtc_remove),
index 2e73f0b..24d35ed 100644 (file)
@@ -276,3 +276,4 @@ MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>");
 MODULE_DESCRIPTION("Dallas DS1742 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:rtc-ds1742");
index ef4f147..1e99325 100644 (file)
@@ -132,6 +132,9 @@ static int __devexit ep93xx_rtc_remove(struct platform_device *dev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:ep93xx-rtc");
+
 static struct platform_driver ep93xx_rtc_platform_driver = {
        .driver         = {
                .name   = "ep93xx-rtc",
index cd0bbc0..013e6c1 100644 (file)
@@ -465,6 +465,9 @@ static int __devexit m48t59_rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:rtc-m48t59");
+
 static struct platform_driver m48t59_rtc_driver = {
        .driver         = {
                .name   = "rtc-m48t59",
index 8ff4a12..3f7f99a 100644 (file)
@@ -199,6 +199,7 @@ MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
 MODULE_DESCRIPTION("M48T86 RTC driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_VERSION);
+MODULE_ALIAS("platform:rtc-m48t86");
 
 module_init(m48t86_rtc_init);
 module_exit(m48t86_rtc_exit);
index a2f84f1..58f81c7 100644 (file)
@@ -497,7 +497,7 @@ static void omap_rtc_shutdown(struct platform_device *pdev)
        rtc_write(0, OMAP_RTC_INTERRUPTS_REG);
 }
 
-MODULE_ALIAS("omap_rtc");
+MODULE_ALIAS("platform:omap_rtc");
 static struct platform_driver omap_rtc_driver = {
        .probe          = omap_rtc_probe,
        .remove         = __devexit_p(omap_rtc_remove),
index 66eb133..664e89a 100644 (file)
@@ -421,3 +421,4 @@ MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR("kogiidena , Nobuhiro Iwamatsu <iwamatsu@nigauri.org>");
 MODULE_DESCRIPTION("Ricoh RS5C313 RTC device driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
index 86766f1..9f4d512 100644 (file)
@@ -592,3 +592,4 @@ module_exit(s3c_rtc_exit);
 MODULE_DESCRIPTION("Samsung S3C RTC Driver");
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s3c2410-rtc");
index ee253cc..82f62d2 100644 (file)
@@ -399,3 +399,4 @@ module_exit(sa1100_rtc_exit);
 MODULE_AUTHOR("Richard Purdie <rpurdie@rpsys.net>");
 MODULE_DESCRIPTION("SA11x0/PXA2xx Realtime Clock Driver (RTC)");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sa1100-rtc");
index c1d6a18..9e9caa5 100644 (file)
@@ -664,3 +664,4 @@ MODULE_DESCRIPTION("SuperH on-chip RTC driver");
 MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>, Jamie Lenehan <lenehan@twibble.org>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRV_NAME);
index a265da7..31d3c8c 100644 (file)
@@ -394,6 +394,9 @@ static int __devexit stk17ta8_rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:stk17ta8");
+
 static struct platform_driver stk17ta8_rtc_driver = {
        .probe          = stk17ta8_rtc_probe,
        .remove         = __devexit_p(stk17ta8_rtc_remove),
index a6b5729..24203a0 100644 (file)
@@ -264,3 +264,4 @@ module_exit(v3020_exit);
 MODULE_DESCRIPTION("V3020 RTC");
 MODULE_AUTHOR("Raphael Assenat");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:v3020");
index ce2f78d..be9c70d 100644 (file)
@@ -422,6 +422,9 @@ static int __devexit rtc_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:RTC");
+
 static struct platform_driver rtc_platform_driver = {
        .probe          = rtc_probe,
        .remove         = __devexit_p(rtc_remove),
index 430997e..55492fa 100644 (file)
@@ -1577,3 +1577,4 @@ module_exit(atmel_serial_exit);
 MODULE_AUTHOR("Rick Bronson");
 MODULE_DESCRIPTION("Atmel AT91 / AT32 serial port driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:atmel_usart");
index 0aa345b..46bb47f 100644 (file)
@@ -1243,6 +1243,7 @@ static struct platform_driver bfin_serial_driver = {
        .resume         = bfin_serial_resume,
        .driver         = {
                .name   = "bfin-uart",
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -1301,3 +1302,4 @@ MODULE_AUTHOR("Aubrey.Li <aubrey.li@analog.com>");
 MODULE_DESCRIPTION("Blackfin generic serial port driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_CHARDEV_MAJOR(BFIN_SERIAL_MAJOR);
+MODULE_ALIAS("platform:bfin-uart");
index 56af1f5..16ba9ac 100644 (file)
@@ -1090,6 +1090,7 @@ static struct platform_driver serial_imx_driver = {
        .resume         = serial_imx_resume,
        .driver         = {
                .name   = "imx-uart",
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -1124,3 +1125,4 @@ module_exit(imx_serial_exit);
 MODULE_AUTHOR("Sascha Hauer");
 MODULE_DESCRIPTION("IMX generic serial port driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:imx-uart");
index e76fc72..7e164e0 100644 (file)
@@ -649,5 +649,6 @@ module_exit(mcf_exit);
 MODULE_AUTHOR("Greg Ungerer <gerg@snapgear.com>");
 MODULE_DESCRIPTION("Freescale ColdFire UART driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:mcfuart");
 
 /****************************************************************************/
index a638f23..d93b357 100644 (file)
@@ -1188,6 +1188,8 @@ mpc52xx_uart_resume(struct platform_device *dev)
 }
 #endif
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:mpc52xx-psc");
 
 static struct platform_driver mpc52xx_uart_platform_driver = {
        .probe          = mpc52xx_uart_probe,
index cb3a919..e8819c4 100644 (file)
@@ -1964,6 +1964,7 @@ static struct platform_driver mpsc_driver = {
        .remove = mpsc_drv_remove,
        .driver = {
                .name   = MPSC_CTLR_NAME,
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -2007,3 +2008,4 @@ MODULE_DESCRIPTION("Generic Marvell MPSC serial/UART driver $Revision: 1.00 $");
 MODULE_VERSION(MPSC_VERSION);
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_CHARDEV_MAJOR(MPSC_MAJOR);
+MODULE_ALIAS("platform:" MPSC_CTLR_NAME);
index b56f7db..3123ffe 100644 (file)
@@ -713,6 +713,7 @@ static struct platform_driver serial_netx_driver = {
 
        .driver         = {
                .name   = DRIVER_NAME,
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -745,3 +746,4 @@ module_exit(netx_serial_exit);
 MODULE_AUTHOR("Sascha Hauer");
 MODULE_DESCRIPTION("NetX serial port driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:" DRIVER_NAME);
index 8d01c59..d0e5a79 100644 (file)
@@ -850,3 +850,4 @@ MODULE_AUTHOR("Embedded Alley Solutions, Inc.");
 MODULE_DESCRIPTION("PNX8XXX SoCs serial port driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_PNX8XXX_MAJOR);
+MODULE_ALIAS("platform:pnx8xxx-uart");
index 352fcb8..b4f7ffb 100644 (file)
@@ -833,6 +833,7 @@ static struct platform_driver serial_pxa_driver = {
        .resume         = serial_pxa_resume,
        .driver         = {
                .name   = "pxa2xx-uart",
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -861,4 +862,4 @@ module_init(serial_pxa_init);
 module_exit(serial_pxa_exit);
 
 MODULE_LICENSE("GPL");
-
+MODULE_ALIAS("platform:pxa2xx-uart");
index 45de193..4ffa258 100644 (file)
@@ -1935,3 +1935,7 @@ console_initcall(s3c24xx_serial_initconsole);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>");
 MODULE_DESCRIPTION("Samsung S3C2410/S3C2440/S3C2412 Serial port driver");
+MODULE_ALIAS("platform:s3c2400-uart");
+MODULE_ALIAS("platform:s3c2410-uart");
+MODULE_ALIAS("platform:s3c2412-uart");
+MODULE_ALIAS("platform:s3c2440-uart");
index 58a83c2..67b2338 100644 (file)
@@ -884,6 +884,7 @@ static struct platform_driver sa11x0_serial_driver = {
        .resume         = sa1100_serial_resume,
        .driver         = {
                .name   = "sa11x0-uart",
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -917,3 +918,4 @@ MODULE_AUTHOR("Deep Blue Solutions Ltd");
 MODULE_DESCRIPTION("SA1100 generic serial port driver $Revision: 1.50 $");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_SA1100_MAJOR);
+MODULE_ALIAS("platform:sa11x0-uart");
index a350b6d..ae2a9e2 100644 (file)
@@ -732,6 +732,7 @@ static struct platform_driver sc26xx_driver = {
        .remove = __devexit_p(sc26xx_driver_remove),
        .driver = {
                .name   = "SC26xx",
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -753,3 +754,4 @@ MODULE_AUTHOR("Thomas Bogendörfer");
 MODULE_DESCRIPTION("SC681/SC2692 serial driver");
 MODULE_VERSION("1.0");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:SC26xx");
index 9d244d1..eff5930 100644 (file)
@@ -1552,3 +1552,4 @@ module_init(sci_init);
 module_exit(sci_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sh-sci");
index 4e06ab6..b565d5a 100644 (file)
@@ -561,6 +561,9 @@ static int __devexit ulite_remove(struct platform_device *pdev)
        return ulite_release(&pdev->dev);
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:uartlite");
+
 static struct platform_driver ulite_platform_driver = {
        .probe  = ulite_probe,
        .remove = __devexit_p(ulite_remove),
index 6fd51b0..98ab649 100644 (file)
@@ -960,3 +960,6 @@ static void __exit vr41xx_siu_exit(void)
 
 module_init(vr41xx_siu_init);
 module_exit(vr41xx_siu_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:SIU");
index 85687aa..1749a27 100644 (file)
@@ -863,3 +863,4 @@ module_exit(atmel_spi_exit);
 MODULE_DESCRIPTION("Atmel AT32/AT91 SPI Controller driver");
 MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:atmel_spi");
index 41a3d00..072c4a5 100644 (file)
@@ -958,6 +958,9 @@ static int __exit au1550_spi_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:au1550-spi");
+
 static struct platform_driver au1550_spi_drv = {
        .remove = __exit_p(au1550_spi_remove),
        .driver = {
index a86315a..9072946 100644 (file)
@@ -500,6 +500,9 @@ static int __exit mpc52xx_psc_spi_remove(struct platform_device *dev)
        return mpc52xx_psc_spi_do_remove(&dev->dev);
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:mpc52xx-psc-spi");
+
 static struct platform_driver mpc52xx_psc_spi_platform_driver = {
        .remove = __exit_p(mpc52xx_psc_spi_remove),
        .driver = {
index a6ba11a..b1cc148 100644 (file)
@@ -1084,6 +1084,9 @@ static int __exit omap2_mcspi_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:omap2_mcspi");
+
 static struct platform_driver omap2_mcspi_driver = {
        .driver = {
                .name =         "omap2_mcspi",
index 8245b51..5f00bd6 100644 (file)
@@ -537,10 +537,12 @@ static int __exit uwire_remove(struct platform_device *pdev)
        return status;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:omap_uwire");
+
 static struct platform_driver uwire_driver = {
        .driver = {
                .name           = "omap_uwire",
-               .bus            = &platform_bus_type,
                .owner          = THIS_MODULE,
        },
        .remove         = __exit_p(uwire_remove),
index 59deed7..147e26a 100644 (file)
@@ -44,6 +44,7 @@
 MODULE_AUTHOR("Stephen Street");
 MODULE_DESCRIPTION("PXA2xx SSP SPI Controller");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pxa2xx-spi");
 
 #define MAX_BUSES 3
 
@@ -1581,7 +1582,6 @@ static int pxa2xx_spi_resume(struct platform_device *pdev)
 static struct platform_driver driver = {
        .driver = {
                .name = "pxa2xx-spi",
-               .bus = &platform_bus_type,
                .owner = THIS_MODULE,
        },
        .remove = pxa2xx_spi_remove,
index d853fce..a9ac1fd 100644 (file)
@@ -713,8 +713,8 @@ static void pump_transfers(unsigned long data)
        } else {
                drv_data->len = transfer->len;
        }
-       dev_dbg(&drv_data->pdev->dev, "transfer: ",
-               "drv_data->write is %p, chip->write is %p, null_wr is %p\n",
+       dev_dbg(&drv_data->pdev->dev,
+               "transfer: drv_data->write is %p, chip->write is %p, null_wr is %p\n",
                drv_data->write, chip->write, null_writer);
 
        /* speed and width has been set on per message */
@@ -1294,6 +1294,12 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
                goto out_error_queue_alloc;
        }
 
+       status = peripheral_request_list(drv_data->pin_req, DRV_NAME);
+       if (status != 0) {
+               dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
+               goto out_error_queue_alloc;
+       }
+
        /* Register with the SPI framework */
        platform_set_drvdata(pdev, drv_data);
        status = spi_register_master(master);
@@ -1302,12 +1308,6 @@ static int __init bfin5xx_spi_probe(struct platform_device *pdev)
                goto out_error_queue_alloc;
        }
 
-       status = peripheral_request_list(drv_data->pin_req, DRV_NAME);
-       if (status != 0) {
-               dev_err(&pdev->dev, ": Requesting Peripherals failed\n");
-               goto out_error;
-       }
-
        dev_info(dev, "%s, Version %s, regs_base@%p, dma channel@%d\n",
                DRV_DESC, DRV_VERSION, drv_data->regs_base,
                drv_data->dma_channel);
@@ -1319,7 +1319,6 @@ out_error_no_dma_ch:
        iounmap((void *) drv_data->regs_base);
 out_error_ioremap:
 out_error_get_res:
-out_error:
        spi_master_put(master);
 
        return status;
@@ -1397,7 +1396,7 @@ static int bfin5xx_spi_resume(struct platform_device *pdev)
 #define bfin5xx_spi_resume NULL
 #endif                         /* CONFIG_PM */
 
-MODULE_ALIAS("bfin-spi-master");       /* for platform bus hotplug */
+MODULE_ALIAS("platform:bfin-spi");
 static struct platform_driver bfin5xx_spi_driver = {
        .driver = {
                .name   = DRV_NAME,
index 1b06471..d4ba640 100644 (file)
@@ -1722,10 +1722,12 @@ static int spi_imx_resume(struct platform_device *pdev)
 #define spi_imx_resume NULL
 #endif /* CONFIG_PM */
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:spi_imx");
+
 static struct platform_driver driver = {
        .driver = {
                .name = "spi_imx",
-               .bus = &platform_bus_type,
                .owner = THIS_MODULE,
        },
        .remove = __exit_p(spi_imx_remove),
index 04f7cd9..be15a62 100644 (file)
@@ -523,11 +523,12 @@ static int __exit mpc83xx_spi_remove(struct platform_device *dev)
        return 0;
 }
 
-MODULE_ALIAS("mpc83xx_spi");                   /* for platform bus hotplug */
+MODULE_ALIAS("platform:mpc83xx_spi");
 static struct platform_driver mpc83xx_spi_driver = {
        .remove = __exit_p(mpc83xx_spi_remove),
        .driver = {
-                  .name = "mpc83xx_spi",
+               .name = "mpc83xx_spi",
+               .owner = THIS_MODULE,
        },
 };
 
index 6e834b8..b7476b8 100644 (file)
@@ -192,8 +192,11 @@ static int s3c24xx_spi_txrx(struct spi_device *spi, struct spi_transfer *t)
        hw->len = t->len;
        hw->count = 0;
 
+       init_completion(&hw->done);
+
        /* send the first byte */
        writeb(hw_txbyte(hw, 0), hw->regs + S3C2410_SPTDAT);
+
        wait_for_completion(&hw->done);
 
        return hw->count;
@@ -235,6 +238,7 @@ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
 
 static int __init s3c24xx_spi_probe(struct platform_device *pdev)
 {
+       struct s3c2410_spi_info *pdata;
        struct s3c24xx_spi *hw;
        struct spi_master *master;
        struct resource *res;
@@ -251,10 +255,10 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev)
        memset(hw, 0, sizeof(struct s3c24xx_spi));
 
        hw->master = spi_master_get(master);
-       hw->pdata = pdev->dev.platform_data;
+       hw->pdata = pdata = pdev->dev.platform_data;
        hw->dev = &pdev->dev;
 
-       if (hw->pdata == NULL) {
+       if (pdata == NULL) {
                dev_err(&pdev->dev, "No platform data supplied\n");
                err = -ENOENT;
                goto err_no_pdata;
@@ -263,6 +267,10 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, hw);
        init_completion(&hw->done);
 
+       /* setup the master state. */
+
+       master->num_chipselect = hw->pdata->num_cs;
+
        /* setup the state for the bitbang driver */
 
        hw->bitbang.master         = hw->master;
@@ -330,13 +338,13 @@ static int __init s3c24xx_spi_probe(struct platform_device *pdev)
 
        /* setup any gpio we can */
 
-       if (!hw->pdata->set_cs) {
+       if (!pdata->set_cs) {
                hw->set_cs = s3c24xx_spi_gpiocs;
 
-               s3c2410_gpio_setpin(hw->pdata->pin_cs, 1);
-               s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT);
+               s3c2410_gpio_setpin(pdata->pin_cs, 1);
+               s3c2410_gpio_cfgpin(pdata->pin_cs, S3C2410_GPIO_OUTPUT);
        } else
-               hw->set_cs = hw->pdata->set_cs;
+               hw->set_cs = pdata->set_cs;
 
        /* register our spi controller */
 
@@ -415,7 +423,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev)
 #define s3c24xx_spi_resume  NULL
 #endif
 
-MODULE_ALIAS("s3c2410_spi");                   /* for platform bus hotplug */
+MODULE_ALIAS("platform:s3c2410-spi");
 static struct platform_driver s3c24xx_spidrv = {
        .remove         = __exit_p(s3c24xx_spi_remove),
        .suspend        = s3c24xx_spi_suspend,
index 82ae7d7..e33f614 100644 (file)
@@ -168,6 +168,8 @@ static int s3c2410_spigpio_remove(struct platform_device *dev)
 #define s3c2410_spigpio_suspend NULL
 #define s3c2410_spigpio_resume NULL
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:spi_s3c24xx_gpio");
 
 static struct platform_driver s3c2410_spigpio_drv = {
        .probe          = s3c2410_spigpio_probe,
index 3dbe71b..7d36720 100644 (file)
@@ -203,3 +203,4 @@ module_exit(sh_sci_spi_exit);
 MODULE_DESCRIPTION("SH SCI SPI Driver");
 MODULE_AUTHOR("Magnus Damm <damm@opensource.se>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:spi_sh_sci");
index 363ac8e..2296f37 100644 (file)
@@ -450,6 +450,9 @@ static int __exit txx9spi_remove(struct platform_device *dev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:spi_txx9");
+
 static struct platform_driver txx9spi_driver = {
        .remove = __exit_p(txx9spi_remove),
        .driver = {
index 5d04f52..cf6aef3 100644 (file)
@@ -408,6 +408,9 @@ static int __devexit xilinx_spi_remove(struct platform_device *dev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:" XILINX_SPI_NAME);
+
 static struct platform_driver xilinx_spi_driver = {
        .probe  = xilinx_spi_probe,
        .remove = __devexit_p(xilinx_spi_remove),
index 3d3dd32..a9e7eb4 100644 (file)
@@ -109,12 +109,13 @@ static void set_irq(struct ssb_device *dev, unsigned int irq)
                clear_irq(bus, oldirq);
 
        /* assign the new one */
-       if (irq == 0)
-               ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) & ssb_read32(mdev, SSB_INTVEC)));
-
-       irqflag <<= ipsflag_irq_shift[irq];
-       irqflag |= (ssb_read32(mdev, SSB_IPSFLAG) & ~ipsflag_irq_mask[irq]);
-       ssb_write32(mdev, SSB_IPSFLAG, irqflag);
+       if (irq == 0) {
+               ssb_write32(mdev, SSB_INTVEC, ((1 << irqflag) | ssb_read32(mdev, SSB_INTVEC)));
+       } else {
+               irqflag <<= ipsflag_irq_shift[irq];
+               irqflag |= (ssb_read32(mdev, SSB_IPSFLAG) & ~ipsflag_irq_mask[irq]);
+               ssb_write32(mdev, SSB_IPSFLAG, irqflag);
+       }
 }
 
 static void ssb_mips_serial_init(struct ssb_mipscore *mcore)
index 74b9a8a..5d777f2 100644 (file)
@@ -551,7 +551,7 @@ int ssb_pcicore_dev_irqvecs_enable(struct ssb_pcicore *pc,
                } else {
                        tmp = ssb_read32(dev, SSB_TPSFLAG);
                        tmp &= SSB_TPSFLAG_BPFLAG;
-                       intvec |= tmp;
+                       intvec |= (1 << tmp);
                }
                ssb_write32(pdev, SSB_INTVEC, intvec);
        }
index bedb2b4..8003a9e 100644 (file)
@@ -436,15 +436,18 @@ static int ssb_devices_register(struct ssb_bus *bus)
 #ifdef CONFIG_SSB_PCIHOST
                        sdev->irq = bus->host_pci->irq;
                        dev->parent = &bus->host_pci->dev;
+                       sdev->dma_dev = &bus->host_pci->dev;
 #endif
                        break;
                case SSB_BUSTYPE_PCMCIA:
 #ifdef CONFIG_SSB_PCMCIAHOST
                        sdev->irq = bus->host_pcmcia->irq.AssignedIRQ;
                        dev->parent = &bus->host_pcmcia->dev;
+                       sdev->dma_dev = &bus->host_pcmcia->dev;
 #endif
                        break;
                case SSB_BUSTYPE_SSB:
+                       sdev->dma_dev = dev;
                        break;
                }
 
@@ -1018,15 +1021,14 @@ EXPORT_SYMBOL(ssb_dma_translation);
 
 int ssb_dma_set_mask(struct ssb_device *ssb_dev, u64 mask)
 {
-       struct device *dev = ssb_dev->dev;
+       struct device *dma_dev = ssb_dev->dma_dev;
 
 #ifdef CONFIG_SSB_PCIHOST
-       if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI &&
-           !dma_supported(dev, mask))
-               return -EIO;
+       if (ssb_dev->bus->bustype == SSB_BUSTYPE_PCI)
+               return dma_set_mask(dma_dev, mask);
 #endif
-       dev->coherent_dma_mask = mask;
-       dev->dma_mask = &dev->coherent_dma_mask;
+       dma_dev->coherent_dma_mask = mask;
+       dma_dev->dma_mask = &dma_dev->coherent_dma_mask;
 
        return 0;
 }
@@ -1044,6 +1046,12 @@ int ssb_bus_may_powerdown(struct ssb_bus *bus)
                goto out;
 
        cc = &bus->chipco;
+
+       if (!cc->dev)
+               goto out;
+       if (cc->dev->id.revision < 5)
+               goto out;
+
        ssb_chipco_set_clockmode(cc, SSB_CLKMODE_SLOW);
        err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 0);
        if (err)
index 8b86e53..7f79bbf 100644 (file)
@@ -196,6 +196,10 @@ static struct device_attribute trip_point_attrs[] = {
        __ATTR(trip_point_8_temp, 0444, trip_point_temp_show, NULL),
        __ATTR(trip_point_9_type, 0444, trip_point_type_show, NULL),
        __ATTR(trip_point_9_temp, 0444, trip_point_temp_show, NULL),
+       __ATTR(trip_point_10_type, 0444, trip_point_type_show, NULL),
+       __ATTR(trip_point_10_temp, 0444, trip_point_temp_show, NULL),
+       __ATTR(trip_point_11_type, 0444, trip_point_type_show, NULL),
+       __ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL),
 };
 
 #define TRIP_POINT_ATTR_ADD(_dev, _index, result)     \
index a83e8b7..fd15ced 100644 (file)
@@ -1884,3 +1884,4 @@ module_exit(udc_exit_module);
 MODULE_DESCRIPTION("AT91 udc driver");
 MODULE_AUTHOR("Thomas Rathbone, David Brownell");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:at91_udc");
index af8b2a3..b0db4c3 100644 (file)
@@ -2054,6 +2054,7 @@ static struct platform_driver udc_driver = {
        .remove         = __exit_p(usba_udc_remove),
        .driver         = {
                .name           = "atmel_usba_udc",
+               .owner          = THIS_MODULE,
        },
 };
 
@@ -2072,3 +2073,4 @@ module_exit(udc_exit);
 MODULE_DESCRIPTION("Atmel USBA UDC driver");
 MODULE_AUTHOR("Haavard Skinnemoen <hskinnemoen@atmel.com>");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:atmel_usba_udc");
index 63e8fa3..254012a 100644 (file)
@@ -2475,3 +2475,4 @@ module_exit(udc_exit);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:fsl-usb2-udc");
index 37243ef..078f724 100644 (file)
@@ -2146,3 +2146,4 @@ module_exit(udc_exit);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR("Mikko Lahteenmaki, Bo Henriksen");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:lh7a40x_udc");
index 835948f..ee6b35f 100644 (file)
@@ -35,6 +35,7 @@
 MODULE_DESCRIPTION("M66592 USB gadget driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yoshihiro Shimoda");
+MODULE_ALIAS("platform:m66592_udc");
 
 #define DRIVER_VERSION "18 Oct 2007"
 
@@ -1671,6 +1672,7 @@ static struct platform_driver m66592_driver = {
        .remove =       __exit_p(m66592_remove),
        .driver         = {
                .name = (char *) udc_name,
+               .owner  = THIS_MODULE,
        },
 };
 
index e6d68bd..ee1e9a3 100644 (file)
@@ -3109,4 +3109,4 @@ module_exit(udc_exit);
 
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_LICENSE("GPL");
-
+MODULE_ALIAS("platform:omap_udc");
index 096c41c..c00cd8b 100644 (file)
@@ -2380,4 +2380,4 @@ module_exit(udc_exit);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_AUTHOR("Frank Becker, Robert Schwebel, David Brownell");
 MODULE_LICENSE("GPL");
-
+MODULE_ALIAS("platform:pxa2xx-udc");
index aadc420..6b1ef48 100644 (file)
@@ -2047,3 +2047,5 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
 MODULE_DESCRIPTION(DRIVER_DESC);
 MODULE_VERSION(DRIVER_VERSION);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:s3c2410-usbgadget");
+MODULE_ALIAS("platform:s3c2440-usbgadget");
index d7071c8..203a335 100644 (file)
@@ -1684,14 +1684,18 @@ static int isp116x_resume(struct platform_device *dev)
 
 #endif
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:isp116x-hcd");
+
 static struct platform_driver isp116x_driver = {
        .probe = isp116x_probe,
        .remove = isp116x_remove,
        .suspend = isp116x_suspend,
        .resume = isp116x_resume,
        .driver = {
-                  .name = (char *)hcd_name,
-                  },
+               .name = (char *)hcd_name,
+               .owner  = THIS_MODULE,
+       },
 };
 
 /*-----------------------------------------------------------------*/
index 126fcbd..d72dc07 100644 (file)
@@ -355,7 +355,7 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
 #define ohci_hcd_at91_drv_resume  NULL
 #endif
 
-MODULE_ALIAS("at91_ohci");
+MODULE_ALIAS("platform:at91_ohci");
 
 static struct platform_driver ohci_hcd_at91_driver = {
        .probe          = ohci_hcd_at91_drv_probe,
@@ -368,4 +368,3 @@ static struct platform_driver ohci_hcd_at91_driver = {
                .owner  = THIS_MODULE,
        },
 };
-
index 663a060..f90fe0c 100644 (file)
@@ -345,3 +345,4 @@ static struct platform_driver ohci_hcd_au1xxx_driver = {
        },
 };
 
+MODULE_ALIAS("platform:au1xxx-ohci");
index a68ce9d..156e93a 100644 (file)
@@ -211,6 +211,8 @@ static struct platform_driver ohci_hcd_ep93xx_driver = {
 #endif
        .driver         = {
                .name   = "ep93xx-ohci",
+               .owner  = THIS_MODULE,
        },
 };
 
+MODULE_ALIAS("platform:ep93xx-ohci");
index 4a043ab..13c12ed 100644 (file)
@@ -251,3 +251,4 @@ static struct platform_driver ohci_hcd_lh7a404_driver = {
        },
 };
 
+MODULE_ALIAS("platform:lh7a404-ohci");
index 74e1f4b..7bfca1e 100644 (file)
@@ -544,3 +544,4 @@ static struct platform_driver ohci_hcd_omap_driver = {
        },
 };
 
+MODULE_ALIAS("platform:ohci");
index 6c52c66..28b458f 100644 (file)
@@ -456,9 +456,13 @@ static int usb_hcd_pnx4008_remove(struct platform_device *pdev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:usb-ohci");
+
 static struct platform_driver usb_hcd_pnx4008_driver = {
        .driver = {
                .name = "usb-ohci",
+               .owner  = THIS_MODULE,
        },
        .probe = usb_hcd_pnx4008_probe,
        .remove = usb_hcd_pnx4008_remove,
index 85fdfd2..605d59c 100644 (file)
@@ -230,11 +230,12 @@ static int ohci_hcd_pnx8550_drv_remove(struct platform_device *pdev)
        return 0;
 }
 
-MODULE_ALIAS("pnx8550-ohci");
+MODULE_ALIAS("platform:pnx8550-ohci");
 
 static struct platform_driver ohci_hcd_pnx8550_driver = {
        .driver = {
-               .name           = "pnx8550-ohci",
+               .name   = "pnx8550-ohci",
+               .owner  = THIS_MODULE,
        },
        .probe          = ohci_hcd_pnx8550_drv_probe,
        .remove         = ohci_hcd_pnx8550_drv_remove,
index f95be18..523c301 100644 (file)
@@ -213,3 +213,4 @@ static struct platform_driver ohci_hcd_ppc_soc_driver = {
        },
 };
 
+MODULE_ALIAS("platform:ppc-soc-ohci");
index ff9a798..8ad9b3b 100644 (file)
@@ -364,6 +364,8 @@ static int ohci_hcd_pxa27x_drv_resume(struct platform_device *pdev)
 }
 #endif
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:pxa27x-ohci");
 
 static struct platform_driver ohci_hcd_pxa27x_driver = {
        .probe          = ohci_hcd_pxa27x_drv_probe,
@@ -375,6 +377,7 @@ static struct platform_driver ohci_hcd_pxa27x_driver = {
 #endif
        .driver         = {
                .name   = "pxa27x-ohci",
+               .owner  = THIS_MODULE,
        },
 };
 
index 44b79e8..ead4772 100644 (file)
@@ -501,3 +501,4 @@ static struct platform_driver ohci_hcd_s3c2410_driver = {
        },
 };
 
+MODULE_ALIAS("platform:s3c2410-ohci");
index 5309ac0..e7ee607 100644 (file)
@@ -141,3 +141,4 @@ static struct platform_driver ohci_hcd_sh_driver = {
        },
 };
 
+MODULE_ALIAS("platform:sh_ohci");
index a970701..4ea9276 100644 (file)
@@ -262,3 +262,4 @@ static struct platform_driver ohci_hcd_sm501_driver = {
                .name   = "sm501-usb",
        },
 };
+MODULE_ALIAS("platform:sm501-usb");
index 0ce2fc5..9f80e52 100644 (file)
@@ -44,6 +44,7 @@
 MODULE_DESCRIPTION("R8A66597 USB Host Controller Driver");
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Yoshihiro Shimoda");
+MODULE_ALIAS("platform:r8a66597_hcd");
 
 #define DRIVER_VERSION "29 May 2007"
 
@@ -2219,6 +2220,7 @@ static struct platform_driver r8a66597_driver = {
        .resume =       r8a66597_resume,
        .driver         = {
                .name = (char *) hcd_name,
+               .owner  = THIS_MODULE,
        },
 };
 
index 59be276..629bca0 100644 (file)
@@ -58,6 +58,7 @@
 
 MODULE_DESCRIPTION("SL811HS USB Host Controller Driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:sl811-hcd");
 
 #define DRIVER_VERSION "19 May 2005"
 
index 3033d69..8e117a7 100644 (file)
@@ -3316,3 +3316,4 @@ static void __exit u132_hcd_exit(void)
 
 module_exit(u132_hcd_exit);
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:u132_hcd");
index a396fbb..d101025 100644 (file)
@@ -109,6 +109,22 @@ static int  option_send_setup(struct usb_serial_port *port);
 #define HUAWEI_PRODUCT_E600                    0x1001
 #define HUAWEI_PRODUCT_E220                    0x1003
 #define HUAWEI_PRODUCT_E220BIS                 0x1004
+#define HUAWEI_PRODUCT_E1401                   0x1401
+#define HUAWEI_PRODUCT_E1403                   0x1403
+#define HUAWEI_PRODUCT_E1405                   0x1405
+#define HUAWEI_PRODUCT_E1406                   0x1406
+#define HUAWEI_PRODUCT_E1408                   0x1408
+#define HUAWEI_PRODUCT_E1409                   0x1409
+#define HUAWEI_PRODUCT_E1410                   0x1410
+#define HUAWEI_PRODUCT_E1411                   0x1411
+#define HUAWEI_PRODUCT_E1412                   0x1412
+#define HUAWEI_PRODUCT_E1413                   0x1413
+#define HUAWEI_PRODUCT_E1414                   0x1414
+#define HUAWEI_PRODUCT_E1415                   0x1415
+#define HUAWEI_PRODUCT_E1416                   0x1416
+#define HUAWEI_PRODUCT_E1417                   0x1417
+#define HUAWEI_PRODUCT_E1418                   0x1418
+#define HUAWEI_PRODUCT_E1419                   0x1419
 
 #define NOVATELWIRELESS_VENDOR_ID              0x1410
 
@@ -129,6 +145,7 @@ static int  option_send_setup(struct usb_serial_port *port);
 #define NOVATELWIRELESS_PRODUCT_EV620          0x2100
 #define NOVATELWIRELESS_PRODUCT_ES720          0x2110
 #define NOVATELWIRELESS_PRODUCT_E725           0x2120
+#define NOVATELWIRELESS_PRODUCT_ES620          0x2130
 #define NOVATELWIRELESS_PRODUCT_EU730          0x2400
 #define NOVATELWIRELESS_PRODUCT_EU740          0x2410
 #define NOVATELWIRELESS_PRODUCT_EU870D         0x2420
@@ -137,6 +154,8 @@ static int  option_send_setup(struct usb_serial_port *port);
 #define NOVATELWIRELESS_PRODUCT_MC727          0x4100
 #define NOVATELWIRELESS_PRODUCT_MC950D         0x4400
 
+#define NOVATELWIRELESS_PRODUCT_U727           0x5010
+
 /* FUTURE NOVATEL PRODUCTS */
 #define NOVATELWIRELESS_PRODUCT_EVDO_1         0x6000
 #define NOVATELWIRELESS_PRODUCT_HSPA_1         0x7000
@@ -147,6 +166,12 @@ static int  option_send_setup(struct usb_serial_port *port);
 #define NOVATELWIRELESS_PRODUCT_EMBEDDED_2     0x8001
 #define NOVATELWIRELESS_PRODUCT_GLOBAL_2       0x9001
 
+/* AMOI PRODUCTS */
+#define AMOI_VENDOR_ID                         0x1614
+#define AMOI_PRODUCT_H01                       0x0800
+#define AMOI_PRODUCT_H01A                      0x7002
+#define AMOI_PRODUCT_H02                       0x0802
+
 #define DELL_VENDOR_ID                         0x413C
 
 #define KYOCERA_VENDOR_ID                      0x0c88
@@ -163,8 +188,13 @@ static int  option_send_setup(struct usb_serial_port *port);
 #define BANDRICH_PRODUCT_C100_1                        0x1002
 #define BANDRICH_PRODUCT_C100_2                        0x1003
 
+#define AMOI_VENDOR_ID                 0x1614
+#define AMOI_PRODUCT_9508                      0x0800
+
 #define QUALCOMM_VENDOR_ID                     0x05C6
 
+#define MAXON_VENDOR_ID                                0x16d8
+
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -204,6 +234,23 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) },
        { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418) },
+       { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419) },
+       { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_9508) },
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, /* Novatel Merlin V640/XV620 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, /* Novatel Merlin V620/S620 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, /* Novatel Merlin EX720/V740/X720 */
@@ -216,13 +263,13 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EV620) }, /* Novatel EV620/ES620 CDMA/EV-DO */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES720) }, /* Novatel ES620/ES720/U720/USB720 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E725) }, /* Novatel E725/E726 */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_ES620) }, /* Novatel Merlin ES620 SM Bus */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU730) }, /* Novatel EU730 and Vodafone EU740 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU740) }, /* Novatel non-Vodafone EU740 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EU870D) }, /* Novatel EU850D/EU860D/EU870D */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC950D) }, /* Novatel MC930D/MC950D */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC727) }, /* Novatel MC727/U727/USB727 */
-       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x5010) }, /* Novatel U727 */
+       { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_U727) }, /* Novatel U727 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EVDO_1) }, /* Novatel EVDO product */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_HSPA_1) }, /* Novatel HSPA product */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_1) }, /* Novatel Embedded product */
@@ -232,6 +279,10 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_EMBEDDED_2) }, /* Novatel Embedded product */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_GLOBAL_2) }, /* Novatel Global product */
 
+       { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
+       { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
+       { USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H02) },
+
        { 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 */
@@ -249,6 +300,7 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
        { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_PRODUCT_KPC680) },
        { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
+       { USB_DEVICE(MAXON_VENDOR_ID, 0x6280) }, /* BP3-USB & BP3-EXT HSDPA */
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index 3ce98e8..2138ba8 100644 (file)
@@ -854,6 +854,7 @@ int usb_serial_probe(struct usb_interface *interface,
        serial->num_interrupt_in = num_interrupt_in;
        serial->num_interrupt_out = num_interrupt_out;
 
+#if 0
        /* check that the device meets the driver's requirements */
        if ((type->num_interrupt_in != NUM_DONT_CARE &&
                                type->num_interrupt_in != num_interrupt_in)
@@ -867,6 +868,7 @@ int usb_serial_probe(struct usb_interface *interface,
                kfree(serial);
                return -EIO;
        }
+#endif
 
        /* found all that we need */
        dev_info(&interface->dev, "%s converter detected\n",
index e5219a5..9125207 100644 (file)
@@ -1530,16 +1530,104 @@ UNUSUAL_DEV(  0x1210, 0x0003, 0x0100, 0x0100,
                US_SC_DEVICE, US_PR_DEVICE, NULL,
                US_FL_IGNORE_RESIDUE ),
 
-/* Reported by fangxiaozhi <fangxiaozhi60675@huawei.com>
- * and by linlei <linlei83@huawei.com>
- * Patch reworked by Johann Wilhelm <johann.wilhelm@student.tugraz.at>
- * This brings the HUAWEI E220 devices into multi-port mode
+/* Reported by fangxiaozhi <huananhu@huawei.com>
+ * This brings the HUAWEI data card devices into multi-port mode
  */
+UNUSUAL_DEV( 0x12d1, 0x1001, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
 UNUSUAL_DEV( 0x12d1, 0x1003, 0x0000, 0x0000,
                "HUAWEI MOBILE",
                "Mass Storage",
                US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
                0),
+UNUSUAL_DEV( 0x12d1, 0x1004, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1401, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1403, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1405, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1406, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1408, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1409, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1410, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1411, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1412, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1413, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1414, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1415, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1416, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1417, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1418, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
+UNUSUAL_DEV( 0x12d1, 0x1419, 0x0000, 0x0000,
+               "HUAWEI MOBILE",
+               "Mass Storage",
+               US_SC_DEVICE, US_PR_DEVICE, usb_stor_huawei_e220_init,
+               0),
 
 /* Reported by Vilius Bilinkevicius <vilisas AT xxx DOT lt) */
 UNUSUAL_DEV(  0x132b, 0x000b, 0x0001, 0x0001,
index 1194f5e..01072f4 100644 (file)
@@ -1521,6 +1521,7 @@ module_init(fbmem_init);
 static void __exit
 fbmem_exit(void)
 {
+       remove_proc_entry("fb", NULL);
        class_destroy(fb_class);
        unregister_chrdev(FB_MAJOR, "fb");
 }
index fb5ed64..ae0fca5 100644 (file)
@@ -418,6 +418,9 @@ static int at32_wdt_resume(struct platform_device *pdev)
 #define at32_wdt_resume NULL
 #endif
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:at32_wdt");
+
 static struct platform_driver at32_wdt_driver = {
        .remove         = __exit_p(at32_wdt_remove),
        .suspend        = at32_wdt_suspend,
index a684b1e..9ff9a95 100644 (file)
@@ -286,3 +286,4 @@ MODULE_AUTHOR("Andrew Victor");
 MODULE_DESCRIPTION("Watchdog driver for Atmel AT91RM9200");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:at91_wdt");
index a61cbd4..1782c79 100644 (file)
@@ -248,6 +248,7 @@ static int davinci_wdt_remove(struct platform_device *pdev)
 static struct platform_driver platform_wdt_driver = {
        .driver = {
                .name = "watchdog",
+               .owner  = THIS_MODULE,
        },
        .probe = davinci_wdt_probe,
        .remove = davinci_wdt_remove,
@@ -277,3 +278,4 @@ MODULE_PARM_DESC(heartbeat,
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:watchdog");
index e3a29c3..df5a6b8 100644 (file)
@@ -306,3 +306,4 @@ MODULE_AUTHOR("Andrew Victor");
 MODULE_DESCRIPTION("Watchdog driver for KS8695");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:ks8695_wdt");
index 6369f56..b16c5cd 100644 (file)
@@ -206,6 +206,7 @@ static struct platform_driver mpc83xx_wdt_driver = {
        .remove         = __devexit_p(mpc83xx_wdt_remove),
        .driver         = {
                .name   = "mpc83xx_wdt",
+               .owner  = THIS_MODULE,
        },
 };
 
@@ -226,3 +227,4 @@ MODULE_AUTHOR("Dave Updegraff, Kumar Gala");
 MODULE_DESCRIPTION("Driver for watchdog timer in MPC83xx uProcessor");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:mpc83xx_wdt");
index 0d2b277..009573b 100644 (file)
@@ -392,6 +392,9 @@ static int __devexit mpcore_wdt_remove(struct platform_device *dev)
        return 0;
 }
 
+/* work with hotplug and coldplug */
+MODULE_ALIAS("platform:mpcore_wdt");
+
 static struct platform_driver mpcore_wdt_driver = {
        .probe          = mpcore_wdt_probe,
        .remove         = __devexit_p(mpcore_wdt_remove),
index 10b89f2..a8e6738 100644 (file)
@@ -243,6 +243,7 @@ static struct platform_driver mtx1_wdt = {
        .probe = mtx1_wdt_probe,
        .remove = mtx1_wdt_remove,
        .driver.name = "mtx1-wdt",
+       .driver.owner = THIS_MODULE,
 };
 
 static int __init mtx1_wdt_init(void)
@@ -262,3 +263,4 @@ MODULE_AUTHOR("Michael Stickel, Florian Fainelli");
 MODULE_DESCRIPTION("Driver for the MTX-1 watchdog");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:mtx1-wdt");
index 0365c31..b59ca32 100644 (file)
@@ -324,3 +324,4 @@ MODULE_AUTHOR("James Chapman <jchapman@katalix.com>");
 MODULE_DESCRIPTION("MV64x60 watchdog driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:" MV64x60_WDT_NAME);
index 635ca45..74bc39a 100644 (file)
@@ -387,3 +387,4 @@ module_exit(omap_wdt_exit);
 MODULE_AUTHOR("George G. Davis");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:omap_wdt");
index b04aa09..6b8483d 100644 (file)
@@ -321,6 +321,7 @@ static int pnx4008_wdt_remove(struct platform_device *pdev)
 static struct platform_driver platform_wdt_driver = {
        .driver = {
                .name = "watchdog",
+               .owner  = THIS_MODULE,
        },
        .probe = pnx4008_wdt_probe,
        .remove = pnx4008_wdt_remove,
@@ -354,3 +355,4 @@ MODULE_PARM_DESC(nowayout,
 
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:watchdog");
index 7645e88..98532c0 100644 (file)
@@ -561,3 +561,4 @@ MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>, "
 MODULE_DESCRIPTION("S3C2410 Watchdog Device Driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:s3c2410-wdt");
index 328b3c7..57cefef 100644 (file)
@@ -274,3 +274,4 @@ module_exit(watchdog_exit);
 MODULE_DESCRIPTION("TXx9 Watchdog Driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform:txx9wdt");
index d731282..c509123 100644 (file)
@@ -1744,10 +1744,10 @@ config ROOT_NFS
          If you want your Linux box to mount its whole root file system (the
          one containing the directory /) from some other computer over the
          net via NFS (presumably because your box doesn't have a hard disk),
-         say Y. Read <file:Documentation/nfsroot.txt> for details. It is
-         likely that in this case, you also want to say Y to "Kernel level IP
-         autoconfiguration" so that your box can discover its network address
-         at boot time.
+         say Y. Read <file:Documentation/filesystems/nfsroot.txt> for
+         details. It is likely that in this case, you also want to say Y to
+         "Kernel level IP autoconfiguration" so that your box can discover
+         its network address at boot time.
 
          Most people say N here.
 
index 0f60f6b..2d3e5d4 100644 (file)
@@ -22,7 +22,7 @@ MODULE_LICENSE("GPL");
 
 unsigned afs_debug;
 module_param_named(debug, afs_debug, uint, S_IWUSR | S_IRUGO);
-MODULE_PARM_DESC(afs_debug, "AFS debugging mask");
+MODULE_PARM_DESC(debug, "AFS debugging mask");
 
 static char *rootcell;
 
index 6af9219..2283686 100644 (file)
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -936,14 +936,6 @@ int aio_complete(struct kiocb *iocb, long res, long res2)
                return 1;
        }
 
-       /*
-        * Check if the user asked us to deliver the result through an
-        * eventfd. The eventfd_signal() function is safe to be called
-        * from IRQ context.
-        */
-       if (!IS_ERR(iocb->ki_eventfd))
-               eventfd_signal(iocb->ki_eventfd, 1);
-
        info = &ctx->ring_info;
 
        /* add a completion event to the ring buffer.
@@ -992,6 +984,15 @@ int aio_complete(struct kiocb *iocb, long res, long res2)
        kunmap_atomic(ring, KM_IRQ1);
 
        pr_debug("added to ring %p at [%lu]\n", iocb, tail);
+
+       /*
+        * Check if the user asked us to deliver the result through an
+        * eventfd. The eventfd_signal() function is safe to be called
+        * from IRQ context.
+        */
+       if (!IS_ERR(iocb->ki_eventfd))
+               eventfd_signal(iocb->ki_eventfd, 1);
+
 put_rq:
        /* everything turned out well, dispose of the aiocb. */
        ret = __aio_put_req(ctx, iocb);
@@ -1790,6 +1791,7 @@ asmlinkage long sys_io_getevents(aio_context_t ctx_id,
                put_ioctx(ioctx);
        }
 
+       asmlinkage_protect(5, ret, ctx_id, min_nr, nr, events, timeout);
        return ret;
 }
 
index 3e8683d..a99d46f 100644 (file)
@@ -835,7 +835,7 @@ ext2_xattr_cache_insert(struct buffer_head *bh)
        struct mb_cache_entry *ce;
        int error;
 
-       ce = mb_cache_entry_alloc(ext2_xattr_cache);
+       ce = mb_cache_entry_alloc(ext2_xattr_cache, GFP_NOFS);
        if (!ce)
                return -ENOMEM;
        error = mb_cache_entry_insert(ce, bh->b_bdev, bh->b_blocknr, &hash);
index a6ea4d6..4285654 100644 (file)
@@ -1126,7 +1126,7 @@ ext3_xattr_cache_insert(struct buffer_head *bh)
        struct mb_cache_entry *ce;
        int error;
 
-       ce = mb_cache_entry_alloc(ext3_xattr_cache);
+       ce = mb_cache_entry_alloc(ext3_xattr_cache, GFP_NOFS);
        if (!ce) {
                ea_bdebug(bh, "out of memory");
                return;
index d796213..e9054c1 100644 (file)
@@ -1386,7 +1386,7 @@ ext4_xattr_cache_insert(struct buffer_head *bh)
        struct mb_cache_entry *ce;
        int error;
 
-       ce = mb_cache_entry_alloc(ext4_xattr_cache);
+       ce = mb_cache_entry_alloc(ext4_xattr_cache, GFP_NOFS);
        if (!ce) {
                ea_bdebug(bh, "out of memory");
                return;
index 2968364..5f40236 100644 (file)
@@ -340,16 +340,23 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry)
 
        if (inode->i_nlink > 0)
                drop_nlink(inode);
-       hfsplus_delete_inode(inode);
-       if (inode->i_ino != cnid && !inode->i_nlink) {
-               if (!atomic_read(&HFSPLUS_I(inode).opencnt)) {
-                       res = hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL);
-                       if (!res)
-                               hfsplus_delete_inode(inode);
+       if (inode->i_ino == cnid)
+               clear_nlink(inode);
+       if (!inode->i_nlink) {
+               if (inode->i_ino != cnid) {
+                       HFSPLUS_SB(sb).file_count--;
+                       if (!atomic_read(&HFSPLUS_I(inode).opencnt)) {
+                               res = hfsplus_delete_cat(inode->i_ino,
+                                                        HFSPLUS_SB(sb).hidden_dir,
+                                                        NULL);
+                               if (!res)
+                                       hfsplus_delete_inode(inode);
+                       } else
+                               inode->i_flags |= S_DEAD;
                } else
-                       inode->i_flags |= S_DEAD;
+                       hfsplus_delete_inode(inode);
        } else
-               clear_nlink(inode);
+               HFSPLUS_SB(sb).file_count--;
        inode->i_ctime = CURRENT_TIME_SEC;
        mark_inode_dirty(inode);
 
index f9c5dd6..dcc2734 100644 (file)
@@ -129,7 +129,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
        struct inode *inode = mapping->host;
        struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
        pgoff_t index = pos >> PAGE_CACHE_SHIFT;
-       uint32_t pageofs = pos & (PAGE_CACHE_SIZE - 1);
+       uint32_t pageofs = index << PAGE_CACHE_SHIFT;
        int ret = 0;
 
        pg = __grab_cache_page(mapping, index);
index d83fab1..43c0af2 100644 (file)
@@ -1801,17 +1801,21 @@ again:
        if (error)
                goto out;
 
-       for (;;) {
-               error = vfs_lock_file(filp, cmd, file_lock, NULL);
-               if (error != -EAGAIN || cmd == F_SETLK)
-                       break;
-               error = wait_event_interruptible(file_lock->fl_wait,
-                               !file_lock->fl_next);
-               if (!error)
-                       continue;
+       if (filp->f_op && filp->f_op->lock != NULL)
+               error = filp->f_op->lock(filp, cmd, file_lock);
+       else {
+               for (;;) {
+                       error = posix_lock_file(filp, file_lock, NULL);
+                       if (error != -EAGAIN || cmd == F_SETLK)
+                               break;
+                       error = wait_event_interruptible(file_lock->fl_wait,
+                                       !file_lock->fl_next);
+                       if (!error)
+                               continue;
 
-               locks_delete_block(file_lock);
-               break;
+                       locks_delete_block(file_lock);
+                       break;
+               }
        }
 
        /*
@@ -1925,17 +1929,21 @@ again:
        if (error)
                goto out;
 
-       for (;;) {
-               error = vfs_lock_file(filp, cmd, file_lock, NULL);
-               if (error != -EAGAIN || cmd == F_SETLK64)
-                       break;
-               error = wait_event_interruptible(file_lock->fl_wait,
-                               !file_lock->fl_next);
-               if (!error)
-                       continue;
+       if (filp->f_op && filp->f_op->lock != NULL)
+               error = filp->f_op->lock(filp, cmd, file_lock);
+       else {
+               for (;;) {
+                       error = posix_lock_file(filp, file_lock, NULL);
+                       if (error != -EAGAIN || cmd == F_SETLK64)
+                               break;
+                       error = wait_event_interruptible(file_lock->fl_wait,
+                                       !file_lock->fl_next);
+                       if (!error)
+                               continue;
 
-               locks_delete_block(file_lock);
-               break;
+                       locks_delete_block(file_lock);
+                       break;
+               }
        }
 
        /*
index eb31b73..ec88ff3 100644 (file)
@@ -399,11 +399,11 @@ mb_cache_destroy(struct mb_cache *cache)
  * if no more memory was available.
  */
 struct mb_cache_entry *
-mb_cache_entry_alloc(struct mb_cache *cache)
+mb_cache_entry_alloc(struct mb_cache *cache, gfp_t gfp_flags)
 {
        struct mb_cache_entry *ce;
 
-       ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL);
+       ce = kmem_cache_alloc(cache->c_entry_cache, gfp_flags);
        if (ce) {
                atomic_inc(&cache->c_entry_count);
                INIT_LIST_HEAD(&ce->e_lru_list);
index ef57a5a..5d2e9d9 100644 (file)
@@ -64,7 +64,11 @@ const struct file_operations nfs_file_operations = {
        .write          = do_sync_write,
        .aio_read       = nfs_file_read,
        .aio_write      = nfs_file_write,
+#ifdef CONFIG_MMU
        .mmap           = nfs_file_mmap,
+#else
+       .mmap           = generic_file_mmap,
+#endif
        .open           = nfs_file_open,
        .flush          = nfs_file_flush,
        .release        = nfs_file_release,
index a4c7cf2..6f88d7c 100644 (file)
@@ -506,6 +506,7 @@ static struct nfs_open_context *alloc_nfs_open_context(struct vfsmount *mnt, str
                ctx->cred = get_rpccred(cred);
                ctx->state = NULL;
                ctx->lockowner = current->files;
+               ctx->flags = 0;
                ctx->error = 0;
                ctx->dir_cookie = 0;
                atomic_set(&ctx->count, 1);
index a4b1202..3fa4e4f 100644 (file)
--- a/fs/open.c
+++ b/fs/open.c
@@ -335,7 +335,7 @@ asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length)
 {
        long ret = do_sys_ftruncate(fd, length, 1);
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(2, ret, fd, length);
        return ret;
 }
 
@@ -350,7 +350,7 @@ asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length)
 {
        long ret = do_sys_ftruncate(fd, length, 0);
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(2, ret, fd, length);
        return ret;
 }
 #endif
@@ -1067,7 +1067,7 @@ asmlinkage long sys_open(const char __user *filename, int flags, int mode)
 
        ret = do_sys_open(AT_FDCWD, filename, flags, mode);
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(3, ret, filename, flags, mode);
        return ret;
 }
 
@@ -1081,7 +1081,7 @@ asmlinkage long sys_openat(int dfd, const char __user *filename, int flags,
 
        ret = do_sys_open(dfd, filename, flags, mode);
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(4, ret, dfd, filename, flags, mode);
        return ret;
 }
 
index cb2b63a..8ead0db 100644 (file)
@@ -111,9 +111,14 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
                err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
                err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
                break;
-       default: /* this is just in case for now ... */
+       default:
+               /*
+                * This case catches also the signals queued by sigqueue().
+                */
                err |= __put_user(kinfo->si_pid, &uinfo->ssi_pid);
                err |= __put_user(kinfo->si_uid, &uinfo->ssi_uid);
+               err |= __put_user((long) kinfo->si_ptr, &uinfo->ssi_ptr);
+               err |= __put_user(kinfo->si_int, &uinfo->ssi_int);
                break;
        }
 
index a861bb3..eeb1a86 100644 (file)
@@ -370,8 +370,10 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
                         * for an in-flight io page
                         */
                        if (flags & SPLICE_F_NONBLOCK) {
-                               if (TestSetPageLocked(page))
+                               if (TestSetPageLocked(page)) {
+                                       error = -EAGAIN;
                                        break;
+                               }
                        } else
                                lock_page(page);
 
@@ -479,9 +481,8 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
                                 struct pipe_inode_info *pipe, size_t len,
                                 unsigned int flags)
 {
-       ssize_t spliced;
-       int ret;
        loff_t isize, left;
+       int ret;
 
        isize = i_size_read(in->f_mapping->host);
        if (unlikely(*ppos >= isize))
@@ -491,29 +492,9 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
        if (unlikely(left < len))
                len = left;
 
-       ret = 0;
-       spliced = 0;
-       while (len && !spliced) {
-               ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
-
-               if (ret < 0)
-                       break;
-               else if (!ret) {
-                       if (spliced)
-                               break;
-                       if (flags & SPLICE_F_NONBLOCK) {
-                               ret = -EAGAIN;
-                               break;
-                       }
-               }
-
+       ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
+       if (ret > 0)
                *ppos += ret;
-               len -= ret;
-               spliced += ret;
-       }
-
-       if (spliced)
-               return spliced;
 
        return ret;
 }
index a9952e4..f34bd01 100644 (file)
@@ -732,7 +732,7 @@ xfs_ioctl(
                 * Only allow the sys admin to reserve space unless
                 * unwritten extents are enabled.
                 */
-               if (!XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) &&
+               if (!xfs_sb_version_hasextflgbit(&mp->m_sb) &&
                    !capable(CAP_SYS_ADMIN))
                        return -EPERM;
 
index 1f3da5b..8e9c5ae 100644 (file)
@@ -1405,13 +1405,13 @@ xfs_qm_qino_alloc(
 #if defined(DEBUG) && defined(XFS_LOUD_RECOVERY)
                unsigned oldv = mp->m_sb.sb_versionnum;
 #endif
-               ASSERT(!XFS_SB_VERSION_HASQUOTA(&mp->m_sb));
+               ASSERT(!xfs_sb_version_hasquota(&mp->m_sb));
                ASSERT((sbfields & (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
                                   XFS_SB_GQUOTINO | XFS_SB_QFLAGS)) ==
                       (XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO |
                        XFS_SB_GQUOTINO | XFS_SB_QFLAGS));
 
-               XFS_SB_VERSION_ADDQUOTA(&mp->m_sb);
+               xfs_sb_version_addquota(&mp->m_sb);
                mp->m_sb.sb_uquotino = NULLFSINO;
                mp->m_sb.sb_gquotino = NULLFSINO;
 
@@ -1954,7 +1954,7 @@ xfs_qm_init_quotainos(
        /*
         * Get the uquota and gquota inodes
         */
-       if (XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) {
+       if (xfs_sb_version_hasquota(&mp->m_sb)) {
                if (XFS_IS_UQUOTA_ON(mp) &&
                    mp->m_sb.sb_uquotino != NULLFSINO) {
                        ASSERT(mp->m_sb.sb_uquotino > 0);
index 97bb329..f4f6c4c 100644 (file)
@@ -118,7 +118,7 @@ xfs_qm_newmount(
        *quotaflags = 0;
        *needquotamount = B_FALSE;
 
-       quotaondisk = XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
+       quotaondisk = xfs_sb_version_hasquota(&mp->m_sb) &&
                                (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
 
        if (quotaondisk) {
index 2cc5886..d2b8be7 100644 (file)
@@ -377,7 +377,7 @@ xfs_qm_scall_trunc_qfiles(
        if (!capable(CAP_SYS_ADMIN))
                return XFS_ERROR(EPERM);
        error = 0;
-       if (!XFS_SB_VERSION_HASQUOTA(&mp->m_sb) || flags == 0) {
+       if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0) {
                qdprintk("qtrunc flags=%x m_qflags=%x\n", flags, mp->m_qflags);
                return XFS_ERROR(EINVAL);
        }
@@ -522,7 +522,7 @@ xfs_qm_scall_getqstat(
        memset(out, 0, sizeof(fs_quota_stat_t));
 
        out->qs_version = FS_QSTAT_VERSION;
-       if (! XFS_SB_VERSION_HASQUOTA(&mp->m_sb)) {
+       if (!xfs_sb_version_hasquota(&mp->m_sb)) {
                out->qs_uquota.qfs_ino = NULLFSINO;
                out->qs_gquota.qfs_ino = NULLFSINO;
                return (0);
index b08e2a2..96ba6aa 100644 (file)
@@ -227,10 +227,10 @@ STATIC void
 xfs_sbversion_add_attr2(xfs_mount_t *mp, xfs_trans_t *tp)
 {
        if ((mp->m_flags & XFS_MOUNT_ATTR2) &&
-           !(XFS_SB_VERSION_HASATTR2(&mp->m_sb))) {
+           !(xfs_sb_version_hasattr2(&mp->m_sb))) {
                spin_lock(&mp->m_sb_lock);
-               if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
-                       XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
+               if (!xfs_sb_version_hasattr2(&mp->m_sb)) {
+                       xfs_sb_version_addattr2(&mp->m_sb);
                        spin_unlock(&mp->m_sb_lock);
                        xfs_mod_sb(tp, XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
                } else
index 1c0a5a5..2def273 100644 (file)
@@ -4047,17 +4047,17 @@ xfs_bmap_add_attrfork(
                xfs_trans_log_inode(tp, ip, logflags);
        if (error)
                goto error2;
-       if (!XFS_SB_VERSION_HASATTR(&mp->m_sb) ||
-          (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2)) {
+       if (!xfs_sb_version_hasattr(&mp->m_sb) ||
+          (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2)) {
                __int64_t sbfields = 0;
 
                spin_lock(&mp->m_sb_lock);
-               if (!XFS_SB_VERSION_HASATTR(&mp->m_sb)) {
-                       XFS_SB_VERSION_ADDATTR(&mp->m_sb);
+               if (!xfs_sb_version_hasattr(&mp->m_sb)) {
+                       xfs_sb_version_addattr(&mp->m_sb);
                        sbfields |= XFS_SB_VERSIONNUM;
                }
-               if (!XFS_SB_VERSION_HASATTR2(&mp->m_sb) && version == 2) {
-                       XFS_SB_VERSION_ADDATTR2(&mp->m_sb);
+               if (!xfs_sb_version_hasattr2(&mp->m_sb) && version == 2) {
+                       xfs_sb_version_addattr2(&mp->m_sb);
                        sbfields |= (XFS_SB_VERSIONNUM | XFS_SB_FEATURES2);
                }
                if (sbfields) {
@@ -5043,7 +5043,7 @@ xfs_bmapi(
                         * A wasdelay extent has been initialized, so
                         * shouldn't be flagged as unwritten.
                         */
-                       if (wr && XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
+                       if (wr && xfs_sb_version_hasextflgbit(&mp->m_sb)) {
                                if (!wasdelay && (flags & XFS_BMAPI_PREALLOC))
                                        got.br_state = XFS_EXT_UNWRITTEN;
                        }
@@ -5483,7 +5483,7 @@ xfs_bunmapi(
                         * get rid of part of a realtime extent.
                         */
                        if (del.br_state == XFS_EXT_UNWRITTEN ||
-                           !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
+                           !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
                                /*
                                 * This piece is unwritten, or we're not
                                 * using unwritten extents.  Skip over it.
@@ -5535,7 +5535,7 @@ xfs_bunmapi(
                        } else if ((del.br_startoff == start &&
                                    (del.br_state == XFS_EXT_UNWRITTEN ||
                                     xfs_trans_get_block_res(tp) == 0)) ||
-                                  !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
+                                  !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
                                /*
                                 * Can't make it unwritten.  There isn't
                                 * a full extent here so just skip it.
index 2d950e9..cd0d4b4 100644 (file)
@@ -120,7 +120,7 @@ typedef enum {
  * Extent state and extent format macros.
  */
 #define XFS_EXTFMT_INODE(x)    \
-       (XFS_SB_VERSION_HASEXTFLGBIT(&((x)->i_mount->m_sb)) ? \
+       (xfs_sb_version_hasextflgbit(&((x)->i_mount->m_sb)) ? \
                XFS_EXTFMT_HASSTATE : XFS_EXTFMT_NOSTATE)
 #define ISUNWRITTEN(x) ((x)->br_state == XFS_EXT_UNWRITTEN)
 
index be7c425..e92e73f 100644 (file)
@@ -49,7 +49,7 @@ void
 xfs_dir_mount(
        xfs_mount_t     *mp)
 {
-       ASSERT(XFS_SB_VERSION_HASDIRV2(&mp->m_sb));
+       ASSERT(xfs_sb_version_hasdirv2(&mp->m_sb));
        ASSERT((1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog)) <=
               XFS_MAX_BLOCKSIZE);
        mp->m_dirblksize = 1 << (mp->m_sb.sb_blocklog + mp->m_sb.sb_dirblklog);
index eadc159..d3a0f53 100644 (file)
@@ -77,36 +77,36 @@ xfs_fs_geometry(
        if (new_version >= 3) {
                geo->version = XFS_FSOP_GEOM_VERSION;
                geo->flags =
-                       (XFS_SB_VERSION_HASATTR(&mp->m_sb) ?
+                       (xfs_sb_version_hasattr(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_ATTR : 0) |
-                       (XFS_SB_VERSION_HASNLINK(&mp->m_sb) ?
+                       (xfs_sb_version_hasnlink(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_NLINK : 0) |
-                       (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) ?
+                       (xfs_sb_version_hasquota(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_QUOTA : 0) |
-                       (XFS_SB_VERSION_HASALIGN(&mp->m_sb) ?
+                       (xfs_sb_version_hasalign(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_IALIGN : 0) |
-                       (XFS_SB_VERSION_HASDALIGN(&mp->m_sb) ?
+                       (xfs_sb_version_hasdalign(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_DALIGN : 0) |
-                       (XFS_SB_VERSION_HASSHARED(&mp->m_sb) ?
+                       (xfs_sb_version_hasshared(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_SHARED : 0) |
-                       (XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb) ?
+                       (xfs_sb_version_hasextflgbit(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_EXTFLG : 0) |
-                       (XFS_SB_VERSION_HASDIRV2(&mp->m_sb) ?
+                       (xfs_sb_version_hasdirv2(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_DIRV2 : 0) |
-                       (XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
+                       (xfs_sb_version_hassector(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_SECTOR : 0) |
                        (xfs_sb_version_haslazysbcount(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_LAZYSB : 0) |
-                       (XFS_SB_VERSION_HASATTR2(&mp->m_sb) ?
+                       (xfs_sb_version_hasattr2(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_ATTR2 : 0);
-               geo->logsectsize = XFS_SB_VERSION_HASSECTOR(&mp->m_sb) ?
+               geo->logsectsize = xfs_sb_version_hassector(&mp->m_sb) ?
                                mp->m_sb.sb_logsectsize : BBSIZE;
                geo->rtsectsize = mp->m_sb.sb_blocksize;
                geo->dirblocksize = mp->m_dirblksize;
        }
        if (new_version >= 4) {
                geo->flags |=
-                       (XFS_SB_VERSION_HASLOGV2(&mp->m_sb) ?
+                       (xfs_sb_version_haslogv2(&mp->m_sb) ?
                                XFS_FSOP_GEOM_FLAGS_LOGV2 : 0);
                geo->logsunit = mp->m_sb.sb_logsunit;
        }
index db9d5fa..5a146cb 100644 (file)
@@ -191,7 +191,7 @@ xfs_ialloc_ag_alloc(
                        ASSERT(!(args.mp->m_flags & XFS_MOUNT_NOALIGN));
                        args.alignment = args.mp->m_dalign;
                        isaligned = 1;
-               } else if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
+               } else if (xfs_sb_version_hasalign(&args.mp->m_sb) &&
                           args.mp->m_sb.sb_inoalignmt >=
                           XFS_B_TO_FSBT(args.mp,
                                XFS_INODE_CLUSTER_SIZE(args.mp)))
@@ -230,7 +230,7 @@ xfs_ialloc_ag_alloc(
                args.agbno = be32_to_cpu(agi->agi_root);
                args.fsbno = XFS_AGB_TO_FSB(args.mp,
                                be32_to_cpu(agi->agi_seqno), args.agbno);
-               if (XFS_SB_VERSION_HASALIGN(&args.mp->m_sb) &&
+               if (xfs_sb_version_hasalign(&args.mp->m_sb) &&
                        args.mp->m_sb.sb_inoalignmt >=
                        XFS_B_TO_FSBT(args.mp, XFS_INODE_CLUSTER_SIZE(args.mp)))
                                args.alignment = args.mp->m_sb.sb_inoalignmt;
@@ -271,7 +271,7 @@ xfs_ialloc_ag_alloc(
         * use the old version so that old kernels will continue to be
         * able to use the file system.
         */
-       if (XFS_SB_VERSION_HASNLINK(&args.mp->m_sb))
+       if (xfs_sb_version_hasnlink(&args.mp->m_sb))
                version = XFS_DINODE_VERSION_2;
        else
                version = XFS_DINODE_VERSION_1;
index a550546..f43a6e0 100644 (file)
@@ -1147,7 +1147,7 @@ xfs_ialloc(
         * the inode version number now.  This way we only do the conversion
         * here rather than here and in the flush/logging code.
         */
-       if (XFS_SB_VERSION_HASNLINK(&tp->t_mountp->m_sb) &&
+       if (xfs_sb_version_hasnlink(&tp->t_mountp->m_sb) &&
            ip->i_d.di_version == XFS_DINODE_VERSION_1) {
                ip->i_d.di_version = XFS_DINODE_VERSION_2;
                /*
@@ -3434,9 +3434,9 @@ xfs_iflush_int(
         * has been updated, then make the conversion permanent.
         */
        ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 ||
-              XFS_SB_VERSION_HASNLINK(&mp->m_sb));
+              xfs_sb_version_hasnlink(&mp->m_sb));
        if (ip->i_d.di_version == XFS_DINODE_VERSION_1) {
-               if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
+               if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
                        /*
                         * Convert it back.
                         */
index 034ca72..2c775b4 100644 (file)
@@ -296,9 +296,9 @@ xfs_inode_item_format(
         */
        mp = ip->i_mount;
        ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 ||
-              XFS_SB_VERSION_HASNLINK(&mp->m_sb));
+              xfs_sb_version_hasnlink(&mp->m_sb));
        if (ip->i_d.di_version == XFS_DINODE_VERSION_1) {
-               if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
+               if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
                        /*
                         * Convert it back.
                         */
index 658aab6..f615e04 100644 (file)
@@ -45,7 +45,7 @@ xfs_internal_inum(
        xfs_ino_t       ino)
 {
        return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino ||
-               (XFS_SB_VERSION_HASQUOTA(&mp->m_sb) &&
+               (xfs_sb_version_hasquota(&mp->m_sb) &&
                 (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)));
 }
 
index a75edca..31f2b04 100644 (file)
@@ -1090,7 +1090,7 @@ xlog_get_iclog_buffer_size(xfs_mount_t    *mp,
                        size >>= 1;
                }
 
-               if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
+               if (xfs_sb_version_haslogv2(&mp->m_sb)) {
                        /* # headers = size / 32K
                         * one header holds cycles from 32K of data
                         */
@@ -1186,13 +1186,13 @@ xlog_alloc_log(xfs_mount_t      *mp,
        log->l_grant_reserve_cycle = 1;
        log->l_grant_write_cycle = 1;
 
-       if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb)) {
+       if (xfs_sb_version_hassector(&mp->m_sb)) {
                log->l_sectbb_log = mp->m_sb.sb_logsectlog - BBSHIFT;
                ASSERT(log->l_sectbb_log <= mp->m_sectbb_log);
                /* for larger sector sizes, must have v2 or external log */
                ASSERT(log->l_sectbb_log == 0 ||
                        log->l_logBBstart == 0 ||
-                       XFS_SB_VERSION_HASLOGV2(&mp->m_sb));
+                       xfs_sb_version_haslogv2(&mp->m_sb));
                ASSERT(mp->m_sb.sb_logsectlog >= BBSHIFT);
        }
        log->l_sectbb_mask = (1 << log->l_sectbb_log) - 1;
@@ -1247,7 +1247,7 @@ xlog_alloc_log(xfs_mount_t        *mp,
                memset(head, 0, sizeof(xlog_rec_header_t));
                head->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
                head->h_version = cpu_to_be32(
-                       XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
+                       xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1);
                head->h_size = cpu_to_be32(log->l_iclog_size);
                /* new fields */
                head->h_fmt = cpu_to_be32(XLOG_FMT);
@@ -1402,7 +1402,7 @@ xlog_sync(xlog_t          *log,
        int             roundoff;       /* roundoff to BB or stripe */
        int             split = 0;      /* split write into two regions */
        int             error;
-       int             v2 = XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb);
+       int             v2 = xfs_sb_version_haslogv2(&log->l_mp->m_sb);
 
        XFS_STATS_INC(xs_log_writes);
        ASSERT(iclog->ic_refcnt == 0);
@@ -2881,7 +2881,7 @@ xlog_state_switch_iclogs(xlog_t           *log,
        log->l_curr_block += BTOBB(eventual_size)+BTOBB(log->l_iclog_hsize);
 
        /* Round up to next log-sunit */
-       if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
+       if (xfs_sb_version_haslogv2(&log->l_mp->m_sb) &&
            log->l_mp->m_sb.sb_logsunit > 1) {
                __uint32_t sunit_bb = BTOBB(log->l_mp->m_sb.sb_logsunit);
                log->l_curr_block = roundup(log->l_curr_block, sunit_bb);
@@ -3334,7 +3334,7 @@ xlog_ticket_get(xlog_t            *log,
        unit_bytes += sizeof(xlog_op_header_t) * num_headers;
 
        /* for roundoff padding for transaction data and one for commit record */
-       if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) &&
+       if (xfs_sb_version_haslogv2(&log->l_mp->m_sb) &&
            log->l_mp->m_sb.sb_logsunit > 1) {
                /* log su roundoff */
                unit_bytes += 2*log->l_mp->m_sb.sb_logsunit;
index e008233..c6244cc 100644 (file)
@@ -49,10 +49,10 @@ struct xfs_mount;
 #define XLOG_HEADER_SIZE       512
 
 #define XLOG_REC_SHIFT(log) \
-       BTOBB(1 << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \
+       BTOBB(1 << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \
         XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
 #define XLOG_TOTAL_REC_SHIFT(log) \
-       BTOBB(XLOG_MAX_ICLOGS << (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? \
+       BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \
         XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT))
 
 
index b82d5d4..b2b70eb 100644 (file)
@@ -478,7 +478,7 @@ xlog_find_verify_log_record(
         * reset last_blk.  Only when last_blk points in the middle of a log
         * record do we update last_blk.
         */
-       if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+       if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
                uint    h_size = be32_to_cpu(head->h_size);
 
                xhdrs = h_size / XLOG_HEADER_CYCLE_SIZE;
@@ -888,7 +888,7 @@ xlog_find_tail(
         * unmount record if there is one, so we pass the lsn of the
         * unmount record rather than the block after it.
         */
-       if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+       if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
                int     h_size = be32_to_cpu(rhead->h_size);
                int     h_version = be32_to_cpu(rhead->h_version);
 
@@ -1101,7 +1101,7 @@ xlog_add_record(
        recp->h_magicno = cpu_to_be32(XLOG_HEADER_MAGIC_NUM);
        recp->h_cycle = cpu_to_be32(cycle);
        recp->h_version = cpu_to_be32(
-                       XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb) ? 2 : 1);
+                       xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? 2 : 1);
        recp->h_lsn = cpu_to_be64(xlog_assign_lsn(cycle, block));
        recp->h_tail_lsn = cpu_to_be64(xlog_assign_lsn(tail_cycle, tail_block));
        recp->h_fmt = cpu_to_be32(XLOG_FMT);
@@ -3348,7 +3348,7 @@ xlog_pack_data(
                dp += BBSIZE;
        }
 
-       if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+       if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
                xhdr = (xlog_in_core_2_t *)&iclog->ic_header;
                for ( ; i < BTOBB(size); i++) {
                        j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
@@ -3388,7 +3388,7 @@ xlog_unpack_data_checksum(
                            be32_to_cpu(rhead->h_chksum), chksum);
                    cmn_err(CE_DEBUG,
 "XFS: Disregard message if filesystem was created with non-DEBUG kernel");
-                   if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+                   if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
                            cmn_err(CE_DEBUG,
                                "XFS: LogR this is a LogV2 filesystem\n");
                    }
@@ -3415,7 +3415,7 @@ xlog_unpack_data(
                dp += BBSIZE;
        }
 
-       if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+       if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
                xhdr = (xlog_in_core_2_t *)rhead;
                for ( ; i < BTOBB(be32_to_cpu(rhead->h_len)); i++) {
                        j = i / (XLOG_HEADER_CYCLE_SIZE / BBSIZE);
@@ -3494,7 +3494,7 @@ xlog_do_recovery_pass(
         * Read the header of the tail block and get the iclog buffer size from
         * h_size.  Use this to tell how many sectors make up the log header.
         */
-       if (XFS_SB_VERSION_HASLOGV2(&log->l_mp->m_sb)) {
+       if (xfs_sb_version_haslogv2(&log->l_mp->m_sb)) {
                /*
                 * When using variable length iclogs, read first sector of
                 * iclog header and extract the header size from it.  Get a
@@ -3838,7 +3838,7 @@ xlog_do_recover(
        sbp = &log->l_mp->m_sb;
        xfs_sb_from_disk(sbp, XFS_BUF_TO_SBP(bp));
        ASSERT(sbp->sb_magicnum == XFS_SB_MAGIC);
-       ASSERT(XFS_SB_GOOD_VERSION(sbp));
+       ASSERT(xfs_sb_good_version(sbp));
        xfs_buf_relse(bp);
 
        /* We've re-read the superblock so re-initialize per-cpu counters */
index 6409b37..8ed164e 100644 (file)
@@ -44,7 +44,7 @@
 #include "xfs_quota.h"
 #include "xfs_fsops.h"
 
-STATIC void    xfs_mount_log_sbunit(xfs_mount_t *, __int64_t);
+STATIC void    xfs_mount_log_sb(xfs_mount_t *, __int64_t);
 STATIC int     xfs_uuid_mount(xfs_mount_t *);
 STATIC void    xfs_uuid_unmount(xfs_mount_t *mp);
 STATIC void    xfs_unmountfs_wait(xfs_mount_t *);
@@ -119,6 +119,7 @@ static const struct {
     { offsetof(xfs_sb_t, sb_logsectsize),0 },
     { offsetof(xfs_sb_t, sb_logsunit),  0 },
     { offsetof(xfs_sb_t, sb_features2),         0 },
+    { offsetof(xfs_sb_t, sb_bad_features2), 0 },
     { sizeof(xfs_sb_t),                         0 }
 };
 
@@ -225,7 +226,7 @@ xfs_mount_validate_sb(
                return XFS_ERROR(EWRONGFS);
        }
 
-       if (!XFS_SB_GOOD_VERSION(sbp)) {
+       if (!xfs_sb_good_version(sbp)) {
                xfs_fs_mount_cmn_err(flags, "bad version");
                return XFS_ERROR(EWRONGFS);
        }
@@ -300,7 +301,7 @@ xfs_mount_validate_sb(
        /*
         * Version 1 directory format has never worked on Linux.
         */
-       if (unlikely(!XFS_SB_VERSION_HASDIRV2(sbp))) {
+       if (unlikely(!xfs_sb_version_hasdirv2(sbp))) {
                xfs_fs_mount_cmn_err(flags,
                        "file system using version 1 directory format");
                return XFS_ERROR(ENOSYS);
@@ -449,6 +450,7 @@ xfs_sb_from_disk(
        to->sb_logsectsize = be16_to_cpu(from->sb_logsectsize);
        to->sb_logsunit = be32_to_cpu(from->sb_logsunit);
        to->sb_features2 = be32_to_cpu(from->sb_features2);
+       to->sb_bad_features2 = be32_to_cpu(from->sb_bad_features2);
 }
 
 /*
@@ -781,7 +783,7 @@ xfs_update_alignment(xfs_mount_t *mp, int mfsi_flags, __uint64_t *update_flags)
                 * Update superblock with new values
                 * and log changes
                 */
-               if (XFS_SB_VERSION_HASDALIGN(sbp)) {
+               if (xfs_sb_version_hasdalign(sbp)) {
                        if (sbp->sb_unit != mp->m_dalign) {
                                sbp->sb_unit = mp->m_dalign;
                                *update_flags |= XFS_SB_UNIT;
@@ -792,7 +794,7 @@ xfs_update_alignment(xfs_mount_t *mp, int mfsi_flags, __uint64_t *update_flags)
                        }
                }
        } else if ((mp->m_flags & XFS_MOUNT_NOALIGN) != XFS_MOUNT_NOALIGN &&
-                   XFS_SB_VERSION_HASDALIGN(&mp->m_sb)) {
+                   xfs_sb_version_hasdalign(&mp->m_sb)) {
                        mp->m_dalign = sbp->sb_unit;
                        mp->m_swidth = sbp->sb_width;
        }
@@ -869,7 +871,7 @@ xfs_set_rw_sizes(xfs_mount_t *mp)
 STATIC void
 xfs_set_inoalignment(xfs_mount_t *mp)
 {
-       if (XFS_SB_VERSION_HASALIGN(&mp->m_sb) &&
+       if (xfs_sb_version_hasalign(&mp->m_sb) &&
            mp->m_sb.sb_inoalignmt >=
            XFS_B_TO_FSBT(mp, mp->m_inode_cluster_size))
                mp->m_inoalign_mask = mp->m_sb.sb_inoalignmt - 1;
@@ -970,6 +972,38 @@ xfs_mountfs(
        xfs_mount_common(mp, sbp);
 
        /*
+        * Check for a mismatched features2 values.  Older kernels
+        * read & wrote into the wrong sb offset for sb_features2
+        * on some platforms due to xfs_sb_t not being 64bit size aligned
+        * when sb_features2 was added, which made older superblock
+        * reading/writing routines swap it as a 64-bit value.
+        *
+        * For backwards compatibility, we make both slots equal.
+        *
+        * If we detect a mismatched field, we OR the set bits into the
+        * existing features2 field in case it has already been modified; we
+        * don't want to lose any features.  We then update the bad location
+        * with the ORed value so that older kernels will see any features2
+        * flags, and mark the two fields as needing updates once the
+        * transaction subsystem is online.
+        */
+       if (xfs_sb_has_mismatched_features2(sbp)) {
+               cmn_err(CE_WARN,
+                       "XFS: correcting sb_features alignment problem");
+               sbp->sb_features2 |= sbp->sb_bad_features2;
+               sbp->sb_bad_features2 = sbp->sb_features2;
+               update_flags |= XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2;
+
+               /*
+                * Re-check for ATTR2 in case it was found in bad_features2
+                * slot.
+                */
+               if (xfs_sb_version_hasattr2(&mp->m_sb))
+                       mp->m_flags |= XFS_MOUNT_ATTR2;
+
+       }
+
+       /*
         * Check if sb_agblocks is aligned at stripe boundary
         * If sb_agblocks is NOT aligned turn off m_dalign since
         * allocator alignment is within an ag, therefore ag has
@@ -1159,11 +1193,10 @@ xfs_mountfs(
        }
 
        /*
-        * If fs is not mounted readonly, then update the superblock
-        * unit and width changes.
+        * If fs is not mounted readonly, then update the superblock changes.
         */
        if (update_flags && !(mp->m_flags & XFS_MOUNT_RDONLY))
-               xfs_mount_log_sbunit(mp, update_flags);
+               xfs_mount_log_sb(mp, update_flags);
 
        /*
         * Initialise the XFS quota management subsystem for this mount
@@ -1875,16 +1908,18 @@ xfs_uuid_unmount(
 
 /*
  * Used to log changes to the superblock unit and width fields which could
- * be altered by the mount options. Only the first superblock is updated.
+ * be altered by the mount options, as well as any potential sb_features2
+ * fixup. Only the first superblock is updated.
  */
 STATIC void
-xfs_mount_log_sbunit(
+xfs_mount_log_sb(
        xfs_mount_t     *mp,
        __int64_t       fields)
 {
        xfs_trans_t     *tp;
 
-       ASSERT(fields & (XFS_SB_UNIT|XFS_SB_WIDTH|XFS_SB_UUID));
+       ASSERT(fields & (XFS_SB_UNIT | XFS_SB_WIDTH | XFS_SB_UUID |
+                        XFS_SB_FEATURES2 | XFS_SB_BAD_FEATURES2));
 
        tp = xfs_trans_alloc(mp, XFS_TRANS_SB_UNIT);
        if (xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
index 94660b1..d904efe 100644 (file)
@@ -89,6 +89,7 @@ struct xfs_mount;
 
 /*
  * Superblock - in core version.  Must match the ondisk version below.
+ * Must be padded to 64 bit alignment.
  */
 typedef struct xfs_sb {
        __uint32_t      sb_magicnum;    /* magic number == XFS_SB_MAGIC */
@@ -145,10 +146,21 @@ typedef struct xfs_sb {
        __uint16_t      sb_logsectsize; /* sector size for the log, bytes */
        __uint32_t      sb_logsunit;    /* stripe unit size for the log */
        __uint32_t      sb_features2;   /* additional feature bits */
+
+       /*
+        * bad features2 field as a result of failing to pad the sb
+        * structure to 64 bits. Some machines will be using this field
+        * for features2 bits. Easiest just to mark it bad and not use
+        * it for anything else.
+        */
+       __uint32_t      sb_bad_features2;
+
+       /* must be padded to 64 bit alignment */
 } xfs_sb_t;
 
 /*
- * Superblock - on disk version.  Must match the in core version below.
+ * Superblock - on disk version.  Must match the in core version above.
+ * Must be padded to 64 bit alignment.
  */
 typedef struct xfs_dsb {
        __be32          sb_magicnum;    /* magic number == XFS_SB_MAGIC */
@@ -205,6 +217,15 @@ typedef struct xfs_dsb {
        __be16          sb_logsectsize; /* sector size for the log, bytes */
        __be32          sb_logsunit;    /* stripe unit size for the log */
        __be32          sb_features2;   /* additional feature bits */
+       /*
+        * bad features2 field as a result of failing to pad the sb
+        * structure to 64 bits. Some machines will be using this field
+        * for features2 bits. Easiest just to mark it bad and not use
+        * it for anything else.
+        */
+       __be32  sb_bad_features2;
+
+       /* must be padded to 64 bit alignment */
 } xfs_dsb_t;
 
 /*
@@ -223,7 +244,7 @@ typedef enum {
        XFS_SBS_GQUOTINO, XFS_SBS_QFLAGS, XFS_SBS_FLAGS, XFS_SBS_SHARED_VN,
        XFS_SBS_INOALIGNMT, XFS_SBS_UNIT, XFS_SBS_WIDTH, XFS_SBS_DIRBLKLOG,
        XFS_SBS_LOGSECTLOG, XFS_SBS_LOGSECTSIZE, XFS_SBS_LOGSUNIT,
-       XFS_SBS_FEATURES2,
+       XFS_SBS_FEATURES2, XFS_SBS_BAD_FEATURES2,
        XFS_SBS_FIELDCOUNT
 } xfs_sb_field_t;
 
@@ -248,13 +269,15 @@ typedef enum {
 #define XFS_SB_IFREE           XFS_SB_MVAL(IFREE)
 #define XFS_SB_FDBLOCKS                XFS_SB_MVAL(FDBLOCKS)
 #define XFS_SB_FEATURES2       XFS_SB_MVAL(FEATURES2)
+#define XFS_SB_BAD_FEATURES2   XFS_SB_MVAL(BAD_FEATURES2)
 #define        XFS_SB_NUM_BITS         ((int)XFS_SBS_FIELDCOUNT)
 #define        XFS_SB_ALL_BITS         ((1LL << XFS_SB_NUM_BITS) - 1)
 #define        XFS_SB_MOD_BITS         \
        (XFS_SB_UUID | XFS_SB_ROOTINO | XFS_SB_RBMINO | XFS_SB_RSUMINO | \
         XFS_SB_VERSIONNUM | XFS_SB_UQUOTINO | XFS_SB_GQUOTINO | \
         XFS_SB_QFLAGS | XFS_SB_SHARED_VN | XFS_SB_UNIT | XFS_SB_WIDTH | \
-        XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2)
+        XFS_SB_ICOUNT | XFS_SB_IFREE | XFS_SB_FDBLOCKS | XFS_SB_FEATURES2 | \
+        XFS_SB_BAD_FEATURES2)
 
 
 /*
@@ -271,7 +294,6 @@ typedef enum {
 
 #define        XFS_SB_VERSION_NUM(sbp) ((sbp)->sb_versionnum & XFS_SB_VERSION_NUMBITS)
 
-#define        XFS_SB_GOOD_VERSION(sbp)        xfs_sb_good_version(sbp)
 #ifdef __KERNEL__
 static inline int xfs_sb_good_version(xfs_sb_t *sbp)
 {
@@ -297,7 +319,15 @@ static inline int xfs_sb_good_version(xfs_sb_t *sbp)
 }
 #endif /* __KERNEL__ */
 
-#define        XFS_SB_VERSION_TONEW(v) xfs_sb_version_tonew(v)
+/*
+ * Detect a mismatched features2 field.  Older kernels read/wrote
+ * this into the wrong slot, so to be safe we keep them in sync.
+ */
+static inline int xfs_sb_has_mismatched_features2(xfs_sb_t *sbp)
+{
+       return (sbp->sb_bad_features2 != sbp->sb_features2);
+}
+
 static inline unsigned xfs_sb_version_tonew(unsigned v)
 {
        return ((((v) == XFS_SB_VERSION_1) ? \
@@ -308,7 +338,6 @@ static inline unsigned xfs_sb_version_tonew(unsigned v)
                XFS_SB_VERSION_4);
 }
 
-#define        XFS_SB_VERSION_TOOLD(v) xfs_sb_version_toold(v)
 static inline unsigned xfs_sb_version_toold(unsigned v)
 {
        return (((v) & (XFS_SB_VERSION_QUOTABIT | XFS_SB_VERSION_ALIGNBIT)) ? \
@@ -320,7 +349,6 @@ static inline unsigned xfs_sb_version_toold(unsigned v)
                                XFS_SB_VERSION_1)));
 }
 
-#define        XFS_SB_VERSION_HASATTR(sbp)     xfs_sb_version_hasattr(sbp)
 static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp)
 {
        return ((sbp)->sb_versionnum == XFS_SB_VERSION_2) || \
@@ -329,7 +357,6 @@ static inline int xfs_sb_version_hasattr(xfs_sb_t *sbp)
                  ((sbp)->sb_versionnum & XFS_SB_VERSION_ATTRBIT));
 }
 
-#define        XFS_SB_VERSION_ADDATTR(sbp)     xfs_sb_version_addattr(sbp)
 static inline void xfs_sb_version_addattr(xfs_sb_t *sbp)
 {
        (sbp)->sb_versionnum = (((sbp)->sb_versionnum == XFS_SB_VERSION_1) ? \
@@ -339,7 +366,6 @@ static inline void xfs_sb_version_addattr(xfs_sb_t *sbp)
                        (XFS_SB_VERSION_4 | XFS_SB_VERSION_ATTRBIT)));
 }
 
-#define        XFS_SB_VERSION_HASNLINK(sbp)    xfs_sb_version_hasnlink(sbp)
 static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp)
 {
        return ((sbp)->sb_versionnum == XFS_SB_VERSION_3) || \
@@ -347,7 +373,6 @@ static inline int xfs_sb_version_hasnlink(xfs_sb_t *sbp)
                  ((sbp)->sb_versionnum & XFS_SB_VERSION_NLINKBIT));
 }
 
-#define        XFS_SB_VERSION_ADDNLINK(sbp)    xfs_sb_version_addnlink(sbp)
 static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp)
 {
        (sbp)->sb_versionnum = ((sbp)->sb_versionnum <= XFS_SB_VERSION_2 ? \
@@ -355,115 +380,63 @@ static inline void xfs_sb_version_addnlink(xfs_sb_t *sbp)
                ((sbp)->sb_versionnum | XFS_SB_VERSION_NLINKBIT));
 }
 
-#define        XFS_SB_VERSION_HASQUOTA(sbp)    xfs_sb_version_hasquota(sbp)
 static inline int xfs_sb_version_hasquota(xfs_sb_t *sbp)
 {
        return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
                ((sbp)->sb_versionnum & XFS_SB_VERSION_QUOTABIT);
 }
 
-#define        XFS_SB_VERSION_ADDQUOTA(sbp)    xfs_sb_version_addquota(sbp)
 static inline void xfs_sb_version_addquota(xfs_sb_t *sbp)
 {
        (sbp)->sb_versionnum = \
                 (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4 ? \
                        ((sbp)->sb_versionnum | XFS_SB_VERSION_QUOTABIT) : \
-                       (XFS_SB_VERSION_TONEW((sbp)->sb_versionnum) | \
+                       (xfs_sb_version_tonew((sbp)->sb_versionnum) | \
                         XFS_SB_VERSION_QUOTABIT));
 }
 
-#define        XFS_SB_VERSION_HASALIGN(sbp)    xfs_sb_version_hasalign(sbp)
 static inline int xfs_sb_version_hasalign(xfs_sb_t *sbp)
 {
        return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
                ((sbp)->sb_versionnum & XFS_SB_VERSION_ALIGNBIT);
 }
 
-#define        XFS_SB_VERSION_SUBALIGN(sbp)    xfs_sb_version_subalign(sbp)
-static inline void xfs_sb_version_subalign(xfs_sb_t *sbp)
-{
-       (sbp)->sb_versionnum = \
-        XFS_SB_VERSION_TOOLD((sbp)->sb_versionnum & ~XFS_SB_VERSION_ALIGNBIT);
-}
-
-#define XFS_SB_VERSION_HASDALIGN(sbp)  xfs_sb_version_hasdalign(sbp)
 static inline int xfs_sb_version_hasdalign(xfs_sb_t *sbp)
 {
        return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
                ((sbp)->sb_versionnum & XFS_SB_VERSION_DALIGNBIT);
 }
 
-#define XFS_SB_VERSION_ADDDALIGN(sbp)  xfs_sb_version_adddalign(sbp)
-static inline int xfs_sb_version_adddalign(xfs_sb_t *sbp)
-{
-       return (sbp)->sb_versionnum = \
-               ((sbp)->sb_versionnum | XFS_SB_VERSION_DALIGNBIT);
-}
-
-#define XFS_SB_VERSION_HASSHARED(sbp)  xfs_sb_version_hasshared(sbp)
 static inline int xfs_sb_version_hasshared(xfs_sb_t *sbp)
 {
        return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
                ((sbp)->sb_versionnum & XFS_SB_VERSION_SHAREDBIT);
 }
 
-#define XFS_SB_VERSION_ADDSHARED(sbp)  xfs_sb_version_addshared(sbp)
-static inline int xfs_sb_version_addshared(xfs_sb_t *sbp)
-{
-       return (sbp)->sb_versionnum = \
-               ((sbp)->sb_versionnum | XFS_SB_VERSION_SHAREDBIT);
-}
-
-#define XFS_SB_VERSION_SUBSHARED(sbp)  xfs_sb_version_subshared(sbp)
-static inline int xfs_sb_version_subshared(xfs_sb_t *sbp)
-{
-       return (sbp)->sb_versionnum = \
-               ((sbp)->sb_versionnum & ~XFS_SB_VERSION_SHAREDBIT);
-}
-
-#define XFS_SB_VERSION_HASDIRV2(sbp)   xfs_sb_version_hasdirv2(sbp)
 static inline int xfs_sb_version_hasdirv2(xfs_sb_t *sbp)
 {
        return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
                ((sbp)->sb_versionnum & XFS_SB_VERSION_DIRV2BIT);
 }
 
-#define XFS_SB_VERSION_HASLOGV2(sbp)   xfs_sb_version_haslogv2(sbp)
 static inline int xfs_sb_version_haslogv2(xfs_sb_t *sbp)
 {
        return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
                ((sbp)->sb_versionnum & XFS_SB_VERSION_LOGV2BIT);
 }
 
-#define XFS_SB_VERSION_HASEXTFLGBIT(sbp)       xfs_sb_version_hasextflgbit(sbp)
 static inline int xfs_sb_version_hasextflgbit(xfs_sb_t *sbp)
 {
        return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
                ((sbp)->sb_versionnum & XFS_SB_VERSION_EXTFLGBIT);
 }
 
-#define XFS_SB_VERSION_ADDEXTFLGBIT(sbp)       xfs_sb_version_addextflgbit(sbp)
-static inline int xfs_sb_version_addextflgbit(xfs_sb_t *sbp)
-{
-       return (sbp)->sb_versionnum = \
-               ((sbp)->sb_versionnum | XFS_SB_VERSION_EXTFLGBIT);
-}
-
-#define XFS_SB_VERSION_SUBEXTFLGBIT(sbp)       xfs_sb_version_subextflgbit(sbp)
-static inline int xfs_sb_version_subextflgbit(xfs_sb_t *sbp)
-{
-       return (sbp)->sb_versionnum = \
-               ((sbp)->sb_versionnum & ~XFS_SB_VERSION_EXTFLGBIT);
-}
-
-#define XFS_SB_VERSION_HASSECTOR(sbp)   xfs_sb_version_hassector(sbp)
 static inline int xfs_sb_version_hassector(xfs_sb_t *sbp)
 {
        return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
                ((sbp)->sb_versionnum & XFS_SB_VERSION_SECTORBIT);
 }
 
-#define XFS_SB_VERSION_HASMOREBITS(sbp)        xfs_sb_version_hasmorebits(sbp)
 static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp)
 {
        return (XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_4) && \
@@ -476,24 +449,22 @@ static inline int xfs_sb_version_hasmorebits(xfs_sb_t *sbp)
  * For example, for a bit defined as XFS_SB_VERSION2_FUNBIT, has a macro:
  *
  * SB_VERSION_HASFUNBIT(xfs_sb_t *sbp)
- *     ((XFS_SB_VERSION_HASMOREBITS(sbp) &&
+ *     ((xfs_sb_version_hasmorebits(sbp) &&
  *      ((sbp)->sb_features2 & XFS_SB_VERSION2_FUNBIT)
  */
 
 static inline int xfs_sb_version_haslazysbcount(xfs_sb_t *sbp)
 {
-       return (XFS_SB_VERSION_HASMOREBITS(sbp) &&      \
+       return (xfs_sb_version_hasmorebits(sbp) &&      \
                ((sbp)->sb_features2 & XFS_SB_VERSION2_LAZYSBCOUNTBIT));
 }
 
-#define XFS_SB_VERSION_HASATTR2(sbp)   xfs_sb_version_hasattr2(sbp)
 static inline int xfs_sb_version_hasattr2(xfs_sb_t *sbp)
 {
-       return (XFS_SB_VERSION_HASMOREBITS(sbp)) &&     \
+       return (xfs_sb_version_hasmorebits(sbp)) &&     \
                ((sbp)->sb_features2 & XFS_SB_VERSION2_ATTR2BIT);
 }
 
-#define XFS_SB_VERSION_ADDATTR2(sbp)   xfs_sb_version_addattr2(sbp)
 static inline void xfs_sb_version_addattr2(xfs_sb_t *sbp)
 {
        ((sbp)->sb_versionnum = \
index 45d740d..18a85e7 100644 (file)
@@ -339,10 +339,10 @@ xfs_bump_ino_vers2(
        ip->i_d.di_onlink = 0;
        memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad));
        mp = tp->t_mountp;
-       if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
+       if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
                spin_lock(&mp->m_sb_lock);
-               if (!XFS_SB_VERSION_HASNLINK(&mp->m_sb)) {
-                       XFS_SB_VERSION_ADDNLINK(&mp->m_sb);
+               if (!xfs_sb_version_hasnlink(&mp->m_sb)) {
+                       xfs_sb_version_addnlink(&mp->m_sb);
                        spin_unlock(&mp->m_sb_lock);
                        xfs_mod_sb(tp, XFS_SB_VERSIONNUM);
                } else {
index 7321304..7094caf 100644 (file)
@@ -330,7 +330,7 @@ xfs_finish_flags(
        int                     ronly = (mp->m_flags & XFS_MOUNT_RDONLY);
 
        /* Fail a mount where the logbuf is smaller then the log stripe */
-       if (XFS_SB_VERSION_HASLOGV2(&mp->m_sb)) {
+       if (xfs_sb_version_haslogv2(&mp->m_sb)) {
                if ((ap->logbufsize <= 0) &&
                    (mp->m_sb.sb_logsunit > XLOG_BIG_RECORD_BSIZE)) {
                        mp->m_logbsize = mp->m_sb.sb_logsunit;
@@ -349,9 +349,8 @@ xfs_finish_flags(
                }
        }
 
-       if (XFS_SB_VERSION_HASATTR2(&mp->m_sb)) {
+       if (xfs_sb_version_hasattr2(&mp->m_sb))
                mp->m_flags |= XFS_MOUNT_ATTR2;
-       }
 
        /*
         * prohibit r/w mounts of read-only filesystems
@@ -366,7 +365,7 @@ xfs_finish_flags(
         * check for shared mount.
         */
        if (ap->flags & XFSMNT_SHARED) {
-               if (!XFS_SB_VERSION_HASSHARED(&mp->m_sb))
+               if (!xfs_sb_version_hasshared(&mp->m_sb))
                        return XFS_ERROR(EINVAL);
 
                /*
@@ -512,7 +511,7 @@ xfs_mount(
        if (!error && logdev && logdev != ddev) {
                unsigned int    log_sector_size = BBSIZE;
 
-               if (XFS_SB_VERSION_HASSECTOR(&mp->m_sb))
+               if (xfs_sb_version_hassector(&mp->m_sb))
                        log_sector_size = mp->m_sb.sb_logsectsize;
                error = xfs_setsize_buftarg(mp->m_logdev_targp,
                                            mp->m_sb.sb_blocksize,
index 5130524..64c5953 100644 (file)
@@ -4132,7 +4132,7 @@ xfs_free_file_space(
         * actually need to zero the extent edges.  Otherwise xfs_bunmapi
         * will take care of it for us.
         */
-       if (rt && !XFS_SB_VERSION_HASEXTFLGBIT(&mp->m_sb)) {
+       if (rt && !xfs_sb_version_hasextflgbit(&mp->m_sb)) {
                nimap = 1;
                error = xfs_bmapi(NULL, ip, startoffset_fsb,
                        1, 0, NULL, 0, &imap, &nimap, NULL, NULL);
index 7ca0ed9..352d338 100644 (file)
@@ -15,6 +15,7 @@
 
 struct s3c2410_spi_info {
        unsigned long            pin_cs;        /* simple gpio cs */
+       unsigned int             num_cs;        /* total chipselects */
 
        void (*set_cs)(struct s3c2410_spi_info *spi, int cs, int pol);
 };
index 8353225..734a1d0 100644 (file)
@@ -60,7 +60,7 @@
  */
 #define BRK_BASE                       __UL(2 * 1024 * 1024 + PAGE_SIZE)
 #define STACK_TOP                      __UL(2 * 1024 * 1024)
-#define STACK_TOP_MAX  STACK_TOP
+#define STACK_TOP_MAX                  __UL(0xc0000000)
 
 /* userspace process size */
 #ifdef CONFIG_MMU
index 6c0682e..4e21904 100644 (file)
@@ -507,13 +507,22 @@ static inline int pte_file(pte_t pte)
  */
 static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte)
 {
+       struct mm_struct *mm;
        unsigned long ampr;
-       pgd_t *pge = pgd_offset(current->mm, address);
-       pud_t *pue = pud_offset(pge, address);
-       pmd_t *pme = pmd_offset(pue, address);
 
-       ampr = pme->ste[0] & 0xffffff00;
-       ampr |= xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C | xAMPRx_V;
+       mm = current->mm;
+       if (mm) {
+               pgd_t *pge = pgd_offset(mm, address);
+               pud_t *pue = pud_offset(pge, address);
+               pmd_t *pme = pmd_offset(pue, address);
+
+               ampr = pme->ste[0] & 0xffffff00;
+               ampr |= xAMPRx_L | xAMPRx_SS_16Kb | xAMPRx_S | xAMPRx_C |
+                       xAMPRx_V;
+       } else {
+               address = ULONG_MAX;
+               ampr = 0;
+       }
 
        asm volatile("movgs %0,scr0\n"
                     "movgs %0,scr1\n"
index c2a541e..01e6af5 100644 (file)
 #define TBR_TT_TRAP1           (0x81 << 4)
 #define TBR_TT_TRAP2           (0x82 << 4)
 #define TBR_TT_TRAP3           (0x83 << 4)
+#define TBR_TT_TRAP120         (0xf8 << 4)
+#define TBR_TT_TRAP121         (0xf9 << 4)
+#define TBR_TT_TRAP122         (0xfa << 4)
+#define TBR_TT_TRAP123         (0xfb << 4)
+#define TBR_TT_TRAP124         (0xfc << 4)
+#define TBR_TT_TRAP125         (0xfd << 4)
 #define TBR_TT_TRAP126         (0xfe << 4)
 #define TBR_TT_BREAK           (0xff << 4)
 
+#define TBR_TT_ATOMIC_CMPXCHG32        TBR_TT_TRAP120
+#define TBR_TT_ATOMIC_XCHG32   TBR_TT_TRAP121
+#define TBR_TT_ATOMIC_XOR      TBR_TT_TRAP122
+#define TBR_TT_ATOMIC_OR       TBR_TT_TRAP123
+#define TBR_TT_ATOMIC_AND      TBR_TT_TRAP124
+#define TBR_TT_ATOMIC_SUB      TBR_TT_TRAP125
+#define TBR_TT_ATOMIC_ADD      TBR_TT_TRAP126
+
 #define __get_TBR()    ({ unsigned long x; asm volatile("movsg tbr,%0" : "=r"(x)); x; })
 
 /*
index 2c57f47..30a67a9 100644 (file)
@@ -179,14 +179,23 @@ do {                                                      \
 #define mb()                   asm volatile ("membar" : : :"memory")
 #define rmb()                  asm volatile ("membar" : : :"memory")
 #define wmb()                  asm volatile ("membar" : : :"memory")
-#define set_mb(var, value)     do { var = value; mb(); } while (0)
+#define read_barrier_depends() barrier()
 
-#define smp_mb()               mb()
-#define smp_rmb()              rmb()
-#define smp_wmb()              wmb()
-
-#define read_barrier_depends()         do {} while(0)
+#ifdef CONFIG_SMP
+#define smp_mb()                       mb()
+#define smp_rmb()                      rmb()
+#define smp_wmb()                      wmb()
 #define smp_read_barrier_depends()     read_barrier_depends()
+#define set_mb(var, value) \
+       do { xchg(&var, (value)); } while (0)
+#else
+#define smp_mb()                       barrier()
+#define smp_rmb()                      barrier()
+#define smp_wmb()                      barrier()
+#define smp_read_barrier_depends()     do {} while(0)
+#define set_mb(var, value) \
+       do { var = (value); barrier(); } while (0)
+#endif
 
 #define HARD_RESET_NOW()                       \
 do {                                           \
index cd1cc39..fcfad32 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/init.h>
 #include <linux/numa.h>
 #include <asm/system.h>
+#include <asm/numa.h>
 
 #define COMPILER_DEPENDENT_INT64       long
 #define COMPILER_DEPENDENT_UINT64      unsigned long
@@ -115,7 +116,11 @@ extern unsigned int is_cpu_cpei_target(unsigned int cpu);
 extern void set_cpei_target_cpu(unsigned int cpu);
 extern unsigned int get_cpei_target_cpu(void);
 extern void prefill_possible_map(void);
+#ifdef CONFIG_ACPI_HOTPLUG_CPU
 extern int additional_cpus;
+#else
+#define additional_cpus 0
+#endif
 
 #ifdef CONFIG_ACPI_NUMA
 #if MAX_NUMNODES > 256
@@ -129,6 +134,34 @@ extern int __initdata nid_to_pxm_map[MAX_NUMNODES];
 
 #define acpi_unlazy_tlb(x)
 
+#ifdef CONFIG_ACPI_NUMA
+extern cpumask_t early_cpu_possible_map;
+#define for_each_possible_early_cpu(cpu)  \
+       for_each_cpu_mask((cpu), early_cpu_possible_map)
+
+static inline void per_cpu_scan_finalize(int min_cpus, int reserve_cpus)
+{
+       int low_cpu, high_cpu;
+       int cpu;
+       int next_nid = 0;
+
+       low_cpu = cpus_weight(early_cpu_possible_map);
+
+       high_cpu = max(low_cpu, min_cpus);
+       high_cpu = min(high_cpu + reserve_cpus, NR_CPUS);
+
+       for (cpu = low_cpu; cpu < high_cpu; cpu++) {
+               cpu_set(cpu, early_cpu_possible_map);
+               if (node_cpuid[cpu].nid == NUMA_NO_NODE) {
+                       node_cpuid[cpu].nid = next_nid;
+                       next_nid++;
+                       if (next_nid >= num_online_nodes())
+                               next_nid = 0;
+               }
+       }
+}
+#endif /* CONFIG_ACPI_NUMA */
+
 #endif /*__KERNEL__*/
 
 #endif /*_ASM_ACPI_H*/
index 72400a7..f9abdec 100644 (file)
@@ -1,6 +1,110 @@
+/*
+ * include/asm-ia64/cputime.h:
+ *             Definitions for measuring cputime on ia64 machines.
+ *
+ * Based on <asm-powerpc/cputime.h>.
+ *
+ * Copyright (C) 2007 FUJITSU LIMITED
+ * Copyright (C) 2007 Hidetoshi Seto <seto.hidetoshi@jp.fujitsu.com>
+ *
+ * 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.
+ *
+ * If we have CONFIG_VIRT_CPU_ACCOUNTING, we measure cpu time in nsec.
+ * Otherwise we measure cpu time in jiffies using the generic definitions.
+ */
+
 #ifndef __IA64_CPUTIME_H
 #define __IA64_CPUTIME_H
 
+#ifndef CONFIG_VIRT_CPU_ACCOUNTING
 #include <asm-generic/cputime.h>
+#else
+
+#include <linux/time.h>
+#include <linux/jiffies.h>
+#include <asm/processor.h>
+
+typedef u64 cputime_t;
+typedef u64 cputime64_t;
+
+#define cputime_zero                   ((cputime_t)0)
+#define cputime_max                    ((~((cputime_t)0) >> 1) - 1)
+#define cputime_add(__a, __b)          ((__a) +  (__b))
+#define cputime_sub(__a, __b)          ((__a) -  (__b))
+#define cputime_div(__a, __n)          ((__a) /  (__n))
+#define cputime_halve(__a)             ((__a) >> 1)
+#define cputime_eq(__a, __b)           ((__a) == (__b))
+#define cputime_gt(__a, __b)           ((__a) >  (__b))
+#define cputime_ge(__a, __b)           ((__a) >= (__b))
+#define cputime_lt(__a, __b)           ((__a) <  (__b))
+#define cputime_le(__a, __b)           ((__a) <= (__b))
+
+#define cputime64_zero                 ((cputime64_t)0)
+#define cputime64_add(__a, __b)                ((__a) + (__b))
+#define cputime64_sub(__a, __b)                ((__a) - (__b))
+#define cputime_to_cputime64(__ct)     (__ct)
+
+/*
+ * Convert cputime <-> jiffies (HZ)
+ */
+#define cputime_to_jiffies(__ct)       ((__ct) / (NSEC_PER_SEC / HZ))
+#define jiffies_to_cputime(__jif)      ((__jif) * (NSEC_PER_SEC / HZ))
+#define cputime64_to_jiffies64(__ct)   ((__ct) / (NSEC_PER_SEC / HZ))
+#define jiffies64_to_cputime64(__jif)  ((__jif) * (NSEC_PER_SEC / HZ))
+
+/*
+ * Convert cputime <-> milliseconds
+ */
+#define cputime_to_msecs(__ct)         ((__ct) / NSEC_PER_MSEC)
+#define msecs_to_cputime(__msecs)      ((__msecs) * NSEC_PER_MSEC)
+
+/*
+ * Convert cputime <-> seconds
+ */
+#define cputime_to_secs(__ct)          ((__ct) / NSEC_PER_SEC)
+#define secs_to_cputime(__secs)                ((__secs) * NSEC_PER_SEC)
+
+/*
+ * Convert cputime <-> timespec (nsec)
+ */
+static inline cputime_t timespec_to_cputime(const struct timespec *val)
+{
+       cputime_t ret = val->tv_sec * NSEC_PER_SEC;
+       return (ret + val->tv_nsec);
+}
+static inline void cputime_to_timespec(const cputime_t ct, struct timespec *val)
+{
+       val->tv_sec  = ct / NSEC_PER_SEC;
+       val->tv_nsec = ct % NSEC_PER_SEC;
+}
+
+/*
+ * Convert cputime <-> timeval (msec)
+ */
+static inline cputime_t timeval_to_cputime(struct timeval *val)
+{
+       cputime_t ret = val->tv_sec * NSEC_PER_SEC;
+       return (ret + val->tv_usec * NSEC_PER_USEC);
+}
+static inline void cputime_to_timeval(const cputime_t ct, struct timeval *val)
+{
+       val->tv_sec = ct / NSEC_PER_SEC;
+       val->tv_usec = (ct % NSEC_PER_SEC) / NSEC_PER_USEC;
+}
+
+/*
+ * Convert cputime <-> clock (USER_HZ)
+ */
+#define cputime_to_clock_t(__ct)       ((__ct) / (NSEC_PER_SEC / USER_HZ))
+#define clock_t_to_cputime(__x)                ((__x) * (NSEC_PER_SEC / USER_HZ))
+
+/*
+ * Convert cputime64 to clock.
+ */
+#define cputime64_to_clock_t(__ct)      cputime_to_clock_t((cputime_t)__ct)
 
+#endif /* CONFIG_VIRT_CPU_ACCOUNTING */
 #endif /* __IA64_CPUTIME_H */
index f8e83ec..5e0c1a6 100644 (file)
@@ -26,6 +26,7 @@
 #define ELF_ARCH       EM_IA_64
 
 #define USE_ELF_CORE_DUMP
+#define CORE_DUMP_USE_REGSET
 
 /* Least-significant four bits of ELF header's e_flags are OS-specific.  The bits are
    interpreted as follows by Linux: */
@@ -154,6 +155,30 @@ extern void ia64_init_addr_space (void);
 #define ELF_NGREG      128     /* we really need just 72 but let's leave some headroom... */
 #define ELF_NFPREG     128     /* f0 and f1 could be omitted, but so what... */
 
+/* elf_gregset_t register offsets */
+#define ELF_GR_0_OFFSET     0
+#define ELF_NAT_OFFSET     (32 * sizeof(elf_greg_t))
+#define ELF_PR_OFFSET      (33 * sizeof(elf_greg_t))
+#define ELF_BR_0_OFFSET    (34 * sizeof(elf_greg_t))
+#define ELF_CR_IIP_OFFSET  (42 * sizeof(elf_greg_t))
+#define ELF_CFM_OFFSET     (43 * sizeof(elf_greg_t))
+#define ELF_CR_IPSR_OFFSET (44 * sizeof(elf_greg_t))
+#define ELF_GR_OFFSET(i)   (ELF_GR_0_OFFSET + i * sizeof(elf_greg_t))
+#define ELF_BR_OFFSET(i)   (ELF_BR_0_OFFSET + i * sizeof(elf_greg_t))
+#define ELF_AR_RSC_OFFSET  (45 * sizeof(elf_greg_t))
+#define ELF_AR_BSP_OFFSET  (46 * sizeof(elf_greg_t))
+#define ELF_AR_BSPSTORE_OFFSET (47 * sizeof(elf_greg_t))
+#define ELF_AR_RNAT_OFFSET (48 * sizeof(elf_greg_t))
+#define ELF_AR_CCV_OFFSET  (49 * sizeof(elf_greg_t))
+#define ELF_AR_UNAT_OFFSET (50 * sizeof(elf_greg_t))
+#define ELF_AR_FPSR_OFFSET (51 * sizeof(elf_greg_t))
+#define ELF_AR_PFS_OFFSET  (52 * sizeof(elf_greg_t))
+#define ELF_AR_LC_OFFSET   (53 * sizeof(elf_greg_t))
+#define ELF_AR_EC_OFFSET   (54 * sizeof(elf_greg_t))
+#define ELF_AR_CSD_OFFSET  (55 * sizeof(elf_greg_t))
+#define ELF_AR_SSD_OFFSET  (56 * sizeof(elf_greg_t))
+#define ELF_AR_END_OFFSET  (57 * sizeof(elf_greg_t))
+
 typedef unsigned long elf_fpxregset_t;
 
 typedef unsigned long elf_greg_t;
@@ -183,12 +208,6 @@ extern void ia64_elf_core_copy_regs (struct pt_regs *src, elf_gregset_t dst);
 
 struct task_struct;
 
-extern int dump_task_regs(struct task_struct *, elf_gregset_t *);
-extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
-
-#define ELF_CORE_COPY_TASK_REGS(tsk, elf_gregs) dump_task_regs(tsk, elf_gregs)
-#define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
-
 #define GATE_EHDR      ((const struct elfhdr *) GATE_ADDR)
 
 /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */
index 7e55a58..aefcdfe 100644 (file)
@@ -31,6 +31,9 @@
 #define IA64_TR_PALCODE                1       /* itr1: maps PALcode as required by EFI */
 #define IA64_TR_CURRENT_STACK  1       /* dtr1: maps kernel's memory- & register-stacks */
 
+#define IA64_TR_ALLOC_BASE     2       /* itr&dtr: Base of dynamic TR resource*/
+#define IA64_TR_ALLOC_MAX      32      /* Max number for dynamic use*/
+
 /* Processor status register bits: */
 #define IA64_PSR_BE_BIT                1
 #define IA64_PSR_UP_BIT                2
index 6a8a27c..3499ff5 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <asm/mmzone.h>
 
+#define NUMA_NO_NODE   -1
+
 extern u16 cpu_to_node_map[NR_CPUS] __cacheline_aligned;
 extern cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
 extern pg_data_t *pgdat_list[MAX_NUMNODES];
index f4904db..89594b4 100644 (file)
@@ -296,6 +296,9 @@ enum {
     EFI_GUID(0xe429faf8, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
 #define SAL_PLAT_BUS_ERR_SECT_GUID  \
     EFI_GUID(0xe429faf9, 0x3cb7, 0x11d4, 0xbc, 0xa7, 0x0, 0x80, 0xc7, 0x3c, 0x88, 0x81)
+#define PROCESSOR_ABSTRACTION_LAYER_OVERWRITE_GUID \
+    EFI_GUID(0x6cb0a200, 0x893a, 0x11da, 0x96, 0xd2, 0x0, 0x10, 0x83, 0xff, \
+               0xca, 0x4d)
 
 #define MAX_CACHE_ERRORS       6
 #define MAX_TLB_ERRORS         6
@@ -879,6 +882,24 @@ extern void ia64_jump_to_sal(struct sal_to_os_boot *);
 
 extern void ia64_sal_handler_init(void *entry_point, void *gpval);
 
+#define PALO_MAX_TLB_PURGES    0xFFFF
+#define PALO_SIG       "PALO"
+
+struct palo_table {
+       u8  signature[4];       /* Should be "PALO" */
+       u32 length;
+       u8  minor_revision;
+       u8  major_revision;
+       u8  checksum;
+       u8  reserved1[5];
+       u16 max_tlb_purges;
+       u8  reserved2[6];
+};
+
+#define NPTCG_FROM_PAL                 0
+#define NPTCG_FROM_PALO                        1
+#define NPTCG_FROM_KERNEL_PARAMETER    2
+
 #endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_IA64_SAL_H */
index 4fa733d..ec5f355 100644 (file)
@@ -38,6 +38,9 @@ ia64_get_lid (void)
        return lid.f.id << 8 | lid.f.eid;
 }
 
+extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *),
+                                 void *info, int wait);
+
 #define hard_smp_processor_id()                ia64_get_lid()
 
 #ifdef CONFIG_SMP
index 595112b..dff8128 100644 (file)
@@ -210,6 +210,13 @@ struct task_struct;
 extern void ia64_save_extra (struct task_struct *task);
 extern void ia64_load_extra (struct task_struct *task);
 
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+extern void ia64_account_on_switch (struct task_struct *prev, struct task_struct *next);
+# define IA64_ACCOUNT_ON_SWITCH(p,n) ia64_account_on_switch(p,n)
+#else
+# define IA64_ACCOUNT_ON_SWITCH(p,n)
+#endif
+
 #ifdef CONFIG_PERFMON
   DECLARE_PER_CPU(unsigned long, pfm_syst_info);
 # define PERFMON_IS_SYSWIDE() (__get_cpu_var(pfm_syst_info) & 0x1)
@@ -222,6 +229,7 @@ extern void ia64_load_extra (struct task_struct *task);
         || IS_IA32_PROCESS(task_pt_regs(t)) || PERFMON_IS_SYSWIDE())
 
 #define __switch_to(prev,next,last) do {                                                        \
+       IA64_ACCOUNT_ON_SWITCH(prev, next);                                                      \
        if (IA64_HAS_EXTRA_STATE(prev))                                                          \
                ia64_save_extra(prev);                                                           \
        if (IA64_HAS_EXTRA_STATE(next))                                                          \
@@ -266,6 +274,10 @@ void cpu_idle_wait(void);
 
 void default_idle(void);
 
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+extern void account_system_vtime(struct task_struct *);
+#endif
+
 #endif /* __KERNEL__ */
 
 #endif /* __ASSEMBLY__ */
index 93d83cb..6da8069 100644 (file)
@@ -31,6 +31,12 @@ struct thread_info {
        mm_segment_t addr_limit;        /* user-level address space limit */
        int preempt_count;              /* 0=premptable, <0=BUG; will also serve as bh-counter */
        struct restart_block restart_block;
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+       __u64 ac_stamp;
+       __u64 ac_leave;
+       __u64 ac_stime;
+       __u64 ac_utime;
+#endif
 };
 
 #define THREAD_SIZE                    KERNEL_STACK_SIZE
@@ -62,9 +68,17 @@ struct thread_info {
 #define task_stack_page(tsk)   ((void *)(tsk))
 
 #define __HAVE_THREAD_FUNCTIONS
+#ifdef CONFIG_VIRT_CPU_ACCOUNTING
+#define setup_thread_stack(p, org)                     \
+       *task_thread_info(p) = *task_thread_info(org);  \
+       task_thread_info(p)->ac_stime = 0;              \
+       task_thread_info(p)->ac_utime = 0;              \
+       task_thread_info(p)->task = (p);
+#else
 #define setup_thread_stack(p, org) \
        *task_thread_info(p) = *task_thread_info(org); \
        task_thread_info(p)->task = (p);
+#endif
 #define end_of_stack(p) (unsigned long *)((void *)(p) + IA64_RBS_OFFSET)
 
 #define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
index 26edcb7..20d8a39 100644 (file)
@@ -64,6 +64,32 @@ struct mmu_gather {
        struct page             *pages[FREE_PTE_NR];
 };
 
+struct ia64_tr_entry {
+       u64 ifa;
+       u64 itir;
+       u64 pte;
+       u64 rr;
+}; /*Record for tr entry!*/
+
+extern int ia64_itr_entry(u64 target_mask, u64 va, u64 pte, u64 log_size);
+extern void ia64_ptr_entry(u64 target_mask, int slot);
+
+extern struct ia64_tr_entry __per_cpu_idtrs[NR_CPUS][2][IA64_TR_ALLOC_MAX];
+
+/*
+ region register macros
+*/
+#define RR_TO_VE(val)   (((val) >> 0) & 0x0000000000000001)
+#define RR_VE(val)     (((val) & 0x0000000000000001) << 0)
+#define RR_VE_MASK     0x0000000000000001L
+#define RR_VE_SHIFT    0
+#define RR_TO_PS(val)  (((val) >> 2) & 0x000000000000003f)
+#define RR_PS(val)     (((val) & 0x000000000000003f) << 2)
+#define RR_PS_MASK     0x00000000000000fcL
+#define RR_PS_SHIFT    2
+#define RR_RID_MASK    0x00000000ffffff00L
+#define RR_TO_RID(val)         ((val >> 8) & 0xffffff)
+
 /* Users of the generic TLB shootdown code must declare this storage space. */
 DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
 
index 7774a1c..3be25df 100644 (file)
@@ -17,6 +17,7 @@
  * Now for some TLB flushing routines.  This is the kind of stuff that
  * can be very expensive, so try to avoid them whenever possible.
  */
+extern void setup_ptcg_sem(int max_purges, int from_palo);
 
 /*
  * Flush everything (kernel mapping may also have changed due to
index e4fe26c..89655c0 100644 (file)
@@ -122,24 +122,6 @@ static const struct drive_list_entry dma_black_list [] = {
 };
 #endif
 
-/* function prototyping */
-u8 auide_inb(unsigned long port);
-u16 auide_inw(unsigned long port);
-u32 auide_inl(unsigned long port);
-void auide_insw(unsigned long port, void *addr, u32 count);
-void auide_insl(unsigned long port, void *addr, u32 count);
-void auide_outb(u8 addr, unsigned long port);
-void auide_outbsync(ide_drive_t *drive, u8 addr, unsigned long port);
-void auide_outw(u16 addr, unsigned long port);
-void auide_outl(u32 addr, unsigned long port);
-void auide_outsw(unsigned long port, void *addr, u32 count);
-void auide_outsl(unsigned long port, void *addr, u32 count);
-static void auide_tune_drive(ide_drive_t *drive, byte pio);
-static int auide_tune_chipset(ide_drive_t *drive, u8 speed);
-static int auide_ddma_init( _auide_hwif *auide );
-static void auide_setup_ports(hw_regs_t *hw, _auide_hwif *ahwif);
-int __init auide_probe(void);
-
 /*******************************************************************************
 * PIO Mode timing calculation :                                                *
 *                                                                              *
index a6bdac6..d2e28e6 100644 (file)
@@ -173,8 +173,8 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define AU1XXX_SMC91111_IRQ                    DB1200_ETH_INT
 
 #define AU1XXX_ATA_PHYS_ADDR           (0x18800000)
-#define AU1XXX_ATA_PHYS_LEN                    (0x100)
-#define AU1XXX_ATA_REG_OFFSET  (5)
+#define AU1XXX_ATA_REG_OFFSET          (5)
+#define AU1XXX_ATA_PHYS_LEN            (16 << AU1XXX_ATA_REG_OFFSET)
 #define AU1XXX_ATA_INT                 DB1200_IDE_INT
 #define AU1XXX_ATA_DDMA_REQ            DSCR_CMD0_DMA_REQ1;
 #define AU1XXX_ATA_RQSIZE              128
index 72213e3..edaa489 100644 (file)
@@ -186,8 +186,8 @@ static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
 #define AU1XXX_SMC91111_IRQ                    PB1200_ETH_INT
 
 #define AU1XXX_ATA_PHYS_ADDR           (0x0C800000)
-#define AU1XXX_ATA_PHYS_LEN                    (0x100)
-#define AU1XXX_ATA_REG_OFFSET  (5)
+#define AU1XXX_ATA_REG_OFFSET          (5)
+#define AU1XXX_ATA_PHYS_LEN            (16 << AU1XXX_ATA_REG_OFFSET)
 #define AU1XXX_ATA_INT                 PB1200_IDE_INT
 #define AU1XXX_ATA_DDMA_REQ            DSCR_CMD0_DMA_REQ1;
 #define AU1XXX_ATA_RQSIZE              128
index 39fc475..5240fa1 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef __UM_TLB_H
 #define __UM_TLB_H
 
+#include <linux/pagemap.h>
 #include <linux/swap.h>
 #include <asm/percpu.h>
 #include <asm/pgalloc.h>
index 31739c7..c048353 100644 (file)
@@ -8,12 +8,45 @@
 
 #ifdef CONFIG_X86_32
 #define asmlinkage CPP_ASMLINKAGE __attribute__((regparm(0)))
-#define prevent_tail_call(ret) __asm__ ("" : "=r" (ret) : "0" (ret))
 /*
  * For 32-bit UML - mark functions implemented in assembly that use
  * regparm input parameters:
  */
 #define asmregparm __attribute__((regparm(3)))
+
+/*
+ * Make sure the compiler doesn't do anything stupid with the
+ * arguments on the stack - they are owned by the *caller*, not
+ * the callee. This just fools gcc into not spilling into them,
+ * and keeps it from doing tailcall recursion and/or using the
+ * stack slots for temporaries, since they are live and "used"
+ * all the way to the end of the function.
+ *
+ * NOTE! On x86-64, all the arguments are in registers, so this
+ * only matters on a 32-bit kernel.
+ */
+#define asmlinkage_protect(n, ret, args...) \
+       __asmlinkage_protect##n(ret, ##args)
+#define __asmlinkage_protect_n(ret, args...) \
+       __asm__ __volatile__ ("" : "=r" (ret) : "0" (ret), ##args)
+#define __asmlinkage_protect0(ret) \
+       __asmlinkage_protect_n(ret)
+#define __asmlinkage_protect1(ret, arg1) \
+       __asmlinkage_protect_n(ret, "g" (arg1))
+#define __asmlinkage_protect2(ret, arg1, arg2) \
+       __asmlinkage_protect_n(ret, "g" (arg1), "g" (arg2))
+#define __asmlinkage_protect3(ret, arg1, arg2, arg3) \
+       __asmlinkage_protect_n(ret, "g" (arg1), "g" (arg2), "g" (arg3))
+#define __asmlinkage_protect4(ret, arg1, arg2, arg3, arg4) \
+       __asmlinkage_protect_n(ret, "g" (arg1), "g" (arg2), "g" (arg3), \
+                             "g" (arg4))
+#define __asmlinkage_protect5(ret, arg1, arg2, arg3, arg4, arg5) \
+       __asmlinkage_protect_n(ret, "g" (arg1), "g" (arg2), "g" (arg3), \
+                             "g" (arg4), "g" (arg5))
+#define __asmlinkage_protect6(ret, arg1, arg2, arg3, arg4, arg5, arg6) \
+       __asmlinkage_protect_n(ret, "g" (arg1), "g" (arg2), "g" (arg3), \
+                             "g" (arg4), "g" (arg5), "g" (arg6))
+
 #endif
 
 #ifdef CONFIG_X86_ALIGNMENT_16
index 9cdd12a..cedbbd8 100644 (file)
@@ -86,6 +86,7 @@ header-y += if_plip.h
 header-y += if_ppp.h
 header-y += if_slip.h
 header-y += if_strip.h
+header-y += if_tun.h
 header-y += if_tunnel.h
 header-y += in6.h
 header-y += in_route.h
@@ -229,7 +230,6 @@ unifdef-y += if_link.h
 unifdef-y += if_pppol2tp.h
 unifdef-y += if_pppox.h
 unifdef-y += if_tr.h
-unifdef-y += if_tun.h
 unifdef-y += if_vlan.h
 unifdef-y += if_wanpipe.h
 unifdef-y += igmp.h
index 72f1c5f..8c71fe2 100644 (file)
 #ifndef __IF_TUN_H
 #define __IF_TUN_H
 
-/* Uncomment to enable debugging */
-/* #define TUN_DEBUG 1 */
-
 #include <linux/types.h>
 
-#ifdef __KERNEL__
-
-#ifdef TUN_DEBUG
-#define DBG  if(tun->debug)printk
-#define DBG1 if(debug==2)printk
-#else
-#define DBG( a... )
-#define DBG1( a... )
-#endif
-
-struct tun_struct {
-       struct list_head        list;
-       unsigned long           flags;
-       int                     attached;
-       uid_t                   owner;
-       gid_t                   group;
-
-       wait_queue_head_t       read_wait;
-       struct sk_buff_head     readq;
-
-       struct net_device       *dev;
-
-       struct fasync_struct    *fasync;
-
-       unsigned long if_flags;
-       u8 dev_addr[ETH_ALEN];
-       u32 chr_filter[2];
-       u32 net_filter[2];
-
-#ifdef TUN_DEBUG       
-       int debug;
-#endif  
-};
-
-#endif /* __KERNEL__ */
-
 /* Read queue size */
 #define TUN_READQ_SIZE 500
 
index cac4b36..2b7a118 100644 (file)
@@ -91,8 +91,10 @@ static inline struct io_context *ioc_task_link(struct io_context *ioc)
         * if ref count is zero, don't allow sharing (ioc is going away, it's
         * a race).
         */
-       if (ioc && atomic_inc_not_zero(&ioc->refcount))
+       if (ioc && atomic_inc_not_zero(&ioc->refcount)) {
+               atomic_inc(&ioc->nr_tasks);
                return ioc;
+       }
 
        return NULL;
 }
index 4aaefc3..134c8e5 100644 (file)
@@ -53,7 +53,7 @@ struct ipv6_opt_hdr {
        /* 
         * TLV encoded option data follows.
         */
-};
+} __attribute__ ((packed));    /* required for some archs */
 
 #define ipv6_destopt_hdr ipv6_opt_hdr
 #define ipv6_hopopt_hdr  ipv6_opt_hdr
index 0592936..2119610 100644 (file)
 # define asmregparm
 #endif
 
-#ifndef prevent_tail_call
-# define prevent_tail_call(ret) do { } while (0)
+/*
+ * This is used by architectures to keep arguments on the stack
+ * untouched by the compiler by keeping them live until the end.
+ * The argument stack may be owned by the assembly-language
+ * caller, not the callee, and gcc doesn't always understand
+ * that.
+ *
+ * We have the return value, and a maximum of six arguments.
+ *
+ * This should always be followed by a "return ret" for the
+ * protection to work (ie no more work that the compiler might
+ * end up needing stack temporaries for).
+ */
+/* Assembly files may be compiled with -traditional .. */
+#ifndef __ASSEMBLY__
+#ifndef asmlinkage_protect
+# define asmlinkage_protect(n, ret, args...)   do { } while (0)
+#endif
 #endif
 
 #ifndef __ALIGN
index 99e044b..a09b84e 100644 (file)
@@ -34,7 +34,7 @@ void mb_cache_destroy(struct mb_cache *);
 
 /* Functions on cache entries */
 
-struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *);
+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *, gfp_t);
 int mb_cache_entry_insert(struct mb_cache_entry *, struct block_device *,
                          sector_t, unsigned int[]);
 void mb_cache_entry_release(struct mb_cache_entry *);
index 29dd558..b2f05c2 100644 (file)
@@ -175,7 +175,7 @@ static inline void pnp_set_card_drvdata(struct pnp_card_link *pcard, void *data)
 struct pnp_dev {
        struct device dev;              /* Driver Model device interface */
        u64 dma_mask;
-       unsigned char number;           /* used as an index, must be unique */
+       unsigned int number;            /* used as an index, must be unique */
        int status;
 
        struct list_head global_list;   /* node in global list of devices */
index 576a5f7..1129ee0 100644 (file)
@@ -341,6 +341,9 @@ static inline void double_spin_unlock(spinlock_t *l1, spinlock_t *l2,
  * atomic_dec_and_lock - lock on reaching reference count zero
  * @atomic: the atomic counter
  * @lock: the spinlock in question
+ *
+ * Decrements @atomic by 1.  If the result is 0, returns true and locks
+ * @lock.  Returns false for all other cases.
  */
 extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
 #define atomic_dec_and_lock(atomic, lock) \
index 20add65..db53def 100644 (file)
@@ -129,6 +129,10 @@ struct ssb_device {
        const struct ssb_bus_ops *ops;
 
        struct device *dev;
+       /* Pointer to the device that has to be used for
+        * any DMA related operation. */
+       struct device *dma_dev;
+
        struct ssb_bus *bus;
        struct ssb_device_id id;
 
index 818ca1c..90c1c19 100644 (file)
@@ -50,7 +50,7 @@ struct thermal_cooling_device_ops {
 };
 
 #define THERMAL_TRIPS_NONE -1
-#define THERMAL_MAX_TRIPS 10
+#define THERMAL_MAX_TRIPS 12
 #define THERMAL_NAME_LENGTH 20
 struct thermal_cooling_device {
        int id;
index ba33db0..7040a78 100644 (file)
@@ -47,7 +47,7 @@ static inline __u8 INET_ECN_encapsulate(__u8 outer, __u8 inner)
     } while (0)
 
 #define        IP6_ECN_flow_xmit(sk, label) do {                               \
-       if (INET_ECN_is_capable(inet_sk(sk)->tos))                      \
+       if (INET_ECN_is_capable(inet6_sk(sk)->tclass))                  \
                (label) |= htonl(INET_ECN_ECT_0 << 20);                 \
     } while (0)
 
index 10ae2da..35b1e83 100644 (file)
@@ -104,6 +104,7 @@ typedef enum {
        SCTP_CMD_ADAPTATION_IND, /* generate and send adaptation event */
        SCTP_CMD_ASSOC_SHKEY,    /* generate the association shared keys */
        SCTP_CMD_T1_RETRAN,      /* Mark for retransmission after T1 timeout  */
+       SCTP_CMD_UPDATE_INITTAG, /* Update peer inittag */
        SCTP_CMD_LAST
 } sctp_verb_t;
 
index 9bcfc12..7ea12e8 100644 (file)
@@ -67,7 +67,7 @@ struct sctp_ulpevent {
 };
 
 /* Retrieve the skb this event sits inside of. */
-static inline struct sk_buff *sctp_event2skb(struct sctp_ulpevent *ev)
+static inline struct sk_buff *sctp_event2skb(const struct sctp_ulpevent *ev)
 {
        return container_of((void *)ev, struct sk_buff, cb);
 }
index 7de4ea3..4fd3eb2 100644 (file)
@@ -752,6 +752,8 @@ static inline unsigned int tcp_packets_in_flight(const struct tcp_sock *tp)
        return tp->packets_out - tcp_left_out(tp) + tp->retrans_out;
 }
 
+extern int tcp_limit_reno_sacked(struct tcp_sock *tp);
+
 /* If cwnd > ssthresh, we may raise ssthresh to be half-way to cwnd.
  * The exception is rate halving phase, when cwnd is decreasing towards
  * ssthresh.
index 62f1a52..2727f92 100644 (file)
@@ -2569,6 +2569,7 @@ static int proc_cgroup_show(struct seq_file *m, void *v)
                /* Skip this hierarchy if it has no active subsystems */
                if (!root->actual_subsys_bits)
                        continue;
+               seq_printf(m, "%lu:", root->subsys_bits);
                for_each_subsys(root, ss)
                        seq_printf(m, "%s%s", count++ ? "," : "", ss->name);
                seq_putc(m, ':');
index 53872bf..073005b 100644 (file)
@@ -1608,7 +1608,7 @@ asmlinkage long sys_waitid(int which, pid_t upid,
        put_pid(pid);
 
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(5, ret, which, upid, infop, options, ru);
        return ret;
 }
 
@@ -1640,7 +1640,7 @@ asmlinkage long sys_wait4(pid_t upid, int __user *stat_addr,
        put_pid(pid);
 
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(4, ret, upid, stat_addr, options, ru);
        return ret;
 }
 
index c46a20a..bdd4ea8 100644 (file)
@@ -643,8 +643,21 @@ static int acquire_console_semaphore_for_printk(unsigned int cpu)
 {
        int retval = 0;
 
-       if (can_use_console(cpu))
-               retval = !try_acquire_console_sem();
+       if (!try_acquire_console_sem()) {
+               retval = 1;
+
+               /*
+                * If we can't use the console, we need to release
+                * the console semaphore by hand to avoid flushing
+                * the buffer. We need to hold the console semaphore
+                * in order to do this test safely.
+                */
+               if (!can_use_console(cpu)) {
+                       console_locked = 0;
+                       up(&console_sem);
+                       retval = 0;
+               }
+       }
        printk_cpu = UINT_MAX;
        spin_unlock(&logbuf_lock);
        return retval;
index 86a9337..0080968 100644 (file)
@@ -510,10 +510,8 @@ place_entity(struct cfs_rq *cfs_rq, struct sched_entity *se, int initial)
 
        if (!initial) {
                /* sleeps upto a single latency don't count. */
-               if (sched_feat(NEW_FAIR_SLEEPERS)) {
-                       vruntime -= calc_delta_fair(sysctl_sched_latency,
-                                                   &cfs_rq->load);
-               }
+               if (sched_feat(NEW_FAIR_SLEEPERS))
+                       vruntime -= sysctl_sched_latency;
 
                /* ensure we never gain time by being placed backwards. */
                vruntime = max_vruntime(se->vruntime, vruntime);
index dd308ba..3e41c16 100644 (file)
@@ -21,7 +21,7 @@ asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gi
 {
        long ret = sys_chown(filename, low2highuid(user), low2highgid(group));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(3, ret, filename, user, group);
        return ret;
 }
 
@@ -29,7 +29,7 @@ asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_g
 {
        long ret = sys_lchown(filename, low2highuid(user), low2highgid(group));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(3, ret, filename, user, group);
        return ret;
 }
 
@@ -37,7 +37,7 @@ asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group)
 {
        long ret = sys_fchown(fd, low2highuid(user), low2highgid(group));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(3, ret, fd, user, group);
        return ret;
 }
 
@@ -45,7 +45,7 @@ asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid)
 {
        long ret = sys_setregid(low2highgid(rgid), low2highgid(egid));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(2, ret, rgid, egid);
        return ret;
 }
 
@@ -53,7 +53,7 @@ asmlinkage long sys_setgid16(old_gid_t gid)
 {
        long ret = sys_setgid(low2highgid(gid));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(1, ret, gid);
        return ret;
 }
 
@@ -61,7 +61,7 @@ asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
 {
        long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(2, ret, ruid, euid);
        return ret;
 }
 
@@ -69,7 +69,7 @@ asmlinkage long sys_setuid16(old_uid_t uid)
 {
        long ret = sys_setuid(low2highuid(uid));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(1, ret, uid);
        return ret;
 }
 
@@ -78,7 +78,7 @@ asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid)
        long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid),
                                 low2highuid(suid));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(3, ret, ruid, euid, suid);
        return ret;
 }
 
@@ -98,7 +98,7 @@ asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid)
        long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid),
                                 low2highgid(sgid));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(3, ret, rgid, egid, sgid);
        return ret;
 }
 
@@ -117,7 +117,7 @@ asmlinkage long sys_setfsuid16(old_uid_t uid)
 {
        long ret = sys_setfsuid(low2highuid(uid));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(1, ret, uid);
        return ret;
 }
 
@@ -125,7 +125,7 @@ asmlinkage long sys_setfsgid16(old_gid_t gid)
 {
        long ret = sys_setfsgid(low2highgid(gid));
        /* avoid REGPARM breakage on x86: */
-       prevent_tail_call(ret);
+       asmlinkage_protect(1, ret, gid);
        return ret;
 }
 
index 9dc7056..77f0f9b 100644 (file)
@@ -158,7 +158,7 @@ match:
                                        t += 7 + *ip++;
                                }
                                m_pos -= le16_to_cpu(get_unaligned(
-                                       (const unsigned short *)ip) >> 2);
+                                       (const unsigned short *)ip)) >> 2;
                                ip += 2;
                                if (m_pos == op)
                                        goto eof_found;
index 23b5fa4..2e0bfc9 100644 (file)
@@ -978,7 +978,7 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node)
 {
        struct mem_cgroup_per_node *pn;
        struct mem_cgroup_per_zone *mz;
-       int zone;
+       int zone, tmp = node;
        /*
         * This routine is called against possible nodes.
         * But it's BUG to call kmalloc() against offline node.
@@ -987,10 +987,9 @@ static int alloc_mem_cgroup_per_zone_info(struct mem_cgroup *mem, int node)
         *       never be onlined. It's better to use memory hotplug callback
         *       function.
         */
-       if (node_state(node, N_HIGH_MEMORY))
-               pn = kmalloc_node(sizeof(*pn), GFP_KERNEL, node);
-       else
-               pn = kmalloc(sizeof(*pn), GFP_KERNEL);
+       if (!node_state(node, N_NORMAL_MEMORY))
+               tmp = -1;
+       pn = kmalloc_node(sizeof(*pn), GFP_KERNEL, tmp);
        if (!pn)
                return 1;
 
index f255eda..beb592f 100644 (file)
@@ -423,7 +423,7 @@ void mem_cgroup_out_of_memory(struct mem_cgroup *mem, gfp_t gfp_mask)
        struct task_struct *p;
 
        cgroup_lock();
-       rcu_read_lock();
+       read_lock(&tasklist_lock);
 retry:
        p = select_bad_process(&points, mem);
        if (PTR_ERR(p) == -1UL)
@@ -436,7 +436,7 @@ retry:
                                "Memory cgroup out of memory"))
                goto retry;
 out:
-       rcu_read_unlock();
+       read_unlock(&tasklist_lock);
        cgroup_unlock();
 }
 #endif
index f6a43c0..98d6b39 100644 (file)
@@ -149,8 +149,18 @@ static inline int sparse_early_nid(struct mem_section *section)
 /* Record a memory area against a node. */
 void __init memory_present(int nid, unsigned long start, unsigned long end)
 {
+       unsigned long max_arch_pfn = 1UL << (MAX_PHYSMEM_BITS-PAGE_SHIFT);
        unsigned long pfn;
 
+       /*
+        * Sanity checks - do not allow an architecture to pass
+        * in larger pfns than the maximum scope of sparsemem:
+        */
+       if (start >= max_arch_pfn)
+               return;
+       if (end >= max_arch_pfn)
+               end = max_arch_pfn;
+
        start &= PAGE_SECTION_MASK;
        for (pfn = start; pfn < end; pfn += PAGES_PER_SECTION) {
                unsigned long section = pfn_to_section_nr(pfn);
index 422d960..7c7286e 100644 (file)
@@ -388,6 +388,7 @@ static char * const migratetype_names[MIGRATE_TYPES] = {
        "Reclaimable",
        "Movable",
        "Reserve",
+       "Isolate",
 };
 
 static void *frag_start(struct seq_file *m, loff_t *pos)
index a2efa7f..3235c57 100644 (file)
@@ -266,7 +266,6 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
        char buf[300];
        int i = 0;
 #endif /* DUMP_PACKETS >0 */
-       DECLARE_MAC_BUF(mac);
 
        pr_debug("lec_start_xmit called\n");
        if (!priv->lecd) {
@@ -374,15 +373,19 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
                if (entry && (entry->tx_wait.qlen < LEC_UNRES_QUE_LEN)) {
                        pr_debug("%s:lec_start_xmit: queuing packet, ",
                                dev->name);
-                       pr_debug("MAC address %s\n",
-                                print_mac(mac, lec_h->h_dest));
+                       pr_debug("MAC address " MAC_FMT "\n",
+                                lec_h->h_dest[0], lec_h->h_dest[1],
+                                lec_h->h_dest[2], lec_h->h_dest[3],
+                                lec_h->h_dest[4], lec_h->h_dest[5]);
                        skb_queue_tail(&entry->tx_wait, skb);
                } else {
                        pr_debug
                            ("%s:lec_start_xmit: tx queue full or no arp entry, dropping, ",
                             dev->name);
-                       pr_debug("MAC address %s\n",
-                                print_mac(mac, lec_h->h_dest));
+                       pr_debug("MAC address " MAC_FMT "\n",
+                                lec_h->h_dest[0], lec_h->h_dest[1],
+                                lec_h->h_dest[2], lec_h->h_dest[3],
+                                lec_h->h_dest[4], lec_h->h_dest[5]);
                        priv->stats.tx_dropped++;
                        dev_kfree_skb(skb);
                }
@@ -394,8 +397,10 @@ static int lec_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        while (entry && (skb2 = skb_dequeue(&entry->tx_wait))) {
                pr_debug("lec.c: emptying tx queue, ");
-               pr_debug("MAC address %s\n",
-                        print_mac(mac, lec_h->h_dest));
+               pr_debug("MAC address " MAC_FMT "\n",
+                        lec_h->h_dest[0], lec_h->h_dest[1],
+                        lec_h->h_dest[2], lec_h->h_dest[3],
+                        lec_h->h_dest[4], lec_h->h_dest[5]);
                lec_send(vcc, skb2, priv);
        }
 
@@ -449,7 +454,6 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
        struct lec_arp_table *entry;
        int i;
        char *tmp;              /* FIXME */
-       DECLARE_MAC_BUF(mac);
 
        atomic_sub(skb->truesize, &sk_atm(vcc)->sk_wmem_alloc);
        mesg = (struct atmlec_msg *)skb->data;
@@ -536,9 +540,14 @@ static int lec_atm_send(struct atm_vcc *vcc, struct sk_buff *skb)
                        struct net_bridge_fdb_entry *f;
 
                        pr_debug
-                           ("%s: bridge zeppelin asks about %s\n",
+                           ("%s: bridge zeppelin asks about " MAC_FMT "\n",
                             dev->name,
-                            print_mac(mac, mesg->content.proxy.mac_addr));
+                            mesg->content.proxy.mac_addr[0],
+                            mesg->content.proxy.mac_addr[1],
+                            mesg->content.proxy.mac_addr[2],
+                            mesg->content.proxy.mac_addr[3],
+                            mesg->content.proxy.mac_addr[4],
+                            mesg->content.proxy.mac_addr[5]);
 
                        if (br_fdb_get_hook == NULL || dev->br_port == NULL)
                                break;
index 5f4eb73..57aeba7 100644 (file)
@@ -218,9 +218,11 @@ void __exit ax25_uid_free(void)
        struct hlist_node *node;
 
        write_lock(&ax25_uid_lock);
+again:
        ax25_uid_for_each(ax25_uid, node, &ax25_uid_list) {
                hlist_del_init(&ax25_uid->uid_node);
                ax25_uid_put(ax25_uid);
+               goto again;
        }
        write_unlock(&ax25_uid_lock);
 }
index 1c0efd8..af7e8be 100644 (file)
@@ -110,7 +110,8 @@ static inline __be16 pppoe_proto(const struct sk_buff *skb)
  * ipt_REJECT needs it.  Future netfilter modules might
  * require us to fill additional fields. */
 static struct net_device __fake_net_device = {
-       .hard_header_len        = ETH_HLEN
+       .hard_header_len        = ETH_HLEN,
+       .nd_net                 = &init_net,
 };
 
 static struct rtable __fake_rtable = {
index 0d0fd28..6087013 100644 (file)
@@ -2131,8 +2131,8 @@ EXPORT_SYMBOL_GPL(skb_pull_rcsum);
  *     @features: features for the output path (see dev->features)
  *
  *     This function performs segmentation on the given skb.  It returns
- *     the segment at the given position.  It returns NULL if there are
- *     no more segments to generate, or when an error is encountered.
+ *     a pointer to the first in a list of new skbs for the segments.
+ *     In case of error it returns ERR_PTR(err).
  */
 struct sk_buff *skb_segment(struct sk_buff *skb, int features)
 {
index 2654c14..7a0567b 100644 (file)
@@ -1725,7 +1725,7 @@ void sock_init_data(struct socket *sock, struct sock *sk)
        sk->sk_rcvtimeo         =       MAX_SCHEDULE_TIMEOUT;
        sk->sk_sndtimeo         =       MAX_SCHEDULE_TIMEOUT;
 
-       sk->sk_stamp = ktime_set(-1L, -1L);
+       sk->sk_stamp = ktime_set(-1L, 0);
 
        atomic_set(&sk->sk_refcnt, 1);
        atomic_set(&sk->sk_drops, 0);
index 287a62b..ba2ef94 100644 (file)
@@ -325,6 +325,12 @@ static inline int dccp_bad_service_code(const struct sock *sk,
  * This is used for transmission as well as for reception.
  */
 struct dccp_skb_cb {
+       union {
+               struct inet_skb_parm    h4;
+#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
+               struct inet6_skb_parm   h6;
+#endif
+       } header;
        __u8  dccpd_type:4;
        __u8  dccpd_ccval:4;
        __u8  dccpd_reset_code,
index 474075a..b337044 100644 (file)
@@ -489,7 +489,6 @@ static int dccp_v4_send_response(struct sock *sk, struct request_sock *req,
 
                dh->dccph_checksum = dccp_v4_csum_finish(skb, ireq->loc_addr,
                                                              ireq->rmt_addr);
-               memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
                err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
                                            ireq->rmt_addr,
                                            ireq->opt);
index 3b763db..3d7d628 100644 (file)
@@ -126,7 +126,6 @@ static int dccp_transmit_skb(struct sock *sk, struct sk_buff *skb)
 
                DCCP_INC_STATS(DCCP_MIB_OUTSEGS);
 
-               memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
                err = icsk->icsk_af_ops->queue_xmit(skb, 0);
                return net_xmit_eval(err);
        }
index e3f5d37..c91d3c1 100644 (file)
@@ -1057,6 +1057,9 @@ static int __init dccp_init(void)
        int ehash_order, bhash_order, i;
        int rc = -ENOBUFS;
 
+       BUILD_BUG_ON(sizeof(struct dccp_skb_cb) >
+                    FIELD_SIZEOF(struct sk_buff, cb));
+
        dccp_hashinfo.bind_bucket_cachep =
                kmem_cache_create("dccp_bind_bucket",
                                  sizeof(struct inet_bind_bucket), 0,
index a7b4175..a80839b 100644 (file)
@@ -301,7 +301,7 @@ static int eth_change_mtu(struct net_device *dev, int new_mtu)
 static int eth_validate_addr(struct net_device *dev)
 {
        if (!is_valid_ether_addr(dev->dev_addr))
-               return -EINVAL;
+               return -EADDRNOTAVAIL;
 
        return 0;
 }
index 1e3f87c..200ee1e 100644 (file)
@@ -271,7 +271,6 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
 {
        struct ieee80211_hdr_3addr *hdr;
        int res, hdrlen;
-       DECLARE_MAC_BUF(mac);
 
        if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
                return 0;
@@ -283,8 +282,12 @@ ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
        res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
-               IEEE80211_DEBUG_DROP("decryption failed (SA=%s"
-                                    ") res=%d\n", print_mac(mac, hdr->addr2), res);
+               IEEE80211_DEBUG_DROP("decryption failed (SA=" MAC_FMT
+                                    ") res=%d\n",
+                                    hdr->addr2[0], hdr->addr2[1],
+                                    hdr->addr2[2], hdr->addr2[3],
+                                    hdr->addr2[4], hdr->addr2[5],
+                                    res);
                if (res == -2)
                        IEEE80211_DEBUG_DROP("Decryption failed ICV "
                                             "mismatch (key %d)\n",
@@ -304,7 +307,6 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
 {
        struct ieee80211_hdr_3addr *hdr;
        int res, hdrlen;
-       DECLARE_MAC_BUF(mac);
 
        if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
                return 0;
@@ -317,8 +319,12 @@ ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
        atomic_dec(&crypt->refcnt);
        if (res < 0) {
                printk(KERN_DEBUG "%s: MSDU decryption/MIC verification failed"
-                      " (SA=%s keyidx=%d)\n",
-                      ieee->dev->name, print_mac(mac, hdr->addr2), keyidx);
+                      " (SA=" MAC_FMT " keyidx=%d)\n",
+                      ieee->dev->name,
+                      hdr->addr2[0], hdr->addr2[1],
+                      hdr->addr2[2], hdr->addr2[3],
+                      hdr->addr2[4], hdr->addr2[5],
+                      keyidx);
                return -1;
        }
 
@@ -462,8 +468,10 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                         * frames silently instead of filling system log with
                         * these reports. */
                        IEEE80211_DEBUG_DROP("Decryption failed (not set)"
-                                            " (SA=%s)\n",
-                                            print_mac(mac, hdr->addr2));
+                                            " (SA=" MAC_FMT ")\n",
+                                            hdr->addr2[0], hdr->addr2[1],
+                                            hdr->addr2[2], hdr->addr2[3],
+                                            hdr->addr2[4], hdr->addr2[5]);
                        ieee->ieee_stats.rx_discards_undecryptable++;
                        goto rx_dropped;
                }
@@ -474,8 +482,10 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                    fc & IEEE80211_FCTL_PROTECTED && ieee->host_decrypt &&
                    (keyidx = hostap_rx_frame_decrypt(ieee, skb, crypt)) < 0) {
                        printk(KERN_DEBUG "%s: failed to decrypt mgmt::auth "
-                              "from %s\n", dev->name,
-                              print_mac(mac, hdr->addr2));
+                              "from " MAC_FMT "\n", dev->name,
+                              hdr->addr2[0], hdr->addr2[1],
+                              hdr->addr2[2], hdr->addr2[3],
+                              hdr->addr2[4], hdr->addr2[5]);
                        /* TODO: could inform hostapd about this so that it
                         * could send auth failure report */
                        goto rx_dropped;
@@ -653,8 +663,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
                         * configured */
                } else {
                        IEEE80211_DEBUG_DROP("encryption configured, but RX "
-                                            "frame not encrypted (SA=%s"
-                                            ")\n", print_mac(mac, hdr->addr2));
+                                            "frame not encrypted (SA="
+                                            MAC_FMT ")\n",
+                                            hdr->addr2[0], hdr->addr2[1],
+                                            hdr->addr2[2], hdr->addr2[3],
+                                            hdr->addr2[4], hdr->addr2[5]);
                        goto rx_dropped;
                }
        }
@@ -662,9 +675,11 @@ int ieee80211_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
        if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !ieee->open_wep &&
            !ieee80211_is_eapol_frame(ieee, skb)) {
                IEEE80211_DEBUG_DROP("dropped unencrypted RX data "
-                                    "frame from %s"
+                                    "frame from " MAC_FMT
                                     " (drop_unencrypted=1)\n",
-                                    print_mac(mac, hdr->addr2));
+                                    hdr->addr2[0], hdr->addr2[1],
+                                    hdr->addr2[2], hdr->addr2[3],
+                                    hdr->addr2[4], hdr->addr2[5]);
                goto rx_dropped;
        }
 
index 9c7e5ff..4670683 100644 (file)
@@ -160,7 +160,7 @@ config IP_PNP_DHCP
 
          If unsure, say Y. Note that if you want to use DHCP, a DHCP server
          must be operating on your network.  Read
-         <file:Documentation/nfsroot.txt> for details.
+         <file:Documentation/filesystems/nfsroot.txt> for details.
 
 config IP_PNP_BOOTP
        bool "IP: BOOTP support"
@@ -175,7 +175,7 @@ config IP_PNP_BOOTP
          does BOOTP itself, providing all necessary information on the kernel
          command line, you can say N here. If unsure, say Y. Note that if you
          want to use BOOTP, a BOOTP server must be operating on your network.
-         Read <file:Documentation/nfsroot.txt> for details.
+         Read <file:Documentation/filesystems/nfsroot.txt> for details.
 
 config IP_PNP_RARP
        bool "IP: RARP support"
@@ -187,8 +187,8 @@ config IP_PNP_RARP
          discovered automatically at boot time using the RARP protocol (an
          older protocol which is being obsoleted by BOOTP and DHCP), say Y
          here. Note that if you want to use RARP, a RARP server must be
-         operating on your network. Read <file:Documentation/nfsroot.txt> for
-         details.
+         operating on your network. Read
+         <file:Documentation/filesystems/nfsroot.txt> for details.
 
 # not yet ready..
 #   bool '    IP: ARP support' CONFIG_IP_PNP_ARP               
index 876169f..717c411 100644 (file)
@@ -124,6 +124,7 @@ struct inet_timewait_sock *inet_twsk_alloc(const struct sock *sk, const int stat
                tw->tw_hash         = sk->sk_hash;
                tw->tw_ipv6only     = 0;
                tw->tw_prot         = sk->sk_prot_creator;
+               tw->tw_net          = sk->sk_net;
                atomic_set(&tw->tw_refcnt, 1);
                inet_twsk_dead_node_init(tw);
                __module_get(tw->tw_prot->owner);
index f72457b..c2921d0 100644 (file)
@@ -1132,7 +1132,7 @@ static int do_ip_getsockopt(struct sock *sk, int level, int optname,
        }
        release_sock(sk);
 
-       if (len < sizeof(int) && len > 0 && val>=0 && val<255) {
+       if (len < sizeof(int) && len > 0 && val>=0 && val<=255) {
                unsigned char ucval = (unsigned char)val;
                len = 1;
                if (put_user(len, optlen))
index 7c992fb..4824fe8 100644 (file)
@@ -1411,7 +1411,7 @@ late_initcall(ip_auto_config);
 
 /*
  *  Decode any IP configuration options in the "ip=" or "nfsaddrs=" kernel
- *  command line parameter.  See Documentation/nfsroot.txt.
+ *  command line parameter.  See Documentation/filesystems/nfsroot.txt.
  */
 static int __init ic_proto_name(char *name)
 {
index 52926c8..a12dd32 100644 (file)
@@ -82,8 +82,8 @@ clusterip_config_put(struct clusterip_config *c)
 static inline void
 clusterip_config_entry_put(struct clusterip_config *c)
 {
+       write_lock_bh(&clusterip_lock);
        if (atomic_dec_and_test(&c->entries)) {
-               write_lock_bh(&clusterip_lock);
                list_del(&c->list);
                write_unlock_bh(&clusterip_lock);
 
@@ -96,7 +96,9 @@ clusterip_config_entry_put(struct clusterip_config *c)
 #ifdef CONFIG_PROC_FS
                remove_proc_entry(c->pde->name, c->pde->parent);
 #endif
+               return;
        }
+       write_unlock_bh(&clusterip_lock);
 }
 
 static struct clusterip_config *
index 0d5fa3a..36b4e3b 100644 (file)
@@ -629,6 +629,8 @@ static int __init nf_nat_init(void)
        size_t i;
        int ret;
 
+       need_ipv4_conntrack();
+
        ret = nf_ct_extend_register(&nat_extend);
        if (ret < 0) {
                printk(KERN_ERR "nf_nat_core: Unable to register extension\n");
index 7facdb0..bbb7d88 100644 (file)
@@ -1625,13 +1625,11 @@ out:
        return flag;
 }
 
-/* If we receive more dupacks than we expected counting segments
- * in assumption of absent reordering, interpret this as reordering.
- * The only another reason could be bug in receiver TCP.
+/* Limits sacked_out so that sum with lost_out isn't ever larger than
+ * packets_out. Returns zero if sacked_out adjustement wasn't necessary.
  */
-static void tcp_check_reno_reordering(struct sock *sk, const int addend)
+int tcp_limit_reno_sacked(struct tcp_sock *tp)
 {
-       struct tcp_sock *tp = tcp_sk(sk);
        u32 holes;
 
        holes = max(tp->lost_out, 1U);
@@ -1639,8 +1637,20 @@ static void tcp_check_reno_reordering(struct sock *sk, const int addend)
 
        if ((tp->sacked_out + holes) > tp->packets_out) {
                tp->sacked_out = tp->packets_out - holes;
-               tcp_update_reordering(sk, tp->packets_out + addend, 0);
+               return 1;
        }
+       return 0;
+}
+
+/* If we receive more dupacks than we expected counting segments
+ * in assumption of absent reordering, interpret this as reordering.
+ * The only another reason could be bug in receiver TCP.
+ */
+static void tcp_check_reno_reordering(struct sock *sk, const int addend)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       if (tcp_limit_reno_sacked(tp))
+               tcp_update_reordering(sk, tp->packets_out + addend, 0);
 }
 
 /* Emulate SACKs for SACKless connection: account for a new dupack. */
@@ -1681,11 +1691,16 @@ static inline void tcp_reset_reno_sack(struct tcp_sock *tp)
 int tcp_use_frto(struct sock *sk)
 {
        const struct tcp_sock *tp = tcp_sk(sk);
+       const struct inet_connection_sock *icsk = inet_csk(sk);
        struct sk_buff *skb;
 
        if (!sysctl_tcp_frto)
                return 0;
 
+       /* MTU probe and F-RTO won't really play nicely along currently */
+       if (icsk->icsk_mtup.probe_size)
+               return 0;
+
        if (IsSackFrto())
                return 1;
 
@@ -2134,11 +2149,13 @@ static void tcp_verify_retransmit_hint(struct tcp_sock *tp, struct sk_buff *skb)
 /* Mark head of queue up as lost. With RFC3517 SACK, the packets is
  * is against sacked "cnt", otherwise it's against facked "cnt"
  */
-static void tcp_mark_head_lost(struct sock *sk, int packets, int fast_rexmit)
+static void tcp_mark_head_lost(struct sock *sk, int packets)
 {
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *skb;
-       int cnt;
+       int cnt, oldcnt;
+       int err;
+       unsigned int mss;
 
        BUG_TRAP(packets <= tp->packets_out);
        if (tp->lost_skb_hint) {
@@ -2157,13 +2174,25 @@ static void tcp_mark_head_lost(struct sock *sk, int packets, int fast_rexmit)
                tp->lost_skb_hint = skb;
                tp->lost_cnt_hint = cnt;
 
+               if (after(TCP_SKB_CB(skb)->end_seq, tp->high_seq))
+                       break;
+
+               oldcnt = cnt;
                if (tcp_is_fack(tp) || tcp_is_reno(tp) ||
                    (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_ACKED))
                        cnt += tcp_skb_pcount(skb);
 
-               if (((!fast_rexmit || (tp->lost_out > 0)) && (cnt > packets)) ||
-                   after(TCP_SKB_CB(skb)->end_seq, tp->high_seq))
-                       break;
+               if (cnt > packets) {
+                       if (tcp_is_sack(tp) || (oldcnt >= packets))
+                               break;
+
+                       mss = skb_shinfo(skb)->gso_size;
+                       err = tcp_fragment(sk, skb, (packets - oldcnt) * mss, mss);
+                       if (err < 0)
+                               break;
+                       cnt = packets;
+               }
+
                if (!(TCP_SKB_CB(skb)->sacked & (TCPCB_SACKED_ACKED|TCPCB_LOST))) {
                        TCP_SKB_CB(skb)->sacked |= TCPCB_LOST;
                        tp->lost_out += tcp_skb_pcount(skb);
@@ -2180,17 +2209,17 @@ static void tcp_update_scoreboard(struct sock *sk, int fast_rexmit)
        struct tcp_sock *tp = tcp_sk(sk);
 
        if (tcp_is_reno(tp)) {
-               tcp_mark_head_lost(sk, 1, fast_rexmit);
+               tcp_mark_head_lost(sk, 1);
        } else if (tcp_is_fack(tp)) {
                int lost = tp->fackets_out - tp->reordering;
                if (lost <= 0)
                        lost = 1;
-               tcp_mark_head_lost(sk, lost, fast_rexmit);
+               tcp_mark_head_lost(sk, lost);
        } else {
                int sacked_upto = tp->sacked_out - tp->reordering;
-               if (sacked_upto < 0)
-                       sacked_upto = 0;
-               tcp_mark_head_lost(sk, sacked_upto, fast_rexmit);
+               if (sacked_upto < fast_rexmit)
+                       sacked_upto = fast_rexmit;
+               tcp_mark_head_lost(sk, sacked_upto);
        }
 
        /* New heuristics: it is possible only after we switched
@@ -2524,7 +2553,7 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
            before(tp->snd_una, tp->high_seq) &&
            icsk->icsk_ca_state != TCP_CA_Open &&
            tp->fackets_out > tp->reordering) {
-               tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering, 0);
+               tcp_mark_head_lost(sk, tp->fackets_out - tp->reordering);
                NET_INC_STATS_BH(LINUX_MIB_TCPLOSS);
        }
 
@@ -2586,6 +2615,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, int flag)
        case TCP_CA_Loss:
                if (flag & FLAG_DATA_ACKED)
                        icsk->icsk_retransmits = 0;
+               if (tcp_is_reno(tp) && flag & FLAG_SND_UNA_ADVANCED)
+                       tcp_reset_reno_sack(tp);
                if (!tcp_try_undo_loss(sk)) {
                        tcp_moderate_cwnd(tp);
                        tcp_xmit_retransmit_queue(sk);
@@ -3810,8 +3841,28 @@ static void tcp_ofo_queue(struct sock *sk)
        }
 }
 
+static int tcp_prune_ofo_queue(struct sock *sk);
 static int tcp_prune_queue(struct sock *sk);
 
+static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size)
+{
+       if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
+           !sk_rmem_schedule(sk, size)) {
+
+               if (tcp_prune_queue(sk) < 0)
+                       return -1;
+
+               if (!sk_rmem_schedule(sk, size)) {
+                       if (!tcp_prune_ofo_queue(sk))
+                               return -1;
+
+                       if (!sk_rmem_schedule(sk, size))
+                               return -1;
+               }
+       }
+       return 0;
+}
+
 static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
 {
        struct tcphdr *th = tcp_hdr(skb);
@@ -3861,12 +3912,9 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb)
                if (eaten <= 0) {
 queue_and_out:
                        if (eaten < 0 &&
-                           (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
-                            !sk_rmem_schedule(sk, skb->truesize))) {
-                               if (tcp_prune_queue(sk) < 0 ||
-                                   !sk_rmem_schedule(sk, skb->truesize))
-                                       goto drop;
-                       }
+                           tcp_try_rmem_schedule(sk, skb->truesize))
+                               goto drop;
+
                        skb_set_owner_r(skb, sk);
                        __skb_queue_tail(&sk->sk_receive_queue, skb);
                }
@@ -3935,12 +3983,8 @@ drop:
 
        TCP_ECN_check_ce(tp, skb);
 
-       if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf ||
-           !sk_rmem_schedule(sk, skb->truesize)) {
-               if (tcp_prune_queue(sk) < 0 ||
-                   !sk_rmem_schedule(sk, skb->truesize))
-                       goto drop;
-       }
+       if (tcp_try_rmem_schedule(sk, skb->truesize))
+               goto drop;
 
        /* Disable header prediction. */
        tp->pred_flags = 0;
@@ -4167,6 +4211,32 @@ static void tcp_collapse_ofo_queue(struct sock *sk)
        }
 }
 
+/*
+ * Purge the out-of-order queue.
+ * Return true if queue was pruned.
+ */
+static int tcp_prune_ofo_queue(struct sock *sk)
+{
+       struct tcp_sock *tp = tcp_sk(sk);
+       int res = 0;
+
+       if (!skb_queue_empty(&tp->out_of_order_queue)) {
+               NET_INC_STATS_BH(LINUX_MIB_OFOPRUNED);
+               __skb_queue_purge(&tp->out_of_order_queue);
+
+               /* Reset SACK state.  A conforming SACK implementation will
+                * do the same at a timeout based retransmit.  When a connection
+                * is in a sad state like this, we care only about integrity
+                * of the connection not performance.
+                */
+               if (tp->rx_opt.sack_ok)
+                       tcp_sack_reset(&tp->rx_opt);
+               sk_mem_reclaim(sk);
+               res = 1;
+       }
+       return res;
+}
+
 /* Reduce allocated memory if we can, trying to get
  * the socket within its memory limits again.
  *
@@ -4200,20 +4270,7 @@ static int tcp_prune_queue(struct sock *sk)
        /* Collapsing did not help, destructive actions follow.
         * This must not ever occur. */
 
-       /* First, purge the out_of_order queue. */
-       if (!skb_queue_empty(&tp->out_of_order_queue)) {
-               NET_INC_STATS_BH(LINUX_MIB_OFOPRUNED);
-               __skb_queue_purge(&tp->out_of_order_queue);
-
-               /* Reset SACK state.  A conforming SACK implementation will
-                * do the same at a timeout based retransmit.  When a connection
-                * is in a sad state like this, we care only about integrity
-                * of the connection not performance.
-                */
-               if (tcp_is_sack(tp))
-                       tcp_sack_reset(&tp->rx_opt);
-               sk_mem_reclaim(sk);
-       }
+       tcp_prune_ofo_queue(sk);
 
        if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf)
                return 0;
index 72b9350..d29ef79 100644 (file)
@@ -1808,6 +1808,9 @@ void tcp_simple_retransmit(struct sock *sk)
        if (!lost)
                return;
 
+       if (tcp_is_reno(tp))
+               tcp_limit_reno_sacked(tp);
+
        tcp_verify_left_out(tp);
 
        /* Don't muck with the congestion window here.
index a65935a..e08955b 100644 (file)
@@ -371,25 +371,26 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
         */
        in6_dev_hold(ndev);
 
+#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+       if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
+               printk(KERN_INFO
+                      "%s: Disabled Multicast RS\n",
+                      dev->name);
+               ndev->cnf.rtr_solicits = 0;
+       }
+#endif
+
 #ifdef CONFIG_IPV6_PRIVACY
        setup_timer(&ndev->regen_timer, ipv6_regen_rndid, (unsigned long)ndev);
        if ((dev->flags&IFF_LOOPBACK) ||
            dev->type == ARPHRD_TUNNEL ||
-#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
+           dev->type == ARPHRD_TUNNEL6 ||
            dev->type == ARPHRD_SIT ||
-#endif
            dev->type == ARPHRD_NONE) {
                printk(KERN_INFO
                       "%s: Disabled Privacy Extensions\n",
                       dev->name);
                ndev->cnf.use_tempaddr = -1;
-
-               if (dev->type == ARPHRD_SIT && (dev->priv_flags & IFF_ISATAP)) {
-                       printk(KERN_INFO
-                              "%s: Disabled Multicast RS\n",
-                              dev->name);
-                       ndev->cnf.rtr_solicits = 0;
-               }
        } else {
                in6_dev_hold(ndev);
                ipv6_regen_rndid((unsigned long) ndev);
index 8897ccf..0a6fbc1 100644 (file)
@@ -372,8 +372,10 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
        read_lock(&raw_v6_hashinfo.lock);
        sk = sk_head(&raw_v6_hashinfo.ht[hash]);
        if (sk != NULL) {
-               saddr = &ipv6_hdr(skb)->saddr;
-               daddr = &ipv6_hdr(skb)->daddr;
+               struct ipv6hdr *hdr = (struct ipv6hdr *) skb->data;
+
+               saddr = &hdr->saddr;
+               daddr = &hdr->daddr;
                net = skb->dev->nd_net;
 
                while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
index e0c72d0..c170685 100644 (file)
@@ -312,14 +312,12 @@ static void ieee80211_sta_wmm_params(struct net_device *dev,
        }
 }
 
-
-static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
-                                  u8 erp_value)
+static u32 ieee80211_handle_protect_preamb(struct ieee80211_sub_if_data *sdata,
+                                          bool use_protection,
+                                          bool use_short_preamble)
 {
        struct ieee80211_bss_conf *bss_conf = &sdata->bss_conf;
        struct ieee80211_if_sta *ifsta = &sdata->u.sta;
-       bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
-       bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;
        DECLARE_MAC_BUF(mac);
        u32 changed = 0;
 
@@ -350,6 +348,32 @@ static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
        return changed;
 }
 
+static u32 ieee80211_handle_erp_ie(struct ieee80211_sub_if_data *sdata,
+                                  u8 erp_value)
+{
+       bool use_protection = (erp_value & WLAN_ERP_USE_PROTECTION) != 0;
+       bool use_short_preamble = (erp_value & WLAN_ERP_BARKER_PREAMBLE) == 0;
+
+       return ieee80211_handle_protect_preamb(sdata,
+                       use_protection, use_short_preamble);
+}
+
+static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
+                                          struct ieee80211_sta_bss *bss)
+{
+       u32 changed = 0;
+
+       if (bss->has_erp_value)
+               changed |= ieee80211_handle_erp_ie(sdata, bss->erp_value);
+       else {
+               u16 capab = bss->capability;
+               changed |= ieee80211_handle_protect_preamb(sdata, false,
+                               (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
+       }
+
+       return changed;
+}
+
 int ieee80211_ht_cap_ie_to_ht_info(struct ieee80211_ht_cap *ht_cap_ie,
                                   struct ieee80211_ht_info *ht_info)
 {
@@ -468,9 +492,7 @@ static void ieee80211_set_associated(struct net_device *dev,
                                           local->hw.conf.channel,
                                           ifsta->ssid, ifsta->ssid_len);
                if (bss) {
-                       if (bss->has_erp_value)
-                               changed |= ieee80211_handle_erp_ie(
-                                               sdata, bss->erp_value);
+                       changed |= ieee80211_handle_bss_capability(sdata, bss);
                        ieee80211_rx_bss_put(dev, bss);
                }
 
@@ -2116,6 +2138,11 @@ static void ieee80211_rx_mgmt_beacon(struct net_device *dev,
 
        if (elems.erp_info && elems.erp_info_len >= 1)
                changed |= ieee80211_handle_erp_ie(sdata, elems.erp_info[0]);
+       else {
+               u16 capab = le16_to_cpu(mgmt->u.beacon.capab_info);
+               changed |= ieee80211_handle_protect_preamb(sdata, false,
+                               (capab & WLAN_CAPABILITY_SHORT_PREAMBLE) != 0);
+       }
 
        if (elems.ht_cap_elem && elems.ht_info_elem &&
            elems.wmm_param && local->ops->conf_ht &&
index 535407d..a8a40ab 100644 (file)
@@ -1050,12 +1050,9 @@ ieee80211_drop_unencrypted(struct ieee80211_txrx_data *rx)
        if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) &&
                     (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA &&
                     (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC &&
-                    (rx->key || rx->sdata->drop_unencrypted))) {
-               if (net_ratelimit())
-                       printk(KERN_DEBUG "%s: RX non-WEP frame, but expected "
-                              "encryption\n", rx->dev->name);
+                    (rx->key || rx->sdata->drop_unencrypted)))
                return -EACCES;
-       }
+
        return 0;
 }
 
index dc29007..40d344b 100644 (file)
@@ -466,38 +466,25 @@ static inline void rateinfo_recalc(struct dsthash_ent *dh, unsigned long now)
 
 static inline __be32 maskl(__be32 a, unsigned int l)
 {
-       return htonl(ntohl(a) & ~(~(u_int32_t)0 >> l));
+       return l ? htonl(ntohl(a) & ~0 << (32 - l)) : 0;
 }
 
 #if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
 static void hashlimit_ipv6_mask(__be32 *i, unsigned int p)
 {
        switch (p) {
-       case 0:
-               i[0] = i[1] = 0;
-               i[2] = i[3] = 0;
-               break;
-       case 1 ... 31:
+       case 0 ... 31:
                i[0] = maskl(i[0], p);
                i[1] = i[2] = i[3] = 0;
                break;
-       case 32:
-               i[1] = i[2] = i[3] = 0;
-               break;
-       case 33 ... 63:
+       case 32 ... 63:
                i[1] = maskl(i[1], p - 32);
                i[2] = i[3] = 0;
                break;
-       case 64:
-               i[2] = i[3] = 0;
-               break;
-       case 65 ... 95:
+       case 64 ... 95:
                i[2] = maskl(i[2], p - 64);
                i[3] = 0;
-       case 96:
-               i[3] = 0;
-               break;
-       case 97 ... 127:
+       case 96 ... 127:
                i[3] = maskl(i[3], p - 96);
                break;
        case 128:
index 140a0a8..4e10a95 100644 (file)
@@ -92,7 +92,7 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state)
        rfkill_states[type] = state;
 
        list_for_each_entry(rfkill, &rfkill_list, node) {
-               if (!rfkill->user_claim)
+               if ((!rfkill->user_claim) && (rfkill->type == type))
                        rfkill_toggle_radio(rfkill, state);
        }
 
index 2d0c29c..4b2682f 100644 (file)
@@ -27,7 +27,7 @@ MODULE_ALIAS_NETPROTO(PF_RXRPC);
 
 unsigned rxrpc_debug; // = RXRPC_DEBUG_KPROTO;
 module_param_named(debug, rxrpc_debug, uint, S_IWUSR | S_IRUGO);
-MODULE_PARM_DESC(rxrpc_debug, "RxRPC debugging mask");
+MODULE_PARM_DESC(debug, "RxRPC debugging mask");
 
 static int sysctl_rxrpc_max_qlen __read_mostly = 10;
 
index d1c296f..6d38a81 100644 (file)
@@ -31,7 +31,7 @@
 
 unsigned rxrpc_debug;
 module_param_named(debug, rxrpc_debug, uint, S_IWUSR | S_IRUGO);
-MODULE_PARM_DESC(rxrpc_debug, "rxkad debugging mask");
+MODULE_PARM_DESC(debug, "rxkad debugging mask");
 
 struct rxkad_level1_hdr {
        __be32  data_size;      /* true data size (excluding padding) */
index c5c16b4..4d75544 100644 (file)
@@ -411,8 +411,10 @@ static void u32_destroy(struct tcf_proto *tp)
                        }
                }
 
-               for (ht=tp_c->hlist; ht; ht = ht->next)
+               for (ht = tp_c->hlist; ht; ht = ht->next) {
+                       ht->refcnt--;
                        u32_clear_hnode(tp, ht);
+               }
 
                while ((ht = tp_c->hlist) != NULL) {
                        tp_c->hlist = ht->next;
@@ -441,8 +443,12 @@ static int u32_delete(struct tcf_proto *tp, unsigned long arg)
        if (tp->root == ht)
                return -EINVAL;
 
-       if (--ht->refcnt == 0)
+       if (ht->refcnt == 1) {
+               ht->refcnt--;
                u32_destroy_hnode(tp, ht);
+       } else {
+               return -EBUSY;
+       }
 
        return 0;
 }
@@ -568,7 +574,7 @@ static int u32_change(struct tcf_proto *tp, unsigned long base, u32 handle,
                if (ht == NULL)
                        return -ENOBUFS;
                ht->tp_c = tp_c;
-               ht->refcnt = 0;
+               ht->refcnt = 1;
                ht->divisor = divisor;
                ht->handle = handle;
                ht->prio = tp->prio;
index 7e3c048..fc8708a 100644 (file)
@@ -386,6 +386,9 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n)
        if (n == 0)
                return;
        while ((parentid = sch->parent)) {
+               if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS))
+                       return;
+
                sch = qdisc_lookup(sch->dev, TC_H_MAJ(parentid));
                if (sch == NULL) {
                        WARN_ON(parentid != TC_H_ROOT);
index b1e05d7..85f1495 100644 (file)
@@ -110,8 +110,9 @@ static int sctp_inet6addr_event(struct notifier_block *this, unsigned long ev,
                spin_lock_bh(&sctp_local_addr_lock);
                list_for_each_entry_safe(addr, temp,
                                        &sctp_local_addr_list, list) {
-                       if (ipv6_addr_equal(&addr->a.v6.sin6_addr,
-                                            &ifa->addr)) {
+                       if (addr->a.sa.sa_family == AF_INET6 &&
+                                       ipv6_addr_equal(&addr->a.v6.sin6_addr,
+                                               &ifa->addr)) {
                                found = 1;
                                addr->valid = 0;
                                list_del_rcu(&addr->list);
index 1bb3c5c..c071446 100644 (file)
@@ -793,6 +793,9 @@ int sctp_outq_flush(struct sctp_outq *q, int rtx_timeout)
                        break;
 
                case SCTP_CID_ABORT:
+                       if (sctp_test_T_bit(chunk)) {
+                               packet->vtag = asoc->c.my_vtag;
+                       }
                case SCTP_CID_SACK:
                case SCTP_CID_HEARTBEAT:
                case SCTP_CID_HEARTBEAT_ACK:
index f90091a..c2dd65d 100644 (file)
@@ -647,7 +647,9 @@ static int sctp_inetaddr_event(struct notifier_block *this, unsigned long ev,
                spin_lock_bh(&sctp_local_addr_lock);
                list_for_each_entry_safe(addr, temp,
                                        &sctp_local_addr_list, list) {
-                       if (addr->a.v4.sin_addr.s_addr == ifa->ifa_local) {
+                       if (addr->a.sa.sa_family == AF_INET &&
+                                       addr->a.v4.sin_addr.s_addr ==
+                                       ifa->ifa_local) {
                                found = 1;
                                addr->valid = 0;
                                list_del_rcu(&addr->list);
index 578630e..36ebb39 100644 (file)
@@ -1982,7 +1982,10 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
                                        struct sctp_chunk *chunk,
                                        struct sctp_chunk **err_chunk)
 {
+       struct sctp_hmac_algo_param *hmacs;
        int retval = SCTP_IERROR_NO_ERROR;
+       __u16 n_elt, id = 0;
+       int i;
 
        /* FIXME - This routine is not looking at each parameter per the
         * chunk type, i.e., unrecognized parameters should be further
@@ -2056,9 +2059,29 @@ static sctp_ierror_t sctp_verify_param(const struct sctp_association *asoc,
                break;
 
        case SCTP_PARAM_HMAC_ALGO:
-               if (sctp_auth_enable)
-                       break;
-               /* Fall Through */
+               if (!sctp_auth_enable)
+                       goto fallthrough;
+
+               hmacs = (struct sctp_hmac_algo_param *)param.p;
+               n_elt = (ntohs(param.p->length) - sizeof(sctp_paramhdr_t)) >> 1;
+
+               /* SCTP-AUTH: Section 6.1
+                * The HMAC algorithm based on SHA-1 MUST be supported and
+                * included in the HMAC-ALGO parameter.
+                */
+               for (i = 0; i < n_elt; i++) {
+                       id = ntohs(hmacs->hmac_ids[i]);
+
+                       if (id == SCTP_AUTH_HMAC_ID_SHA1)
+                               break;
+               }
+
+               if (id != SCTP_AUTH_HMAC_ID_SHA1) {
+                       sctp_process_inv_paramlength(asoc, param.p, chunk,
+                                                    err_chunk);
+                       retval = SCTP_IERROR_ABORT;
+               }
+               break;
 fallthrough:
        default:
                SCTP_DEBUG_PRINTK("Unrecognized param: %d for chunk %d.\n",
index 28eb38e..a4763fd 100644 (file)
@@ -1536,6 +1536,9 @@ static int sctp_cmd_interpreter(sctp_event_t event_type,
                        error = sctp_auth_asoc_init_active_key(asoc,
                                                GFP_ATOMIC);
                        break;
+               case SCTP_CMD_UPDATE_INITTAG:
+                       asoc->peer.i.init_tag = cmd->obj.u32;
+                       break;
 
                default:
                        printk(KERN_WARNING "Impossible command: %u, %p\n",
index f2ed647..07194c2 100644 (file)
@@ -4144,6 +4144,24 @@ static sctp_disposition_t sctp_sf_abort_violation(
                goto nomem;
 
        if (asoc) {
+               /* Treat INIT-ACK as a special case during COOKIE-WAIT. */
+               if (chunk->chunk_hdr->type == SCTP_CID_INIT_ACK &&
+                   !asoc->peer.i.init_tag) {
+                       sctp_initack_chunk_t *initack;
+
+                       initack = (sctp_initack_chunk_t *)chunk->chunk_hdr;
+                       if (!sctp_chunk_length_valid(chunk,
+                                                    sizeof(sctp_initack_chunk_t)))
+                               abort->chunk_hdr->flags |= SCTP_CHUNK_FLAG_T;
+                       else {
+                               unsigned int inittag;
+
+                               inittag = ntohl(initack->init_hdr.init_tag);
+                               sctp_add_cmd_sf(commands, SCTP_CMD_UPDATE_INITTAG,
+                                               SCTP_U32(inittag));
+                       }
+               }
+
                sctp_add_cmd_sf(commands, SCTP_CMD_REPLY, SCTP_CHUNK(abort));
                SCTP_INC_STATS(SCTP_MIB_OUTCTRLCHUNKS);
 
@@ -4349,6 +4367,7 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
                                       sctp_cmd_seq_t *commands)
 {
        struct sctp_chunk *repl;
+       struct sctp_association* my_asoc;
 
        /* The comment below says that we enter COOKIE-WAIT AFTER
         * sending the INIT, but that doesn't actually work in our
@@ -4372,8 +4391,8 @@ sctp_disposition_t sctp_sf_do_prm_asoc(const struct sctp_endpoint *ep,
        /* Cast away the const modifier, as we want to just
         * rerun it through as a sideffect.
         */
-       sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC,
-                       SCTP_ASOC((struct sctp_association *) asoc));
+       my_asoc = (struct sctp_association *)asoc;
+       sctp_add_cmd_sf(commands, SCTP_CMD_NEW_ASOC, SCTP_ASOC(my_asoc));
 
        /* Choose transport for INIT. */
        sctp_add_cmd_sf(commands, SCTP_CMD_INIT_CHOOSE_TRANSPORT,
index d994d82..998e63a 100644 (file)
@@ -5868,11 +5868,12 @@ SCTP_STATIC int sctp_msghdr_parse(const struct msghdr *msg,
                                  sctp_cmsgs_t *cmsgs)
 {
        struct cmsghdr *cmsg;
+       struct msghdr *my_msg = (struct msghdr *)msg;
 
        for (cmsg = CMSG_FIRSTHDR(msg);
             cmsg != NULL;
-            cmsg = CMSG_NXTHDR((struct msghdr*)msg, cmsg)) {
-               if (!CMSG_OK(msg, cmsg))
+            cmsg = CMSG_NXTHDR(my_msg, cmsg)) {
+               if (!CMSG_OK(my_msg, cmsg))
                        return -EINVAL;
 
                /* Should we parse this header or ignore?  */
index b43f1f1..ce6cda6 100644 (file)
@@ -859,7 +859,7 @@ __u16 sctp_ulpevent_get_notification_type(const struct sctp_ulpevent *event)
        union sctp_notification *notification;
        struct sk_buff *skb;
 
-       skb = sctp_event2skb((struct sctp_ulpevent *)event);
+       skb = sctp_event2skb(event);
        notification = (union sctp_notification *) skb->data;
        return notification->sn_header.sn_type;
 }
index 8c6a7f1..8834d68 100644 (file)
@@ -261,10 +261,6 @@ struct rpc_clnt *rpc_create(struct rpc_create_args *args)
        };
        char servername[48];
 
-       xprt = xprt_create_transport(&xprtargs);
-       if (IS_ERR(xprt))
-               return (struct rpc_clnt *)xprt;
-
        /*
         * If the caller chooses not to specify a hostname, whip
         * up a string representation of the passed-in address.
index 995c3fd..79a55d5 100644 (file)
@@ -244,7 +244,7 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
        pgto = pages + (pgbase >> PAGE_CACHE_SHIFT);
        pgbase &= ~PAGE_CACHE_MASK;
 
-       do {
+       for (;;) {
                copy = PAGE_CACHE_SIZE - pgbase;
                if (copy > len)
                        copy = len;
@@ -253,6 +253,10 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
                memcpy(vto + pgbase, p, copy);
                kunmap_atomic(vto, KM_USER0);
 
+               len -= copy;
+               if (len == 0)
+                       break;
+
                pgbase += copy;
                if (pgbase == PAGE_CACHE_SIZE) {
                        flush_dcache_page(*pgto);
@@ -260,8 +264,7 @@ _copy_to_pages(struct page **pages, size_t pgbase, const char *p, size_t len)
                        pgto++;
                }
                p += copy;
-
-       } while ((len -= copy) != 0);
+       }
        flush_dcache_page(*pgto);
 }
 
index e3a214f..f68a5c8 100644 (file)
@@ -945,7 +945,7 @@ static int nl80211_new_station(struct sk_buff *skb, struct genl_info *info)
                nla_len(info->attrs[NL80211_ATTR_STA_SUPPORTED_RATES]);
        params.listen_interval =
                nla_get_u16(info->attrs[NL80211_ATTR_STA_LISTEN_INTERVAL]);
-       params.listen_interval = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
+       params.aid = nla_get_u16(info->attrs[NL80211_ATTR_STA_AID]);
 
        if (parse_station_flags(info->attrs[NL80211_ATTR_STA_FLAGS],
                                &params.station_flags))
index 5d96f27..019d21d 100644 (file)
@@ -288,7 +288,7 @@ static void copy_from_user_state(struct xfrm_state *x, struct xfrm_usersa_info *
        memcpy(&x->props.saddr, &p->saddr, sizeof(x->props.saddr));
        x->props.flags = p->flags;
 
-       if (x->props.mode == XFRM_MODE_TRANSPORT)
+       if (!x->sel.family)
                x->sel.family = p->family;
 
 }
index 89bb6d3..d39b59c 100644 (file)
@@ -760,13 +760,13 @@ static void selinux_sb_clone_mnt_opts(const struct super_block *oldsb,
         * this early in the boot process. */
        BUG_ON(!ss_initialized);
 
-       /* this might go away sometime down the line if there is a new user
-        * of clone, but for now, nfs better not get here... */
-       BUG_ON(newsbsec->initialized);
-
        /* how can we clone if the old one wasn't set up?? */
        BUG_ON(!oldsbsec->initialized);
 
+       /* if fs is reusing a sb, just let its options stand... */
+       if (newsbsec->initialized)
+               return;
+
        mutex_lock(&newsbsec->lock);
 
        newsbsec->flags = oldsbsec->flags;
index 25ccfce..7d911a1 100644 (file)
@@ -617,6 +617,18 @@ static int snd_es1968_ac97_wait(struct es1968 *chip)
        return 1; /* timeout */
 }
 
+static int snd_es1968_ac97_wait_poll(struct es1968 *chip)
+{
+       int timeout = 100000;
+
+       while (timeout-- > 0) {
+               if (!(inb(chip->io_port + ESM_AC97_INDEX) & 1))
+                       return 0;
+       }
+       snd_printd("es1968: ac97 timeout\n");
+       return 1; /* timeout */
+}
+
 static void snd_es1968_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val)
 {
        struct es1968 *chip = ac97->private_data;
@@ -645,7 +657,7 @@ static unsigned short snd_es1968_ac97_read(struct snd_ac97 *ac97, unsigned short
        outb(reg | 0x80, chip->io_port + ESM_AC97_INDEX);
        /*msleep(1);*/
 
-       if (! snd_es1968_ac97_wait(chip)) {
+       if (!snd_es1968_ac97_wait_poll(chip)) {
                data = inw(chip->io_port + ESM_AC97_DATA);
                /*msleep(1);*/
        }