Merge branch 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied...
authorLinus Torvalds <torvalds@g5.osdl.org>
Sun, 23 Apr 2006 16:41:20 +0000 (09:41 -0700)
committerLinus Torvalds <torvalds@g5.osdl.org>
Sun, 23 Apr 2006 16:41:20 +0000 (09:41 -0700)
* 'drm-patches' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm: possible cleanups
  drm: fixup r300 scratch on BE machines

215 files changed:
Documentation/block/switching-sched.txt [new file with mode: 0644]
Documentation/feature-removal-schedule.txt
Documentation/vm/hugetlbpage.txt
MAINTAINERS
README
arch/arm/configs/ep93xx_defconfig
arch/arm/configs/ixp2000_defconfig
arch/arm/configs/ixp23xx_defconfig
arch/arm/kernel/setup.c
arch/arm/mach-ixp4xx/common.c
arch/i386/kernel/apm.c
arch/i386/kernel/cpu/amd.c
arch/i386/kernel/cpuid.c
arch/i386/kernel/kprobes.c
arch/i386/kernel/msr.c
arch/i386/mach-voyager/voyager_cat.c
arch/ia64/kernel/kprobes.c
arch/m32r/kernel/entry.S
arch/m32r/kernel/process.c
arch/m32r/kernel/signal.c
arch/powerpc/configs/g5_defconfig
arch/powerpc/configs/iseries_defconfig
arch/powerpc/configs/pseries_defconfig
arch/powerpc/kernel/iommu.c
arch/powerpc/kernel/kprobes.c
arch/powerpc/kernel/pci_iommu.c
arch/powerpc/kernel/ppc_ksyms.c
arch/powerpc/kernel/prom.c
arch/powerpc/kernel/systbl.S
arch/powerpc/kernel/vio.c
arch/powerpc/platforms/cell/spu_callbacks.c
arch/powerpc/platforms/powermac/low_i2c.c
arch/powerpc/sysdev/dart_iommu.c
arch/ppc/kernel/asm-offsets.c
arch/ppc/kernel/entry.S
arch/ppc/kernel/ppc_ksyms.c
arch/sparc64/kernel/kprobes.c
arch/um/drivers/cow_user.c
arch/um/include/longjmp.h
arch/um/include/sysdep-i386/kernel-offsets.h
arch/um/include/sysdep-x86_64/kernel-offsets.h
arch/um/os-Linux/mem.c
arch/um/os-Linux/process.c
arch/um/os-Linux/skas/process.c
arch/um/os-Linux/start_up.c
arch/um/os-Linux/trap.c
arch/um/os-Linux/uaccess.c
arch/um/os-Linux/util.c
arch/um/sys-i386/signal.c
arch/um/sys-i386/stub_segv.c
arch/um/sys-x86_64/stub_segv.c
arch/x86_64/ia32/Makefile
arch/x86_64/kernel/kprobes.c
arch/x86_64/kernel/pci-gart.c
arch/x86_64/kernel/process.c
arch/x86_64/kernel/setup.c
arch/x86_64/mm/numa.c
block/elevator.c
block/ll_rw_blk.c
drivers/char/cs5535_gpio.c
drivers/char/ipmi/ipmi_bt_sm.c
drivers/char/ipmi/ipmi_si_intf.c
drivers/char/snsc.c
drivers/char/sonypi.c
drivers/char/tpm/Kconfig
drivers/char/tpm/Makefile
drivers/char/tpm/tpm.c
drivers/char/tpm/tpm.h
drivers/char/tpm/tpm_atmel.c
drivers/char/tpm/tpm_atmel.h
drivers/char/tpm/tpm_bios.c
drivers/char/tpm/tpm_infineon.c
drivers/char/tpm/tpm_nsc.c
drivers/char/tpm/tpm_tis.c [new file with mode: 0644]
drivers/char/tty_io.c
drivers/i2c/busses/i2c-i801.c
drivers/i2c/chips/m41t00.c
drivers/ide/pci/alim15x3.c
drivers/ide/pci/atiixp.c
drivers/ide/pci/pdc202xx_old.c
drivers/ide/setup-pci.c
drivers/infiniband/core/mad.c
drivers/infiniband/hw/ipath/ipath_diag.c
drivers/infiniband/hw/ipath/ipath_driver.c
drivers/infiniband/hw/ipath/ipath_intr.c
drivers/infiniband/hw/ipath/ipath_kernel.h
drivers/infiniband/hw/ipath/ipath_layer.c
drivers/infiniband/hw/ipath/ipath_pe800.c
drivers/infiniband/hw/ipath/ipath_qp.c
drivers/infiniband/hw/ipath/ipath_ud.c
drivers/infiniband/hw/ipath/ipath_verbs.c
drivers/infiniband/hw/ipath/ipath_verbs.h
drivers/infiniband/hw/mthca/mthca_mad.c
drivers/infiniband/ulp/srp/ib_srp.c
drivers/isdn/gigaset/bas-gigaset.c
drivers/isdn/gigaset/common.c
drivers/isdn/gigaset/ev-layer.c
drivers/isdn/gigaset/gigaset.h
drivers/isdn/gigaset/i4l.c
drivers/isdn/gigaset/isocdata.c
drivers/macintosh/therm_adt746x.c
drivers/md/md.c
drivers/net/ne.c
drivers/net/sungem_phy.c
drivers/net/wireless/Kconfig
drivers/net/wireless/airo.c
drivers/net/wireless/atmel.c
drivers/net/wireless/bcm43xx/Kconfig
drivers/net/wireless/bcm43xx/bcm43xx.h
drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
drivers/net/wireless/bcm43xx/bcm43xx_dma.c
drivers/net/wireless/bcm43xx/bcm43xx_main.c
drivers/net/wireless/bcm43xx/bcm43xx_phy.c
drivers/net/wireless/bcm43xx/bcm43xx_power.c
drivers/net/wireless/bcm43xx/bcm43xx_power.h
drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h
drivers/net/wireless/bcm43xx/bcm43xx_wx.c
drivers/net/wireless/orinoco.c
drivers/parport/parport_pc.c
drivers/pci/quirks.c
drivers/pnp/manager.c
drivers/serial/m32r_sio.c
drivers/video/aty/radeon_base.c
drivers/video/fbmem.c
drivers/video/pm2fb.c
drivers/video/savage/savagefb_driver.c
fs/Kconfig
fs/cifs/CHANGES
fs/cifs/README
fs/cifs/cifsfs.c
fs/cifs/cifssmb.c
fs/cifs/connect.c
fs/cifs/dir.c
fs/cifs/fcntl.c
fs/cifs/file.c
fs/cifs/inode.c
fs/cifs/link.c
fs/cifs/ntlmssp.c
fs/cifs/readdir.c
fs/cifs/xattr.c
fs/exec.c
fs/lockd/svclock.c
fs/locks.c
fs/nfs/dir.c
fs/nfs/direct.c
fs/nfs/file.c
fs/nfs/inode.c
fs/nfs/nfs4proc.c
fs/proc/base.c
fs/reiserfs/xattr_acl.c
fs/splice.c
include/asm-i386/atomic.h
include/asm-i386/cpufeature.h
include/asm-i386/i387.h
include/asm-m32r/assembler.h
include/asm-m32r/mappi3/mappi3_pld.h
include/asm-m32r/ptrace.h
include/asm-m32r/semaphore.h
include/asm-m32r/sigcontext.h
include/asm-m32r/system.h
include/asm-powerpc/iommu.h
include/asm-powerpc/machdep.h
include/asm-sparc/unistd.h
include/asm-sparc64/unistd.h
include/asm-x86_64/cache.h
include/asm-x86_64/cpufeature.h
include/asm-x86_64/i387.h
include/asm-x86_64/percpu.h
include/asm-xtensa/ioctls.h
include/linux/ide.h
include/linux/memory_hotplug.h
include/linux/pci_ids.h
include/linux/sched.h
include/linux/skbuff.h
include/linux/sunrpc/metrics.h
include/linux/sunrpc/xprt.h
include/net/ieee80211softmac.h
include/net/sock.h
kernel/exit.c
kernel/fork.c
kernel/kprobes.c
kernel/power/snapshot.c
kernel/uid16.c
lib/Kconfig.debug
mm/mempolicy.c
mm/oom_kill.c
mm/page_alloc.c
mm/shmem.c
mm/slob.c
net/bridge/netfilter/ebtables.c
net/core/dev.c
net/core/skbuff.c
net/core/stream.c
net/core/wireless.c
net/ieee80211/softmac/Kconfig
net/ieee80211/softmac/ieee80211softmac_assoc.c
net/ieee80211/softmac/ieee80211softmac_event.c
net/ieee80211/softmac/ieee80211softmac_io.c
net/ieee80211/softmac/ieee80211softmac_scan.c
net/ieee80211/softmac/ieee80211softmac_wx.c
net/ipv4/tcp_output.c
net/llc/llc_input.c
net/socket.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/auth_gss/gss_krb5_crypto.c
net/sunrpc/stats.c
scripts/kconfig/conf.c
security/selinux/ss/mls.c
sound/drivers/mpu401/mpu401_uart.c
sound/oss/Kconfig
sound/oss/dmasound/tas_common.c
sound/ppc/daca.c
sound/ppc/tumbler.c
usr/gen_init_cpio.c

diff --git a/Documentation/block/switching-sched.txt b/Documentation/block/switching-sched.txt
new file mode 100644 (file)
index 0000000..5fa130a
--- /dev/null
@@ -0,0 +1,22 @@
+As of the Linux 2.6.10 kernel, it is now possible to change the
+IO scheduler for a given block device on the fly (thus making it possible,
+for instance, to set the CFQ scheduler for the system default, but
+set a specific device to use the anticipatory or noop schedulers - which
+can improve that device's throughput).
+
+To set a specific scheduler, simply do this:
+
+echo SCHEDNAME > /sys/block/DEV/queue/scheduler
+
+where SCHEDNAME is the name of a defined IO scheduler, and DEV is the
+device name (hda, hdb, sga, or whatever you happen to have).
+
+The list of defined schedulers can be found by simply doing
+a "cat /sys/block/DEV/queue/scheduler" - the list of valid names
+will be displayed, with the currently selected scheduler in brackets:
+
+# cat /sys/block/hda/queue/scheduler
+noop anticipatory deadline [cfq]
+# echo anticipatory > /sys/block/hda/queue/scheduler
+# cat /sys/block/hda/queue/scheduler
+noop [anticipatory] deadline cfq
index 293fed113dff3fe08dbffb4db235ca62612ea7fc..421bcfff6ad21be680fcf819243ca9d750fa8ab2 100644 (file)
@@ -25,8 +25,9 @@ Who:  Adrian Bunk <bunk@stusta.de>
 
 ---------------------------
 
-What:  drivers depending on OBSOLETE_OSS_DRIVER
-When:  January 2006
+What:  drivers that were depending on OBSOLETE_OSS_DRIVER
+        (config options already removed)
+When:  before 2.6.19
 Why:   OSS drivers with ALSA replacements
 Who:   Adrian Bunk <bunk@stusta.de>
 
index 2803f63c1a27622a3e3f3680d6c2a6398c993c7e..687104bfd09a79eef794b8dbe1357c33864d028c 100644 (file)
@@ -32,7 +32,16 @@ The output of "cat /proc/meminfo" will have lines like:
 .....
 HugePages_Total: xxx
 HugePages_Free:  yyy
-Hugepagesize:    zzz KB
+HugePages_Rsvd:  www
+Hugepagesize:    zzz kB
+
+where:
+HugePages_Total is the size of the pool of hugepages.
+HugePages_Free is the number of hugepages in the pool that are not yet
+allocated.
+HugePages_Rsvd is short for "reserved," and is the number of hugepages
+for which a commitment to allocate from the pool has been made, but no
+allocation has yet been made. It's vaguely analogous to overcommit.
 
 /proc/filesystems should also show a filesystem of type "hugetlbfs" configured
 in the kernel.
index 78a2f5b4322e9b129da34f19d4c07985f2fc8f1c..61060e82fb0eb0f28b5c496f045e7b2b7845f6b1 100644 (file)
@@ -1458,6 +1458,13 @@ M:       support@pathscale.com
 L:     openib-general@openib.org
 S:     Supported
 
+IPMI SUBSYSTEM
+P:     Corey Minyard
+M:     minyard@acm.org
+L:     openipmi-developer@lists.sourceforge.net
+W:     http://openipmi.sourceforge.net/
+S:     Supported
+
 IPX NETWORK LAYER
 P:     Arnaldo Carvalho de Melo
 M:     acme@conectiva.com.br
diff --git a/README b/README
index 05e055530bbb687599dd732d6753c77ffa281ae5..3e264723b863add275e6f32c44762f8d09cfe0a0 100644 (file)
--- a/README
+++ b/README
@@ -165,10 +165,31 @@ CONFIGURING the kernel:
        "make xconfig"     X windows (Qt) based configuration tool.
        "make gconfig"     X windows (Gtk) based configuration tool.
        "make oldconfig"   Default all questions based on the contents of
-                          your existing ./.config file.
+                          your existing ./.config file and asking about
+                          new config symbols.
        "make silentoldconfig"
                           Like above, but avoids cluttering the screen
                           with questions already answered.
+       "make defconfig"   Create a ./.config file by using the default
+                          symbol values from arch/$ARCH/defconfig.
+       "make allyesconfig"
+                          Create a ./.config file by setting symbol
+                          values to 'y' as much as possible.
+       "make allmodconfig"
+                          Create a ./.config file by setting symbol
+                          values to 'm' as much as possible.
+       "make allnoconfig" Create a ./.config file by setting symbol
+                          values to 'n' as much as possible.
+       "make randconfig"  Create a ./.config file by setting symbol
+                          values to random values.
+
+   The allyesconfig/allmodconfig/allnoconfig/randconfig variants can
+   also use the environment variable KCONFIG_ALLCONFIG to specify a
+   filename that contains config options that the user requires to be
+   set to a specific value.  If KCONFIG_ALLCONFIG=filename is not used,
+   "make *config" checks for a file named "all{yes/mod/no/random}.config"
+   for symbol values that are to be forced.  If this file is not found,
+   it checks for a file named "all.config" to contain forced values.
    
        NOTES on "make config":
        - having unnecessary drivers will make the kernel bigger, and can
index 8dcc8e8ec81314a662a5a60fd5fd028ce11829df..b69e88bbc909d906df7730eecf9b8e897e691fc0 100644 (file)
@@ -1,12 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16
-# Mon Mar 20 14:54:51 2006
+# Linux kernel version: 2.6.17-rc2
+# Wed Apr 19 21:21:01 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
 
 #
 # Code maturity level options
@@ -28,6 +30,7 @@ CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -43,10 +46,6 @@ CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
@@ -59,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
@@ -67,6 +65,7 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
+# CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
 # IO Schedulers
@@ -94,6 +93,7 @@ CONFIG_ARCH_EP93XX=y
 # CONFIG_ARCH_IOP3XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 # CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
@@ -112,7 +112,6 @@ CONFIG_ARCH_EP93XX=y
 #
 # Cirrus EP93xx Implementation Options
 #
-CONFIG_CRUNCH=y
 
 #
 # EP93xx Platforms
@@ -232,12 +231,15 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -346,7 +348,6 @@ CONFIG_MTD_CFI_I2=y
 # CONFIG_MTD_OTP is not set
 CONFIG_MTD_CFI_INTELEXT=y
 CONFIG_MTD_CFI_AMDSTD=y
-CONFIG_MTD_CFI_AMDSTD_RETRY=0
 CONFIG_MTD_CFI_STAA=y
 CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_RAM is not set
@@ -371,7 +372,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -412,7 +412,7 @@ CONFIG_MTD_NAND_IDS=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_UB is not set
 # CONFIG_BLK_DEV_RAM is not set
-CONFIG_BLK_DEV_RAM_COUNT=16
+# CONFIG_BLK_DEV_INITRD is not set
 # CONFIG_CDROM_PKTCDVD is not set
 # CONFIG_ATA_OVER_ETH is not set
 
@@ -576,13 +576,13 @@ CONFIG_WATCHDOG=y
 # Watchdog Device Drivers
 #
 # CONFIG_SOFT_WATCHDOG is not set
+CONFIG_EP93XX_WATCHDOG=y
 
 #
 # USB-based Watchdog Cards
 #
 # CONFIG_USBPCWATCHDOG is not set
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 
@@ -626,9 +626,7 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
 CONFIG_I2C_DEBUG_CORE=y
 CONFIG_I2C_DEBUG_ALGO=y
 CONFIG_I2C_DEBUG_BUS=y
@@ -690,7 +688,16 @@ CONFIG_HWMON=y
 #
 
 #
-# Multimedia Capabilities Port drivers
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
 #
 
 #
@@ -702,6 +709,7 @@ CONFIG_HWMON=y
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
@@ -718,6 +726,7 @@ CONFIG_HWMON=y
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 # CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
 CONFIG_USB=y
 CONFIG_USB_DEBUG=y
 
@@ -775,15 +784,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
 
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
 #
 # USB Network Adapters
 #
@@ -813,6 +813,7 @@ CONFIG_USB_SERIAL_CONSOLE=y
 # CONFIG_USB_SERIAL_CYPRESS_M8 is not set
 # CONFIG_USB_SERIAL_EMPEG is not set
 # CONFIG_USB_SERIAL_FTDI_SIO is not set
+# CONFIG_USB_SERIAL_FUNSOFT is not set
 # CONFIG_USB_SERIAL_VISOR is not set
 # CONFIG_USB_SERIAL_IPAQ is not set
 # CONFIG_USB_SERIAL_IR is not set
@@ -825,6 +826,7 @@ CONFIG_USB_SERIAL_CONSOLE=y
 # CONFIG_USB_SERIAL_KLSI is not set
 # CONFIG_USB_SERIAL_KOBIL_SCT is not set
 # CONFIG_USB_SERIAL_MCT_U232 is not set
+# CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=y
 # CONFIG_USB_SERIAL_HP4X is not set
 # CONFIG_USB_SERIAL_SAFE is not set
@@ -864,6 +866,32 @@ CONFIG_USB_SERIAL_PL2303=y
 #
 # CONFIG_MMC is not set
 
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+
+#
+# RTC drivers
+#
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+CONFIG_RTC_DRV_M48T86=y
+CONFIG_RTC_DRV_EP93XX=y
+# CONFIG_RTC_DRV_TEST is not set
+
 #
 # File systems
 #
@@ -912,7 +940,6 @@ CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1044,6 +1071,7 @@ CONFIG_LOG_BUF_SHIFT=14
 CONFIG_DETECT_SOFTLOCKUP=y
 # CONFIG_SCHEDSTATS is not set
 CONFIG_DEBUG_SLAB=y
+# CONFIG_DEBUG_SLAB_LEAK is not set
 CONFIG_DEBUG_MUTEXES=y
 CONFIG_DEBUG_SPINLOCK=y
 # CONFIG_DEBUG_SPINLOCK_SLEEP is not set
@@ -1053,6 +1081,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
index 7b02ca04c3eebb681c5ef027fc5c93d3f085d599..e6f3e4873d6cb967342e41afec4883b1b63341d8 100644 (file)
@@ -1,18 +1,19 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc2
-# Wed Feb  8 04:49:11 2006
+# Linux kernel version: 2.6.17-rc2
+# Wed Apr 19 21:12:49 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
 
 #
 # Code maturity level options
 #
 CONFIG_EXPERIMENTAL=y
-CONFIG_CLEAN_COMPILE=y
 CONFIG_BROKEN_ON_SMP=y
 CONFIG_INIT_ENV_ARG_LIMIT=32
 
@@ -29,6 +30,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -44,10 +46,6 @@ CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
@@ -60,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
@@ -68,6 +65,7 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
+# CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
 # IO Schedulers
@@ -89,11 +87,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
 # CONFIG_ARCH_CLPS711X is not set
 # CONFIG_ARCH_CO285 is not set
 # CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
 # CONFIG_ARCH_FOOTBRIDGE is not set
 # CONFIG_ARCH_INTEGRATOR is not set
 # CONFIG_ARCH_IOP3XX is not set
 # CONFIG_ARCH_IXP4XX is not set
 CONFIG_ARCH_IXP2000=y
+# CONFIG_ARCH_IXP23XX is not set
 # CONFIG_ARCH_L7200 is not set
 # CONFIG_ARCH_PXA is not set
 # CONFIG_ARCH_RPC is not set
@@ -123,6 +123,7 @@ CONFIG_ARCH_IXDP2800=y
 CONFIG_ARCH_IXDP2X00=y
 CONFIG_ARCH_IXDP2401=y
 CONFIG_ARCH_IXDP2801=y
+CONFIG_MACH_IXDP28X5=y
 CONFIG_ARCH_IXDP2X01=y
 # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set
 
@@ -147,7 +148,6 @@ CONFIG_XSCALE_PMU=y
 # Bus support
 #
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -160,6 +160,7 @@ CONFIG_PCI_LEGACY_PROC=y
 #
 # CONFIG_PREEMPT is not set
 # CONFIG_NO_IDLE_HZ is not set
+CONFIG_HZ=100
 # CONFIG_AEABI is not set
 # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
 CONFIG_SELECT_MEMORY_MODEL=y
@@ -213,6 +214,7 @@ CONFIG_NET=y
 #
 # Networking options
 #
+# CONFIG_NETDEBUG is not set
 CONFIG_PACKET=y
 CONFIG_PACKET_MMAP=y
 CONFIG_UNIX=y
@@ -232,12 +234,15 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -347,7 +352,6 @@ CONFIG_MTD_CFI_UTIL=y
 # CONFIG_MTD_ROM is not set
 # CONFIG_MTD_ABSENT is not set
 # CONFIG_MTD_OBSOLETE_CHIPS is not set
-# CONFIG_MTD_XIP is not set
 
 #
 # Mapping drivers for chip access
@@ -366,7 +370,6 @@ CONFIG_MTD_IXP2000=y
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -614,8 +617,9 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=3
-CONFIG_SERIAL_8250_RUNTIME_UARTS=4
+CONFIG_SERIAL_8250_RUNTIME_UARTS=3
 # CONFIG_SERIAL_8250_EXTENDED is not set
 
 #
@@ -623,6 +627,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 #
 CONFIG_SERIAL_CORE=y
 CONFIG_SERIAL_CORE_CONSOLE=y
+# CONFIG_SERIAL_JSM is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_LEGACY_PTYS=y
 CONFIG_LEGACY_PTY_COUNT=256
@@ -650,7 +655,6 @@ CONFIG_IXP2000_WATCHDOG=y
 # CONFIG_PCIPCWATCHDOG is not set
 # CONFIG_WDTPCI is not set
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -696,7 +700,6 @@ CONFIG_I2C_IXP2000=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
@@ -715,9 +718,7 @@ CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -729,6 +730,11 @@ CONFIG_SENSORS_EEPROM=y
 # CONFIG_SPI is not set
 # CONFIG_SPI_MASTER is not set
 
+#
+# Dallas's 1-wire bus
+#
+# CONFIG_W1 is not set
+
 #
 # Hardware Monitoring support
 #
@@ -742,6 +748,7 @@ CONFIG_HWMON=y
 # CONFIG_SENSORS_ASB100 is not set
 # CONFIG_SENSORS_ATXP1 is not set
 # CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
 # CONFIG_SENSORS_FSCHER is not set
 # CONFIG_SENSORS_FSCPOS is not set
 # CONFIG_SENSORS_GL518SM is not set
@@ -776,7 +783,16 @@ CONFIG_HWMON=y
 #
 
 #
-# Multimedia Capabilities Port drivers
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
 #
 
 #
@@ -804,6 +820,7 @@ CONFIG_HWMON=y
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
 
 #
@@ -820,6 +837,12 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
 #
 # File systems
 #
@@ -870,7 +893,6 @@ CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -972,6 +994,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
index 1a2751e9ab05793d40fcbd522bec29faeb537cd1..9ce898a6cf87f3daa5b4828f18fd608084271405 100644 (file)
@@ -1,12 +1,14 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16
-# Tue Mar 21 03:27:20 2006
+# Linux kernel version: 2.6.17-rc2
+# Wed Apr 19 21:13:50 2006
 #
 CONFIG_ARM=y
 CONFIG_MMU=y
 CONFIG_RWSEM_GENERIC_SPINLOCK=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_VECTORS_BASE=0xffff0000
 
 #
 # Code maturity level options
@@ -28,6 +30,7 @@ CONFIG_BSD_PROCESS_ACCT=y
 CONFIG_SYSCTL=y
 # CONFIG_AUDIT is not set
 # CONFIG_IKCONFIG is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_UID16=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
@@ -43,10 +46,6 @@ CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
@@ -59,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 # CONFIG_MODVERSIONS is not set
 # CONFIG_MODULE_SRCVERSION_ALL is not set
 CONFIG_KMOD=y
@@ -67,6 +65,7 @@ CONFIG_KMOD=y
 #
 # Block layer
 #
+# CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
 # IO Schedulers
@@ -143,7 +142,6 @@ CONFIG_CPU_BIG_ENDIAN=y
 # Bus support
 #
 CONFIG_PCI=y
-CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -230,12 +228,15 @@ CONFIG_SYN_COOKIES=y
 # CONFIG_INET_AH is not set
 # CONFIG_INET_ESP is not set
 # CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
 # CONFIG_INET_TUNNEL is not set
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
 # CONFIG_TCP_CONG_ADVANCED is not set
 CONFIG_TCP_CONG_BIC=y
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
 # CONFIG_NETFILTER is not set
 
 #
@@ -365,7 +366,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1
 # CONFIG_MTD_SLRAM is not set
 # CONFIG_MTD_PHRAM is not set
 # CONFIG_MTD_MTDRAM is not set
-# CONFIG_MTD_BLKMTD is not set
 # CONFIG_MTD_BLOCK2MTD is not set
 
 #
@@ -527,7 +527,6 @@ CONFIG_BLK_DEV_SD=y
 # CONFIG_SCSI_INIA100 is not set
 # CONFIG_SCSI_SYM53C8XX_2 is not set
 # CONFIG_SCSI_IPR is not set
-# CONFIG_SCSI_QLOGIC_FC is not set
 # CONFIG_SCSI_QLOGIC_1280 is not set
 # CONFIG_SCSI_QLA_FC is not set
 # CONFIG_SCSI_LPFC is not set
@@ -735,6 +734,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -776,7 +776,6 @@ CONFIG_WATCHDOG=y
 #
 # CONFIG_USBPCWATCHDOG is not set
 # CONFIG_NVRAM is not set
-# CONFIG_RTC is not set
 # CONFIG_DTLK is not set
 # CONFIG_R3964 is not set
 # CONFIG_APPLICOM is not set
@@ -821,7 +820,6 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
@@ -840,9 +838,7 @@ CONFIG_SENSORS_EEPROM=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -907,7 +903,16 @@ CONFIG_HWMON=y
 #
 
 #
-# Multimedia Capabilities Port drivers
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
+#
+# LED drivers
+#
+
+#
+# LED Triggers
 #
 
 #
@@ -919,6 +924,7 @@ CONFIG_HWMON=y
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
@@ -935,6 +941,7 @@ CONFIG_HWMON=y
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1000,9 +1007,7 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_ACECAD is not set
 # CONFIG_USB_KBTAB is not set
 # CONFIG_USB_POWERMATE is not set
-# CONFIG_USB_MTOUCH is not set
-# CONFIG_USB_ITMTOUCH is not set
-# CONFIG_USB_EGALAX is not set
+# CONFIG_USB_TOUCHSCREEN is not set
 # CONFIG_USB_YEALINK is not set
 # CONFIG_USB_XPAD is not set
 # CONFIG_USB_ATI_REMOTE is not set
@@ -1016,15 +1021,6 @@ CONFIG_USB_STORAGE=y
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
 
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
 #
 # USB Network Adapters
 #
@@ -1075,6 +1071,12 @@ CONFIG_USB_MON=y
 #
 # CONFIG_MMC is not set
 
+#
+# Real Time Clock
+#
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+
 #
 # File systems
 #
@@ -1127,7 +1129,6 @@ CONFIG_SYSFS=y
 CONFIG_TMPFS=y
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
@@ -1268,6 +1269,7 @@ CONFIG_DEBUG_BUGVERBOSE=y
 # CONFIG_DEBUG_FS is not set
 # CONFIG_DEBUG_VM is not set
 CONFIG_FRAME_POINTER=y
+# CONFIG_UNWIND_INFO is not set
 CONFIG_FORCED_INLINING=y
 # CONFIG_RCU_TORTURE_TEST is not set
 CONFIG_DEBUG_USER=y
index 8cff73e668b38be7d93d448c44d5f731e3452eac..9fc9af88c60c72e54cad5e835c579b95027624e6 100644 (file)
@@ -407,7 +407,7 @@ static void __init early_initrd(char **p)
 }
 __early_param("initrd=", early_initrd);
 
-static void __init add_memory(unsigned long start, unsigned long size)
+static void __init arm_add_memory(unsigned long start, unsigned long size)
 {
        /*
         * Ensure that start/size are aligned to a page boundary.
@@ -445,7 +445,7 @@ static void __init early_mem(char **p)
        if (**p == '@')
                start = memparse(*p + 1, p);
 
-       add_memory(start, size);
+       arm_add_memory(start, size);
 }
 __early_param("mem=", early_mem);
 
@@ -587,7 +587,7 @@ static int __init parse_tag_mem32(const struct tag *tag)
                        tag->u.mem.start, tag->u.mem.size / 1024);
                return -EINVAL;
        }
-       add_memory(tag->u.mem.start, tag->u.mem.size);
+       arm_add_memory(tag->u.mem.start, tag->u.mem.size);
        return 0;
 }
 
@@ -807,7 +807,7 @@ static int __init topology_init(void)
 {
        int cpu;
 
-       for_each_cpu(cpu)
+       for_each_possible_cpu(cpu)
                register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL);
 
        return 0;
index a0888e160e3b7f180c8c91fafa9c636a284a919c..00b761ff0f9ce75b76fcf60217919eb1acbf308b 100644 (file)
@@ -91,7 +91,7 @@ static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type);
 /*
  * IRQ -> GPIO mapping table
  */
-static char irq2gpio[32] = {
+static signed char irq2gpio[32] = {
        -1, -1, -1, -1, -1, -1,  0,  1,
        -1, -1, -1, -1, -1, -1, -1, -1,
        -1, -1, -1,  2,  3,  4,  5,  6,
index da30a374dd4efba117ecf8de4b10a4fdfb59f920..df0e1745f189764174a70bb3d5430e36a290a0f1 100644 (file)
@@ -1079,7 +1079,7 @@ static int apm_console_blank(int blank)
                        break;
        }
 
-       if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) {
+       if (error == APM_NOT_ENGAGED) {
                static int tried;
                int eng_error;
                if (tried++ == 0) {
index ff2b2154ac1b6c8a0e4bddec0d27319575f47933..786d1a57048b9156396a7f7d5739306097420c60 100644 (file)
@@ -207,6 +207,8 @@ static void __init init_amd(struct cpuinfo_x86 *c)
                set_bit(X86_FEATURE_K7, c->x86_capability); 
                break;
        }
+       if (c->x86 >= 6)
+               set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability);
 
        display_cacheinfo(c);
 
index 006141d1c12a080f2d3fe39464db9da8a7a7bdf7..1d9a4abcdfc71f034c1c822853049280b32de0a2 100644 (file)
@@ -168,7 +168,7 @@ static int cpuid_class_device_create(int i)
        return err;
 }
 
-static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
        unsigned int cpu = (unsigned long)hcpu;
 
index f19768789e8a607203023d7ba3788efbc7bc3c1b..043f5292e70a203eda9ed4051331227adc6bffa5 100644 (file)
@@ -43,7 +43,7 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 
 /* insert a jmp code */
-static inline void set_jmp_op(void *from, void *to)
+static __always_inline void set_jmp_op(void *from, void *to)
 {
        struct __arch_jmp_op {
                char op;
@@ -57,7 +57,7 @@ static inline void set_jmp_op(void *from, void *to)
 /*
  * returns non-zero if opcodes can be boosted.
  */
-static inline int can_boost(kprobe_opcode_t opcode)
+static __always_inline int can_boost(kprobe_opcode_t opcode)
 {
        switch (opcode & 0xf0 ) {
        case 0x70:
@@ -88,7 +88,7 @@ static inline int can_boost(kprobe_opcode_t opcode)
 /*
  * returns non-zero if opcode modifies the interrupt flag.
  */
-static inline int is_IF_modifier(kprobe_opcode_t opcode)
+static int __kprobes is_IF_modifier(kprobe_opcode_t opcode)
 {
        switch (opcode) {
        case 0xfa:              /* cli */
@@ -138,7 +138,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
        mutex_unlock(&kprobe_mutex);
 }
 
-static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        kcb->prev_kprobe.kp = kprobe_running();
        kcb->prev_kprobe.status = kcb->kprobe_status;
@@ -146,7 +146,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
        kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags;
 }
 
-static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
        kcb->kprobe_status = kcb->prev_kprobe.status;
@@ -154,7 +154,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
        kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
                                struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = p;
@@ -164,7 +164,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
                kcb->kprobe_saved_eflags &= ~IF_MASK;
 }
 
-static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
        regs->eflags |= TF_MASK;
        regs->eflags &= ~IF_MASK;
@@ -507,7 +507,7 @@ no_change:
  * Interrupts are disabled on entry as trap1 is an interrupt gate and they
  * remain disabled thoroughout this function.
  */
-static inline int post_kprobe_handler(struct pt_regs *regs)
+static int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
        struct kprobe *cur = kprobe_running();
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -543,7 +543,7 @@ out:
        return 1;
 }
 
-static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
        struct kprobe *cur = kprobe_running();
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
index 1d0a55e687602ff49be8aed13771e76a1c43c3d2..7a328230e540f8b073e5d0306f457a1a9bffbc28 100644 (file)
@@ -251,7 +251,7 @@ static int msr_class_device_create(int i)
        return err;
 }
 
-static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
+static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu)
 {
        unsigned int cpu = (unsigned long)hcpu;
 
index 3039539de51e548a2a92eb83033278fc5daf38df..10d21df1453143c5c8d6c33c629a6267985f2385 100644 (file)
@@ -120,7 +120,6 @@ static struct resource qic_res = {
  * It writes num_bits of the data buffer in msg starting at start_bit.
  * Note: This function assumes that any unused bit in the data stream
  * is set to zero so that the ors will work correctly */
-#define BITS_PER_BYTE 8
 static void
 cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits)
 {
index 789881ca83d43606e389b65b481a8fc99083fb54..f9039f88d01dfbcefb9174c0f59bb968fa92f5bd 100644 (file)
@@ -251,7 +251,7 @@ static void __kprobes prepare_break_inst(uint template, uint  slot,
        update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p);
 }
 
-static inline void get_kprobe_inst(bundle_t *bundle, uint slot,
+static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot,
                unsigned long *kprobe_inst, uint *major_opcode)
 {
        unsigned long kprobe_inst_p0, kprobe_inst_p1;
@@ -278,7 +278,7 @@ static inline void get_kprobe_inst(bundle_t *bundle, uint slot,
 }
 
 /* Returns non-zero if the addr is in the Interrupt Vector Table */
-static inline int in_ivt_functions(unsigned long addr)
+static int __kprobes in_ivt_functions(unsigned long addr)
 {
        return (addr >= (unsigned long)__start_ivt_text
                && addr < (unsigned long)__end_ivt_text);
@@ -308,19 +308,19 @@ static int __kprobes valid_kprobe_addr(int template, int slot,
        return 0;
 }
 
-static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        kcb->prev_kprobe.kp = kprobe_running();
        kcb->prev_kprobe.status = kcb->kprobe_status;
 }
 
-static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
        kcb->kprobe_status = kcb->prev_kprobe.status;
 }
 
-static inline void set_current_kprobe(struct kprobe *p,
+static void __kprobes set_current_kprobe(struct kprobe *p,
                        struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = p;
index 3871b65f0c827966eede1b0cac8d1d07464198ff..920bb742b7a2a90394c133998809917f0bb33f56 100644 (file)
@@ -20,7 +20,7 @@
  * Stack layout in 'ret_from_system_call':
  *     ptrace needs to have all regs on the stack.
  *     if the order here is changed, it needs to be
- *     updated in fork.c:copy_process, signal.c:do_signal,
+ *     updated in fork.c:copy_thread, signal.c:do_signal,
  *     ptrace.c and ptrace.h
  *
  * M32Rx/M32R2                         M32R
  *       @(0x38,sp) - syscall_nr       ditto
  *       @(0x3c,sp) - acc0h            @(0x3c,sp) - acch
  *       @(0x40,sp) - acc0l            @(0x40,sp) - accl
- *       @(0x44,sp) - acc1h            @(0x44,sp) - psw
- *       @(0x48,sp) - acc1l            @(0x48,sp) - bpc
- *       @(0x4c,sp) - psw              @(0x4c,sp) - bbpsw
- *       @(0x50,sp) - bpc              @(0x50,sp) - bbpc
- *       @(0x54,sp) - bbpsw            @(0x54,sp) - spu (cr3)
- *       @(0x58,sp) - bbpc             @(0x58,sp) - fp (r13)
- *       @(0x5c,sp) - spu (cr3)                @(0x5c,sp) - lr (r14)
- *       @(0x60,sp) - fp (r13)         @(0x60,sp) - spi (cr12)
- *       @(0x64,sp) - lr (r14)         @(0x64,sp) - orig_r0
- *       @(0x68,sp) - spi (cr2)
- *       @(0x6c,sp) - orig_r0
- *
+ *       @(0x44,sp) - acc1h            @(0x44,sp) - dummy_acc1h
+ *       @(0x48,sp) - acc1l            @(0x48,sp) - dummy_acc1l
+ *       @(0x4c,sp) - psw              ditto
+ *       @(0x50,sp) - bpc              ditto
+ *       @(0x54,sp) - bbpsw            ditto
+ *       @(0x58,sp) - bbpc             ditto
+ *       @(0x5c,sp) - spu (cr3)                ditto
+ *       @(0x60,sp) - fp (r13)         ditto
+ *       @(0x64,sp) - lr (r14)         ditto
+ *       @(0x68,sp) - spi (cr2)                ditto
+ *       @(0x6c,sp) - orig_r0          ditto
  */
 
 #include <linux/config.h>
 #define ACC0L(reg)             @(0x40,reg)
 #define ACC1H(reg)             @(0x44,reg)
 #define ACC1L(reg)             @(0x48,reg)
+#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
+#define ACCH(reg)              @(0x3C,reg)
+#define ACCL(reg)              @(0x40,reg)
+#else
+#error unknown isa configuration
+#endif
 #define PSW(reg)               @(0x4C,reg)
 #define BPC(reg)               @(0x50,reg)
 #define BBPSW(reg)             @(0x54,reg)
 #define LR(reg)                        @(0x64,reg)
 #define SP(reg)                        @(0x68,reg)
 #define ORIG_R0(reg)           @(0x6C,reg)
-#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
-#define ACCH(reg)              @(0x3C,reg)
-#define ACCL(reg)              @(0x40,reg)
-#define PSW(reg)               @(0x44,reg)
-#define BPC(reg)               @(0x48,reg)
-#define BBPSW(reg)             @(0x4C,reg)
-#define BBPC(reg)              @(0x50,reg)
-#define SPU(reg)               @(0x54,reg)
-#define FP(reg)                        @(0x58,reg)  /* FP = R13 */
-#define LR(reg)                        @(0x5C,reg)
-#define SP(reg)                        @(0x60,reg)
-#define ORIG_R0(reg)           @(0x64,reg)
-#else
-#error unknown isa configuration
-#endif
 
 CF_MASK                = 0x00000001
 TF_MASK                = 0x00000100
@@ -142,7 +132,7 @@ VM_MASK             = 0x00020000
 #endif
 
 ENTRY(ret_from_fork)
-       ld      r0, @sp+
+       pop     r0
        bl      schedule_tail
        GET_THREAD_INFO(r8)
        bra     syscall_exit
@@ -231,7 +221,7 @@ restore_all:
        RESTORE_ALL
 
        # perform work that needs to be done immediately before resumption
-       # r9 : frags
+       # r9 : flags
        ALIGN
 work_pending:
        and3    r4, r9, #_TIF_NEED_RESCHED
@@ -320,7 +310,7 @@ ENTRY(ei_handler)
 ;    GET_ICU_STATUS;
        seth    r0, #shigh(M32R_ICU_ISTS_ADDR)
        ld      r0, @(low(M32R_ICU_ISTS_ADDR),r0)
-       st      r0, @-sp
+       push    r0
 #if defined(CONFIG_SMP)
        /*
         * If IRQ == 0      --> Nothing to do,  Not write IMASK
@@ -557,7 +547,7 @@ check_end:
 #endif  /* CONFIG_PLAT_M32104UT */
        bl      do_IRQ
 #endif  /* CONFIG_SMP */
-       ld      r14, @sp+
+       pop     r14
        seth    r0, #shigh(M32R_ICU_IMASK_ADDR)
        st      r14, @(low(M32R_ICU_IMASK_ADDR),r0)
 #else
@@ -1015,4 +1005,3 @@ ENTRY(sys_call_table)
        .long sys_waitid
 
 syscall_table_size=(.-sys_call_table)
-
index 5dfc7ea45cf7a9b19887f7de1049a7d337e5833e..065f5e7190587cf4e6a8122a34c64617523ab1cc 100644 (file)
@@ -116,6 +116,10 @@ void cpu_idle (void)
 
 void machine_restart(char *__unused)
 {
+#if defined(CONFIG_PLAT_MAPPI3)
+       outw(1, (unsigned long)PLD_REBOOT);
+#endif
+
        printk("Please push reset button!\n");
        while (1)
                cpu_relax();
index cb33097fefc4453475451d31443b2e380b97f0d5..6498ee70bb738d4c6aedf927b2b45d7de17215fe 100644 (file)
@@ -118,6 +118,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc,
 #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
        COPY(acch);
        COPY(accl);
+       COPY(dummy_acc1h);
+       COPY(dummy_acc1l);
 #else
 #error unknown isa configuration
 #endif
@@ -203,6 +205,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
 #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
        COPY(acch);
        COPY(accl);
+       COPY(dummy_acc1h);
+       COPY(dummy_acc1l);
 #else
 #error unknown isa configuration
 #endif
index 2c3fd2007676520b52b808cc8c331e38556ce6b6..a45627547d03f235716138346a9f929c24ca0ead 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc2
-# Fri Feb 10 17:33:08 2006
+# Linux kernel version: 2.6.17-rc1
+# Wed Apr 19 13:24:37 2006
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -9,6 +9,7 @@ CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
@@ -29,6 +30,7 @@ CONFIG_POWER4=y
 CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 CONFIG_PPC_STD_MMU=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=4
 
@@ -53,6 +55,7 @@ CONFIG_SYSCTL=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
@@ -67,10 +70,6 @@ CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
@@ -82,7 +81,6 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
@@ -91,6 +89,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+# CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
 # IO Schedulers
@@ -185,7 +184,6 @@ CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PPC_INDIRECT_PCI is not set
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -227,6 +225,7 @@ CONFIG_SYN_COOKIES=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
 CONFIG_INET_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
@@ -238,6 +237,8 @@ CONFIG_TCP_CONG_BIC=y
 #
 # CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 
@@ -261,6 +262,7 @@ CONFIG_IP_NF_IRC=m
 CONFIG_IP_NF_TFTP=m
 CONFIG_IP_NF_AMANDA=m
 # CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
 CONFIG_IP_NF_QUEUE=m
 
 #
@@ -513,6 +515,7 @@ CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID10=m
 CONFIG_MD_RAID5=y
+# CONFIG_MD_RAID5_RESHAPE is not set
 CONFIG_MD_RAID6=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
@@ -761,7 +764,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
@@ -772,6 +774,7 @@ CONFIG_GEN_RTC=y
 # Ftape, the floppy tape device driver
 #
 CONFIG_AGP=m
+# CONFIG_AGP_VIA is not set
 CONFIG_AGP_UNINORTH=m
 # CONFIG_DRM is not set
 CONFIG_RAW_DRIVER=y
@@ -813,7 +816,6 @@ CONFIG_I2C_POWERMAC=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
@@ -832,9 +834,7 @@ CONFIG_I2C_POWERMAC=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -861,10 +861,6 @@ CONFIG_I2C_POWERMAC=y
 # Misc devices
 #
 
-#
-# Multimedia Capabilities Port drivers
-#
-
 #
 # Multimedia devices
 #
@@ -874,6 +870,7 @@ CONFIG_I2C_POWERMAC=y
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
@@ -883,6 +880,7 @@ CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_MACMODES=y
+CONFIG_FB_FIRMWARE_EDID=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
@@ -901,7 +899,6 @@ CONFIG_FB_NVIDIA=y
 CONFIG_FB_NVIDIA_I2C=y
 # CONFIG_FB_RIVA is not set
 # CONFIG_FB_MATROX is not set
-# CONFIG_FB_RADEON_OLD is not set
 CONFIG_FB_RADEON=y
 CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_RADEON_DEBUG is not set
@@ -958,9 +955,11 @@ CONFIG_SND_SEQUENCER=m
 CONFIG_SND_OSSEMUL=y
 CONFIG_SND_MIXER_OSS=m
 CONFIG_SND_PCM_OSS=m
+CONFIG_SND_PCM_OSS_PLUGINS=y
 CONFIG_SND_SEQUENCER_OSS=y
 # CONFIG_SND_DYNAMIC_MINORS is not set
 CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
 # CONFIG_SND_VERBOSE_PRINTK is not set
 # CONFIG_SND_DEBUG is not set
 
@@ -977,6 +976,7 @@ CONFIG_SND_SUPPORT_OLD_API=y
 # PCI devices
 #
 # CONFIG_SND_AD1889 is not set
+# CONFIG_SND_ALS300 is not set
 # CONFIG_SND_ALS4000 is not set
 # CONFIG_SND_ALI5451 is not set
 # CONFIG_SND_ATIIXP is not set
@@ -1009,6 +1009,7 @@ CONFIG_SND_SUPPORT_OLD_API=y
 # CONFIG_SND_MIXART is not set
 # CONFIG_SND_NM256 is not set
 # CONFIG_SND_PCXHR is not set
+# CONFIG_SND_RIPTIDE is not set
 # CONFIG_SND_RME32 is not set
 # CONFIG_SND_RME96 is not set
 # CONFIG_SND_RME9652 is not set
@@ -1041,6 +1042,7 @@ CONFIG_SND_USB_AUDIO=m
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1068,7 +1070,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
 #
 # USB Device Class drivers
 #
-# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set
 CONFIG_USB_ACM=m
 CONFIG_USB_PRINTER=y
 
@@ -1125,15 +1126,6 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
 
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
 #
 # USB Network Adapters
 #
@@ -1194,6 +1186,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y
 CONFIG_USB_SERIAL_KLSI=m
 CONFIG_USB_SERIAL_KOBIL_SCT=m
 CONFIG_USB_SERIAL_MCT_U232=m
+# CONFIG_USB_SERIAL_NAVMAN is not set
 CONFIG_USB_SERIAL_PL2303=m
 # CONFIG_USB_SERIAL_HP4X is not set
 CONFIG_USB_SERIAL_SAFE=m
@@ -1236,18 +1229,24 @@ CONFIG_USB_EZUSB=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
 #
 # InfiniBand support
 #
 # CONFIG_INFINIBAND is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
 #
-# EDAC - error detection and reporting (RAS)
+# Real Time Clock
 #
+# CONFIG_RTC_CLASS is not set
 
 #
 # File systems
@@ -1319,7 +1318,6 @@ CONFIG_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
index 1816a46742f650bb54784a9b0162d0dcca243ba9..a95e455a1944a9a2102af115416a43eeeb867daa 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc6
-# Wed Mar 15 16:19:52 2006
+# Linux kernel version: 2.6.17-rc1
+# Wed Apr 19 11:46:44 2006
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -9,6 +9,7 @@ CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
@@ -30,6 +31,7 @@ CONFIG_POWER4=y
 CONFIG_PPC_FPU=y
 # CONFIG_ALTIVEC is not set
 CONFIG_PPC_STD_MMU=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=32
 
@@ -55,6 +57,7 @@ CONFIG_AUDITSYSCALL=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 # CONFIG_CPUSETS is not set
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
@@ -69,10 +72,6 @@ CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
@@ -84,7 +83,6 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
@@ -93,6 +91,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+# CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
 # IO Schedulers
@@ -165,7 +164,6 @@ CONFIG_GENERIC_ISA_DMA=y
 # CONFIG_PPC_INDIRECT_PCI is not set
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -207,6 +205,7 @@ CONFIG_SYN_COOKIES=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
 CONFIG_INET_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
@@ -218,6 +217,8 @@ CONFIG_TCP_CONG_BIC=y
 #
 # CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 
@@ -236,11 +237,14 @@ CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m
 CONFIG_NETFILTER_XT_MATCH_CONNMARK=m
 CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
 # CONFIG_NETFILTER_XT_MATCH_DCCP is not set
+# CONFIG_NETFILTER_XT_MATCH_ESP is not set
 CONFIG_NETFILTER_XT_MATCH_HELPER=m
 CONFIG_NETFILTER_XT_MATCH_LENGTH=m
 CONFIG_NETFILTER_XT_MATCH_LIMIT=m
 CONFIG_NETFILTER_XT_MATCH_MAC=m
 CONFIG_NETFILTER_XT_MATCH_MARK=m
+# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
+# CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set
 CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
 CONFIG_NETFILTER_XT_MATCH_REALM=m
 CONFIG_NETFILTER_XT_MATCH_SCTP=m
@@ -262,20 +266,19 @@ CONFIG_IP_NF_IRC=m
 CONFIG_IP_NF_TFTP=m
 CONFIG_IP_NF_AMANDA=m
 # CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
 CONFIG_IP_NF_QUEUE=m
 CONFIG_IP_NF_IPTABLES=m
 CONFIG_IP_NF_MATCH_IPRANGE=m
-CONFIG_IP_NF_MATCH_MULTIPORT=m
 CONFIG_IP_NF_MATCH_TOS=m
 CONFIG_IP_NF_MATCH_RECENT=m
 CONFIG_IP_NF_MATCH_ECN=m
 CONFIG_IP_NF_MATCH_DSCP=m
-CONFIG_IP_NF_MATCH_AH_ESP=m
+# CONFIG_IP_NF_MATCH_AH is not set
 CONFIG_IP_NF_MATCH_TTL=m
 CONFIG_IP_NF_MATCH_OWNER=m
 CONFIG_IP_NF_MATCH_ADDRTYPE=m
 CONFIG_IP_NF_MATCH_HASHLIMIT=m
-CONFIG_IP_NF_MATCH_POLICY=m
 CONFIG_IP_NF_FILTER=m
 CONFIG_IP_NF_TARGET_REJECT=m
 CONFIG_IP_NF_TARGET_LOG=m
@@ -479,6 +482,7 @@ CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID10=m
 CONFIG_MD_RAID5=y
+# CONFIG_MD_RAID5_RESHAPE is not set
 CONFIG_MD_RAID6=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
@@ -702,7 +706,6 @@ CONFIG_LEGACY_PTY_COUNT=256
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
@@ -750,10 +753,6 @@ CONFIG_MAX_RAW_DEVS=256
 # Misc devices
 #
 
-#
-# Multimedia Capabilities Port drivers
-#
-
 #
 # Multimedia devices
 #
@@ -779,6 +778,7 @@ CONFIG_MAX_RAW_DEVS=256
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 # CONFIG_USB is not set
 
 #
@@ -795,6 +795,11 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
 #
 # InfiniBand support
 #
@@ -804,6 +809,11 @@ CONFIG_USB_ARCH_HAS_OHCI=y
 # EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
+#
+# Real Time Clock
+#
+# CONFIG_RTC_CLASS is not set
+
 #
 # File systems
 #
@@ -878,7 +888,6 @@ CONFIG_TMPFS=y
 # CONFIG_HUGETLBFS is not set
 # CONFIG_HUGETLB_PAGE is not set
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
index daaf038a1faa472d7afe956816b34afe811b16cc..58e68ce09b0fc1e247e535933213382fec3b6b1c 100644 (file)
@@ -1,7 +1,7 @@
 #
 # Automatically generated make config: don't edit
-# Linux kernel version: 2.6.16-rc2
-# Fri Feb 10 17:33:32 2006
+# Linux kernel version: 2.6.17-rc1
+# Wed Apr 19 11:48:00 2006
 #
 CONFIG_PPC64=y
 CONFIG_64BIT=y
@@ -9,6 +9,7 @@ CONFIG_PPC_MERGE=y
 CONFIG_MMU=y
 CONFIG_GENERIC_HARDIRQS=y
 CONFIG_RWSEM_XCHGADD_ALGORITHM=y
+CONFIG_GENERIC_HWEIGHT=y
 CONFIG_GENERIC_CALIBRATE_DELAY=y
 CONFIG_PPC=y
 CONFIG_EARLY_PRINTK=y
@@ -30,6 +31,7 @@ CONFIG_POWER4=y
 CONFIG_PPC_FPU=y
 CONFIG_ALTIVEC=y
 CONFIG_PPC_STD_MMU=y
+CONFIG_VIRT_CPU_ACCOUNTING=y
 CONFIG_SMP=y
 CONFIG_NR_CPUS=128
 
@@ -55,6 +57,7 @@ CONFIG_AUDITSYSCALL=y
 CONFIG_IKCONFIG=y
 CONFIG_IKCONFIG_PROC=y
 CONFIG_CPUSETS=y
+# CONFIG_RELAY is not set
 CONFIG_INITRAMFS_SOURCE=""
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_EMBEDDED is not set
@@ -69,10 +72,6 @@ CONFIG_BASE_FULL=y
 CONFIG_FUTEX=y
 CONFIG_EPOLL=y
 CONFIG_SHMEM=y
-CONFIG_CC_ALIGN_FUNCTIONS=0
-CONFIG_CC_ALIGN_LABELS=0
-CONFIG_CC_ALIGN_LOOPS=0
-CONFIG_CC_ALIGN_JUMPS=0
 CONFIG_SLAB=y
 # CONFIG_TINY_SHMEM is not set
 CONFIG_BASE_SMALL=0
@@ -84,7 +83,6 @@ CONFIG_BASE_SMALL=0
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 # CONFIG_MODULE_FORCE_UNLOAD is not set
-CONFIG_OBSOLETE_MODPARM=y
 CONFIG_MODVERSIONS=y
 CONFIG_MODULE_SRCVERSION_ALL=y
 CONFIG_KMOD=y
@@ -93,6 +91,7 @@ CONFIG_STOP_MACHINE=y
 #
 # Block layer
 #
+# CONFIG_BLK_DEV_IO_TRACE is not set
 
 #
 # IO Schedulers
@@ -188,7 +187,6 @@ CONFIG_PPC_I8259=y
 # CONFIG_PPC_INDIRECT_PCI is not set
 CONFIG_PCI=y
 CONFIG_PCI_DOMAINS=y
-CONFIG_PCI_LEGACY_PROC=y
 # CONFIG_PCI_DEBUG is not set
 
 #
@@ -235,6 +233,7 @@ CONFIG_SYN_COOKIES=y
 CONFIG_INET_AH=m
 CONFIG_INET_ESP=m
 CONFIG_INET_IPCOMP=m
+CONFIG_INET_XFRM_TUNNEL=m
 CONFIG_INET_TUNNEL=y
 CONFIG_INET_DIAG=y
 CONFIG_INET_TCP_DIAG=y
@@ -246,6 +245,8 @@ CONFIG_TCP_CONG_BIC=y
 #
 # CONFIG_IP_VS is not set
 # CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
 CONFIG_NETFILTER=y
 # CONFIG_NETFILTER_DEBUG is not set
 
@@ -272,6 +273,7 @@ CONFIG_IP_NF_IRC=m
 CONFIG_IP_NF_TFTP=m
 CONFIG_IP_NF_AMANDA=m
 # CONFIG_IP_NF_PPTP is not set
+# CONFIG_IP_NF_H323 is not set
 CONFIG_IP_NF_QUEUE=m
 
 #
@@ -519,6 +521,7 @@ CONFIG_MD_RAID0=y
 CONFIG_MD_RAID1=y
 CONFIG_MD_RAID10=m
 CONFIG_MD_RAID5=y
+# CONFIG_MD_RAID5_RESHAPE is not set
 CONFIG_MD_RAID6=m
 CONFIG_MD_MULTIPATH=m
 CONFIG_MD_FAULTY=m
@@ -750,6 +753,7 @@ CONFIG_HW_CONSOLE=y
 #
 CONFIG_SERIAL_8250=y
 CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_PCI=y
 CONFIG_SERIAL_8250_NR_UARTS=4
 CONFIG_SERIAL_8250_RUNTIME_UARTS=4
 # CONFIG_SERIAL_8250_EXTENDED is not set
@@ -767,7 +771,9 @@ CONFIG_LEGACY_PTY_COUNT=256
 # CONFIG_PRINTER is not set
 # CONFIG_PPDEV is not set
 # CONFIG_TIPAR is not set
+CONFIG_HVC_DRIVER=y
 CONFIG_HVC_CONSOLE=y
+# CONFIG_HVC_RTAS is not set
 CONFIG_HVCS=m
 
 #
@@ -779,7 +785,6 @@ CONFIG_HVCS=m
 # Watchdog Cards
 #
 # CONFIG_WATCHDOG is not set
-# CONFIG_RTC is not set
 CONFIG_GEN_RTC=y
 # CONFIG_GEN_RTC_X is not set
 # CONFIG_DTLK is not set
@@ -830,7 +835,6 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_I2C_PARPORT_LIGHT is not set
 # CONFIG_I2C_PROSAVAGE is not set
 # CONFIG_I2C_SAVAGE4 is not set
-# CONFIG_SCx200_ACB is not set
 # CONFIG_I2C_SIS5595 is not set
 # CONFIG_I2C_SIS630 is not set
 # CONFIG_I2C_SIS96X is not set
@@ -849,9 +853,7 @@ CONFIG_I2C_ALGOBIT=y
 # CONFIG_SENSORS_PCF8574 is not set
 # CONFIG_SENSORS_PCA9539 is not set
 # CONFIG_SENSORS_PCF8591 is not set
-# CONFIG_SENSORS_RTC8564 is not set
 # CONFIG_SENSORS_MAX6875 is not set
-# CONFIG_RTC_X1205_I2C is not set
 # CONFIG_I2C_DEBUG_CORE is not set
 # CONFIG_I2C_DEBUG_ALGO is not set
 # CONFIG_I2C_DEBUG_BUS is not set
@@ -878,10 +880,6 @@ CONFIG_I2C_ALGOBIT=y
 # Misc devices
 #
 
-#
-# Multimedia Capabilities Port drivers
-#
-
 #
 # Multimedia devices
 #
@@ -891,6 +889,7 @@ CONFIG_I2C_ALGOBIT=y
 # Digital Video Broadcasting Devices
 #
 # CONFIG_DVB is not set
+# CONFIG_USB_DABUSB is not set
 
 #
 # Graphics support
@@ -900,6 +899,7 @@ CONFIG_FB_CFB_FILLRECT=y
 CONFIG_FB_CFB_COPYAREA=y
 CONFIG_FB_CFB_IMAGEBLIT=y
 CONFIG_FB_MACMODES=y
+CONFIG_FB_FIRMWARE_EDID=y
 CONFIG_FB_MODE_HELPERS=y
 CONFIG_FB_TILEBLITTING=y
 # CONFIG_FB_CIRRUS is not set
@@ -919,7 +919,6 @@ CONFIG_FB_MATROX_MYSTIQUE=y
 CONFIG_FB_MATROX_G=y
 # CONFIG_FB_MATROX_I2C is not set
 CONFIG_FB_MATROX_MULTIHEAD=y
-# CONFIG_FB_RADEON_OLD is not set
 CONFIG_FB_RADEON=y
 CONFIG_FB_RADEON_I2C=y
 # CONFIG_FB_RADEON_DEBUG is not set
@@ -968,6 +967,7 @@ CONFIG_LCD_DEVICE=y
 #
 CONFIG_USB_ARCH_HAS_HCD=y
 CONFIG_USB_ARCH_HAS_OHCI=y
+CONFIG_USB_ARCH_HAS_EHCI=y
 CONFIG_USB=y
 # CONFIG_USB_DEBUG is not set
 
@@ -1047,15 +1047,6 @@ CONFIG_USB_HIDDEV=y
 # CONFIG_USB_MDC800 is not set
 # CONFIG_USB_MICROTEK is not set
 
-#
-# USB Multimedia devices
-#
-# CONFIG_USB_DABUSB is not set
-
-#
-# Video4Linux support is needed for USB Multimedia device support
-#
-
 #
 # USB Network Adapters
 #
@@ -1108,6 +1099,11 @@ CONFIG_USB_MON=y
 #
 # CONFIG_MMC is not set
 
+#
+# LED devices
+#
+# CONFIG_NEW_LEDS is not set
+
 #
 # InfiniBand support
 #
@@ -1121,12 +1117,13 @@ CONFIG_INFINIBAND_IPOIB=m
 # CONFIG_INFINIBAND_SRP is not set
 
 #
-# SN Devices
+# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
 #
 
 #
-# EDAC - error detection and reporting (RAS)
+# Real Time Clock
 #
+# CONFIG_RTC_CLASS is not set
 
 #
 # File systems
@@ -1202,7 +1199,6 @@ CONFIG_TMPFS=y
 CONFIG_HUGETLBFS=y
 CONFIG_HUGETLB_PAGE=y
 CONFIG_RAMFS=y
-# CONFIG_RELAYFS_FS is not set
 # CONFIG_CONFIGFS_FS is not set
 
 #
index d9a7fdef59b98234b3cbfddd378a84c12f9c7286..4eba60a328907d753cbcb0ab5ab2736552e3a8e1 100644 (file)
@@ -61,6 +61,7 @@ __setup("iommu=", setup_iommu);
 static unsigned long iommu_range_alloc(struct iommu_table *tbl,
                                        unsigned long npages,
                                        unsigned long *handle,
+                                       unsigned long mask,
                                        unsigned int align_order)
 { 
        unsigned long n, end, i, start;
@@ -97,9 +98,21 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
         */
        if (start >= limit)
                start = largealloc ? tbl->it_largehint : tbl->it_hint;
-       
+
  again:
 
+       if (limit + tbl->it_offset > mask) {
+               limit = mask - tbl->it_offset + 1;
+               /* If we're constrained on address range, first try
+                * at the masked hint to avoid O(n) search complexity,
+                * but on second pass, start at 0.
+                */
+               if ((start & mask) >= limit || pass > 0)
+                       start = 0;
+               else
+                       start &= mask;
+       }
+
        n = find_next_zero_bit(tbl->it_map, limit, start);
 
        /* Align allocation */
@@ -150,14 +163,14 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl,
 
 static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page,
                       unsigned int npages, enum dma_data_direction direction,
-                      unsigned int align_order)
+                      unsigned long mask, unsigned int align_order)
 {
        unsigned long entry, flags;
        dma_addr_t ret = DMA_ERROR_CODE;
-       
+
        spin_lock_irqsave(&(tbl->it_lock), flags);
 
-       entry = iommu_range_alloc(tbl, npages, NULL, align_order);
+       entry = iommu_range_alloc(tbl, npages, NULL, mask, align_order);
 
        if (unlikely(entry == DMA_ERROR_CODE)) {
                spin_unlock_irqrestore(&(tbl->it_lock), flags);
@@ -236,7 +249,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
 
 int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                struct scatterlist *sglist, int nelems,
-               enum dma_data_direction direction)
+               unsigned long mask, enum dma_data_direction direction)
 {
        dma_addr_t dma_next = 0, dma_addr;
        unsigned long flags;
@@ -274,7 +287,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
                vaddr = (unsigned long)page_address(s->page) + s->offset;
                npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK);
                npages >>= PAGE_SHIFT;
-               entry = iommu_range_alloc(tbl, npages, &handle, 0);
+               entry = iommu_range_alloc(tbl, npages, &handle, mask >> PAGE_SHIFT, 0);
 
                DBG("  - vaddr: %lx, size: %lx\n", vaddr, slen);
 
@@ -479,7 +492,8 @@ void iommu_free_table(struct device_node *dn)
  * byte within the page as vaddr.
  */
 dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
-               size_t size, enum dma_data_direction direction)
+               size_t size, unsigned long mask,
+               enum dma_data_direction direction)
 {
        dma_addr_t dma_handle = DMA_ERROR_CODE;
        unsigned long uaddr;
@@ -492,7 +506,8 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
        npages >>= PAGE_SHIFT;
 
        if (tbl) {
-               dma_handle = iommu_alloc(tbl, vaddr, npages, direction, 0);
+               dma_handle = iommu_alloc(tbl, vaddr, npages, direction,
+                                        mask >> PAGE_SHIFT, 0);
                if (dma_handle == DMA_ERROR_CODE) {
                        if (printk_ratelimit())  {
                                printk(KERN_INFO "iommu_alloc failed, "
@@ -521,7 +536,7 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
  * to the dma address (mapping) of the first page.
  */
 void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
-               dma_addr_t *dma_handle, gfp_t flag)
+               dma_addr_t *dma_handle, unsigned long mask, gfp_t flag)
 {
        void *ret = NULL;
        dma_addr_t mapping;
@@ -551,7 +566,8 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
        memset(ret, 0, size);
 
        /* Set up tces to cover the allocated range */
-       mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, order);
+       mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL,
+                             mask >> PAGE_SHIFT, order);
        if (mapping == DMA_ERROR_CODE) {
                free_pages((unsigned long)ret, order);
                ret = NULL;
index ad7a90212204ee68eea83075b51fbadf5a62ef4b..856ef1a832b9466031309cd9b20f4dda31242396 100644 (file)
@@ -88,7 +88,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
        mutex_unlock(&kprobe_mutex);
 }
 
-static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
+static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
 {
        kprobe_opcode_t insn = *p->ainsn.insn;
 
@@ -101,21 +101,21 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs)
                regs->nip = (unsigned long)p->ainsn.insn;
 }
 
-static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        kcb->prev_kprobe.kp = kprobe_running();
        kcb->prev_kprobe.status = kcb->kprobe_status;
        kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr;
 }
 
-static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
        kcb->kprobe_status = kcb->prev_kprobe.status;
        kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
                                struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = p;
@@ -141,7 +141,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp,
        }
 }
 
-static inline int kprobe_handler(struct pt_regs *regs)
+static int __kprobes kprobe_handler(struct pt_regs *regs)
 {
        struct kprobe *p;
        int ret = 0;
@@ -334,7 +334,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs)
                regs->nip = (unsigned long)p->addr + 4;
 }
 
-static inline int post_kprobe_handler(struct pt_regs *regs)
+static int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
        struct kprobe *cur = kprobe_running();
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -370,7 +370,7 @@ out:
        return 1;
 }
 
-static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
        struct kprobe *cur = kprobe_running();
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
index c336f3e31cff3d7579886aa5fbabe76b5fc482c0..c1d95e14bbed21e8f979367baa5ee1a2b71c9a69 100644 (file)
@@ -59,6 +59,25 @@ static inline struct iommu_table *devnode_table(struct device *dev)
 }
 
 
+static inline unsigned long device_to_mask(struct device *hwdev)
+{
+       struct pci_dev *pdev;
+
+       if (!hwdev) {
+               pdev = ppc64_isabridge_dev;
+               if (!pdev) /* This is the best guess we can do */
+                       return 0xfffffffful;
+       } else
+               pdev = to_pci_dev(hwdev);
+
+       if (pdev->dma_mask)
+               return pdev->dma_mask;
+
+       /* Assume devices without mask can take 32 bit addresses */
+       return 0xfffffffful;
+}
+
+
 /* Allocates a contiguous real buffer and creates mappings over it.
  * Returns the virtual address of the buffer and sets dma_handle
  * to the dma address (mapping) of the first page.
@@ -67,7 +86,7 @@ static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
                           dma_addr_t *dma_handle, gfp_t flag)
 {
        return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle,
-                       flag);
+                       device_to_mask(hwdev), flag);
 }
 
 static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
@@ -85,7 +104,8 @@ static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
 static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
                size_t size, enum dma_data_direction direction)
 {
-       return iommu_map_single(devnode_table(hwdev), vaddr, size, direction);
+       return iommu_map_single(devnode_table(hwdev), vaddr, size,
+                               device_to_mask(hwdev), direction);
 }
 
 
@@ -100,7 +120,7 @@ static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
                int nelems, enum dma_data_direction direction)
 {
        return iommu_map_sg(pdev, devnode_table(pdev), sglist,
-                       nelems, direction);
+                       nelems, device_to_mask(pdev), direction);
 }
 
 static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
@@ -112,7 +132,19 @@ static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
 /* We support DMA to/from any memory page via the iommu */
 static int pci_iommu_dma_supported(struct device *dev, u64 mask)
 {
-       return 1;
+       struct iommu_table *tbl = devnode_table(dev);
+
+       if (!tbl || tbl->it_offset > mask) {
+               printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
+               if (tbl)
+                       printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n",
+                               mask, tbl->it_offset);
+               else
+                       printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
+                               mask);
+               return 0;
+       } else
+               return 1;
 }
 
 void pci_iommu_init(void)
index dfa5398ab3c8d68edfd2c65602f71d3858b161e8..4b052ae5dc344a39eb93b0ab4e5018558ee0bc65 100644 (file)
@@ -81,6 +81,7 @@ EXPORT_SYMBOL(strcat);
 EXPORT_SYMBOL(strlen);
 EXPORT_SYMBOL(strcmp);
 EXPORT_SYMBOL(strcasecmp);
+EXPORT_SYMBOL(strncasecmp);
 
 EXPORT_SYMBOL(csum_partial);
 EXPORT_SYMBOL(csum_partial_copy_generic);
index 4336390bcf34e86671b12e5e4b66594b9f401e68..1cb69e8fb0b10139f2f83531854f40cde57b63a0 100644 (file)
@@ -62,7 +62,7 @@ static int __initdata dt_root_addr_cells;
 static int __initdata dt_root_size_cells;
 
 #ifdef CONFIG_PPC64
-static int __initdata iommu_is_off;
+int __initdata iommu_is_off;
 int __initdata iommu_force_on;
 unsigned long tce_alloc_start, tce_alloc_end;
 #endif
index a14c964038403fa6d6271967df95fa5727a41b1f..8d15226905015f63da9ad53677c869c9f18e309f 100644 (file)
@@ -324,3 +324,8 @@ COMPAT_SYS(ppoll)
 SYSCALL(unshare)
 SYSCALL(splice)
 SYSCALL(tee)
+
+/*
+ * please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c
+ * as well when appropriate.
+ */
index 13c655ba2841aac42db44ddb6f2f76862eff8ffe..971020cf3f7d24f90bd6d33edaf454e166fa7df7 100644 (file)
@@ -202,7 +202,7 @@ static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
                          size_t size, enum dma_data_direction direction)
 {
        return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
-                       direction);
+                       ~0ul, direction);
 }
 
 static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
@@ -216,7 +216,7 @@ static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
                int nelems, enum dma_data_direction direction)
 {
        return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
-                       nelems, direction);
+                       nelems, ~0ul, direction);
 }
 
 static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
@@ -229,7 +229,7 @@ static void *vio_alloc_coherent(struct device *dev, size_t size,
                           dma_addr_t *dma_handle, gfp_t flag)
 {
        return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
-                       dma_handle, flag);
+                       dma_handle, ~0ul, flag);
 }
 
 static void vio_free_coherent(struct device *dev, size_t size,
index 6594bec7388243d8581f816dbca1d98b29176b01..deb3afb94484a0372978fca73ca2c4d37ca21dfd 100644 (file)
@@ -317,17 +317,16 @@ void *spu_syscall_table[] = {
        [__NR_ppoll]                    sys_ni_syscall, /* sys_ppoll */
        [__NR_unshare]                  sys_unshare,
        [__NR_splice]                   sys_splice,
+       [__NR_tee]                      sys_tee,
 };
 
 long spu_sys_callback(struct spu_syscall_block *s)
 {
        long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6);
 
-       BUILD_BUG_ON(ARRAY_SIZE(spu_syscall_table) != __NR_syscalls);
-
        syscall = spu_syscall_table[s->nr_ret];
 
-       if (s->nr_ret >= __NR_syscalls) {
+       if (s->nr_ret >= ARRAY_SIZE(spu_syscall_table)) {
                pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret);
                return -ENOSYS;
        }
index e14f9ac55cf4b11254c33b3337057932ca3738a7..df2343e1956bc266cc634ac88a217dd51f86d9ce 100644 (file)
@@ -231,6 +231,14 @@ static u8 kw_i2c_wait_interrupt(struct pmac_i2c_host_kw *host)
        return isr;
 }
 
+static void kw_i2c_do_stop(struct pmac_i2c_host_kw *host, int result)
+{
+       kw_write_reg(reg_control, KW_I2C_CTL_STOP);
+       host->state = state_stop;
+       host->result = result;
+}
+
+
 static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr)
 {
        u8 ack;
@@ -246,42 +254,36 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr)
        }
 
        if (isr == 0) {
+               printk(KERN_WARNING "low_i2c: Timeout in i2c transfer"
+                      " on keywest !\n");
                if (host->state != state_stop) {
-                       DBG_LOW("KW: Timeout !\n");
-                       host->result = -EIO;
-                       goto stop;
-               }
-               if (host->state == state_stop) {
-                       ack = kw_read_reg(reg_status);
-                       if (ack & KW_I2C_STAT_BUSY)
-                               kw_write_reg(reg_status, 0);
-                       host->state = state_idle;
-                       kw_write_reg(reg_ier, 0x00);
-                       if (!host->polled)
-                               complete(&host->complete);
+                       kw_i2c_do_stop(host, -EIO);
+                       return;
                }
+               ack = kw_read_reg(reg_status);
+               if (ack & KW_I2C_STAT_BUSY)
+                       kw_write_reg(reg_status, 0);
+               host->state = state_idle;
+               kw_write_reg(reg_ier, 0x00);
+               if (!host->polled)
+                       complete(&host->complete);
                return;
        }
 
        if (isr & KW_I2C_IRQ_ADDR) {
                ack = kw_read_reg(reg_status);
                if (host->state != state_addr) {
-                       kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
                        WRONG_STATE("KW_I2C_IRQ_ADDR"); 
-                       host->result = -EIO;
-                       goto stop;
+                       kw_i2c_do_stop(host, -EIO);
                }
                if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
-                       host->result = -ENODEV;
-                       DBG_LOW("KW: NAK on address\n");
+                       host->result = -ENXIO;
                        host->state = state_stop;
-                       return;
+                       DBG_LOW("KW: NAK on address\n");
                } else {
-                       if (host->len == 0) {
-                               kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR);
-                               goto stop;
-                       }
-                       if (host->rw) {
+                       if (host->len == 0)
+                               kw_i2c_do_stop(host, 0);
+                       else if (host->rw) {
                                host->state = state_read;
                                if (host->len > 1)
                                        kw_write_reg(reg_control,
@@ -308,25 +310,19 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr)
                        ack = kw_read_reg(reg_status);
                        if ((ack & KW_I2C_STAT_LAST_AAK) == 0) {
                                DBG_LOW("KW: nack on data write\n");
-                               host->result = -EIO;
-                               goto stop;
+                               host->result = -EFBIG;
+                               host->state = state_stop;
                        } else if (host->len) {
                                kw_write_reg(reg_data, *(host->data++));
                                host->len--;
-                       } else {
-                               kw_write_reg(reg_control, KW_I2C_CTL_STOP);
-                               host->state = state_stop;
-                               host->result = 0;
-                       }
-                       kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
+                       } else
+                               kw_i2c_do_stop(host, 0);
                } else {
-                       kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
                        WRONG_STATE("KW_I2C_IRQ_DATA"); 
-                       if (host->state != state_stop) {
-                               host->result = -EIO;
-                               goto stop;
-                       }
+                       if (host->state != state_stop)
+                               kw_i2c_do_stop(host, -EIO);
                }
+               kw_write_reg(reg_isr, KW_I2C_IRQ_DATA);
        }
 
        if (isr & KW_I2C_IRQ_STOP) {
@@ -340,14 +336,10 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr)
                        complete(&host->complete);
        }
 
+       /* Below should only happen in manual mode which we don't use ... */
        if (isr & KW_I2C_IRQ_START)
                kw_write_reg(reg_isr, KW_I2C_IRQ_START);
 
-       return;
- stop:
-       kw_write_reg(reg_control, KW_I2C_CTL_STOP);     
-       host->state = state_stop;
-       return;
 }
 
 /* Interrupt handler */
@@ -544,11 +536,11 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np)
                return NULL;
        }
 
-       /* Make sure IRA is disabled */
+       /* Make sure IRQ is disabled */
        kw_write_reg(reg_ier, 0);
 
        /* Request chip interrupt */
-       if (request_irq(host->irq, kw_i2c_irq, SA_SHIRQ, "keywest i2c", host))
+       if (request_irq(host->irq, kw_i2c_irq, 0, "keywest i2c", host))
                host->irq = NO_IRQ;
 
        printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n",
index 61d317428610ab3d953211366d2e938284f0d72a..38087bd6e3cf4273d5efeb38baa68ccf90328245 100644 (file)
@@ -49,6 +49,7 @@
 
 #include "dart.h"
 
+extern int iommu_is_off;
 extern int iommu_force_on;
 
 /* Physical base address and size of the DART table */
@@ -329,10 +330,17 @@ void iommu_init_early_dart(void)
 
 void __init alloc_dart_table(void)
 {
-       /* Only reserve DART space if machine has more than 2GB of RAM
+       /* Only reserve DART space if machine has more than 1GB of RAM
         * or if requested with iommu=on on cmdline.
+        *
+        * 1GB of RAM is picked as limit because some default devices
+        * (i.e. Airport Extreme) have 30 bit address range limits.
         */
-       if (lmb_end_of_DRAM() <= 0x80000000ull && !iommu_force_on)
+
+       if (iommu_is_off)
+               return;
+
+       if (!iommu_force_on && lmb_end_of_DRAM() <= 0x40000000ull)
                return;
 
        /* 512 pages (2MB) is max DART tablesize. */
index 77e4dc780f8cfa3efae51e0f1a088a1c9123bcfc..cc7c4aea939751a42985f5bc944614290993ffad 100644 (file)
@@ -134,6 +134,7 @@ main(void)
        DEFINE(TI_TASK, offsetof(struct thread_info, task));
        DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain));
        DEFINE(TI_FLAGS, offsetof(struct thread_info, flags));
+       DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, flags));
        DEFINE(TI_CPU, offsetof(struct thread_info, cpu));
        DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count));
 
index 5891ecbdc703294d0de7736cd4a94da57bdaffc0..1adc9145516f9eaf88a14047031038821ee67940 100644 (file)
@@ -128,29 +128,26 @@ transfer_to_handler:
        stw     r12,4(r11)
 #endif
        b       3f
+
 2:     /* if from kernel, check interrupted DOZE/NAP mode and
          * check for stack overflow
          */
+       lwz     r9,THREAD_INFO-THREAD(r12)
+       cmplw   r1,r9                   /* if r1 <= current->thread_info */
+       ble-    stack_ovf               /* then the kernel stack overflowed */
+5:
 #ifdef CONFIG_6xx
-       mfspr   r11,SPRN_HID0
-       mtcr    r11
-BEGIN_FTR_SECTION
-       bt-     8,4f                    /* Check DOZE */
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE)
-BEGIN_FTR_SECTION
-       bt-     9,4f                    /* Check NAP */
-END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP)
+       tophys(r9,r9)                   /* check local flags */
+       lwz     r12,TI_LOCAL_FLAGS(r9)
+       mtcrf   0x01,r12
+       bt-     31-TLF_NAPPING,4f
 #endif /* CONFIG_6xx */
        .globl transfer_to_handler_cont
 transfer_to_handler_cont:
-       lwz     r11,THREAD_INFO-THREAD(r12)
-       cmplw   r1,r11                  /* if r1 <= current->thread_info */
-       ble-    stack_ovf               /* then the kernel stack overflowed */
 3:
        mflr    r9
        lwz     r11,0(r9)               /* virtual address of handler */
        lwz     r9,4(r9)                /* where to go when done */
-       FIX_SRR1(r10,r12)
        mtspr   SPRN_SRR0,r11
        mtspr   SPRN_SRR1,r10
        mtlr    r9
@@ -158,7 +155,9 @@ transfer_to_handler_cont:
        RFI                             /* jump to handler, enable MMU */
 
 #ifdef CONFIG_6xx
-4:     b       power_save_6xx_restore
+4:     rlwinm  r12,r12,0,~_TLF_NAPPING
+       stw     r12,TI_LOCAL_FLAGS(r9)
+       b       power_save_6xx_restore
 #endif
 
 /*
@@ -167,10 +166,10 @@ transfer_to_handler_cont:
  */
 stack_ovf:
        /* sometimes we use a statically-allocated stack, which is OK. */
-       lis     r11,_end@h
-       ori     r11,r11,_end@l
-       cmplw   r1,r11
-       ble     3b                      /* r1 <= &_end is OK */
+       lis     r12,_end@h
+       ori     r12,r12,_end@l
+       cmplw   r1,r12
+       ble     5b                      /* r1 <= &_end is OK */
        SAVE_NVGPRS(r11)
        addi    r3,r1,STACK_FRAME_OVERHEAD
        lis     r1,init_thread_union@ha
index 865ba74991a9eec6927bcd47f1ac788564673389..b250b1b539b681f9be079e0bb7bf60dd87bba9ea 100644 (file)
@@ -94,6 +94,7 @@ EXPORT_SYMBOL(strcat);
 EXPORT_SYMBOL(strlen);
 EXPORT_SYMBOL(strcmp);
 EXPORT_SYMBOL(strcasecmp);
+EXPORT_SYMBOL(strncasecmp);
 EXPORT_SYMBOL(__div64_32);
 
 EXPORT_SYMBOL(csum_partial);
index ffc7309e9f22d51e640f77b95aab4028e57c841f..2e1c824c1cc9512356460ea3a09f2fd74c11dfe2 100644 (file)
@@ -63,7 +63,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p)
        flushi(p->addr);
 }
 
-static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        kcb->prev_kprobe.kp = kprobe_running();
        kcb->prev_kprobe.status = kcb->kprobe_status;
@@ -71,7 +71,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
        kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil;
 }
 
-static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
        kcb->kprobe_status = kcb->prev_kprobe.status;
@@ -79,7 +79,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
        kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
                                struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = p;
@@ -87,7 +87,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
        kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL);
 }
 
-static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
+static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs,
                        struct kprobe_ctlblk *kcb)
 {
        regs->tstate |= TSTATE_PIL;
@@ -273,7 +273,7 @@ static void __kprobes resume_execution(struct kprobe *p,
                        kcb->kprobe_orig_tstate_pil);
 }
 
-static inline int post_kprobe_handler(struct pt_regs *regs)
+static int __kprobes post_kprobe_handler(struct pt_regs *regs)
 {
        struct kprobe *cur = kprobe_running();
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -300,7 +300,7 @@ out:
        return 1;
 }
 
-static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
+static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
 {
        struct kprobe *cur = kprobe_running();
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
index 0ec4052db9c5bbb183714a44012ef07fc388b026..6ab852bfcd3ac62cb66b18a02433d6b3feaadfcb 100644 (file)
@@ -100,7 +100,7 @@ struct cow_header_v3_broken {
        __u32 alignment;
        __u32 cow_format;
        char backing_file[PATH_LEN_V3];
-};
+} __attribute__((packed));
 
 /* COW format definitions - for now, we have only the usual COW bitmap */
 #define COW_BITMAP 0
index 018b3819ab0bf3ea4fc3007a8240b6b7f99c8dca..8e7053013f7b7d11d218603487abf8c9dcd96294 100644 (file)
@@ -4,11 +4,11 @@
 #include <setjmp.h>
 #include "os.h"
 
-#define UML_SIGLONGJMP(buf, val) do { \
+#define UML_LONGJMP(buf, val) do { \
        longjmp(*buf, val);     \
 } while(0)
 
-#define UML_SIGSETJMP(buf, enable) ({ \
+#define UML_SETJMP(buf, enable) ({ \
        int n; \
        enable = get_signals(); \
        n = setjmp(*buf); \
index 82f96c574144cbc327daa8b5c82624014bb9cf83..2c13de321f2fb330eb5dc162fe53bffca57f3bad 100644 (file)
@@ -1,6 +1,7 @@
 #include <linux/stddef.h>
 #include <linux/sched.h>
 #include <linux/elf.h>
+#include <asm/mman.h>
 
 #define DEFINE(sym, val) \
        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -16,6 +17,7 @@
 void foo(void)
 {
        OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
+       DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
 #ifdef CONFIG_MODE_TT
        OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
 #endif
index 5ce93abd0b54fd79f95dea8df40cf3a756366bc0..939cc475757a583e7b38977f02c6f095de004465 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/time.h>
 #include <linux/elf.h>
 #include <asm/page.h>
+#include <asm/mman.h>
 
 #define DEFINE(sym, val) \
        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -18,6 +19,7 @@
 
 void foo(void)
 {
+       DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
 #ifdef CONFIG_MODE_TT
        OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
 #endif
index 71bb90a7606d0ebf8dab332fd874aa0e0f6d707b..c6432e7292411de1ea2006aabf97a13c3a7fa4eb 100644 (file)
@@ -8,6 +8,7 @@
 #include <fcntl.h>
 #include <sys/types.h>
 #include <sys/mman.h>
+#include <sys/statfs.h>
 #include "kern_util.h"
 #include "user.h"
 #include "user_util.h"
@@ -19,6 +20,7 @@
 
 #include <sys/param.h>
 
+static char *default_tmpdir = "/tmp";
 static char *tempdir = NULL;
 
 static void __init find_tempdir(void)
@@ -34,7 +36,7 @@ static void __init find_tempdir(void)
                        break;
        }
        if((dir == NULL) || (*dir == '\0'))
-               dir = "/tmp";
+               dir = default_tmpdir;
 
        tempdir = malloc(strlen(dir) + 2);
        if(tempdir == NULL){
@@ -46,6 +48,96 @@ static void __init find_tempdir(void)
        strcat(tempdir, "/");
 }
 
+/* This will return 1, with the first character in buf being the
+ * character following the next instance of c in the file.  This will
+ * read the file as needed.  If there's an error, -errno is returned;
+ * if the end of the file is reached, 0 is returned.
+ */
+static int next(int fd, char *buf, int size, char c)
+{
+       int n;
+       char *ptr;
+
+       while((ptr = strchr(buf, c)) == NULL){
+               n = read(fd, buf, size - 1);
+               if(n == 0)
+                       return 0;
+               else if(n < 0)
+                       return -errno;
+
+               buf[n] = '\0';
+       }
+
+       ptr++;
+       memmove(buf, ptr, strlen(ptr) + 1);
+       return 1;
+}
+
+static int checked_tmpdir = 0;
+
+/* Look for a tmpfs mounted at /dev/shm.  I couldn't find a cleaner
+ * way to do this than to parse /proc/mounts.  statfs will return the
+ * same filesystem magic number and fs id for both /dev and /dev/shm
+ * when they are both tmpfs, so you can't tell if they are different
+ * filesystems.  Also, there seems to be no other way of finding the
+ * mount point of a filesystem from within it.
+ *
+ * If a /dev/shm tmpfs entry is found, then we switch to using it.
+ * Otherwise, we stay with the default /tmp.
+ */
+static void which_tmpdir(void)
+{
+       int fd, found;
+       char buf[128] = { '\0' };
+
+       if(checked_tmpdir)
+               return;
+
+       checked_tmpdir = 1;
+
+       printf("Checking for tmpfs mount on /dev/shm...");
+
+       fd = open("/proc/mounts", O_RDONLY);
+       if(fd < 0){
+               printf("failed to open /proc/mounts, errno = %d\n", errno);
+               return;
+       }
+
+       while(1){
+               found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' ');
+               if(found != 1)
+                       break;
+
+               if(!strncmp(buf, "/dev/shm", strlen("/dev/shm")))
+                       goto found;
+
+               found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), '\n');
+               if(found != 1)
+                       break;
+       }
+
+err:
+       if(found == 0)
+               printf("nothing mounted on /dev/shm\n");
+       else if(found < 0)
+               printf("read returned errno %d\n", -found);
+
+       return;
+
+found:
+       found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' ');
+       if(found != 1)
+               goto err;
+
+       if(strncmp(buf, "tmpfs", strlen("tmpfs"))){
+               printf("not tmpfs\n");
+               return;
+       }
+
+       printf("OK\n");
+       default_tmpdir = "/dev/shm";
+}
+
 /*
  * This proc still used in tt-mode
  * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger).
@@ -56,6 +148,7 @@ int make_tempfile(const char *template, char **out_tempname, int do_unlink)
        char *tempname;
        int fd;
 
+       which_tmpdir();
        tempname = malloc(MAXPATHLEN);
 
        find_tempdir();
@@ -137,3 +230,26 @@ int create_mem_file(unsigned long long len)
        }
        return(fd);
 }
+
+
+void check_tmpexec(void)
+{
+       void *addr;
+       int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
+
+       addr = mmap(NULL, UM_KERN_PAGE_SIZE,
+                   PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
+       printf("Checking PROT_EXEC mmap in %s...",tempdir);
+       fflush(stdout);
+       if(addr == MAP_FAILED){
+               err = errno;
+               perror("failed");
+               if(err == EPERM)
+                       printf("%s must be not mounted noexec\n",tempdir);
+               exit(1);
+       }
+       printf("OK\n");
+       munmap(addr, UM_KERN_PAGE_SIZE);
+
+       close(fd);
+}
index 8176b0b52047061ae681e19d51583f4e683cad97..3505f44f8a25b4d2687327f4844ee61c468752e7 100644 (file)
@@ -190,7 +190,7 @@ int os_unmap_memory(void *addr, int len)
 }
 
 #ifndef MADV_REMOVE
-#define MADV_REMOVE    0x5             /* remove these pages & resources */
+#define MADV_REMOVE KERNEL_MADV_REMOVE
 #endif
 
 int os_drop_memory(void *addr, int length)
@@ -216,7 +216,7 @@ int can_drop_memory(void)
        }
 
        addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
-                     MAP_PRIVATE, fd, 0);
+                     MAP_SHARED, fd, 0);
        if(addr == MAP_FAILED){
                printk("Mapping test memory file failed, err = %d\n", -errno);
                return 0;
@@ -266,11 +266,11 @@ void init_new_thread_signals(int altstack)
 
 int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr)
 {
-       sigjmp_buf buf;
+       jmp_buf buf;
        int n, enable;
 
        *jmp_ptr = &buf;
-       n = UML_SIGSETJMP(&buf, enable);
+       n = UML_SETJMP(&buf, enable);
        if(n != 0)
                return(n);
        (*fn)(arg);
index 045ae0037456a3a723e5d58fdb9858af64349a61..0776bc18ca85ebeab95d1f579e244a7b2fe988e8 100644 (file)
@@ -434,7 +434,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
                void (*handler)(int))
 {
        unsigned long flags;
-       sigjmp_buf switch_buf, fork_buf;
+       jmp_buf switch_buf, fork_buf;
        int enable;
 
        *switch_buf_ptr = &switch_buf;
@@ -450,7 +450,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
         */
        flags = get_signals();
        block_signals();
-       if(UML_SIGSETJMP(&fork_buf, enable) == 0)
+       if(UML_SETJMP(&fork_buf, enable) == 0)
                new_thread_proc(stack, handler);
 
        remove_sigstack();
@@ -466,35 +466,35 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr,
 
 void thread_wait(void *sw, void *fb)
 {
-       sigjmp_buf buf, **switch_buf = sw, *fork_buf;
+       jmp_buf buf, **switch_buf = sw, *fork_buf;
        int enable;
 
        *switch_buf = &buf;
        fork_buf = fb;
-       if(UML_SIGSETJMP(&buf, enable) == 0)
+       if(UML_SETJMP(&buf, enable) == 0)
                siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK);
 }
 
 void switch_threads(void *me, void *next)
 {
-       sigjmp_buf my_buf, **me_ptr = me, *next_buf = next;
+       jmp_buf my_buf, **me_ptr = me, *next_buf = next;
        int enable;
 
        *me_ptr = &my_buf;
-       if(UML_SIGSETJMP(&my_buf, enable) == 0)
-               UML_SIGLONGJMP(next_buf, 1);
+       if(UML_SETJMP(&my_buf, enable) == 0)
+               UML_LONGJMP(next_buf, 1);
 }
 
-static sigjmp_buf initial_jmpbuf;
+static jmp_buf initial_jmpbuf;
 
 /* XXX Make these percpu */
 static void (*cb_proc)(void *arg);
 static void *cb_arg;
-static sigjmp_buf *cb_back;
+static jmp_buf *cb_back;
 
 int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
 {
-       sigjmp_buf **switch_buf = switch_buf_ptr;
+       jmp_buf **switch_buf = switch_buf_ptr;
        int n, enable;
 
        set_handler(SIGWINCH, (__sighandler_t) sig_handler,
@@ -502,7 +502,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
                    SIGVTALRM, -1);
 
        *fork_buf_ptr = &initial_jmpbuf;
-       n = UML_SIGSETJMP(&initial_jmpbuf, enable);
+       n = UML_SETJMP(&initial_jmpbuf, enable);
        switch(n){
        case INIT_JMP_NEW_THREAD:
                new_thread_proc((void *) stack, new_thread_handler);
@@ -512,7 +512,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
                break;
        case INIT_JMP_CALLBACK:
                (*cb_proc)(cb_arg);
-               UML_SIGLONGJMP(cb_back, 1);
+               UML_LONGJMP(cb_back, 1);
                break;
        case INIT_JMP_HALT:
                kmalloc_ok = 0;
@@ -523,12 +523,12 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr)
        default:
                panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
        }
-       UML_SIGLONGJMP(*switch_buf, 1);
+       UML_LONGJMP(*switch_buf, 1);
 }
 
 void initial_thread_cb_skas(void (*proc)(void *), void *arg)
 {
-       sigjmp_buf here;
+       jmp_buf here;
        int enable;
 
        cb_proc = proc;
@@ -536,8 +536,8 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
        cb_back = &here;
 
        block_signals();
-       if(UML_SIGSETJMP(&here, enable) == 0)
-               UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
+       if(UML_SETJMP(&here, enable) == 0)
+               UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
        unblock_signals();
 
        cb_proc = NULL;
@@ -548,13 +548,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
 void halt_skas(void)
 {
        block_signals();
-       UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT);
+       UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT);
 }
 
 void reboot_skas(void)
 {
        block_signals();
-       UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);
+       UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);
 }
 
 void switch_mm_skas(struct mm_id *mm_idp)
index 387e26af301a57c6ca0a861c654727af7a5b3696..5031485040090bfc07ba71eca0a41564c0cc8b03 100644 (file)
@@ -296,29 +296,7 @@ static void __init check_ptrace(void)
        check_sysemu();
 }
 
-extern int create_tmp_file(unsigned long long len);
-
-static void check_tmpexec(void)
-{
-       void *addr;
-       int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE);
-
-       addr = mmap(NULL, UM_KERN_PAGE_SIZE,
-                   PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0);
-       printf("Checking PROT_EXEC mmap in /tmp...");
-       fflush(stdout);
-       if(addr == MAP_FAILED){
-               err = errno;
-               perror("failed");
-               if(err == EPERM)
-                       printf("/tmp must be not mounted noexec\n");
-               exit(1);
-       }
-       printf("OK\n");
-       munmap(addr, UM_KERN_PAGE_SIZE);
-
-       close(fd);
-}
+extern void check_tmpexec(void);
 
 void os_early_checks(void)
 {
index a9f6b26f9828f8f4c0a99bc6a2f8449054be8bb8..90b29ae9af46158ed52154d7e77ce1c4b100f83f 100644 (file)
@@ -35,7 +35,7 @@ void os_fill_handlinfo(struct kern_handlers h)
 
 void do_longjmp(void *b, int val)
 {
-       sigjmp_buf *buf = b;
+       jmp_buf *buf = b;
 
-       UML_SIGLONGJMP(buf, val);
+       UML_LONGJMP(buf, val);
 }
index 166fb66995df87e58793c6f99a33334324eaddce..e523719330b27cb2b0a29bd1dacbf15bc8b1ca05 100644 (file)
@@ -16,9 +16,9 @@ unsigned long __do_user_copy(void *to, const void *from, int n,
        unsigned long *faddrp = (unsigned long *) fault_addr, ret;
        int enable;
 
-       sigjmp_buf jbuf;
+       jmp_buf jbuf;
        *fault_catcher = &jbuf;
-       if(UML_SIGSETJMP(&jbuf, enable) == 0){
+       if(UML_SETJMP(&jbuf, enable) == 0){
                (*op)(to, from, n);
                ret = 0;
                *faulted_out = 0;
index e32065e2fdc80d7203a817d8708e3d3cbed845be..c47a2a7ce70e75614e425e7270b2e1364188b67d 100644 (file)
@@ -104,7 +104,7 @@ void setup_hostinfo(void)
 int setjmp_wrapper(void (*proc)(void *, void *), ...)
 {
        va_list args;
-       sigjmp_buf buf;
+       jmp_buf buf;
        int n;
 
        n = sigsetjmp(buf, 1);
index 618fd8594643b147ec6c878f696ab28a02ce0aeb..0709fc6670c287ab4b3bf2323792ebc19e4a0873 100644 (file)
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs,
        return(0);
 }
 
-int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp,
+int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp,
                          struct pt_regs *regs, unsigned long sp)
 {
        struct sigcontext sc;
@@ -132,7 +132,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
        return(err);
 }
 
-int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp,
+int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp,
                       struct sigcontext *from, int fpsize, unsigned long sp)
 {
        struct _fpstate __user *to_fp;
@@ -167,7 +167,7 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from)
        return(ret);
 }
 
-static int copy_sc_to_user(struct sigcontext *to, struct _fpstate __user *fp,
+static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp,
                           struct pt_regs *from, unsigned long sp)
 {
        return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
index a37f672ec964e3815c4f2de247b82d7d09dc1e30..2355dc19c46c544db5627b4e6f678903a23a5a0c 100644 (file)
@@ -27,6 +27,6 @@ stub_segv_handler(int sig)
         * the stack in its original form when we do the sigreturn here, by
         * hand.
         */
-       __asm__("mov %0,%%esp ; movl %1, %%eax ; "
-               "int $0x80" : : "a" (sc), "g" (__NR_sigreturn));
+       __asm__ __volatile__("mov %0,%%esp ; movl %1, %%eax ; "
+                            "int $0x80" : : "a" (sc), "g" (__NR_sigreturn));
 }
index a27099533198573d223f54a94134b84f8b7b7674..1c967026c957dd08e4b81406a82712b60ada8ee6 100644 (file)
@@ -33,7 +33,7 @@ stub_segv_handler(int sig)
        struct ucontext *uc;
         int pid;
 
-       __asm__("movq %%rdx, %0" : "=g" (uc) :);
+       __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :);
        GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
                              &uc->uc_mcontext);
 
@@ -44,8 +44,8 @@ stub_segv_handler(int sig)
         * the signal frame.  So, we use the ucontext pointer, which we know
         * already, to get the signal frame pointer, and add 8 to that.
         */
-       __asm__("movq %0, %%rsp; movq %1, %%rax ; syscall": :
-               "g" ((unsigned long) container_of(uc, struct rt_sigframe, 
-                                                 uc) + 8),
-                "g" (__NR_rt_sigreturn));
+       __asm__ __volatile__("movq %0, %%rsp; movq %1, %%rax ; syscall": :
+                             "g" ((unsigned long)
+                                  container_of(uc, struct rt_sigframe, uc) + 8),
+                             "g" (__NR_rt_sigreturn));
 }
index 929e6b0771f803bb410e37d63188dba10b63fd4f..e9263b4975e0c4fec437c134ae45bebac2d501af 100644 (file)
@@ -27,5 +27,5 @@ $(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \
 $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE
        $(call if_changed,syscall)
 
-AFLAGS_vsyscall-sysenter.o = -m32
-AFLAGS_vsyscall-syscall.o = -m32
+AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32
+AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32
index accbff3fec491826071ad572c19d0207413a1bca..1eaa5dae6174ff57b514a56828f07e6f8ed0a149 100644 (file)
@@ -53,7 +53,7 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
 /*
  * returns non-zero if opcode modifies the interrupt flag.
  */
-static inline int is_IF_modifier(kprobe_opcode_t *insn)
+static __always_inline int is_IF_modifier(kprobe_opcode_t *insn)
 {
        switch (*insn) {
        case 0xfa:              /* cli */
@@ -84,7 +84,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
  * If it does, return the address of the 32-bit displacement word.
  * If not, return null.
  */
-static inline s32 *is_riprel(u8 *insn)
+static s32 __kprobes *is_riprel(u8 *insn)
 {
 #define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf)               \
        (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) |   \
@@ -229,7 +229,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p)
        mutex_unlock(&kprobe_mutex);
 }
 
-static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        kcb->prev_kprobe.kp = kprobe_running();
        kcb->prev_kprobe.status = kcb->kprobe_status;
@@ -237,7 +237,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb)
        kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags;
 }
 
-static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp;
        kcb->kprobe_status = kcb->prev_kprobe.status;
@@ -245,7 +245,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb)
        kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags;
 }
 
-static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
+static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs,
                                struct kprobe_ctlblk *kcb)
 {
        __get_cpu_var(current_kprobe) = p;
index a6c01e121266c8f521e1e7336c42cf41735e4afa..9d3d76c85ae7160ea9def9af5ccb4d133370ffbe 100644 (file)
@@ -112,10 +112,6 @@ static unsigned long alloc_iommu(int size)
 static void free_iommu(unsigned long offset, int size)
 { 
        unsigned long flags;
-       if (size == 1) { 
-               clear_bit(offset, iommu_gart_bitmap); 
-               return;
-       }
        spin_lock_irqsave(&iommu_bitmap_lock, flags);
        __clear_bit_string(iommu_gart_bitmap, offset, size);
        spin_unlock_irqrestore(&iommu_bitmap_lock, flags);
index 1c44b53cb15bb48391cf4300dbb93fd5fac34835..fb903e65e079a26034f76a30ef6f54b40613453d 100644 (file)
@@ -575,8 +575,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
        prev->userrsp = read_pda(oldrsp); 
        write_pda(oldrsp, next->userrsp); 
        write_pda(pcurrent, next_p); 
+
        /* This must be here to ensure both math_state_restore() and
-          kernel_fpu_begin() work consistently. */
+          kernel_fpu_begin() work consistently. 
+          And the AMD workaround requires it to be after DS reload. */
        unlazy_fpu(prev_p);
        write_pda(kernelstack,
                  task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET);
index c50b06765a80ddc16d0d17a59055a8cd42044cea..759070c827511bb482c3b770ff0f35407746936c 100644 (file)
@@ -930,6 +930,10 @@ static int __init init_amd(struct cpuinfo_x86 *c)
        if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58))
                set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability);
 
+       /* Enable workaround for FXSAVE leak */
+       if (c->x86 >= 6)
+               set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability);
+
        r = get_model_name(c);
        if (!r) { 
                switch (c->x86) { 
index cc02573a327170f80cbf5fa64c99c3d25aad9eef..b2fac14baac0fc151838b32ad54f6eaf741b8047 100644 (file)
@@ -188,11 +188,13 @@ void __init setup_node_zones(int nodeid)
           memory. */
        memmapsize = sizeof(struct page) * (end_pfn-start_pfn);
        limit = end_pfn << PAGE_SHIFT;
+#ifdef CONFIG_FLAT_NODE_MEM_MAP
        NODE_DATA(nodeid)->node_mem_map = 
                __alloc_bootmem_core(NODE_DATA(nodeid)->bdata, 
                                memmapsize, SMP_CACHE_BYTES, 
                                round_down(limit - memmapsize, PAGE_SIZE), 
                                limit);
+#endif
 
        size_zones(zones, holes, start_pfn, end_pfn);
        free_area_init_node(nodeid, NODE_DATA(nodeid), zones,
index 0d6be03d929ea348423f8abf4a222f7c699d4e3b..29825792cbd5305cfbea9c1f6063710ec4b46be8 100644 (file)
@@ -895,10 +895,8 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name)
 EXPORT_SYMBOL(elv_dispatch_sort);
 EXPORT_SYMBOL(elv_add_request);
 EXPORT_SYMBOL(__elv_add_request);
-EXPORT_SYMBOL(elv_requeue_request);
 EXPORT_SYMBOL(elv_next_request);
 EXPORT_SYMBOL(elv_dequeue_request);
 EXPORT_SYMBOL(elv_queue_empty);
-EXPORT_SYMBOL(elv_completed_request);
 EXPORT_SYMBOL(elevator_exit);
 EXPORT_SYMBOL(elevator_init);
index e112d1a5dab6b8c2dcae45e2a6b18bbfc4529760..1755c053fd68ce648ba90bcbc3c7132ac23d8ad1 100644 (file)
@@ -1554,7 +1554,7 @@ void blk_plug_device(request_queue_t *q)
         * don't plug a stopped queue, it must be paired with blk_start_queue()
         * which will restart the queueing
         */
-       if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))
+       if (blk_queue_stopped(q))
                return;
 
        if (!test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) {
@@ -1587,7 +1587,7 @@ EXPORT_SYMBOL(blk_remove_plug);
  */
 void __generic_unplug_device(request_queue_t *q)
 {
-       if (unlikely(test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)))
+       if (unlikely(blk_queue_stopped(q)))
                return;
 
        if (!blk_remove_plug(q))
index 5d72f50de1ac97c6e377fb6c5e0d0d4192016983..46d66037b917c5851222b56af77f4b158ce793aa 100644 (file)
@@ -241,9 +241,10 @@ static int __init cs5535_gpio_init(void)
 static void __exit cs5535_gpio_cleanup(void)
 {
        dev_t dev_id = MKDEV(major, 0);
+
+       cdev_del(&cs5535_gpio_cdev);
        unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT);
-       if (gpio_base != 0)
-               release_region(gpio_base, CS5535_GPIO_SIZE);
+       release_region(gpio_base, CS5535_GPIO_SIZE);
 }
 
 module_init(cs5535_gpio_init);
index 58dcdee1cd719ab3d165907fb76f53c6e55c5db6..0030cd8e2e956cb436ae781c854ba41df23058a9 100644 (file)
@@ -165,7 +165,7 @@ static int bt_start_transaction(struct si_sm_data *bt,
 {
        unsigned int i;
 
-       if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH))
+       if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2)))
               return -1;
 
        if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED))
index a86c0f29953e7c1e2fa5921af10bb7ba88ebe062..b36eef0e9d199ff2751ddba5b77d812bacf489cb 100644 (file)
@@ -2198,11 +2198,11 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info)
        }
 }
 
-static struct ipmi_default_vals
+static __devinitdata struct ipmi_default_vals
 {
        int type;
        int port;
-} __devinit ipmi_defaults[] =
+} ipmi_defaults[] =
 {
        { .type = SI_KCS, .port = 0xca2 },
        { .type = SI_SMIC, .port = 0xca9 },
index b543821d8cb4c6be928c2769bce38b5f649fb9a8..56c8243cdb734b2d9212ec1eed9643560e82864b 100644 (file)
@@ -390,7 +390,8 @@ scdrv_init(void)
                        format_module_id(devnamep, geo_module(geoid),
                                         MODULE_FORMAT_BRIEF);
                        devnamep = devname + strlen(devname);
-                       sprintf(devnamep, "#%d", geo_slab(geoid));
+                       sprintf(devnamep, "^%d#%d", geo_slot(geoid),
+                               geo_slab(geoid));
 
                        /* allocate sysctl device data */
                        scd = kzalloc(sizeof (struct sysctl_data_s),
index f8dd8527c6aa9d8e30d17a26b64ed5b5dcccb2f7..a90f5d97df35dc8c262145efe0187085a6bd2009 100644 (file)
@@ -1341,6 +1341,9 @@ static int __devinit sonypi_probe(struct platform_device *dev)
        else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
                                          PCI_DEVICE_ID_INTEL_ICH6_1, NULL)))
                sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
+       else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL,
+                                         PCI_DEVICE_ID_INTEL_ICH7_1, NULL)))
+               sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3;
        else
                sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2;
 
index a6873bf89ffad63c6196dacc9f3499dcb6c22387..1efde3b27619b4113ca95ee1ca3116f6409b0ca2 100644 (file)
@@ -20,9 +20,18 @@ config TCG_TPM
          Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI
          and CONFIG_PNPACPI.
 
+config TCG_TIS
+       tristate "TPM Interface Specification 1.2 Interface"
+       depends on TCG_TPM
+       ---help---
+         If you have a TPM security chip that is compliant with the
+         TCG TIS 1.2 TPM specification say Yes and it will be accessible
+         from within Linux.  To compile this driver as a module, choose
+         M here; the module will be called tpm_tis.
+
 config TCG_NSC
        tristate "National Semiconductor TPM Interface"
-       depends on TCG_TPM
+       depends on TCG_TPM && PNPACPI
        ---help---
          If you have a TPM security chip from National Semicondutor 
          say Yes and it will be accessible from within Linux.  To 
index ba4582d160fd6081a852f57aa4d8abff8779f663..ea3a1e02a824de2b1a80feaa5ebc0e0125162c1c 100644 (file)
@@ -5,6 +5,7 @@ obj-$(CONFIG_TCG_TPM) += tpm.o
 ifdef CONFIG_ACPI
        obj-$(CONFIG_TCG_TPM) += tpm_bios.o
 endif
+obj-$(CONFIG_TCG_TIS) += tpm_tis.o
 obj-$(CONFIG_TCG_NSC) += tpm_nsc.o
 obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o
 obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o
index 5a3870477ef182ddb815ab196fa321b93c42872a..6889e7db3aff5285dd7824317c3f6469fc2e00c2 100644 (file)
@@ -32,12 +32,291 @@ enum tpm_const {
        TPM_MINOR = 224,        /* officially assigned */
        TPM_BUFSIZE = 2048,
        TPM_NUM_DEVICES = 256,
-       TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int))
 };
 
+enum tpm_duration {
+       TPM_SHORT = 0,
+       TPM_MEDIUM = 1,
+       TPM_LONG = 2,
+       TPM_UNDEFINED,
+};
+
+#define TPM_MAX_ORDINAL 243
+#define TPM_MAX_PROTECTED_ORDINAL 12
+#define TPM_PROTECTED_ORDINAL_MASK 0xFF
+
 static LIST_HEAD(tpm_chip_list);
 static DEFINE_SPINLOCK(driver_lock);
-static int dev_mask[TPM_NUM_MASK_ENTRIES];
+static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES);
+
+/*
+ * Array with one entry per ordinal defining the maximum amount
+ * of time the chip could take to return the result.  The ordinal
+ * designation of short, medium or long is defined in a table in
+ * TCG Specification TPM Main Part 2 TPM Structures Section 17. The
+ * values of the SHORT, MEDIUM, and LONG durations are retrieved
+ * from the chip during initialization with a call to tpm_get_timeouts.
+ */
+static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = {
+       TPM_UNDEFINED,          /* 0 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 5 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 10 */
+       TPM_SHORT,
+};
+
+static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = {
+       TPM_UNDEFINED,          /* 0 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 5 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 10 */
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_LONG,
+       TPM_LONG,
+       TPM_MEDIUM,             /* 15 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_LONG,
+       TPM_SHORT,              /* 20 */
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_SHORT,              /* 25 */
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_MEDIUM,             /* 30 */
+       TPM_LONG,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,              /* 35 */
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_MEDIUM,             /* 40 */
+       TPM_LONG,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,              /* 45 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_LONG,
+       TPM_MEDIUM,             /* 50 */
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 55 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_MEDIUM,             /* 60 */
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_MEDIUM,             /* 65 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 70 */
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 75 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_LONG,               /* 80 */
+       TPM_UNDEFINED,
+       TPM_MEDIUM,
+       TPM_LONG,
+       TPM_SHORT,
+       TPM_UNDEFINED,          /* 85 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 90 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,          /* 95 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_MEDIUM,             /* 100 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 105 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 110 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,              /* 115 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_LONG,               /* 120 */
+       TPM_LONG,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_SHORT,
+       TPM_SHORT,              /* 125 */
+       TPM_SHORT,
+       TPM_LONG,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,              /* 130 */
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,          /* 135 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 140 */
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 145 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 150 */
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,          /* 155 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 160 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 165 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_LONG,               /* 170 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 175 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_MEDIUM,             /* 180 */
+       TPM_SHORT,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_MEDIUM,             /* 185 */
+       TPM_SHORT,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 190 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 195 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 200 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,
+       TPM_SHORT,              /* 205 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_MEDIUM,             /* 210 */
+       TPM_UNDEFINED,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,          /* 215 */
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,
+       TPM_SHORT,              /* 220 */
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_SHORT,
+       TPM_UNDEFINED,          /* 225 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 230 */
+       TPM_LONG,
+       TPM_MEDIUM,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,          /* 235 */
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_UNDEFINED,
+       TPM_SHORT,              /* 240 */
+       TPM_UNDEFINED,
+       TPM_MEDIUM,
+};
 
 static void user_reader_timeout(unsigned long ptr)
 {
@@ -46,7 +325,7 @@ static void user_reader_timeout(unsigned long ptr)
        schedule_work(&chip->work);
 }
 
-static void timeout_work(void * ptr)
+static void timeout_work(void *ptr)
 {
        struct tpm_chip *chip = ptr;
 
@@ -56,6 +335,32 @@ static void timeout_work(void * ptr)
        up(&chip->buffer_mutex);
 }
 
+/*
+ * Returns max number of jiffies to wait
+ */
+unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip,
+                                          u32 ordinal)
+{
+       int duration_idx = TPM_UNDEFINED;
+       int duration = 0;
+
+       if (ordinal < TPM_MAX_ORDINAL)
+               duration_idx = tpm_ordinal_duration[ordinal];
+       else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) <
+                TPM_MAX_PROTECTED_ORDINAL)
+               duration_idx =
+                   tpm_protected_ordinal_duration[ordinal &
+                                                  TPM_PROTECTED_ORDINAL_MASK];
+
+       if (duration_idx != TPM_UNDEFINED)
+               duration = chip->vendor.duration[duration_idx];
+       if (duration <= 0)
+               return 2 * 60 * HZ;
+       else
+               return duration;
+}
+EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration);
+
 /*
  * Internal kernel interface to transmit TPM commands
  */
@@ -63,11 +368,11 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
                            size_t bufsiz)
 {
        ssize_t rc;
-       u32 count;
+       u32 count, ordinal;
        unsigned long stop;
 
        count = be32_to_cpu(*((__be32 *) (buf + 2)));
-
+       ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
        if (count == 0)
                return -ENODATA;
        if (count > bufsiz) {
@@ -78,21 +383,23 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
 
        down(&chip->tpm_mutex);
 
-       if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) {
+       if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) {
                dev_err(chip->dev,
                        "tpm_transmit: tpm_send: error %zd\n", rc);
                goto out;
        }
 
-       stop = jiffies + 2 * 60 * HZ;
+       if (chip->vendor.irq)
+               goto out_recv;
+
+       stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal);
        do {
-               u8 status = chip->vendor->status(chip);
-               if ((status & chip->vendor->req_complete_mask) ==
-                   chip->vendor->req_complete_val) {
+               u8 status = chip->vendor.status(chip);
+               if ((status & chip->vendor.req_complete_mask) ==
+                   chip->vendor.req_complete_val)
                        goto out_recv;
-               }
 
-               if ((status == chip->vendor->req_canceled)) {
+               if ((status == chip->vendor.req_canceled)) {
                        dev_err(chip->dev, "Operation Canceled\n");
                        rc = -ECANCELED;
                        goto out;
@@ -102,14 +409,13 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf,
                rmb();
        } while (time_before(jiffies, stop));
 
-
-       chip->vendor->cancel(chip);
+       chip->vendor.cancel(chip);
        dev_err(chip->dev, "Operation Timed out\n");
        rc = -ETIME;
        goto out;
 
 out_recv:
-       rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz);
+       rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz);
        if (rc < 0)
                dev_err(chip->dev,
                        "tpm_transmit: tpm_recv: error %zd\n", rc);
@@ -119,17 +425,247 @@ out:
 }
 
 #define TPM_DIGEST_SIZE 20
-#define CAP_PCR_RESULT_SIZE 18
-static const u8 cap_pcr[] = {
+#define TPM_ERROR_SIZE 10
+#define TPM_RET_CODE_IDX 6
+#define TPM_GET_CAP_RET_SIZE_IDX 10
+#define TPM_GET_CAP_RET_UINT32_1_IDX 14
+#define TPM_GET_CAP_RET_UINT32_2_IDX 18
+#define TPM_GET_CAP_RET_UINT32_3_IDX 22
+#define TPM_GET_CAP_RET_UINT32_4_IDX 26
+#define TPM_GET_CAP_PERM_DISABLE_IDX 16
+#define TPM_GET_CAP_PERM_INACTIVE_IDX 18
+#define TPM_GET_CAP_RET_BOOL_1_IDX 14
+#define TPM_GET_CAP_TEMP_INACTIVE_IDX 16
+
+#define TPM_CAP_IDX 13
+#define TPM_CAP_SUBCAP_IDX 21
+
+enum tpm_capabilities {
+       TPM_CAP_FLAG = 4,
+       TPM_CAP_PROP = 5,
+};
+
+enum tpm_sub_capabilities {
+       TPM_CAP_PROP_PCR = 0x1,
+       TPM_CAP_PROP_MANUFACTURER = 0x3,
+       TPM_CAP_FLAG_PERM = 0x8,
+       TPM_CAP_FLAG_VOL = 0x9,
+       TPM_CAP_PROP_OWNER = 0x11,
+       TPM_CAP_PROP_TIS_TIMEOUT = 0x15,
+       TPM_CAP_PROP_TIS_DURATION = 0x20,
+};
+
+/*
+ * This is a semi generic GetCapability command for use
+ * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG
+ * and their associated sub_capabilities.
+ */
+
+static const u8 tpm_cap[] = {
        0, 193,                 /* TPM_TAG_RQU_COMMAND */
        0, 0, 0, 22,            /* length */
        0, 0, 0, 101,           /* TPM_ORD_GetCapability */
-       0, 0, 0, 5,
-       0, 0, 0, 4,
-       0, 0, 1, 1
+       0, 0, 0, 0,             /* TPM_CAP_<TYPE> */
+       0, 0, 0, 4,             /* TPM_CAP_SUB_<TYPE> size */
+       0, 0, 1, 0              /* TPM_CAP_SUB_<TYPE> */
 };
 
-#define READ_PCR_RESULT_SIZE 30
+static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len,
+                           char *desc)
+{
+       int err;
+
+       len = tpm_transmit(chip, data, len);
+       if (len <  0)
+               return len;
+       if (len == TPM_ERROR_SIZE) {
+               err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)));
+               dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc);
+               return err;
+       }
+       return 0;
+}
+
+void tpm_gen_interrupt(struct tpm_chip *chip)
+{
+       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+       ssize_t rc;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the timeouts");
+}
+EXPORT_SYMBOL_GPL(tpm_gen_interrupt);
+
+void tpm_get_timeouts(struct tpm_chip *chip)
+{
+       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)];
+       ssize_t rc;
+       u32 timeout;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the timeouts");
+       if (rc)
+               goto duration;
+
+       if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+           != 4 * sizeof(u32))
+               goto duration;
+
+       /* Don't overwrite default if value is 0 */
+       timeout =
+           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)));
+       if (timeout)
+               chip->vendor.timeout_a = msecs_to_jiffies(timeout);
+       timeout =
+           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX)));
+       if (timeout)
+               chip->vendor.timeout_b = msecs_to_jiffies(timeout);
+       timeout =
+           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX)));
+       if (timeout)
+               chip->vendor.timeout_c = msecs_to_jiffies(timeout);
+       timeout =
+           be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX)));
+       if (timeout)
+               chip->vendor.timeout_d = msecs_to_jiffies(timeout);
+
+duration:
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the durations");
+       if (rc)
+               return;
+
+       if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX)))
+           != 3 * sizeof(u32))
+               return;
+
+       chip->vendor.duration[TPM_SHORT] =
+           msecs_to_jiffies(be32_to_cpu
+                            (*((__be32 *) (data +
+                                           TPM_GET_CAP_RET_UINT32_1_IDX))));
+       chip->vendor.duration[TPM_MEDIUM] =
+           msecs_to_jiffies(be32_to_cpu
+                            (*((__be32 *) (data +
+                                           TPM_GET_CAP_RET_UINT32_2_IDX))));
+       chip->vendor.duration[TPM_LONG] =
+           msecs_to_jiffies(be32_to_cpu
+                            (*((__be32 *) (data +
+                                           TPM_GET_CAP_RET_UINT32_3_IDX))));
+}
+EXPORT_SYMBOL_GPL(tpm_get_timeouts);
+
+void tpm_continue_selftest(struct tpm_chip *chip)
+{
+       u8 data[] = {
+               0, 193,                 /* TPM_TAG_RQU_COMMAND */
+               0, 0, 0, 10,            /* length */
+               0, 0, 0, 83,            /* TPM_ORD_GetCapability */
+       };
+
+       tpm_transmit(chip, data, sizeof(data));
+}
+EXPORT_SYMBOL_GPL(tpm_continue_selftest);
+
+ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr,
+                       char *buf)
+{
+       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
+       ssize_t rc;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attemtping to determine the permanent state");
+       if (rc)
+               return 0;
+       return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]);
+}
+EXPORT_SYMBOL_GPL(tpm_show_enabled);
+
+ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr,
+                       char *buf)
+{
+       u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)];
+       ssize_t rc;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attemtping to determine the permanent state");
+       if (rc)
+               return 0;
+       return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]);
+}
+EXPORT_SYMBOL_GPL(tpm_show_active);
+
+ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr,
+                       char *buf)
+{
+       u8 data[sizeof(tpm_cap)];
+       ssize_t rc;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the owner state");
+       if (rc)
+               return 0;
+       return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]);
+}
+EXPORT_SYMBOL_GPL(tpm_show_owned);
+
+ssize_t tpm_show_temp_deactivated(struct device * dev,
+                               struct device_attribute * attr, char *buf)
+{
+       u8 data[sizeof(tpm_cap)];
+       ssize_t rc;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_FLAG;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the temporary state");
+       if (rc)
+               return 0;
+       return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]);
+}
+EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated);
+
 static const u8 pcrread[] = {
        0, 193,                 /* TPM_TAG_RQU_COMMAND */
        0, 0, 0, 14,            /* length */
@@ -140,8 +676,8 @@ static const u8 pcrread[] = {
 ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
-       u8 data[READ_PCR_RESULT_SIZE];
-       ssize_t len;
+       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)];
+       ssize_t rc;
        int i, j, num_pcrs;
        __be32 index;
        char *str = buf;
@@ -150,29 +686,24 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr,
        if (chip == NULL)
                return -ENODEV;
 
-       memcpy(data, cap_pcr, sizeof(cap_pcr));
-       if ((len = tpm_transmit(chip, data, sizeof(data)))
-           < CAP_PCR_RESULT_SIZE) {
-               dev_dbg(chip->dev, "A TPM error (%d) occurred "
-                               "attempting to determine the number of PCRS\n",
-                       be32_to_cpu(*((__be32 *) (data + 6))));
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR;
+
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the number of PCRS");
+       if (rc)
                return 0;
-       }
 
        num_pcrs = be32_to_cpu(*((__be32 *) (data + 14)));
-
        for (i = 0; i < num_pcrs; i++) {
                memcpy(data, pcrread, sizeof(pcrread));
                index = cpu_to_be32(i);
                memcpy(data + 10, &index, 4);
-               if ((len = tpm_transmit(chip, data, sizeof(data)))
-                   < READ_PCR_RESULT_SIZE){
-                       dev_dbg(chip->dev, "A TPM error (%d) occurred"
-                               " attempting to read PCR %d of %d\n",
-                               be32_to_cpu(*((__be32 *) (data + 6))),
-                               i, num_pcrs);
+               rc = transmit_cmd(chip, data, sizeof(data),
+                               "attempting to read a PCR");
+               if (rc)
                        goto out;
-               }
                str += sprintf(str, "PCR-%02d: ", i);
                for (j = 0; j < TPM_DIGEST_SIZE; j++)
                        str += sprintf(str, "%02X ", *(data + 10 + j));
@@ -194,7 +725,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
                       char *buf)
 {
        u8 *data;
-       ssize_t len;
+       ssize_t err;
        int i, rc;
        char *str = buf;
 
@@ -208,14 +739,10 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
 
        memcpy(data, readpubek, sizeof(readpubek));
 
-       if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) <
-           READ_PUBEK_RESULT_SIZE) {
-               dev_dbg(chip->dev, "A TPM error (%d) occurred "
-                               "attempting to read the PUBEK\n",
-                           be32_to_cpu(*((__be32 *) (data + 6))));
-               rc = 0;
+       err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE,
+                       "attempting to read the PUBEK");
+       if (err)
                goto out;
-       }
 
        /* 
           ignore header 10 bytes
@@ -245,67 +772,110 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr,
                if ((i + 1) % 16 == 0)
                        str += sprintf(str, "\n");
        }
-       rc = str - buf;
 out:
+       rc = str - buf;
        kfree(data);
        return rc;
 }
 EXPORT_SYMBOL_GPL(tpm_show_pubek);
 
-#define CAP_VER_RESULT_SIZE 18
+#define CAP_VERSION_1_1 6
+#define CAP_VERSION_1_2 0x1A
+#define CAP_VERSION_IDX 13
 static const u8 cap_version[] = {
        0, 193,                 /* TPM_TAG_RQU_COMMAND */
        0, 0, 0, 18,            /* length */
        0, 0, 0, 101,           /* TPM_ORD_GetCapability */
-       0, 0, 0, 6,
+       0, 0, 0, 0,
        0, 0, 0, 0
 };
 
-#define CAP_MANUFACTURER_RESULT_SIZE 18
-static const u8 cap_manufacturer[] = {
-       0, 193,                 /* TPM_TAG_RQU_COMMAND */
-       0, 0, 0, 22,            /* length */
-       0, 0, 0, 101,           /* TPM_ORD_GetCapability */
-       0, 0, 0, 5,
-       0, 0, 0, 4,
-       0, 0, 1, 3
-};
-
 ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr,
                      char *buf)
 {
-       u8 data[sizeof(cap_manufacturer)];
-       ssize_t len;
+       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
+       ssize_t rc;
        char *str = buf;
 
        struct tpm_chip *chip = dev_get_drvdata(dev);
        if (chip == NULL)
                return -ENODEV;
 
-       memcpy(data, cap_manufacturer, sizeof(cap_manufacturer));
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
 
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <
-           CAP_MANUFACTURER_RESULT_SIZE)
-               return len;
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the manufacturer");
+       if (rc)
+               return 0;
 
        str += sprintf(str, "Manufacturer: 0x%x\n",
-                      be32_to_cpu(*((__be32 *) (data + 14))));
+                      be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
 
        memcpy(data, cap_version, sizeof(cap_version));
+       data[CAP_VERSION_IDX] = CAP_VERSION_1_1;
+       rc = transmit_cmd(chip, data, sizeof(data),
+                       "attempting to determine the 1.1 version");
+       if (rc)
+               goto out;
 
-       if ((len = tpm_transmit(chip, data, sizeof(data))) <
-           CAP_VER_RESULT_SIZE)
-               return len;
-
-       str +=
-           sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n",
-                   (int) data[14], (int) data[15], (int) data[16],
-                   (int) data[17]);
+       str += sprintf(str,
+                      "TCG version: %d.%d\nFirmware version: %d.%d\n",
+                      (int) data[14], (int) data[15], (int) data[16],
+                      (int) data[17]);
 
+out:
        return str - buf;
 }
 EXPORT_SYMBOL_GPL(tpm_show_caps);
 
+ssize_t tpm_show_caps_1_2(struct device * dev,
+                         struct device_attribute * attr, char *buf)
+{
+       u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)];
+       ssize_t len;
+       char *str = buf;
+
+       struct tpm_chip *chip = dev_get_drvdata(dev);
+       if (chip == NULL)
+               return -ENODEV;
+
+       memcpy(data, tpm_cap, sizeof(tpm_cap));
+       data[TPM_CAP_IDX] = TPM_CAP_PROP;
+       data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER;
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+           TPM_ERROR_SIZE) {
+               dev_dbg(chip->dev, "A TPM error (%d) occurred "
+                       "attempting to determine the manufacturer\n",
+                       be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+               return 0;
+       }
+
+       str += sprintf(str, "Manufacturer: 0x%x\n",
+                      be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))));
+
+       memcpy(data, cap_version, sizeof(cap_version));
+       data[CAP_VERSION_IDX] = CAP_VERSION_1_2;
+
+       if ((len = tpm_transmit(chip, data, sizeof(data))) <=
+           TPM_ERROR_SIZE) {
+               dev_err(chip->dev, "A TPM error (%d) occurred "
+                       "attempting to determine the 1.2 version\n",
+                       be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))));
+               goto out;
+       }
+       str += sprintf(str,
+                      "TCG version: %d.%d\nFirmware version: %d.%d\n",
+                      (int) data[16], (int) data[17], (int) data[18],
+                      (int) data[19]);
+
+out:
+       return str - buf;
+}
+EXPORT_SYMBOL_GPL(tpm_show_caps_1_2);
+
 ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count)
 {
@@ -313,7 +883,7 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr,
        if (chip == NULL)
                return 0;
 
-       chip->vendor->cancel(chip);
+       chip->vendor.cancel(chip);
        return count;
 }
 EXPORT_SYMBOL_GPL(tpm_store_cancel);
@@ -329,7 +899,7 @@ int tpm_open(struct inode *inode, struct file *file)
        spin_lock(&driver_lock);
 
        list_for_each_entry(pos, &tpm_chip_list, list) {
-               if (pos->vendor->miscdev.minor == minor) {
+               if (pos->vendor.miscdev.minor == minor) {
                        chip = pos;
                        break;
                }
@@ -387,7 +957,7 @@ int tpm_release(struct inode *inode, struct file *file)
 EXPORT_SYMBOL_GPL(tpm_release);
 
 ssize_t tpm_write(struct file *file, const char __user *buf,
-                 size_t size, loff_t * off)
+                 size_t size, loff_t *off)
 {
        struct tpm_chip *chip = file->private_data;
        int in_size = size, out_size;
@@ -419,11 +989,10 @@ ssize_t tpm_write(struct file *file, const char __user *buf,
 
        return in_size;
 }
-
 EXPORT_SYMBOL_GPL(tpm_write);
 
-ssize_t tpm_read(struct file * file, char __user *buf,
-                size_t size, loff_t * off)
+ssize_t tpm_read(struct file *file, char __user *buf,
+                size_t size, loff_t *off)
 {
        struct tpm_chip *chip = file->private_data;
        int ret_size;
@@ -462,14 +1031,13 @@ void tpm_remove_hardware(struct device *dev)
        spin_unlock(&driver_lock);
 
        dev_set_drvdata(dev, NULL);
-       misc_deregister(&chip->vendor->miscdev);
-       kfree(chip->vendor->miscdev.name);
+       misc_deregister(&chip->vendor.miscdev);
+       kfree(chip->vendor.miscdev.name);
 
-       sysfs_remove_group(&dev->kobj, chip->vendor->attr_group);
+       sysfs_remove_group(&dev->kobj, chip->vendor.attr_group);
        tpm_bios_log_teardown(chip->bios_dir);
 
-       dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &=
-               ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES));
+       clear_bit(chip->dev_num, dev_mask);
 
        kfree(chip);
 
@@ -520,18 +1088,18 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume);
  * upon errant exit from this function specific probe function should call
  * pci_disable_device
  */
-int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
+struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific
+                                      *entry)
 {
 #define DEVNAME_SIZE 7
 
        char *devname;
        struct tpm_chip *chip;
-       int i, j;
 
        /* Driver specific per-device data */
        chip = kzalloc(sizeof(*chip), GFP_KERNEL);
        if (chip == NULL)
-               return -ENOMEM;
+               return NULL;
 
        init_MUTEX(&chip->buffer_mutex);
        init_MUTEX(&chip->tpm_mutex);
@@ -543,45 +1111,37 @@ int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry)
        chip->user_read_timer.function = user_reader_timeout;
        chip->user_read_timer.data = (unsigned long) chip;
 
-       chip->vendor = entry;
-
-       chip->dev_num = -1;
+       memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific));
 
-       for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++)
-               for (j = 0; j < 8 * sizeof(int); j++)
-                       if ((dev_mask[i] & (1 << j)) == 0) {
-                               chip->dev_num =
-                                   i * TPM_NUM_MASK_ENTRIES + j;
-                               dev_mask[i] |= 1 << j;
-                               goto dev_num_search_complete;
-                       }
+       chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES);
 
-dev_num_search_complete:
-       if (chip->dev_num < 0) {
+       if (chip->dev_num >= TPM_NUM_DEVICES) {
                dev_err(dev, "No available tpm device numbers\n");
                kfree(chip);
-               return -ENODEV;
+               return NULL;
        } else if (chip->dev_num == 0)
-               chip->vendor->miscdev.minor = TPM_MINOR;
+               chip->vendor.miscdev.minor = TPM_MINOR;
        else
-               chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR;
+               chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR;
+
+       set_bit(chip->dev_num, dev_mask);
 
        devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL);
        scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num);
-       chip->vendor->miscdev.name = devname;
+       chip->vendor.miscdev.name = devname;
 
-       chip->vendor->miscdev.dev = dev;
+       chip->vendor.miscdev.dev = dev;
        chip->dev = get_device(dev);
 
-       if (misc_register(&chip->vendor->miscdev)) {
+       if (misc_register(&chip->vendor.miscdev)) {
                dev_err(chip->dev,
                        "unable to misc_register %s, minor %d\n",
-                       chip->vendor->miscdev.name,
-                       chip->vendor->miscdev.minor);
+                       chip->vendor.miscdev.name,
+                       chip->vendor.miscdev.minor);
                put_device(dev);
+               clear_bit(chip->dev_num, dev_mask);
                kfree(chip);
-               dev_mask[i] &= !(1 << j);
-               return -ENODEV;
+               return NULL;
        }
 
        spin_lock(&driver_lock);
@@ -592,11 +1152,11 @@ dev_num_search_complete:
 
        spin_unlock(&driver_lock);
 
-       sysfs_create_group(&dev->kobj, chip->vendor->attr_group);
+       sysfs_create_group(&dev->kobj, chip->vendor.attr_group);
 
        chip->bios_dir = tpm_bios_log_setup(devname);
 
-       return 0;
+       return chip;
 }
 EXPORT_SYMBOL_GPL(tpm_register_hardware);
 
index dec0224b4478803c566cb932ae81da22d1d00bed..54a4c804e25f30fc38eed78e5a4b32d2e07f1bc9 100644 (file)
@@ -42,18 +42,30 @@ extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr,
                                char *);
 extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr,
                                char *);
+extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr,
+                               char *);
 extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr,
                                const char *, size_t);
+extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr,
+                               char *);
+extern ssize_t tpm_show_temp_deactivated(struct device *,
+                                        struct device_attribute *attr, char *);
 
 struct tpm_chip;
 
 struct tpm_vendor_specific {
-       u8 req_complete_mask;
-       u8 req_complete_val;
-       u8 req_canceled;
+       const u8 req_complete_mask;
+       const u8 req_complete_val;
+       const u8 req_canceled;
        void __iomem *iobase;           /* ioremapped address */
        unsigned long base;             /* TPM base address */
 
+       int irq;
+
        int region_size;
        int have_region;
 
@@ -63,6 +75,13 @@ struct tpm_vendor_specific {
        u8 (*status) (struct tpm_chip *);
        struct miscdevice miscdev;
        struct attribute_group *attr_group;
+       struct list_head list;
+       int locality;
+       unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */
+       unsigned long duration[3]; /* jiffies */
+
+       wait_queue_head_t read_queue;
+       wait_queue_head_t int_queue;
 };
 
 struct tpm_chip {
@@ -81,13 +100,15 @@ struct tpm_chip {
        struct work_struct work;
        struct semaphore tpm_mutex;     /* tpm is processing */
 
-       struct tpm_vendor_specific *vendor;
+       struct tpm_vendor_specific vendor;
 
        struct dentry **bios_dir;
 
        struct list_head list;
 };
 
+#define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor)
+
 static inline int tpm_read_index(int base, int index)
 {
        outb(index, base);
@@ -100,8 +121,12 @@ static inline void tpm_write_index(int base, int index, int value)
        outb(value & 0xFF, base+1);
 }
 
-extern int tpm_register_hardware(struct device *,
-                                struct tpm_vendor_specific *);
+extern void tpm_get_timeouts(struct tpm_chip *);
+extern void tpm_gen_interrupt(struct tpm_chip *);
+extern void tpm_continue_selftest(struct tpm_chip *);
+extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32);
+extern struct tpm_chip* tpm_register_hardware(struct device *,
+                                const struct tpm_vendor_specific *);
 extern int tpm_open(struct inode *, struct file *);
 extern int tpm_release(struct inode *, struct file *);
 extern ssize_t tpm_write(struct file *, const char __user *, size_t,
index ff3654964fe32e24ef45185f0c7e01ea3aa222c4..58a258cec1530594ef3c46e9ecd591d3192213e9 100644 (file)
@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
                return -EIO;
 
        for (i = 0; i < 6; i++) {
-               status = ioread8(chip->vendor->iobase + 1);
+               status = ioread8(chip->vendor.iobase + 1);
                if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
                        dev_err(chip->dev, "error reading header\n");
                        return -EIO;
                }
-               *buf++ = ioread8(chip->vendor->iobase);
+               *buf++ = ioread8(chip->vendor.iobase);
        }
 
        /* size of the data received */
@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
                dev_err(chip->dev,
                        "Recv size(%d) less than available space\n", size);
                for (; i < size; i++) { /* clear the waiting data anyway */
-                       status = ioread8(chip->vendor->iobase + 1);
+                       status = ioread8(chip->vendor.iobase + 1);
                        if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
                                dev_err(chip->dev, "error reading data\n");
                                return -EIO;
@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count)
 
        /* read all the data available */
        for (; i < size; i++) {
-               status = ioread8(chip->vendor->iobase + 1);
+               status = ioread8(chip->vendor.iobase + 1);
                if ((status & ATML_STATUS_DATA_AVAIL) == 0) {
                        dev_err(chip->dev, "error reading data\n");
                        return -EIO;
                }
-               *buf++ = ioread8(chip->vendor->iobase);
+               *buf++ = ioread8(chip->vendor.iobase);
        }
 
        /* make sure data available is gone */
-       status = ioread8(chip->vendor->iobase + 1);
+       status = ioread8(chip->vendor.iobase + 1);
 
        if (status & ATML_STATUS_DATA_AVAIL) {
                dev_err(chip->dev, "data available is stuck\n");
@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
        dev_dbg(chip->dev, "tpm_atml_send:\n");
        for (i = 0; i < count; i++) {
                dev_dbg(chip->dev, "%d 0x%x(%d)\n",  i, buf[i], buf[i]);
-               iowrite8(buf[i], chip->vendor->iobase);
+               iowrite8(buf[i], chip->vendor.iobase);
        }
 
        return count;
@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count)
 
 static void tpm_atml_cancel(struct tpm_chip *chip)
 {
-       iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1);
+       iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1);
 }
 
 static u8 tpm_atml_status(struct tpm_chip *chip)
 {
-       return ioread8(chip->vendor->iobase + 1);
+       return ioread8(chip->vendor.iobase + 1);
 }
 
 static struct file_operations atmel_ops = {
@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] = {
 
 static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
 
-static struct tpm_vendor_specific tpm_atmel = {
+static const struct tpm_vendor_specific tpm_atmel = {
        .recv = tpm_atml_recv,
        .send = tpm_atml_send,
        .cancel = tpm_atml_cancel,
@@ -159,10 +159,10 @@ static void atml_plat_remove(void)
        struct tpm_chip *chip = dev_get_drvdata(&pdev->dev);
 
        if (chip) {
-               if (chip->vendor->have_region)
-                       atmel_release_region(chip->vendor->base,
-                                            chip->vendor->region_size);
-               atmel_put_base_addr(chip->vendor);
+               if (chip->vendor.have_region)
+                       atmel_release_region(chip->vendor.base,
+                                            chip->vendor.region_size);
+               atmel_put_base_addr(chip->vendor.iobase);
                tpm_remove_hardware(chip->dev);
                platform_device_unregister(pdev);
        }
@@ -179,18 +179,22 @@ static struct device_driver atml_drv = {
 static int __init init_atmel(void)
 {
        int rc = 0;
+       void __iomem *iobase = NULL;
+       int have_region, region_size;
+       unsigned long base;
+       struct  tpm_chip *chip;
 
        driver_register(&atml_drv);
 
-       if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) {
+       if ((iobase = atmel_get_base_addr(&base, &region_size)) == NULL) {
                rc = -ENODEV;
                goto err_unreg_drv;
        }
 
-       tpm_atmel.have_region =
+       have_region =
            (atmel_request_region
-            (tpm_atmel.base, tpm_atmel.region_size,
-             "tpm_atmel0") == NULL) ? 0 : 1;
+            (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1;
+
 
        if (IS_ERR
            (pdev =
@@ -199,17 +203,25 @@ static int __init init_atmel(void)
                goto err_rel_reg;
        }
 
-       if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0)
+       if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) {
+               rc = -ENODEV;
                goto err_unreg_dev;
+       }
+
+       chip->vendor.iobase = iobase;
+       chip->vendor.base = base;
+       chip->vendor.have_region = have_region;
+       chip->vendor.region_size = region_size;
+
        return 0;
 
 err_unreg_dev:
        platform_device_unregister(pdev);
 err_rel_reg:
-       atmel_put_base_addr(&tpm_atmel);
-       if (tpm_atmel.have_region)
-               atmel_release_region(tpm_atmel.base,
-                                    tpm_atmel.region_size);
+       atmel_put_base_addr(iobase);
+       if (have_region)
+               atmel_release_region(base,
+                                    region_size);
 err_unreg_drv:
        driver_unregister(&atml_drv);
        return rc;
index d3478aaadd77a20b24db39f668ea1efb1f826f1c..2e68eeb8a2cdfa8397dfacf58f7ac85e37585619 100644 (file)
 #define atmel_request_region request_mem_region
 #define atmel_release_region release_mem_region
 
-static inline void atmel_put_base_addr(struct tpm_vendor_specific
-                                        *vendor)
+static inline void atmel_put_base_addr(void __iomem *iobase)
 {
-       iounmap(vendor->iobase);
+       iounmap(iobase);
 }
 
-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
+static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
 {
        struct device_node *dn;
        unsigned long address, size;
@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor)
        else
                size = reg[naddrc];
 
-       vendor->base = address;
-       vendor->region_size = size;
-       return ioremap(vendor->base, vendor->region_size);
+       *base = address;
+       *region_size = size;
+       return ioremap(*base, *region_size);
 }
 #else
 #define atmel_getb(chip, offset) inb(chip->vendor->base + offset)
@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void)
        return 0;
 }
 
-static inline void atmel_put_base_addr(struct tpm_vendor_specific
-                                        *vendor)
+static inline void atmel_put_base_addr(void __iomem *iobase)
 {
 }
 
 /* Determine where to talk to device */
-static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
-                                        *vendor)
+static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size)
 {
        int lo, hi;
 
@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific
        lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO);
        hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI);
 
-       vendor->base = (hi << 8) | lo;
-       vendor->region_size = 2;
+       *base = (hi << 8) | lo;
+       *region_size = 2;
 
-       return ioport_map(vendor->base, vendor->region_size);
+       return ioport_map(*base, *region_size);
 }
 #endif
index 537aa45d8c67a9cb98ca4fb44c7abdf85d625414..e45f0d3d12de5427cf708585d08e3c615d8e087e 100644 (file)
 #define MAX_TEXT_EVENT         1000    /* Max event string length */
 #define ACPI_TCPA_SIG          "TCPA"  /* 0x41504354 /'TCPA' */
 
+enum bios_platform_class {
+       BIOS_CLIENT = 0x00,
+       BIOS_SERVER = 0x01,
+};
+
 struct tpm_bios_log {
        void *bios_event_log;
        void *bios_event_log_end;
@@ -36,9 +41,18 @@ struct tpm_bios_log {
 
 struct acpi_tcpa {
        struct acpi_table_header hdr;
-       u16 reserved;
-       u32 log_max_len __attribute__ ((packed));
-       u32 log_start_addr __attribute__ ((packed));
+       u16 platform_class;
+       union {
+               struct client_hdr {
+                       u32 log_max_len __attribute__ ((packed));
+                       u64 log_start_addr __attribute__ ((packed));
+               } client;
+               struct server_hdr {
+                       u16 reserved;
+                       u64 log_max_len __attribute__ ((packed));
+                       u64 log_start_addr __attribute__ ((packed));
+               } server;
+       };
 };
 
 struct tcpa_event {
@@ -120,6 +134,7 @@ static const char* tcpa_pc_event_id_strings[] = {
        "S-CRTM Version",
        "S-CRTM Contents",
        "S-CRTM POST Contents",
+       "POST Contents",
 };
 
 /* returns pointer to start of pos. entry of tcg log */
@@ -306,6 +321,7 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v)
        /* 5th: delimiter */
        seq_putc(m, '\0');
 
+       kfree(eventname);
        return 0;
 }
 
@@ -353,6 +369,7 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v)
        /* 4th: eventname <= max + \'0' delimiter */
        seq_printf(m, " %s\n", eventname);
 
+       kfree(eventname);
        return 0;
 }
 
@@ -376,6 +393,7 @@ static int read_log(struct tpm_bios_log *log)
        struct acpi_tcpa *buff;
        acpi_status status;
        struct acpi_table_header *virt;
+       u64 len, start;
 
        if (log->bios_event_log != NULL) {
                printk(KERN_ERR
@@ -396,27 +414,37 @@ static int read_log(struct tpm_bios_log *log)
                return -EIO;
        }
 
-       if (buff->log_max_len == 0) {
+       switch(buff->platform_class) {
+       case BIOS_SERVER:
+               len = buff->server.log_max_len;
+               start = buff->server.log_start_addr;
+               break;
+       case BIOS_CLIENT:
+       default:
+               len = buff->client.log_max_len;
+               start = buff->client.log_start_addr;
+               break;
+       }
+       if (!len) {
                printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__);
                return -EIO;
        }
 
        /* malloc EventLog space */
-       log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL);
+       log->bios_event_log = kmalloc(len, GFP_KERNEL);
        if (!log->bios_event_log) {
-               printk
-                   ("%s: ERROR - Not enough  Memory for BIOS measurements\n",
-                    __func__);
+               printk("%s: ERROR - Not enough  Memory for BIOS measurements\n",
+                       __func__);
                return -ENOMEM;
        }
 
-       log->bios_event_log_end = log->bios_event_log + buff->log_max_len;
+       log->bios_event_log_end = log->bios_event_log + len;
 
-       acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt);
+       acpi_os_map_memory(start, len, (void *) &virt);
 
-       memcpy(log->bios_event_log, virt, buff->log_max_len);
+       memcpy(log->bios_event_log, virt, len);
 
-       acpi_os_unmap_memory(virt, buff->log_max_len);
+       acpi_os_unmap_memory(virt, len);
        return 0;
 }
 
index 24095f6ee6dab4f0a16f3b8d31570b7cfea06cc2..adfff21beb219f9965d50626dfbc582cc016be31 100644 (file)
@@ -15,6 +15,7 @@
  * License.
  */
 
+#include <linux/init.h>
 #include <linux/pnp.h>
 #include "tpm.h"
 
@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
 
        if (clear_wrfifo) {
                for (i = 0; i < 4096; i++) {
-                       status = inb(chip->vendor->base + WRFIFO);
+                       status = inb(chip->vendor.base + WRFIFO);
                        if (status == 0xff) {
                                if (check == 5)
                                        break;
@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo)
         */
        i = 0;
        do {
-               status = inb(chip->vendor->base + RDFIFO);
-               status = inb(chip->vendor->base + STAT);
+               status = inb(chip->vendor.base + RDFIFO);
+               status = inb(chip->vendor.base + STAT);
                i++;
                if (i == TPM_MAX_TRIES)
                        return -EIO;
@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
        int status;
        int i;
        for (i = 0; i < TPM_MAX_TRIES; i++) {
-               status = inb(chip->vendor->base + STAT);
+               status = inb(chip->vendor.base + STAT);
                /* check the status-register if wait_for_bit is set */
                if (status & 1 << wait_for_bit)
                        break;
@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit)
 static void wait_and_send(struct tpm_chip *chip, u8 sendbyte)
 {
        wait(chip, STAT_XFE);
-       outb(sendbyte, chip->vendor->base + WRFIFO);
+       outb(sendbyte, chip->vendor.base + WRFIFO);
 }
 
     /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more
@@ -204,7 +205,7 @@ recv_begin:
                ret = wait(chip, STAT_RDA);
                if (ret)
                        return -EIO;
-               buf[i] = inb(chip->vendor->base + RDFIFO);
+               buf[i] = inb(chip->vendor.base + RDFIFO);
        }
 
        if (buf[0] != TPM_VL_VER) {
@@ -219,7 +220,7 @@ recv_begin:
 
                for (i = 0; i < size; i++) {
                        wait(chip, STAT_RDA);
-                       buf[i] = inb(chip->vendor->base + RDFIFO);
+                       buf[i] = inb(chip->vendor.base + RDFIFO);
                }
 
                if ((size == 0x6D00) && (buf[1] == 0x80)) {
@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count)
        u8 count_high, count_low, count_4, count_3, count_2, count_1;
 
        /* Disabling Reset, LP and IRQC */
-       outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);
+       outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD);
 
        ret = empty_fifo(chip, 1);
        if (ret) {
@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_chip *chip)
 
 static u8 tpm_inf_status(struct tpm_chip *chip)
 {
-       return inb(chip->vendor->base + STAT);
+       return inb(chip->vendor.base + STAT);
 }
 
 static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
@@ -346,7 +347,7 @@ static struct file_operations inf_ops = {
        .release = tpm_release,
 };
 
-static struct tpm_vendor_specific tpm_inf = {
+static const struct tpm_vendor_specific tpm_inf = {
        .recv = tpm_inf_recv,
        .send = tpm_inf_send,
        .cancel = tpm_inf_cancel,
@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
        int version[2];
        int productid[2];
        char chipname[20];
+       struct tpm_chip *chip;
 
        /* read IO-ports through PnP */
        if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&
@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
                        goto err_last;
                }
                /* publish my base address and request region */
-               tpm_inf.base = TPM_INF_BASE;
                if (request_region
-                   (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
+                   (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {
                        rc = -EINVAL;
                        goto err_last;
                }
-               if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,
-                               "tpm_infineon0") == NULL) {
+               if (request_region
+                   (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) {
                        rc = -EINVAL;
                        goto err_last;
                }
@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
 
                /* configure TPM with IO-ports */
                outb(IOLIMH, TPM_INF_ADDR);
-               outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);
+               outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA);
                outb(IOLIML, TPM_INF_ADDR);
-               outb((tpm_inf.base & 0xff), TPM_INF_DATA);
+               outb((TPM_INF_BASE & 0xff), TPM_INF_DATA);
 
                /* control if IO-ports are set correctly */
                outb(IOLIMH, TPM_INF_ADDR);
@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
                outb(IOLIML, TPM_INF_ADDR);
                iol = inb(TPM_INF_DATA);
 
-               if ((ioh << 8 | iol) != tpm_inf.base) {
+               if ((ioh << 8 | iol) != TPM_INF_BASE) {
                        dev_err(&dev->dev,
-                               "Could not set IO-ports to 0x%lx\n",
-                               tpm_inf.base);
+                               "Could not set IO-ports to 0x%x\n",
+                               TPM_INF_BASE);
                        rc = -EIO;
                        goto err_release_region;
                }
@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
                outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);
 
                /* disable RESET, LP and IRQC */
-               outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);
+               outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD);
 
                /* Finally, we're done, print some infos */
                dev_info(&dev->dev, "TPM found: "
                         "config base 0x%x, "
                         "io base 0x%x, "
-                        "chip version %02x%02x, "
-                        "vendor id %x%x (Infineon), "
-                        "product id %02x%02x"
+                        "chip version 0x%02x%02x, "
+                        "vendor id 0x%x%x (Infineon), "
+                        "product id 0x%02x%02x"
                         "%s\n",
                         TPM_INF_ADDR,
                         TPM_INF_BASE,
@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
                         vendorid[0], vendorid[1],
                         productid[0], productid[1], chipname);
 
-               rc = tpm_register_hardware(&dev->dev, &tpm_inf);
-               if (rc < 0) {
-                       rc = -ENODEV;
+               if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) {
                        goto err_release_region;
                }
+               chip->vendor.base = TPM_INF_BASE;
                return 0;
        } else {
                rc = -ENODEV;
@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,
        }
 
 err_release_region:
-       release_region(tpm_inf.base, TPM_INF_PORT_LEN);
+       release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
        release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
 
 err_last:
@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev)
        struct tpm_chip *chip = pnp_get_drvdata(dev);
 
        if (chip) {
-               release_region(chip->vendor->base, TPM_INF_PORT_LEN);
+               release_region(TPM_INF_BASE, TPM_INF_PORT_LEN);
+               release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);
                tpm_remove_hardware(chip->dev);
        }
 }
@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = {
        },
        .id_table = tpm_pnp_tbl,
        .probe = tpm_inf_pnp_probe,
-       .remove = tpm_inf_pnp_remove,
+       .remove = __devexit_p(tpm_inf_pnp_remove),
 };
 
 static int __init init_inf(void)
@@ -538,5 +539,5 @@ module_exit(cleanup_inf);
 
 MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");
 MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");
-MODULE_VERSION("1.7");
+MODULE_VERSION("1.8");
 MODULE_LICENSE("GPL");
index 680a8e3318877b6c6bd7f09ae61d46abd5605871..4c8bc06c7d95af6462d867014c8528a2cc93a12e 100644 (file)
@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
        unsigned long stop;
 
        /* status immediately available check */
-       *data = inb(chip->vendor->base + NSC_STATUS);
+       *data = inb(chip->vendor.base + NSC_STATUS);
        if ((*data & mask) == val)
                return 0;
 
@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data)
        stop = jiffies + 10 * HZ;
        do {
                msleep(TPM_TIMEOUT);
-               *data = inb(chip->vendor->base + 1);
+               *data = inb(chip->vendor.base + 1);
                if ((*data & mask) == val)
                        return 0;
        }
@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
        unsigned long stop;
 
        /* status immediately available check */
-       status = inb(chip->vendor->base + NSC_STATUS);
+       status = inb(chip->vendor.base + NSC_STATUS);
        if (status & NSC_STATUS_OBF)
-               status = inb(chip->vendor->base + NSC_DATA);
+               status = inb(chip->vendor.base + NSC_DATA);
        if (status & NSC_STATUS_RDY)
                return 0;
 
@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm_chip *chip)
        stop = jiffies + 100;
        do {
                msleep(TPM_TIMEOUT);
-               status = inb(chip->vendor->base + NSC_STATUS);
+               status = inb(chip->vendor.base + NSC_STATUS);
                if (status & NSC_STATUS_OBF)
-                       status = inb(chip->vendor->base + NSC_DATA);
+                       status = inb(chip->vendor.base + NSC_DATA);
                if (status & NSC_STATUS_RDY)
                        return 0;
        }
@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
                return -EIO;
        }
        if ((data =
-            inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
+            inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) {
                dev_err(chip->dev, "not in normal mode (0x%x)\n",
                        data);
                return -EIO;
@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
                }
                if (data & NSC_STATUS_F0)
                        break;
-               *p = inb(chip->vendor->base + NSC_DATA);
+               *p = inb(chip->vendor.base + NSC_DATA);
        }
 
        if ((data & NSC_STATUS_F0) == 0 &&
@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count)
                dev_err(chip->dev, "F0 not set\n");
                return -EIO;
        }
-       if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) {
+       if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) {
                dev_err(chip->dev,
                        "expected end of command(0x%x)\n", data);
                return -EIO;
@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
         * fix it. Not sure why this is needed, we followed the flow
         * chart in the manual to the letter.
         */
-       outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
+       outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
 
        if (nsc_wait_for_ready(chip) != 0)
                return -EIO;
@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
                return -EIO;
        }
 
-       outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND);
+       outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND);
        if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) {
                dev_err(chip->dev, "IBR timeout\n");
                return -EIO;
@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count)
                                "IBF timeout (while writing data)\n");
                        return -EIO;
                }
-               outb(buf[i], chip->vendor->base + NSC_DATA);
+               outb(buf[i], chip->vendor.base + NSC_DATA);
        }
 
        if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) {
                dev_err(chip->dev, "IBF timeout\n");
                return -EIO;
        }
-       outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND);
+       outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND);
 
        return count;
 }
 
 static void tpm_nsc_cancel(struct tpm_chip *chip)
 {
-       outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND);
+       outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND);
 }
 
 static u8 tpm_nsc_status(struct tpm_chip *chip)
 {
-       return inb(chip->vendor->base + NSC_STATUS);
+       return inb(chip->vendor.base + NSC_STATUS);
 }
 
 static struct file_operations nsc_ops = {
@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = {
 
 static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
 
-static struct tpm_vendor_specific tpm_nsc = {
+static const struct tpm_vendor_specific tpm_nsc = {
        .recv = tpm_nsc_recv,
        .send = tpm_nsc_send,
        .cancel = tpm_nsc_cancel,
@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(struct device *dev)
 {
        struct tpm_chip *chip = dev_get_drvdata(dev);
        if ( chip ) {
-               release_region(chip->vendor->base, 2);
+               release_region(chip->vendor.base, 2);
                tpm_remove_hardware(chip->dev);
        }
 }
@@ -286,7 +286,8 @@ static int __init init_nsc(void)
        int rc = 0;
        int lo, hi;
        int nscAddrBase = TPM_ADDR;
-
+       struct tpm_chip *chip;
+       unsigned long base;
 
        /* verify that it is a National part (SID) */
        if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) {
@@ -300,7 +301,7 @@ static int __init init_nsc(void)
 
        hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI);
        lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO);
-       tpm_nsc.base = (hi<<8) | lo;
+       base = (hi<<8) | lo;
 
        /* enable the DPM module */
        tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01);
@@ -320,13 +321,15 @@ static int __init init_nsc(void)
        if ((rc = platform_device_register(pdev)) < 0)
                goto err_free_dev;
 
-       if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) {
+       if (request_region(base, 2, "tpm_nsc0") == NULL ) {
                rc = -EBUSY;
                goto err_unreg_dev;
        }
 
-       if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0)
+       if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) {
+               rc = -ENODEV;
                goto err_rel_reg;
+       }
 
        dev_dbg(&pdev->dev, "NSC TPM detected\n");
        dev_dbg(&pdev->dev,
@@ -361,10 +364,12 @@ static int __init init_nsc(void)
                 "NSC TPM revision %d\n",
                 tpm_read_index(nscAddrBase, 0x27) & 0x1F);
 
+       chip->vendor.base = base;
+
        return 0;
 
 err_rel_reg:
-       release_region(tpm_nsc.base, 2);
+       release_region(base, 2);
 err_unreg_dev:
        platform_device_unregister(pdev);
 err_free_dev:
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
new file mode 100644 (file)
index 0000000..b9cae9a
--- /dev/null
@@ -0,0 +1,669 @@
+/*
+ * Copyright (C) 2005, 2006 IBM Corporation
+ *
+ * Authors:
+ * Leendert van Doorn <leendert@watson.ibm.com>
+ * Kylene Hall <kjhall@us.ibm.com>
+ *
+ * Device driver for TCG/TCPA TPM (trusted platform module).
+ * Specifications at www.trustedcomputinggroup.org
+ *
+ * This device driver implements the TPM interface as defined in
+ * the TCG TPM Interface Spec version 1.2, revision 1.0.
+ *
+ * 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, version 2 of the
+ * License.
+ */
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/pnp.h>
+#include <linux/interrupt.h>
+#include <linux/wait.h>
+#include "tpm.h"
+
+#define TPM_HEADER_SIZE 10
+
+enum tis_access {
+       TPM_ACCESS_VALID = 0x80,
+       TPM_ACCESS_ACTIVE_LOCALITY = 0x20,
+       TPM_ACCESS_REQUEST_PENDING = 0x04,
+       TPM_ACCESS_REQUEST_USE = 0x02,
+};
+
+enum tis_status {
+       TPM_STS_VALID = 0x80,
+       TPM_STS_COMMAND_READY = 0x40,
+       TPM_STS_GO = 0x20,
+       TPM_STS_DATA_AVAIL = 0x10,
+       TPM_STS_DATA_EXPECT = 0x08,
+};
+
+enum tis_int_flags {
+       TPM_GLOBAL_INT_ENABLE = 0x80000000,
+       TPM_INTF_BURST_COUNT_STATIC = 0x100,
+       TPM_INTF_CMD_READY_INT = 0x080,
+       TPM_INTF_INT_EDGE_FALLING = 0x040,
+       TPM_INTF_INT_EDGE_RISING = 0x020,
+       TPM_INTF_INT_LEVEL_LOW = 0x010,
+       TPM_INTF_INT_LEVEL_HIGH = 0x008,
+       TPM_INTF_LOCALITY_CHANGE_INT = 0x004,
+       TPM_INTF_STS_VALID_INT = 0x002,
+       TPM_INTF_DATA_AVAIL_INT = 0x001,
+};
+
+enum tis_defaults {
+       TIS_MEM_BASE = 0xFED4000,
+       TIS_MEM_LEN = 0x5000,
+       TIS_SHORT_TIMEOUT = 750,        /* ms */
+       TIS_LONG_TIMEOUT = 2000,        /* 2 sec */
+};
+
+#define        TPM_ACCESS(l)                   (0x0000 | ((l) << 12))
+#define        TPM_INT_ENABLE(l)               (0x0008 | ((l) << 12))
+#define        TPM_INT_VECTOR(l)               (0x000C | ((l) << 12))
+#define        TPM_INT_STATUS(l)               (0x0010 | ((l) << 12))
+#define        TPM_INTF_CAPS(l)                (0x0014 | ((l) << 12))
+#define        TPM_STS(l)                      (0x0018 | ((l) << 12))
+#define        TPM_DATA_FIFO(l)                (0x0024 | ((l) << 12))
+
+#define        TPM_DID_VID(l)                  (0x0F00 | ((l) << 12))
+#define        TPM_RID(l)                      (0x0F04 | ((l) << 12))
+
+static LIST_HEAD(tis_chips);
+static DEFINE_SPINLOCK(tis_lock);
+
+static int check_locality(struct tpm_chip *chip, int l)
+{
+       if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
+            (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) ==
+           (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID))
+               return chip->vendor.locality = l;
+
+       return -1;
+}
+
+static void release_locality(struct tpm_chip *chip, int l, int force)
+{
+       if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) &
+                     (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) ==
+           (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID))
+               iowrite8(TPM_ACCESS_ACTIVE_LOCALITY,
+                        chip->vendor.iobase + TPM_ACCESS(l));
+}
+
+static int request_locality(struct tpm_chip *chip, int l)
+{
+       unsigned long stop;
+       long rc;
+
+       if (check_locality(chip, l) >= 0)
+               return l;
+
+       iowrite8(TPM_ACCESS_REQUEST_USE,
+                chip->vendor.iobase + TPM_ACCESS(l));
+
+       if (chip->vendor.irq) {
+               rc = wait_event_interruptible_timeout(chip->vendor.int_queue,
+                                                     (check_locality
+                                                      (chip, l) >= 0),
+                                                     chip->vendor.timeout_a);
+               if (rc > 0)
+                       return l;
+
+       } else {
+               /* wait for burstcount */
+               stop = jiffies + chip->vendor.timeout_a;
+               do {
+                       if (check_locality(chip, l) >= 0)
+                               return l;
+                       msleep(TPM_TIMEOUT);
+               }
+               while (time_before(jiffies, stop));
+       }
+       return -1;
+}
+
+static u8 tpm_tis_status(struct tpm_chip *chip)
+{
+       return ioread8(chip->vendor.iobase +
+                      TPM_STS(chip->vendor.locality));
+}
+
+static void tpm_tis_ready(struct tpm_chip *chip)
+{
+       /* this causes the current command to be aborted */
+       iowrite8(TPM_STS_COMMAND_READY,
+                chip->vendor.iobase + TPM_STS(chip->vendor.locality));
+}
+
+static int get_burstcount(struct tpm_chip *chip)
+{
+       unsigned long stop;
+       int burstcnt;
+
+       /* wait for burstcount */
+       /* which timeout value, spec has 2 answers (c & d) */
+       stop = jiffies + chip->vendor.timeout_d;
+       do {
+               burstcnt = ioread8(chip->vendor.iobase +
+                                  TPM_STS(chip->vendor.locality) + 1);
+               burstcnt += ioread8(chip->vendor.iobase +
+                                   TPM_STS(chip->vendor.locality) +
+                                   2) << 8;
+               if (burstcnt)
+                       return burstcnt;
+               msleep(TPM_TIMEOUT);
+       } while (time_before(jiffies, stop));
+       return -EBUSY;
+}
+
+static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout,
+                        wait_queue_head_t *queue)
+{
+       unsigned long stop;
+       long rc;
+       u8 status;
+
+       /* check current status */
+       status = tpm_tis_status(chip);
+       if ((status & mask) == mask)
+               return 0;
+
+       if (chip->vendor.irq) {
+               rc = wait_event_interruptible_timeout(*queue,
+                                                     ((tpm_tis_status
+                                                       (chip) & mask) ==
+                                                      mask), timeout);
+               if (rc > 0)
+                       return 0;
+       } else {
+               stop = jiffies + timeout;
+               do {
+                       msleep(TPM_TIMEOUT);
+                       status = tpm_tis_status(chip);
+                       if ((status & mask) == mask)
+                               return 0;
+               } while (time_before(jiffies, stop));
+       }
+       return -ETIME;
+}
+
+static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+       int size = 0, burstcnt;
+       while (size < count &&
+              wait_for_stat(chip,
+                            TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+                            chip->vendor.timeout_c,
+                            &chip->vendor.read_queue)
+              == 0) {
+               burstcnt = get_burstcount(chip);
+               for (; burstcnt > 0 && size < count; burstcnt--)
+                       buf[size++] = ioread8(chip->vendor.iobase +
+                                             TPM_DATA_FIFO(chip->vendor.
+                                                           locality));
+       }
+       return size;
+}
+
+static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count)
+{
+       int size = 0;
+       int expected, status;
+
+       if (count < TPM_HEADER_SIZE) {
+               size = -EIO;
+               goto out;
+       }
+
+       /* read first 10 bytes, including tag, paramsize, and result */
+       if ((size =
+            recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) {
+               dev_err(chip->dev, "Unable to read header\n");
+               goto out;
+       }
+
+       expected = be32_to_cpu(*(__be32 *) (buf + 2));
+       if (expected > count) {
+               size = -EIO;
+               goto out;
+       }
+
+       if ((size +=
+            recv_data(chip, &buf[TPM_HEADER_SIZE],
+                      expected - TPM_HEADER_SIZE)) < expected) {
+               dev_err(chip->dev, "Unable to read remainder of result\n");
+               size = -ETIME;
+               goto out;
+       }
+
+       wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
+                     &chip->vendor.int_queue);
+       status = tpm_tis_status(chip);
+       if (status & TPM_STS_DATA_AVAIL) {      /* retry? */
+               dev_err(chip->dev, "Error left over data\n");
+               size = -EIO;
+               goto out;
+       }
+
+out:
+       tpm_tis_ready(chip);
+       release_locality(chip, chip->vendor.locality, 0);
+       return size;
+}
+
+/*
+ * If interrupts are used (signaled by an irq set in the vendor structure)
+ * tpm.c can skip polling for the data to be available as the interrupt is
+ * waited for here
+ */
+static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len)
+{
+       int rc, status, burstcnt;
+       size_t count = 0;
+       u32 ordinal;
+
+       if (request_locality(chip, 0) < 0)
+               return -EBUSY;
+
+       status = tpm_tis_status(chip);
+       if ((status & TPM_STS_COMMAND_READY) == 0) {
+               tpm_tis_ready(chip);
+               if (wait_for_stat
+                   (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b,
+                    &chip->vendor.int_queue) < 0) {
+                       rc = -ETIME;
+                       goto out_err;
+               }
+       }
+
+       while (count < len - 1) {
+               burstcnt = get_burstcount(chip);
+               for (; burstcnt > 0 && count < len - 1; burstcnt--) {
+                       iowrite8(buf[count], chip->vendor.iobase +
+                                TPM_DATA_FIFO(chip->vendor.locality));
+                       count++;
+               }
+
+               wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
+                             &chip->vendor.int_queue);
+               status = tpm_tis_status(chip);
+               if ((status & TPM_STS_DATA_EXPECT) == 0) {
+                       rc = -EIO;
+                       goto out_err;
+               }
+       }
+
+       /* write last byte */
+       iowrite8(buf[count],
+                chip->vendor.iobase +
+                TPM_DATA_FIFO(chip->vendor.locality));
+       wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c,
+                     &chip->vendor.int_queue);
+       status = tpm_tis_status(chip);
+       if ((status & TPM_STS_DATA_EXPECT) != 0) {
+               rc = -EIO;
+               goto out_err;
+       }
+
+       /* go and do it */
+       iowrite8(TPM_STS_GO,
+                chip->vendor.iobase + TPM_STS(chip->vendor.locality));
+
+       if (chip->vendor.irq) {
+               ordinal = be32_to_cpu(*((__be32 *) (buf + 6)));
+               if (wait_for_stat
+                   (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+                    tpm_calc_ordinal_duration(chip, ordinal),
+                    &chip->vendor.read_queue) < 0) {
+                       rc = -ETIME;
+                       goto out_err;
+               }
+       }
+       return len;
+out_err:
+       tpm_tis_ready(chip);
+       release_locality(chip, chip->vendor.locality, 0);
+       return rc;
+}
+
+static struct file_operations tis_ops = {
+       .owner = THIS_MODULE,
+       .llseek = no_llseek,
+       .open = tpm_open,
+       .read = tpm_read,
+       .write = tpm_write,
+       .release = tpm_release,
+};
+
+static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);
+static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);
+static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL);
+static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL);
+static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL);
+static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated,
+                  NULL);
+static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL);
+static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);
+
+static struct attribute *tis_attrs[] = {
+       &dev_attr_pubek.attr,
+       &dev_attr_pcrs.attr,
+       &dev_attr_enabled.attr,
+       &dev_attr_active.attr,
+       &dev_attr_owned.attr,
+       &dev_attr_temp_deactivated.attr,
+       &dev_attr_caps.attr,
+       &dev_attr_cancel.attr, NULL,
+};
+
+static struct attribute_group tis_attr_grp = {
+       .attrs = tis_attrs
+};
+
+static struct tpm_vendor_specific tpm_tis = {
+       .status = tpm_tis_status,
+       .recv = tpm_tis_recv,
+       .send = tpm_tis_send,
+       .cancel = tpm_tis_ready,
+       .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+       .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID,
+       .req_canceled = TPM_STS_COMMAND_READY,
+       .attr_group = &tis_attr_grp,
+       .miscdev = {
+                   .fops = &tis_ops,},
+};
+
+static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct tpm_chip *chip = (struct tpm_chip *) dev_id;
+       u32 interrupt;
+
+       interrupt = ioread32(chip->vendor.iobase +
+                            TPM_INT_STATUS(chip->vendor.locality));
+
+       if (interrupt == 0)
+               return IRQ_NONE;
+
+       chip->vendor.irq = irq;
+
+       /* Clear interrupts handled with TPM_EOI */
+       iowrite32(interrupt,
+                 chip->vendor.iobase +
+                 TPM_INT_STATUS(chip->vendor.locality));
+       return IRQ_HANDLED;
+}
+
+static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+       struct tpm_chip *chip = (struct tpm_chip *) dev_id;
+       u32 interrupt;
+       int i;
+
+       interrupt = ioread32(chip->vendor.iobase +
+                            TPM_INT_STATUS(chip->vendor.locality));
+
+       if (interrupt == 0)
+               return IRQ_NONE;
+
+       if (interrupt & TPM_INTF_DATA_AVAIL_INT)
+               wake_up_interruptible(&chip->vendor.read_queue);
+       if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT)
+               for (i = 0; i < 5; i++)
+                       if (check_locality(chip, i) >= 0)
+                               break;
+       if (interrupt &
+           (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT |
+            TPM_INTF_CMD_READY_INT))
+               wake_up_interruptible(&chip->vendor.int_queue);
+
+       /* Clear interrupts handled with TPM_EOI */
+       iowrite32(interrupt,
+                 chip->vendor.iobase +
+                 TPM_INT_STATUS(chip->vendor.locality));
+       return IRQ_HANDLED;
+}
+
+static int interrupts = 1;
+module_param(interrupts, bool, 0444);
+MODULE_PARM_DESC(interrupts, "Enable interrupts");
+
+static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev,
+                                     const struct pnp_device_id *pnp_id)
+{
+       u32 vendor, intfcaps, intmask;
+       int rc, i;
+       unsigned long start, len;
+       struct tpm_chip *chip;
+
+       start = pnp_mem_start(pnp_dev, 0);
+       len = pnp_mem_len(pnp_dev, 0);
+
+       if (!start)
+               start = TIS_MEM_BASE;
+       if (!len)
+               len = TIS_MEM_LEN;
+
+       if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis)))
+               return -ENODEV;
+
+       chip->vendor.iobase = ioremap(start, len);
+       if (!chip->vendor.iobase) {
+               rc = -EIO;
+               goto out_err;
+       }
+
+       vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0));
+       if ((vendor & 0xFFFF) == 0xFFFF) {
+               rc = -ENODEV;
+               goto out_err;
+       }
+
+       /* Default timeouts */
+       chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
+       chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT);
+       chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
+       chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT);
+
+       dev_info(&pnp_dev->dev,
+                "1.2 TPM (device-id 0x%X, rev-id %d)\n",
+                vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0)));
+
+       /* Figure out the capabilities */
+       intfcaps =
+           ioread32(chip->vendor.iobase +
+                    TPM_INTF_CAPS(chip->vendor.locality));
+       dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n",
+               intfcaps);
+       if (intfcaps & TPM_INTF_BURST_COUNT_STATIC)
+               dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n");
+       if (intfcaps & TPM_INTF_CMD_READY_INT)
+               dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n");
+       if (intfcaps & TPM_INTF_INT_EDGE_FALLING)
+               dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n");
+       if (intfcaps & TPM_INTF_INT_EDGE_RISING)
+               dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n");
+       if (intfcaps & TPM_INTF_INT_LEVEL_LOW)
+               dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n");
+       if (intfcaps & TPM_INTF_INT_LEVEL_HIGH)
+               dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n");
+       if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT)
+               dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n");
+       if (intfcaps & TPM_INTF_STS_VALID_INT)
+               dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n");
+       if (intfcaps & TPM_INTF_DATA_AVAIL_INT)
+               dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n");
+
+       if (request_locality(chip, 0) != 0) {
+               rc = -ENODEV;
+               goto out_err;
+       }
+
+       /* INTERRUPT Setup */
+       init_waitqueue_head(&chip->vendor.read_queue);
+       init_waitqueue_head(&chip->vendor.int_queue);
+
+       intmask =
+           ioread32(chip->vendor.iobase +
+                    TPM_INT_ENABLE(chip->vendor.locality));
+
+       intmask |= TPM_INTF_CMD_READY_INT
+           | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT
+           | TPM_INTF_STS_VALID_INT;
+
+       iowrite32(intmask,
+                 chip->vendor.iobase +
+                 TPM_INT_ENABLE(chip->vendor.locality));
+       if (interrupts) {
+               chip->vendor.irq =
+                   ioread8(chip->vendor.iobase +
+                           TPM_INT_VECTOR(chip->vendor.locality));
+
+               for (i = 3; i < 16 && chip->vendor.irq == 0; i++) {
+                       iowrite8(i, chip->vendor.iobase +
+                                   TPM_INT_VECTOR(chip->vendor.locality));
+                       if (request_irq
+                           (i, tis_int_probe, SA_SHIRQ,
+                            chip->vendor.miscdev.name, chip) != 0) {
+                               dev_info(chip->dev,
+                                        "Unable to request irq: %d for probe\n",
+                                        i);
+                               continue;
+                       }
+
+                       /* Clear all existing */
+                       iowrite32(ioread32
+                                 (chip->vendor.iobase +
+                                  TPM_INT_STATUS(chip->vendor.locality)),
+                                 chip->vendor.iobase +
+                                 TPM_INT_STATUS(chip->vendor.locality));
+
+                       /* Turn on */
+                       iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
+                                 chip->vendor.iobase +
+                                 TPM_INT_ENABLE(chip->vendor.locality));
+
+                       /* Generate Interrupts */
+                       tpm_gen_interrupt(chip);
+
+                       /* Turn off */
+                       iowrite32(intmask,
+                                 chip->vendor.iobase +
+                                 TPM_INT_ENABLE(chip->vendor.locality));
+                       free_irq(i, chip);
+               }
+       }
+       if (chip->vendor.irq) {
+               iowrite8(chip->vendor.irq,
+                        chip->vendor.iobase +
+                        TPM_INT_VECTOR(chip->vendor.locality));
+               if (request_irq
+                   (chip->vendor.irq, tis_int_handler, SA_SHIRQ,
+                    chip->vendor.miscdev.name, chip) != 0) {
+                       dev_info(chip->dev,
+                                "Unable to request irq: %d for use\n",
+                                chip->vendor.irq);
+                       chip->vendor.irq = 0;
+               } else {
+                       /* Clear all existing */
+                       iowrite32(ioread32
+                                 (chip->vendor.iobase +
+                                  TPM_INT_STATUS(chip->vendor.locality)),
+                                 chip->vendor.iobase +
+                                 TPM_INT_STATUS(chip->vendor.locality));
+
+                       /* Turn on */
+                       iowrite32(intmask | TPM_GLOBAL_INT_ENABLE,
+                                 chip->vendor.iobase +
+                                 TPM_INT_ENABLE(chip->vendor.locality));
+               }
+       }
+
+       INIT_LIST_HEAD(&chip->vendor.list);
+       spin_lock(&tis_lock);
+       list_add(&chip->vendor.list, &tis_chips);
+       spin_unlock(&tis_lock);
+
+       tpm_get_timeouts(chip);
+       tpm_continue_selftest(chip);
+
+       return 0;
+out_err:
+       if (chip->vendor.iobase)
+               iounmap(chip->vendor.iobase);
+       tpm_remove_hardware(chip->dev);
+       return rc;
+}
+
+static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg)
+{
+       return tpm_pm_suspend(&dev->dev, msg);
+}
+
+static int tpm_tis_pnp_resume(struct pnp_dev *dev)
+{
+       return tpm_pm_resume(&dev->dev);
+}
+
+static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
+       {"PNP0C31", 0},         /* TPM */
+       {"ATM1200", 0},         /* Atmel */
+       {"IFX0102", 0},         /* Infineon */
+       {"BCM0101", 0},         /* Broadcom */
+       {"NSC1200", 0},         /* National */
+       /* Add new here */
+       {"", 0},                /* User Specified */
+       {"", 0}                 /* Terminator */
+};
+
+static struct pnp_driver tis_pnp_driver = {
+       .name = "tpm_tis",
+       .id_table = tpm_pnp_tbl,
+       .probe = tpm_tis_pnp_init,
+       .suspend = tpm_tis_pnp_suspend,
+       .resume = tpm_tis_pnp_resume,
+};
+
+#define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2
+module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id,
+                   sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444);
+MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe");
+
+static int __init init_tis(void)
+{
+       return pnp_register_driver(&tis_pnp_driver);
+}
+
+static void __exit cleanup_tis(void)
+{
+       struct tpm_vendor_specific *i, *j;
+       struct tpm_chip *chip;
+       spin_lock(&tis_lock);
+       list_for_each_entry_safe(i, j, &tis_chips, list) {
+               chip = to_tpm_chip(i);
+               iowrite32(~TPM_GLOBAL_INT_ENABLE &
+                         ioread32(chip->vendor.iobase +
+                                  TPM_INT_ENABLE(chip->vendor.
+                                                 locality)),
+                         chip->vendor.iobase +
+                         TPM_INT_ENABLE(chip->vendor.locality));
+               release_locality(chip, chip->vendor.locality, 1);
+               if (chip->vendor.irq)
+                       free_irq(chip->vendor.irq, chip);
+               iounmap(i->iobase);
+               list_del(&i->list);
+               tpm_remove_hardware(chip->dev);
+       }
+       spin_unlock(&tis_lock);
+       pnp_unregister_driver(&tis_pnp_driver);
+}
+
+module_init(init_tis);
+module_exit(cleanup_tis);
+MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)");
+MODULE_DESCRIPTION("TPM Driver");
+MODULE_VERSION("2.0");
+MODULE_LICENSE("GPL");
index 841f0bd3eaaf8426194c8cd838c1a0dfb67f37cc..f07637a8f88fd038bac53f44c7181ea901c2ec51 100644 (file)
@@ -2723,7 +2723,11 @@ static void __do_SAK(void *arg)
                }
                task_lock(p);
                if (p->files) {
-                       rcu_read_lock();
+                       /*
+                        * We don't take a ref to the file, so we must
+                        * hold ->file_lock instead.
+                        */
+                       spin_lock(&p->files->file_lock);
                        fdt = files_fdtable(p->files);
                        for (i=0; i < fdt->max_fds; i++) {
                                filp = fcheck_files(p->files, i);
@@ -2738,7 +2742,7 @@ static void __do_SAK(void *arg)
                                        break;
                                }
                        }
-                       rcu_read_unlock();
+                       spin_unlock(&p->files->file_lock);
                }
                task_unlock(p);
        } while_each_thread(g, p);
index 8e0f3158215f6bc191864ef5f0a87f49ecc67bbd..dfca74933625e0c1c629778f0af1f9f8f00351b3 100644 (file)
@@ -478,6 +478,11 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr,
                ret = i801_transaction();
        }
 
+       /* Some BIOSes don't like it when PEC is enabled at reboot or resume
+          time, so we forcibly disable it after every transaction. */
+       if (hwpec)
+               outb_p(0, SMBAUXCTL);
+
        if(block)
                return ret;
        if(ret)
index 27fc9ff2961a6dd9abff1f1ed9db358f4adb29ac..99ab4ec343902e8d5f3054fba8ffd301cfa2f168 100644 (file)
@@ -131,13 +131,13 @@ m41t00_set(void *arg)
        if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0)
                || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f)
                        < 0)
-               || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x7f)
+               || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f)
                        < 0)
-               || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x7f)
+               || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f)
                        < 0)
-               || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x7f)
+               || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f)
                        < 0)
-               || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0x7f)
+               || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff)
                        < 0))
 
                dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n");
index cf84350efc550b3dc804dd9a5cb03d8978dc9002..8b24b4f2a839a0abe424cf5e75eebd2bf5a9434b 100644 (file)
@@ -731,6 +731,8 @@ static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif)
        
        if(m5229_revision <= 0x20)
                tmpbyte = (tmpbyte & (~0x02)) | 0x01;
+       else if (m5229_revision == 0xc7)
+               tmpbyte |= 0x03;
        else
                tmpbyte |= 0x01;
 
index df9ee9a784350c2d63ab3ba345d90bd2da25c9cb..900efd1da587d782a0afd369579c62713935280b 100644 (file)
@@ -348,6 +348,7 @@ static struct pci_device_id atiixp_pci_tbl[] = {
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
+       { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
        { 0, },
 };
 MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
index 6f8f8645b02c5666ad4cc336b0a93d8ba6aa7447..7ce5bf7836882b32ed8da8587706eee826a543b9 100644 (file)
@@ -798,7 +798,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
                .autodma        = AUTODMA,
                .bootable       = OFF_BOARD,
                .extra          = 48,
-               .flags          = IDEPCI_FLAG_FORCE_PDC,
        },{     /* 2 */
                .name           = "PDC20263",
                .init_setup     = init_setup_pdc202ata4,
@@ -819,7 +818,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = {
                .autodma        = AUTODMA,
                .bootable       = OFF_BOARD,
                .extra          = 48,
-               .flags          = IDEPCI_FLAG_FORCE_PDC,
        },{     /* 4 */
                .name           = "PDC20267",
                .init_setup     = init_setup_pdc202xx,
index 7ebf992e8c2f40f2050060ea2e3f8cd53d188436..462ed3006c3082124a0a9622dfa9e7448116cc09 100644 (file)
@@ -580,7 +580,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a
        int port;
        int at_least_one_hwif_enabled = 0;
        ide_hwif_t *hwif, *mate = NULL;
-       static int secondpdc = 0;
        u8 tmp;
 
        index->all = 0xf0f0;
@@ -592,21 +591,9 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a
        for (port = 0; port <= 1; ++port) {
                ide_pci_enablebit_t *e = &(d->enablebits[port]);
        
-               /* 
-                * If this is a Promise FakeRaid controller,
-                * the 2nd controller will be marked as 
-                * disabled while it is actually there and enabled
-                * by the bios for raid purposes. 
-                * Skip the normal "is it enabled" test for those.
-                */
-               if ((d->flags & IDEPCI_FLAG_FORCE_PDC) &&
-                   (secondpdc++==1) && (port==1))
-                       goto controller_ok;
-                       
                if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) ||
                    (tmp & e->mask) != e->val))
                        continue;       /* port not enabled */
-controller_ok:
 
                if (d->channels <= port)
                        break;
index 3a702da83e41bc595263aa29438fadc0ed3df3d3..469b6923a2e2e0a2c59b388d8f93fedc2e961fac 100644 (file)
@@ -228,10 +228,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device,
                                goto error1;
                }
                /* Make sure class supplied is consistent with RMPP */
-               if (ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) {
-                       if (!rmpp_version)
-                               goto error1;
-               } else {
+               if (!ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) {
                        if (rmpp_version)
                                goto error1;
                }
index cd533cf951c26b5a7cc25b3dcad22386065ca092..7d3fb6996b41d6fb6aecf589b2ef2bcddbe5588e 100644 (file)
@@ -365,15 +365,3 @@ static ssize_t ipath_diag_write(struct file *fp, const char __user *data,
 bail:
        return ret;
 }
-
-void ipath_diag_bringup_link(struct ipath_devdata *dd)
-{
-       if (diag_set_link || (dd->ipath_flags & IPATH_LINKACTIVE))
-               return;
-
-       diag_set_link = 1;
-       ipath_cdbg(VERBOSE, "Trying to set to set link active for "
-                  "diag pkt\n");
-       ipath_layer_set_linkstate(dd, IPATH_IB_LINKARM);
-       ipath_layer_set_linkstate(dd, IPATH_IB_LINKACTIVE);
-}
index 58a94efb0070bb14d658ae1e32f90b2e17b9f3c0..e7617c3982ea6c18641d9a6be9aee2120e566d6b 100644 (file)
@@ -1729,7 +1729,7 @@ void ipath_free_pddata(struct ipath_devdata *dd, u32 port, int freehdrq)
        }
 }
 
-int __init infinipath_init(void)
+static int __init infinipath_init(void)
 {
        int ret;
 
index 60f5f4108069253e20c84d2c06eded189b2e0865..0bcb428041f32eb7fb2990ee9ae0610390fe201e 100644 (file)
@@ -172,8 +172,8 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd,
                                   "was %s\n", dd->ipath_unit,
                                   ib_linkstate(lstate),
                                   ib_linkstate((unsigned)
-                                               dd->ipath_lastibcstat
-                                               & IPATH_IBSTATE_MASK));
+                                               dd->ipath_lastibcstat
+                                               & IPATH_IBSTATE_MASK));
        }
        else {
                lstate = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK;
index 159d0aed31a5b0b792e69b28f1b6ef32dd2596b1..0ce5f19c9d62ac5f2bd07356f1bcc8ce9f31fee1 100644 (file)
@@ -528,7 +528,6 @@ extern spinlock_t ipath_devs_lock;
 extern struct ipath_devdata *ipath_lookup(int unit);
 
 extern u16 ipath_layer_rcv_opcode;
-extern int ipath_verbs_registered;
 extern int __ipath_layer_intr(struct ipath_devdata *, u32);
 extern int ipath_layer_intr(struct ipath_devdata *, u32);
 extern int __ipath_layer_rcv(struct ipath_devdata *, void *,
index 2cabf634057212f3ca8f2b8410b07b61ab6cecdc..69ed1100701af5db8ff1cbc226b8076b03979f15 100644 (file)
@@ -52,7 +52,7 @@ static int (*layer_rcv)(void *, void *, struct sk_buff *);
 static int (*layer_rcv_lid)(void *, void *);
 static int (*verbs_piobufavail)(void *);
 static void (*verbs_rcv)(void *, void *, void *, u32);
-int ipath_verbs_registered;
+static int ipath_verbs_registered;
 
 static void *(*layer_add_one)(int, struct ipath_devdata *);
 static void (*layer_remove_one)(void *);
index e693a7a8266703996f99e5fe58f5e30fe1a244b3..e1dc4f757062a5ac8f9595fc197de26c20e7dda7 100644 (file)
@@ -305,8 +305,8 @@ static const struct ipath_cregs ipath_pe_cregs = {
  * we'll print them and continue.  We reuse the same message buffer as
  * ipath_handle_errors() to avoid excessive stack usage.
  */
-void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
-       size_t msgl)
+static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg,
+                                    size_t msgl)
 {
        ipath_err_t hwerrs;
        u32 bits, ctrl;
@@ -552,7 +552,7 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name,
  * freeze mode), and enable hardware errors as errors (along with
  * everything else) in errormask
  */
-void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
+static void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
 {
        ipath_err_t val;
        u64 extsval;
@@ -577,7 +577,7 @@ void ipath_pe_init_hwerrors(struct ipath_devdata *dd)
  * ipath_pe_bringup_serdes - bring up the serdes
  * @dd: the infinipath device
  */
-int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
+static int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
 {
        u64 val, tmp, config1;
        int ret = 0, change = 0;
@@ -694,7 +694,7 @@ int ipath_pe_bringup_serdes(struct ipath_devdata *dd)
  * @dd: the infinipath device
  * Called when driver is being unloaded
  */
-void ipath_pe_quiet_serdes(struct ipath_devdata *dd)
+static void ipath_pe_quiet_serdes(struct ipath_devdata *dd)
 {
        u64 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0);
 
index 6058d70d7577bb349ab7e5db759e1e3d37db4fc3..18890716db1ed3bf5812968d8945f71905cdfd3a 100644 (file)
@@ -188,8 +188,8 @@ static void free_qpn(struct ipath_qp_table *qpt, u32 qpn)
  * Allocate the next available QPN and put the QP into the hash table.
  * The hash table holds a reference to the QP.
  */
-int ipath_alloc_qpn(struct ipath_qp_table *qpt, struct ipath_qp *qp,
-                   enum ib_qp_type type)
+static int ipath_alloc_qpn(struct ipath_qp_table *qpt, struct ipath_qp *qp,
+                          enum ib_qp_type type)
 {
        unsigned long flags;
        u32 qpn;
@@ -232,7 +232,7 @@ bail:
  * Remove the QP from the table so it can't be found asynchronously by
  * the receive interrupt routine.
  */
-void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp)
+static void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp)
 {
        struct ipath_qp *q, **qpp;
        unsigned long flags;
@@ -357,6 +357,65 @@ static void ipath_reset_qp(struct ipath_qp *qp)
        qp->r_reuse_sge = 0;
 }
 
+/**
+ * ipath_error_qp - put a QP into an error state
+ * @qp: the QP to put into an error state
+ *
+ * Flushes both send and receive work queues.
+ * QP r_rq.lock and s_lock should be held.
+ */
+
+static void ipath_error_qp(struct ipath_qp *qp)
+{
+       struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
+       struct ib_wc wc;
+
+       _VERBS_INFO("QP%d/%d in error state\n",
+                   qp->ibqp.qp_num, qp->remote_qpn);
+
+       spin_lock(&dev->pending_lock);
+       /* XXX What if its already removed by the timeout code? */
+       if (qp->timerwait.next != LIST_POISON1)
+               list_del(&qp->timerwait);
+       if (qp->piowait.next != LIST_POISON1)
+               list_del(&qp->piowait);
+       spin_unlock(&dev->pending_lock);
+
+       wc.status = IB_WC_WR_FLUSH_ERR;
+       wc.vendor_err = 0;
+       wc.byte_len = 0;
+       wc.imm_data = 0;
+       wc.qp_num = qp->ibqp.qp_num;
+       wc.src_qp = 0;
+       wc.wc_flags = 0;
+       wc.pkey_index = 0;
+       wc.slid = 0;
+       wc.sl = 0;
+       wc.dlid_path_bits = 0;
+       wc.port_num = 0;
+
+       while (qp->s_last != qp->s_head) {
+               struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
+
+               wc.wr_id = wqe->wr.wr_id;
+               wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
+               if (++qp->s_last >= qp->s_size)
+                       qp->s_last = 0;
+               ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1);
+       }
+       qp->s_cur = qp->s_tail = qp->s_head;
+       qp->s_hdrwords = 0;
+       qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
+
+       wc.opcode = IB_WC_RECV;
+       while (qp->r_rq.tail != qp->r_rq.head) {
+               wc.wr_id = get_rwqe_ptr(&qp->r_rq, qp->r_rq.tail)->wr_id;
+               if (++qp->r_rq.tail >= qp->r_rq.size)
+                       qp->r_rq.tail = 0;
+               ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
+       }
+}
+
 /**
  * ipath_modify_qp - modify the attributes of a queue pair
  * @ibqp: the queue pair who's attributes we're modifying
@@ -820,65 +879,6 @@ void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc)
        qp->state = IB_QPS_SQE;
 }
 
-/**
- * ipath_error_qp - put a QP into an error state
- * @qp: the QP to put into an error state
- *
- * Flushes both send and receive work queues.
- * QP r_rq.lock and s_lock should be held.
- */
-
-void ipath_error_qp(struct ipath_qp *qp)
-{
-       struct ipath_ibdev *dev = to_idev(qp->ibqp.device);
-       struct ib_wc wc;
-
-       _VERBS_INFO("QP%d/%d in error state\n",
-                   qp->ibqp.qp_num, qp->remote_qpn);
-
-       spin_lock(&dev->pending_lock);
-       /* XXX What if its already removed by the timeout code? */
-       if (qp->timerwait.next != LIST_POISON1)
-               list_del(&qp->timerwait);
-       if (qp->piowait.next != LIST_POISON1)
-               list_del(&qp->piowait);
-       spin_unlock(&dev->pending_lock);
-
-       wc.status = IB_WC_WR_FLUSH_ERR;
-       wc.vendor_err = 0;
-       wc.byte_len = 0;
-       wc.imm_data = 0;
-       wc.qp_num = qp->ibqp.qp_num;
-       wc.src_qp = 0;
-       wc.wc_flags = 0;
-       wc.pkey_index = 0;
-       wc.slid = 0;
-       wc.sl = 0;
-       wc.dlid_path_bits = 0;
-       wc.port_num = 0;
-
-       while (qp->s_last != qp->s_head) {
-               struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
-
-               wc.wr_id = wqe->wr.wr_id;
-               wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode];
-               if (++qp->s_last >= qp->s_size)
-                       qp->s_last = 0;
-               ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1);
-       }
-       qp->s_cur = qp->s_tail = qp->s_head;
-       qp->s_hdrwords = 0;
-       qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE;
-
-       wc.opcode = IB_WC_RECV;
-       while (qp->r_rq.tail != qp->r_rq.head) {
-               wc.wr_id = get_rwqe_ptr(&qp->r_rq, qp->r_rq.tail)->wr_id;
-               if (++qp->r_rq.tail >= qp->r_rq.size)
-                       qp->r_rq.tail = 0;
-               ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1);
-       }
-}
-
 /**
  * ipath_get_credit - flush the send work queue of a QP
  * @qp: the qp who's send work queue to flush
index 5ff3de6128b2fd21b9f79f8dfb64704f65aa643e..01cfb30ee16040f31ee06a01527227ece95176ba 100644 (file)
@@ -46,8 +46,8 @@
  * This is called from ipath_post_ud_send() to forward a WQE addressed
  * to the same HCA.
  */
-void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss,
-                      u32 length, struct ib_send_wr *wr, struct ib_wc *wc)
+static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss,
+                             u32 length, struct ib_send_wr *wr, struct ib_wc *wc)
 {
        struct ipath_ibdev *dev = to_idev(sqp->ibqp.device);
        struct ipath_qp *qp;
index 9f27fd35cdbb7e5500c4f5b7e17e8b5418b78221..8d2558a01f35e5a599d1fb0a0827987934fbdc75 100644 (file)
@@ -41,7 +41,7 @@
 /* Not static, because we don't want the compiler removing it */
 const char ipath_verbs_version[] = "ipath_verbs " IPATH_IDSTR;
 
-unsigned int ib_ipath_qp_table_size = 251;
+static unsigned int ib_ipath_qp_table_size = 251;
 module_param_named(qp_table_size, ib_ipath_qp_table_size, uint, S_IRUGO);
 MODULE_PARM_DESC(qp_table_size, "QP table size");
 
@@ -87,7 +87,7 @@ const enum ib_wc_opcode ib_ipath_wc_opcode[] = {
 /*
  * System image GUID.
  */
-__be64 sys_image_guid;
+static __be64 sys_image_guid;
 
 /**
  * ipath_copy_sge - copy data to SGE memory
@@ -1110,7 +1110,7 @@ static void ipath_unregister_ib_device(void *arg)
        ib_dealloc_device(ibdev);
 }
 
-int __init ipath_verbs_init(void)
+static int __init ipath_verbs_init(void)
 {
        return ipath_verbs_register(ipath_register_ib_device,
                                    ipath_unregister_ib_device,
@@ -1118,33 +1118,33 @@ int __init ipath_verbs_init(void)
                                    ipath_ib_timer);
 }
 
-void __exit ipath_verbs_cleanup(void)
+static void __exit ipath_verbs_cleanup(void)
 {
        ipath_verbs_unregister();
 }
 
 static ssize_t show_rev(struct class_device *cdev, char *buf)
 {
-        struct ipath_ibdev *dev =
-                container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
-        int vendor, boardrev, majrev, minrev;
+       struct ipath_ibdev *dev =
+               container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
+       int vendor, boardrev, majrev, minrev;
 
-        ipath_layer_query_device(dev->dd, &vendor, &boardrev,
-                                 &majrev, &minrev);
-        return sprintf(buf, "%d.%d\n", majrev, minrev);
+       ipath_layer_query_device(dev->dd, &vendor, &boardrev,
+                                &majrev, &minrev);
+       return sprintf(buf, "%d.%d\n", majrev, minrev);
 }
 
 static ssize_t show_hca(struct class_device *cdev, char *buf)
 {
-        struct ipath_ibdev *dev =
-                container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
-        int ret;
+       struct ipath_ibdev *dev =
+               container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
+       int ret;
 
-        ret = ipath_layer_get_boardname(dev->dd, buf, 128);
-        if (ret < 0)
-                goto bail;
-        strcat(buf, "\n");
-        ret = strlen(buf);
+       ret = ipath_layer_get_boardname(dev->dd, buf, 128);
+       if (ret < 0)
+               goto bail;
+       strcat(buf, "\n");
+       ret = strlen(buf);
 
 bail:
        return ret;
@@ -1152,40 +1152,40 @@ bail:
 
 static ssize_t show_stats(struct class_device *cdev, char *buf)
 {
-        struct ipath_ibdev *dev =
-                container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
-        int i;
-        int len;
-
-        len = sprintf(buf,
-                      "RC resends  %d\n"
-                      "RC QACKs    %d\n"
-                      "RC ACKs     %d\n"
-                      "RC SEQ NAKs %d\n"
-                      "RC RDMA seq %d\n"
-                      "RC RNR NAKs %d\n"
-                      "RC OTH NAKs %d\n"
-                      "RC timeouts %d\n"
-                      "RC RDMA dup %d\n"
-                      "piobuf wait %d\n"
-                      "no piobuf   %d\n"
-                      "PKT drops   %d\n"
-                      "WQE errs    %d\n",
-                      dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks,
-                      dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks,
-                      dev->n_other_naks, dev->n_timeouts,
-                      dev->n_rdma_dup_busy, dev->n_piowait,
-                      dev->n_no_piobuf, dev->n_pkt_drops, dev->n_wqe_errs);
-        for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) {
+       struct ipath_ibdev *dev =
+               container_of(cdev, struct ipath_ibdev, ibdev.class_dev);
+       int i;
+       int len;
+
+       len = sprintf(buf,
+                     "RC resends  %d\n"
+                     "RC QACKs    %d\n"
+                     "RC ACKs     %d\n"
+                     "RC SEQ NAKs %d\n"
+                     "RC RDMA seq %d\n"
+                     "RC RNR NAKs %d\n"
+                     "RC OTH NAKs %d\n"
+                     "RC timeouts %d\n"
+                     "RC RDMA dup %d\n"
+                     "piobuf wait %d\n"
+                     "no piobuf   %d\n"
+                     "PKT drops   %d\n"
+                     "WQE errs    %d\n",
+                     dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks,
+                     dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks,
+                     dev->n_other_naks, dev->n_timeouts,
+                     dev->n_rdma_dup_busy, dev->n_piowait,
+                     dev->n_no_piobuf, dev->n_pkt_drops, dev->n_wqe_errs);
+       for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) {
                const struct ipath_opcode_stats *si = &dev->opstats[i];
 
-                if (!si->n_packets && !si->n_bytes)
-                        continue;
-                len += sprintf(buf + len, "%02x %llu/%llu\n", i,
+               if (!si->n_packets && !si->n_bytes)
+                       continue;
+               len += sprintf(buf + len, "%02x %llu/%llu\n", i,
                               (unsigned long long) si->n_packets,
-                               (unsigned long long) si->n_bytes);
-        }
-        return len;
+                              (unsigned long long) si->n_bytes);
+       }
+       return len;
 }
 
 static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL);
@@ -1194,25 +1194,25 @@ static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL);
 static CLASS_DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL);
 
 static struct class_device_attribute *ipath_class_attributes[] = {
-        &class_device_attr_hw_rev,
-        &class_device_attr_hca_type,
-        &class_device_attr_board_id,
-        &class_device_attr_stats
+       &class_device_attr_hw_rev,
+       &class_device_attr_hca_type,
+       &class_device_attr_board_id,
+       &class_device_attr_stats
 };
 
 static int ipath_verbs_register_sysfs(struct ib_device *dev)
 {
-        int i;
+       int i;
        int ret;
 
-        for (i = 0; i < ARRAY_SIZE(ipath_class_attributes); ++i)
-                if (class_device_create_file(&dev->class_dev,
-                                             ipath_class_attributes[i])) {
-                        ret = 1;
+       for (i = 0; i < ARRAY_SIZE(ipath_class_attributes); ++i)
+               if (class_device_create_file(&dev->class_dev,
+                                            ipath_class_attributes[i])) {
+                       ret = 1;
                        goto bail;
                }
 
-        ret = 0;
+       ret = 0;
 
 bail:
        return ret;
index b824632b2a8c4f35809bcdb3ddc60c00cbece7c7..fcafbc7c9e71053002d9cd9b1a93bff2490ff545 100644 (file)
@@ -577,8 +577,6 @@ int ipath_init_qp_table(struct ipath_ibdev *idev, int size);
 
 void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc);
 
-void ipath_error_qp(struct ipath_qp *qp);
-
 void ipath_get_credit(struct ipath_qp *qp, u32 aeth);
 
 void ipath_do_rc_send(unsigned long data);
@@ -607,9 +605,6 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
 
 void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc);
 
-void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss,
-                      u32 length, struct ib_send_wr *wr, struct ib_wc *wc);
-
 int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr);
 
 void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr,
index f235c7ea42f07d7ed4e6d5aee255e834d7fdc2a6..4730863ece9a398c89e62c366d2f112d81b509f4 100644 (file)
@@ -49,7 +49,7 @@ enum {
        MTHCA_VENDOR_CLASS2 = 0xa
 };
 
-int mthca_update_rate(struct mthca_dev *dev, u8 port_num)
+static int mthca_update_rate(struct mthca_dev *dev, u8 port_num)
 {
        struct ib_port_attr *tprops = NULL;
        int                  ret;
index 5f2b3f6e4c4777c5a775627ba703669e66e5828c..5bb55742ada68d34249d11ae9390150b30e078f5 100644 (file)
@@ -617,6 +617,14 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd,
                     scmnd->sc_data_direction);
 }
 
+static void srp_remove_req(struct srp_target_port *target, struct srp_request *req,
+                          int index)
+{
+       list_del(&req->list);
+       req->next = target->req_head;
+       target->req_head = index;
+}
+
 static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
 {
        struct srp_request *req;
@@ -664,9 +672,7 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp)
                        scmnd->host_scribble = (void *) -1L;
                        scmnd->scsi_done(scmnd);
 
-                       list_del(&req->list);
-                       req->next = target->req_head;
-                       target->req_head = rsp->tag & ~SRP_TAG_TSK_MGMT;
+                       srp_remove_req(target, req, rsp->tag & ~SRP_TAG_TSK_MGMT);
                } else
                        req->cmd_done = 1;
        }
@@ -1188,12 +1194,10 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func)
        spin_lock_irq(target->scsi_host->host_lock);
 
        if (req->cmd_done) {
-               list_del(&req->list);
-               req->next = target->req_head;
-               target->req_head = req_index;
-
+               srp_remove_req(target, req, req_index);
                scmnd->scsi_done(scmnd);
        } else if (!req->tsk_status) {
+               srp_remove_req(target, req, req_index);
                scmnd->result = DID_ABORT << 16;
                ret = SUCCESS;
        }
index f86ed6af3aa2d5fb68575cd4a78c2fb8082034ba..eb41aba3ddef4bdd72be0b2cbfc5f6aaf6ff8d1a 100644 (file)
@@ -5,8 +5,6 @@
  *                       Tilman Schmidt <tilman@imap.cc>,
  *                       Stefan Eilers.
  *
- * Based on usb-gigaset.c.
- *
  * =====================================================================
  *     This program is free software; you can redistribute it and/or
  *     modify it under the terms of the GNU General Public License as
@@ -46,19 +44,20 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode");
 #define GIGASET_DEVFSNAME  "gig/bas/"
 #define GIGASET_DEVNAME    "ttyGB"
 
-#define IF_WRITEBUF 256 //FIXME
+/* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */
+#define IF_WRITEBUF 264
 
 /* Values for the Gigaset 307x */
 #define USB_GIGA_VENDOR_ID      0x0681
-#define USB_GIGA_PRODUCT_ID     0x0001
-#define USB_4175_PRODUCT_ID     0x0002
+#define USB_3070_PRODUCT_ID     0x0001
+#define USB_3075_PRODUCT_ID     0x0002
 #define USB_SX303_PRODUCT_ID    0x0021
 #define USB_SX353_PRODUCT_ID    0x0022
 
 /* table of devices that work with this driver */
 static struct usb_device_id gigaset_table [] = {
-       { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_GIGA_PRODUCT_ID) },
-       { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_4175_PRODUCT_ID) },
+       { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) },
+       { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) },
        { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) },
        { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX353_PRODUCT_ID) },
        { } /* Terminating entry */
@@ -77,6 +76,10 @@ static int gigaset_probe(struct usb_interface *interface,
 /* Function will be called if the device is unplugged */
 static void gigaset_disconnect(struct usb_interface *interface);
 
+static void read_ctrl_callback(struct urb *, struct pt_regs *);
+static void stopurbs(struct bas_bc_state *);
+static int atwrite_submit(struct cardstate *, unsigned char *, int);
+static int start_cbsend(struct cardstate *);
 
 /*==============================================================================*/
 
@@ -111,12 +114,14 @@ struct bas_cardstate {
 };
 
 /* status of direct USB connection to 307x base (bits in basstate) */
-#define BS_ATOPEN      0x001
-#define BS_B1OPEN      0x002
-#define BS_B2OPEN      0x004
-#define BS_ATREADY     0x008
-#define BS_INIT                0x010
-#define BS_ATTIMER     0x020
+#define BS_ATOPEN      0x001   /* AT channel open */
+#define BS_B1OPEN      0x002   /* B channel 1 open */
+#define BS_B2OPEN      0x004   /* B channel 2 open */
+#define BS_ATREADY     0x008   /* base ready for AT command */
+#define BS_INIT                0x010   /* base has signalled INIT_OK */
+#define BS_ATTIMER     0x020   /* waiting for HD_READY_SEND_ATDATA */
+#define BS_ATRDPEND    0x040   /* urb_cmd_in in use */
+#define BS_ATWRPEND    0x080   /* urb_cmd_out in use */
 
 
 static struct gigaset_driver *driver = NULL;
@@ -130,6 +135,47 @@ static struct usb_driver gigaset_usb_driver = {
        .id_table =     gigaset_table,
 };
 
+/* get message text for usb_submit_urb return code
+ */
+static char *get_usb_rcmsg(int rc)
+{
+       static char unkmsg[28];
+
+       switch (rc) {
+       case 0:
+               return "success";
+       case -ENOMEM:
+               return "out of memory";
+       case -ENODEV:
+               return "device not present";
+       case -ENOENT:
+               return "endpoint not present";
+       case -ENXIO:
+               return "URB type not supported";
+       case -EINVAL:
+               return "invalid argument";
+       case -EAGAIN:
+               return "start frame too early or too much scheduled";
+       case -EFBIG:
+               return "too many isochronous frames requested";
+       case -EPIPE:
+               return "endpoint stalled";
+       case -EMSGSIZE:
+               return "invalid packet size";
+       case -ENOSPC:
+               return "would overcommit USB bandwidth";
+       case -ESHUTDOWN:
+               return "device shut down";
+       case -EPERM:
+               return "reject flag set";
+       case -EHOSTUNREACH:
+               return "device suspended";
+       default:
+               snprintf(unkmsg, sizeof(unkmsg), "unknown error %d", rc);
+               return unkmsg;
+       }
+}
+
 /* get message text for USB status code
  */
 static char *get_usb_statmsg(int status)
@@ -140,43 +186,37 @@ static char *get_usb_statmsg(int status)
        case 0:
                return "success";
        case -ENOENT:
-               return "canceled";
-       case -ECONNRESET:
-               return "canceled (async)";
+               return "unlinked (sync)";
        case -EINPROGRESS:
                return "pending";
        case -EPROTO:
-               return "bit stuffing or unknown USB error";
+               return "bit stuffing error, timeout, or unknown USB error";
        case -EILSEQ:
-               return "Illegal byte sequence (CRC mismatch)";
-       case -EPIPE:
-               return "babble detect or endpoint stalled";
-       case -ENOSR:
-               return "buffer error";
+               return "CRC mismatch, timeout, or unknown USB error";
        case -ETIMEDOUT:
                return "timed out";
-       case -ENODEV:
-               return "device not present";
+       case -EPIPE:
+               return "endpoint stalled";
+       case -ECOMM:
+               return "IN buffer overrun";
+       case -ENOSR:
+               return "OUT buffer underrun";
+       case -EOVERFLOW:
+               return "too much data";
        case -EREMOTEIO:
                return "short packet detected";
+       case -ENODEV:
+               return "device removed";
        case -EXDEV:
                return "partial isochronous transfer";
        case -EINVAL:
                return "invalid argument";
-       case -ENXIO:
-               return "URB already queued";
-       case -EAGAIN:
-               return "isochronous start frame too early or too much scheduled";
-       case -EFBIG:
-               return "too many isochronous frames requested";
-       case -EMSGSIZE:
-               return "endpoint message size zero";
+       case -ECONNRESET:
+               return "unlinked (async)";
        case -ESHUTDOWN:
-               return "endpoint shutdown";
-       case -EBUSY:
-               return "another request pending";
+               return "device shut down";
        default:
-               snprintf(unkmsg, sizeof(unkmsg), "unknown error %d", status);
+               snprintf(unkmsg, sizeof(unkmsg), "unknown status %d", status);
                return unkmsg;
        }
 }
@@ -277,18 +317,17 @@ static inline void error_hangup(struct bc_state *bcs)
        gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d",
                __func__, bcs->channel);
 
-       if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) {
-               //FIXME what should we do?
-               return;
-       }
+       if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL))
+               dev_err(cs->dev, "event queue full\n");
 
        gigaset_schedule_event(cs);
 }
 
 /* error_reset
  * reset Gigaset device because of an unrecoverable error
- * This function may be called from any context and takes care of scheduling
- * the necessary actions for execution outside of interrupt context.
+ * This function may be called from any context, and should take care of
+ * scheduling the necessary actions for execution outside of interrupt context.
+ * Right now, it just generates a kernel message calling for help.
  * argument:
  *     controller state structure
  */
@@ -364,36 +403,38 @@ static void cmd_in_timeout(unsigned long data)
 {
        struct cardstate *cs = (struct cardstate *) data;
        struct bas_cardstate *ucs = cs->hw.bas;
-       unsigned long flags;
 
-       spin_lock_irqsave(&cs->lock, flags);
-       if (unlikely(!cs->connected)) {
-               gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__);
-               spin_unlock_irqrestore(&cs->lock, flags);
-               return;
-       }
        if (!ucs->rcvbuf_size) {
                gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__);
-               spin_unlock_irqrestore(&cs->lock, flags);
                return;
        }
-       spin_unlock_irqrestore(&cs->lock, flags);
 
        dev_err(cs->dev, "timeout reading AT response\n");
        error_reset(cs);        //FIXME retry?
 }
 
+/* set/clear bits in base connection state, return previous state
+ */
+inline static int update_basstate(struct bas_cardstate *ucs,
+                                 int set, int clear)
+{
+       unsigned long flags;
+       int state;
 
-static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs);
+       spin_lock_irqsave(&ucs->lock, flags);
+       state = atomic_read(&ucs->basstate);
+       atomic_set(&ucs->basstate, (state & ~clear) | set);
+       spin_unlock_irqrestore(&ucs->lock, flags);
+       return state;
+}
 
 /* atread_submit
- * submit an HD_READ_ATMESSAGE command URB
+ * submit an HD_READ_ATMESSAGE command URB and optionally start a timeout
  * parameters:
  *     cs      controller state structure
  *     timeout timeout in 1/10 sec., 0: none
  * return value:
  *     0 on success
- *     -EINVAL if a NULL pointer is encountered somewhere
  *     -EBUSY if another request is pending
  *     any URB submission error code
  */
@@ -405,7 +446,7 @@ static int atread_submit(struct cardstate *cs, int timeout)
        gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)",
                ucs->rcvbuf_size);
 
-       if (ucs->urb_cmd_in->status == -EINPROGRESS) {
+       if (update_basstate(ucs, BS_ATRDPEND, 0) & BS_ATRDPEND) {
                dev_err(cs->dev,
                        "could not submit HD_READ_ATMESSAGE: URB busy\n");
                return -EBUSY;
@@ -423,6 +464,7 @@ static int atread_submit(struct cardstate *cs, int timeout)
                             read_ctrl_callback, cs->inbuf);
 
        if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) {
+               update_basstate(ucs, 0, BS_ATRDPEND);
                dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n",
                        get_usb_statmsg(ret));
                return ret;
@@ -438,26 +480,6 @@ static int atread_submit(struct cardstate *cs, int timeout)
        return 0;
 }
 
-static void stopurbs(struct bas_bc_state *);
-static int start_cbsend(struct cardstate *);
-
-/* set/clear bits in base connection state
- */
-inline static void update_basstate(struct bas_cardstate *ucs,
-                                  int set, int clear)
-{
-       unsigned long flags;
-       int state;
-
-       spin_lock_irqsave(&ucs->lock, flags);
-       state = atomic_read(&ucs->basstate);
-       state &= ~clear;
-       state |= set;
-       atomic_set(&ucs->basstate, state);
-       spin_unlock_irqrestore(&ucs->lock, flags);
-}
-
-
 /* read_int_callback
  * USB completion handler for interrupt pipe input
  * called by the USB subsystem in interrupt context
@@ -471,20 +493,25 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
        struct bas_cardstate *ucs = cs->hw.bas;
        struct bc_state *bcs;
        unsigned long flags;
-       int status;
+       int rc;
        unsigned l;
        int channel;
 
        switch (urb->status) {
        case 0:                 /* success */
                break;
-       case -ENOENT:                   /* canceled */
-       case -ECONNRESET:               /* canceled (async) */
+       case -ENOENT:                   /* cancelled */
+       case -ECONNRESET:               /* cancelled (async) */
        case -EINPROGRESS:              /* pending */
                /* ignore silently */
                gig_dbg(DEBUG_USBREQ, "%s: %s",
                        __func__, get_usb_statmsg(urb->status));
                return;
+       case -ENODEV:                   /* device removed */
+       case -ESHUTDOWN:                /* device shut down */
+               //FIXME use this as disconnect indicator?
+               gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__);
+               return;
        default:                /* severe trouble */
                dev_warn(cs->dev, "interrupt read: %s\n",
                         get_usb_statmsg(urb->status));
@@ -492,6 +519,13 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
                goto resubmit;
        }
 
+       /* drop incomplete packets even if the missing bytes wouldn't matter */
+       if (unlikely(urb->actual_length < 3)) {
+               dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n",
+                        urb->actual_length);
+               goto resubmit;
+       }
+
        l = (unsigned) ucs->int_in_buf[1] +
            (((unsigned) ucs->int_in_buf[2]) << 8);
 
@@ -558,25 +592,28 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
                }
                spin_lock_irqsave(&cs->lock, flags);
                if (ucs->rcvbuf_size) {
-                       spin_unlock_irqrestore(&cs->lock, flags);
+                       /* throw away previous buffer - we have no queue */
                        dev_err(cs->dev,
-                               "receive AT data overrun, %d bytes lost\n", l);
-                       error_reset(cs);        //FIXME reschedule
-                       break;
+                               "receive AT data overrun, %d bytes lost\n",
+                               ucs->rcvbuf_size);
+                       kfree(ucs->rcvbuf);
+                       ucs->rcvbuf_size = 0;
                }
                if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) {
                        spin_unlock_irqrestore(&cs->lock, flags);
-                       dev_err(cs->dev, "out of memory, %d bytes lost\n", l);
-                       error_reset(cs);        //FIXME reschedule
+                       dev_err(cs->dev, "out of memory receiving AT data\n");
+                       error_reset(cs);
                        break;
                }
                ucs->rcvbuf_size = l;
                ucs->retry_cmd_in = 0;
-               if ((status = atread_submit(cs, BAS_TIMEOUT)) < 0) {
+               if ((rc = atread_submit(cs, BAS_TIMEOUT)) < 0) {
                        kfree(ucs->rcvbuf);
                        ucs->rcvbuf = NULL;
                        ucs->rcvbuf_size = 0;
-                       error_reset(cs);        //FIXME reschedule
+                       if (rc != -ENODEV)
+                               //FIXME corrective action?
+                               error_reset(cs);
                }
                spin_unlock_irqrestore(&cs->lock, flags);
                break;
@@ -598,12 +635,10 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs)
        check_pending(ucs);
 
 resubmit:
-       spin_lock_irqsave(&cs->lock, flags);
-       status = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
-       spin_unlock_irqrestore(&cs->lock, flags);
-       if (unlikely(status)) {
+       rc = usb_submit_urb(urb, SLAB_ATOMIC);
+       if (unlikely(rc != 0 && rc != -ENODEV)) {
                dev_err(cs->dev, "could not resubmit interrupt URB: %s\n",
-                       get_usb_statmsg(status));
+                       get_usb_rcmsg(rc));
                error_reset(cs);
        }
 }
@@ -622,18 +657,12 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
        struct bas_cardstate *ucs = cs->hw.bas;
        int have_data = 0;
        unsigned numbytes;
-       unsigned long flags;
+       int rc;
 
-       spin_lock_irqsave(&cs->lock, flags);
-       if (unlikely(!cs->connected)) {
-               warn("%s: disconnected", __func__);
-               spin_unlock_irqrestore(&cs->lock, flags);
-               return;
-       }
+       update_basstate(ucs, 0, BS_ATRDPEND);
 
        if (!ucs->rcvbuf_size) {
                dev_warn(cs->dev, "%s: no receive in progress\n", __func__);
-               spin_unlock_irqrestore(&cs->lock, flags);
                return;
        }
 
@@ -666,9 +695,11 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
                }
                break;
 
-       case -ENOENT:                   /* canceled */
-       case -ECONNRESET:               /* canceled (async) */
+       case -ENOENT:                   /* cancelled */
+       case -ECONNRESET:               /* cancelled (async) */
        case -EINPROGRESS:              /* pending */
+       case -ENODEV:                   /* device removed */
+       case -ESHUTDOWN:                /* device shut down */
                /* no action necessary */
                gig_dbg(DEBUG_USBREQ, "%s: %s",
                        __func__, get_usb_statmsg(urb->status));
@@ -681,11 +712,11 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
                if (ucs->retry_cmd_in++ < BAS_RETRY) {
                        dev_notice(cs->dev, "control read: retry %d\n",
                                   ucs->retry_cmd_in);
-                       if (atread_submit(cs, BAS_TIMEOUT) >= 0) {
-                               /* resubmitted - bypass regular exit block */
-                               spin_unlock_irqrestore(&cs->lock, flags);
+                       rc = atread_submit(cs, BAS_TIMEOUT);
+                       if (rc >= 0 || rc == -ENODEV)
+                               /* resubmitted or disconnected */
+                               /* - bypass regular exit block */
                                return;
-                       }
                } else {
                        dev_err(cs->dev,
                                "control read: giving up after %d tries\n",
@@ -697,7 +728,6 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs)
        kfree(ucs->rcvbuf);
        ucs->rcvbuf = NULL;
        ucs->rcvbuf_size = 0;
-       spin_unlock_irqrestore(&cs->lock, flags);
        if (have_data) {
                gig_dbg(DEBUG_INTR, "%s-->BH", __func__);
                gigaset_schedule_event(cs);
@@ -719,8 +749,11 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs)
        int i, rc;
 
        /* status codes not worth bothering the tasklet with */
-       if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET ||
-                    urb->status == -EINPROGRESS)) {
+       if (unlikely(urb->status == -ENOENT ||
+                    urb->status == -ECONNRESET ||
+                    urb->status == -EINPROGRESS ||
+                    urb->status == -ENODEV ||
+                    urb->status == -ESHUTDOWN)) {
                gig_dbg(DEBUG_ISO, "%s: %s",
                        __func__, get_usb_statmsg(urb->status));
                return;
@@ -740,9 +773,9 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs)
                for (i = 0; i < BAS_NUMFRAMES; i++) {
                        ubc->isoinlost += urb->iso_frame_desc[i].actual_length;
                        if (unlikely(urb->iso_frame_desc[i].status != 0 &&
-                                    urb->iso_frame_desc[i].status != -EINPROGRESS)) {
+                                    urb->iso_frame_desc[i].status !=
+                                                               -EINPROGRESS))
                                ubc->loststatus = urb->iso_frame_desc[i].status;
-                       }
                        urb->iso_frame_desc[i].status = 0;
                        urb->iso_frame_desc[i].actual_length = 0;
                }
@@ -754,10 +787,10 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs)
                        gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit",
                                __func__);
                        rc = usb_submit_urb(urb, SLAB_ATOMIC);
-                       if (unlikely(rc != 0)) {
+                       if (unlikely(rc != 0 && rc != -ENODEV)) {
                                dev_err(bcs->cs->dev,
                                        "could not resubmit isochronous read "
-                                       "URB: %s\n", get_usb_statmsg(rc));
+                                       "URB: %s\n", get_usb_rcmsg(rc));
                                dump_urb(DEBUG_ISO, "isoc read", urb);
                                error_hangup(bcs);
                        }
@@ -780,8 +813,11 @@ static void write_iso_callback(struct urb *urb, struct pt_regs *regs)
        unsigned long flags;
 
        /* status codes not worth bothering the tasklet with */
-       if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET ||
-                    urb->status == -EINPROGRESS)) {
+       if (unlikely(urb->status == -ENOENT ||
+                    urb->status == -ECONNRESET ||
+                    urb->status == -EINPROGRESS ||
+                    urb->status == -ENODEV ||
+                    urb->status == -ESHUTDOWN)) {
                gig_dbg(DEBUG_ISO, "%s: %s",
                        __func__, get_usb_statmsg(urb->status));
                return;
@@ -822,7 +858,6 @@ static int starturbs(struct bc_state *bcs)
        for (k = 0; k < BAS_INURBS; k++) {
                urb = ubc->isoinurbs[k];
                if (!urb) {
-                       dev_err(bcs->cs->dev, "isoinurbs[%d]==NULL\n", k);
                        rc = -EFAULT;
                        goto error;
                }
@@ -844,12 +879,8 @@ static int starturbs(struct bc_state *bcs)
                }
 
                dump_urb(DEBUG_ISO, "Initial isoc read", urb);
-               if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) {
-                       dev_err(bcs->cs->dev,
-                              "could not submit isochronous read URB %d: %s\n",
-                               k, get_usb_statmsg(rc));
+               if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0)
                        goto error;
-               }
        }
 
        /* initialize L2 transmission */
@@ -859,7 +890,6 @@ static int starturbs(struct bc_state *bcs)
        for (k = 0; k < BAS_OUTURBS; ++k) {
                urb = ubc->isoouturbs[k].urb;
                if (!urb) {
-                       dev_err(bcs->cs->dev, "isoouturbs[%d].urb==NULL\n", k);
                        rc = -EFAULT;
                        goto error;
                }
@@ -885,12 +915,8 @@ static int starturbs(struct bc_state *bcs)
        for (k = 0; k < 2; ++k) {
                dump_urb(DEBUG_ISO, "Initial isoc write", urb);
                rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC);
-               if (rc != 0) {
-                       dev_err(bcs->cs->dev,
-                             "could not submit isochronous write URB %d: %s\n",
-                               k, get_usb_statmsg(rc));
+               if (rc != 0)
                        goto error;
-               }
        }
        dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb);
        ubc->isooutfree = &ubc->isoouturbs[2];
@@ -916,15 +942,15 @@ static void stopurbs(struct bas_bc_state *ubc)
        for (k = 0; k < BAS_INURBS; ++k) {
                rc = usb_unlink_urb(ubc->isoinurbs[k]);
                gig_dbg(DEBUG_ISO,
-                       "%s: isoc input URB %d unlinked, result = %d",
-                       __func__, k, rc);
+                       "%s: isoc input URB %d unlinked, result = %s",
+                       __func__, k, get_usb_rcmsg(rc));
        }
 
        for (k = 0; k < BAS_OUTURBS; ++k) {
                rc = usb_unlink_urb(ubc->isoouturbs[k].urb);
                gig_dbg(DEBUG_ISO,
-                       "%s: isoc output URB %d unlinked, result = %d",
-                       __func__, k, rc);
+                       "%s: isoc output URB %d unlinked, result = %s",
+                       __func__, k, get_usb_rcmsg(rc));
        }
 }
 
@@ -934,7 +960,7 @@ static void stopurbs(struct bas_bc_state *ubc)
 /* submit_iso_write_urb
  * fill and submit the next isochronous write URB
  * parameters:
- *     bcs     B channel state structure
+ *     ucx     context structure containing URB
  * return value:
  *     number of frames submitted in URB
  *     0 if URB not submitted because no data available (isooutbuf busy)
@@ -946,7 +972,6 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
        struct bas_bc_state *ubc = ucx->bcs->hw.bas;
        struct usb_iso_packet_descriptor *ifd;
        int corrbytes, nframe, rc;
-       unsigned long flags;
 
        /* urb->dev is clobbered by USB subsystem */
        urb->dev = ucx->bcs->cs->hw.bas->udev;
@@ -992,20 +1017,22 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx)
                ifd->status = 0;
                ifd->actual_length = 0;
        }
-       if ((urb->number_of_packets = nframe) > 0) {
-               spin_lock_irqsave(&ucx->bcs->cs->lock, flags);
-               rc = ucx->bcs->cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
-               spin_unlock_irqrestore(&ucx->bcs->cs->lock, flags);
+       if (unlikely(nframe == 0))
+               return 0;       /* no data to send */
+       urb->number_of_packets = nframe;
 
-               if (rc) {
+       rc = usb_submit_urb(urb, SLAB_ATOMIC);
+       if (unlikely(rc)) {
+               if (rc == -ENODEV)
+                       /* device removed - give up silently */
+                       gig_dbg(DEBUG_ISO, "%s: disconnected", __func__);
+               else
                        dev_err(ucx->bcs->cs->dev,
                                "could not submit isochronous write URB: %s\n",
-                               get_usb_statmsg(rc));
-                       dump_urb(DEBUG_ISO, "isoc write", urb);
-                       return rc;
-               }
-               ++ubc->numsub;
+                               get_usb_rcmsg(rc));
+               return rc;
        }
+       ++ubc->numsub;
        return nframe;
 }
 
@@ -1028,6 +1055,7 @@ static void write_iso_tasklet(unsigned long data)
        int i;
        struct sk_buff *skb;
        int len;
+       int rc;
 
        /* loop while completed URBs arrive in time */
        for (;;) {
@@ -1057,7 +1085,8 @@ static void write_iso_tasklet(unsigned long data)
                ubc->isooutfree = NULL;
                spin_unlock_irqrestore(&ubc->isooutlock, flags);
                if (next) {
-                       if (submit_iso_write_urb(next) <= 0) {
+                       rc = submit_iso_write_urb(next);
+                       if (unlikely(rc <= 0 && rc != -ENODEV)) {
                                /* could not submit URB, put it back */
                                spin_lock_irqsave(&ubc->isooutlock, flags);
                                if (ubc->isooutfree == NULL) {
@@ -1077,17 +1106,18 @@ static void write_iso_tasklet(unsigned long data)
                /* process completed URB */
                urb = done->urb;
                switch (urb->status) {
+               case -EXDEV:                    /* partial completion */
+                       gig_dbg(DEBUG_ISO, "%s: URB partially completed",
+                               __func__);
+                       /* fall through - what's the difference anyway? */
                case 0:                         /* normal completion */
-                       break;
-               case -EXDEV:                    /* inspect individual frames */
-                       /* assumptions (for lack of documentation):
-                        * - actual_length bytes of the frame in error are
+                       /* inspect individual frames
+                        * assumptions (for lack of documentation):
+                        * - actual_length bytes of first frame in error are
                         *   successfully sent
                         * - all following frames are not sent at all
                         */
-                       gig_dbg(DEBUG_ISO, "%s: URB partially completed",
-                               __func__);
-                       offset = done->limit;   /* just in case */
+                       offset = done->limit;   /* default (no error) */
                        for (i = 0; i < BAS_NUMFRAMES; i++) {
                                ifd = &urb->iso_frame_desc[i];
                                if (ifd->status ||
@@ -1122,7 +1152,7 @@ static void write_iso_tasklet(unsigned long data)
                        }
 #endif
                        break;
-               case -EPIPE:            //FIXME is this the code for "underrun"?
+               case -EPIPE:                    /* stall - probably underrun */
                        dev_err(cs->dev, "isochronous write stalled\n");
                        error_hangup(bcs);
                        break;
@@ -1142,7 +1172,8 @@ static void write_iso_tasklet(unsigned long data)
                spin_unlock_irqrestore(&ubc->isooutlock, flags);
                if (next) {
                        /* only one URB still active - resubmit one */
-                       if (submit_iso_write_urb(next) <= 0) {
+                       rc = submit_iso_write_urb(next);
+                       if (unlikely(rc <= 0 && rc != -ENODEV)) {
                                /* couldn't submit */
                                error_hangup(bcs);
                        }
@@ -1222,10 +1253,9 @@ static void read_iso_tasklet(unsigned long data)
                        break;
                case -ENOENT:
                case -ECONNRESET:
-                       gig_dbg(DEBUG_ISO, "%s: URB canceled", __func__);
-                       continue;               /* -> skip */
-               case -EINPROGRESS:              /* huh? */
-                       gig_dbg(DEBUG_ISO, "%s: URB still pending", __func__);
+               case -EINPROGRESS:
+                       gig_dbg(DEBUG_ISO, "%s: %s",
+                               __func__, get_usb_statmsg(urb->status));
                        continue;               /* -> skip */
                case -EPIPE:
                        dev_err(cs->dev, "isochronous read stalled\n");
@@ -1290,13 +1320,11 @@ static void read_iso_tasklet(unsigned long data)
                urb->dev = bcs->cs->hw.bas->udev;
                urb->transfer_flags = URB_ISO_ASAP;
                urb->number_of_packets = BAS_NUMFRAMES;
-               spin_lock_irqsave(&cs->lock, flags);
-               rc = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV;
-               spin_unlock_irqrestore(&cs->lock, flags);
-               if (rc) {
+               rc = usb_submit_urb(urb, SLAB_ATOMIC);
+               if (unlikely(rc != 0 && rc != -ENODEV)) {
                        dev_err(cs->dev,
                                "could not resubmit isochronous read URB: %s\n",
-                               get_usb_statmsg(rc));
+                               get_usb_rcmsg(rc));
                        dump_urb(DEBUG_ISO, "resubmit iso read", urb);
                        error_hangup(bcs);
                }
@@ -1397,7 +1425,6 @@ static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs)
  *     timeout timeout in seconds (0: no timeout)
  * return value:
  *     0 on success
- *     -EINVAL if a NULL pointer is encountered somewhere
  *     -EBUSY if another request is pending
  *     any URB submission error code
  */
@@ -1418,12 +1445,6 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout)
                        req, ucs->pending);
                return -EBUSY;
        }
-       if (ucs->urb_ctrl->status == -EINPROGRESS) {
-               spin_unlock_irqrestore(&ucs->lock, flags);
-               dev_err(bcs->cs->dev,
-                       "could not submit request 0x%02x: URB busy\n", req);
-               return -EBUSY;
-       }
 
        ucs->dr_ctrl.bRequestType = OUT_VENDOR_REQ;
        ucs->dr_ctrl.bRequest = req;
@@ -1465,22 +1486,36 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout)
 static int gigaset_init_bchannel(struct bc_state *bcs)
 {
        int req, ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&bcs->cs->lock, flags);
+       if (unlikely(!bcs->cs->connected)) {
+               gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
+               spin_unlock_irqrestore(&bcs->cs->lock, flags);
+               return -ENODEV;
+       }
 
        if ((ret = starturbs(bcs)) < 0) {
                dev_err(bcs->cs->dev,
-                       "could not start isochronous I/O for channel %d\n",
-                       bcs->channel + 1);
-               error_hangup(bcs);
+                       "could not start isochronous I/O for channel B%d: %s\n",
+                       bcs->channel + 1,
+                       ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret));
+               if (ret != -ENODEV)
+                       error_hangup(bcs);
+               spin_unlock_irqrestore(&bcs->cs->lock, flags);
                return ret;
        }
 
        req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL;
        if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) {
-               dev_err(bcs->cs->dev, "could not open channel %d: %s\n",
-                       bcs->channel + 1, get_usb_statmsg(ret));
+               dev_err(bcs->cs->dev, "could not open channel B%d\n",
+                       bcs->channel + 1);
                stopurbs(bcs->hw.bas);
-               error_hangup(bcs);
+               if (ret != -ENODEV)
+                       error_hangup(bcs);
        }
+
+       spin_unlock_irqrestore(&bcs->cs->lock, flags);
        return ret;
 }
 
@@ -1497,19 +1532,30 @@ static int gigaset_init_bchannel(struct bc_state *bcs)
 static int gigaset_close_bchannel(struct bc_state *bcs)
 {
        int req, ret;
+       unsigned long flags;
+
+       spin_lock_irqsave(&bcs->cs->lock, flags);
+       if (unlikely(!bcs->cs->connected)) {
+               spin_unlock_irqrestore(&bcs->cs->lock, flags);
+               gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
+               return -ENODEV;
+       }
 
        if (!(atomic_read(&bcs->cs->hw.bas->basstate) &
              (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) {
                /* channel not running: just signal common.c */
+               spin_unlock_irqrestore(&bcs->cs->lock, flags);
                gigaset_bchannel_down(bcs);
                return 0;
        }
 
+       /* channel running: tell device to close it */
        req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL;
        if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0)
-               dev_err(bcs->cs->dev,
-                       "could not submit HD_CLOSE_BxCHANNEL request: %s\n",
-                       get_usb_statmsg(ret));
+               dev_err(bcs->cs->dev, "closing channel B%d failed\n",
+                       bcs->channel + 1);
+
+       spin_unlock_irqrestore(&bcs->cs->lock, flags);
        return ret;
 }
 
@@ -1545,8 +1591,6 @@ static void complete_cb(struct cardstate *cs)
        kfree(cb);
 }
 
-static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len);
-
 /* write_command_callback
  * USB completion handler for AT command transmission
  * called by the USB subsystem in interrupt context
@@ -1560,13 +1604,17 @@ static void write_command_callback(struct urb *urb, struct pt_regs *regs)
        struct bas_cardstate *ucs = cs->hw.bas;
        unsigned long flags;
 
+       update_basstate(ucs, 0, BS_ATWRPEND);
+
        /* check status */
        switch (urb->status) {
        case 0:                                 /* normal completion */
                break;
-       case -ENOENT:                   /* canceled */
-       case -ECONNRESET:               /* canceled (async) */
+       case -ENOENT:                   /* cancelled */
+       case -ECONNRESET:               /* cancelled (async) */
        case -EINPROGRESS:              /* pending */
+       case -ENODEV:                   /* device removed */
+       case -ESHUTDOWN:                /* device shut down */
                /* ignore silently */
                gig_dbg(DEBUG_USBREQ, "%s: %s",
                        __func__, get_usb_statmsg(urb->status));
@@ -1627,19 +1675,17 @@ static void atrdy_timeout(unsigned long data)
  *     len     length of command to send
  * return value:
  *     0 on success
- *     -EFAULT if a NULL pointer is encountered somewhere
  *     -EBUSY if another request is pending
  *     any URB submission error code
  */
 static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
 {
        struct bas_cardstate *ucs = cs->hw.bas;
-       unsigned long flags;
-       int ret;
+       int rc;
 
        gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len);
 
-       if (ucs->urb_cmd_out->status == -EINPROGRESS) {
+       if (update_basstate(ucs, BS_ATWRPEND, 0) & BS_ATWRPEND) {
                dev_err(cs->dev,
                        "could not submit HD_WRITE_ATMESSAGE: URB busy\n");
                return -EBUSY;
@@ -1654,29 +1700,22 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len)
                             usb_sndctrlpipe(ucs->udev, 0),
                             (unsigned char*) &ucs->dr_cmd_out, buf, len,
                             write_command_callback, cs);
-
-       spin_lock_irqsave(&cs->lock, flags);
-       ret = cs->connected ? usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC) : -ENODEV;
-       spin_unlock_irqrestore(&cs->lock, flags);
-
-       if (ret) {
+       rc = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC);
+       if (unlikely(rc)) {
+               update_basstate(ucs, 0, BS_ATWRPEND);
                dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n",
-                       get_usb_statmsg(ret));
-               return ret;
+                       get_usb_rcmsg(rc));
+               return rc;
        }
 
-       /* submitted successfully */
-       update_basstate(ucs, 0, BS_ATREADY);
-
-       /* start timeout if necessary */
-       if (!(atomic_read(&ucs->basstate) & BS_ATTIMER)) {
+       /* submitted successfully, start timeout if necessary */
+       if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) {
                gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs",
                        ATRDY_TIMEOUT);
                ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10;
                ucs->timer_atrdy.data = (unsigned long) cs;
                ucs->timer_atrdy.function = atrdy_timeout;
                add_timer(&ucs->timer_atrdy);
-               update_basstate(ucs, BS_ATTIMER, 0);
        }
        return 0;
 }
@@ -1702,7 +1741,6 @@ static int start_cbsend(struct cardstate *cs)
                gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open");
                rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT);
                if (rc < 0) {
-                       dev_err(cs->dev, "could not open AT channel\n");
                        /* flush command queue */
                        spin_lock_irqsave(&cs->cmdlock, flags);
                        while (cs->cmdbuf != NULL)
@@ -1786,8 +1824,14 @@ static int gigaset_write_cmd(struct cardstate *cs,
        cs->lastcmdbuf = cb;
        spin_unlock_irqrestore(&cs->cmdlock, flags);
 
+       spin_lock_irqsave(&cs->lock, flags);
+       if (unlikely(!cs->connected)) {
+               spin_unlock_irqrestore(&cs->lock, flags);
+               gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__);
+               return -ENODEV;
+       }
        status = start_cbsend(cs);
-
+       spin_unlock_irqrestore(&cs->lock, flags);
        return status < 0 ? status : len;
 }
 
@@ -1849,12 +1893,32 @@ static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6])
  */
 static int gigaset_freebcshw(struct bc_state *bcs)
 {
-       if (!bcs->hw.bas)
+       struct bas_bc_state *ubc = bcs->hw.bas;
+       int i;
+
+       if (!ubc)
                return 0;
 
-       if (bcs->hw.bas->isooutbuf)
-               kfree(bcs->hw.bas->isooutbuf);
-       kfree(bcs->hw.bas);
+       /* kill URBs and tasklets before freeing - better safe than sorry */
+       atomic_set(&ubc->running, 0);
+       for (i = 0; i < BAS_OUTURBS; ++i)
+               if (ubc->isoouturbs[i].urb) {
+                       gig_dbg(DEBUG_INIT, "%s: killing iso out URB %d",
+                               __func__, i);
+                       usb_kill_urb(ubc->isoouturbs[i].urb);
+                       usb_free_urb(ubc->isoouturbs[i].urb);
+               }
+       for (i = 0; i < BAS_INURBS; ++i)
+               if (ubc->isoinurbs[i]) {
+                       gig_dbg(DEBUG_INIT, "%s: killing iso in URB %d",
+                               __func__, i);
+                       usb_kill_urb(ubc->isoinurbs[i]);
+                       usb_free_urb(ubc->isoinurbs[i]);
+               }
+       tasklet_kill(&ubc->sent_tasklet);
+       tasklet_kill(&ubc->rcvd_tasklet);
+       kfree(ubc->isooutbuf);
+       kfree(ubc);
        bcs->hw.bas = NULL;
        return 1;
 }
@@ -1931,13 +1995,9 @@ static void gigaset_reinitbcshw(struct bc_state *bcs)
 
 static void gigaset_freecshw(struct cardstate *cs)
 {
-       struct bas_cardstate *ucs = cs->hw.bas;
-
-       del_timer(&ucs->timer_ctrl);
-       del_timer(&ucs->timer_atrdy);
-       del_timer(&ucs->timer_cmd_in);
-
+       /* timers, URBs and rcvbuf are disposed of in disconnect */
        kfree(cs->hw.bas);
+       cs->hw.bas = NULL;
 }
 
 static int gigaset_initcshw(struct cardstate *cs)
@@ -2041,23 +2101,13 @@ static int gigaset_probe(struct usb_interface *interface,
        struct bas_bc_state *ubc;
        struct usb_endpoint_descriptor *endpoint;
        int i, j;
-       int ret;
+       int rc;
 
        gig_dbg(DEBUG_ANY,
                "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)",
                __func__, le16_to_cpu(udev->descriptor.idVendor),
                le16_to_cpu(udev->descriptor.idProduct));
 
-       /* See if the device offered us matches what we can accept */
-       if ((le16_to_cpu(udev->descriptor.idVendor)  != USB_GIGA_VENDOR_ID) ||
-           (le16_to_cpu(udev->descriptor.idProduct) != USB_GIGA_PRODUCT_ID &&
-            le16_to_cpu(udev->descriptor.idProduct) != USB_4175_PRODUCT_ID &&
-            le16_to_cpu(udev->descriptor.idProduct) != USB_SX303_PRODUCT_ID &&
-            le16_to_cpu(udev->descriptor.idProduct) != USB_SX353_PRODUCT_ID)) {
-               gig_dbg(DEBUG_ANY, "%s: unmatched ID - exiting", __func__);
-               return -ENODEV;
-       }
-
        /* set required alternate setting */
        hostif = interface->cur_altsetting;
        if (hostif->desc.bAlternateSetting != 3) {
@@ -2105,45 +2155,22 @@ static int gigaset_probe(struct usb_interface *interface,
         * - three for the different uses of the default control pipe
         * - three for each isochronous pipe
         */
-       ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL);
-       if (!ucs->urb_int_in) {
-               dev_err(cs->dev, "no free urbs available\n");
-               goto error;
-       }
-       ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL);
-       if (!ucs->urb_cmd_in) {
-               dev_err(cs->dev, "no free urbs available\n");
-               goto error;
-       }
-       ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL);
-       if (!ucs->urb_cmd_out) {
-               dev_err(cs->dev, "no free urbs available\n");
-               goto error;
-       }
-       ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL);
-       if (!ucs->urb_ctrl) {
-               dev_err(cs->dev, "no free urbs available\n");
-               goto error;
-       }
+       if (!(ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL)) ||
+           !(ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL)) ||
+           !(ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL)) ||
+           !(ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL)))
+               goto allocerr;
 
        for (j = 0; j < 2; ++j) {
                ubc = cs->bcs[j].hw.bas;
-               for (i = 0; i < BAS_OUTURBS; ++i) {
-                       ubc->isoouturbs[i].urb =
-                               usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL);
-                       if (!ubc->isoouturbs[i].urb) {
-                               dev_err(cs->dev, "no free urbs available\n");
-                               goto error;
-                       }
-               }
-               for (i = 0; i < BAS_INURBS; ++i) {
-                       ubc->isoinurbs[i] =
-                               usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL);
-                       if (!ubc->isoinurbs[i]) {
-                               dev_err(cs->dev, "no free urbs available\n");
-                               goto error;
-                       }
-               }
+               for (i = 0; i < BAS_OUTURBS; ++i)
+                       if (!(ubc->isoouturbs[i].urb =
+                             usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL)))
+                               goto allocerr;
+               for (i = 0; i < BAS_INURBS; ++i)
+                       if (!(ubc->isoinurbs[i] =
+                             usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL)))
+                               goto allocerr;
        }
 
        ucs->rcvbuf = NULL;
@@ -2156,15 +2183,14 @@ static int gigaset_probe(struct usb_interface *interface,
                                        (endpoint->bEndpointAddress) & 0x0f),
                         ucs->int_in_buf, 3, read_int_callback, cs,
                         endpoint->bInterval);
-       ret = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL);
-       if (ret) {
+       if ((rc = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL)) != 0) {
                dev_err(cs->dev, "could not submit interrupt URB: %s\n",
-                       get_usb_statmsg(ret));
+                       get_usb_rcmsg(rc));
                goto error;
        }
 
        /* tell the device that the driver is ready */
-       if ((ret = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0)) != 0)
+       if ((rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0)) != 0)
                goto error;
 
        /* tell common part that the device is ready */
@@ -2179,6 +2205,8 @@ static int gigaset_probe(struct usb_interface *interface,
 
        return 0;
 
+allocerr:
+       dev_err(cs->dev, "could not allocate URBs\n");
 error:
        freeurbs(cs);
        usb_set_intfdata(interface, NULL);
@@ -2193,19 +2221,34 @@ static void gigaset_disconnect(struct usb_interface *interface)
 {
        struct cardstate *cs;
        struct bas_cardstate *ucs;
+       int j;
 
        cs = usb_get_intfdata(interface);
 
        ucs = cs->hw.bas;
 
        dev_info(cs->dev, "disconnecting Gigaset base\n");
+
+       /* mark base as not ready, all channels disconnected */
+       atomic_set(&ucs->basstate, 0);
+
+       /* tell LL all channels are down */
+       //FIXME shouldn't gigaset_stop() do this?
+       for (j = 0; j < 2; ++j)
+               gigaset_bchannel_down(cs->bcs + j);
+
+       /* stop driver (common part) */
        gigaset_stop(cs);
+
+       /* stop timers and URBs, free ressources */
+       del_timer_sync(&ucs->timer_ctrl);
+       del_timer_sync(&ucs->timer_atrdy);
+       del_timer_sync(&ucs->timer_cmd_in);
        freeurbs(cs);
        usb_set_intfdata(interface, NULL);
        kfree(ucs->rcvbuf);
        ucs->rcvbuf = NULL;
        ucs->rcvbuf_size = 0;
-       atomic_set(&ucs->basstate, 0);
        usb_put_dev(ucs->udev);
        ucs->interface = NULL;
        ucs->udev = NULL;
@@ -2277,6 +2320,8 @@ error:    if (cardstate)
  */
 static void __exit bas_gigaset_exit(void)
 {
+       struct bas_cardstate *ucs = cardstate->hw.bas;
+
        gigaset_blockdriver(driver); /* => probe will fail
                                      * => no gigaset_start any more
                                      */
@@ -2284,14 +2329,26 @@ static void __exit bas_gigaset_exit(void)
        gigaset_shutdown(cardstate);
        /* from now on, no isdn callback should be possible */
 
-       if (atomic_read(&cardstate->hw.bas->basstate) & BS_ATOPEN) {
-               gig_dbg(DEBUG_ANY, "closing AT channel");
-               if (req_submit(cardstate->bcs,
-                              HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT) >= 0) {
-                       /* successfully submitted */
-                       //FIXME wait for completion?
-               }
+       /* close all still open channels */
+       if (atomic_read(&ucs->basstate) & BS_B1OPEN) {
+               gig_dbg(DEBUG_INIT, "closing B1 channel");
+               usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0),
+                               HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ, 0, 0,
+                               NULL, 0, BAS_TIMEOUT);
+       }
+       if (atomic_read(&ucs->basstate) & BS_B2OPEN) {
+               gig_dbg(DEBUG_INIT, "closing B2 channel");
+               usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0),
+                               HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ, 0, 0,
+                               NULL, 0, BAS_TIMEOUT);
+       }
+       if (atomic_read(&ucs->basstate) & BS_ATOPEN) {
+               gig_dbg(DEBUG_INIT, "closing AT channel");
+               usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0),
+                               HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ, 0, 0,
+                               NULL, 0, BAS_TIMEOUT);
        }
+       atomic_set(&ucs->basstate, 0);
 
        /* deregister this driver with the USB subsystem */
        usb_deregister(&gigaset_usb_driver);
index 749b3da1236e382e4ee2840f7d3e89da6bcd2e44..e55767b2ccd3cc8d3f8fab741aec3e37a900b8bf 100644 (file)
@@ -781,8 +781,7 @@ error:      if (cs)
 }
 EXPORT_SYMBOL_GPL(gigaset_initcs);
 
-/* ReInitialize the b-channel structure */
-/* e.g. called on hangup, disconnect */
+/* ReInitialize the b-channel structure on hangup */
 void gigaset_bcs_reinit(struct bc_state *bcs)
 {
        struct sk_buff *skb;
index 1ba3424a286b6fc7aa3a0896ea36749a249b7e5d..18e05c09b71c9b46022ab6da87712e2d46ab7aae 100644 (file)
@@ -373,6 +373,9 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */
 
        {EV_TIMEOUT,  750,750, -1,                  0, 0, {ACT_CONNTIMEOUT}},
 
+       /* B channel closed (general case) */
+       {EV_BC_CLOSED, -1, -1, -1,                 -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME
+
        /* misc. */
        {EV_PROTO_L2,  -1, -1, -1,                 -1,-1, {ACT_PROTO_L2}}, //FIXME
 
index 9d21ba8757b04ea6b97c104739d8eb7191596e18..22b9693f7c0a1623d007d77b492fb746cb32d157 100644 (file)
@@ -75,7 +75,7 @@ extern int gigaset_debuglevel;        /* "needs" cast to (enum debuglevel) */
  * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and
  * DEBUG_INTR.
  */
-enum debuglevel { /* up to 24 bits (atomic_t) */
+enum debuglevel {
        DEBUG_REG         = 0x0002, /* serial port I/O register operations */
        DEBUG_OPEN        = 0x0004, /* open/close serial port */
        DEBUG_INTR        = 0x0008, /* interrupt processing */
@@ -141,7 +141,7 @@ enum debuglevel { /* up to 24 bits (atomic_t) */
                        printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \
                               ## arg); \
        } while (0)
-#define DEBUG_DEFAULT (DEBUG_INIT | DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ)
+#define DEBUG_DEFAULT (DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ)
 
 #else
 
@@ -627,8 +627,7 @@ struct gigaset_ops {
        /* Called by gigaset_freecs() for freeing bcs->hw.xxx */
        int (*freebcshw)(struct bc_state *bcs);
 
-       /* Called by gigaset_stop() or gigaset_bchannel_down() for resetting
-          bcs->hw.xxx */
+       /* Called by gigaset_bchannel_down() for resetting bcs->hw.xxx */
        void (*reinitbcshw)(struct bc_state *bcs);
 
        /* Called by gigaset_initcs() for setting up cs->hw.xxx */
index 0815dbfb8291119f6beb58558cdd9290d66c9128..1654fa41357553c2287ed5ba8cf9108187cd2191 100644 (file)
@@ -73,7 +73,7 @@ static int writebuf_from_LL(int driverID, int channel, int ack,
                len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]);
 
        /* pass to device-specific module */
-       return cs->ops->send_skb(bcs, skb); //FIXME cs->ops->send_skb() must handle !cs->connected correctly
+       return cs->ops->send_skb(bcs, skb);
 }
 
 void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb)
index 45f017ed6e8caf093bca94fc9422c9bb87cafff5..8667daaa1a82e74eb74af3704ea4021e283c50e6 100644 (file)
@@ -992,14 +992,18 @@ int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb)
        int len = skb->len;
        unsigned long flags;
 
+       spin_lock_irqsave(&bcs->cs->lock, flags);
+       if (!bcs->cs->connected) {
+               spin_unlock_irqrestore(&bcs->cs->lock, flags);
+               return -ENODEV;
+       }
+
        skb_queue_tail(&bcs->squeue, skb);
        gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d",
                __func__, skb_queue_len(&bcs->squeue));
 
        /* tasklet submits URB if necessary */
-       spin_lock_irqsave(&bcs->cs->lock, flags);
-       if (bcs->cs->connected)
-               tasklet_schedule(&bcs->hw.bas->sent_tasklet);
+       tasklet_schedule(&bcs->hw.bas->sent_tasklet);
        spin_unlock_irqrestore(&bcs->cs->lock, flags);
 
        return len;     /* ok so far */
index 5ebfd1d138dafc027d3c1c0ed37f926e010f0834..5282fec17075be859759a29c0eeb8662603f016e 100644 (file)
@@ -627,8 +627,8 @@ thermostat_init(void)
        if(therm_type == ADT7460)
                device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed);
 
-#ifndef CONFIG_I2C_KEYWEST
-       request_module("i2c-keywest");
+#ifndef CONFIG_I2C_POWERMAC
+       request_module("i2c-powermac");
 #endif
 
        return i2c_add_driver(&thermostat_driver);
index 434ca39d19c1d7b7dfb40c1163cb8281a52aeefb..d7316b829a62687a4c29372a893d2684121fb3a3 100644 (file)
@@ -279,11 +279,6 @@ static inline int mddev_lock(mddev_t * mddev)
        return mutex_lock_interruptible(&mddev->reconfig_mutex);
 }
 
-static inline void mddev_lock_uninterruptible(mddev_t * mddev)
-{
-       mutex_lock(&mddev->reconfig_mutex);
-}
-
 static inline int mddev_trylock(mddev_t * mddev)
 {
        return mutex_trylock(&mddev->reconfig_mutex);
@@ -2458,9 +2453,11 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page)
 
        if (!entry->show)
                return -EIO;
-       mddev_lock(mddev);
-       rv = entry->show(mddev, page);
-       mddev_unlock(mddev);
+       rv = mddev_lock(mddev);
+       if (!rv) {
+               rv = entry->show(mddev, page);
+               mddev_unlock(mddev);
+       }
        return rv;
 }
 
@@ -2474,9 +2471,11 @@ md_attr_store(struct kobject *kobj, struct attribute *attr,
 
        if (!entry->store)
                return -EIO;
-       mddev_lock(mddev);
-       rv = entry->store(mddev, page, length);
-       mddev_unlock(mddev);
+       rv = mddev_lock(mddev);
+       if (!rv) {
+               rv = entry->store(mddev, page, length);
+               mddev_unlock(mddev);
+       }
        return rv;
 }
 
@@ -4341,8 +4340,9 @@ static int md_seq_show(struct seq_file *seq, void *v)
                return 0;
        }
 
-       if (mddev_lock(mddev)!=0) 
+       if (mddev_lock(mddev) < 0)
                return -EINTR;
+
        if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) {
                seq_printf(seq, "%s : %sactive", mdname(mddev),
                                                mddev->pers ? "" : "in");
index 08b218c5bfbc372186f8102a4d112cedde2ea938..93c494bcd18d67beaf035473f37a77dd7c45171b 100644 (file)
@@ -226,7 +226,7 @@ struct net_device * __init ne_probe(int unit)
        netdev_boot_setup_check(dev);
 
 #ifdef CONFIG_TOSHIBA_RBTX4938
-       dev->base_addr = 0x07f20280;
+       dev->base_addr = RBTX4938_RTL_8019_BASE;
        dev->irq = RBTX4938_RTL_8019_IRQ;
 #endif
        err = do_ne_probe(dev);
index cb0aba95d4e32c56a339c979a24340d3b1954d55..046371ee5bbe25a5d98da69f6ff28612c9dc959d 100644 (file)
@@ -275,7 +275,7 @@ static int bcm5411_init(struct mii_phy* phy)
        return 0;
 }
 
-static int bcm5411_suspend(struct mii_phy* phy)
+static int generic_suspend(struct mii_phy* phy)
 {
        phy_write(phy, MII_BMCR, BMCR_PDOWN);
 
@@ -738,7 +738,7 @@ static struct mii_phy_def bcm5401_phy_def = {
 /* Broadcom BCM 5411 */
 static struct mii_phy_ops bcm5411_phy_ops = {
        .init           = bcm5411_init,
-       .suspend        = bcm5411_suspend,
+       .suspend        = generic_suspend,
        .setup_aneg     = bcm54xx_setup_aneg,
        .setup_forced   = bcm54xx_setup_forced,
        .poll_link      = genmii_poll_link,
@@ -757,7 +757,7 @@ static struct mii_phy_def bcm5411_phy_def = {
 /* Broadcom BCM 5421 */
 static struct mii_phy_ops bcm5421_phy_ops = {
        .init           = bcm5421_init,
-       .suspend        = bcm5411_suspend,
+       .suspend        = generic_suspend,
        .setup_aneg     = bcm54xx_setup_aneg,
        .setup_forced   = bcm54xx_setup_forced,
        .poll_link      = genmii_poll_link,
@@ -776,7 +776,7 @@ static struct mii_phy_def bcm5421_phy_def = {
 /* Broadcom BCM 5421 built-in K2 */
 static struct mii_phy_ops bcm5421k2_phy_ops = {
        .init           = bcm5421_init,
-       .suspend        = bcm5411_suspend,
+       .suspend        = generic_suspend,
        .setup_aneg     = bcm54xx_setup_aneg,
        .setup_forced   = bcm54xx_setup_forced,
        .poll_link      = genmii_poll_link,
@@ -795,7 +795,7 @@ static struct mii_phy_def bcm5421k2_phy_def = {
 /* Broadcom BCM 5462 built-in Vesta */
 static struct mii_phy_ops bcm5462V_phy_ops = {
        .init           = bcm5421_init,
-       .suspend        = bcm5411_suspend,
+       .suspend        = generic_suspend,
        .setup_aneg     = bcm54xx_setup_aneg,
        .setup_forced   = bcm54xx_setup_forced,
        .poll_link      = genmii_poll_link,
@@ -816,6 +816,7 @@ static struct mii_phy_def bcm5462V_phy_def = {
  * would be useful here) --BenH.
  */
 static struct mii_phy_ops marvell_phy_ops = {
+       .suspend        = generic_suspend,
        .setup_aneg     = marvell_setup_aneg,
        .setup_forced   = marvell_setup_forced,
        .poll_link      = genmii_poll_link,
index bad09ebdb50b9622d6b635a9301a886d98d878f5..e0874cbfefea36ff0a16b8943437f9b9f2ed5a67 100644 (file)
@@ -6,7 +6,7 @@ menu "Wireless LAN (non-hamradio)"
        depends on NETDEVICES
 
 config NET_RADIO
-       bool "Wireless LAN drivers (non-hamradio)"
+       bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions"
        select WIRELESS_EXT
        ---help---
          Support for wireless LANs and everything having to do with radio,
index 108d9fed8f0761f2487b8505c85f8c959bc47794..00764ddd74d8fc5593339107cd149fac3fec8ed1 100644 (file)
@@ -3139,6 +3139,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
                }
                if ( status & EV_LINK ) {
                        union iwreq_data        wrqu;
+                       int scan_forceloss = 0;
                        /* The link status has changed, if you want to put a
                           monitor hook in, do it here.  (Remember that
                           interrupts are still disabled!)
@@ -3157,7 +3158,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
                          code) */
 #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason
                           code) */
-#define ASSOCIATED 0x0400 /* Assocatied */
+#define ASSOCIATED 0x0400 /* Associated */
+#define REASSOCIATED 0x0600 /* Reassociated?  Only on firmware >= 5.30.17 */
 #define RC_RESERVED 0 /* Reserved return code */
 #define RC_NOREASON 1 /* Unspecified reason */
 #define RC_AUTHINV 2 /* Previous authentication invalid */
@@ -3174,44 +3176,30 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs)
                          leaving BSS */
 #define RC_NOAUTH 9 /* Station requesting (Re)Association is not
                       Authenticated with the responding station */
-                       if (newStatus != ASSOCIATED) {
-                               if (auto_wep && !apriv->expires) {
-                                       apriv->expires = RUN_AT(3*HZ);
-                                       wake_up_interruptible(&apriv->thr_wait);
-                               }
-                       } else {
-                               struct task_struct *task = apriv->task;
+                       if (newStatus == FORCELOSS && apriv->scan_timeout > 0)
+                               scan_forceloss = 1;
+                       if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) {
                                if (auto_wep)
                                        apriv->expires = 0;
-                               if (task)
-                                       wake_up_process (task);
+                               if (apriv->task)
+                                       wake_up_process (apriv->task);
                                set_bit(FLAG_UPDATE_UNI, &apriv->flags);
                                set_bit(FLAG_UPDATE_MULTI, &apriv->flags);
-                       }
-                       /* Question : is ASSOCIATED the only status
-                        * that is valid ? We want to catch handover
-                        * and reassociations as valid status
-                        * Jean II */
-                       if(newStatus == ASSOCIATED) {
-#if 0
-                               /* FIXME: Grabbing scan results here
-                                * seems to be too early???  Just wait for
-                                * timeout instead. */
-                               if (apriv->scan_timeout > 0) {
-                                       set_bit(JOB_SCAN_RESULTS, &apriv->flags);
-                                       wake_up_interruptible(&apriv->thr_wait);
-                               }
-#endif
+
                                if (down_trylock(&apriv->sem) != 0) {
                                        set_bit(JOB_EVENT, &apriv->flags);
                                        wake_up_interruptible(&apriv->thr_wait);
                                } else
                                        airo_send_event(dev);
-                       } else {
-                               memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
-                               wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                       } else if (!scan_forceloss) {
+                               if (auto_wep && !apriv->expires) {
+                                       apriv->expires = RUN_AT(3*HZ);
+                                       wake_up_interruptible(&apriv->thr_wait);
+                               }
 
                                /* Send event to user space */
+                               memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
+                               wrqu.ap_addr.sa_family = ARPHRD_ETHER;
                                wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL);
                        }
                }
@@ -7136,10 +7124,10 @@ static int airo_set_scan(struct net_device *dev,
                goto out;
 
        /* Initiate a scan command */
+       ai->scan_timeout = RUN_AT(3*HZ);
        memset(&cmd, 0, sizeof(cmd));
        cmd.cmd=CMD_LISTBSS;
        issuecommand(ai, &cmd, &rsp);
-       ai->scan_timeout = RUN_AT(3*HZ);
        wake = 1;
 
 out:
index 87afa6878f26c98a79e8800982a2f7ae8bfb20ed..8606c88886fca9237fd8b3f4bd774fca8aa7e02c 100644 (file)
@@ -3463,6 +3463,7 @@ static void atmel_command_irq(struct atmel_private *priv)
        u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET));
        u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET));
        int fast_scan;
+       union iwreq_data wrqu;
 
        if (status == CMD_STATUS_IDLE ||
            status == CMD_STATUS_IN_PROGRESS)
@@ -3487,6 +3488,7 @@ static void atmel_command_irq(struct atmel_private *priv)
                        atmel_scan(priv, 1);
                } else {
                        int bss_index = retrieve_bss(priv);
+                       int notify_scan_complete = 1;
                        if (bss_index != -1) {
                                atmel_join_bss(priv, bss_index);
                        } else if (priv->operating_mode == IW_MODE_ADHOC &&
@@ -3495,8 +3497,14 @@ static void atmel_command_irq(struct atmel_private *priv)
                        } else {
                                priv->fast_scan = !fast_scan;
                                atmel_scan(priv, 1);
+                               notify_scan_complete = 0;
                        }
                        priv->site_survey_state = SITE_SURVEY_COMPLETED;
+                       if (notify_scan_complete) {
+                               wrqu.data.length = 0;
+                               wrqu.data.flags = 0;
+                               wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
+                       }
                }
                break;
 
@@ -3509,6 +3517,9 @@ static void atmel_command_irq(struct atmel_private *priv)
                priv->site_survey_state = SITE_SURVEY_COMPLETED;
                if (priv->station_is_associated) {
                        atmel_enter_state(priv, STATION_STATE_READY);
+                       wrqu.data.length = 0;
+                       wrqu.data.flags = 0;
+                       wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL);
                } else {
                        atmel_scan(priv, 1);
                }
index 418465600a77e8dd491ac6fee0d95255190013ce..25ea4748f0b9a3ea3d800e84c1bc395dd04c371c 100644 (file)
@@ -17,8 +17,11 @@ config BCM43XX_DEBUG
 
 config BCM43XX_DMA
        bool
+       depends on BCM43XX
+
 config BCM43XX_PIO
        bool
+       depends on BCM43XX
 
 choice
        prompt "BCM43xx data transfer mode"
index dcadd295de4f6fa42aeb51d85e6a2286eb1bfa64..2e83083935e1d9bd90570975c5cb771b62055a1e 100644 (file)
@@ -15,7 +15,6 @@
 
 #include "bcm43xx_debugfs.h"
 #include "bcm43xx_leds.h"
-#include "bcm43xx_sysfs.h"
 
 
 #define PFX                            KBUILD_MODNAME ": "
@@ -638,8 +637,6 @@ struct bcm43xx_key {
 };
 
 struct bcm43xx_private {
-       struct bcm43xx_sysfs sysfs;
-
        struct ieee80211_device *ieee;
        struct ieee80211softmac_device *softmac;
 
@@ -772,6 +769,20 @@ struct bcm43xx_private * bcm43xx_priv(struct net_device *dev)
        return ieee80211softmac_priv(dev);
 }
 
+struct device;
+
+static inline
+struct bcm43xx_private * dev_to_bcm(struct device *dev)
+{
+       struct net_device *net_dev;
+       struct bcm43xx_private *bcm;
+
+       net_dev = dev_get_drvdata(dev);
+       bcm = bcm43xx_priv(net_dev);
+
+       return bcm;
+}
+
 
 /* Helper function, which returns a boolean.
  * TRUE, if PIO is used; FALSE, if DMA is used.
index d2c3401e9b70438fba9cb46f6794d115fdca8c41..35a4fcb6d9233bc0887255ccc30ab08d336f9599 100644 (file)
@@ -452,12 +452,12 @@ void bcm43xx_printk_dump(const char *data,
        size_t i;
        char c;
 
-       printk(KERN_INFO PFX "Data dump (%s, %u bytes):",
+       printk(KERN_INFO PFX "Data dump (%s, %zd bytes):",
               description, size);
        for (i = 0; i < size; i++) {
                c = data[i];
                if (i % 8 == 0)
-                       printk("\n" KERN_INFO PFX "0x%08x:  0x%02x, ", i, c & 0xff);
+                       printk("\n" KERN_INFO PFX "0x%08zx:  0x%02x, ", i, c & 0xff);
                else
                        printk("0x%02x, ", c & 0xff);
        }
@@ -472,12 +472,12 @@ void bcm43xx_printk_bitdump(const unsigned char *data,
        int j;
        const unsigned char *d;
 
-       printk(KERN_INFO PFX "*** Bitdump (%s, %u bytes, %s) ***",
+       printk(KERN_INFO PFX "*** Bitdump (%s, %zd bytes, %s) ***",
               description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB");
        for (i = 0; i < bytes; i++) {
                d = data + i;
                if (i % 8 == 0)
-                       printk("\n" KERN_INFO PFX "0x%08x:  ", i);
+                       printk("\n" KERN_INFO PFX "0x%08zx:  ", i);
                if (msb_to_lsb) {
                        for (j = 7; j >= 0; j--) {
                                if (*d & (1 << j))
index c3681b8f09b42f81cf2d4848c1a12c03fa7856c1..bbecba02e69775671187f84b9e19611f9c00fe19 100644 (file)
@@ -196,8 +196,9 @@ static int alloc_ringmemory(struct bcm43xx_dmaring *ring)
        }
        if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) {
                printk(KERN_ERR PFX ">>>FATAL ERROR<<<  DMA RINGMEMORY >1G "
-                                   "(0x%08x, len: %lu)\n",
-                      ring->dmabase, BCM43xx_DMA_RINGMEMSIZE);
+                                   "(0x%llx, len: %lu)\n",
+                               (unsigned long long)ring->dmabase,
+                               BCM43xx_DMA_RINGMEMSIZE);
                dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
                                  ring->vbase, ring->dmabase);
                return -ENOMEM;
@@ -307,8 +308,8 @@ static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
                unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
                dev_kfree_skb_any(skb);
                printk(KERN_ERR PFX ">>>FATAL ERROR<<<  DMA RX SKB >1G "
-                                   "(0x%08x, len: %u)\n",
-                      dmaaddr, ring->rx_buffersize);
+                                   "(0x%llx, len: %u)\n",
+                       (unsigned long long)dmaaddr, ring->rx_buffersize);
                return -ENOMEM;
        }
        meta->skb = skb;
@@ -729,8 +730,8 @@ static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
        if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) {
                return_slot(ring, slot);
                printk(KERN_ERR PFX ">>>FATAL ERROR<<<  DMA TX SKB >1G "
-                                   "(0x%08x, len: %u)\n",
-                      meta->dmaaddr, skb->len);
+                                   "(0x%llx, len: %u)\n",
+                       (unsigned long long)meta->dmaaddr, skb->len);
                return -ENOMEM;
        }
 
index c37371fc9e01a4c818f2402606d9aa9739c764a7..9a06e61df0a253c4fed8e0df22af350e8979e58f 100644 (file)
@@ -52,6 +52,7 @@
 #include "bcm43xx_wx.h"
 #include "bcm43xx_ethtool.h"
 #include "bcm43xx_xmit.h"
+#include "bcm43xx_sysfs.h"
 
 
 MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver");
@@ -3522,6 +3523,7 @@ static inline int bcm43xx_tx(struct bcm43xx_private *bcm,
                err = bcm43xx_pio_tx(bcm, txb);
        else
                err = bcm43xx_dma_tx(bcm, txb);
+       bcm->net_dev->trans_start = jiffies;
 
        return err;
 }
index 0a66f43ca0c01a1089fccaa3b66bf1bb28661c0e..33137165727f7c69c054a9507324beda7fcd2830 100644 (file)
@@ -2151,6 +2151,7 @@ int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm)
                                phy->tssi2dbm = NULL;
                                printk(KERN_ERR PFX "Could not generate "
                                                    "tssi2dBm table\n");
+                               kfree(dyn_tssi2dbm);
                                return -ENODEV;
                        }
                phy->tssi2dbm = dyn_tssi2dbm;
index 3c92b62807c56afafd5a88a04b8ab8d3f29ccdbb..6569da3a7a395987f8be1e5a6a285580343066fa 100644 (file)
 #include "bcm43xx_main.h"
 
 
+/* Get the Slow Clock Source */
+static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm)
+{
+       u32 tmp;
+       int err;
+
+       assert(bcm->current_core == &bcm->core_chipcommon);
+       if (bcm->current_core->rev < 6) {
+               if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA ||
+                   bcm->bustype == BCM43xx_BUSTYPE_SB)
+                       return BCM43xx_PCTL_CLKSRC_XTALOS;
+               if (bcm->bustype == BCM43xx_BUSTYPE_PCI) {
+                       err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
+                       assert(!err);
+                       if (tmp & 0x10)
+                               return BCM43xx_PCTL_CLKSRC_PCI;
+                       return BCM43xx_PCTL_CLKSRC_XTALOS;
+               }
+       }
+       if (bcm->current_core->rev < 10) {
+               tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
+               tmp &= 0x7;
+               if (tmp == 0)
+                       return BCM43xx_PCTL_CLKSRC_LOPWROS;
+               if (tmp == 1)
+                       return BCM43xx_PCTL_CLKSRC_XTALOS;
+               if (tmp == 2)
+                       return BCM43xx_PCTL_CLKSRC_PCI;
+       }
+
+       return BCM43xx_PCTL_CLKSRC_XTALOS;
+}
+
 /* Get max/min slowclock frequency
  * as described in http://bcm-specs.sipsolutions.net/PowerControl
  */
 static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm,
                                       int get_max)
 {
-       int limit = 0;
+       int limit;
+       int clocksrc;
        int divisor;
-       int selection;
-       int err;
        u32 tmp;
-       struct bcm43xx_coreinfo *old_core;
 
-       if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL))
-               goto out;
-       old_core = bcm->current_core;
-       err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon);
-       if (err)
-               goto out;
+       assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL);
+       assert(bcm->current_core == &bcm->core_chipcommon);
 
+       clocksrc = bcm43xx_pctl_get_slowclksrc(bcm);
        if (bcm->current_core->rev < 6) {
-               if ((bcm->bustype == BCM43xx_BUSTYPE_PCMCIA) ||
-                       (bcm->bustype == BCM43xx_BUSTYPE_SB)) {
-                       selection = 1;
+               switch (clocksrc) {
+               case BCM43xx_PCTL_CLKSRC_PCI:
+                       divisor = 64;
+                       break;
+               case BCM43xx_PCTL_CLKSRC_XTALOS:
                        divisor = 32;
-               } else {
-                       err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp);
-                       if (err) {
-                               printk(KERN_ERR PFX "clockfreqlimit pcicfg read failure\n");
-                               goto out_switchback;
-                       }
-                       if (tmp & 0x10) {
-                               /* PCI */
-                               selection = 2;
-                               divisor = 64;
-                       } else {
-                               /* XTAL */
-                               selection = 1;
-                               divisor = 32;
-                       }
+                       break;
+               default:
+                       assert(0);
+                       divisor = 1;
                }
        } else if (bcm->current_core->rev < 10) {
-               selection = (tmp & 0x07);
-               if (selection) {
+               switch (clocksrc) {
+               case BCM43xx_PCTL_CLKSRC_LOPWROS:
+                       divisor = 1;
+                       break;
+               case BCM43xx_PCTL_CLKSRC_XTALOS:
+               case BCM43xx_PCTL_CLKSRC_PCI:
                        tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL);
-                       divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16));
-               } else
+                       divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
+                       divisor *= 4;
+                       break;
+               default:
+                       assert(0);
                        divisor = 1;
+               }
        } else {
                tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL);
-               divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16));
-               selection = 1;
+               divisor = ((tmp & 0xFFFF0000) >> 16) + 1;
+               divisor *= 4;
        }
-       
-       switch (selection) {
-       case 0:
-               /* LPO */
+
+       switch (clocksrc) {
+       case BCM43xx_PCTL_CLKSRC_LOPWROS:
                if (get_max)
                        limit = 43000;
                else
                        limit = 25000;
                break;
-       case 1:
-               /* XTAL */
+       case BCM43xx_PCTL_CLKSRC_XTALOS:
                if (get_max)
                        limit = 20200000;
                else
                        limit = 19800000;
                break;
-       case 2:
-               /* PCI */
+       case BCM43xx_PCTL_CLKSRC_PCI:
                if (get_max)
                        limit = 34000000;
                else
@@ -113,17 +137,14 @@ static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm,
                break;
        default:
                assert(0);
+               limit = 0;
        }
        limit /= divisor;
 
-out_switchback:
-       err = bcm43xx_switch_core(bcm, old_core);
-       assert(err == 0);
-
-out:
        return limit;
 }
 
+
 /* init power control
  * as described in http://bcm-specs.sipsolutions.net/PowerControl
  */
index 5f63640810bdc01302d85dc734645b6b7ff3061b..c966ab3a5a8c9f806a7dcb8dd2cb4db910c873e0 100644 (file)
 
 #include <linux/types.h>
 
+/* Clock sources */
+enum {
+       /* PCI clock */
+       BCM43xx_PCTL_CLKSRC_PCI,
+       /* Crystal slow clock oscillator */
+       BCM43xx_PCTL_CLKSRC_XTALOS,
+       /* Low power oscillator */
+       BCM43xx_PCTL_CLKSRC_LOPWROS,
+};
 
 struct bcm43xx_private;
 
index c44d890b949b149f5346ea7d0205f2bd08b3fd12..b438f48e891d185c2933828ee2b9080de3097564 100644 (file)
@@ -71,14 +71,46 @@ static int get_boolean(const char *buf, size_t count)
        return -EINVAL;
 }
 
+static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len)
+{
+       int i, pos = 0;
+
+       for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
+               pos += snprintf(buf + pos, buf_len - pos - 1,
+                               "%04X", swab16(sprom[i]) & 0xFFFF);
+       }
+       pos += snprintf(buf + pos, buf_len - pos - 1, "\n");
+
+       return pos + 1;
+}
+
+static int hex2sprom(u16 *sprom, const char *dump, size_t len)
+{
+       char tmp[5] = { 0 };
+       int cnt = 0;
+       unsigned long parsed;
+
+       if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2)
+               return -EINVAL;
+
+       while (cnt < BCM43xx_SPROM_SIZE) {
+               memcpy(tmp, dump, 4);
+               dump += 4;
+               parsed = simple_strtoul(tmp, NULL, 16);
+               sprom[cnt++] = swab16((u16)parsed);
+       }
+
+       return 0;
+}
+
 static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
                                       struct device_attribute *attr,
                                       char *buf)
 {
-       struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom);
+       struct bcm43xx_private *bcm = dev_to_bcm(dev);
        u16 *sprom;
        unsigned long flags;
-       int i, err;
+       int err;
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
@@ -91,55 +123,53 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev,
        bcm43xx_lock_mmio(bcm, flags);
        assert(bcm->initialized);
        err = bcm43xx_sprom_read(bcm, sprom);
-       if (!err) {
-               for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
-                       buf[i * 2] = sprom[i] & 0x00FF;
-                       buf[i * 2 + 1] = (sprom[i] & 0xFF00) >> 8;
-               }
-       }
+       if (!err)
+               err = sprom2hex(sprom, buf, PAGE_SIZE);
        bcm43xx_unlock_mmio(bcm, flags);
        kfree(sprom);
 
-       return err ? err : BCM43xx_SPROM_SIZE * sizeof(u16);
+       return err;
 }
 
 static ssize_t bcm43xx_attr_sprom_store(struct device *dev,
                                        struct device_attribute *attr,
                                        const char *buf, size_t count)
 {
-       struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom);
+       struct bcm43xx_private *bcm = dev_to_bcm(dev);
        u16 *sprom;
        unsigned long flags;
-       int i, err;
+       int err;
 
        if (!capable(CAP_NET_ADMIN))
                return -EPERM;
 
-       if (count != BCM43xx_SPROM_SIZE * sizeof(u16))
-               return -EINVAL;
        sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom),
                        GFP_KERNEL);
        if (!sprom)
                return -ENOMEM;
-       for (i = 0; i < BCM43xx_SPROM_SIZE; i++) {
-               sprom[i] = buf[i * 2] & 0xFF;
-               sprom[i] |= ((u16)(buf[i * 2 + 1] & 0xFF)) << 8;
-       }
+       err = hex2sprom(sprom, buf, count);
+       if (err)
+               goto out_kfree;
        bcm43xx_lock_mmio(bcm, flags);
        assert(bcm->initialized);
        err = bcm43xx_sprom_write(bcm, sprom);
        bcm43xx_unlock_mmio(bcm, flags);
+out_kfree:
        kfree(sprom);
 
        return err ? err : count;
 
 }
 
+static DEVICE_ATTR(sprom, 0600,
+                  bcm43xx_attr_sprom_show,
+                  bcm43xx_attr_sprom_store);
+
 static ssize_t bcm43xx_attr_interfmode_show(struct device *dev,
                                            struct device_attribute *attr,
                                            char *buf)
 {
-       struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode);
+       struct bcm43xx_private *bcm = dev_to_bcm(dev);
        unsigned long flags;
        int err;
        ssize_t count = 0;
@@ -175,7 +205,7 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
                                             struct device_attribute *attr,
                                             const char *buf, size_t count)
 {
-       struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode);
+       struct bcm43xx_private *bcm = dev_to_bcm(dev);
        unsigned long flags;
        int err;
        int mode;
@@ -215,11 +245,15 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev,
        return err ? err : count;
 }
 
+static DEVICE_ATTR(interference, 0644,
+                  bcm43xx_attr_interfmode_show,
+                  bcm43xx_attr_interfmode_store);
+
 static ssize_t bcm43xx_attr_preamble_show(struct device *dev,
                                          struct device_attribute *attr,
                                          char *buf)
 {
-       struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble);
+       struct bcm43xx_private *bcm = dev_to_bcm(dev);
        unsigned long flags;
        int err;
        ssize_t count;
@@ -245,7 +279,7 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
                                           struct device_attribute *attr,
                                           const char *buf, size_t count)
 {
-       struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble);
+       struct bcm43xx_private *bcm = dev_to_bcm(dev);
        unsigned long flags;
        int err;
        int value;
@@ -267,56 +301,41 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
        return err ? err : count;
 }
 
+static DEVICE_ATTR(shortpreamble, 0644,
+                  bcm43xx_attr_preamble_show,
+                  bcm43xx_attr_preamble_store);
+
 int bcm43xx_sysfs_register(struct bcm43xx_private *bcm)
 {
        struct device *dev = &bcm->pci_dev->dev;
-       struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
        int err;
 
        assert(bcm->initialized);
 
-       sysfs->attr_sprom.attr.name = "sprom";
-       sysfs->attr_sprom.attr.owner = THIS_MODULE;
-       sysfs->attr_sprom.attr.mode = 0600;
-       sysfs->attr_sprom.show = bcm43xx_attr_sprom_show;
-       sysfs->attr_sprom.store = bcm43xx_attr_sprom_store;
-       err = device_create_file(dev, &sysfs->attr_sprom);
+       err = device_create_file(dev, &dev_attr_sprom);
        if (err)
                goto out;
-
-       sysfs->attr_interfmode.attr.name = "interference";
-       sysfs->attr_interfmode.attr.owner = THIS_MODULE;
-       sysfs->attr_interfmode.attr.mode = 0600;
-       sysfs->attr_interfmode.show = bcm43xx_attr_interfmode_show;
-       sysfs->attr_interfmode.store = bcm43xx_attr_interfmode_store;
-       err = device_create_file(dev, &sysfs->attr_interfmode);
+       err = device_create_file(dev, &dev_attr_interference);
        if (err)
                goto err_remove_sprom;
-
-       sysfs->attr_preamble.attr.name = "shortpreamble";
-       sysfs->attr_preamble.attr.owner = THIS_MODULE;
-       sysfs->attr_preamble.attr.mode = 0600;
-       sysfs->attr_preamble.show = bcm43xx_attr_preamble_show;
-       sysfs->attr_preamble.store = bcm43xx_attr_preamble_store;
-       err = device_create_file(dev, &sysfs->attr_preamble);
+       err = device_create_file(dev, &dev_attr_shortpreamble);
        if (err)
                goto err_remove_interfmode;
 
 out:
        return err;
 err_remove_interfmode:
-       device_remove_file(dev, &sysfs->attr_interfmode);
+       device_remove_file(dev, &dev_attr_interference);
 err_remove_sprom:
-       device_remove_file(dev, &sysfs->attr_sprom);
+       device_remove_file(dev, &dev_attr_sprom);
        goto out;
 }
 
 void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm)
 {
        struct device *dev = &bcm->pci_dev->dev;
-       struct bcm43xx_sysfs *sysfs = &bcm->sysfs;
 
-       device_remove_file(dev, &sysfs->attr_preamble);
-       device_remove_file(dev, &sysfs->attr_interfmode);
-       device_remove_file(dev, &sysfs->attr_sprom);
+       device_remove_file(dev, &dev_attr_shortpreamble);
+       device_remove_file(dev, &dev_attr_interference);
+       device_remove_file(dev, &dev_attr_sprom);
 }
index 57f14514e3e073d6fc56cb895a2c128487088e83..cc701df71e2a0637bce01d67cefe3ce6e858f5d8 100644 (file)
@@ -1,22 +1,6 @@
 #ifndef BCM43xx_SYSFS_H_
 #define BCM43xx_SYSFS_H_
 
-#include <linux/device.h>
-
-
-struct bcm43xx_sysfs {
-       struct device_attribute attr_sprom;
-       struct device_attribute attr_interfmode;
-       struct device_attribute attr_preamble;
-};
-
-#define devattr_to_bcm(attr, attr_name)        ({                              \
-       struct bcm43xx_sysfs *__s; struct bcm43xx_private *__p;         \
-       __s = container_of((attr), struct bcm43xx_sysfs, attr_name);    \
-       __p = container_of(__s, struct bcm43xx_private, sysfs);         \
-       __p;                                                            \
-                                       })
-
 struct bcm43xx_private;
 
 int bcm43xx_sysfs_register(struct bcm43xx_private *bcm);
index 3daee828ef4b7a78ad68a6e4cb3ddfb8d148c768..3edbb481a0a035ebd957decbe43a76cad3c294e6 100644 (file)
@@ -962,22 +962,22 @@ static const struct iw_priv_args bcm43xx_priv_wx_args[] = {
        {
                .cmd            = PRIV_WX_SET_SHORTPREAMBLE,
                .set_args       = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-               .name           = "set_shortpreambl",
+               .name           = "set_shortpreamb",
        },
        {
                .cmd            = PRIV_WX_GET_SHORTPREAMBLE,
                .get_args       = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
-               .name           = "get_shortpreambl",
+               .name           = "get_shortpreamb",
        },
        {
                .cmd            = PRIV_WX_SET_SWENCRYPTION,
                .set_args       = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1,
-               .name           = "set_swencryption",
+               .name           = "set_swencrypt",
        },
        {
                .cmd            = PRIV_WX_GET_SWENCRYPTION,
                .get_args       = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING,
-               .name           = "get_swencryption",
+               .name           = "get_swencrypt",
        },
        {
                .cmd            = PRIV_WX_SPROM_WRITE,
index 8dfdfbd5966c5b1b95e54617009eab26fa55dd6b..06523e2a8471f0be0a3fd5e2ef09625283667596 100644 (file)
@@ -390,7 +390,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
                }
        } else {
                struct {
-                       __le16 qual, signal, noise;
+                       __le16 qual, signal, noise, unused;
                } __attribute__ ((packed)) cq;
 
                err = HERMES_READ_RECORD(hw, USER_BAP,
index d5890027f8af86b0c11f5bf5222eba4fd8f01b05..48bbf32fd9802cb76e72eb1c8d8707e3d24d2357 100644 (file)
@@ -97,7 +97,7 @@ static struct superio_struct {        /* For Super-IO chips autodetection */
        int io;
        int irq;
        int dma;
-} superios[NR_SUPERIOS] __devinitdata = { {0,},};
+} superios[NR_SUPERIOS] = { {0,},};
 
 static int user_specified;
 #if defined(CONFIG_PARPORT_PC_SUPERIO) || \
@@ -1557,7 +1557,7 @@ static int __devinit get_superio_dma (struct parport *p)
        return PARPORT_DMA_NONE;
 }
 
-static int __devinit get_superio_irq (struct parport *p)
+static int get_superio_irq (struct parport *p)
 {
        int i=0;
         while( (superios[i].io != p->base) && (i<NR_SUPERIOS))
@@ -1579,7 +1579,7 @@ static int __devinit get_superio_irq (struct parport *p)
  *                         this shall always be the case!)
  *
  */
-static int __devinit parport_SPP_supported(struct parport *pb)
+static int parport_SPP_supported(struct parport *pb)
 {
        unsigned char r, w;
 
@@ -1660,7 +1660,7 @@ static int __devinit parport_SPP_supported(struct parport *pb)
  * two bits of ECR aren't writable, so we check by writing ECR and
  * reading it back to see if it's what we expect.
  */
-static int __devinit parport_ECR_present(struct parport *pb)
+static int parport_ECR_present(struct parport *pb)
 {
        struct parport_pc_private *priv = pb->private_data;
        unsigned char r = 0xc;
@@ -1712,7 +1712,7 @@ static int __devinit parport_ECR_present(struct parport *pb)
  * be misdetected here is rather academic. 
  */
 
-static int __devinit parport_PS2_supported(struct parport *pb)
+static int parport_PS2_supported(struct parport *pb)
 {
        int ok = 0;
   
@@ -1868,7 +1868,7 @@ static int __devinit parport_ECP_supported(struct parport *pb)
 }
 #endif
 
-static int __devinit parport_ECPPS2_supported(struct parport *pb)
+static int parport_ECPPS2_supported(struct parport *pb)
 {
        const struct parport_pc_private *priv = pb->private_data;
        int result;
@@ -1886,7 +1886,7 @@ static int __devinit parport_ECPPS2_supported(struct parport *pb)
 
 /* EPP mode detection  */
 
-static int __devinit parport_EPP_supported(struct parport *pb)
+static int parport_EPP_supported(struct parport *pb)
 {
        const struct parport_pc_private *priv = pb->private_data;
 
@@ -1931,7 +1931,7 @@ static int __devinit parport_EPP_supported(struct parport *pb)
        return 1;
 }
 
-static int __devinit parport_ECPEPP_supported(struct parport *pb)
+static int parport_ECPEPP_supported(struct parport *pb)
 {
        struct parport_pc_private *priv = pb->private_data;
        int result;
@@ -2073,7 +2073,7 @@ static int __devinit irq_probe_SPP(struct parport *pb)
  * When ECP is available we can autoprobe for IRQs.
  * NOTE: If we can autoprobe it, we can register the IRQ.
  */
-static int __devinit parport_irq_probe(struct parport *pb)
+static int parport_irq_probe(struct parport *pb)
 {
        struct parport_pc_private *priv = pb->private_data;
 
@@ -2779,7 +2779,7 @@ static struct parport_pc_pci {
        /* If set, this is called after probing for ports.  If 'failed'
         * is non-zero we couldn't use any of the ports. */
        void (*postinit_hook) (struct pci_dev *pdev, int failed);
-} cards[] __devinitdata = {
+} cards[] = {
        /* siig_1p_10x */               { 1, { { 2, 3 }, } },
        /* siig_2p_10x */               { 2, { { 2, 3 }, { 4, 5 }, } },
        /* siig_1p_20x */               { 1, { { 0, 1 }, } },
index 827550d25c9e3cfb058c8ef3d579fa09da1164d1..c42ae2cf8d64a262036381bd07ebb66b5d1b1cf8 100644 (file)
@@ -864,6 +864,35 @@ static void __init quirk_eisa_bridge(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL,  PCI_DEVICE_ID_INTEL_82375,      quirk_eisa_bridge );
 
+/*
+ * On the MSI-K8T-Neo2Fir Board, the internal Soundcard is disabled
+ * when a PCI-Soundcard is added. The BIOS only gives Options
+ * "Disabled" and "AUTO". This Quirk Sets the corresponding
+ * Register-Value to enable the Soundcard.
+ */
+static void __init k8t_sound_hostbridge(struct pci_dev *dev)
+{
+       unsigned char val;
+
+       printk(KERN_INFO "PCI: Quirk-MSI-K8T Soundcard On\n");
+       pci_read_config_byte(dev, 0x50, &val);
+       if (val == 0x88 || val == 0xc8) {
+               pci_write_config_byte(dev, 0x50, val & (~0x40));
+
+               /* Verify the Change for Status output */
+               pci_read_config_byte(dev, 0x50, &val);
+               if (val & 0x40)
+                       printk(KERN_INFO "PCI: MSI-K8T soundcard still off\n");
+               else
+                       printk(KERN_INFO "PCI: MSI-K8T soundcard on\n");
+       } else {
+               printk(KERN_INFO "PCI: Unexpected Value in PCI-Register: "
+                                       "no Change!\n");
+       }
+
+}
+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
+
 /*
  * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge
  * is not activated. The myth is that Asus said that they do not want the
index c4256aa32bcb0cc296624301cc8087aabfdac350..6fff109bdab606e98eb188f70a4b4a1dcafe6415 100644 (file)
@@ -479,7 +479,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev)
 int pnp_start_dev(struct pnp_dev *dev)
 {
        if (!pnp_can_write(dev)) {
-               pnp_info("Device %s does not supported activation.", dev->dev.bus_id);
+               pnp_info("Device %s does not support activation.", dev->dev.bus_id);
                return -EINVAL;
        }
 
@@ -503,7 +503,7 @@ int pnp_start_dev(struct pnp_dev *dev)
 int pnp_stop_dev(struct pnp_dev *dev)
 {
        if (!pnp_can_disable(dev)) {
-               pnp_info("Device %s does not supported disabling.", dev->dev.bus_id);
+               pnp_info("Device %s does not support disabling.", dev->dev.bus_id);
                return -EINVAL;
        }
        if (dev->protocol->disable(dev)<0) {
index e9c10c0a30fc057c9c47c49caadd3e557bbbd6a9..321a40f33b5042c93db4baac5ef6300c1f7f1f68 100644 (file)
@@ -1057,7 +1057,6 @@ static void m32r_sio_console_write(struct console *co, const char *s,
 {
        struct uart_sio_port *up = &m32r_sio_ports[co->index];
        unsigned int ier;
-       int i;
 
        /*
         *      First save the UER then disable the interrupts
index 9a6b5b39b88ebed5807771037e7aeba34228258f..387a18a47ac24b533037368e0928f874500658af 100644 (file)
@@ -2265,7 +2265,7 @@ static struct bin_attribute edid2_attr = {
 };
 
 
-static int radeonfb_pci_register (struct pci_dev *pdev,
+static int __devinit radeonfb_pci_register (struct pci_dev *pdev,
                                  const struct pci_device_id *ent)
 {
        struct fb_info *info;
index 8d8eadb648530add752890c8a38a6b6bcd74d62b..372aa177682798bc2544ad3f04032ad6a36dc7c9 100644 (file)
@@ -674,13 +674,19 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
                total_size = info->fix.smem_len;
 
        if (p > total_size)
-               return 0;
+               return -EFBIG;
 
-       if (count >= total_size)
+       if (count > total_size) {
+               err = -EFBIG;
                count = total_size;
+       }
+
+       if (count + p > total_size) {
+               if (!err)
+                       err = -ENOSPC;
 
-       if (count + p > total_size)
                count = total_size - p;
+       }
 
        buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count,
                         GFP_KERNEL);
@@ -722,7 +728,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
 
        kfree(buffer);
 
-       return (err) ? err : cnt;
+       return (cnt) ? cnt : err;
 }
 
 #ifdef CONFIG_KMOD
index 5fe197943deb4a1c1deea3fa3b71e716a93265b0..4e963930b50ae40ee358e19e999e12dc5b3db368 100644 (file)
@@ -73,8 +73,8 @@ static char *mode __devinitdata = NULL;
  * these flags allow the user to specify that requests for +ve sync
  * should be silently turned in -ve sync.
  */
-static int lowhsync __devinitdata = 0;
-static int lowvsync __devinitdata = 0;
+static int lowhsync;
+static int lowvsync;
 
 /*
  * The hardware state of the graphics card that isn't part of the
index 10e6b3aab9eaf18f7bd11824cfa63c12b88ba86e..0da624e6524f5e3be9c7c1406f5c9248613f7eaa 100644 (file)
@@ -73,7 +73,7 @@
 /* --------------------------------------------------------------------- */
 
 
-static char *mode_option __initdata = NULL;
+static char *mode_option __devinitdata = NULL;
 
 #ifdef MODULE
 
@@ -1545,7 +1545,7 @@ static int __devinit savage_map_mmio (struct fb_info *info)
        return 0;
 }
 
-static void __devinit savage_unmap_mmio (struct fb_info *info)
+static void savage_unmap_mmio (struct fb_info *info)
 {
        struct savagefb_par *par = info->par;
        DBG ("savage_unmap_mmio");
@@ -1597,7 +1597,7 @@ static int __devinit savage_map_video (struct fb_info *info,
        return 0;
 }
 
-static void __devinit savage_unmap_video (struct fb_info *info)
+static void savage_unmap_video (struct fb_info *info)
 {
        struct savagefb_par *par = info->par;
 
@@ -1614,7 +1614,7 @@ static void __devinit savage_unmap_video (struct fb_info *info)
        }
 }
 
-static int __devinit savage_init_hw (struct savagefb_par *par)
+static int savage_init_hw (struct savagefb_par *par)
 {
        unsigned char config1, m, n, n1, n2, sr8, cr3f, cr66 = 0, tmp;
 
index 2524629dc8350558a608e6eca0f67cf8f5b7c8b0..f9b5842c8d2de67e6f9258f65fad1fc6207b9242 100644 (file)
@@ -842,6 +842,12 @@ config TMPFS
 config HUGETLBFS
        bool "HugeTLB file system support"
        depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN
+       help
+         hugetlbfs is a filesystem backing for HugeTLB pages, based on
+         ramfs. For architectures that support it, say Y here and read
+         <file:Documentation/vm/hugetlbpage.txt> for details.
+
+         If unsure, say N.
 
 config HUGETLB_PAGE
        def_bool HUGETLBFS
index 8a2de038882e32bb881e53c92171e5967e073a42..1a27ecb46c9a71d7458b9119b345a8a4f6ec104c 100644 (file)
@@ -1,7 +1,11 @@
 Version 1.42
 ------------
 Fix slow oplock break when mounted to different servers at the same time and
-the tids match and we try to find matching fid on wrong server.
+the tids match and we try to find matching fid on wrong server. Fix read
+looping when signing required by server (2.6.16 kernel only). Fix readdir
+vs. rename race which could cause each to hang. Return . and .. even
+if server does not.  Allow searches to skip first three entries and
+begin at any location. Fix oops in find_writeable_file.
 
 Version 1.41
 ------------
index b2b4d0803761b82ed937d795bdecf539ac35a9b4..0355003f4f0a3b69eb021606d96f9e5261480c40 100644 (file)
@@ -511,6 +511,14 @@ LinuxExtensionsEnabled     If set to one then the client will attempt to
                        support and want to map the uid and gid fields 
                        to values supplied at mount (rather than the 
                        actual values, then set this to zero. (default 1)
+Experimental            When set to 1 used to enable certain experimental
+                       features (currently enables multipage writes
+                       when signing is enabled, the multipage write
+                       performance enhancement was disabled when
+                       signing turned on in case buffer was modified
+                       just before it was sent, also this flag will
+                       be used to use the new experimental sessionsetup
+                       code).
 
 These experimental features and tracing can be enabled by changing flags in 
 /proc/fs/cifs (after the cifs module has been installed or built into the 
index d4b713e5affbdd86e7050f343173897336071e40..c262d8874ce97b87cc6b8c137c44d230621d3d00 100644 (file)
@@ -33,6 +33,7 @@
 #include <linux/vfs.h>
 #include <linux/mempool.h>
 #include <linux/delay.h>
+#include <linux/kthread.h>
 #include "cifsfs.h"
 #include "cifspdu.h"
 #define DECLARE_GLOBALS_HERE
@@ -75,9 +76,6 @@ unsigned int cifs_max_pending = CIFS_MAX_REQ;
 module_param(cifs_max_pending, int, 0);
 MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256");
 
-static DECLARE_COMPLETION(cifs_oplock_exited);
-static DECLARE_COMPLETION(cifs_dnotify_exited);
-
 extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
 extern mempool_t *cifs_mid_poolp;
@@ -841,10 +839,6 @@ static int cifs_oplock_thread(void * dummyarg)
        __u16  netfid;
        int rc;
 
-       daemonize("cifsoplockd");
-       allow_signal(SIGTERM);
-
-       oplockThread = current;
        do {
                if (try_to_freeze()) 
                        continue;
@@ -900,9 +894,9 @@ static int cifs_oplock_thread(void * dummyarg)
                        set_current_state(TASK_INTERRUPTIBLE);
                        schedule_timeout(1);  /* yield in case q were corrupt */
                }
-       } while(!signal_pending(current));
-       oplockThread = NULL;
-       complete_and_exit (&cifs_oplock_exited, 0);
+       } while (!kthread_should_stop());
+
+       return 0;
 }
 
 static int cifs_dnotify_thread(void * dummyarg)
@@ -910,10 +904,6 @@ static int cifs_dnotify_thread(void * dummyarg)
        struct list_head *tmp;
        struct cifsSesInfo *ses;
 
-       daemonize("cifsdnotifyd");
-       allow_signal(SIGTERM);
-
-       dnotifyThread = current;
        do {
                if(try_to_freeze())
                        continue;
@@ -931,8 +921,9 @@ static int cifs_dnotify_thread(void * dummyarg)
                                wake_up_all(&ses->server->response_q);
                }
                read_unlock(&GlobalSMBSeslock);
-       } while(!signal_pending(current));
-       complete_and_exit (&cifs_dnotify_exited, 0);
+       } while (!kthread_should_stop());
+
+       return 0;
 }
 
 static int __init
@@ -982,32 +973,48 @@ init_cifs(void)
        }
 
        rc = cifs_init_inodecache();
-       if (!rc) {
-               rc = cifs_init_mids();
-               if (!rc) {
-                       rc = cifs_init_request_bufs();
-                       if (!rc) {
-                               rc = register_filesystem(&cifs_fs_type);
-                               if (!rc) {                
-                                       rc = (int)kernel_thread(cifs_oplock_thread, NULL, 
-                                               CLONE_FS | CLONE_FILES | CLONE_VM);
-                                       if(rc > 0) {
-                                               rc = (int)kernel_thread(cifs_dnotify_thread, NULL,
-                                                       CLONE_FS | CLONE_FILES | CLONE_VM);
-                                               if(rc > 0)
-                                                       return 0;
-                                               else
-                                                       cERROR(1,("error %d create dnotify thread", rc));
-                                       } else {
-                                               cERROR(1,("error %d create oplock thread",rc));
-                                       }
-                               }
-                               cifs_destroy_request_bufs();
-                       }
-                       cifs_destroy_mids();
-               }
-               cifs_destroy_inodecache();
+       if (rc)
+               goto out_clean_proc;
+
+       rc = cifs_init_mids();
+       if (rc)
+               goto out_destroy_inodecache;
+
+       rc = cifs_init_request_bufs();
+       if (rc)
+               goto out_destroy_mids;
+
+       rc = register_filesystem(&cifs_fs_type);
+       if (rc)
+               goto out_destroy_request_bufs;
+
+       oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd");
+       if (IS_ERR(oplockThread)) {
+               rc = PTR_ERR(oplockThread);
+               cERROR(1,("error %d create oplock thread", rc));
+               goto out_unregister_filesystem;
        }
+
+       dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd");
+       if (IS_ERR(dnotifyThread)) {
+               rc = PTR_ERR(dnotifyThread);
+               cERROR(1,("error %d create dnotify thread", rc));
+               goto out_stop_oplock_thread;
+       }
+
+       return 0;
+
+ out_stop_oplock_thread:
+       kthread_stop(oplockThread);
+ out_unregister_filesystem:
+       unregister_filesystem(&cifs_fs_type);
+ out_destroy_request_bufs:
+       cifs_destroy_request_bufs();
+ out_destroy_mids:
+       cifs_destroy_mids();
+ out_destroy_inodecache:
+       cifs_destroy_inodecache();
+ out_clean_proc:
 #ifdef CONFIG_PROC_FS
        cifs_proc_clean();
 #endif
@@ -1025,14 +1032,8 @@ exit_cifs(void)
        cifs_destroy_inodecache();
        cifs_destroy_mids();
        cifs_destroy_request_bufs();
-       if(oplockThread) {
-               send_sig(SIGTERM, oplockThread, 1);
-               wait_for_completion(&cifs_oplock_exited);
-       }
-       if(dnotifyThread) {
-               send_sig(SIGTERM, dnotifyThread, 1);
-               wait_for_completion(&cifs_dnotify_exited);
-       }
+       kthread_stop(oplockThread);
+       kthread_stop(dnotifyThread);
 }
 
 MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>");
index d705500aa283ab7170f42d9ff654668d1b1ad6a6..fd36892eda55a282fc207842e0ff62787c746703 100644 (file)
@@ -3119,7 +3119,7 @@ findFirstRetry:
                                psrch_inf->endOfSearch = FALSE;
 
                        psrch_inf->entries_in_buffer  = le16_to_cpu(parms->SearchCount);
-                       psrch_inf->index_of_last_entry = 
+                       psrch_inf->index_of_last_entry = 2 /* skip . and .. */ +
                                psrch_inf->entries_in_buffer;
                        *pnetfid = parms->SearchHandle;
                } else {
index 0b86d5ca90143be659add6e82b29282b6279b764..aaf151cb5822b35c3e95eb04ec99a1036a4ea6da 100644 (file)
@@ -3447,7 +3447,10 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
                        pSesInfo->server->secMode,
                        pSesInfo->server->capabilities,
                        pSesInfo->server->timeZone));
-               if (extended_security
+               if(experimEnabled > 1)
+                       rc = CIFS_SessSetup(xid, pSesInfo, CIFS_NTLM /* type */,
+                                           &ntlmv2_flag, nls_info);    
+               else if (extended_security
                                && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
                                && (pSesInfo->server->secType == NTLMSSP)) {
                        cFYI(1, ("New style sesssetup"));
index 1d0ca3eaaca51f282bcec21163493fda104b5cad..82315edc77d7daaaaaca6865ca44e4946807190c 100644 (file)
@@ -139,9 +139,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
 
-       mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
        if(full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -316,9 +314,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
 
-       mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
        if(full_path == NULL)
                rc = -ENOMEM;
        else if (pTcon->ses->capabilities & CAP_UNIX) {
@@ -440,6 +436,20 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
        cifs_sb = CIFS_SB(parent_dir_inode->i_sb);
        pTcon = cifs_sb->tcon;
 
+       /*
+        * Don't allow the separator character in a path component.
+        * The VFS will not allow "/", but "\" is allowed by posix.
+        */
+       if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) {
+               int i;
+               for (i = 0; i < direntry->d_name.len; i++)
+                       if (direntry->d_name.name[i] == '\\') {
+                               cFYI(1, ("Invalid file name"));
+                               FreeXid(xid);
+                               return ERR_PTR(-EINVAL);
+                       }
+       }
+
        /* can not grab the rename sem here since it would
        deadlock in the cases (beginning of sys_rename itself)
        in which we already have the sb rename sem */
index ec4dfe9bf5ef2c84fe91351da3804f37d1b9f502..633a938113287f2d0a75c6ba58953e800b755747 100644 (file)
@@ -86,9 +86,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg)
        cifs_sb = CIFS_SB(file->f_dentry->d_sb);
        pTcon = cifs_sb->tcon;
 
-       mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(file->f_dentry);
-       mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
 
        if(full_path == NULL) {
                rc = -ENOMEM;
index 5c497c529772a43396a567b515f3927fbe6a1437..e152bf6afa60fadc91c2080231858d9b5653f0fb 100644 (file)
@@ -203,9 +203,7 @@ int cifs_open(struct inode *inode, struct file *file)
                }
        }
 
-       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(file->f_dentry);
-       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -906,8 +904,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                if (rc != 0)
                                        break;
                        }
-                       /* BB FIXME We can not sign across two buffers yet */
-                       if((pTcon->ses->server->secMode & 
+                       if(experimEnabled || (pTcon->ses->server->secMode & 
                         (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) {
                                struct kvec iov[2];
                                unsigned int len;
@@ -923,13 +920,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
                                                *poffset, &bytes_written,
                                                iov, 1, long_op);
                        } else
-                       /* BB FIXME fixup indentation of line below */
-                       rc = CIFSSMBWrite(xid, pTcon,
-                                open_file->netfid,
-                                min_t(const int, cifs_sb->wsize, 
-                                      write_size - total_written),
-                                *poffset, &bytes_written,
-                                write_data + total_written, NULL, long_op);
+                               rc = CIFSSMBWrite(xid, pTcon,
+                                        open_file->netfid,
+                                        min_t(const int, cifs_sb->wsize,
+                                              write_size - total_written),
+                                        *poffset, &bytes_written,
+                                        write_data + total_written,
+                                        NULL, long_op);
                }
                if (rc || (bytes_written == 0)) {
                        if (total_written)
@@ -968,6 +965,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode)
        struct cifsFileInfo *open_file;
        int rc;
 
+       /* Having a null inode here (because mapping->host was set to zero by
+       the VFS or MM) should not happen but we had reports of on oops (due to
+       it being zero) during stress testcases so we need to check for it */
+
+       if(cifs_inode == NULL) {
+               cERROR(1,("Null inode passed to cifs_writeable_file"));
+               dump_stack();
+               return NULL;
+       }
+
        read_lock(&GlobalSMBSeslock);
        list_for_each_entry(open_file, &cifs_inode->openFileList, flist) {
                if (open_file->closePend)
@@ -1093,12 +1100,11 @@ static int cifs_writepages(struct address_space *mapping,
        if (cifs_sb->wsize < PAGE_CACHE_SIZE)
                return generic_writepages(mapping, wbc);
 
-       /* BB FIXME we do not have code to sign across multiple buffers yet,
-          so go to older writepage style write which we can sign if needed */
        if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server))
                if(cifs_sb->tcon->ses->server->secMode &
                           (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
-                       return generic_writepages(mapping, wbc);
+                       if(!experimEnabled)
+                               return generic_writepages(mapping, wbc);
 
        /*
         * BB: Is this meaningful for a non-block-device file system?
index 957ddd1571c6f0d72e99b053ded08fd14e551b43..4093764ef461e1797ac5e7403a238c3c12891ea3 100644 (file)
@@ -722,9 +722,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
 
-       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -807,9 +805,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry)
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
 
-       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -1141,9 +1137,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs)
                        rc = 0;
        }
                
-       mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
        if (full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
index 9562f5bba65c14e3eb4e42beb1b2a7bf8f498a42..2ec99f8331422a2e089cc8f0b0b1381eddc6e131 100644 (file)
@@ -48,10 +48,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode,
 /* No need to check for cross device links since server will do that
    BB note DFS case in future though (when we may have to check) */
 
-       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        fromName = build_path_from_dentry(old_file);
        toName = build_path_from_dentry(direntry);
-       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
        if((fromName == NULL) || (toName == NULL)) {
                rc = -ENOMEM;
                goto cifs_hl_exit;
@@ -103,9 +101,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd)
 
        xid = GetXid();
 
-       mutex_lock(&direntry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex);
 
        if (!full_path)
                goto out_no_free;
@@ -164,9 +160,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
        cifs_sb = CIFS_SB(inode->i_sb);
        pTcon = cifs_sb->tcon;
 
-       mutex_lock(&inode->i_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&inode->i_sb->s_vfs_rename_mutex);
 
        if(full_path == NULL) {
                FreeXid(xid);
index 78866f9257474ad8049ef5694748ac94cbcea0c3..115359cc7a32ce6cb5332435688bcaba5ee56397 100644 (file)
@@ -121,6 +121,20 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type,
        }
 
 
+       /* copy session key */
+
+       /* if Unicode, align strings to two byte boundary */
+
+       /* copy user name */ /* BB Do we need to special case null user name? */
+
+       /* copy domain name */
+
+       /* copy Linux version */
+
+       /* copy network operating system name */
+
+       /* update bcc and smb buffer length */
+
 /*     rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */
        /* SMB request buf freed in SendReceive2 */
 
index 2f6e2825571ec22f630f77981d3fe9a174418a2c..b689c5035124d137d1b019393cbad2d0b1123bf9 100644 (file)
@@ -404,9 +404,7 @@ static int initiate_cifs_search(const int xid, struct file *file)
        if(pTcon == NULL)
                return -EINVAL;
 
-       mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(file->f_dentry);
-       mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex);
 
        if(full_path == NULL) {
                return -ENOMEM;
@@ -592,6 +590,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
        first_entry_in_buffer = 
                cifsFile->srch_inf.index_of_last_entry - 
                        cifsFile->srch_inf.entries_in_buffer;
+
+       /* if first entry in buf is zero then is first buffer
+       in search response data which means it is likely . and ..
+       will be in this buffer, although some servers do not return
+       . and .. for the root of a drive and for those we need
+       to start two entries earlier */
+
 /*     dump_cifs_file_struct(file, "In fce ");*/
        if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && 
             is_dir_changed(file)) || 
@@ -634,23 +639,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon,
                char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + 
                        smbCalcSize((struct smb_hdr *)
                                cifsFile->srch_inf.ntwrk_buf_start);
+
+               current_entry = cifsFile->srch_inf.srch_entries_start;
                first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry
                                        - cifsFile->srch_inf.entries_in_buffer;
                pos_in_buf = index_to_find - first_entry_in_buffer;
                cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); 
-               current_entry = cifsFile->srch_inf.srch_entries_start;
                for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) {
                        /* go entry by entry figuring out which is first */
-                       /* if( . or ..)
-                               skip */
-                       rc = cifs_entry_is_dot(current_entry,cifsFile);
-                       if(rc == 1) /* is . or .. so skip */ {
-                               cFYI(1,("Entry is .")); /* BB removeme BB */
-                               /* continue; */
-                       } else if (rc == 2 ) {
-                               cFYI(1,("Entry is ..")); /* BB removeme BB */
-                               /* continue; */
-                       }
                        current_entry = nxt_dir_entry(current_entry,end_of_smb);
                }
                if((current_entry == NULL) && (i < pos_in_buf)) {
@@ -770,6 +766,11 @@ static int cifs_filldir(char *pfindEntry, struct file *file,
        if(file->f_dentry == NULL)
                return -ENOENT;
 
+       rc = cifs_entry_is_dot(pfindEntry,pCifsF);
+       /* skip . and .. since we added them first */
+       if(rc != 0) 
+               return 0;
+
        cifs_sb = CIFS_SB(file->f_dentry->d_sb);
 
        qstring.name = scratch_buf;
@@ -898,22 +899,22 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
 
        switch ((int) file->f_pos) {
        case 0:
-               /*if (filldir(direntry, ".", 1, file->f_pos,
+               if (filldir(direntry, ".", 1, file->f_pos,
                     file->f_dentry->d_inode->i_ino, DT_DIR) < 0) {
-                       cERROR(1, ("Filldir for current dir failed "));
+                       cERROR(1, ("Filldir for current dir failed"));
                        rc = -ENOMEM;
                        break;
                }
-               file->f_pos++; */
+               file->f_pos++;
        case 1:
-               /* if (filldir(direntry, "..", 2, file->f_pos,
+               if (filldir(direntry, "..", 2, file->f_pos,
                     file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
                        cERROR(1, ("Filldir for parent dir failed "));
                        rc = -ENOMEM;
                        break;
                }
-               file->f_pos++; */
-       case 2:
+               file->f_pos++;
+       default:
                /* 1) If search is active, 
                        is in current search buffer? 
                        if it before then restart search
@@ -927,7 +928,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                                return rc;
                        }
                }
-       default:
                if(file->private_data == NULL) {
                        rc = -EINVAL;
                        FreeXid(xid);
@@ -947,8 +947,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                kfree(cifsFile->search_resume_name);
                cifsFile->search_resume_name = NULL; */
 
-               /* BB account for . and .. in f_pos as special case */
-
                rc = find_cifs_entry(xid,pTcon, file,
                                &current_entry,&num_to_fill);
                if(rc) {
@@ -977,7 +975,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
                                          num_to_fill, i));
                                break;
                        }
-
+                       /* if buggy server returns . and .. late do
+                       we want to check for that here? */
                        rc = cifs_filldir(current_entry, file, 
                                        filldir, direntry,tmp_buf);
                        file->f_pos++;
index 3938444d87b29d557ceaaffeb5f5430421b030e2..7754d641775eb9e24e3535158b047e54c1b0217a 100644 (file)
@@ -62,9 +62,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name)
        cifs_sb = CIFS_SB(sb);
        pTcon = cifs_sb->tcon;
                                                                                      
-       mutex_lock(&sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&sb->s_vfs_rename_mutex);
        if(full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -116,9 +114,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name,
        cifs_sb = CIFS_SB(sb);
        pTcon = cifs_sb->tcon;
 
-       mutex_lock(&sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&sb->s_vfs_rename_mutex);
        if(full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -223,9 +219,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name,
        cifs_sb = CIFS_SB(sb);
        pTcon = cifs_sb->tcon;
 
-       mutex_lock(&sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&sb->s_vfs_rename_mutex);
        if(full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
@@ -341,9 +335,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size)
        cifs_sb = CIFS_SB(sb);
        pTcon = cifs_sb->tcon;
 
-       mutex_lock(&sb->s_vfs_rename_mutex);
        full_path = build_path_from_dentry(direntry);
-       mutex_unlock(&sb->s_vfs_rename_mutex);
        if(full_path == NULL) {
                FreeXid(xid);
                return -ENOMEM;
index 4121bb55973933b8a407c6969edba4094dad8022..3a79d97ac234422c353ad6c37ab973d3363471bd 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -712,7 +712,7 @@ static int de_thread(struct task_struct *tsk)
                attach_pid(current, PIDTYPE_PID,  current->pid);
                attach_pid(current, PIDTYPE_PGID, current->signal->pgrp);
                attach_pid(current, PIDTYPE_SID,  current->signal->session);
-               list_add_tail(&current->tasks, &init_task.tasks);
+               list_add_tail_rcu(&current->tasks, &init_task.tasks);
 
                current->group_leader = current;
                leader->group_leader = current;
index d2b66bad7d50458a9725d9aa5eabb47b017932b0..3ef739120dff32b1a772514be25167e546b7d3af 100644 (file)
@@ -650,7 +650,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data)
        svc_wake_up(block->b_daemon);
 }
 
-void nlmsvc_grant_release(void *data)
+static void nlmsvc_grant_release(void *data)
 {
        struct nlm_rqst         *call = data;
 
index dda83d6cd48b17934797de3f6c9f65c52662f859..efad798824dc19913b7aace09dbee47b8c6ca6a7 100644 (file)
@@ -2230,7 +2230,12 @@ void steal_locks(fl_owner_t from)
 
        lock_kernel();
        j = 0;
-       rcu_read_lock();
+
+       /*
+        * We are not taking a ref to the file structures, so
+        * we need to acquire ->file_lock.
+        */
+       spin_lock(&files->file_lock);
        fdt = files_fdtable(files);
        for (;;) {
                unsigned long set;
@@ -2248,7 +2253,7 @@ void steal_locks(fl_owner_t from)
                        set >>= 1;
                }
        }
-       rcu_read_unlock();
+       spin_unlock(&files->file_lock);
        unlock_kernel();
 }
 EXPORT_SYMBOL(steal_locks);
index a23f3489416709288655f80603337f91ea94e398..cae74dd4c7f51f6bd674c5e61bad36c415cb4460 100644 (file)
@@ -128,15 +128,14 @@ struct inode_operations nfs4_dir_inode_operations = {
 static int
 nfs_opendir(struct inode *inode, struct file *filp)
 {
-       int res = 0;
+       int res;
 
        dfprintk(VFS, "NFS: opendir(%s/%ld)\n",
                        inode->i_sb->s_id, inode->i_ino);
 
        lock_kernel();
        /* Call generic open code in order to cache credentials */
-       if (!res)
-               res = nfs_open(inode, filp);
+       res = nfs_open(inode, filp);
        unlock_kernel();
        return res;
 }
index 0f583cb16ddbc4bad0b48787a41160a6a5b8c148..3c72b0c072839383950c59955da28c6c098897bf 100644 (file)
@@ -112,10 +112,9 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode
  */
 ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs)
 {
-       struct dentry *dentry = iocb->ki_filp->f_dentry;
-
        dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n",
-                       dentry->d_name.name, (long long) pos, nr_segs);
+                       iocb->ki_filp->f_dentry->d_name.name,
+                       (long long) pos, nr_segs);
 
        return -EINVAL;
 }
@@ -468,7 +467,6 @@ static const struct rpc_call_ops nfs_commit_direct_ops = {
 static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
 {
        struct nfs_write_data *data = dreq->commit_data;
-       struct rpc_task *task = &data->task;
 
        data->inode = dreq->inode;
        data->cred = dreq->ctx->cred;
@@ -489,7 +487,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq)
        /* Note: task.tk_ops->rpc_release will free dreq->commit_data */
        dreq->commit_data = NULL;
 
-       dprintk("NFS: %5u initiated commit call\n", task->tk_pid);
+       dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid);
 
        lock_kernel();
        rpc_execute(&data->task);
index f1df2c8d92591e4fa1474d66ecda7f887868fd86..fade02c15e6ef11a8575e6381b6f10445a1de375 100644 (file)
@@ -534,10 +534,9 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl)
  */
 static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl)
 {
-       struct inode * inode = filp->f_mapping->host;
-
        dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n",
-                       inode->i_sb->s_id, inode->i_ino,
+                       filp->f_dentry->d_inode->i_sb->s_id,
+                       filp->f_dentry->d_inode->i_ino,
                        fl->fl_type, fl->fl_flags);
 
        /*
index 2f7656b911b66df6f03a96561c2f03534ffa4241..d0b991a92327f32941a454865c6aed187523d52e 100644 (file)
@@ -700,12 +700,9 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt)
        /*
         * Display superblock I/O counters
         */
-       for (cpu = 0; cpu < NR_CPUS; cpu++) {
+       for_each_possible_cpu(cpu) {
                struct nfs_iostats *stats;
 
-               if (!cpu_possible(cpu))
-                       continue;
-
                preempt_disable();
                stats = per_cpu_ptr(nfss->io_stats, cpu);
 
index 47ece1dd3c6705fa12282b31354c5d1558228319..d86c0db7b1e82a03bd003bc54aca52385e2c1bb7 100644 (file)
@@ -1218,7 +1218,7 @@ out:
        return status;
 }
 
-static void nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state)
+static int nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state)
 {
        struct file *filp;
 
@@ -1227,8 +1227,10 @@ static void nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, st
                struct nfs_open_context *ctx;
                ctx = (struct nfs_open_context *)filp->private_data;
                ctx->state = state;
-       } else
-               nfs4_close_state(state, nd->intent.open.flags);
+               return 0;
+       }
+       nfs4_close_state(state, nd->intent.open.flags);
+       return PTR_ERR(filp);
 }
 
 struct dentry *
@@ -1835,7 +1837,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr,
                        nfs_setattr_update_inode(state->inode, sattr);
        }
        if (status == 0 && nd != NULL && (nd->flags & LOOKUP_OPEN))
-               nfs4_intent_set_file(nd, dentry, state);
+               status = nfs4_intent_set_file(nd, dentry, state);
        else
                nfs4_close_state(state, flags);
 out:
index a3a3eecef68946110f8f2641959af78eff7be428..6cc77dc3f3ff79c49fa7d4ce89360b595995d839 100644 (file)
@@ -297,16 +297,20 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm
 
        files = get_files_struct(task);
        if (files) {
-               rcu_read_lock();
+               /*
+                * We are not taking a ref to the file structure, so we must
+                * hold ->file_lock.
+                */
+               spin_lock(&files->file_lock);
                file = fcheck_files(files, fd);
                if (file) {
                        *mnt = mntget(file->f_vfsmnt);
                        *dentry = dget(file->f_dentry);
-                       rcu_read_unlock();
+                       spin_unlock(&files->file_lock);
                        put_files_struct(files);
                        return 0;
                }
-               rcu_read_unlock();
+               spin_unlock(&files->file_lock);
                put_files_struct(files);
        }
        return -ENOENT;
@@ -1523,7 +1527,12 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
        if (!files)
                goto out_unlock;
        inode->i_mode = S_IFLNK;
-       rcu_read_lock();
+
+       /*
+        * We are not taking a ref to the file structure, so we must
+        * hold ->file_lock.
+        */
+       spin_lock(&files->file_lock);
        file = fcheck_files(files, fd);
        if (!file)
                goto out_unlock2;
@@ -1531,7 +1540,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
                inode->i_mode |= S_IRUSR | S_IXUSR;
        if (file->f_mode & 2)
                inode->i_mode |= S_IWUSR | S_IXUSR;
-       rcu_read_unlock();
+       spin_unlock(&files->file_lock);
        put_files_struct(files);
        inode->i_op = &proc_pid_link_inode_operations;
        inode->i_size = 64;
@@ -1541,7 +1550,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry,
        return NULL;
 
 out_unlock2:
-       rcu_read_unlock();
+       spin_unlock(&files->file_lock);
        put_files_struct(files);
 out_unlock:
        iput(inode);
index 58c418fbca2cc3e4405b194299fcb3dfaa4dbc79..97ae1b92bc47d0088a10ff3b1bc6433a70f05bda 100644 (file)
@@ -408,8 +408,9 @@ int reiserfs_cache_default_acl(struct inode *inode)
                acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT);
                reiserfs_read_unlock_xattrs(inode->i_sb);
                reiserfs_read_unlock_xattr_i(inode);
-               ret = acl ? 1 : 0;
-               posix_acl_release(acl);
+               ret = (acl && !IS_ERR(acl));
+               if (ret)
+                       posix_acl_release(acl);
        }
 
        return ret;
index 8d57e89924a68990efa6a72d279dd35efa0fc7a7..0559e7577a04164ececffdcdbd57089d980dd586 100644 (file)
@@ -50,7 +50,8 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,
        struct page *page = buf->page;
        struct address_space *mapping = page_mapping(page);
 
-       WARN_ON(!PageLocked(page));
+       lock_page(page);
+
        WARN_ON(!PageUptodate(page));
 
        /*
@@ -65,8 +66,10 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,
        if (PagePrivate(page))
                try_to_release_page(page, mapping_gfp_mask(mapping));
 
-       if (!remove_mapping(mapping, page))
+       if (!remove_mapping(mapping, page)) {
+               unlock_page(page);
                return 1;
+       }
 
        buf->flags |= PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU;
        return 0;
@@ -145,8 +148,8 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = {
  * pipe buffer operations. Otherwise very similar to the regular pipe_writev().
  */
 static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages,
-                           int nr_pages, unsigned long offset,
-                           unsigned long len, unsigned int flags)
+                           int nr_pages, unsigned long len,
+                           unsigned int offset, unsigned int flags)
 {
        int ret, do_wakeup, i;
 
@@ -243,14 +246,16 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
                           unsigned int flags)
 {
        struct address_space *mapping = in->f_mapping;
-       unsigned int offset, nr_pages;
+       unsigned int loff, offset, nr_pages;
        struct page *pages[PIPE_BUFFERS];
        struct page *page;
-       pgoff_t index;
+       pgoff_t index, end_index;
+       loff_t isize;
+       size_t bytes;
        int i, error;
 
        index = *ppos >> PAGE_CACHE_SHIFT;
-       offset = *ppos & ~PAGE_CACHE_MASK;
+       loff = offset = *ppos & ~PAGE_CACHE_MASK;
        nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
        if (nr_pages > PIPE_BUFFERS)
@@ -268,21 +273,23 @@ __generic_file_splice_read(struct file *in, loff_t *ppos,
         * Now fill in the holes:
         */
        error = 0;
+       bytes = 0;
        for (i = 0; i < nr_pages; i++, index++) {
+               unsigned int this_len;
+
+               if (!len)
+                       break;
+
+               /*
+                * this_len is the max we'll use from this page
+                */
+               this_len = min(len, PAGE_CACHE_SIZE - loff);
 find_page:
                /*
                 * lookup the page for this index
                 */
                page = find_get_page(mapping, index);
                if (!page) {
-                       /*
-                        * If in nonblock mode then dont block on
-                        * readpage (we've kicked readahead so there
-                        * will be asynchronous progress):
-                        */
-                       if (flags & SPLICE_F_NONBLOCK)
-                               break;
-
                        /*
                         * page didn't exist, allocate one
                         */
@@ -304,6 +311,13 @@ find_page:
                 * If the page isn't uptodate, we may need to start io on it
                 */
                if (!PageUptodate(page)) {
+                       /*
+                        * If in nonblock mode then dont block on waiting
+                        * for an in-flight io page
+                        */
+                       if (flags & SPLICE_F_NONBLOCK)
+                               break;
+
                        lock_page(page);
 
                        /*
@@ -336,13 +350,43 @@ readpage:
                                        goto find_page;
                                break;
                        }
+
+                       /*
+                        * i_size must be checked after ->readpage().
+                        */
+                       isize = i_size_read(mapping->host);
+                       end_index = (isize - 1) >> PAGE_CACHE_SHIFT;
+                       if (unlikely(!isize || index > end_index)) {
+                               page_cache_release(page);
+                               break;
+                       }
+
+                       /*
+                        * if this is the last page, see if we need to shrink
+                        * the length and stop
+                        */
+                       if (end_index == index) {
+                               loff = PAGE_CACHE_SIZE - (isize & ~PAGE_CACHE_MASK);
+                               if (bytes + loff > isize) {
+                                       page_cache_release(page);
+                                       break;
+                               }
+                               /*
+                                * force quit after adding this page
+                                */
+                               nr_pages = i;
+                               this_len = min(this_len, loff);
+                       }
                }
 fill_it:
                pages[i] = page;
+               bytes += this_len;
+               len -= this_len;
+               loff = 0;
        }
 
        if (i)
-               return move_to_pipe(pipe, pages, i, offset, len, flags);
+               return move_to_pipe(pipe, pages, i, bytes, offset, flags);
 
        return error;
 }
@@ -369,17 +413,20 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos,
        while (len) {
                ret = __generic_file_splice_read(in, ppos, pipe, len, flags);
 
-               if (ret <= 0)
+               if (ret < 0)
                        break;
+               else if (!ret) {
+                       if (spliced)
+                               break;
+                       if (flags & SPLICE_F_NONBLOCK) {
+                               ret = -EAGAIN;
+                               break;
+                       }
+               }
 
                *ppos += ret;
                len -= ret;
                spliced += ret;
-
-               if (!(flags & SPLICE_F_NONBLOCK))
-                       continue;
-               ret = -EAGAIN;
-               break;
        }
 
        if (spliced)
@@ -474,14 +521,12 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
        if (sd->flags & SPLICE_F_MOVE) {
                /*
                 * If steal succeeds, buf->page is now pruned from the vm
-                * side (LRU and page cache) and we can reuse it.
+                * side (LRU and page cache) and we can reuse it. The page
+                * will also be looked on successful return.
                 */
                if (buf->ops->steal(info, buf))
                        goto find_page;
 
-               /*
-                * this will also set the page locked
-                */
                page = buf->page;
                if (add_to_page_cache(page, mapping, index, gfp_mask))
                        goto find_page;
@@ -490,15 +535,27 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
                        lru_cache_add(page);
        } else {
 find_page:
-               ret = -ENOMEM;
-               page = find_or_create_page(mapping, index, gfp_mask);
-               if (!page)
-                       goto out_nomem;
+               page = find_lock_page(mapping, index);
+               if (!page) {
+                       ret = -ENOMEM;
+                       page = page_cache_alloc_cold(mapping);
+                       if (unlikely(!page))
+                               goto out_nomem;
+
+                       /*
+                        * This will also lock the page
+                        */
+                       ret = add_to_page_cache_lru(page, mapping, index,
+                                                   gfp_mask);
+                       if (unlikely(ret))
+                               goto out;
+               }
 
                /*
-                * If the page is uptodate, it is also locked. If it isn't
-                * uptodate, we can mark it uptodate if we are filling the
-                * full page. Otherwise we need to read it in first...
+                * We get here with the page locked. If the page is also
+                * uptodate, we don't need to do more. If it isn't, we
+                * may need to bring it in if we are not going to overwrite
+                * the full page.
                 */
                if (!PageUptodate(page)) {
                        if (sd->len < PAGE_CACHE_SIZE) {
@@ -520,10 +577,8 @@ find_page:
                                        ret = -EIO;
                                        goto out;
                                }
-                       } else {
-                               WARN_ON(!PageLocked(page));
+                       } else
                                SetPageUptodate(page);
-                       }
                }
        }
 
@@ -552,10 +607,10 @@ find_page:
        mark_page_accessed(page);
        balance_dirty_pages_ratelimited(mapping);
 out:
-       if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) {
+       if (!(buf->flags & PIPE_BUF_FLAG_STOLEN))
                page_cache_release(page);
-               unlock_page(page);
-       }
+
+       unlock_page(page);
 out_nomem:
        buf->ops->unmap(info, buf);
        return ret;
@@ -687,22 +742,26 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
        ssize_t ret;
 
        ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file);
-
-       /*
-        * If file or inode is SYNC and we actually wrote some data, sync it.
-        */
-       if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(mapping->host))
-           && ret > 0) {
+       if (ret > 0) {
                struct inode *inode = mapping->host;
-               int err;
 
-               mutex_lock(&inode->i_mutex);
-               err = generic_osync_inode(mapping->host, mapping,
-                                         OSYNC_METADATA|OSYNC_DATA);
-               mutex_unlock(&inode->i_mutex);
+               *ppos += ret;
+
+               /*
+                * If file or inode is SYNC and we actually wrote some data,
+                * sync it.
+                */
+               if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
+                       int err;
+
+                       mutex_lock(&inode->i_mutex);
+                       err = generic_osync_inode(inode, mapping,
+                                                 OSYNC_METADATA|OSYNC_DATA);
+                       mutex_unlock(&inode->i_mutex);
 
-               if (err)
-                       ret = err;
+                       if (err)
+                               ret = err;
+               }
        }
 
        return ret;
@@ -904,6 +963,7 @@ static long do_splice(struct file *in, loff_t __user *off_in,
 {
        struct pipe_inode_info *pipe;
        loff_t offset, *off;
+       long ret;
 
        pipe = in->f_dentry->d_inode->i_pipe;
        if (pipe) {
@@ -918,7 +978,12 @@ static long do_splice(struct file *in, loff_t __user *off_in,
                } else
                        off = &out->f_pos;
 
-               return do_splice_from(pipe, out, off, len, flags);
+               ret = do_splice_from(pipe, out, off, len, flags);
+
+               if (off_out && copy_to_user(off_out, off, sizeof(loff_t)))
+                       ret = -EFAULT;
+
+               return ret;
        }
 
        pipe = out->f_dentry->d_inode->i_pipe;
@@ -934,7 +999,12 @@ static long do_splice(struct file *in, loff_t __user *off_in,
                } else
                        off = &in->f_pos;
 
-               return do_splice_to(in, off, pipe, len, flags);
+               ret = do_splice_to(in, off, pipe, len, flags);
+
+               if (off_in && copy_to_user(off_in, off, sizeof(loff_t)))
+                       ret = -EFAULT;
+
+               return ret;
        }
 
        return -EINVAL;
@@ -979,7 +1049,9 @@ static int link_pipe(struct pipe_inode_info *ipipe,
                     size_t len, unsigned int flags)
 {
        struct pipe_buffer *ibuf, *obuf;
-       int ret = 0, do_wakeup = 0, i;
+       int ret, do_wakeup, i, ipipe_first;
+
+       ret = do_wakeup = ipipe_first = 0;
 
        /*
         * Potential ABBA deadlock, work around it by ordering lock
@@ -987,6 +1059,7 @@ static int link_pipe(struct pipe_inode_info *ipipe,
         * could deadlock (one doing tee from A -> B, the other from B -> A).
         */
        if (ipipe->inode < opipe->inode) {
+               ipipe_first = 1;
                mutex_lock(&ipipe->inode->i_mutex);
                mutex_lock(&opipe->inode->i_mutex);
        } else {
@@ -1035,9 +1108,11 @@ static int link_pipe(struct pipe_inode_info *ipipe,
 
                        /*
                         * We have input available, but no output room.
-                        * If we already copied data, return that.
+                        * If we already copied data, return that. If we
+                        * need to drop the opipe lock, it must be ordered
+                        * last to avoid deadlocks.
                         */
-                       if (flags & SPLICE_F_NONBLOCK) {
+                       if ((flags & SPLICE_F_NONBLOCK) || !ipipe_first) {
                                if (!ret)
                                        ret = -EAGAIN;
                                break;
@@ -1071,7 +1146,12 @@ static int link_pipe(struct pipe_inode_info *ipipe,
                        if (ret)
                                break;
                }
-               if (flags & SPLICE_F_NONBLOCK) {
+               /*
+                * pipe_wait() drops the ipipe mutex. To avoid deadlocks
+                * with another process, we can only safely do that if
+                * the ipipe lock is ordered last.
+                */
+               if ((flags & SPLICE_F_NONBLOCK) || ipipe_first) {
                        if (!ret)
                                ret = -EAGAIN;
                        break;
index 22d80ece95cb48de54ed1dea6e0c9475d10935ba..4ddce5296a788a2b6442700f4126bb636cd14df9 100644 (file)
@@ -183,6 +183,7 @@ static __inline__ int atomic_add_return(int i, atomic_t *v)
 {
        int __i;
 #ifdef CONFIG_M386
+       unsigned long flags;
        if(unlikely(boot_cpu_data.x86==3))
                goto no_xadd;
 #endif
@@ -196,10 +197,10 @@ static __inline__ int atomic_add_return(int i, atomic_t *v)
 
 #ifdef CONFIG_M386
 no_xadd: /* Legacy 386 processor */
-       local_irq_disable();
+       local_irq_save(flags);
        __i = atomic_read(v);
        atomic_set(v, i + __i);
-       local_irq_enable();
+       local_irq_restore(flags);
        return i + __i;
 #endif
 }
index 5c0b5876b9318cf7e41af251c367597776330569..b44bfc6239cb51debea374b173e58b5469f8ff1c 100644 (file)
@@ -71,6 +71,7 @@
 #define X86_FEATURE_P4         (3*32+ 7) /* P4 */
 #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */
 #define X86_FEATURE_UP         (3*32+ 9) /* smp kernel running on up */
+#define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
index 152d0baa576a675b39bfa408a6b69f670e8ad118..7b1f01191e7063df3ab056dfdb17e6de0bcd828f 100644 (file)
@@ -13,6 +13,7 @@
 
 #include <linux/sched.h>
 #include <linux/init.h>
+#include <linux/kernel_stat.h>
 #include <asm/processor.h>
 #include <asm/sigcontext.h>
 #include <asm/user.h>
@@ -38,17 +39,38 @@ extern void init_fpu(struct task_struct *);
 extern void kernel_fpu_begin(void);
 #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0)
 
+/* We need a safe address that is cheap to find and that is already
+   in L1 during context switch. The best choices are unfortunately
+   different for UP and SMP */
+#ifdef CONFIG_SMP
+#define safe_address (__per_cpu_offset[0])
+#else
+#define safe_address (kstat_cpu(0).cpustat.user)
+#endif
+
 /*
  * These must be called with preempt disabled
  */
 static inline void __save_init_fpu( struct task_struct *tsk )
 {
+       /* Use more nops than strictly needed in case the compiler
+          varies code */
        alternative_input(
-               "fnsave %1 ; fwait ;" GENERIC_NOP2,
-               "fxsave %1 ; fnclex",
+               "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4,
+               "fxsave %[fx]\n"
+               "bt $7,%[fsw] ; jc 1f ; fnclex\n1:",
                X86_FEATURE_FXSR,
-               "m" (tsk->thread.i387.fxsave)
-               :"memory");
+               [fx] "m" (tsk->thread.i387.fxsave),
+               [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
+       /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
+          is pending.  Clear the x87 state here by setting it to fixed
+          values. __per_cpu_offset[0] is a random variable that should be in L1 */
+       alternative_input(
+               GENERIC_NOP8 GENERIC_NOP2,
+               "emms\n\t"              /* clear stack tags */
+               "fildl %[addr]",        /* set F?P to defined value */
+               X86_FEATURE_FXSAVE_LEAK,
+               [addr] "m" (safe_address));
        task_thread_info(tsk)->status &= ~TS_USEDFPU;
 }
 
index b7f4d8aaeb469b0409103dd8057e3b6f80c2cc8f..1a1aa17edd33fe737d1035676d756421b93a1fe8 100644 (file)
        push    r13
        mvfachi r13
        push    r13
+       ldi     r13, #0
+       push    r13             ; dummy push acc1h
+       push    r13             ; dummy push acc1l
 #else
 #error unknown isa configuration
 #endif
        pop     r13
        mvtaclo r13, a1
 #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
+       pop     r13             ; dummy pop acc1h
+       pop     r13             ; dummy pop acc1l
        pop     r13
        mvtachi r13
        pop     r13
index 1d3c25d61bcb2399e6f4def20b7ac16b2a911fd0..031369a7afc85ed732613f483906b826707afecb 100644 (file)
 /* Power Control of MMC and CF */
 #define PLD_CPCR               __reg16(PLD_BASE + 0x14000)
 
-
-/*==== ICU ====*/
-#define  M32R_IRQ_PC104        (5)   /* INT4(PC/104) */
-#define  M32R_IRQ_I2C          (28)  /* I2C-BUS     */
-#define  PLD_IRQ_CFIREQ       (6)  /* INT5 CFC Card Interrupt */
-#define  PLD_IRQ_CFC_INSERT   (7)  /* INT6 CFC Card Insert */
-#define  PLD_IRQ_IDEIREQ      (8)  /* INT7 IDE Interrupt   */
-#define  PLD_IRQ_MMCCARD      (43)  /* MMC Card Insert */
-#define  PLD_IRQ_MMCIRQ       (44)  /* MMC Transfer Done */
-
+/* ICU */
+#define M32R_IRQ_PC104         (5)     /* INT4(PC/104) */
+#define M32R_IRQ_I2C           (28)    /* I2C-BUS */
+#define PLD_IRQ_CFIREQ         (6)     /* INT5 CFC Card Interrupt */
+#define PLD_IRQ_CFC_INSERT     (7)     /* INT6 CFC Card Insert & Eject */
+#define PLD_IRQ_IDEIREQ                (8)     /* INT7 IDE Interrupt */
+#define PLD_IRQ_MMCCARD                (43)    /* MMC Card Insert */
+#define PLD_IRQ_MMCIRQ         (44)    /* MMC Transfer Done */
 
 #if 0
 /* LED Control
@@ -97,7 +95,6 @@
 #define PLD_CRC16ADATA         __reg16(PLD_BASE + 0x18008)
 #define PLD_CRC16AINDATA       __reg16(PLD_BASE + 0x1800a)
 
-
 #if 0
 /* RTC */
 #define PLD_RTCCR              __reg16(PLD_BASE + 0x1c000)
 
 #endif
 
+/* Reset Control */
+#define PLD_REBOOT             __reg16(PLD_BASE + 0x38000)
+
 #endif /* _MAPPI3_PLD.H */
index 0d058b2d844e468ac6d6ac448a553dfa1d752528..53c792452dfc0c036538230f69fce24406d119f9 100644 (file)
 #define PT_ACC1L       18
 #define PT_ACCH                PT_ACC0H
 #define PT_ACCL                PT_ACC0L
+#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
+#define PT_ACCH                15
+#define PT_ACCL                16
+#define PT_DUMMY_ACC1H 17
+#define PT_DUMMY_ACC1L 18
+#else
+#error unknown isa conifiguration
+#endif
 #define PT_PSW         19
 #define PT_BPC         20
 #define PT_BBPSW       21
 #define PT_LR          25
 #define PT_SPI         26
 #define PT_ORIGR0      27
-#elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
-#define PT_ACCH                15
-#define PT_ACCL                16
-#define PT_PSW         17
-#define PT_BPC         18
-#define PT_BBPSW       19
-#define PT_BBPC                20
-#define PT_SPU         21
-#define PT_FP          22
-#define PT_LR          23
-#define PT_SPI         24
-#define PT_ORIGR0      25
-#else
-#error unknown isa conifiguration
-#endif
 
 /* virtual pt_reg entry for gdb */
 #define PT_PC          30
@@ -121,6 +114,8 @@ struct pt_regs {
 #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
        unsigned long acch;
        unsigned long accl;
+       unsigned long dummy_acc1h;
+       unsigned long dummy_acc1l;
 #else
 #error unknown isa configuration
 #endif
index bf447c52a0a126c8a26719885d5e081f73c3c728..81750edc8916267e035dcf47484afe001910c74a 100644 (file)
@@ -9,7 +9,7 @@
  * SMP- and interrupt-safe semaphores..
  *
  * Copyright (C) 1996  Linus Torvalds
- * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ * Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
  */
 
 #include <linux/config.h>
@@ -77,27 +77,8 @@ asmlinkage void __up(struct semaphore * sem);
  */
 static inline void down(struct semaphore * sem)
 {
-       unsigned long flags;
-       long count;
-
        might_sleep();
-       local_irq_save(flags);
-       __asm__ __volatile__ (
-               "# down                         \n\t"
-               DCACHE_CLEAR("%0", "r4", "%1")
-               M32R_LOCK" %0, @%1;             \n\t"
-               "addi   %0, #-1;                \n\t"
-               M32R_UNLOCK" %0, @%1;           \n\t"
-               : "=&r" (count)
-               : "r" (&sem->count)
-               : "memory"
-#ifdef CONFIG_CHIP_M32700_TS1
-               , "r4"
-#endif /* CONFIG_CHIP_M32700_TS1 */
-       );
-       local_irq_restore(flags);
-
-       if (unlikely(count < 0))
+       if (unlikely(atomic_dec_return(&sem->count) < 0))
                __down(sem);
 }
 
@@ -107,28 +88,10 @@ static inline void down(struct semaphore * sem)
  */
 static inline int down_interruptible(struct semaphore * sem)
 {
-       unsigned long flags;
-       long count;
        int result = 0;
 
        might_sleep();
-       local_irq_save(flags);
-       __asm__ __volatile__ (
-               "# down_interruptible           \n\t"
-               DCACHE_CLEAR("%0", "r4", "%1")
-               M32R_LOCK" %0, @%1;             \n\t"
-               "addi   %0, #-1;                \n\t"
-               M32R_UNLOCK" %0, @%1;           \n\t"
-               : "=&r" (count)
-               : "r" (&sem->count)
-               : "memory"
-#ifdef CONFIG_CHIP_M32700_TS1
-               , "r4"
-#endif /* CONFIG_CHIP_M32700_TS1 */
-       );
-       local_irq_restore(flags);
-
-       if (unlikely(count < 0))
+       if (unlikely(atomic_dec_return(&sem->count) < 0))
                result = __down_interruptible(sem);
 
        return result;
@@ -174,26 +137,7 @@ static inline int down_trylock(struct semaphore * sem)
  */
 static inline void up(struct semaphore * sem)
 {
-       unsigned long flags;
-       long count;
-
-       local_irq_save(flags);
-       __asm__ __volatile__ (
-               "# up                           \n\t"
-               DCACHE_CLEAR("%0", "r4", "%1")
-               M32R_LOCK" %0, @%1;             \n\t"
-               "addi   %0, #1;                 \n\t"
-               M32R_UNLOCK" %0, @%1;           \n\t"
-               : "=&r" (count)
-               : "r" (&sem->count)
-               : "memory"
-#ifdef CONFIG_CHIP_M32700_TS1
-               , "r4"
-#endif /* CONFIG_CHIP_M32700_TS1 */
-       );
-       local_irq_restore(flags);
-
-       if (unlikely(count <= 0))
+       if (unlikely(atomic_inc_return(&sem->count) <= 0))
                __up(sem);
 }
 
index c233e2def2a3d198fd881c7e5f2e153b8763a0a3..942b8a30937df79deb9ac1dc76bb8cd27862afd9 100644 (file)
@@ -32,6 +32,8 @@ struct sigcontext {
 #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R)
        unsigned long sc_acch;
        unsigned long sc_accl;
+       unsigned long sc_dummy_acc1h;
+       unsigned long sc_dummy_acc1l;
 #else
 #error unknown isa configuration
 #endif
index c5ab5da56d21acb42dfb4c18e5bbdd8151aa58f8..e55013f378e582357df670aee5638e62e8e5a2af 100644 (file)
@@ -6,8 +6,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001  by Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
- * Copyright (C) 2004  Hirokazu Takata <takata at linux-m32r.org>
+ * Copyright (C) 2001  Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto
+ * Copyright (C) 2004, 2006  Hirokazu Takata <takata at linux-m32r.org>
  */
 
 #include <linux/config.h>
  * switch_to(prev, next) should switch from task `prev' to `next'
  * `prev' will never be the same as `next'.
  *
- * `next' and `prev' should be struct task_struct, but it isn't always defined
+ * `next' and `prev' should be task_t, but it isn't always defined
  */
 
 #define switch_to(prev, next, last)  do { \
-       register unsigned long  arg0 __asm__ ("r0") = (unsigned long)prev; \
-       register unsigned long  arg1 __asm__ ("r1") = (unsigned long)next; \
-       register unsigned long  *oldsp __asm__ ("r2") = &(prev->thread.sp); \
-       register unsigned long  *newsp __asm__ ("r3") = &(next->thread.sp); \
-       register unsigned long  *oldlr __asm__ ("r4") = &(prev->thread.lr); \
-       register unsigned long  *newlr __asm__ ("r5") = &(next->thread.lr); \
-       register struct task_struct  *__last __asm__ ("r6"); \
        __asm__ __volatile__ ( \
-               "st     r8, @-r15                                 \n\t" \
-               "st     r9, @-r15                                 \n\t" \
-               "st    r10, @-r15                                 \n\t" \
-               "st    r11, @-r15                                 \n\t" \
-               "st    r12, @-r15                                 \n\t" \
-               "st    r13, @-r15                                 \n\t" \
-               "st    r14, @-r15                                 \n\t" \
-               "seth  r14, #high(1f)                             \n\t" \
-               "or3   r14, r14, #low(1f)                         \n\t" \
-               "st    r14, @r4    ; store old LR                 \n\t" \
-               "st    r15, @r2    ; store old SP                 \n\t" \
-               "ld    r15, @r3    ; load new SP                  \n\t" \
-               "st     r0, @-r15  ; store 'prev' onto new stack  \n\t" \
-               "ld    r14, @r5    ; load new LR                  \n\t" \
-               "jmp   r14                                        \n\t" \
-               ".fillinsn                                        \n  " \
-               "1:                                               \n\t" \
-               "ld     r6, @r15+  ; load 'prev' from new stack   \n\t" \
-               "ld    r14, @r15+                                 \n\t" \
-               "ld    r13, @r15+                                 \n\t" \
-               "ld    r12, @r15+                                 \n\t" \
-               "ld    r11, @r15+                                 \n\t" \
-               "ld    r10, @r15+                                 \n\t" \
-               "ld     r9, @r15+                                 \n\t" \
-               "ld     r8, @r15+                                 \n\t" \
-               : "=&r" (__last) \
-               : "r" (arg0), "r" (arg1), "r" (oldsp), "r" (newsp), \
-                 "r" (oldlr), "r" (newlr) \
-               : "memory" \
+               "       seth    lr, #high(1f)                           \n" \
+               "       or3     lr, lr, #low(1f)                        \n" \
+               "       st      lr, @%4  ; store old LR                 \n" \
+               "       ld      lr, @%5  ; load new LR                  \n" \
+               "       st      sp, @%2  ; store old SP                 \n" \
+               "       ld      sp, @%3  ; load new SP                  \n" \
+               "       push    %1  ; store `prev' on new stack         \n" \
+               "       jmp     lr                                      \n" \
+               "       .fillinsn                                       \n" \
+               "1:                                                     \n" \
+               "       pop     %0  ; restore `__last' from new stack   \n" \
+               : "=r" (last) \
+               : "0" (prev), \
+                 "r" (&(prev->thread.sp)), "r" (&(next->thread.sp)), \
+                 "r" (&(prev->thread.lr)), "r" (&(next->thread.lr)) \
+               : "memory", "lr" \
        ); \
-       last = __last; \
 } while(0)
 
 /*
@@ -167,8 +146,8 @@ extern void  __xchg_called_with_bad_pointer(void);
 #define DCACHE_CLEAR(reg0, reg1, addr)
 #endif /* CONFIG_CHIP_M32700_TS1 */
 
-static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr,
-       int size)
+static inline unsigned long
+__xchg(unsigned long x, volatile void * ptr, int size)
 {
        unsigned long flags;
        unsigned long tmp = 0;
@@ -220,7 +199,7 @@ static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr,
 
 #define __HAVE_ARCH_CMPXCHG    1
 
-static __inline__ unsigned long
+static inline unsigned long
 __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
 {
        unsigned long flags;
@@ -254,7 +233,7 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new)
    if something tries to do an invalid cmpxchg().  */
 extern void __cmpxchg_called_with_bad_pointer(void);
 
-static __inline__ unsigned long
+static inline unsigned long
 __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
 {
        switch (size) {
index d5677cbec200fc748ee9802f969760c7f4510707..18ca29e9105a5d92f1e302d49f411f1f83229159 100644 (file)
@@ -70,17 +70,18 @@ extern void iommu_free_table(struct device_node *dn);
 extern struct iommu_table *iommu_init_table(struct iommu_table * tbl);
 
 extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl,
-               struct scatterlist *sglist, int nelems,
+               struct scatterlist *sglist, int nelems, unsigned long mask,
                enum dma_data_direction direction);
 extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
                int nelems, enum dma_data_direction direction);
 
 extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
-               dma_addr_t *dma_handle, gfp_t flag);
+               dma_addr_t *dma_handle, unsigned long mask, gfp_t flag);
 extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
                void *vaddr, dma_addr_t dma_handle);
 extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
-               size_t size, enum dma_data_direction direction);
+               size_t size, unsigned long mask,
+               enum dma_data_direction direction);
 extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
                size_t size, enum dma_data_direction direction);
 
index 5ed8476807542049dad3143916d18080902f6642..0f9254c18914d6c6afad891d62dc87781cbe3f85 100644 (file)
@@ -253,7 +253,11 @@ extern struct machdep_calls *machine_id;
 
 #define __machine_desc __attribute__ ((__section__ (".machine.desc")))
 
-#define define_machine(name) struct machdep_calls mach_##name __machine_desc =
+#define define_machine(name)                                   \
+       extern struct machdep_calls mach_##name;                \
+       EXPORT_SYMBOL(mach_##name);                             \
+       struct machdep_calls mach_##name __machine_desc =
+
 #define machine_is(name) \
        ({ \
                extern struct machdep_calls mach_##name \
index 2a911aa4cae9f8578d2410a2d26fe07f8c868540..45feff893b8e0f9df1d5c60b6bd4ec423a150058 100644 (file)
 #define __NR_setfsgid           229 /* Linux Specific                              */
 #define __NR__newselect         230 /* Linux Specific                              */
 #define __NR_time               231 /* Linux Specific                              */
-#define __NR_sys_splice         232 /* Linux Specific                              */
+#define __NR_splice             232 /* Linux Specific                              */
 #define __NR_stime              233 /* Linux Specific                              */
 #define __NR_statfs64           234 /* Linux Specific                              */
 #define __NR_fstatfs64          235 /* Linux Specific                              */
index 6ada6a871cc8b60b3eaf4deb9b1ca158660c3894..597f6923a46eec7665cb887a0c2b7e9b51404f1c 100644 (file)
 #ifdef __KERNEL__
 #define __NR_time              231 /* Linux sparc32                               */
 #endif
-#define __NR_sys_splice         232 /* Linux Specific                              */
+#define __NR_splice             232 /* Linux Specific                              */
 #define __NR_stime              233 /* Linux Specific                              */
 #define __NR_statfs64           234 /* Linux Specific                              */
 #define __NR_fstatfs64          235 /* Linux Specific                              */
index c8043a16152e31fc52d3a48c32ae94ec2155eed9..f8dff1c67538b75381964b6c5c7b4dd3dcc9b37d 100644 (file)
@@ -20,8 +20,8 @@
        __attribute__((__section__(".data.page_aligned")))
 #endif
 
-#define __read_mostly __attribute__((__section__(".data.read_mostly")))
-
 #endif
 
+#define __read_mostly __attribute__((__section__(".data.read_mostly")))
+
 #endif
index 76bb6193ae9107a380ac6b754d5dd498869eef5f..662964b74e348f228fbb9c874567c574d6339175 100644 (file)
@@ -64,6 +64,7 @@
 #define X86_FEATURE_REP_GOOD   (3*32+ 4) /* rep microcode works well on this CPU */
 #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */
 #define X86_FEATURE_SYNC_RDTSC  (3*32+6)  /* RDTSC syncs CPU core */
+#define X86_FEATURE_FXSAVE_LEAK (3*32+7)  /* FIP/FOP/FDP leaks through FXSAVE */
 
 /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */
 #define X86_FEATURE_XMM3       (4*32+ 0) /* Streaming SIMD Extensions-3 */
index 876eb9a2fe7868a7c7ce01ef694403b3150f4601..cba8a3b0cded5a77191d9528710b04c85bc13c5b 100644 (file)
@@ -72,6 +72,23 @@ extern int set_fpregs(struct task_struct *tsk,
 #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val))
 #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val))
 
+#define X87_FSW_ES (1 << 7)    /* Exception Summary */
+
+/* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception
+   is pending. Clear the x87 state here by setting it to fixed
+   values. The kernel data segment can be sometimes 0 and sometimes
+   new user value. Both should be ok.
+   Use the PDA as safe address because it should be already in L1. */
+static inline void clear_fpu_state(struct i387_fxsave_struct *fx)
+{
+       if (unlikely(fx->swd & X87_FSW_ES))
+                asm volatile("fnclex");
+       alternative_input(ASM_NOP8 ASM_NOP2,
+                    "    emms\n"               /* clear stack tags */
+                    "    fildl %%gs:0",        /* load to clear state */
+                    X86_FEATURE_FXSAVE_LEAK);
+}
+
 static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) 
 { 
        int err;
@@ -119,6 +136,7 @@ static inline int save_i387_checking(struct i387_fxsave_struct __user *fx)
 #endif
        if (unlikely(err))
                __clear_user(fx, sizeof(struct i387_fxsave_struct));
+       /* No need to clear here because the caller clears USED_MATH */
        return err;
 } 
 
@@ -149,7 +167,7 @@ static inline void __fxsave_clear(struct task_struct *tsk)
                                "i" (offsetof(__typeof__(*tsk),
                                              thread.i387.fxsave)));
 #endif
-       __asm__ __volatile__("fnclex");
+       clear_fpu_state(&tsk->thread.i387.fxsave);
 }
 
 static inline void kernel_fpu_begin(void)
index 4405b4adeabad5e09a0d014f578dd8f618433740..7f33aaf9f7b1870c1b58d9de974712c004809182 100644 (file)
@@ -26,7 +26,7 @@
 #define percpu_modcopy(pcpudst, src, size)                     \
 do {                                                           \
        unsigned int __i;                                       \
-       for_each_cpu(__i)                                       \
+       for_each_possible_cpu(__i)                              \
                memcpy((pcpudst)+__per_cpu_offset(__i),         \
                       (src), (size));                          \
 } while (0)
index 10c443435c117084abfbf10b204c7254eff26970..3b89a772d0a0b954e5cec7647cdf0890f0db68c5 100644 (file)
 #define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */
 
 #define TIOCMIWAIT     _IO('T', 92) /* wait for a change on serial input line(s) */
-#define TIOCGICOUNT    _IOR('T', 93, struct async_icount) /* read serial port inline interrupt counts */
+#define TIOCGICOUNT    0x545D  /* read serial port inline interrupt counts */
 
 #endif /* _XTENSA_IOCTLS_H */
index 8d2db412ba9ca2f46f9161642b70705d68f7fe03..a8bef1d1371cc999ce6882d355c7554ca7738173 100644 (file)
@@ -1220,7 +1220,6 @@ typedef struct ide_pci_enablebit_s {
 enum {
        /* Uses ISA control ports not PCI ones. */
        IDEPCI_FLAG_ISA_PORTS           = (1 << 0),
-       IDEPCI_FLAG_FORCE_PDC           = (1 << 1),
 };
 
 typedef struct ide_pci_device_s {
index 4ca3e6ad03ec4c2b7838fec75386262dac583199..911206386171ccedc51397d9e36a7c424de9642c 100644 (file)
@@ -99,10 +99,7 @@ static inline int __remove_pages(struct zone *zone, unsigned long start_pfn,
        return -ENOSYS;
 }
 
-#if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \
-       || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)
 extern int add_memory(u64 start, u64 size);
 extern int remove_memory(u64 start, u64 size);
-#endif
 
 #endif /* __LINUX_MEMORY_HOTPLUG_H */
index 8d03e10212f5bfceda1b85b12135016765874ea3..d6fe048376ab02010a1709b6dcce4e94f4b70601 100644 (file)
 #define PCI_DEVICE_ID_ATI_IXP300_SATA   0x436e
 #define PCI_DEVICE_ID_ATI_IXP400_IDE   0x4376
 #define PCI_DEVICE_ID_ATI_IXP400_SATA   0x4379
+#define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a
+#define PCI_DEVICE_ID_ATI_IXP600_SATA  0x4380
+#define PCI_DEVICE_ID_ATI_IXP600_SRAID 0x4381
+#define PCI_DEVICE_ID_ATI_IXP600_IDE   0x438c
 
 #define PCI_VENDOR_ID_VLSI             0x1004
 #define PCI_DEVICE_ID_VLSI_82C592      0x0005
index b7d31e2e1729027ada80a4759eb2eb7618d482ae..29b7d4f87d207a69a1b8a2c0167416f1332f030d 100644 (file)
@@ -1192,8 +1192,7 @@ extern void wait_task_inactive(task_t * p);
 #define remove_parent(p)       list_del_init(&(p)->sibling)
 #define add_parent(p)          list_add_tail(&(p)->sibling,&(p)->parent->children)
 
-#define next_task(p)   list_entry((p)->tasks.next, struct task_struct, tasks)
-#define prev_task(p)   list_entry((p)->tasks.prev, struct task_struct, tasks)
+#define next_task(p)   list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks)
 
 #define for_each_process(p) \
        for (p = &init_task ; (p = next_task(p)) != &init_task ; )
index c4619a428d9b11f86648e1971645c2d312a99a8b..f8f234708b984c58addf22edcef14a93d29b4df2 100644 (file)
@@ -344,6 +344,13 @@ extern void              skb_over_panic(struct sk_buff *skb, int len,
                                     void *here);
 extern void          skb_under_panic(struct sk_buff *skb, int len,
                                      void *here);
+extern void          skb_truesize_bug(struct sk_buff *skb);
+
+static inline void skb_truesize_check(struct sk_buff *skb)
+{
+       if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len))
+               skb_truesize_bug(skb);
+}
 
 extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb,
                        int getfrag(void *from, char *to, int offset,
index 8f96e9dc369abebb5cbef5f8a8cfed63398efb65..77f78e56c4814606066669b2ba45104fafb45b91 100644 (file)
@@ -69,9 +69,21 @@ struct rpc_clnt;
 /*
  * EXPORTed functions for managing rpc_iostats structures
  */
+
+#ifdef CONFIG_PROC_FS
+
 struct rpc_iostats *   rpc_alloc_iostats(struct rpc_clnt *);
 void                   rpc_count_iostats(struct rpc_task *);
 void                   rpc_print_iostats(struct seq_file *, struct rpc_clnt *);
 void                   rpc_free_iostats(struct rpc_iostats *);
 
+#else  /*  CONFIG_PROC_FS  */
+
+static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; }
+static inline void rpc_count_iostats(struct rpc_task *task) {}
+static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {}
+static inline void rpc_free_iostats(struct rpc_iostats *stats) {}
+
+#endif  /*  CONFIG_PROC_FS  */
+
 #endif /* _LINUX_SUNRPC_METRICS_H */
index 7eebbab7160bf1900b5bec67374c271e6a4d9539..e8bbe8118de8118dc6f5fd1b7e21cacafa8afef4 100644 (file)
@@ -53,6 +53,7 @@ struct rpc_timeout {
 
 struct rpc_task;
 struct rpc_xprt;
+struct seq_file;
 
 /*
  * This describes a complete RPC request
index b971d8c82bdd6fbd92fb65795766438fa6300fbb..6b3693f05ca05722660df48af1cb352a17a70c3e 100644 (file)
@@ -267,8 +267,9 @@ extern void ieee80211softmac_stop(struct net_device *dev);
 #define IEEE80211SOFTMAC_EVENT_AUTH_FAILED             5
 #define IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT            6
 #define IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND 7
+#define IEEE80211SOFTMAC_EVENT_DISASSOCIATED           8
 /* keep this updated! */
-#define IEEE80211SOFTMAC_EVENT_LAST                    7
+#define IEEE80211SOFTMAC_EVENT_LAST                    8
 /*
  * If you want to be notified of certain events, you can call
  * ieee80211softmac_notify[_atomic] with
index af2b0544586e73ad6a0420f5a4bcaec527250ca4..ff8b0dad7b0fcb5831f0801e4489fce01944d8ab 100644 (file)
@@ -454,6 +454,7 @@ static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk)
 
 static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb)
 {
+       skb_truesize_check(skb);
        sock_set_flag(sk, SOCK_QUEUE_SHRUNK);
        sk->sk_wmem_queued   -= skb->truesize;
        sk->sk_forward_alloc += skb->truesize;
index 1a9787ac61733abbc793c10c515347904a678bff..f86434d7b3d1811b689bfedcfc1bc40079950a34 100644 (file)
@@ -56,7 +56,7 @@ static void __unhash_process(struct task_struct *p)
                detach_pid(p, PIDTYPE_PGID);
                detach_pid(p, PIDTYPE_SID);
 
-               list_del_init(&p->tasks);
+               list_del_rcu(&p->tasks);
                __get_cpu_var(process_counts)--;
        }
        list_del_rcu(&p->thread_group);
index 54b15f8cda538b3a721c03704c04390a369ae65c..d2fa57d480d4af9c868c2e7a5602f50b6e164795 100644 (file)
@@ -180,6 +180,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
        atomic_set(&tsk->usage,2);
        atomic_set(&tsk->fs_excl, 0);
        tsk->btrace_seq = 0;
+       tsk->splice_pipe = NULL;
        return tsk;
 }
 
@@ -1204,7 +1205,7 @@ static task_t *copy_process(unsigned long clone_flags,
                        attach_pid(p, PIDTYPE_PGID, process_group(p));
                        attach_pid(p, PIDTYPE_SID, p->signal->session);
 
-                       list_add_tail(&p->tasks, &init_task.tasks);
+                       list_add_tail_rcu(&p->tasks, &init_task.tasks);
                        __get_cpu_var(process_counts)++;
                }
                attach_pid(p, PIDTYPE_PID, p->pid);
index 1156eb0977d04db06b1daeb926d776e87c34a5b7..1fbf466a29aab6ca0dfe1cf6e5d6ac16fba546d8 100644 (file)
@@ -585,6 +585,9 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
        int i;
 
        rp->kp.pre_handler = pre_handler_kretprobe;
+       rp->kp.post_handler = NULL;
+       rp->kp.fault_handler = NULL;
+       rp->kp.break_handler = NULL;
 
        /* Pre-allocate memory for max kretprobe instances */
        if (rp->maxactive <= 0) {
index c5863d02c89efc08ef430752bb062f0aafcb4bc7..3eeedbb13b7864d525c6740a99156b433e3b6a51 100644 (file)
@@ -240,14 +240,15 @@ static void copy_data_pages(struct pbe *pblist)
  *     free_pagedir - free pages allocated with alloc_pagedir()
  */
 
-static void free_pagedir(struct pbe *pblist)
+static void free_pagedir(struct pbe *pblist, int clear_nosave_free)
 {
        struct pbe *pbe;
 
        while (pblist) {
                pbe = (pblist + PB_PAGE_SKIP)->next;
                ClearPageNosave(virt_to_page(pblist));
-               ClearPageNosaveFree(virt_to_page(pblist));
+               if (clear_nosave_free)
+                       ClearPageNosaveFree(virt_to_page(pblist));
                free_page((unsigned long)pblist);
                pblist = pbe;
        }
@@ -389,7 +390,7 @@ struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed
                pbe->next = alloc_image_page(gfp_mask, safe_needed);
        }
        if (!pbe) { /* get_zeroed_page() failed */
-               free_pagedir(pblist);
+               free_pagedir(pblist, 1);
                pblist = NULL;
         } else
                create_pbe_list(pblist, nr_pages);
@@ -736,7 +737,7 @@ static int create_image(struct snapshot_handle *handle)
                pblist = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 1);
                if (pblist)
                        copy_page_backup_list(pblist, p);
-               free_pagedir(p);
+               free_pagedir(p, 0);
                if (!pblist)
                        error = -ENOMEM;
        }
index aa25605027c8eb19c682cd6efec17b0d79073451..187e2a423878229b53e7c5310946621274901bf7 100644 (file)
 
 asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group)
 {
-       return sys_chown(filename, low2highuid(user), low2highgid(group));
+       long ret = sys_chown(filename, low2highuid(user), low2highgid(group));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group)
 {
-       return sys_lchown(filename, low2highuid(user), low2highgid(group));
+       long ret = sys_lchown(filename, low2highuid(user), low2highgid(group));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group)
 {
-       return sys_fchown(fd, low2highuid(user), low2highgid(group));
+       long ret = sys_fchown(fd, low2highuid(user), low2highgid(group));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid)
 {
-       return sys_setregid(low2highgid(rgid), low2highgid(egid));
+       long ret = sys_setregid(low2highgid(rgid), low2highgid(egid));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_setgid16(old_gid_t gid)
 {
-       return sys_setgid(low2highgid(gid));
+       long ret = sys_setgid(low2highgid(gid));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid)
 {
-       return sys_setreuid(low2highuid(ruid), low2highuid(euid));
+       long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_setuid16(old_uid_t uid)
 {
-       return sys_setuid(low2highuid(uid));
+       long ret = sys_setuid(low2highuid(uid));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid)
 {
-       return sys_setresuid(low2highuid(ruid), low2highuid(euid),
-               low2highuid(suid));
+       long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid),
+                                low2highuid(suid));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid)
@@ -72,8 +96,11 @@ asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid,
 
 asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid)
 {
-       return sys_setresgid(low2highgid(rgid), low2highgid(egid),
-               low2highgid(sgid));
+       long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid),
+                                low2highgid(sgid));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid)
@@ -89,12 +116,18 @@ asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid,
 
 asmlinkage long sys_setfsuid16(old_uid_t uid)
 {
-       return sys_setfsuid(low2highuid(uid));
+       long ret = sys_setfsuid(low2highuid(uid));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 asmlinkage long sys_setfsgid16(old_gid_t gid)
 {
-       return sys_setfsgid(low2highgid(gid));
+       long ret = sys_setfsgid(low2highgid(gid));
+       /* avoid REGPARM breakage on x86: */
+       prevent_tail_call(ret);
+       return ret;
 }
 
 static int groups16_to_user(old_gid_t __user *grouplist,
index d57fd9181b187ed07856ae0bb845bcc6e93a006b..6ecc180beb7145c5c649f36bc2b7961eab7af13e 100644 (file)
@@ -101,7 +101,7 @@ config DEBUG_PREEMPT
 
 config DEBUG_MUTEXES
        bool "Mutex debugging, deadlock detection"
-       default y
+       default n
        depends on DEBUG_KERNEL
        help
         This allows mutex semantics violations and mutex related deadlocks
index dec8249e972de3cdae046203b16ef32d25d1cda9..8778f58880c41c55cab9a2de035e960379b0cfe4 100644 (file)
@@ -1761,7 +1761,6 @@ static void gather_stats(struct page *page, void *private, int pte_dirty)
                md->mapcount_max = count;
 
        md->node[page_to_nid(page)]++;
-       cond_resched();
 }
 
 #ifdef CONFIG_HUGETLB_PAGE
index 78747afad6b0d6e2b2a2e0c08075e9911c8b85c6..042e6436c3ee8db6548a687dc289a207f2c43fd6 100644 (file)
 unsigned long badness(struct task_struct *p, unsigned long uptime)
 {
        unsigned long points, cpu_time, run_time, s;
-       struct list_head *tsk;
+       struct mm_struct *mm;
+       struct task_struct *child;
 
-       if (!p->mm)
+       task_lock(p);
+       mm = p->mm;
+       if (!mm) {
+               task_unlock(p);
                return 0;
+       }
 
        /*
         * The memory size of the process is the basis for the badness.
         */
-       points = p->mm->total_vm;
+       points = mm->total_vm;
+
+       /*
+        * After this unlock we can no longer dereference local variable `mm'
+        */
+       task_unlock(p);
 
        /*
         * Processes which fork a lot of child processes are likely
@@ -64,11 +74,11 @@ unsigned long badness(struct task_struct *p, unsigned long uptime)
         * child is eating the vast majority of memory, adding only half
         * to the parents will make the child our kill candidate of choice.
         */
-       list_for_each(tsk, &p->children) {
-               struct task_struct *chld;
-               chld = list_entry(tsk, struct task_struct, sibling);
-               if (chld->mm != p->mm && chld->mm)
-                       points += chld->mm->total_vm/2 + 1;
+       list_for_each_entry(child, &p->children, sibling) {
+               task_lock(child);
+               if (child->mm != mm && child->mm)
+                       points += child->mm->total_vm/2 + 1;
+               task_unlock(child);
        }
 
        /*
@@ -244,17 +254,24 @@ static void __oom_kill_task(task_t *p, const char *message)
        force_sig(SIGKILL, p);
 }
 
-static struct mm_struct *oom_kill_task(task_t *p, const char *message)
+static int oom_kill_task(task_t *p, const char *message)
 {
-       struct mm_struct *mm = get_task_mm(p);
+       struct mm_struct *mm;
        task_t * g, * q;
 
-       if (!mm)
-               return NULL;
-       if (mm == &init_mm) {
-               mmput(mm);
-               return NULL;
-       }
+       mm = p->mm;
+
+       /* WARNING: mm may not be dereferenced since we did not obtain its
+        * value from get_task_mm(p).  This is OK since all we need to do is
+        * compare mm to q->mm below.
+        *
+        * Furthermore, even if mm contains a non-NULL value, p->mm may
+        * change to NULL at any time since we do not hold task_lock(p).
+        * However, this is of no concern to us.
+        */
+
+       if (mm == NULL || mm == &init_mm)
+               return 1;
 
        __oom_kill_task(p, message);
        /*
@@ -266,13 +283,12 @@ static struct mm_struct *oom_kill_task(task_t *p, const char *message)
                        __oom_kill_task(q, message);
        while_each_thread(g, q);
 
-       return mm;
+       return 0;
 }
 
-static struct mm_struct *oom_kill_process(struct task_struct *p,
-                               unsigned long points, const char *message)
+static int oom_kill_process(struct task_struct *p, unsigned long points,
+               const char *message)
 {
-       struct mm_struct *mm;
        struct task_struct *c;
        struct list_head *tsk;
 
@@ -283,9 +299,8 @@ static struct mm_struct *oom_kill_process(struct task_struct *p,
                c = list_entry(tsk, struct task_struct, sibling);
                if (c->mm == p->mm)
                        continue;
-               mm = oom_kill_task(c, message);
-               if (mm)
-                       return mm;
+               if (!oom_kill_task(c, message))
+                       return 0;
        }
        return oom_kill_task(p, message);
 }
@@ -300,7 +315,6 @@ static struct mm_struct *oom_kill_process(struct task_struct *p,
  */
 void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
 {
-       struct mm_struct *mm = NULL;
        task_t *p;
        unsigned long points = 0;
 
@@ -320,12 +334,12 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order)
         */
        switch (constrained_alloc(zonelist, gfp_mask)) {
        case CONSTRAINT_MEMORY_POLICY:
-               mm = oom_kill_process(current, points,
+               oom_kill_process(current, points,
                                "No available memory (MPOL_BIND)");
                break;
 
        case CONSTRAINT_CPUSET:
-               mm = oom_kill_process(current, points,
+               oom_kill_process(current, points,
                                "No available memory in cpuset");
                break;
 
@@ -347,8 +361,7 @@ retry:
                        panic("Out of memory and no killable processes...\n");
                }
 
-               mm = oom_kill_process(p, points, "Out of memory");
-               if (!mm)
+               if (oom_kill_process(p, points, "Out of memory"))
                        goto retry;
 
                break;
@@ -357,8 +370,6 @@ retry:
 out:
        read_unlock(&tasklist_lock);
        cpuset_unlock();
-       if (mm)
-               mmput(mm);
 
        /*
         * Give "p" a good chance of killing itself before we
index 97d6827c7d669529fb7e5607cad4ba838d1847bf..123c605867404ecfc00ef0d19a8a65d852ed0be0 100644 (file)
@@ -232,11 +232,13 @@ static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags)
  * zone->lock is already acquired when we use these.
  * So, we don't need atomic page->flags operations here.
  */
-static inline unsigned long page_order(struct page *page) {
+static inline unsigned long page_order(struct page *page)
+{
        return page_private(page);
 }
 
-static inline void set_page_order(struct page *page, int order) {
+static inline void set_page_order(struct page *page, int order)
+{
        set_page_private(page, order);
        __SetPageBuddy(page);
 }
@@ -299,9 +301,9 @@ static inline int page_is_buddy(struct page *page, int order)
 
        if (PageBuddy(page) && page_order(page) == order) {
                BUG_ON(page_count(page) != 0);
-               return 1;
+               return 1;
        }
-       return 0;
+       return 0;
 }
 
 /*
index 37eaf42ed2c686541e4e1ef7a7a41afe736e7eb7..4c5e68e4e9aed7fcf6b31a88d240046ffeb0f899 100644 (file)
@@ -46,6 +46,8 @@
 #include <linux/mempolicy.h>
 #include <linux/namei.h>
 #include <linux/ctype.h>
+#include <linux/migrate.h>
+
 #include <asm/uaccess.h>
 #include <asm/div64.h>
 #include <asm/pgtable.h>
@@ -2173,6 +2175,7 @@ static struct address_space_operations shmem_aops = {
        .prepare_write  = shmem_prepare_write,
        .commit_write   = simple_commit_write,
 #endif
+       .migratepage    = migrate_page,
 };
 
 static struct file_operations shmem_file_operations = {
index 9bcc7e2cabfd4d5b9147b8547a34e6dd0594a629..a68255ba4553770f7c4050857a11661160ea3942 100644 (file)
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -354,9 +354,7 @@ void *__alloc_percpu(size_t size)
        if (!pdata)
                return NULL;
 
-       for (i = 0; i < NR_CPUS; i++) {
-               if (!cpu_possible(i))
-                       continue;
+       for_each_possible_cpu(i) {
                pdata->ptrs[i] = kmalloc(size, GFP_KERNEL);
                if (!pdata->ptrs[i])
                        goto unwind_oom;
@@ -383,11 +381,9 @@ free_percpu(const void *objp)
        int i;
        struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp);
 
-       for (i = 0; i < NR_CPUS; i++) {
-               if (!cpu_possible(i))
-                       continue;
+       for_each_possible_cpu(i)
                kfree(p->ptrs[i]);
-       }
+
        kfree(p);
 }
 EXPORT_SYMBOL(free_percpu);
index 84b9af76f0a2390763ef878b365cbe75d12a4fcc..3a13ed643459bc3d249d0b73b1c98a1d76e5a3c5 100644 (file)
@@ -831,7 +831,7 @@ static int translate_table(struct ebt_replace *repl,
                        return -ENOMEM;
                for_each_possible_cpu(i) {
                        newinfo->chainstack[i] =
-                          vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
+                         vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0])));
                        if (!newinfo->chainstack[i]) {
                                while (i)
                                        vfree(newinfo->chainstack[--i]);
@@ -841,8 +841,7 @@ static int translate_table(struct ebt_replace *repl,
                        }
                }
 
-               cl_s = (struct ebt_cl_stack *)
-                  vmalloc(udc_cnt * sizeof(struct ebt_cl_stack));
+               cl_s = vmalloc(udc_cnt * sizeof(*cl_s));
                if (!cl_s)
                        return -ENOMEM;
                i = 0; /* the i'th udc */
@@ -944,8 +943,7 @@ static int do_replace(void __user *user, unsigned int len)
 
        countersize = COUNTER_OFFSET(tmp.nentries) * 
                                        (highest_possible_processor_id()+1);
-       newinfo = (struct ebt_table_info *)
-          vmalloc(sizeof(struct ebt_table_info) + countersize);
+       newinfo = vmalloc(sizeof(*newinfo) + countersize);
        if (!newinfo)
                return -ENOMEM;
 
@@ -967,8 +965,7 @@ static int do_replace(void __user *user, unsigned int len)
        /* the user wants counters back
           the check on the size is done later, when we have the lock */
        if (tmp.num_counters) {
-               counterstmp = (struct ebt_counter *)
-                  vmalloc(tmp.num_counters * sizeof(struct ebt_counter));
+               counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp));
                if (!counterstmp) {
                        ret = -ENOMEM;
                        goto free_entries;
@@ -1148,8 +1145,7 @@ int ebt_register_table(struct ebt_table *table)
 
        countersize = COUNTER_OFFSET(table->table->nentries) *
                                        (highest_possible_processor_id()+1);
-       newinfo = (struct ebt_table_info *)
-          vmalloc(sizeof(struct ebt_table_info) + countersize);
+       newinfo = vmalloc(sizeof(*newinfo) + countersize);
        ret = -ENOMEM;
        if (!newinfo)
                return -ENOMEM;
@@ -1247,8 +1243,7 @@ static int update_counters(void __user *user, unsigned int len)
        if (hlp.num_counters == 0)
                return -EINVAL;
 
-       if ( !(tmp = (struct ebt_counter *)
-          vmalloc(hlp.num_counters * sizeof(struct ebt_counter))) ){
+       if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) {
                MEMPRINT("Update_counters && nomemory\n");
                return -ENOMEM;
        }
@@ -1377,8 +1372,7 @@ static int copy_everything_to_user(struct ebt_table *t, void __user *user,
                        BUGPRINT("Num_counters wrong\n");
                        return -EINVAL;
                }
-               counterstmp = (struct ebt_counter *)
-                  vmalloc(nentries * sizeof(struct ebt_counter));
+               counterstmp = vmalloc(nentries * sizeof(*counterstmp));
                if (!counterstmp) {
                        MEMPRINT("Couldn't copy counters, out of memory\n");
                        return -ENOMEM;
index 83231a27ae028caa5c0757d35c9d107220e8711e..3bad1afc89fa48b505c001a24da094de18f14cab 100644 (file)
@@ -2698,7 +2698,8 @@ int dev_ioctl(unsigned int cmd, void __user *arg)
                                /* If command is `set a parameter', or
                                 * `get the encoding parameters', check if
                                 * the user has the right to do it */
-                               if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE) {
+                               if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE
+                                   || cmd == SIOCGIWENCODEEXT) {
                                        if (!capable(CAP_NET_ADMIN))
                                                return -EPERM;
                                }
index 09464fa8d72f8b10c881b44678e8aa1084a3bcfb..fb3770f9c09405f3dce34e2b429e74d4a9761508 100644 (file)
@@ -112,6 +112,14 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here)
        BUG();
 }
 
+void skb_truesize_bug(struct sk_buff *skb)
+{
+       printk(KERN_ERR "SKB BUG: Invalid truesize (%u) "
+              "len=%u, sizeof(sk_buff)=%Zd\n",
+              skb->truesize, skb->len, sizeof(struct sk_buff));
+}
+EXPORT_SYMBOL(skb_truesize_bug);
+
 /*     Allocate a new skbuff. We do this ourselves so we can fill in a few
  *     'private' fields and also do memory statistics to find all the
  *     [BEEP] leaks.
index 35e25259fd95712a0145853eeea4f01493ad5599..e9489696f694540bfb90d12aba6e1cd3c5dd1d57 100644 (file)
@@ -176,6 +176,7 @@ void sk_stream_rfree(struct sk_buff *skb)
 {
        struct sock *sk = skb->sk;
 
+       skb_truesize_check(skb);
        atomic_sub(skb->truesize, &sk->sk_rmem_alloc);
        sk->sk_forward_alloc += skb->truesize;
 }
index 81d6995fcfdb30bd684b839626a0145fd079bd31..d2bc72d318f7bdb41dc4ab9c1ab3c08978c5af4e 100644 (file)
@@ -1726,6 +1726,14 @@ int wireless_rtnetlink_get(struct net_device *   dev,
        if(!IW_IS_GET(request->cmd))
                return -EOPNOTSUPP;
 
+       /* If command is `get the encoding parameters', check if
+        * the user has the right to do it */
+       if (request->cmd == SIOCGIWENCODE ||
+           request->cmd == SIOCGIWENCODEEXT) {
+               if (!capable(CAP_NET_ADMIN))
+                       return -EPERM;
+       }
+
        /* Special cases */
        if(request->cmd == SIOCGIWSTATS)
                /* Get Wireless Stats */
index 6cd9f3427be6c029daa85340ae2a1bca69b1e20a..f2a27cc6ecb1fc653fa7643e543cd1e7dfb4a3f8 100644 (file)
@@ -1,6 +1,7 @@
 config IEEE80211_SOFTMAC
        tristate "Software MAC add-on to the IEEE 802.11 networking stack"
        depends on IEEE80211 && EXPERIMENTAL
+       select WIRELESS_EXT
        ---help---
        This option enables the hardware independent software MAC addon
        for the IEEE 802.11 networking stack.
index be61de78dfa4a6dc01f6a653e3b6efee89ceac54..4498023841dcc7d83e0e59d792a27b2f839256d4 100644 (file)
@@ -101,6 +101,7 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason)
        /* Do NOT clear bssvalid as that will break ieee80211softmac_assoc_work! */
        mac->associated = 0;
        mac->associnfo.associating = 0;
+       ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
        spin_unlock_irqrestore(&mac->lock, flags);
 }
 
@@ -373,6 +374,7 @@ ieee80211softmac_handle_disassoc(struct net_device * dev,
        spin_lock_irqsave(&mac->lock, flags);
        mac->associnfo.bssvalid = 0;
        mac->associated = 0;
+       ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL);
        schedule_work(&mac->associnfo.work);
        spin_unlock_irqrestore(&mac->lock, flags);
        
@@ -391,6 +393,7 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev,
                dprintkl(KERN_INFO PFX "reassoc request from unknown network\n");
                return 0;
        }
-       ieee80211softmac_assoc(mac, network);
+       schedule_work(&mac->associnfo.work);
+
        return 0;
 }
index 0a52bbda1e4c8c20e2862eb69d673a3c406def2b..8cc8f3f0f8e73d3809556a6cb30c3c8cf588c111 100644 (file)
@@ -67,6 +67,7 @@ static char *event_descriptions[IEEE80211SOFTMAC_EVENT_LAST+1] = {
        "authenticating failed",
        "authenticating timed out",
        "associating failed because no suitable network was found",
+       "disassociated",
 };
 
 
@@ -128,13 +129,42 @@ void
 ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int event, void *event_ctx)
 {
        struct ieee80211softmac_event *eventptr, *tmp;
-       union iwreq_data wrqu;
-       char *msg;
+       struct ieee80211softmac_network *network;
        
        if (event >= 0) {
-               msg = event_descriptions[event];
-               wrqu.data.length = strlen(msg);
-               wireless_send_event(mac->dev, IWEVCUSTOM, &wrqu, msg);
+               union iwreq_data wrqu;
+               int we_event;
+               char *msg = NULL;
+
+               switch(event) {
+               case IEEE80211SOFTMAC_EVENT_ASSOCIATED:
+                       network = (struct ieee80211softmac_network *)event_ctx;
+                       wrqu.data.length = 0;
+                       wrqu.data.flags = 0;
+                       memcpy(wrqu.ap_addr.sa_data, &network->bssid[0], ETH_ALEN);
+                       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                       we_event = SIOCGIWAP;
+                       break;
+               case IEEE80211SOFTMAC_EVENT_DISASSOCIATED:
+                       wrqu.data.length = 0;
+                       wrqu.data.flags = 0;
+                       memset(&wrqu, '\0', sizeof (union iwreq_data));
+                       wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+                       we_event = SIOCGIWAP;
+                       break;
+               case IEEE80211SOFTMAC_EVENT_SCAN_FINISHED:
+                       wrqu.data.length = 0;
+                       wrqu.data.flags = 0;
+                       memset(&wrqu, '\0', sizeof (union iwreq_data));
+                       we_event = SIOCGIWSCAN;
+                       break;
+               default:
+                       msg = event_descriptions[event];
+                       wrqu.data.length = strlen(msg);
+                       we_event = IWEVCUSTOM;
+                       break;
+               }
+               wireless_send_event(mac->dev, we_event, &wrqu, msg);
        }
 
        if (!list_empty(&mac->events))
index febc51dbb41247119f501625f6bd54f537dc0afc..cc6cd56c85b100af93a7216442c4a6d9ade20e36 100644 (file)
@@ -180,9 +180,21 @@ ieee80211softmac_assoc_req(struct ieee80211_assoc_request **pkt,
        ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid);
 
        /* Fill in capability Info */
-       (*pkt)->capability = (mac->ieee->iw_mode == IW_MODE_MASTER) || (mac->ieee->iw_mode == IW_MODE_INFRA) ?
-               cpu_to_le16(WLAN_CAPABILITY_ESS) :
-               cpu_to_le16(WLAN_CAPABILITY_IBSS);
+       switch (mac->ieee->iw_mode) {
+       case IW_MODE_INFRA:
+               (*pkt)->capability = cpu_to_le16(WLAN_CAPABILITY_ESS);
+               break;
+       case IW_MODE_ADHOC:
+               (*pkt)->capability = cpu_to_le16(WLAN_CAPABILITY_IBSS);
+               break;
+       case IW_MODE_AUTO:
+               (*pkt)->capability = net->capabilities & (WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS);
+               break;
+       default:
+               /* bleh. we don't ever go to these modes */
+               printk(KERN_ERR PFX "invalid iw_mode!\n");
+               break;
+       }
        /* Need to add this
        (*pkt)->capability |= mac->ieee->short_slot ? 
                        cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0;
index bb9ab8b45d09fde0898f3e19ee2fbf9d6726152b..2b9e7edfa3ce4719d5783bd1b822bd825c763cce 100644 (file)
@@ -47,6 +47,7 @@ ieee80211softmac_start_scan(struct ieee80211softmac_device *sm)
        sm->scanning = 1;
        spin_unlock_irqrestore(&sm->lock, flags);
 
+       netif_tx_disable(sm->ieee->dev);
        ret = sm->start_scan(sm->dev);
        if (ret) {
                spin_lock_irqsave(&sm->lock, flags);
@@ -239,6 +240,7 @@ void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm)
                if (net)
                        sm->set_channel(sm->dev, net->channel);
        }
+       netif_wake_queue(sm->ieee->dev);
        ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL);
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished);
index b559aa9b5507712acea32ca7b6e7c614e5e37773..00f0d4f71897aff525361f4c8ee9b7e76b284dcd 100644 (file)
@@ -41,13 +41,23 @@ ieee80211softmac_wx_trigger_scan(struct net_device *net_dev,
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_trigger_scan);
 
 
+/* if we're still scanning, return -EAGAIN so that userspace tools
+ * can get the complete scan results, otherwise return 0. */
 int
 ieee80211softmac_wx_get_scan_results(struct net_device *net_dev,
                                     struct iw_request_info *info,
                                     union iwreq_data *data,
                                     char *extra)
 {
+       unsigned long flags;
        struct ieee80211softmac_device *sm = ieee80211_priv(net_dev);
+
+       spin_lock_irqsave(&sm->lock, flags);
+       if (sm->scanning) {
+               spin_unlock_irqrestore(&sm->lock, flags);
+               return -EAGAIN;
+       }
+       spin_unlock_irqrestore(&sm->lock, flags);
        return ieee80211_wx_get_scan(sm->ieee, info, data, extra);
 }
 EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_scan_results);
index 44df1db726a37bc77c28dda33d5238b9f40a5a8e..a28ae593b97613d4d09a692e2363f24e2b59417b 100644 (file)
@@ -533,6 +533,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
        struct tcp_sock *tp = tcp_sk(sk);
        struct sk_buff *buff;
        int nsize, old_factor;
+       int nlen;
        u16 flags;
 
        BUG_ON(len > skb->len);
@@ -552,8 +553,10 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
        if (buff == NULL)
                return -ENOMEM; /* We'll just try again later. */
 
-       buff->truesize = skb->len - len;
-       skb->truesize -= buff->truesize;
+       sk_charge_skb(sk, buff);
+       nlen = skb->len - len - nsize;
+       buff->truesize += nlen;
+       skb->truesize -= nlen;
 
        /* Correct the sequence numbers. */
        TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len;
@@ -1039,7 +1042,8 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
        if (unlikely(buff == NULL))
                return -ENOMEM;
 
-       buff->truesize = nlen;
+       sk_charge_skb(sk, buff);
+       buff->truesize += nlen;
        skb->truesize -= nlen;
 
        /* Correct the sequence numbers. */
index 8f3addf0724c01658c8c46b96677f701c52197f8..d62e0f9b9da3edca21a8292bc321764aa1866187 100644 (file)
@@ -118,7 +118,8 @@ static inline int llc_fixup_skb(struct sk_buff *skb)
                u16 pdulen = eth_hdr(skb)->h_proto,
                    data_size = ntohs(pdulen) - llc_len;
 
-               skb_trim(skb, data_size);
+               if (unlikely(pskb_trim_rcsum(skb, data_size)))
+                       return 0;
        }
        return 1;
 }
index 23898f45f7137d2da995ebe8c89784e1deefaf13..0ce12dfc7a71651cd1d3c49f8d7881da14a02020 100644 (file)
@@ -490,6 +490,7 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
        struct file *file;
        struct socket *sock;
 
+       *err = -EBADF;
        file = fget_light(fd, fput_needed);
        if (file) {
                sock = sock_from_file(file, err);
index 900ef31f5a0e601bd7f0a4cfc9fbfea06584c3c4..519ebc17c02845a762102c00b35efb6f01b73b46 100644 (file)
@@ -794,7 +794,6 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags)
 
 out_err:
        dprintk("RPC:      gss_create_cred failed with error %d\n", err);
-       if (cred) gss_destroy_cred(&cred->gc_base);
        return ERR_PTR(err);
 }
 
index 97c981fa6b8ee4a48118cf46801e1fef60388b23..76b969e6904fdca3607845a050c331376845b180 100644 (file)
@@ -212,7 +212,6 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
        char                            *cksumname;
        struct crypto_tfm               *tfm = NULL; /* XXX add to ctx? */
        struct scatterlist              sg[1];
-       u32                             code = GSS_S_FAILURE;
 
        switch (cksumtype) {
                case CKSUMTYPE_RSA_MD5:
@@ -221,13 +220,11 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
                default:
                        dprintk("RPC:      krb5_make_checksum:"
                                " unsupported checksum %d", cksumtype);
-                       goto out;
+                       return GSS_S_FAILURE;
        }
        if (!(tfm = crypto_alloc_tfm(cksumname, CRYPTO_TFM_REQ_MAY_SLEEP)))
-               goto out;
+               return GSS_S_FAILURE;
        cksum->len = crypto_tfm_alg_digestsize(tfm);
-       if ((cksum->data = kmalloc(cksum->len, GFP_KERNEL)) == NULL)
-               goto out;
 
        crypto_digest_init(tfm);
        sg_set_buf(sg, header, hdrlen);
@@ -235,10 +232,8 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body,
        process_xdr_buf(body, body_offset, body->len - body_offset,
                        checksummer, tfm);
        crypto_digest_final(tfm, cksum->data);
-       code = 0;
-out:
        crypto_free_tfm(tfm);
-       return code;
+       return 0;
 }
 
 EXPORT_SYMBOL(make_checksum);
index dea529666d6991077aa69deaecad2818033def0c..15c2db26767bc5e5b6848d904078c9b0975dcfa4 100644 (file)
@@ -176,7 +176,8 @@ void rpc_count_iostats(struct rpc_task *task)
        op_metrics->om_execute += execute;
 }
 
-void _print_name(struct seq_file *seq, unsigned int op, struct rpc_procinfo *procs)
+static void _print_name(struct seq_file *seq, unsigned int op,
+                       struct rpc_procinfo *procs)
 {
        if (procs[op].p_name)
                seq_printf(seq, "\t%12s: ", procs[op].p_name);
index ae5ab981bb1d170d215bf9bde96845d731c8e7e0..8012d1076876bb1f4ee9766a63720f0e53d9f829 100644 (file)
@@ -5,6 +5,7 @@
 
 #include <ctype.h>
 #include <stdlib.h>
+#include <stdio.h>
 #include <string.h>
 #include <unistd.h>
 #include <time.h>
@@ -531,7 +532,7 @@ int main(int ac, char **av)
                        break;
                case 'h':
                case '?':
-                       printf("%s [-o|-s] config\n", av[0]);
+                       fprintf(stderr, "See README for usage info\n");
                        exit(0);
                }
        }
index 640d0bfdbc6819e4ffa7845f1e10e92b5640e14a..84047f69f9c1b4d0bdfbbfe511457d6a62c18dad 100644 (file)
@@ -264,7 +264,7 @@ int mls_context_to_sid(char oldc,
 
        if (!selinux_mls_enabled) {
                if (def_sid != SECSID_NULL && oldc)
-                       *scontext += strlen(*scontext);
+                       *scontext += strlen(*scontext)+1;
                return 0;
        }
 
index 8687ae3c66b8c54bf156e2424c0a9ecf6d8e4c9a..b49a45cbf67a09aa9faf39ae75671dd0f7cad1bf 100644 (file)
@@ -183,7 +183,8 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input)
 
  */
 
-static void snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int ack)
+static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd,
+               int ack)
 {
        unsigned long flags;
        int timeout, ok;
@@ -218,9 +219,11 @@ static void snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int
                ok = 1;
        }
        spin_unlock_irqrestore(&mpu->input_lock, flags);
-       if (! ok)
+       if (!ok) {
                snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu)));
-       // snd_printk("cmd: 0x%x at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu)));
+               return 1;
+       }
+       return 0;
 }
 
 /*
@@ -235,12 +238,19 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream)
        if (mpu->open_input && (err = mpu->open_input(mpu)) < 0)
                return err;
        if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) {
-               snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1);
-               snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1);
+               if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
+                       goto error_out;
+               if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+                       goto error_out;
        }
        mpu->substream_input = substream;
        set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
        return 0;
+
+error_out:
+       if (mpu->open_input && mpu->close_input)
+               mpu->close_input(mpu);
+       return -EIO;
 }
 
 static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
@@ -252,39 +262,52 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream)
        if (mpu->open_output && (err = mpu->open_output(mpu)) < 0)
                return err;
        if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) {
-               snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1);
-               snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1);
+               if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1))
+                       goto error_out;
+               if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1))
+                       goto error_out;
        }
        mpu->substream_output = substream;
        set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
        return 0;
+
+error_out:
+       if (mpu->open_output && mpu->close_output)
+               mpu->close_output(mpu);
+       return -EIO;
 }
 
 static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream)
 {
        struct snd_mpu401 *mpu;
+       int err = 0;
 
        mpu = substream->rmidi->private_data;
        clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode);
        mpu->substream_input = NULL;
        if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode))
-               snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
+               err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
        if (mpu->close_input)
                mpu->close_input(mpu);
+       if (err)
+               return -EIO;
        return 0;
 }
 
 static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream)
 {
        struct snd_mpu401 *mpu;
+       int err = 0;
 
        mpu = substream->rmidi->private_data;
        clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode);
        mpu->substream_output = NULL;
        if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode))
-               snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
+               err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0);
        if (mpu->close_output)
                mpu->close_output(mpu);
+       if (err)
+               return -EIO;
        return 0;
 }
 
@@ -316,6 +339,7 @@ static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substrea
                        snd_mpu401_uart_remove_timer(mpu, 1);
                clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode);
        }
+
 }
 
 /*
index 88e52dc84c096b94514fd2e4ed76761edaceb42a..6275266dde2e754104badf084ce20003596a0d36 100644 (file)
@@ -5,23 +5,9 @@
 #
 # Prompt user for primary drivers.
 
-config OBSOLETE_OSS_DRIVER
-       bool "Obsolete OSS drivers"
-       depends on SOUND_PRIME
-       help
-         This option enables support for obsolete OSS drivers that
-         are scheduled for removal in the near future since there
-         are ALSA drivers for the same hardware.
-
-         Please contact Adrian Bunk <bunk@stusta.de> if you had to
-         say Y here because your soundcard is not properly supported
-         by ALSA.
-
-         If unsure, say N.
-
 config SOUND_BT878
        tristate "BT878 audio dma"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
+       depends on SOUND_PRIME && PCI
        ---help---
          Audio DMA support for bt878 based grabber boards.  As you might have
          already noticed, bt878 is listed with two functions in /proc/pci.
@@ -35,48 +21,9 @@ config SOUND_BT878
          To compile this driver as a module, choose M here: the module will
          be called btaudio.
 
-config SOUND_CMPCI
-       tristate "C-Media PCI (CMI8338/8738)"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
-       help
-         Say Y or M if you have a PCI sound card using the CMI8338
-         or the CMI8738 chipset.  Data on these chips are available at
-         <http://www.cmedia.com.tw/>.
-
-         A userspace utility to control some internal registers of these
-         chips is available at
-         <http://member.nifty.ne.jp/Breeze/softwares/unix/cmictl-e.html>.
-
-config SOUND_CMPCI_FM
-       bool "Enable legacy FM"
-       depends on SOUND_CMPCI && X86
-       help
-         Say Y here to enable the legacy FM (frequency-modulation) synthesizer
-         support on a card using the CMI8338 or CMI8378 chipset. Even it is
-         enabled, you need to set fmio as proper value to enable it.
-         Say N here if you don't need this.
-
-config SOUND_CMPCI_MIDI
-       bool "Enable legacy MPU-401"
-       depends on SOUND_CMPCI && X86
-       help
-         Say Y here to enable the legacy MPU401 MIDI synthesizer support on a
-         card using the CMI8338 or CMI8378 chipset. Even it is enabled,
-         you need to set mpuio as proper value to enable it.
-         Say N here if you don't need this.
-
-config SOUND_CMPCI_JOYSTICK
-       bool "Enable joystick"
-       depends on SOUND_CMPCI && X86 && (GAMEPORT=y || SOUND_CMPCI=GAMEPORT)
-       help
-         Say Y here in order to enable the joystick port on a sound card using
-         the CMI8338 or the CMI8738 chipset.  You need to config the
-         gameport support and set joystick parameter as 1 to use it.
-         Say N here if you don't need this.
-
 config SOUND_EMU10K1
        tristate "Creative SBLive! (EMU10K1)"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
+       depends on SOUND_PRIME && PCI
        ---help---
          Say Y or M if you have a PCI sound card using the EMU10K1 chipset,
          such as the Creative SBLive!, SB PCI512 or Emu-APS.
@@ -108,13 +55,6 @@ config SOUND_FUSION
          series) when wired as native sound drivers with AC97 codecs.  If
          this driver does not work try the CS4232 driver.
 
-config SOUND_CS4281
-       tristate "Crystal Sound CS4281"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
-       help
-         Picture and feature list at
-         <http://www.pcbroker.com/crystal4281.html>.
-
 config SOUND_BCM_CS4297A
        tristate "Crystal Sound CS4297a (for Swarm)"
        depends on SOUND_PRIME && SIBYTE_SWARM
@@ -125,22 +65,9 @@ config SOUND_BCM_CS4297A
          note that CONFIG_KGDB should not be enabled at the same
          time, since it also attempts to use this UART port.
 
-config SOUND_ES1370
-       tristate "Ensoniq AudioPCI (ES1370)"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
-       help
-         Say Y or M if you have a PCI sound card utilizing the Ensoniq
-         ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find
-         out if your sound card uses an ES1370 without removing your
-         computer's cover, use lspci -n and look for the PCI ID
-         1274:5000. Since Ensoniq was bought by Creative Labs,
-         Sound Blaster 64/PCI models are either ES1370 or ES1371 based.
-         This driver differs slightly from OSS/Free, so PLEASE READ
-         <file:Documentation/sound/oss/es1370>.
-
 config SOUND_ES1371
        tristate "Creative Ensoniq AudioPCI 97 (ES1371)"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
+       depends on SOUND_PRIME && PCI
        help
          Say Y or M if you have a PCI sound card utilizing the Ensoniq
          ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if
@@ -151,33 +78,6 @@ config SOUND_ES1371
          slightly from OSS/Free, so PLEASE READ
          <file:Documentation/sound/oss/es1371>.
 
-config SOUND_ESSSOLO1
-       tristate "ESS Technology Solo1" 
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
-       help
-         Say Y or M if you have a PCI sound card utilizing the ESS Technology
-         Solo1 chip. To find out if your sound card uses a
-         Solo1 chip without removing your computer's cover, use
-         lspci -n and look for the PCI ID 125D:1969. This driver
-         differs slightly from OSS/Free, so PLEASE READ
-         <file:Documentation/sound/oss/solo1>.
-
-config SOUND_MAESTRO
-       tristate "ESS Maestro, Maestro2, Maestro2E driver"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
-       help
-         Say Y or M if you have a sound system driven by ESS's Maestro line
-         of PCI sound chips.  These include the Maestro 1, Maestro 2, and
-         Maestro 2E.  See <file:Documentation/sound/oss/Maestro> for more
-         details.
-
-config SOUND_MAESTRO3
-       tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)"
-       depends on SOUND_PRIME && PCI && EXPERIMENTAL && OBSOLETE_OSS_DRIVER
-       help
-         Say Y or M if you have a sound system driven by ESS's Maestro 3
-         PCI sound chip.
-
 config SOUND_ICH
        tristate "Intel ICH (i8xx) audio support"
        depends on SOUND_PRIME && PCI
@@ -185,24 +85,6 @@ config SOUND_ICH
          Support for integral audio in Intel's I/O Controller Hub (ICH)
          chipset, as used on the 810/820/840 motherboards.
 
-config SOUND_HARMONY
-       tristate "PA Harmony audio driver"
-       depends on GSC_LASI && SOUND_PRIME && OBSOLETE_OSS_DRIVER
-       help
-         Say 'Y' or 'M' to include support for Harmony soundchip
-         on HP 712, 715/new and many other GSC based machines.
-
-config SOUND_SONICVIBES
-       tristate "S3 SonicVibes"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
-       help
-         Say Y or M if you have a PCI sound card utilizing the S3
-         SonicVibes chipset. To find out if your sound card uses a
-         SonicVibes chip without removing your computer's cover, use
-         lspci -n and look for the PCI ID 5333:CA00. This driver
-         differs slightly from OSS/Free, so PLEASE READ
-         <file:Documentation/sound/oss/sonicvibes>.
-
 config SOUND_VWSND
        tristate "SGI Visual Workstation Sound"
        depends on SOUND_PRIME && X86_VISWS
@@ -231,10 +113,6 @@ config SOUND_VRC5477
          integrated, multi-function controller chip for MIPS CPUs.  Works
          with the AC97 codec.
 
-config SOUND_AU1000
-       tristate "Au1000 Sound"
-       depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && OBSOLETE_OSS_DRIVER
-
 config SOUND_AU1550_AC97
        tristate "Au1550 AC97 Sound"
        depends on SOUND_PRIME && SOC_AU1550
@@ -507,7 +385,7 @@ config MSND_FIFOSIZE
 
 config SOUND_VIA82CXXX
        tristate "VIA 82C686 Audio Codec"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
+       depends on SOUND_PRIME && PCI
        help
          Say Y here to include support for the audio codec found on VIA
          82Cxxx-based chips. Typically these are built into a motherboard.
@@ -576,18 +454,6 @@ config SOUND_AD1889
          Say M here if you have a sound card based on the Analog Devices
          AD1889 chip.
 
-config SOUND_SGALAXY
-       tristate "Aztech Sound Galaxy (non-PnP) cards"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
-       help
-         This module initializes the older non Plug and Play sound galaxy
-         cards from Aztech. It supports the Waverider Pro 32 - 3D and the
-         Galaxy Washington 16.
-
-         If you compile the driver into the kernel, you have to add
-         "sgalaxy=<io>,<irq>,<dma>,<dma2>,<sgbase>" to the kernel command
-         line.
-
 config SOUND_ADLIB
        tristate "Adlib Cards"
        depends on SOUND_OSS
@@ -612,56 +478,6 @@ config SOUND_ACI_MIXER
 
          This driver is also available as a module and will be called aci.
 
-config SOUND_CS4232
-       tristate "Crystal CS4232 based (PnP) cards"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
-       help
-         Say Y here if you have a card based on the Crystal CS4232 chip set,
-         which uses its own Plug and Play protocol.
-
-         If you compile the driver into the kernel, you have to add
-         "cs4232=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the kernel
-         command line.
-
-         See <file:Documentation/sound/oss/CS4232> for more information on
-         configuring this card.
-
-config SOUND_SSCAPE
-       tristate "Ensoniq SoundScape support"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
-       help
-         Answer Y if you have a sound card based on the Ensoniq SoundScape
-         chipset. Such cards are being manufactured at least by Ensoniq, Spea
-         and Reveal (Reveal makes also other cards).
-
-         If you compile the driver into the kernel, you have to add
-         "sscape=<io>,<irq>,<dma>,<mpuio>,<mpuirq>" to the kernel command
-         line.
-
-config SOUND_GUS
-       tristate "Gravis Ultrasound support"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
-       help
-         Say Y here for any type of Gravis Ultrasound card, including the GUS
-         or GUS MAX.  See also <file:Documentation/sound/oss/ultrasound> for more
-         information on configuring this card with modules.
-
-         If you compile the driver into the kernel, you have to add
-         "gus=<io>,<irq>,<dma>,<dma2>" to the kernel command line.
-
-config SOUND_GUS16
-       bool "16 bit sampling option of GUS (_NOT_ GUS MAX)"
-       depends on SOUND_GUS
-       help
-         Support for Gravis Ulstrasound (GUS) cards (other than the GUS),
-         sampling at 16-bit width.
-
-config SOUND_GUSMAX
-       bool "GUS MAX support"
-       depends on SOUND_GUS
-       help
-         Support for Gravis Ulstrasound MAX.
-
 config SOUND_VMIDI
        tristate "Loopback MIDI device support"
        depends on SOUND_OSS
@@ -742,7 +558,7 @@ config SOUND_MPU401
 
 config SOUND_NM256
        tristate "NM256AV/NM256ZX audio support"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
+       depends on SOUND_OSS
        help
          Say M here to include audio support for the NeoMagic 256AV/256ZX
          chipsets. These are the audio chipsets found in the Sony
@@ -752,35 +568,6 @@ config SOUND_NM256
 
          See <file:Documentation/sound/oss/NM256> for further information.
 
-config SOUND_MAD16
-       tristate "OPTi MAD16 and/or Mozart based cards"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
-       ---help---
-         Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi
-         82C928 or 82C929 or 82C931) audio interface chip. These chips are
-         quite common so it's possible that many no-name cards have one of
-         them. In addition the MAD16 chip is used in some cards made by known
-         manufacturers such as Turtle Beach (Tropez), Reveal (some models)
-         and Diamond (latest ones). Note however that the Tropez sound cards
-         have their own driver; if you have one of those, say N here and Y or
-         M to "Full support for Turtle Beach WaveFront", below.
-
-         If you compile the driver into the kernel, you have to add
-         "mad16=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the
-         kernel command line.
-
-         See also <file:Documentation/sound/oss/Opti> and
-         <file:Documentation/sound/oss/MAD16> for more information on setting
-         these cards up as modules.
-
-config MAD16_OLDCARD
-       bool "Support MIDI in older MAD16 based cards (requires SB)"
-       depends on SOUND_MAD16
-       help
-         Answer Y (or M) if you have an older card based on the C928 or
-         Mozart chipset and you want to have MIDI support. If you enable this
-         option you also need to enable support for Sound Blaster.
-
 config SOUND_PAS
        tristate "ProAudioSpectrum 16 support"
        depends on SOUND_OSS
@@ -873,53 +660,9 @@ config SOUND_SB
          You can say M here to compile this driver as a module; the module is
          called sb.
 
-config SOUND_AWE32_SYNTH
-       tristate "AWE32 synth"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
-       help
-         Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or
-         similar sound card. See <file:Documentation/sound/oss/README.awe>,
-         <file:Documentation/sound/oss/AWE32> and the Soundblaster-AWE
-         mini-HOWTO, available from <http://www.tldp.org/docs.html#howto>
-         for more info.
-
-config SOUND_WAVEFRONT
-       tristate "Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards"
-       depends on SOUND_OSS && m && OBSOLETE_OSS_DRIVER
-       help
-         Answer Y or M if you have a Tropez Plus, Tropez or Maui sound card
-         and read the files <file:Documentation/sound/oss/Wavefront> and
-         <file:Documentation/sound/oss/Tropez+>.
-
-config SOUND_MAUI
-       tristate "Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
-       help
-         Say Y here if you have a Turtle Beach Wave Front, Maui, or Tropez
-         sound card.
-
-         If you compile the driver into the kernel, you have to add
-         "maui=<io>,<irq>" to the kernel command line.
-
-config MAUI_HAVE_BOOT
-       bool "Have OSWF.MOT firmware file"
-       depends on SOUND_MAUI=y && !STANDALONE
-       help
-         Turtle Beach Maui and Tropez sound cards have a microcontroller
-         which needs to be initialized prior to use. OSWF.MOT is a file
-         distributed with the card's DOS/Windows drivers. Answer Y if you
-         have this file.
-
-config MAUI_BOOT_FILE
-       string "Full pathname of OSWF.MOT firmware file"
-       depends on MAUI_HAVE_BOOT
-       default "/etc/sound/oswf.mot"
-       help
-         Enter the full pathname of your OSWF.MOT file, starting from /.
-
 config SOUND_YM3812
        tristate "Yamaha FM synthesizer (YM3812/OPL-3) support"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
+       depends on SOUND_OSS
        ---help---
          Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4).
          Answering Y is usually a safe and recommended choice, however some
@@ -933,18 +676,6 @@ config SOUND_YM3812
 
          If unsure, say Y.
 
-config SOUND_OPL3SA1
-       tristate "Yamaha OPL3-SA1 audio controller"
-       depends on SOUND_OSS && OBSOLETE_OSS_DRIVER
-       help
-         Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is
-         usually built into motherboards. Read
-         <file:Documentation/sound/oss/OPL3-SA> for details.
-
-         If you compile the driver into the kernel, you have to add
-         "opl3sa=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the kernel
-         command line.
-
 config SOUND_OPL3SA2
        tristate "Yamaha OPL3-SA2 and SA3 based PnP cards"
        depends on SOUND_OSS
@@ -959,19 +690,6 @@ config SOUND_OPL3SA2
          "opl3sa2=<io>,<irq>,<dma>,<dma2>,<mssio>,<mpuio>" to the kernel
          command line.
 
-config SOUND_YMFPCI
-       tristate "Yamaha YMF7xx PCI audio (native mode)"
-       depends on SOUND_OSS && PCI && OBSOLETE_OSS_DRIVER
-       help
-         Support for Yamaha cards including the YMF711, YMF715, YMF718,
-         YMF719, YMF724, Waveforce 192XG, and Waveforce 192 Digital.
-
-config SOUND_YMFPCI_LEGACY
-       bool "Yamaha PCI legacy ports support"
-       depends on SOUND_YMFPCI
-       help
-         Support for YMF7xx PCI cards emulating an MP401.
-
 config SOUND_UART6850
        tristate "6850 UART support"
        depends on SOUND_OSS
@@ -1101,30 +819,6 @@ config SOUND_KAHLUA
        tristate "XpressAudio Sound Blaster emulation"
        depends on SOUND_SB
 
-config SOUND_ALI5455
-       tristate "ALi5455 audio support"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
-
-config SOUND_FORTE
-       tristate "ForteMedia FM801 driver"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
-       help
-         Say Y or M if you want driver support for the ForteMedia FM801 PCI
-         audio controller (Abit AU10, Genius Sound Maker, HP Workstation
-         zx2000, and others).
-
-config SOUND_RME96XX
-       tristate "RME Hammerfall (RME96XX) support"
-       depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER
-       help
-         Say Y or M if you have a Hammerfall or Hammerfall light
-         multichannel card from RME. If you want to access advanced
-         features of the card, read <file:Documentation/sound/oss/rme96xx>.
-
-config SOUND_AD1980
-       tristate "AD1980 front/back switch plugin"
-       depends on SOUND_PRIME && OBSOLETE_OSS_DRIVER
-
 config SOUND_SH_DAC_AUDIO
        tristate "SuperH DAC audio support"
        depends on SOUND_PRIME && CPU_SH3
index 81315996c0f1bf142c840a8bf2c7e87d39c1ba44..882ae98a41b127c7b23d76d4465bc1cc3e5f2acf 100644 (file)
@@ -195,8 +195,8 @@ tas_init(int driver_id, const char *driver_name)
 
        printk(KERN_INFO "tas driver [%s])\n", driver_name);
 
-#ifndef CONFIG_I2C_KEYWEST
-       request_module("i2c-keywest");
+#ifndef CONFIG_I2C_POWERMAC
+       request_module("i2c-powermac");
 #endif
        tas_node = find_devices("deq");
        if (tas_node == NULL)
index aa09ebd9ffb8cfe9aed528a5e8f8d315bd9097a7..46eebf5610e39386cd3fc72eb40ccba456380d80 100644 (file)
@@ -255,7 +255,7 @@ int __init snd_pmac_daca_init(struct snd_pmac *chip)
 
 #ifdef CONFIG_KMOD
        if (current->fs->root)
-               request_module("i2c-keywest");
+               request_module("i2c-powermac");
 #endif /* CONFIG_KMOD */       
 
        mix = kmalloc(sizeof(*mix), GFP_KERNEL);
index 1146dd882bb1079b684e9e381bb87a239992f21e..70e4ebc70260deea11b06670272e863b29da7340 100644 (file)
@@ -1313,7 +1313,7 @@ int __init snd_pmac_tumbler_init(struct snd_pmac *chip)
 
 #ifdef CONFIG_KMOD
        if (current->fs->root)
-               request_module("i2c-keywest");
+               request_module("i2c-powermac");
 #endif /* CONFIG_KMOD */       
 
        mix = kmalloc(sizeof(*mix), GFP_KERNEL);
index 33dbcbf77c5b0d5713d4c6774e5c7f863d4750fb..83acd6cc0b3cd70325ec383eb8fdc309918a0a98 100644 (file)
@@ -471,6 +471,7 @@ int main (int argc, char *argv[])
                                "ERROR: incorrect format, could not locate file type line %d: '%s'\n",
                                line_nr, line);
                        ec = -1;
+                       break;
                }
 
                if ('\n' == *type) {
@@ -506,7 +507,8 @@ int main (int argc, char *argv[])
                                line_nr, line);
                }
        }
-       cpio_trailer();
+       if (ec == 0)
+               cpio_trailer();
 
        exit(ec);
 }
This page took 1.259168 seconds and 5 git commands to generate.