# HG changeset patch
# User Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
# Date 1191402044 -3600
# Node ID 3e8752eb6d9c63bbc49faf4873316aed366e07cf
# Parent aafef975e5186fe684b466235f26194bb89609be
Apply patch for 2.6.18.8.
Signed-off-by: Ian Campbell <ian.campbell@xxxxxxxxxxxxx>
---
include/asm-arm26/Kbuild | 1
include/asm-um/Kbuild | 1
Documentation/dontdiff | 1
Documentation/sysctl/vm.txt | 27
Makefile | 13
arch/alpha/Kconfig | 2
arch/arm/kernel/calls.S | 13
arch/i386/Kconfig.cpu | 3
arch/i386/kernel/alternative.c | 6
arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c | 3
arch/i386/kernel/microcode.c | 9
arch/i386/kernel/smpboot.c | 6
arch/i386/mm/boot_ioremap.c | 7
arch/i386/pci/irq.c | 4
arch/ia64/kernel/acpi.c | 13
arch/ia64/kernel/numa.c | 34
arch/ia64/kernel/topology.c | 4
arch/ia64/sn/kernel/bte.c | 9
arch/m32r/kernel/entry.S | 65 -
arch/powerpc/Kconfig | 9
arch/powerpc/configs/pseries_defconfig | 1
arch/powerpc/kernel/traps.c | 20
arch/ppc/kernel/traps.c | 20
arch/s390/Kconfig | 4
arch/s390/lib/Makefile | 1
arch/s390/lib/div64.c | 151 +++
arch/s390/lib/uaccess.S | 12
arch/s390/lib/uaccess64.S | 12
arch/sh/kernel/process.c | 1
arch/sparc/kernel/entry.S | 3
arch/sparc64/kernel/central.c | 4
arch/sparc64/kernel/entry.S | 3
arch/sparc64/kernel/of_device.c | 39
arch/sparc64/kernel/pci_common.c | 29
arch/sparc64/kernel/pci_iommu.c | 2
arch/sparc64/kernel/pci_sabre.c | 25
arch/sparc64/kernel/prom.c | 32
arch/sparc64/kernel/time.c | 2
arch/sparc64/mm/init.c | 3
arch/um/Kconfig | 5
arch/um/Makefile-x86_64 | 2
arch/um/include/common-offsets.h | 1
arch/um/include/kern_util.h | 1
arch/um/include/sysdep-i386/kernel-offsets.h | 1
arch/um/include/sysdep-x86_64/kernel-offsets.h | 1
arch/um/os-Linux/process.c | 4
arch/um/os-Linux/sys-i386/tls.c | 6
arch/um/os-Linux/tls.c | 9
arch/um/sys-x86_64/stub_segv.c | 1
arch/x86_64/ia32/ptrace32.c | 1
arch/x86_64/kernel/entry.S | 4
arch/x86_64/kernel/pci-calgary.c | 13
arch/x86_64/kernel/process.c | 7
arch/x86_64/kernel/setup.c | 5
arch/x86_64/kernel/setup64.c | 6
arch/x86_64/kernel/time.c | 2
block/elevator.c | 4
block/ll_rw_blk.c | 24
block/scsi_ioctl.c | 5
drivers/block/DAC960.c | 2
drivers/block/cciss.c | 6
drivers/block/cpqarray.c | 19
drivers/char/agp/generic.c | 2
drivers/char/agp/intel-agp.c | 2
drivers/char/hw_random/intel-rng.c | 188 +++
drivers/char/ipmi/ipmi_si_intf.c | 2
drivers/char/isicom.c | 3
drivers/char/mem.c | 12
drivers/char/rtc.c | 5
drivers/char/watchdog/sc1200wdt.c | 9
drivers/clocksource/scx200_hrt.c | 4
drivers/cpufreq/cpufreq_stats.c | 2
drivers/i2c/chips/ds1337.c | 8
drivers/ide/pci/generic.c | 18
drivers/ide/ppc/pmac.c | 2
drivers/ieee1394/ohci1394.c | 21
drivers/infiniband/core/mad.c | 2
drivers/infiniband/hw/mthca/mthca_cq.c | 7
drivers/infiniband/hw/mthca/mthca_mad.c | 2
drivers/infiniband/hw/mthca/mthca_qp.c | 19
drivers/infiniband/hw/mthca/mthca_srq.c | 8
drivers/infiniband/ulp/ipoib/ipoib_ib.c | 4
drivers/infiniband/ulp/srp/ib_srp.c | 2
drivers/infiniband/ulp/srp/ib_srp.h | 2
drivers/input/mouse/psmouse-base.c | 10
drivers/isdn/capi/capidrv.c | 3
drivers/isdn/hisax/config.c | 6
drivers/isdn/i4l/isdn_common.c | 9
drivers/isdn/icn/icn.c | 3
drivers/isdn/isdnloop/isdnloop.c | 3
drivers/isdn/pcbit/drv.c | 16
drivers/macintosh/via-pmu-backlight.c | 2
drivers/md/dm-crypt.c | 6
drivers/md/dm-snap.c | 1
drivers/md/md.c | 2
drivers/md/multipath.c | 2
drivers/md/raid10.c | 2
drivers/media/Kconfig | 1
drivers/media/dvb/b2c2/flexcop-fe-tuner.c | 2
drivers/media/dvb/dvb-core/dvb_net.c | 4
drivers/media/dvb/frontends/cx24123.c | 4
drivers/media/dvb/frontends/dvb-pll.c | 3
drivers/media/dvb/frontends/lgdt330x.c | 6
drivers/media/video/cx88/cx88-cards.c | 2
drivers/media/video/cx88/cx88-dvb.c | 14
drivers/media/video/ks0127.c | 8
drivers/media/video/msp3400-driver.c | 2
drivers/media/video/msp3400-driver.h | 1
drivers/media/video/msp3400-kthreads.c | 5
drivers/media/video/pvrusb2/Kconfig | 9
drivers/media/video/pvrusb2/pvrusb2-ctrl.c | 21
drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h | 2
drivers/media/video/pvrusb2/pvrusb2-hdw.c | 30
drivers/media/video/pvrusb2/pvrusb2-v4l2.c | 101 --
drivers/media/video/saa7134/saa7134-dvb.c | 4
drivers/media/video/tuner-simple.c | 2
drivers/media/video/tuner-types.c | 14
drivers/media/video/tveeprom.c | 2
drivers/media/video/usbvideo/quickcam_messenger.h | 14
drivers/media/video/video-buf.c | 1
drivers/media/video/videodev.c | 6
drivers/net/bonding/bond_main.c | 2
drivers/net/e1000/e1000_main.c | 7
drivers/net/forcedeth.c | 3
drivers/net/lp486e.c | 6
drivers/net/mv643xx_eth.c | 2
drivers/net/sky2.c | 95 +-
drivers/net/sky2.h | 2
drivers/net/sunhme.c | 5
drivers/net/tg3.c | 4
drivers/net/wireless/bcm43xx/bcm43xx.h | 183 +--
drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c | 80 +
drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h | 1
drivers/net/wireless/bcm43xx/bcm43xx_dma.c | 601 ++++++++----
drivers/net/wireless/bcm43xx/bcm43xx_dma.h | 296 ++++--
drivers/net/wireless/bcm43xx/bcm43xx_leds.c | 16
drivers/net/wireless/bcm43xx/bcm43xx_main.c | 997 ++++++++++++---------
drivers/net/wireless/bcm43xx/bcm43xx_main.h | 6
drivers/net/wireless/bcm43xx/bcm43xx_phy.c | 50 -
drivers/net/wireless/bcm43xx/bcm43xx_pio.c | 4
drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | 54 -
drivers/net/wireless/bcm43xx/bcm43xx_wx.c | 127 +-
drivers/net/wireless/bcm43xx/bcm43xx_xmit.h | 10
drivers/net/wireless/zd1211rw/zd_chip.c | 2
drivers/pci/pci-sysfs.c | 3
drivers/pci/quirks.c | 27
drivers/pcmcia/ds.c | 5
drivers/rtc/rtc-max6902.c | 2
drivers/rtc/rtc-pcf8563.c | 4
drivers/scsi/aic7xxx/aic7xxx_osm.c | 23
drivers/scsi/sata_mv.c | 1
drivers/scsi/scsi_lib.c | 2
drivers/serial/serial_core.c | 9
drivers/serial/serial_cs.c | 14
drivers/usb/class/usblp.c | 1
drivers/usb/core/devio.c | 28
drivers/usb/core/notify.c | 3
drivers/usb/core/usb.h | 1
drivers/usb/gadget/ether.c | 4
drivers/usb/input/hid-core.c | 4
drivers/usb/input/hid-input.c | 17
drivers/usb/input/hid.h | 1
drivers/usb/input/usbtouchscreen.c | 2
drivers/video/fbmem.c | 3
drivers/video/fbsysfs.c | 12
drivers/video/nvidia/nv_hw.c | 12
drivers/video/nvidia/nv_setup.c | 18
drivers/video/nvidia/nv_type.h | 1
drivers/video/nvidia/nvidia.c | 24
fs/buffer.c | 26
fs/cifs/CHANGES | 6
fs/cifs/file.c | 3
fs/cifs/inode.c | 14
fs/compat.c | 2
fs/ext2/super.c | 4
fs/ext3/super.c | 4
fs/fuse/dir.c | 82 +
fs/fuse/file.c | 12
fs/fuse/inode.c | 5
fs/hfs/super.c | 2
fs/jbd/commit.c | 188 ++-
fs/jfs/jfs_imap.c | 4
fs/nfs/dir.c | 14
fs/nfsd/nfs2acl.c | 17
fs/splice.c | 6
fs/sysfs/file.c | 5
include/Kbuild | 11
include/asm-alpha/Kbuild | 10
include/asm-arm/elf.h | 18
include/asm-arm/page.h | 4
include/asm-arm/unistd.h | 13
include/asm-cris/Kbuild | 4
include/asm-cris/arch-v10/Kbuild | 2
include/asm-cris/arch-v32/Kbuild | 2
include/asm-cris/byteorder.h | 3
include/asm-cris/elf.h | 8
include/asm-cris/page.h | 8
include/asm-cris/posix_types.h | 9
include/asm-cris/unistd.h | 4
include/asm-generic/Kbuild | 15
include/asm-generic/Kbuild.asm | 38
include/asm-generic/audit_change_attr.h | 4
include/asm-generic/audit_dir_write.h | 4
include/asm-h8300/page.h | 7
include/asm-i386/Kbuild | 9
include/asm-ia64/Kbuild | 18
include/asm-ia64/numa.h | 6
include/asm-m32r/page.h | 3
include/asm-m32r/ptrace.h | 32
include/asm-m32r/sigcontext.h | 13
include/asm-m32r/signal.h | 1
include/asm-m32r/unistd.h | 4
include/asm-m32r/user.h | 1
include/asm-m68knommu/page.h | 7
include/asm-powerpc/Kbuild | 45
include/asm-powerpc/current.h | 12
include/asm-powerpc/ptrace.h | 4
include/asm-s390/Kbuild | 11
include/asm-s390/div64.h | 48 -
include/asm-sh/page.h | 3
include/asm-sh/ptrace.h | 2
include/asm-sh64/page.h | 3
include/asm-sh64/shmparam.h | 16
include/asm-sh64/signal.h | 1
include/asm-sh64/user.h | 1
include/asm-sparc/Kbuild | 17
include/asm-sparc/page.h | 8
include/asm-sparc/unistd.h | 2
include/asm-sparc64/Kbuild | 24
include/asm-sparc64/futex.h | 18
include/asm-sparc64/page.h | 9
include/asm-sparc64/shmparam.h | 2
include/asm-sparc64/unistd.h | 2
include/asm-v850/page.h | 7
include/asm-v850/param.h | 4
include/asm-x86_64/Kbuild | 18
include/asm-x86_64/system.h | 5
include/linux/Kbuild | 400 +++++++-
include/linux/byteorder/Kbuild | 9
include/linux/dvb/Kbuild | 11
include/linux/mmzone.h | 15
include/linux/netfilter/Kbuild | 47
include/linux/netfilter_arp/Kbuild | 5
include/linux/netfilter_bridge/Kbuild | 21
include/linux/netfilter_ipv4.h | 2
include/linux/netfilter_ipv4/Kbuild | 82 +
include/linux/netfilter_ipv6/Kbuild | 27
include/linux/nfsd/Kbuild | 9
include/linux/raid/Kbuild | 3
include/linux/scx200.h | 2
include/linux/serial_core.h | 1
include/linux/stddef.h | 2
include/linux/sunrpc/Kbuild | 2
include/linux/swap.h | 1
include/linux/sysctl.h | 1
include/linux/tc_act/Kbuild | 5
include/linux/tc_ematch/Kbuild | 5
include/linux/ufs_fs.h | 2
include/media/cx2341x.h | 2
include/mtd/Kbuild | 8
include/rdma/Kbuild | 2
include/scsi/Kbuild | 4
include/sound/Kbuild | 12
include/video/Kbuild | 2
init/Kconfig | 1
kernel/module.c | 6
kernel/posix-cpu-timers.c | 27
kernel/sched.c | 54 -
kernel/softirq.c | 2
kernel/sysctl.c | 11
kernel/taskstats.c | 15
lib/audit.c | 2
mm/memory.c | 41
mm/migrate.c | 3
mm/mincore.c | 177 +--
mm/msync.c | 68 -
mm/page_alloc.c | 25
mm/shmem.c | 7
mm/slab.c | 2
mm/truncate.c | 34
mm/vmscan.c | 125 +-
mm/vmstat.c | 2
net/bluetooth/cmtp/capi.c | 39
net/bluetooth/hci_sock.c | 11
net/bluetooth/rfcomm/tty.c | 3
net/bridge/br_ioctl.c | 11
net/bridge/netfilter/ebtables.c | 54 -
net/core/dev.c | 16
net/core/skbuff.c | 1
net/core/sock.c | 2
net/dccp/ipv6.c | 2
net/decnet/af_decnet.c | 4
net/ieee80211/softmac/ieee80211softmac_io.c | 2
net/ieee80211/softmac/ieee80211softmac_scan.c | 2
net/ipv4/ipvs/ip_vs_core.c | 10
net/ipv4/netfilter.c | 9
net/ipv4/netfilter/arp_tables.c | 39
net/ipv4/netfilter/ip_conntrack_helper_h323.c | 4
net/ipv4/netfilter/ip_nat_standalone.c | 14
net/ipv4/netfilter/ip_tables.c | 116 +-
net/ipv4/netfilter/iptable_mangle.c | 3
net/ipv4/route.c | 2
net/ipv4/tcp.c | 4
net/ipv4/tcp_cubic.c | 6
net/ipv4/tcp_input.c | 18
net/ipv4/udp.c | 19
net/ipv4/xfrm4_policy.c | 2
net/ipv6/ip6_flowlabel.c | 2
net/ipv6/ipv6_sockglue.c | 3
net/ipv6/netfilter/ip6_tables.c | 53 -
net/ipv6/tcp_ipv6.c | 2
net/ipv6/udp.c | 7
net/irda/irttp.c | 4
net/netfilter/Kconfig | 6
net/sched/act_gact.c | 4
net/sched/act_police.c | 26
net/sched/cls_api.c | 4
net/sched/cls_basic.c | 2
net/sched/sch_api.c | 16
net/sched/sch_generic.c | 68 -
net/sctp/input.c | 3
net/sunrpc/svcsock.c | 2
security/seclvl.c | 2
sound/core/control.c | 1
sound/core/hwdep.c | 3
sound/core/info.c | 5
sound/core/rtctimer.c | 17
sound/pci/au88x0/au88x0.c | 1
sound/pci/emu10k1/emu10k1_main.c | 4
sound/ppc/keywest.c | 3
sound/usb/usx2y/usbusx2yaudio.c | 18
sound/usb/usx2y/usx2yhwdeppcm.c | 17
332 files changed, 4573 insertions(+), 2435 deletions(-)
diff -r aafef975e518 -r 3e8752eb6d9c Documentation/dontdiff
--- a/Documentation/dontdiff Tue Oct 02 09:52:15 2007 +0100
+++ b/Documentation/dontdiff Wed Oct 03 10:00:44 2007 +0100
@@ -135,6 +135,7 @@ times.h*
times.h*
tkparse
trix_boot.h
+utsrelease.h*
version.h*
vmlinux
vmlinux-*
diff -r aafef975e518 -r 3e8752eb6d9c Documentation/sysctl/vm.txt
--- a/Documentation/sysctl/vm.txt Tue Oct 02 09:52:15 2007 +0100
+++ b/Documentation/sysctl/vm.txt Wed Oct 03 10:00:44 2007 +0100
@@ -29,6 +29,7 @@ Currently, these files are in /proc/sys/
- drop-caches
- zone_reclaim_mode
- min_unmapped_ratio
+- min_slab_ratio
- panic_on_oom
==============================================================
@@ -138,7 +139,6 @@ 1 = Zone reclaim on
1 = Zone reclaim on
2 = Zone reclaim writes dirty pages out
4 = Zone reclaim swaps pages
-8 = Also do a global slab reclaim pass
zone_reclaim_mode is set during bootup to 1 if it is determined that pages
from remote zones will cause a measurable performance reduction. The
@@ -162,23 +162,36 @@ node unless explicitly overridden by mem
node unless explicitly overridden by memory policies or cpuset
configurations.
-It may be advisable to allow slab reclaim if the system makes heavy
-use of files and builds up large slab caches. However, the slab
-shrink operation is global, may take a long time and free slabs
-in all nodes of the system.
-
=============================================================
min_unmapped_ratio:
This is available only on NUMA kernels.
-A percentage of the file backed pages in each zone. Zone reclaim will only
+A percentage of the total pages in each zone. Zone reclaim will only
occur if more than this percentage of pages are file backed and unmapped.
This is to insure that a minimal amount of local pages is still available for
file I/O even if the node is overallocated.
The default is 1 percent.
+
+=============================================================
+
+min_slab_ratio:
+
+This is available only on NUMA kernels.
+
+A percentage of the total pages in each zone. On Zone reclaim
+(fallback from the local zone occurs) slabs will be reclaimed if more
+than this percentage of pages in a zone are reclaimable slab pages.
+This insures that the slab growth stays under control even in NUMA
+systems that rarely perform global reclaim.
+
+The default is 5 percent.
+
+Note that slab reclaim is triggered in a per zone / node fashion.
+The process of reclaiming slab memory is currently not node specific
+and may not be fast.
=============================================================
diff -r aafef975e518 -r 3e8752eb6d9c Makefile
--- a/Makefile Tue Oct 02 09:52:15 2007 +0100
+++ b/Makefile Wed Oct 03 10:00:44 2007 +0100
@@ -1,7 +1,7 @@ VERSION = 2
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 18
-EXTRAVERSION =
+EXTRAVERSION = .8
NAME=Avast! A bilge rat!
# *DOCUMENTATION*
@@ -894,6 +894,9 @@ export INSTALL_HDR_PATH
PHONY += headers_install
headers_install: include/linux/version.h
+ @if [ ! -r include/asm-$(ARCH)/Kbuild ]; then \
+ echo '*** Error: Headers not exportable for this architecture
($(ARCH))'; \
+ exit 1 ; fi
$(Q)unifdef -Ux /dev/null
$(Q)rm -rf $(INSTALL_HDR_PATH)/include
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.headersinst obj=include
@@ -1076,13 +1079,17 @@ help:
@echo ' cscope - Generate cscope index'
@echo ' kernelrelease - Output the release version string'
@echo ' kernelversion - Output the version stored in Makefile'
- @echo ' headers_install - Install sanitised kernel headers to
INSTALL_HDR_PATH'
+ @if [ -r include/asm-$(ARCH)/Kbuild ]; then \
+ echo ' headers_install - Install sanitised kernel headers to
INSTALL_HDR_PATH'; \
+ fi
@echo ' (default: $(INSTALL_HDR_PATH))'
@echo ''
@echo 'Static analysers'
@echo ' checkstack - Generate a list of stack hogs'
@echo ' namespacecheck - Name space analysis on compiled kernel'
- @echo ' headers_check - Sanity check on exported headers'
+ @if [ -r include/asm-$(ARCH)/Kbuild ]; then \
+ echo ' headers_check - Sanity check on exported headers'; \
+ fi
@echo ''
@echo 'Kernel packaging:'
@$(MAKE) $(build)=$(package-dir) help
diff -r aafef975e518 -r 3e8752eb6d9c arch/alpha/Kconfig
--- a/arch/alpha/Kconfig Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/alpha/Kconfig Wed Oct 03 10:00:44 2007 +0100
@@ -381,7 +381,7 @@ config ALPHA_EV56
config ALPHA_EV56
prompt "EV56 CPU (speed >= 333MHz)?"
- depends on ALPHA_NORITAKE && ALPHA_PRIMO
+ depends on ALPHA_NORITAKE || ALPHA_PRIMO
config ALPHA_EV56
prompt "EV56 CPU (speed >= 400MHz)?"
diff -r aafef975e518 -r 3e8752eb6d9c arch/arm/kernel/calls.S
--- a/arch/arm/kernel/calls.S Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/arm/kernel/calls.S Wed Oct 03 10:00:44 2007 +0100
@@ -331,6 +331,19 @@
CALL(sys_mbind)
/* 320 */ CALL(sys_get_mempolicy)
CALL(sys_set_mempolicy)
+ CALL(sys_openat)
+ CALL(sys_mkdirat)
+ CALL(sys_mknodat)
+/* 325 */ CALL(sys_fchownat)
+ CALL(sys_futimesat)
+ CALL(sys_fstatat64)
+ CALL(sys_unlinkat)
+ CALL(sys_renameat)
+/* 330 */ CALL(sys_linkat)
+ CALL(sys_symlinkat)
+ CALL(sys_readlinkat)
+ CALL(sys_fchmodat)
+ CALL(sys_faccessat)
#ifndef syscalls_counted
.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
#define syscalls_counted
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/Kconfig.cpu
--- a/arch/i386/Kconfig.cpu Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/Kconfig.cpu Wed Oct 03 10:00:44 2007 +0100
@@ -7,6 +7,7 @@ choice
config M386
bool "386"
+ depends on !UML
---help---
This is the processor type of your CPU. This information is used for
optimizing purposes. In order to compile a kernel that can run on
@@ -301,7 +302,7 @@ config X86_USE_PPRO_CHECKSUM
config X86_USE_3DNOW
bool
- depends on MCYRIXIII || MK7 || MGEODE_LX
+ depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML
default y
config X86_OOSTORE
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/kernel/alternative.c
--- a/arch/i386/kernel/alternative.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/kernel/alternative.c Wed Oct 03 10:00:44 2007 +0100
@@ -344,6 +344,7 @@ void alternatives_smp_switch(int smp)
void __init alternative_instructions(void)
{
+ unsigned long flags;
if (no_replacement) {
printk(KERN_INFO "(SMP-)alternatives turned off\n");
free_init_pages("SMP alternatives",
@@ -351,6 +352,8 @@ void __init alternative_instructions(voi
(unsigned long)__smp_alt_end);
return;
}
+
+ local_irq_save(flags);
apply_alternatives(__alt_instructions, __alt_instructions_end);
/* switch to patch-once-at-boottime-only mode and free the
@@ -386,4 +389,5 @@ void __init alternative_instructions(voi
alternatives_smp_switch(0);
}
#endif
-}
+ local_irq_restore(flags);
+}
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c
--- a/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c Tue Oct 02 09:52:15
2007 +0100
+++ b/arch/i386/kernel/cpu/cpufreq/acpi-cpufreq.c Wed Oct 03 10:00:44
2007 +0100
@@ -560,7 +560,6 @@ static struct cpufreq_driver acpi_cpufre
.name = "acpi-cpufreq",
.owner = THIS_MODULE,
.attr = acpi_cpufreq_attr,
- .flags = CPUFREQ_STICKY,
};
@@ -571,7 +570,7 @@ acpi_cpufreq_init (void)
acpi_cpufreq_early_init_acpi();
- return cpufreq_register_driver(&acpi_cpufreq_driver);
+ return cpufreq_register_driver(&acpi_cpufreq_driver);
}
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/kernel/microcode.c
--- a/arch/i386/kernel/microcode.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/kernel/microcode.c Wed Oct 03 10:00:44 2007 +0100
@@ -250,14 +250,14 @@ static int find_matching_ucodes (void)
}
total_size = get_totalsize(&mc_header);
- if ((cursor + total_size > user_buffer_size) || (total_size <
DEFAULT_UCODE_TOTALSIZE)) {
+ if (cursor + total_size > user_buffer_size) {
printk(KERN_ERR "microcode: error! Bad data in
microcode data file\n");
error = -EINVAL;
goto out;
}
data_size = get_datasize(&mc_header);
- if ((data_size + MC_HEADER_SIZE > total_size) || (data_size <
DEFAULT_UCODE_DATASIZE)) {
+ if (data_size + MC_HEADER_SIZE > total_size) {
printk(KERN_ERR "microcode: error! Bad data in
microcode data file\n");
error = -EINVAL;
goto out;
@@ -460,11 +460,6 @@ static ssize_t microcode_write (struct f
{
ssize_t ret;
- if (len < DEFAULT_UCODE_TOTALSIZE) {
- printk(KERN_ERR "microcode: not enough data\n");
- return -EINVAL;
- }
-
if ((len >> PAGE_SHIFT) > num_physpages) {
printk(KERN_ERR "microcode: too much data (max %ld pages)\n",
num_physpages);
return -EINVAL;
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/kernel/smpboot.c
--- a/arch/i386/kernel/smpboot.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/kernel/smpboot.c Wed Oct 03 10:00:44 2007 +0100
@@ -642,9 +642,13 @@ static void map_cpu_to_logical_apicid(vo
{
int cpu = smp_processor_id();
int apicid = logical_smp_processor_id();
+ int node = apicid_to_node(apicid);
+
+ if (!node_online(node))
+ node = first_online_node;
cpu_2_logical_apicid[cpu] = apicid;
- map_cpu_to_node(cpu, apicid_to_node(apicid));
+ map_cpu_to_node(cpu, node);
}
static void unmap_cpu_to_logical_apicid(int cpu)
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/mm/boot_ioremap.c
--- a/arch/i386/mm/boot_ioremap.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/mm/boot_ioremap.c Wed Oct 03 10:00:44 2007 +0100
@@ -29,8 +29,11 @@
*/
#define BOOT_PTE_PTRS (PTRS_PER_PTE*2)
-#define boot_pte_index(address) \
- (((address) >> PAGE_SHIFT) & (BOOT_PTE_PTRS - 1))
+
+static unsigned long boot_pte_index(unsigned long vaddr)
+{
+ return __pa(vaddr) >> PAGE_SHIFT;
+}
static inline boot_pte_t* boot_vaddr_to_pte(void *address)
{
diff -r aafef975e518 -r 3e8752eb6d9c arch/i386/pci/irq.c
--- a/arch/i386/pci/irq.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/i386/pci/irq.c Wed Oct 03 10:00:44 2007 +0100
@@ -255,13 +255,13 @@ static int pirq_via_set(struct pci_dev *
*/
static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int
pirq)
{
- static const unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+ static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
return read_config_nybble(router, 0x55, pirqmap[pirq-1]);
}
static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int
pirq, int irq)
{
- static const unsigned int pirqmap[4] = { 3, 2, 5, 1 };
+ static const unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 };
write_config_nybble(router, 0x55, pirqmap[pirq-1], irq);
return 1;
}
diff -r aafef975e518 -r 3e8752eb6d9c arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ia64/kernel/acpi.c Wed Oct 03 10:00:44 2007 +0100
@@ -777,16 +777,19 @@ int acpi_map_cpu2node(acpi_handle handle
{
#ifdef CONFIG_ACPI_NUMA
int pxm_id;
+ int nid;
pxm_id = acpi_get_pxm(handle);
-
/*
- * Assuming that the container driver would have set the proximity
- * domain and would have initialized pxm_to_node(pxm_id) && pxm_flag
+ * We don't have cpu-only-node hotadd. But if the system equips
+ * SRAT table, pxm is already found and node is ready.
+ * So, just pxm_to_nid(pxm) is OK.
+ * This code here is for the system which doesn't have full SRAT
+ * table for possible cpus.
*/
- node_cpuid[cpu].nid = (pxm_id < 0) ? 0 : pxm_to_node(pxm_id);
-
+ nid = acpi_map_pxm_to_node(pxm_id);
node_cpuid[cpu].phys_id = physid;
+ node_cpuid[cpu].nid = nid;
#endif
return (0);
}
diff -r aafef975e518 -r 3e8752eb6d9c arch/ia64/kernel/numa.c
--- a/arch/ia64/kernel/numa.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ia64/kernel/numa.c Wed Oct 03 10:00:44 2007 +0100
@@ -29,6 +29,36 @@ EXPORT_SYMBOL(cpu_to_node_map);
cpumask_t node_to_cpu_mask[MAX_NUMNODES] __cacheline_aligned;
+void __cpuinit map_cpu_to_node(int cpu, int nid)
+{
+ int oldnid;
+ if (nid < 0) { /* just initialize by zero */
+ cpu_to_node_map[cpu] = 0;
+ return;
+ }
+ /* sanity check first */
+ oldnid = cpu_to_node_map[cpu];
+ if (cpu_isset(cpu, node_to_cpu_mask[oldnid])) {
+ return; /* nothing to do */
+ }
+ /* we don't have cpu-driven node hot add yet...
+ In usual case, node is created from SRAT at boot time. */
+ if (!node_online(nid))
+ nid = first_online_node;
+ cpu_to_node_map[cpu] = nid;
+ cpu_set(cpu, node_to_cpu_mask[nid]);
+ return;
+}
+
+void __cpuinit unmap_cpu_from_node(int cpu, int nid)
+{
+ WARN_ON(!cpu_isset(cpu, node_to_cpu_mask[nid]));
+ WARN_ON(cpu_to_node_map[cpu] != nid);
+ cpu_to_node_map[cpu] = 0;
+ cpu_clear(cpu, node_to_cpu_mask[nid]);
+}
+
+
/**
* build_cpu_to_node_map - setup cpu to node and node to cpumask arrays
*
@@ -49,8 +79,6 @@ void __init build_cpu_to_node_map(void)
node = node_cpuid[i].nid;
break;
}
- cpu_to_node_map[cpu] = (node >= 0) ? node : 0;
- if (node >= 0)
- cpu_set(cpu, node_to_cpu_mask[node]);
+ map_cpu_to_node(cpu, node);
}
}
diff -r aafef975e518 -r 3e8752eb6d9c arch/ia64/kernel/topology.c
--- a/arch/ia64/kernel/topology.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ia64/kernel/topology.c Wed Oct 03 10:00:44 2007 +0100
@@ -36,6 +36,7 @@ int arch_register_cpu(int num)
*/
if (!can_cpei_retarget() && is_cpu_cpei_target(num))
sysfs_cpus[num].cpu.no_control = 1;
+ map_cpu_to_node(num, node_cpuid[num].nid);
#endif
return register_cpu(&sysfs_cpus[num].cpu, num);
@@ -45,7 +46,8 @@ int arch_register_cpu(int num)
void arch_unregister_cpu(int num)
{
- return unregister_cpu(&sysfs_cpus[num].cpu);
+ unregister_cpu(&sysfs_cpus[num].cpu);
+ unmap_cpu_from_node(num, cpu_to_node(num));
}
EXPORT_SYMBOL(arch_register_cpu);
EXPORT_SYMBOL(arch_unregister_cpu);
diff -r aafef975e518 -r 3e8752eb6d9c arch/ia64/sn/kernel/bte.c
--- a/arch/ia64/sn/kernel/bte.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ia64/sn/kernel/bte.c Wed Oct 03 10:00:44 2007 +0100
@@ -382,14 +382,13 @@ bte_result_t bte_unaligned_copy(u64 src,
* bcopy to the destination.
*/
- /* Add the leader from source */
- headBteLen = len + (src & L1_CACHE_MASK);
- /* Add the trailing bytes from footer. */
- headBteLen += L1_CACHE_BYTES - (headBteLen & L1_CACHE_MASK);
- headBteSource = src & ~L1_CACHE_MASK;
headBcopySrcOffset = src & L1_CACHE_MASK;
headBcopyDest = dest;
headBcopyLen = len;
+
+ headBteSource = src - headBcopySrcOffset;
+ /* Add the leading and trailing bytes from source */
+ headBteLen = L1_CACHE_ALIGN(len + headBcopySrcOffset);
}
if (headBcopyLen > 0) {
diff -r aafef975e518 -r 3e8752eb6d9c arch/m32r/kernel/entry.S
--- a/arch/m32r/kernel/entry.S Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/m32r/kernel/entry.S Wed Oct 03 10:00:44 2007 +0100
@@ -23,35 +23,35 @@
* updated in fork.c:copy_thread, signal.c:do_signal,
* ptrace.c and ptrace.h
*
- * M32Rx/M32R2 M32R
- * @(sp) - r4 ditto
- * @(0x04,sp) - r5 ditto
- * @(0x08,sp) - r6 ditto
- * @(0x0c,sp) - *pt_regs ditto
- * @(0x10,sp) - r0 ditto
- * @(0x14,sp) - r1 ditto
- * @(0x18,sp) - r2 ditto
- * @(0x1c,sp) - r3 ditto
- * @(0x20,sp) - r7 ditto
- * @(0x24,sp) - r8 ditto
- * @(0x28,sp) - r9 ditto
- * @(0x2c,sp) - r10 ditto
- * @(0x30,sp) - r11 ditto
- * @(0x34,sp) - r12 ditto
- * @(0x38,sp) - syscall_nr ditto
- * @(0x3c,sp) - acc0h @(0x3c,sp) - acch
- * @(0x40,sp) - acc0l @(0x40,sp) - accl
- * @(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
+ * M32R/M32Rx/M32R2
+ * @(sp) - r4
+ * @(0x04,sp) - r5
+ * @(0x08,sp) - r6
+ * @(0x0c,sp) - *pt_regs
+ * @(0x10,sp) - r0
+ * @(0x14,sp) - r1
+ * @(0x18,sp) - r2
+ * @(0x1c,sp) - r3
+ * @(0x20,sp) - r7
+ * @(0x24,sp) - r8
+ * @(0x28,sp) - r9
+ * @(0x2c,sp) - r10
+ * @(0x30,sp) - r11
+ * @(0x34,sp) - r12
+ * @(0x38,sp) - syscall_nr
+ * @(0x3c,sp) - acc0h
+ * @(0x40,sp) - acc0l
+ * @(0x44,sp) - acc1h ; ISA_DSP_LEVEL2 only
+ * @(0x48,sp) - acc1l ; ISA_DSP_LEVEL2 only
+ * @(0x4c,sp) - psw
+ * @(0x50,sp) - bpc
+ * @(0x54,sp) - bbpsw
+ * @(0x58,sp) - bbpc
+ * @(0x5c,sp) - spu (cr3)
+ * @(0x60,sp) - fp (r13)
+ * @(0x64,sp) - lr (r14)
+ * @(0x68,sp) - spi (cr2)
+ * @(0x6c,sp) - orig_r0
*/
#include <linux/linkage.h>
@@ -95,17 +95,10 @@
#define R11(reg) @(0x30,reg)
#define R12(reg) @(0x34,reg)
#define SYSCALL_NR(reg) @(0x38,reg)
-#if defined(CONFIG_ISA_M32R2) && defined(CONFIG_ISA_DSP_LEVEL2)
#define ACC0H(reg) @(0x3C,reg)
#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)
diff -r aafef975e518 -r 3e8752eb6d9c arch/powerpc/Kconfig
--- a/arch/powerpc/Kconfig Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/powerpc/Kconfig Wed Oct 03 10:00:44 2007 +0100
@@ -740,6 +740,15 @@ config ARCH_MEMORY_PROBE
def_bool y
depends on MEMORY_HOTPLUG
+# Some NUMA nodes have memory ranges that span
+# other nodes. Even though a pfn is valid and
+# between a node's start and end pfns, it may not
+# reside on that node. See memmap_init_zone()
+# for details.
+config NODES_SPAN_OTHER_NODES
+ def_bool y
+ depends on NEED_MULTIPLE_NODES
+
config PPC_64K_PAGES
bool "64k page size"
depends on PPC64
diff -r aafef975e518 -r 3e8752eb6d9c arch/powerpc/configs/pseries_defconfig
--- a/arch/powerpc/configs/pseries_defconfig Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/powerpc/configs/pseries_defconfig Wed Oct 03 10:00:44 2007 +0100
@@ -184,6 +184,7 @@ CONFIG_MIGRATION=y
CONFIG_MIGRATION=y
CONFIG_RESOURCES_64BIT=y
CONFIG_HAVE_ARCH_EARLY_PFN_TO_NID=y
+CONFIG_NODES_SPAN_OTHER_NODES=y
# CONFIG_PPC_64K_PAGES is not set
CONFIG_SCHED_SMT=y
CONFIG_PROC_DEVICETREE=y
diff -r aafef975e518 -r 3e8752eb6d9c arch/powerpc/kernel/traps.c
--- a/arch/powerpc/kernel/traps.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/powerpc/kernel/traps.c Wed Oct 03 10:00:44 2007 +0100
@@ -818,7 +818,7 @@ void __kprobes program_check_exception(s
void alignment_exception(struct pt_regs *regs)
{
- int fixed = 0;
+ int sig, code, fixed = 0;
/* we don't implement logging of alignment exceptions */
if (!(current->thread.align_ctl & PR_UNALIGN_SIGBUS))
@@ -832,14 +832,16 @@ void alignment_exception(struct pt_regs
/* Operand address was bad */
if (fixed == -EFAULT) {
- if (user_mode(regs))
- _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
- else
- /* Search exception table */
- bad_page_fault(regs, regs->dar, SIGSEGV);
- return;
- }
- _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+ sig = SIGSEGV;
+ code = SEGV_ACCERR;
+ } else {
+ sig = SIGBUS;
+ code = BUS_ADRALN;
+ }
+ if (user_mode(regs))
+ _exception(sig, regs, code, regs->dar);
+ else
+ bad_page_fault(regs, regs->dar, sig);
}
void StackOverflow(struct pt_regs *regs)
diff -r aafef975e518 -r 3e8752eb6d9c arch/ppc/kernel/traps.c
--- a/arch/ppc/kernel/traps.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/ppc/kernel/traps.c Wed Oct 03 10:00:44 2007 +0100
@@ -708,7 +708,7 @@ void single_step_exception(struct pt_reg
void alignment_exception(struct pt_regs *regs)
{
- int fixed;
+ int sig, code, fixed = 0;
fixed = fix_alignment(regs);
if (fixed == 1) {
@@ -717,14 +717,16 @@ void alignment_exception(struct pt_regs
return;
}
if (fixed == -EFAULT) {
- /* fixed == -EFAULT means the operand address was bad */
- if (user_mode(regs))
- _exception(SIGSEGV, regs, SEGV_ACCERR, regs->dar);
- else
- bad_page_fault(regs, regs->dar, SIGSEGV);
- return;
- }
- _exception(SIGBUS, regs, BUS_ADRALN, regs->dar);
+ sig = SIGSEGV;
+ code = SEGV_ACCERR;
+ } else {
+ sig = SIGBUS;
+ code = BUS_ADRALN;
+ }
+ if (user_mode(regs))
+ _exception(sig, regs, code, regs->dar);
+ else
+ bad_page_fault(regs, regs->dar, sig);
}
void StackOverflow(struct pt_regs *regs)
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/Kconfig
--- a/arch/s390/Kconfig Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/s390/Kconfig Wed Oct 03 10:00:44 2007 +0100
@@ -50,6 +50,10 @@ config 64BIT
help
Select this option if you have a 64 bit IBM zSeries machine
and want to use the 64 bit addressing mode.
+
+config 32BIT
+ bool
+ default y if !64BIT
config SMP
bool "Symmetric multi-processing support"
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/lib/Makefile
--- a/arch/s390/lib/Makefile Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/s390/lib/Makefile Wed Oct 03 10:00:44 2007 +0100
@@ -7,3 +7,4 @@ lib-y += delay.o string.o
lib-y += delay.o string.o
lib-y += $(if $(CONFIG_64BIT),uaccess64.o,uaccess.o)
lib-$(CONFIG_SMP) += spinlock.o
+lib-$(CONFIG_32BIT) += div64.o
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/lib/div64.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/s390/lib/div64.c Wed Oct 03 10:00:44 2007 +0100
@@ -0,0 +1,151 @@
+/*
+ * arch/s390/lib/div64.c
+ *
+ * __div64_32 implementation for 31 bit.
+ *
+ * Copyright (C) IBM Corp. 2006
+ * Author(s): Martin Schwidefsky (schwidefsky@xxxxxxxxxx),
+ */
+
+#include <linux/types.h>
+#include <linux/module.h>
+
+#ifdef CONFIG_MARCH_G5
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 31 bit integer using signed 64/32 bit division.
+ */
+static uint32_t __div64_31(uint64_t *n, uint32_t base)
+{
+ register uint32_t reg2 asm("2");
+ register uint32_t reg3 asm("3");
+ uint32_t *words = (uint32_t *) n;
+ uint32_t tmp;
+
+ /* Special case base==1, remainder = 0, quotient = n */
+ if (base == 1)
+ return 0;
+ /*
+ * Special case base==0 will cause a fixed point divide exception
+ * on the dr instruction and may not happen anyway. For the
+ * following calculation we can assume base > 1. The first
+ * signed 64 / 32 bit division with an upper half of 0 will
+ * give the correct upper half of the 64 bit quotient.
+ */
+ reg2 = 0UL;
+ reg3 = words[0];
+ asm volatile(
+ " dr %0,%2\n"
+ : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+ words[0] = reg3;
+ reg3 = words[1];
+ /*
+ * To get the lower half of the 64 bit quotient and the 32 bit
+ * remainder we have to use a little trick. Since we only have
+ * a signed division the quotient can get too big. To avoid this
+ * the 64 bit dividend is halved, then the signed division will
+ * work. Afterwards the quotient and the remainder are doubled.
+ * If the last bit of the dividend has been one the remainder
+ * is increased by one then checked against the base. If the
+ * remainder has overflown subtract base and increase the
+ * quotient. Simple, no ?
+ */
+ asm volatile(
+ " nr %2,%1\n"
+ " srdl %0,1\n"
+ " dr %0,%3\n"
+ " alr %0,%0\n"
+ " alr %1,%1\n"
+ " alr %0,%2\n"
+ " clr %0,%3\n"
+ " jl 0f\n"
+ " slr %0,%3\n"
+ " alr %1,%2\n"
+ "0:\n"
+ : "+d" (reg2), "+d" (reg3), "=d" (tmp)
+ : "d" (base), "2" (1UL) : "cc" );
+ words[1] = reg3;
+ return reg2;
+}
+
+/*
+ * Function to divide an unsigned 64 bit integer by an unsigned
+ * 32 bit integer using the unsigned 64/31 bit division.
+ */
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+ uint32_t r;
+
+ /*
+ * If the most significant bit of base is set, divide n by
+ * (base/2). That allows to use 64/31 bit division and gives a
+ * good approximation of the result: n = (base/2)*q + r. The
+ * result needs to be corrected with two simple transformations.
+ * If base is already < 2^31-1 __div64_31 can be used directly.
+ */
+ r = __div64_31(n, ((signed) base < 0) ? (base/2) : base);
+ if ((signed) base < 0) {
+ uint64_t q = *n;
+ /*
+ * First transformation:
+ * n = (base/2)*q + r
+ * = ((base/2)*2)*(q/2) + ((q&1) ? (base/2) : 0) + r
+ * Since r < (base/2), r + (base/2) < base.
+ * With q1 = (q/2) and r1 = r + ((q&1) ? (base/2) : 0)
+ * n = ((base/2)*2)*q1 + r1 with r1 < base.
+ */
+ if (q & 1)
+ r += base/2;
+ q >>= 1;
+ /*
+ * Second transformation. ((base/2)*2) could have lost the
+ * last bit.
+ * n = ((base/2)*2)*q1 + r1
+ * = base*q1 - ((base&1) ? q1 : 0) + r1
+ */
+ if (base & 1) {
+ int64_t rx = r - q;
+ /*
+ * base is >= 2^31. The worst case for the while
+ * loop is n=2^64-1 base=2^31+1. That gives a
+ * maximum for q=(2^64-1)/2^31 = 0x1ffffffff. Since
+ * base >= 2^31 the loop is finished after a maximum
+ * of three iterations.
+ */
+ while (rx < 0) {
+ rx += base;
+ q--;
+ }
+ r = rx;
+ }
+ *n = q;
+ }
+ return r;
+}
+
+#else /* MARCH_G5 */
+
+uint32_t __div64_32(uint64_t *n, uint32_t base)
+{
+ register uint32_t reg2 asm("2");
+ register uint32_t reg3 asm("3");
+ uint32_t *words = (uint32_t *) n;
+
+ reg2 = 0UL;
+ reg3 = words[0];
+ asm volatile(
+ " dlr %0,%2\n"
+ : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+ words[0] = reg3;
+ reg3 = words[1];
+ asm volatile(
+ " dlr %0,%2\n"
+ : "+d" (reg2), "+d" (reg3) : "d" (base) : "cc" );
+ words[1] = reg3;
+ return reg2;
+}
+
+#endif /* MARCH_G5 */
+
+EXPORT_SYMBOL(__div64_32);
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/lib/uaccess.S
--- a/arch/s390/lib/uaccess.S Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/s390/lib/uaccess.S Wed Oct 03 10:00:44 2007 +0100
@@ -40,7 +40,17 @@ 4: lhi %r0,-4096
# move with the reduced length which is < 256
5: mvcp 0(%r5,%r2),0(%r4),%r0
slr %r3,%r5
-6: lr %r2,%r3
+ alr %r2,%r5
+6: lr %r5,%r3 # copy remaining size
+ ahi %r5,-1 # subtract 1 for xc loop
+ bras %r4,8f
+ xc 0(1,%r2),0(%r2)
+7: xc 0(256,%r2),0(%r2)
+ la %r2,256(%r2)
+8: ahi %r5,-256
+ jnm 7b
+ ex %r5,0(%r4)
+9: lr %r2,%r3
br %r14
.section __ex_table,"a"
.long 0b,4b
diff -r aafef975e518 -r 3e8752eb6d9c arch/s390/lib/uaccess64.S
--- a/arch/s390/lib/uaccess64.S Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/s390/lib/uaccess64.S Wed Oct 03 10:00:44 2007 +0100
@@ -40,7 +40,17 @@ 4: lghi %r0,-4096
# move with the reduced length which is < 256
5: mvcp 0(%r5,%r2),0(%r4),%r0
slgr %r3,%r5
-6: lgr %r2,%r3
+ algr %r2,%r5
+6: lgr %r5,%r3 # copy remaining size
+ aghi %r5,-1 # subtract 1 for xc loop
+ bras %r4,8f
+ xc 0(1,%r2),0(%r2)
+7: xc 0(256,%r2),0(%r2)
+ la %r2,256(%r2)
+8: aghi %r5,-256
+ jnm 7b
+ ex %r5,0(%r4)
+9: lgr %r2,%r3
br %r14
.section __ex_table,"a"
.quad 0b,4b
diff -r aafef975e518 -r 3e8752eb6d9c arch/sh/kernel/process.c
--- a/arch/sh/kernel/process.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sh/kernel/process.c Wed Oct 03 10:00:44 2007 +0100
@@ -26,6 +26,7 @@
#include <asm/uaccess.h>
#include <asm/mmu_context.h>
#include <asm/elf.h>
+#include <asm/ubc.h>
static int hlt_counter=0;
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc/kernel/entry.S
--- a/arch/sparc/kernel/entry.S Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc/kernel/entry.S Wed Oct 03 10:00:44 2007 +0100
@@ -32,12 +32,11 @@
#include <asm/mxcc.h>
#include <asm/thread_info.h>
#include <asm/param.h>
+#include <asm/unistd.h>
#include <asm/asmmacro.h>
#define curptr g6
-
-#define NR_SYSCALLS 300 /* Each OS is different... */
/* These are just handy. */
#define _SV save %sp, -STACKFRAME_SZ, %sp
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/central.c
--- a/arch/sparc64/kernel/central.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/central.c Wed Oct 03 10:00:44 2007 +0100
@@ -125,6 +125,10 @@ static void probe_other_fhcs(void)
struct linux_fhc *fhc;
int board;
u32 tmp;
+
+ if (dp->parent &&
+ dp->parent->parent != NULL)
+ continue;
fhc = (struct linux_fhc *)
central_alloc_bootmem(sizeof(struct linux_fhc));
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/entry.S
--- a/arch/sparc64/kernel/entry.S Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/entry.S Wed Oct 03 10:00:44 2007 +0100
@@ -22,10 +22,9 @@
#include <asm/auxio.h>
#include <asm/sfafsr.h>
#include <asm/pil.h>
+#include <asm/unistd.h>
#define curptr g6
-
-#define NR_SYSCALLS 300 /* Each OS is different... */
.text
.align 32
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/of_device.c
--- a/arch/sparc64/kernel/of_device.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/of_device.c Wed Oct 03 10:00:44 2007 +0100
@@ -398,16 +398,22 @@ static void of_bus_sbus_count_cells(stru
*sizec = 1;
}
-static int of_bus_sbus_map(u32 *addr, const u32 *range, int na, int ns, int
pna)
-{
- return of_bus_default_map(addr, range, na, ns, pna);
-}
-
-static unsigned int of_bus_sbus_get_flags(u32 *addr)
-{
- return IORESOURCE_MEM;
-}
-
+/*
+ * FHC/Central bus specific translator.
+ *
+ * This is just needed to hard-code the address and size cell
+ * counts. 'fhc' and 'central' nodes lack the #address-cells and
+ * #size-cells properties, and if you walk to the root on such
+ * Enterprise boxes all you'll get is a #size-cells of 2 which is
+ * not what we want to use.
+ */
+static int of_bus_fhc_match(struct device_node *np)
+{
+ return !strcmp(np->name, "fhc") ||
+ !strcmp(np->name, "central");
+}
+
+#define of_bus_fhc_count_cells of_bus_sbus_count_cells
/*
* Array of bus specific translators
@@ -429,8 +435,17 @@ static struct of_bus of_busses[] = {
.addr_prop_name = "reg",
.match = of_bus_sbus_match,
.count_cells = of_bus_sbus_count_cells,
- .map = of_bus_sbus_map,
- .get_flags = of_bus_sbus_get_flags,
+ .map = of_bus_default_map,
+ .get_flags = of_bus_default_get_flags,
+ },
+ /* FHC */
+ {
+ .name = "fhc",
+ .addr_prop_name = "reg",
+ .match = of_bus_fhc_match,
+ .count_cells = of_bus_fhc_count_cells,
+ .map = of_bus_default_map,
+ .get_flags = of_bus_default_get_flags,
},
/* Default */
{
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/pci_common.c
--- a/arch/sparc64/kernel/pci_common.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/pci_common.c Wed Oct 03 10:00:44 2007 +0100
@@ -328,19 +328,6 @@ __init get_device_resource(struct linux_
};
return res;
-}
-
-static int __init pdev_resource_collisions_expected(struct pci_dev *pdev)
-{
- if (pdev->vendor != PCI_VENDOR_ID_SUN)
- return 0;
-
- if (pdev->device == PCI_DEVICE_ID_SUN_RIO_EBUS ||
- pdev->device == PCI_DEVICE_ID_SUN_RIO_1394 ||
- pdev->device == PCI_DEVICE_ID_SUN_RIO_USB)
- return 1;
-
- return 0;
}
static void __init pdev_record_assignments(struct pci_pbm_info *pbm,
@@ -400,19 +387,23 @@ static void __init pdev_record_assignmen
pbm->parent->resource_adjust(pdev, res, root);
if (request_resource(root, res) < 0) {
+ int rnum;
+
/* OK, there is some conflict. But this is fine
* since we'll reassign it in the fixup pass.
*
- * We notify the user that OBP made an error if it
- * is a case we don't expect.
+ * Do not print the warning for ROM resources
+ * as such a conflict is quite common and
+ * harmless as the ROM bar is disabled.
*/
- if (!pdev_resource_collisions_expected(pdev)) {
- printk(KERN_ERR "PCI: Address space collision
on region %ld "
+ rnum = (res - &pdev->resource[0]);
+ if (rnum != PCI_ROM_RESOURCE)
+ printk(KERN_ERR "PCI: Resource collision, "
+ "region %d "
"[%016lx:%016lx] of device %s\n",
- (res - &pdev->resource[0]),
+ rnum,
res->start, res->end,
pci_name(pdev));
- }
}
}
}
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/pci_iommu.c
--- a/arch/sparc64/kernel/pci_iommu.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/pci_iommu.c Wed Oct 03 10:00:44 2007 +0100
@@ -281,7 +281,7 @@ static void pci_4u_free_consistent(struc
spin_lock_irqsave(&iommu->lock, flags);
- free_npages(iommu, dvma, npages);
+ free_npages(iommu, dvma - iommu->page_table_map_base, npages);
spin_unlock_irqrestore(&iommu->lock, flags);
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/pci_sabre.c
--- a/arch/sparc64/kernel/pci_sabre.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/pci_sabre.c Wed Oct 03 10:00:44 2007 +0100
@@ -1196,7 +1196,7 @@ static void pbm_register_toplevel_resour
&pbm->mem_space);
}
-static void sabre_pbm_init(struct pci_controller_info *p, struct device_node
*dp, u32 dma_begin)
+static void sabre_pbm_init(struct pci_controller_info *p, struct device_node
*dp, u32 dma_start, u32 dma_end)
{
struct pci_pbm_info *pbm;
struct device_node *node;
@@ -1261,6 +1261,8 @@ static void sabre_pbm_init(struct pci_co
node = node->sibling;
}
if (simbas_found == 0) {
+ struct resource *rp;
+
/* No APBs underneath, probably this is a hummingbird
* system.
*/
@@ -1302,8 +1304,10 @@ static void sabre_pbm_init(struct pci_co
pbm->io_space.end = pbm->io_space.start + (1UL << 24) - 1UL;
pbm->io_space.flags = IORESOURCE_IO;
- pbm->mem_space.start = p->pbm_A.controller_regs +
SABRE_MEMSPACE;
- pbm->mem_space.end = pbm->mem_space.start + (unsigned
long)dma_begin - 1UL;
+ pbm->mem_space.start =
+ (p->pbm_A.controller_regs + SABRE_MEMSPACE);
+ pbm->mem_space.end =
+ (pbm->mem_space.start + ((1UL << 32UL) - 1UL));
pbm->mem_space.flags = IORESOURCE_MEM;
if (request_resource(&ioport_resource, &pbm->io_space) < 0) {
@@ -1314,6 +1318,17 @@ static void sabre_pbm_init(struct pci_co
prom_printf("Cannot register Hummingbird's MEM
space.\n");
prom_halt();
}
+
+ rp = kmalloc(sizeof(*rp), GFP_KERNEL);
+ if (!rp) {
+ prom_printf("Cannot allocate IOMMU resource.\n");
+ prom_halt();
+ }
+ rp->name = "IOMMU";
+ rp->start = pbm->mem_space.start + (unsigned long) dma_start;
+ rp->end = pbm->mem_space.start + (unsigned long) dma_end - 1UL;
+ rp->flags = IORESOURCE_BUSY;
+ request_resource(&pbm->mem_space, rp);
pci_register_legacy_regions(&pbm->io_space,
&pbm->mem_space);
@@ -1450,5 +1465,5 @@ void sabre_init(struct device_node *dp,
/*
* Look for APB underneath.
*/
- sabre_pbm_init(p, dp, vdma[0]);
-}
+ sabre_pbm_init(p, dp, vdma[0], vdma[0] + vdma[1]);
+}
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/prom.c
--- a/arch/sparc64/kernel/prom.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/prom.c Wed Oct 03 10:00:44 2007 +0100
@@ -1080,23 +1080,22 @@ static void sun4v_vdev_irq_trans_init(st
static void irq_trans_init(struct device_node *dp)
{
+#ifdef CONFIG_PCI
const char *model;
-#ifdef CONFIG_PCI
int i;
#endif
+#ifdef CONFIG_PCI
model = of_get_property(dp, "model", NULL);
if (!model)
model = of_get_property(dp, "compatible", NULL);
- if (!model)
- return;
-
-#ifdef CONFIG_PCI
- for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
- struct irq_trans *t = &pci_irq_trans_table[i];
-
- if (!strcmp(model, t->name))
- return t->init(dp);
+ if (model) {
+ for (i = 0; i < ARRAY_SIZE(pci_irq_trans_table); i++) {
+ struct irq_trans *t = &pci_irq_trans_table[i];
+
+ if (!strcmp(model, t->name))
+ return t->init(dp);
+ }
}
#endif
#ifdef CONFIG_SBUS
@@ -1104,8 +1103,9 @@ static void irq_trans_init(struct device
!strcmp(dp->name, "sbi"))
return sbus_irq_trans_init(dp);
#endif
- if (!strcmp(dp->name, "central"))
- return central_irq_trans_init(dp->child);
+ if (!strcmp(dp->name, "fhc") &&
+ !strcmp(dp->parent->name, "central"))
+ return central_irq_trans_init(dp);
if (!strcmp(dp->name, "virtual-devices"))
return sun4v_vdev_irq_trans_init(dp);
}
@@ -1517,7 +1517,7 @@ static char * __init get_one_property(ph
return buf;
}
-static struct device_node * __init create_node(phandle node)
+static struct device_node * __init create_node(phandle node, struct
device_node *parent)
{
struct device_node *dp;
@@ -1526,6 +1526,7 @@ static struct device_node * __init creat
dp = prom_early_alloc(sizeof(*dp));
dp->unique_id = unique_id++;
+ dp->parent = parent;
kref_init(&dp->kref);
@@ -1544,12 +1545,11 @@ static struct device_node * __init build
{
struct device_node *dp;
- dp = create_node(node);
+ dp = create_node(node, parent);
if (dp) {
*(*nextp) = dp;
*nextp = &dp->allnext;
- dp->parent = parent;
dp->path_component_name = build_path_component(dp);
dp->full_name = build_full_name(dp);
@@ -1565,7 +1565,7 @@ void __init prom_build_devicetree(void)
{
struct device_node **nextp;
- allnodes = create_node(prom_root_node);
+ allnodes = create_node(prom_root_node, NULL);
allnodes->path_component_name = "";
allnodes->full_name = "/";
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/kernel/time.c Wed Oct 03 10:00:44 2007 +0100
@@ -983,7 +983,7 @@ static struct time_interpolator sparc64_
};
/* The quotient formula is taken from the IA64 port. */
-#define SPARC64_NSEC_PER_CYC_SHIFT 30UL
+#define SPARC64_NSEC_PER_CYC_SHIFT 10UL
void __init time_init(void)
{
unsigned long clock = sparc64_init_timers();
diff -r aafef975e518 -r 3e8752eb6d9c arch/sparc64/mm/init.c
--- a/arch/sparc64/mm/init.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/sparc64/mm/init.c Wed Oct 03 10:00:44 2007 +0100
@@ -920,8 +920,7 @@ static unsigned long __init bootmem_init
if (sparc_ramdisk_image || sparc_ramdisk_image64) {
unsigned long ramdisk_image = sparc_ramdisk_image ?
sparc_ramdisk_image : sparc_ramdisk_image64;
- if (ramdisk_image >= (unsigned long)_end - 2 * PAGE_SIZE)
- ramdisk_image -= KERNBASE;
+ ramdisk_image -= KERNBASE;
initrd_start = ramdisk_image + phys_base;
initrd_end = initrd_start + sparc_ramdisk_size;
if (initrd_end > end_of_phys_memory) {
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/Kconfig
--- a/arch/um/Kconfig Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/Kconfig Wed Oct 03 10:00:44 2007 +0100
@@ -1,3 +1,8 @@
+config DEFCONFIG_LIST
+ string
+ option defconfig_list
+ default "arch/$ARCH/defconfig"
+
# UML uses the generic IRQ sugsystem
config GENERIC_HARDIRQS
bool
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/Makefile-x86_64
--- a/arch/um/Makefile-x86_64 Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/Makefile-x86_64 Wed Oct 03 10:00:44 2007 +0100
@@ -1,7 +1,7 @@
# Copyright 2003 - 2004 Pathscale, Inc
# Released under the GPL
-core-y += arch/um/sys-x86_64/
+core-y += arch/um/sys-x86_64/ arch/x86_64/crypto/
START := 0x60000000
#We #undef __x86_64__ for kernelspace, not for userspace where
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/include/common-offsets.h
--- a/arch/um/include/common-offsets.h Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/include/common-offsets.h Wed Oct 03 10:00:44 2007 +0100
@@ -15,3 +15,4 @@ DEFINE(UM_ELF_CLASS, ELF_CLASS);
DEFINE(UM_ELF_CLASS, ELF_CLASS);
DEFINE(UM_ELFCLASS32, ELFCLASS32);
DEFINE(UM_ELFCLASS64, ELFCLASS64);
+DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/include/kern_util.h
--- a/arch/um/include/kern_util.h Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/include/kern_util.h Wed Oct 03 10:00:44 2007 +0100
@@ -6,7 +6,6 @@
#ifndef __KERN_UTIL_H__
#define __KERN_UTIL_H__
-#include "linux/threads.h"
#include "sysdep/ptrace.h"
#include "sysdep/faultinfo.h"
diff -r aafef975e518 -r 3e8752eb6d9c
arch/um/include/sysdep-i386/kernel-offsets.h
--- a/arch/um/include/sysdep-i386/kernel-offsets.h Tue Oct 02 09:52:15
2007 +0100
+++ b/arch/um/include/sysdep-i386/kernel-offsets.h Wed Oct 03 10:00:44
2007 +0100
@@ -1,6 +1,7 @@
#include <linux/stddef.h>
#include <linux/sched.h>
#include <linux/elf.h>
+#include <linux/crypto.h>
#include <asm/mman.h>
#define DEFINE(sym, val) \
diff -r aafef975e518 -r 3e8752eb6d9c
arch/um/include/sysdep-x86_64/kernel-offsets.h
--- a/arch/um/include/sysdep-x86_64/kernel-offsets.h Tue Oct 02 09:52:15
2007 +0100
+++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h Wed Oct 03 10:00:44
2007 +0100
@@ -2,6 +2,7 @@
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/elf.h>
+#include <linux/crypto.h>
#include <asm/page.h>
#include <asm/mman.h>
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/os-Linux/process.c
--- a/arch/um/os-Linux/process.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/os-Linux/process.c Wed Oct 03 10:00:44 2007 +0100
@@ -141,11 +141,9 @@ void os_usr1_process(int pid)
* syscalls, and also breaks with clone(), which does not unshare the TLS.
*/
-inline _syscall0(pid_t, getpid)
-
int os_getpid(void)
{
- return(getpid());
+ return syscall(__NR_getpid);
}
int os_getpgrp(void)
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/os-Linux/sys-i386/tls.c
--- a/arch/um/os-Linux/sys-i386/tls.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/os-Linux/sys-i386/tls.c Wed Oct 03 10:00:44 2007 +0100
@@ -1,9 +1,9 @@
#include <errno.h>
+#include <sys/syscall.h>
+#include <unistd.h>
#include <linux/unistd.h>
#include "sysdep/tls.h"
#include "user_util.h"
-
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
/* Checks whether host supports TLS, and sets *tls_min according to the value
* valid on the host.
@@ -17,7 +17,7 @@ void check_host_supports_tls(int *suppor
user_desc_t info;
info.entry_number = val[i];
- if (get_thread_area(&info) == 0) {
+ if(syscall(__NR_get_thread_area, &info) == 0){
*tls_min = val[i];
*supports_tls = 1;
return;
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/os-Linux/tls.c
--- a/arch/um/os-Linux/tls.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/os-Linux/tls.c Wed Oct 03 10:00:44 2007 +0100
@@ -1,6 +1,8 @@
#include <errno.h>
#include <sys/ptrace.h>
+#include <sys/syscall.h>
#include <asm/ldt.h>
+#include <unistd.h>
#include "sysdep/tls.h"
#include "uml-config.h"
@@ -48,14 +50,11 @@ int os_get_thread_area(user_desc_t *info
#ifdef UML_CONFIG_MODE_TT
#include "linux/unistd.h"
-static _syscall1(int, get_thread_area, user_desc_t *, u_info);
-static _syscall1(int, set_thread_area, user_desc_t *, u_info);
-
int do_set_thread_area_tt(user_desc_t *info)
{
int ret;
- ret = set_thread_area(info);
+ ret = syscall(__NR_set_thread_area, info);
if (ret < 0) {
ret = -errno;
}
@@ -66,7 +65,7 @@ int do_get_thread_area_tt(user_desc_t *i
{
int ret;
- ret = get_thread_area(info);
+ ret = syscall(__NR_get_thread_area, info);
if (ret < 0) {
ret = -errno;
}
diff -r aafef975e518 -r 3e8752eb6d9c arch/um/sys-x86_64/stub_segv.c
--- a/arch/um/sys-x86_64/stub_segv.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/um/sys-x86_64/stub_segv.c Wed Oct 03 10:00:44 2007 +0100
@@ -5,7 +5,6 @@
#include <stddef.h>
#include <signal.h>
-#include <linux/compiler.h>
#include <asm/unistd.h>
#include "uml-config.h"
#include "sysdep/sigcontext.h"
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/ia32/ptrace32.c
--- a/arch/x86_64/ia32/ptrace32.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/ia32/ptrace32.c Wed Oct 03 10:00:44 2007 +0100
@@ -239,6 +239,7 @@ asmlinkage long sys32_ptrace(long reques
case PTRACE_SINGLESTEP:
case PTRACE_DETACH:
case PTRACE_SYSCALL:
+ case PTRACE_OLDSETOPTIONS:
case PTRACE_SETOPTIONS:
return sys_ptrace(request, pid, addr, data);
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/entry.S
--- a/arch/x86_64/kernel/entry.S Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/entry.S Wed Oct 03 10:00:44 2007 +0100
@@ -146,6 +146,10 @@ 1:
/* rdi: prev */
ENTRY(ret_from_fork)
CFI_DEFAULT_STACK
+ push kernel_eflags(%rip)
+ CFI_ADJUST_CFA_OFFSET 4
+ popf # reset kernel eflags
+ CFI_ADJUST_CFA_OFFSET -4
call schedule_tail
GET_THREAD_INFO(%rcx)
testl $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT),threadinfo_flags(%rcx)
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/pci-calgary.c
--- a/arch/x86_64/kernel/pci-calgary.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/pci-calgary.c Wed Oct 03 10:00:44 2007 +0100
@@ -759,7 +759,16 @@ static inline unsigned int __init locate
int rionodeid;
u32 address;
- rionodeid = (dev->bus->number % 15 > 4) ? 3 : 2;
+ /*
+ * Each Calgary has four busses. The first four busses (first Calgary)
+ * have RIO node ID 2, then the next four (second Calgary) have RIO
+ * node ID 3, the next four (third Calgary) have node ID 2 again, etc.
+ * We use a gross hack - relying on the dev->bus->number ordering,
+ * modulo 14 - to decide which Calgary a given bus is on. Busses 0, 1,
+ * 2 and 4 are on the first Calgary (id 2), 6, 8, a and c are on the
+ * second (id 3), and then it repeats modulo 14.
+ */
+ rionodeid = (dev->bus->number % 14 > 4) ? 3 : 2;
/*
* register space address calculation as follows:
* FE0MB-8MB*OneBasedChassisNumber+1MB*(RioNodeId-ChassisBase)
@@ -767,7 +776,7 @@ static inline unsigned int __init locate
* RioNodeId is 2 for first Calgary, 3 for second Calgary
*/
address = START_ADDRESS -
- (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 15)) +
+ (0x800000 * (ONE_BASED_CHASSIS_NUM + dev->bus->number / 14)) +
(0x100000) * (rionodeid - CHASSIS_BASE);
return address;
}
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/process.c
--- a/arch/x86_64/kernel/process.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/process.c Wed Oct 03 10:00:44 2007 +0100
@@ -571,6 +571,9 @@ __switch_to(struct task_struct *prev_p,
prev->gsindex = gsindex;
}
+ /* Must be after DS reload */
+ unlazy_fpu(prev_p);
+
/*
* Switch the PDA and FPU contexts.
*/
@@ -578,10 +581,6 @@ __switch_to(struct task_struct *prev_p,
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.
- 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);
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/setup.c
--- a/arch/x86_64/kernel/setup.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/setup.c Wed Oct 03 10:00:44 2007 +0100
@@ -1010,7 +1010,10 @@ static void __cpuinit init_intel(struct
if ((c->x86 == 0xf && c->x86_model >= 0x03) ||
(c->x86 == 0x6 && c->x86_model >= 0x0e))
set_bit(X86_FEATURE_CONSTANT_TSC, &c->x86_capability);
- set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
+ if (c->x86 == 15)
+ set_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
+ else
+ clear_bit(X86_FEATURE_SYNC_RDTSC, &c->x86_capability);
c->x86_max_cores = intel_num_cpu_cores(c);
srat_detect_node();
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/setup64.c
--- a/arch/x86_64/kernel/setup64.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/setup64.c Wed Oct 03 10:00:44 2007 +0100
@@ -178,6 +178,8 @@ void __cpuinit check_efer(void)
}
}
+unsigned long kernel_eflags;
+
/*
* cpu_init() initializes state that is per-CPU. Some data is already
* initialized (naturally) in the bootstrap process, such as the GDT
@@ -290,4 +292,6 @@ void __cpuinit cpu_init (void)
set_debugreg(0UL, 7);
fpu_init();
-}
+
+ raw_local_save_flags(kernel_eflags);
+}
diff -r aafef975e518 -r 3e8752eb6d9c arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c Tue Oct 02 09:52:15 2007 +0100
+++ b/arch/x86_64/kernel/time.c Wed Oct 03 10:00:44 2007 +0100
@@ -960,7 +960,7 @@ __cpuinit int unsynchronized_tsc(void)
if (boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) {
#ifdef CONFIG_ACPI
/* But TSC doesn't tick in C3 so don't use it there */
- if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 100)
+ if (acpi_fadt.length > 0 && acpi_fadt.plvl3_lat < 1000)
return 1;
#endif
return 0;
diff -r aafef975e518 -r 3e8752eb6d9c block/elevator.c
--- a/block/elevator.c Tue Oct 02 09:52:15 2007 +0100
+++ b/block/elevator.c Wed Oct 03 10:00:44 2007 +0100
@@ -892,7 +892,7 @@ ssize_t elv_iosched_show(request_queue_t
struct list_head *entry;
int len = 0;
- spin_lock_irq(q->queue_lock);
+ spin_lock_irq(&elv_list_lock);
list_for_each(entry, &elv_list) {
struct elevator_type *__e;
@@ -902,7 +902,7 @@ ssize_t elv_iosched_show(request_queue_t
else
len += sprintf(name+len, "%s ", __e->elevator_name);
}
- spin_unlock_irq(q->queue_lock);
+ spin_unlock_irq(&elv_list_lock);
len += sprintf(len+name, "\n");
return len;
diff -r aafef975e518 -r 3e8752eb6d9c block/ll_rw_blk.c
--- a/block/ll_rw_blk.c Tue Oct 02 09:52:15 2007 +0100
+++ b/block/ll_rw_blk.c Wed Oct 03 10:00:44 2007 +0100
@@ -3021,6 +3021,7 @@ void generic_make_request(struct bio *bi
{
request_queue_t *q;
sector_t maxsector;
+ sector_t old_sector;
int ret, nr_sectors = bio_sectors(bio);
dev_t old_dev;
@@ -3049,7 +3050,7 @@ void generic_make_request(struct bio *bi
* NOTE: we don't repeat the blk_size check for each new device.
* Stacking drivers are expected to know what they are doing.
*/
- maxsector = -1;
+ old_sector = -1;
old_dev = 0;
do {
char b[BDEVNAME_SIZE];
@@ -3083,14 +3084,29 @@ end_io:
*/
blk_partition_remap(bio);
- if (maxsector != -1)
+ if (old_sector != -1)
blk_add_trace_remap(q, bio, old_dev, bio->bi_sector,
- maxsector);
+ old_sector);
blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
- maxsector = bio->bi_sector;
+ old_sector = bio->bi_sector;
old_dev = bio->bi_bdev->bd_dev;
+
+ maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
+ if (maxsector) {
+ sector_t sector = bio->bi_sector;
+
+ if (maxsector < nr_sectors || maxsector - nr_sectors <
sector) {
+ /*
+ * This may well happen - partitions are not
checked
+ * to make sure they are within the size of the
+ * whole device.
+ */
+ handle_bad_sector(bio);
+ goto end_io;
+ }
+ }
ret = q->make_request_fn(q, bio);
} while (ret);
diff -r aafef975e518 -r 3e8752eb6d9c block/scsi_ioctl.c
--- a/block/scsi_ioctl.c Tue Oct 02 09:52:15 2007 +0100
+++ b/block/scsi_ioctl.c Wed Oct 03 10:00:44 2007 +0100
@@ -246,10 +246,10 @@ static int sg_io(struct file *file, requ
switch (hdr->dxfer_direction) {
default:
return -EINVAL;
- case SG_DXFER_TO_FROM_DEV:
case SG_DXFER_TO_DEV:
writing = 1;
break;
+ case SG_DXFER_TO_FROM_DEV:
case SG_DXFER_FROM_DEV:
break;
}
@@ -286,9 +286,8 @@ static int sg_io(struct file *file, requ
* fill in request structure
*/
rq->cmd_len = hdr->cmd_len;
+ memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
memcpy(rq->cmd, cmd, hdr->cmd_len);
- if (sizeof(rq->cmd) != hdr->cmd_len)
- memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) -
hdr->cmd_len);
memset(sense, 0, sizeof(sense));
rq->sense = sense;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/block/DAC960.c
--- a/drivers/block/DAC960.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/block/DAC960.c Wed Oct 03 10:00:44 2007 +0100
@@ -7115,7 +7115,7 @@ static struct pci_device_id DAC960_id_ta
{
.vendor = PCI_VENDOR_ID_MYLEX,
.device = PCI_DEVICE_ID_MYLEX_DAC960_GEM,
- .subvendor = PCI_ANY_ID,
+ .subvendor = PCI_VENDOR_ID_MYLEX,
.subdevice = PCI_ANY_ID,
.driver_data = (unsigned long) &DAC960_GEM_privdata,
},
diff -r aafef975e518 -r 3e8752eb6d9c drivers/block/cciss.c
--- a/drivers/block/cciss.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/block/cciss.c Wed Oct 03 10:00:44 2007 +0100
@@ -1301,6 +1301,12 @@ static void cciss_softirq_done(struct re
}
complete_buffers(rq->bio, rq->errors);
+
+ if (blk_fs_request(rq)) {
+ const int rw = rq_data_dir(rq);
+
+ disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
+ }
#ifdef CCISS_DEBUG
printk("Done with %p\n", rq);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/block/cpqarray.c
--- a/drivers/block/cpqarray.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/block/cpqarray.c Wed Oct 03 10:00:44 2007 +0100
@@ -1000,6 +1000,7 @@ static inline void complete_buffers(stru
*/
static inline void complete_command(cmdlist_t *cmd, int timeout)
{
+ struct request *rq = cmd->rq;
int ok=1;
int i, ddir;
@@ -1031,12 +1032,18 @@ static inline void complete_command(cmdl
pci_unmap_page(hba[cmd->ctlr]->pci_dev, cmd->req.sg[i].addr,
cmd->req.sg[i].size, ddir);
- complete_buffers(cmd->rq->bio, ok);
-
- add_disk_randomness(cmd->rq->rq_disk);
-
- DBGPX(printk("Done with %p\n", cmd->rq););
- end_that_request_last(cmd->rq, ok ? 1 : -EIO);
+ complete_buffers(rq->bio, ok);
+
+ if (blk_fs_request(rq)) {
+ const int rw = rq_data_dir(rq);
+
+ disk_stat_add(rq->rq_disk, sectors[rw], rq->nr_sectors);
+ }
+
+ add_disk_randomness(rq->rq_disk);
+
+ DBGPX(printk("Done with %p\n", rq););
+ end_that_request_last(rq, ok ? 1 : -EIO);
}
/*
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/agp/generic.c
--- a/drivers/char/agp/generic.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/agp/generic.c Wed Oct 03 10:00:44 2007 +0100
@@ -1020,7 +1020,7 @@ void *agp_generic_alloc_page(struct agp_
{
struct page * page;
- page = alloc_page(GFP_KERNEL);
+ page = alloc_page(GFP_KERNEL | GFP_DMA32);
if (page == NULL)
return NULL;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/agp/intel-agp.c
--- a/drivers/char/agp/intel-agp.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/agp/intel-agp.c Wed Oct 03 10:00:44 2007 +0100
@@ -160,7 +160,7 @@ static void *i8xx_alloc_pages(void)
{
struct page * page;
- page = alloc_pages(GFP_KERNEL, 2);
+ page = alloc_pages(GFP_KERNEL | GFP_DMA32, 2);
if (page == NULL)
return NULL;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/hw_random/intel-rng.c
--- a/drivers/char/hw_random/intel-rng.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/hw_random/intel-rng.c Wed Oct 03 10:00:44 2007 +0100
@@ -50,6 +50,43 @@
#define INTEL_RNG_ADDR_LEN 3
/*
+ * LPC bridge PCI config space registers
+ */
+#define FWH_DEC_EN1_REG_OLD 0xe3
+#define FWH_DEC_EN1_REG_NEW 0xd9 /* high byte of 16-bit
register */
+#define FWH_F8_EN_MASK 0x80
+
+#define BIOS_CNTL_REG_OLD 0x4e
+#define BIOS_CNTL_REG_NEW 0xdc
+#define BIOS_CNTL_WRITE_ENABLE_MASK 0x01
+#define BIOS_CNTL_LOCK_ENABLE_MASK 0x02
+
+/*
+ * Magic address at which Intel Firmware Hubs get accessed
+ */
+#define INTEL_FWH_ADDR 0xffff0000
+#define INTEL_FWH_ADDR_LEN 2
+
+/*
+ * Intel Firmware Hub command codes (write to any address inside the device)
+ */
+#define INTEL_FWH_RESET_CMD 0xff /* aka READ_ARRAY */
+#define INTEL_FWH_READ_ID_CMD 0x90
+
+/*
+ * Intel Firmware Hub Read ID command result addresses
+ */
+#define INTEL_FWH_MANUFACTURER_CODE_ADDRESS 0x000000
+#define INTEL_FWH_DEVICE_CODE_ADDRESS 0x000001
+
+/*
+ * Intel Firmware Hub Read ID command result values
+ */
+#define INTEL_FWH_MANUFACTURER_CODE 0x89
+#define INTEL_FWH_DEVICE_CODE_8M 0xac
+#define INTEL_FWH_DEVICE_CODE_4M 0xad
+
+/*
* Data for PCI driver interface
*
* This data only exists for exporting the supported
@@ -58,12 +95,50 @@
* want to register another driver on the same PCI id.
*/
static const struct pci_device_id pci_tbl[] = {
- { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
- { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, },
+/* AA
+ { 0x8086, 0x2418, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x2410, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AA */
+/* AB
+ { 0x8086, 0x2428, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x2420, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* AB */
+/* ??
+ { 0x8086, 0x2430, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+/* BAM, CAM, DBM, FBM, GxM
+ { 0x8086, 0x2448, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x244c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BAM */
+ { 0x8086, 0x248c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CAM */
+ { 0x8086, 0x24cc, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DBM */
+ { 0x8086, 0x2641, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* FBM */
+ { 0x8086, 0x27b9, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM */
+ { 0x8086, 0x27bd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* GxM DH */
+/* BA, CA, DB, Ex, 6300, Fx, 631x/632x, Gx
+ { 0x8086, 0x244e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x2440, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* BA */
+ { 0x8086, 0x2480, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* CA */
+ { 0x8086, 0x24c0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* DB */
+ { 0x8086, 0x24d0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Ex */
+ { 0x8086, 0x25a1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 6300 */
+ { 0x8086, 0x2640, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Fx */
+ { 0x8086, 0x2670, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2671, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2672, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2673, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2674, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2675, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2676, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2677, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2678, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x2679, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x267f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* 631x/632x */
+ { 0x8086, 0x27b8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* Gx */
+/* E
+ { 0x8086, 0x245e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, */
+ { 0x8086, 0x2450, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* E */
{ 0, }, /* terminate list */
};
MODULE_DEVICE_TABLE(pci, pci_tbl);
@@ -138,14 +213,107 @@ static struct hwrng intel_rng = {
};
+#ifdef CONFIG_SMP
+static char __initdata waitflag;
+
+static void __init intel_init_wait(void *unused)
+{
+ while (waitflag)
+ cpu_relax();
+}
+#endif
+
static int __init mod_init(void)
{
int err = -ENODEV;
+ unsigned i;
+ struct pci_dev *dev = NULL;
void __iomem *mem;
- u8 hw_status;
-
- if (!pci_dev_present(pci_tbl))
+ unsigned long flags;
+ u8 bios_cntl_off, fwh_dec_en1_off;
+ u8 bios_cntl_val = 0xff, fwh_dec_en1_val = 0xff;
+ u8 hw_status, mfc, dvc;
+
+ for (i = 0; !dev && pci_tbl[i].vendor; ++i)
+ dev = pci_get_device(pci_tbl[i].vendor, pci_tbl[i].device,
NULL);
+
+ if (!dev)
goto out; /* Device not found. */
+
+ /* Check for Intel 82802 */
+ if (dev->device < 0x2640) {
+ fwh_dec_en1_off = FWH_DEC_EN1_REG_OLD;
+ bios_cntl_off = BIOS_CNTL_REG_OLD;
+ } else {
+ fwh_dec_en1_off = FWH_DEC_EN1_REG_NEW;
+ bios_cntl_off = BIOS_CNTL_REG_NEW;
+ }
+
+ pci_read_config_byte(dev, fwh_dec_en1_off, &fwh_dec_en1_val);
+ pci_read_config_byte(dev, bios_cntl_off, &bios_cntl_val);
+
+ mem = ioremap_nocache(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN);
+ if (mem == NULL) {
+ pci_dev_put(dev);
+ err = -EBUSY;
+ goto out;
+ }
+
+ /*
+ * Since the BIOS code/data is going to disappear from its normal
+ * location with the Read ID command, all activity on the system
+ * must be stopped until the state is back to normal.
+ */
+#ifdef CONFIG_SMP
+ set_mb(waitflag, 1);
+ if (smp_call_function(intel_init_wait, NULL, 1, 0) != 0) {
+ set_mb(waitflag, 0);
+ pci_dev_put(dev);
+ printk(KERN_ERR PFX "cannot run on all processors\n");
+ err = -EAGAIN;
+ goto err_unmap;
+ }
+#endif
+ local_irq_save(flags);
+
+ if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+ pci_write_config_byte(dev,
+ fwh_dec_en1_off,
+ fwh_dec_en1_val | FWH_F8_EN_MASK);
+ if (!(bios_cntl_val &
+ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+ pci_write_config_byte(dev,
+ bios_cntl_off,
+ bios_cntl_val |
BIOS_CNTL_WRITE_ENABLE_MASK);
+
+ writeb(INTEL_FWH_RESET_CMD, mem);
+ writeb(INTEL_FWH_READ_ID_CMD, mem);
+ mfc = readb(mem + INTEL_FWH_MANUFACTURER_CODE_ADDRESS);
+ dvc = readb(mem + INTEL_FWH_DEVICE_CODE_ADDRESS);
+ writeb(INTEL_FWH_RESET_CMD, mem);
+
+ if (!(bios_cntl_val &
+ (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)))
+ pci_write_config_byte(dev, bios_cntl_off, bios_cntl_val);
+ if (!(fwh_dec_en1_val & FWH_F8_EN_MASK))
+ pci_write_config_byte(dev, fwh_dec_en1_off, fwh_dec_en1_val);
+
+ local_irq_restore(flags);
+#ifdef CONFIG_SMP
+ /* Tell other CPUs to resume. */
+ set_mb(waitflag, 0);
+#endif
+
+ iounmap(mem);
+ pci_dev_put(dev);
+
+ if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
+ (dvc != INTEL_FWH_DEVICE_CODE_8M &&
+ dvc != INTEL_FWH_DEVICE_CODE_4M)) {
+ printk(KERN_ERR PFX "FWH not detected\n");
+ err = -ENODEV;
+ goto out;
+ }
err = -ENOMEM;
mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN);
@@ -153,7 +321,7 @@ static int __init mod_init(void)
goto out;
intel_rng.priv = (unsigned long)mem;
- /* Check for Intel 82802 */
+ /* Check for Random Number Generator */
err = -ENODEV;
hw_status = hwstatus_get(mem);
if ((hw_status & INTEL_RNG_PRESENT) == 0)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/ipmi/ipmi_si_intf.c
--- a/drivers/char/ipmi/ipmi_si_intf.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/ipmi/ipmi_si_intf.c Wed Oct 03 10:00:44 2007 +0100
@@ -1845,7 +1845,7 @@ static int ipmi_pci_resume(struct pci_de
static struct pci_device_id ipmi_pci_devices[] = {
{ PCI_DEVICE(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID) },
- { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE) }
+ { PCI_DEVICE_CLASS(PCI_ERMC_CLASSCODE, PCI_ERMC_CLASSCODE_MASK) }
};
MODULE_DEVICE_TABLE(pci, ipmi_pci_devices);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/isicom.c
--- a/drivers/char/isicom.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/isicom.c Wed Oct 03 10:00:44 2007 +0100
@@ -1062,11 +1062,12 @@ static void isicom_close(struct tty_stru
static void isicom_close(struct tty_struct *tty, struct file *filp)
{
struct isi_port *port = tty->driver_data;
- struct isi_board *card = port->card;
+ struct isi_board *card;
unsigned long flags;
if (!port)
return;
+ card = port->card;
if (isicom_paranoia_check(port, tty->name, "isicom_close"))
return;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/mem.c
--- a/drivers/char/mem.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/mem.c Wed Oct 03 10:00:44 2007 +0100
@@ -618,7 +618,8 @@ static inline size_t read_zero_pagealign
count = size;
zap_page_range(vma, addr, count, NULL);
- zeromap_page_range(vma, addr, count, PAGE_COPY);
+ if (zeromap_page_range(vma, addr, count, PAGE_COPY))
+ break;
size -= count;
buf += count;
@@ -685,11 +686,14 @@ out:
static int mmap_zero(struct file * file, struct vm_area_struct * vma)
{
+ int err;
+
if (vma->vm_flags & VM_SHARED)
return shmem_zero_setup(vma);
- if (zeromap_page_range(vma, vma->vm_start, vma->vm_end - vma->vm_start,
vma->vm_page_prot))
- return -EAGAIN;
- return 0;
+ err = zeromap_page_range(vma, vma->vm_start,
+ vma->vm_end - vma->vm_start, vma->vm_page_prot);
+ BUG_ON(err == -EEXIST);
+ return err;
}
#else /* CONFIG_MMU */
static ssize_t read_zero(struct file * file, char * buf,
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/rtc.c
--- a/drivers/char/rtc.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/rtc.c Wed Oct 03 10:00:44 2007 +0100
@@ -209,11 +209,12 @@ static const unsigned char days_in_mo[]
*/
static inline unsigned char rtc_is_updating(void)
{
+ unsigned long flags;
unsigned char uip;
- spin_lock_irq(&rtc_lock);
+ spin_lock_irqsave(&rtc_lock, flags);
uip = (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP);
- spin_unlock_irq(&rtc_lock);
+ spin_unlock_irqrestore(&rtc_lock, flags);
return uip;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/char/watchdog/sc1200wdt.c
--- a/drivers/char/watchdog/sc1200wdt.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/char/watchdog/sc1200wdt.c Wed Oct 03 10:00:44 2007 +0100
@@ -392,7 +392,7 @@ static int __init sc1200wdt_init(void)
if (io == -1) {
printk(KERN_ERR PFX "io parameter must be specified\n");
ret = -EINVAL;
- goto out_clean;
+ goto out_pnp;
}
#if defined CONFIG_PNP
@@ -405,7 +405,7 @@ static int __init sc1200wdt_init(void)
if (!request_region(io, io_len, SC1200_MODULE_NAME)) {
printk(KERN_ERR PFX "Unable to register IO port %#x\n", io);
ret = -EBUSY;
- goto out_clean;
+ goto out_pnp;
}
ret = sc1200wdt_probe();
@@ -435,6 +435,11 @@ out_io:
out_io:
release_region(io, io_len);
+out_pnp:
+#if defined CONFIG_PNP
+ if (isapnp)
+ pnp_unregister_driver(&scl200wdt_pnp_driver);
+#endif
goto out_clean;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/clocksource/scx200_hrt.c
--- a/drivers/clocksource/scx200_hrt.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/clocksource/scx200_hrt.c Wed Oct 03 10:00:44 2007 +0100
@@ -63,7 +63,7 @@ static struct clocksource cs_hrt = {
static int __init init_hrt_clocksource(void)
{
- /* Make sure scx200 has initializedd the configuration block */
+ /* Make sure scx200 has initialized the configuration block */
if (!scx200_cb_present())
return -ENODEV;
@@ -76,7 +76,7 @@ static int __init init_hrt_clocksource(v
}
/* write timer config */
- outb(HR_TMEN | (mhz27) ? HR_TMCLKSEL : 0,
+ outb(HR_TMEN | (mhz27 ? HR_TMCLKSEL : 0),
scx200_cb_base + SCx200_TMCNFG_OFFSET);
if (mhz27) {
diff -r aafef975e518 -r 3e8752eb6d9c drivers/cpufreq/cpufreq_stats.c
--- a/drivers/cpufreq/cpufreq_stats.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/cpufreq/cpufreq_stats.c Wed Oct 03 10:00:44 2007 +0100
@@ -350,12 +350,10 @@ __init cpufreq_stats_init(void)
}
register_hotcpu_notifier(&cpufreq_stat_cpu_notifier);
- lock_cpu_hotplug();
for_each_online_cpu(cpu) {
cpufreq_stat_cpu_callback(&cpufreq_stat_cpu_notifier,
CPU_ONLINE,
(void *)(long)cpu);
}
- unlock_cpu_hotplug();
return 0;
}
static void
diff -r aafef975e518 -r 3e8752eb6d9c drivers/i2c/chips/ds1337.c
--- a/drivers/i2c/chips/ds1337.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/i2c/chips/ds1337.c Wed Oct 03 10:00:44 2007 +0100
@@ -347,13 +347,19 @@ static void ds1337_init_client(struct i2
if ((status & 0x80) || (control & 0x80)) {
/* RTC not running */
- u8 buf[16];
+ u8 buf[1+16]; /* First byte is interpreted as address */
struct i2c_msg msg[1];
dev_dbg(&client->dev, "%s: RTC not running!\n", __FUNCTION__);
/* Initialize all, including STATUS and CONTROL to zero */
memset(buf, 0, sizeof(buf));
+
+ /* Write valid values in the date/time registers */
+ buf[1+DS1337_REG_DAY] = 1;
+ buf[1+DS1337_REG_DATE] = 1;
+ buf[1+DS1337_REG_MONTH] = 1;
+
msg[0].addr = client->addr;
msg[0].flags = 0;
msg[0].len = sizeof(buf);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/ide/pci/generic.c
--- a/drivers/ide/pci/generic.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/ide/pci/generic.c Wed Oct 03 10:00:44 2007 +0100
@@ -242,13 +242,17 @@ static int __devinit generic_init_one(st
(!(PCI_FUNC(dev->devfn) & 1)))
goto out;
- if (dev->vendor == PCI_VENDOR_ID_JMICRON && PCI_FUNC(dev->devfn) != 1)
- goto out;
-
- pci_read_config_word(dev, PCI_COMMAND, &command);
- if (!(command & PCI_COMMAND_IO)) {
- printk(KERN_INFO "Skipping disabled %s IDE controller.\n",
d->name);
- goto out;
+ if (dev->vendor == PCI_VENDOR_ID_JMICRON) {
+ if (dev->device != PCI_DEVICE_ID_JMICRON_JMB368 &&
PCI_FUNC(dev->devfn) != 1)
+ goto out;
+ }
+
+ if (dev->vendor != PCI_VENDOR_ID_JMICRON) {
+ pci_read_config_word(dev, PCI_COMMAND, &command);
+ if (!(command & PCI_COMMAND_IO)) {
+ printk(KERN_INFO "Skipping disabled %s IDE
controller.\n", d->name);
+ goto out;
+ }
}
ret = ide_setup_pci_device(dev, d);
out:
diff -r aafef975e518 -r 3e8752eb6d9c drivers/ide/ppc/pmac.c
--- a/drivers/ide/ppc/pmac.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/ide/ppc/pmac.c Wed Oct 03 10:00:44 2007 +0100
@@ -1326,7 +1326,7 @@ pmac_ide_macio_attach(struct macio_dev *
if (macio_irq_count(mdev) == 0) {
printk(KERN_WARNING "ide%d: no intrs for device %s, using 13\n",
i, mdev->ofdev.node->full_name);
- irq = 13;
+ irq = irq_create_mapping(NULL, 13);
} else
irq = macio_irq(mdev, 0);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/ieee1394/ohci1394.c
--- a/drivers/ieee1394/ohci1394.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/ieee1394/ohci1394.c Wed Oct 03 10:00:44 2007 +0100
@@ -3218,6 +3218,19 @@ static int __devinit ohci1394_pci_probe(
struct ti_ohci *ohci; /* shortcut to currently handled device */
resource_size_t ohci_base;
+#ifdef CONFIG_PPC_PMAC
+ /* Necessary on some machines if ohci1394 was loaded/ unloaded before */
+ if (machine_is(powermac)) {
+ struct device_node *of_node = pci_device_to_OF_node(dev);
+
+ if (of_node) {
+ pmac_call_feature(PMAC_FTR_1394_CABLE_POWER, of_node,
+ 0, 1);
+ pmac_call_feature(PMAC_FTR_1394_ENABLE, of_node, 0, 1);
+ }
+ }
+#endif /* CONFIG_PPC_PMAC */
+
if (pci_enable_device(dev))
FAIL(-ENXIO, "Failed to enable OHCI hardware");
pci_set_master(dev);
@@ -3506,11 +3519,9 @@ static void ohci1394_pci_remove(struct p
#endif
#ifdef CONFIG_PPC_PMAC
- /* On UniNorth, power down the cable and turn off the chip
- * clock when the module is removed to save power on
- * laptops. Turning it back ON is done by the arch code when
- * pci_enable_device() is called */
- {
+ /* On UniNorth, power down the cable and turn off the chip clock
+ * to save power on laptops */
+ if (machine_is(powermac)) {
struct device_node* of_node;
of_node = pci_device_to_OF_node(ohci->dev);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/core/mad.c
--- a/drivers/infiniband/core/mad.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/core/mad.c Wed Oct 03 10:00:44 2007 +0100
@@ -1750,7 +1750,7 @@ ib_find_send_mad(struct ib_mad_agent_pri
*/
(is_direct(wc->recv_buf.mad->mad_hdr.mgmt_class) ||
rcv_has_same_gid(mad_agent_priv, wr, wc)))
- return wr;
+ return (wr->status == IB_WC_SUCCESS) ? wr : NULL;
}
/*
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/hw/mthca/mthca_cq.c
--- a/drivers/infiniband/hw/mthca/mthca_cq.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/hw/mthca/mthca_cq.c Wed Oct 03 10:00:44 2007 +0100
@@ -39,6 +39,8 @@
#include <linux/init.h>
#include <linux/hardirq.h>
+#include <asm/io.h>
+
#include <rdma/ib_pack.h>
#include "mthca_dev.h"
@@ -210,6 +212,11 @@ static inline void update_cons_index(str
mthca_write64(doorbell,
dev->kar + MTHCA_CQ_DOORBELL,
MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+ /*
+ * Make sure doorbells don't leak out of CQ spinlock
+ * and reach the HCA out of order:
+ */
+ mmiowb();
}
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/hw/mthca/mthca_mad.c
--- a/drivers/infiniband/hw/mthca/mthca_mad.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/hw/mthca/mthca_mad.c Wed Oct 03 10:00:44 2007 +0100
@@ -119,7 +119,7 @@ static void smp_snoop(struct ib_device *
mthca_update_rate(to_mdev(ibdev), port_num);
update_sm_ah(to_mdev(ibdev), port_num,
- be16_to_cpu(pinfo->lid),
+ be16_to_cpu(pinfo->sm_lid),
pinfo->neighbormtu_mastersmsl & 0xf);
event.device = ibdev;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/hw/mthca/mthca_qp.c
--- a/drivers/infiniband/hw/mthca/mthca_qp.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c Wed Oct 03 10:00:44 2007 +0100
@@ -38,6 +38,8 @@
#include <linux/init.h>
#include <linux/string.h>
#include <linux/slab.h>
+
+#include <asm/io.h>
#include <rdma/ib_verbs.h>
#include <rdma/ib_cache.h>
@@ -1730,6 +1732,11 @@ out:
mthca_write64(doorbell,
dev->kar + MTHCA_SEND_DOORBELL,
MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
+ /*
+ * Make sure doorbells don't leak out of SQ spinlock
+ * and reach the HCA out of order:
+ */
+ mmiowb();
}
qp->sq.next_ind = ind;
@@ -1848,6 +1855,12 @@ out:
qp->rq.next_ind = ind;
qp->rq.head += nreq;
+
+ /*
+ * Make sure doorbells don't leak out of RQ spinlock and reach
+ * the HCA out of order:
+ */
+ mmiowb();
spin_unlock_irqrestore(&qp->rq.lock, flags);
return err;
@@ -2110,6 +2123,12 @@ out:
MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
}
+ /*
+ * Make sure doorbells don't leak out of SQ spinlock and reach
+ * the HCA out of order:
+ */
+ mmiowb();
+
spin_unlock_irqrestore(&qp->sq.lock, flags);
return err;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/hw/mthca/mthca_srq.c
--- a/drivers/infiniband/hw/mthca/mthca_srq.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/hw/mthca/mthca_srq.c Wed Oct 03 10:00:44 2007 +0100
@@ -35,6 +35,8 @@
#include <linux/slab.h>
#include <linux/string.h>
+#include <asm/io.h>
+
#include "mthca_dev.h"
#include "mthca_cmd.h"
#include "mthca_memfree.h"
@@ -592,6 +594,12 @@ int mthca_tavor_post_srq_recv(struct ib_
dev->kar + MTHCA_RECEIVE_DOORBELL,
MTHCA_GET_DOORBELL_LOCK(&dev->doorbell_lock));
}
+
+ /*
+ * Make sure doorbells don't leak out of SRQ spinlock and
+ * reach the HCA out of order:
+ */
+ mmiowb();
spin_unlock_irqrestore(&srq->lock, flags);
return err;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/ulp/ipoib/ipoib_ib.c
--- a/drivers/infiniband/ulp/ipoib/ipoib_ib.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/ulp/ipoib/ipoib_ib.c Wed Oct 03 10:00:44 2007 +0100
@@ -619,8 +619,10 @@ void ipoib_ib_dev_flush(void *_dev)
* The device could have been brought down between the start and when
* we get here, don't bring it back up if it's not configured up
*/
- if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
+ if (test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags)) {
ipoib_ib_dev_up(dev);
+ ipoib_mcast_restart_task(dev);
+ }
mutex_lock(&priv->vlan_mutex);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/ulp/srp/ib_srp.c
--- a/drivers/infiniband/ulp/srp/ib_srp.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/ulp/srp/ib_srp.c Wed Oct 03 10:00:44 2007 +0100
@@ -1851,7 +1851,7 @@ static void srp_add_one(struct ib_device
*/
srp_dev->fmr_page_shift = max(9, ffs(dev_attr->page_size_cap) - 1);
srp_dev->fmr_page_size = 1 << srp_dev->fmr_page_shift;
- srp_dev->fmr_page_mask = ~((unsigned long) srp_dev->fmr_page_size - 1);
+ srp_dev->fmr_page_mask = ~((u64) srp_dev->fmr_page_size - 1);
INIT_LIST_HEAD(&srp_dev->dev_list);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/infiniband/ulp/srp/ib_srp.h
--- a/drivers/infiniband/ulp/srp/ib_srp.h Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/infiniband/ulp/srp/ib_srp.h Wed Oct 03 10:00:44 2007 +0100
@@ -87,7 +87,7 @@ struct srp_device {
struct ib_fmr_pool *fmr_pool;
int fmr_page_shift;
int fmr_page_size;
- unsigned long fmr_page_mask;
+ u64 fmr_page_mask;
};
struct srp_host {
diff -r aafef975e518 -r 3e8752eb6d9c drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/input/mouse/psmouse-base.c Wed Oct 03 10:00:44 2007 +0100
@@ -1332,19 +1332,21 @@ ssize_t psmouse_attr_set_helper(struct d
static ssize_t psmouse_show_int_attr(struct psmouse *psmouse, void *offset,
char *buf)
{
- unsigned long *field = (unsigned long *)((char *)psmouse +
(size_t)offset);
-
- return sprintf(buf, "%lu\n", *field);
+ unsigned int *field = (unsigned int *)((char *)psmouse +
(size_t)offset);
+
+ return sprintf(buf, "%u\n", *field);
}
static ssize_t psmouse_set_int_attr(struct psmouse *psmouse, void *offset,
const char *buf, size_t count)
{
- unsigned long *field = (unsigned long *)((char *)psmouse +
(size_t)offset);
+ unsigned int *field = (unsigned int *)((char *)psmouse +
(size_t)offset);
unsigned long value;
char *rest;
value = simple_strtoul(buf, &rest, 10);
if (*rest)
+ return -EINVAL;
+ if ((unsigned int)value != value)
return -EINVAL;
*field = value;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/capi/capidrv.c
--- a/drivers/isdn/capi/capidrv.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/capi/capidrv.c Wed Oct 03 10:00:44 2007 +0100
@@ -1907,7 +1907,8 @@ static int if_readstat(u8 __user *buf, i
}
for (p=buf, count=0; count < len; p++, count++) {
- put_user(*card->q931_read++, p);
+ if (put_user(*card->q931_read++, p))
+ return -EFAULT;
if (card->q931_read > card->q931_end)
card->q931_read = card->q931_buf;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/hisax/config.c
--- a/drivers/isdn/hisax/config.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/hisax/config.c Wed Oct 03 10:00:44 2007 +0100
@@ -631,7 +631,8 @@ static int HiSax_readstatus(u_char __use
count = cs->status_end - cs->status_read + 1;
if (count >= len)
count = len;
- copy_to_user(p, cs->status_read, count);
+ if (copy_to_user(p, cs->status_read, count))
+ return -EFAULT;
cs->status_read += count;
if (cs->status_read > cs->status_end)
cs->status_read = cs->status_buf;
@@ -642,7 +643,8 @@ static int HiSax_readstatus(u_char __use
cnt = HISAX_STATUS_BUFSIZE;
else
cnt = count;
- copy_to_user(p, cs->status_read, cnt);
+ if (copy_to_user(p, cs->status_read, cnt))
+ return -EFAULT;
p += cnt;
cs->status_read += cnt % HISAX_STATUS_BUFSIZE;
count -= cnt;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/i4l/isdn_common.c
--- a/drivers/isdn/i4l/isdn_common.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/i4l/isdn_common.c Wed Oct 03 10:00:44 2007 +0100
@@ -1134,9 +1134,12 @@ isdn_read(struct file *file, char __user
if (dev->drv[drvidx]->interface->readstat) {
if (count > dev->drv[drvidx]->stavail)
count = dev->drv[drvidx]->stavail;
- len = dev->drv[drvidx]->interface->
- readstat(buf, count, drvidx,
- isdn_minor2chan(minor));
+ len = dev->drv[drvidx]->interface->readstat(buf, count,
+ drvidx, isdn_minor2chan(minor));
+ if (len < 0) {
+ retval = len;
+ goto out;
+ }
} else {
len = 0;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/icn/icn.c
--- a/drivers/isdn/icn/icn.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/icn/icn.c Wed Oct 03 10:00:44 2007 +0100
@@ -1010,7 +1010,8 @@ icn_readstatus(u_char __user *buf, int l
for (p = buf, count = 0; count < len; p++, count++) {
if (card->msg_buf_read == card->msg_buf_write)
return count;
- put_user(*card->msg_buf_read++, p);
+ if (put_user(*card->msg_buf_read++, p))
+ return -EFAULT;
if (card->msg_buf_read > card->msg_buf_end)
card->msg_buf_read = card->msg_buf;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/isdnloop/isdnloop.c
--- a/drivers/isdn/isdnloop/isdnloop.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/isdnloop/isdnloop.c Wed Oct 03 10:00:44 2007 +0100
@@ -451,7 +451,8 @@ isdnloop_readstatus(u_char __user *buf,
for (p = buf, count = 0; count < len; p++, count++) {
if (card->msg_buf_read == card->msg_buf_write)
return count;
- put_user(*card->msg_buf_read++, p);
+ if (put_user(*card->msg_buf_read++, p))
+ return -EFAULT;
if (card->msg_buf_read > card->msg_buf_end)
card->msg_buf_read = card->msg_buf;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/isdn/pcbit/drv.c
--- a/drivers/isdn/pcbit/drv.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/isdn/pcbit/drv.c Wed Oct 03 10:00:44 2007 +0100
@@ -725,23 +725,27 @@ static int pcbit_stat(u_char __user *buf
if (stat_st < stat_end)
{
- copy_to_user(buf, statbuf + stat_st, len);
+ if (copy_to_user(buf, statbuf + stat_st, len))
+ return -EFAULT;
stat_st += len;
}
else
{
if (len > STATBUF_LEN - stat_st)
{
- copy_to_user(buf, statbuf + stat_st,
- STATBUF_LEN - stat_st);
- copy_to_user(buf, statbuf,
- len - (STATBUF_LEN - stat_st));
+ if (copy_to_user(buf, statbuf + stat_st,
+ STATBUF_LEN - stat_st))
+ return -EFAULT;
+ if (copy_to_user(buf, statbuf,
+ len - (STATBUF_LEN - stat_st)))
+ return -EFAULT;
stat_st = len - (STATBUF_LEN - stat_st);
}
else
{
- copy_to_user(buf, statbuf + stat_st, len);
+ if (copy_to_user(buf, statbuf + stat_st, len))
+ return -EFAULT;
stat_st += len;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/macintosh/via-pmu-backlight.c
--- a/drivers/macintosh/via-pmu-backlight.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/macintosh/via-pmu-backlight.c Wed Oct 03 10:00:44 2007 +0100
@@ -16,7 +16,7 @@
#define MAX_PMU_LEVEL 0xFF
static struct backlight_properties pmu_backlight_data;
-static spinlock_t pmu_backlight_lock;
+static DEFINE_SPINLOCK(pmu_backlight_lock);
static int sleeping;
static u8 bl_curve[FB_BACKLIGHT_LEVELS];
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/dm-crypt.c
--- a/drivers/md/dm-crypt.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/dm-crypt.c Wed Oct 03 10:00:44 2007 +0100
@@ -717,13 +717,15 @@ static int crypt_endio(struct bio *bio,
if (bio->bi_size)
return 1;
+ if (!bio_flagged(bio, BIO_UPTODATE) && !error)
+ error = -EIO;
+
bio_put(bio);
/*
* successful reads are decrypted by the worker thread
*/
- if ((bio_data_dir(bio) == READ)
- && bio_flagged(bio, BIO_UPTODATE)) {
+ if (bio_data_dir(io->bio) == READ && !error) {
kcryptd_queue_io(io);
return 0;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/dm-snap.c
--- a/drivers/md/dm-snap.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/dm-snap.c Wed Oct 03 10:00:44 2007 +0100
@@ -691,6 +691,7 @@ static void pending_complete(struct pend
free_exception(e);
+ remove_exception(&pe->e);
error_snapshot_bios(pe);
goto out;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/md.c
--- a/drivers/md/md.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/md.c Wed Oct 03 10:00:44 2007 +0100
@@ -1994,6 +1994,7 @@ static mdk_rdev_t *md_import_device(dev_
kobject_init(&rdev->kobj);
rdev->desc_nr = -1;
+ rdev->saved_raid_disk = -1;
rdev->flags = 0;
rdev->data_offset = 0;
rdev->sb_events = 0;
@@ -3867,6 +3868,7 @@ static int hot_add_disk(mddev_t * mddev,
}
clear_bit(In_sync, &rdev->flags);
rdev->desc_nr = -1;
+ rdev->saved_raid_disk = -1;
err = bind_rdev_to_array(rdev, mddev);
if (err)
goto abort_export;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/multipath.c
--- a/drivers/md/multipath.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/multipath.c Wed Oct 03 10:00:44 2007 +0100
@@ -480,7 +480,7 @@ static int multipath_run (mddev_t *mddev
mdname(mddev));
goto out_free_conf;
}
- mddev->degraded = conf->raid_disks = conf->working_disks;
+ mddev->degraded = conf->raid_disks - conf->working_disks;
conf->pool = mempool_create_kzalloc_pool(NR_RESERVED_BUFS,
sizeof(struct multipath_bh));
diff -r aafef975e518 -r 3e8752eb6d9c drivers/md/raid10.c
--- a/drivers/md/raid10.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/md/raid10.c Wed Oct 03 10:00:44 2007 +0100
@@ -2042,7 +2042,7 @@ static int run(mddev_t *mddev)
disk = conf->mirrors + i;
if (!disk->rdev ||
- !test_bit(In_sync, &rdev->flags)) {
+ !test_bit(In_sync, &disk->rdev->flags)) {
disk->head_position = 0;
mddev->degraded++;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/Kconfig
--- a/drivers/media/Kconfig Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/Kconfig Wed Oct 03 10:00:44 2007 +0100
@@ -54,6 +54,7 @@ config VIDEO_V4L1_COMPAT
config VIDEO_V4L2
bool
+ depends on VIDEO_DEV
default y
source "drivers/media/video/Kconfig"
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/b2c2/flexcop-fe-tuner.c
--- a/drivers/media/dvb/b2c2/flexcop-fe-tuner.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/b2c2/flexcop-fe-tuner.c Wed Oct 03 10:00:44 2007 +0100
@@ -527,7 +527,7 @@ int flexcop_frontend_init(struct flexcop
/* try the air atsc 2nd generation (nxt2002) */
if ((fc->fe = nxt200x_attach(&samsung_tbmv_config, &fc->i2c_adap)) !=
NULL) {
fc->dev_type = FC_AIR_ATSC2;
- dvb_pll_attach(fc->fe, 0x61, &fc->i2c_adap,
&dvb_pll_samsung_tbmv);
+ dvb_pll_attach(fc->fe, 0x61, NULL, &dvb_pll_samsung_tbmv);
info("found the nxt2002 at i2c address:
0x%02x",samsung_tbmv_config.demod_address);
} else
/* try the air atsc 3nd generation (lgdt3303) */
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/dvb-core/dvb_net.c
--- a/drivers/media/dvb/dvb-core/dvb_net.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/dvb-core/dvb_net.c Wed Oct 03 10:00:44 2007 +0100
@@ -604,7 +604,7 @@ static void dvb_net_ule( struct net_devi
{ &utype, sizeof utype },
{ priv->ule_skb->data, priv->ule_skb->len - 4 }
};
- unsigned long ule_crc = ~0L, expected_crc;
+ u32 ule_crc = ~0L, expected_crc;
if (priv->ule_dbit) {
/* Set D-bit for CRC32 verification,
* if it was set originally. */
@@ -617,7 +617,7 @@ static void dvb_net_ule( struct net_devi
*((u8 *)priv->ule_skb->tail - 2) << 8 |
*((u8 *)priv->ule_skb->tail - 1);
if (ule_crc != expected_crc) {
- printk(KERN_WARNING "%lu: CRC32 check FAILED:
%#lx / %#lx, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
+ printk(KERN_WARNING "%lu: CRC32 check FAILED:
%08x / %08x, SNDU len %d type %#x, ts_remain %d, next 2: %x.\n",
priv->ts_count, ule_crc, expected_crc,
priv->ule_sndu_len, priv->ule_sndu_type, ts_remain, ts_remain > 2 ? *(unsigned
short *)from_where : 0);
#ifdef ULE_DEBUG
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/frontends/cx24123.c
--- a/drivers/media/dvb/frontends/cx24123.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/frontends/cx24123.c Wed Oct 03 10:00:44 2007 +0100
@@ -549,8 +549,8 @@ static int cx24123_pll_calculate(struct
ndiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) / 32) &
0x1ff;
adiv = ( ((p->frequency * vco_div * 10) / (2 * XTAL / 1000)) % 32) &
0x1f;
- if (adiv == 0)
- ndiv++;
+ if (adiv == 0 && ndiv > 0)
+ ndiv--;
/* control bits 11, refdiv 11, charge pump polarity 1, charge pump
current, ndiv, adiv */
state->pllarg = (3 << 19) | (3 << 17) | (1 << 16) | (pump << 14) |
(ndiv << 5) | adiv;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/frontends/dvb-pll.c
--- a/drivers/media/dvb/frontends/dvb-pll.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/frontends/dvb-pll.c Wed Oct 03 10:00:44 2007 +0100
@@ -493,6 +493,9 @@ static int dvb_pll_sleep(struct dvb_fron
int i;
int result;
+ if (priv->i2c == NULL)
+ return -EINVAL;
+
for (i = 0; i < priv->pll_desc->count; i++) {
if (priv->pll_desc->entries[i].limit == 0)
break;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/dvb/frontends/lgdt330x.c
--- a/drivers/media/dvb/frontends/lgdt330x.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/dvb/frontends/lgdt330x.c Wed Oct 03 10:00:44 2007 +0100
@@ -435,9 +435,6 @@ static int lgdt3302_read_status(struct d
/* Test signal does not exist flag */
/* as well as the AGC lock flag. */
*status |= FE_HAS_SIGNAL;
- } else {
- /* Without a signal all other status bits are meaningless */
- return 0;
}
/*
@@ -500,9 +497,6 @@ static int lgdt3303_read_status(struct d
/* Test input signal does not exist flag */
/* as well as the AGC lock flag. */
*status |= FE_HAS_SIGNAL;
- } else {
- /* Without a signal all other status bits are meaningless */
- return 0;
}
/* Carrier Recovery Lock Status Register */
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/cx88/cx88-cards.c
--- a/drivers/media/video/cx88/cx88-cards.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/cx88/cx88-cards.c Wed Oct 03 10:00:44 2007 +0100
@@ -1465,7 +1465,7 @@ const unsigned int cx88_idcount = ARRAY_
/* ----------------------------------------------------------------------- */
/* some leadtek specific stuff */
-static void __devinit leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
+static void leadtek_eeprom(struct cx88_core *core, u8 *eeprom_data)
{
/* This is just for the "Winfast 2000XP Expert" board ATM; I don't have
data on
* any others.
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/cx88/cx88-dvb.c
--- a/drivers/media/video/cx88/cx88-dvb.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/cx88/cx88-dvb.c Wed Oct 03 10:00:44 2007 +0100
@@ -576,7 +576,7 @@ static int dvb_register(struct cx8802_de
&dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dvb_pll_attach(dev->dvb.frontend, 0x60,
- &dev->core->i2c_adap,
+ NULL,
&dvb_pll_thomson_dtt7579);
break;
}
@@ -587,7 +587,7 @@ static int dvb_register(struct cx8802_de
&dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dvb_pll_attach(dev->dvb.frontend, 0x60,
- &dev->core->i2c_adap,
+ NULL,
&dvb_pll_thomson_dtt7579);
}
#endif
@@ -600,7 +600,7 @@ static int dvb_register(struct cx8802_de
&dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
+ NULL,
&dvb_pll_thomson_dtt7579);
break;
}
@@ -611,7 +611,7 @@ static int dvb_register(struct cx8802_de
&dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
+ NULL,
&dvb_pll_thomson_dtt7579);
}
#endif
@@ -623,7 +623,7 @@ static int dvb_register(struct cx8802_de
&dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
+ NULL,
&dvb_pll_lg_z201);
}
break;
@@ -634,7 +634,7 @@ static int dvb_register(struct cx8802_de
&dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
+ NULL,
&dvb_pll_unknown_1);
}
break;
@@ -757,7 +757,7 @@ static int dvb_register(struct cx8802_de
&dev->core->i2c_adap);
if (dev->dvb.frontend != NULL) {
dvb_pll_attach(dev->dvb.frontend, 0x61,
- &dev->core->i2c_adap,
+ NULL,
&dvb_pll_tuv1236d);
}
break;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/ks0127.c
--- a/drivers/media/video/ks0127.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/ks0127.c Wed Oct 03 10:00:44 2007 +0100
@@ -712,13 +712,13 @@ static int ks0127_command(struct i2c_cli
*iarg = 0;
status = ks0127_read(ks, KS_STAT);
if (!(status & 0x20)) /* NOVID not set */
- *iarg = (*iarg & DECODER_STATUS_GOOD);
+ *iarg = (*iarg | DECODER_STATUS_GOOD);
if ((status & 0x01)) /* CLOCK set */
- *iarg = (*iarg & DECODER_STATUS_COLOR);
+ *iarg = (*iarg | DECODER_STATUS_COLOR);
if ((status & 0x08)) /* PALDET set */
- *iarg = (*iarg & DECODER_STATUS_PAL);
+ *iarg = (*iarg | DECODER_STATUS_PAL);
else
- *iarg = (*iarg & DECODER_STATUS_NTSC);
+ *iarg = (*iarg | DECODER_STATUS_NTSC);
break;
//Catch any unknown command
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/msp3400-driver.c
--- a/drivers/media/video/msp3400-driver.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/msp3400-driver.c Wed Oct 03 10:00:44 2007 +0100
@@ -904,6 +904,8 @@ static int msp_attach(struct i2c_adapter
state->has_virtual_dolby_surround = msp_revision == 'G' && msp_prod_lo
== 1;
/* Has Virtual Dolby Surround & Dolby Pro Logic: only in msp34x2 */
state->has_dolby_pro_logic = msp_revision == 'G' && msp_prod_lo == 2;
+ /* The msp343xG supports BTSC only and cannot do Automatic Standard
Detection. */
+ state->force_btsc = msp_family == 3 && msp_revision == 'G' &&
msp_prod_hi == 3;
state->opmode = opmode;
if (state->opmode == OPMODE_AUTO) {
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/msp3400-driver.h
--- a/drivers/media/video/msp3400-driver.h Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/msp3400-driver.h Wed Oct 03 10:00:44 2007 +0100
@@ -64,6 +64,7 @@ struct msp_state {
u8 has_sound_processing;
u8 has_virtual_dolby_surround;
u8 has_dolby_pro_logic;
+ u8 force_btsc;
int radio;
int opmode;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/msp3400-kthreads.c
--- a/drivers/media/video/msp3400-kthreads.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/msp3400-kthreads.c Wed Oct 03 10:00:44 2007 +0100
@@ -960,9 +960,10 @@ int msp34xxg_thread(void *data)
/* setup the chip*/
msp34xxg_reset(client);
- state->std = state->radio ? 0x40 : msp_standard;
+ state->std = state->radio ? 0x40 :
+ (state->force_btsc && msp_standard == 1) ? 32 :
msp_standard;
+ msp_write_dem(client, 0x20, state->std);
/* start autodetect */
- msp_write_dem(client, 0x20, state->std);
if (state->std != 1)
goto unmute;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/pvrusb2/Kconfig
--- a/drivers/media/video/pvrusb2/Kconfig Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/pvrusb2/Kconfig Wed Oct 03 10:00:44 2007 +0100
@@ -25,14 +25,9 @@ config VIDEO_PVRUSB2_24XXX
form "24xxx" (leading prefix of "24" followed by 3 digits).
To see if you may need this option, examine the white
sticker on the underside of your device. Enabling this
- option will not harm support for older devices, however it
- is a separate option because of the experimental nature of
- this new feature.
+ option will not harm support for older devices.
- If you are in doubt, say N.
-
- Note: This feature is _very_ experimental. You have been
- warned.
+ If you are in doubt, say Y.
config VIDEO_PVRUSB2_SYSFS
bool "pvrusb2 sysfs support (EXPERIMENTAL)"
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/pvrusb2/pvrusb2-ctrl.c
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c Wed Oct 03 10:00:44
2007 +0100
@@ -43,12 +43,17 @@ int pvr2_ctrl_set_mask_value(struct pvr2
if (cptr->info->type == pvr2_ctl_bitmask) {
mask &= cptr->info->def.type_bitmask.valid_bits;
} else if (cptr->info->type == pvr2_ctl_int) {
- if (val < cptr->info->def.type_int.min_value) {
- break;
+ int lim;
+ lim = cptr->info->def.type_int.min_value;
+ if (cptr->info->get_min_value) {
+ cptr->info->get_min_value(cptr,&lim);
}
- if (val > cptr->info->def.type_int.max_value) {
- break;
+ if (val < lim) break;
+ lim = cptr->info->def.type_int.max_value;
+ if (cptr->info->get_max_value) {
+ cptr->info->get_max_value(cptr,&lim);
}
+ if (val > lim) break;
} else if (cptr->info->type == pvr2_ctl_enum) {
if (val >= cptr->info->def.type_enum.count) {
break;
@@ -91,7 +96,9 @@ int pvr2_ctrl_get_max(struct pvr2_ctrl *
int ret = 0;
if (!cptr) return 0;
LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_int) {
+ if (cptr->info->get_max_value) {
+ cptr->info->get_max_value(cptr,&ret);
+ } else if (cptr->info->type == pvr2_ctl_int) {
ret = cptr->info->def.type_int.max_value;
}
} while(0); LOCK_GIVE(cptr->hdw->big_lock);
@@ -105,7 +112,9 @@ int pvr2_ctrl_get_min(struct pvr2_ctrl *
int ret = 0;
if (!cptr) return 0;
LOCK_TAKE(cptr->hdw->big_lock); do {
- if (cptr->info->type == pvr2_ctl_int) {
+ if (cptr->info->get_min_value) {
+ cptr->info->get_min_value(cptr,&ret);
+ } else if (cptr->info->type == pvr2_ctl_int) {
ret = cptr->info->def.type_int.min_value;
}
} while(0); LOCK_GIVE(cptr->hdw->big_lock);
diff -r aafef975e518 -r 3e8752eb6d9c
drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h Tue Oct 02
09:52:15 2007 +0100
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw-internal.h Wed Oct 03
10:00:44 2007 +0100
@@ -107,6 +107,8 @@ struct pvr2_ctl_info {
/* Control's implementation */
pvr2_ctlf_get_value get_value; /* Get its value */
+ pvr2_ctlf_get_value get_min_value; /* Get minimum allowed value */
+ pvr2_ctlf_get_value get_max_value; /* Get maximum allowed value */
pvr2_ctlf_set_value set_value; /* Set its value */
pvr2_ctlf_val_to_sym val_to_sym; /* Custom convert value->symbol */
pvr2_ctlf_sym_to_val sym_to_val; /* Custom convert symbol->value */
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/pvrusb2/pvrusb2-hdw.c
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c Wed Oct 03 10:00:44 2007 +0100
@@ -362,6 +362,30 @@ static int ctrl_freq_set(struct pvr2_ctr
return 0;
}
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+static int ctrl_hres_max_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ /* If we're dealing with a 24xxx device, force the horizontal
+ maximum to be 720 no matter what, since we can't get the device
+ to work properly with any other value. Otherwise just return
+ the normal value. */
+ *vp = cptr->info->def.type_int.max_value;
+ if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
+ return 0;
+}
+
+static int ctrl_hres_min_get(struct pvr2_ctrl *cptr,int *vp)
+{
+ /* If we're dealing with a 24xxx device, force the horizontal
+ minimum to be 720 no matter what, since we can't get the device
+ to work properly with any other value. Otherwise just return
+ the normal value. */
+ *vp = cptr->info->def.type_int.min_value;
+ if (cptr->hdw->hdw_type == PVR2_HDW_TYPE_24XXX) *vp = 720;
+ return 0;
+}
+#endif
+
static int ctrl_cx2341x_is_dirty(struct pvr2_ctrl *cptr)
{
return cptr->hdw->enc_stale != 0;
@@ -720,6 +744,12 @@ static const struct pvr2_ctl_info contro
.default_value = 720,
DEFREF(res_hor),
DEFINT(320,720),
+#ifdef CONFIG_VIDEO_PVRUSB2_24XXX
+ /* Hook in check for clamp on horizontal resolution in
+ order to avoid unsolved problem involving cx25840. */
+ .get_max_value = ctrl_hres_max_get,
+ .get_min_value = ctrl_hres_min_get,
+#endif
},{
.desc = "Vertical capture resolution",
.name = "resolution_ver",
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/pvrusb2/pvrusb2-v4l2.c
--- a/drivers/media/video/pvrusb2/pvrusb2-v4l2.c Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/media/video/pvrusb2/pvrusb2-v4l2.c Wed Oct 03 10:00:44
2007 +0100
@@ -22,6 +22,7 @@
#include <linux/kernel.h>
#include <linux/version.h>
+#include <linux/videodev.h>
#include "pvrusb2-context.h"
#include "pvrusb2-hdw.h"
#include "pvrusb2.h"
@@ -31,25 +32,21 @@
#include <linux/videodev2.h>
#include <media/v4l2-common.h>
+/* Mike Isely <isely@xxxxxxxxx> 23-Sep-2006 - This function is prototyped
+ * only for V4L1 but is implemented regardless of the V4L1 compatibility
+ * option state. V4L2 has no replacement for this and we need it. For now
+ * copy the prototype here so we can avoid the compiler warning. */
+extern struct video_device* video_devdata(struct file*);
+
struct pvr2_v4l2_dev;
struct pvr2_v4l2_fh;
struct pvr2_v4l2;
-/* V4L no longer provide the ability to set / get a private context pointer
- (i.e. video_get_drvdata / video_set_drvdata), which means we have to
- concoct our own context locating mechanism. Supposedly this is intended
- to simplify driver implementation. It's not clear to me how that can
- possibly be true. Our solution here is to maintain a lookup table of
- our context instances, indexed by the minor device number of the V4L
- device. See pvr2_v4l2_open() for some implications of this approach. */
-static struct pvr2_v4l2_dev *devices[256];
-static DEFINE_MUTEX(device_lock);
struct pvr2_v4l2_dev {
struct pvr2_v4l2 *v4lp;
struct video_device *vdev;
struct pvr2_context_stream *stream;
- int ctxt_idx;
enum pvr2_config config;
};
@@ -459,18 +456,26 @@ static int pvr2_v4l2_do_ioctl(struct ino
ret = 0;
switch(vf->type) {
case V4L2_BUF_TYPE_VIDEO_CAPTURE: {
+ int lmin,lmax;
+ struct pvr2_ctrl *hcp,*vcp;
int h = vf->fmt.pix.height;
int w = vf->fmt.pix.width;
-
- if (h < 200) {
- h = 200;
- } else if (h > 625) {
- h = 625;
- }
- if (w < 320) {
- w = 320;
- } else if (w > 720) {
- w = 720;
+ hcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_HRES);
+ vcp = pvr2_hdw_get_ctrl_by_id(hdw,PVR2_CID_VRES);
+
+ lmin = pvr2_ctrl_get_min(hcp);
+ lmax = pvr2_ctrl_get_max(hcp);
+ if (w < lmin) {
+ w = lmin;
+ } else if (w > lmax) {
+ w = lmax;
+ }
+ lmin = pvr2_ctrl_get_min(vcp);
+ lmax = pvr2_ctrl_get_max(vcp);
+ if (h < lmin) {
+ h = lmin;
+ } else if (h > lmax) {
+ h = lmax;
}
memcpy(vf, &pvr_format[PVR_FORMAT_PIX],
@@ -479,14 +484,8 @@ static int pvr2_v4l2_do_ioctl(struct ino
vf->fmt.pix.height = h;
if (cmd == VIDIOC_S_FMT) {
- pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw,
- PVR2_CID_HRES),
- vf->fmt.pix.width);
- pvr2_ctrl_set_value(
- pvr2_hdw_get_ctrl_by_id(hdw,
- PVR2_CID_VRES),
- vf->fmt.pix.height);
+ pvr2_ctrl_set_value(hcp,vf->fmt.pix.width);
+ pvr2_ctrl_set_value(vcp,vf->fmt.pix.height);
}
} break;
case V4L2_BUF_TYPE_VBI_CAPTURE:
@@ -703,12 +702,6 @@ static void pvr2_v4l2_dev_destroy(struct
{
printk(KERN_INFO "pvrusb2: unregistering device video%d [%s]\n",
dip->vdev->minor,pvr2_config_get_name(dip->config));
- if (dip->ctxt_idx >= 0) {
- mutex_lock(&device_lock);
- devices[dip->ctxt_idx] = NULL;
- dip->ctxt_idx = -1;
- mutex_unlock(&device_lock);
- }
video_unregister_device(dip->vdev);
}
@@ -800,33 +793,10 @@ static int pvr2_v4l2_open(struct inode *
struct pvr2_v4l2 *vp;
struct pvr2_hdw *hdw;
- mutex_lock(&device_lock);
- /* MCI 7-Jun-2006 Even though we're just doing what amounts to an
- atomic read of the device mapping array here, we still need the
- mutex. The problem is that there is a tiny race possible when
- we register the device. We can't update the device mapping
- array until after the device has been registered, owing to the
- fact that we can't know the minor device number until after the
- registration succeeds. And if another thread tries to open the
- device in the window of time after registration but before the
- map is updated, then it will get back an erroneous null pointer
- and the open will result in a spurious failure. The only way to
- prevent that is to (a) be inside the mutex here before we access
- the array, and (b) cover the entire registration process later
- on with this same mutex. Thus if we get inside the mutex here,
- then we can be assured that the registration process actually
- completed correctly. This is an unhappy complication from the
- use of global data in a driver that lives in a preemptible
- environment. It sure would be nice if the video device itself
- had a means for storing and retrieving a local context pointer.
- Oh wait. It did. But now it's gone. Silly me. */
- {
- unsigned int midx = iminor(file->f_dentry->d_inode);
- if (midx < sizeof(devices)/sizeof(devices[0])) {
- dip = devices[midx];
- }
- }
- mutex_unlock(&device_lock);
+ {
+ struct video_device *vdev = video_devdata(file);
+ dip = (struct pvr2_v4l2_dev *)video_get_drvdata(vdev);
+ }
if (!dip) return -ENODEV; /* Should be impossible but I'm paranoid */
@@ -1066,7 +1036,7 @@ static void pvr2_v4l2_dev_init(struct pv
memcpy(dip->vdev,&vdev_template,sizeof(vdev_template));
dip->vdev->release = video_device_release;
- mutex_lock(&device_lock);
+ video_set_drvdata(dip->vdev,dip);
mindevnum = -1;
unit_number = pvr2_hdw_get_unit_number(vp->channel.mc_head->hdw);
@@ -1081,12 +1051,6 @@ static void pvr2_v4l2_dev_init(struct pv
dip->vdev->minor,pvr2_config_get_name(dip->config));
}
- if ((dip->vdev->minor < sizeof(devices)/sizeof(devices[0])) &&
- (devices[dip->vdev->minor] == NULL)) {
- dip->ctxt_idx = dip->vdev->minor;
- devices[dip->ctxt_idx] = dip;
- }
- mutex_unlock(&device_lock);
pvr2_hdw_v4l_store_minor_number(vp->channel.mc_head->hdw,
dip->vdev->minor);
@@ -1100,7 +1064,6 @@ struct pvr2_v4l2 *pvr2_v4l2_create(struc
vp = kmalloc(sizeof(*vp),GFP_KERNEL);
if (!vp) return vp;
memset(vp,0,sizeof(*vp));
- vp->video_dev.ctxt_idx = -1;
pvr2_channel_init(&vp->channel,mnp);
pvr2_trace(PVR2_TRACE_STRUCT,"Creating pvr2_v4l2 id=%p",vp);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/saa7134/saa7134-dvb.c
--- a/drivers/media/video/saa7134/saa7134-dvb.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/saa7134/saa7134-dvb.c Wed Oct 03 10:00:44 2007 +0100
@@ -1158,13 +1158,13 @@ static int dvb_init(struct saa7134_dev *
case SAA7134_BOARD_AVERMEDIA_AVERTVHD_A180:
dev->dvb.frontend = nxt200x_attach(&avertvhda180,
&dev->i2c_adap);
if (dev->dvb.frontend) {
- dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap,
&dvb_pll_tdhu2);
+ dvb_pll_attach(dev->dvb.frontend, 0x61, NULL,
&dvb_pll_tdhu2);
}
break;
case SAA7134_BOARD_KWORLD_ATSC110:
dev->dvb.frontend = nxt200x_attach(&kworldatsc110,
&dev->i2c_adap);
if (dev->dvb.frontend) {
- dvb_pll_attach(dev->dvb.frontend, 0x61, &dev->i2c_adap,
&dvb_pll_tuv1236d);
+ dvb_pll_attach(dev->dvb.frontend, 0x61, NULL,
&dvb_pll_tuv1236d);
}
break;
#endif
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/tuner-simple.c
--- a/drivers/media/video/tuner-simple.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/tuner-simple.c Wed Oct 03 10:00:44 2007 +0100
@@ -108,6 +108,7 @@ static int tuner_stereo(struct i2c_clien
case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3:
case TUNER_PHILIPS_FM1256_IH3:
+ case TUNER_LG_NTSC_TAPE:
stereo = ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
break;
default:
@@ -419,6 +420,7 @@ static void default_set_radio_freq(struc
case TUNER_PHILIPS_FM1216ME_MK3:
case TUNER_PHILIPS_FM1236_MK3:
case TUNER_PHILIPS_FMD1216ME_MK3:
+ case TUNER_LG_NTSC_TAPE:
buffer[3] = 0x19;
break;
case TUNER_TNF_5335MF:
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/tuner-types.c
--- a/drivers/media/video/tuner-types.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/tuner-types.c Wed Oct 03 10:00:44 2007 +0100
@@ -671,16 +671,6 @@ static struct tuner_params tuner_panason
},
};
-/* ------------ TUNER_LG_NTSC_TAPE - LGINNOTEK NTSC ------------ */
-
-static struct tuner_params tuner_lg_ntsc_tape_params[] = {
- {
- .type = TUNER_PARAM_TYPE_NTSC,
- .ranges = tuner_fm1236_mk3_ntsc_ranges,
- .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
- },
-};
-
/* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */
static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = {
@@ -1331,8 +1321,8 @@ struct tunertype tuners[] = {
},
[TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
.name = "LG NTSC (TAPE series)",
- .params = tuner_lg_ntsc_tape_params,
- .count = ARRAY_SIZE(tuner_lg_ntsc_tape_params),
+ .params = tuner_fm1236_mk3_params,
+ .count = ARRAY_SIZE(tuner_fm1236_mk3_params),
},
[TUNER_TNF_8831BGFF] = { /* Philips PAL */
.name = "Tenna TNF 8831 BGFF)",
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/tveeprom.c
--- a/drivers/media/video/tveeprom.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/tveeprom.c Wed Oct 03 10:00:44 2007 +0100
@@ -184,7 +184,7 @@ hauppauge_tuner[] =
{ TUNER_ABSENT, "Thompson DTT757"},
/* 80-89 */
{ TUNER_ABSENT, "Philips FQ1216LME MK3"},
- { TUNER_ABSENT, "LG TAPC G701D"},
+ { TUNER_LG_PAL_NEW_TAPC, "LG TAPC G701D"},
{ TUNER_LG_NTSC_NEW_TAPC, "LG TAPC H791F"},
{ TUNER_LG_PAL_NEW_TAPC, "TCL 2002MB 3"},
{ TUNER_LG_PAL_NEW_TAPC, "TCL 2002MI 3"},
diff -r aafef975e518 -r 3e8752eb6d9c
drivers/media/video/usbvideo/quickcam_messenger.h
--- a/drivers/media/video/usbvideo/quickcam_messenger.h Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/media/video/usbvideo/quickcam_messenger.h Wed Oct 03 10:00:44
2007 +0100
@@ -35,27 +35,13 @@ struct rgb {
};
struct bayL0 {
-#ifdef __BIG_ENDIAN
- u8 r;
- u8 g;
-#elif __LITTLE_ENDIAN
u8 g;
u8 r;
-#else
-#error not byte order defined
-#endif
};
struct bayL1 {
-#ifdef __BIG_ENDIAN
- u8 g;
- u8 b;
-#elif __LITTLE_ENDIAN
u8 b;
u8 g;
-#else
-#error not byte order defined
-#endif
};
struct cam_size {
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/video-buf.c
--- a/drivers/media/video/video-buf.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/video-buf.c Wed Oct 03 10:00:44 2007 +0100
@@ -695,6 +695,7 @@ videobuf_qbuf(struct videobuf_queue *q,
goto done;
}
if (buf->state == STATE_QUEUED ||
+ buf->state == STATE_PREPARED ||
buf->state == STATE_ACTIVE) {
dprintk(1,"qbuf: buffer is already queued or active.\n");
goto done;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/media/video/videodev.c
--- a/drivers/media/video/videodev.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/media/video/videodev.c Wed Oct 03 10:00:44 2007 +0100
@@ -739,13 +739,13 @@ static int __video_do_ioctl(struct inode
case VIDIOC_DQBUF:
{
struct v4l2_buffer *p=arg;
- if (!vfd->vidioc_qbuf)
+ if (!vfd->vidioc_dqbuf)
break;
ret = check_fmt (vfd, p->type);
if (ret)
break;
- ret=vfd->vidioc_qbuf(file, fh, p);
+ ret=vfd->vidioc_dqbuf(file, fh, p);
if (!ret)
dbgbuf(cmd,vfd,p);
break;
@@ -836,7 +836,7 @@ static int __video_do_ioctl(struct inode
break;
}
- if (index<=0 || index >= vfd->tvnormsize) {
+ if (index < 0 || index >= vfd->tvnormsize) {
ret=-EINVAL;
break;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/bonding/bond_main.c Wed Oct 03 10:00:44 2007 +0100
@@ -3547,7 +3547,7 @@ static int bond_do_ioctl(struct net_devi
mii->val_out = 0;
read_lock_bh(&bond->lock);
read_lock(&bond->curr_slave_lock);
- if (bond->curr_active_slave) {
+ if (netif_carrier_ok(bond->dev)) {
mii->val_out = BMSR_LSTATUS;
}
read_unlock(&bond->curr_slave_lock);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/e1000/e1000_main.c
--- a/drivers/net/e1000/e1000_main.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/e1000/e1000_main.c Wed Oct 03 10:00:44 2007 +0100
@@ -4683,6 +4683,9 @@ e1000_suspend(struct pci_dev *pdev, pm_m
if (adapter->hw.phy_type == e1000_phy_igp_3)
e1000_phy_powerdown_workaround(&adapter->hw);
+ if (netif_running(netdev))
+ e1000_free_irq(adapter);
+
/* Release control of h/w to f/w. If f/w is AMT enabled, this
* would have already happened in close and is redundant. */
e1000_release_hw_control(adapter);
@@ -4710,6 +4713,10 @@ e1000_resume(struct pci_dev *pdev)
pci_enable_wake(pdev, PCI_D3hot, 0);
pci_enable_wake(pdev, PCI_D3cold, 0);
+ if (netif_running(netdev) && (ret_val = e1000_request_irq(adapter)))
+ return ret_val;
+
+ e1000_power_up_phy(adapter);
e1000_reset(adapter);
E1000_WRITE_REG(&adapter->hw, WUS, ~0);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/forcedeth.c
--- a/drivers/net/forcedeth.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/forcedeth.c Wed Oct 03 10:00:44 2007 +0100
@@ -2692,11 +2692,13 @@ static int nv_request_irq(struct net_dev
}
if (ret != 0 && np->msi_flags & NV_MSI_CAPABLE) {
if ((ret = pci_enable_msi(np->pci_dev)) == 0) {
+ pci_intx(np->pci_dev, 0);
np->msi_flags |= NV_MSI_ENABLED;
if ((!intr_test && request_irq(np->pci_dev->irq,
&nv_nic_irq, IRQF_SHARED, dev->name, dev) != 0) ||
(intr_test && request_irq(np->pci_dev->irq,
&nv_nic_irq_test, IRQF_SHARED, dev->name, dev) != 0)) {
printk(KERN_INFO "forcedeth: request_irq failed
%d\n", ret);
pci_disable_msi(np->pci_dev);
+ pci_intx(np->pci_dev, 1);
np->msi_flags &= ~NV_MSI_ENABLED;
goto out_err;
}
@@ -2739,6 +2741,7 @@ static void nv_free_irq(struct net_devic
free_irq(np->pci_dev->irq, dev);
if (np->msi_flags & NV_MSI_ENABLED) {
pci_disable_msi(np->pci_dev);
+ pci_intx(np->pci_dev, 1);
np->msi_flags &= ~NV_MSI_ENABLED;
}
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/lp486e.c
--- a/drivers/net/lp486e.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/lp486e.c Wed Oct 03 10:00:44 2007 +0100
@@ -442,16 +442,16 @@ init_rx_bufs(struct net_device *dev, int
if (rbd) {
rbd->pad = 0;
rbd->count = 0;
- rbd->skb = dev_alloc_skb(RX_SKB_SIZE);
+ rbd->skb = dev_alloc_skb(RX_SKBSIZE);
if (!rbd->skb) {
printk("dev_alloc_skb failed");
}
rbd->next = rfd->rbd;
if (i) {
rfd->rbd->prev = rbd;
- rbd->size = RX_SKB_SIZE;
+ rbd->size = RX_SKBSIZE;
} else {
- rbd->size = (RX_SKB_SIZE | RBD_EL);
+ rbd->size = (RX_SKBSIZE | RBD_EL);
lp->rbd_tail = rbd;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/mv643xx_eth.c
--- a/drivers/net/mv643xx_eth.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/mv643xx_eth.c Wed Oct 03 10:00:44 2007 +0100
@@ -385,7 +385,7 @@ static int mv643xx_eth_receive_queue(str
struct pkt_info pkt_info;
while (budget-- > 0 && eth_port_receive(mp, &pkt_info) == ETH_OK) {
- dma_unmap_single(NULL, pkt_info.buf_ptr, RX_SKB_SIZE,
+ dma_unmap_single(NULL, pkt_info.buf_ptr, ETH_RX_SKB_SIZE,
DMA_FROM_DEVICE);
mp->rx_desc_count--;
received_packets++;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/sky2.c
--- a/drivers/net/sky2.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/sky2.c Wed Oct 03 10:00:44 2007 +0100
@@ -106,6 +106,7 @@ static const struct pci_device_id sky2_i
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9000) },
{ PCI_DEVICE(PCI_VENDOR_ID_SYSKONNECT, 0x9E00) },
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4b00) }, /* DGE-560T */
+ { PCI_DEVICE(PCI_VENDOR_ID_DLINK, 0x4001) }, /* DGE-550SX */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4340) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4341) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4342) },
@@ -117,10 +118,17 @@ static const struct pci_device_id sky2_i
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4350) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4351) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4352) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4353) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4360) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) },
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4365) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4369) },
{ 0 }
};
@@ -670,7 +678,7 @@ static void sky2_mac_init(struct sky2_hw
sky2_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
if (hw->chip_id == CHIP_ID_YUKON_EC_U) {
- sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 768/8);
+ sky2_write8(hw, SK_REG(port, RX_GMF_LP_THR), 512/8);
sky2_write8(hw, SK_REG(port, RX_GMF_UP_THR), 1024/8);
if (hw->dev[port]->mtu > ETH_DATA_LEN) {
/* set Tx GMAC FIFO Almost Empty Threshold */
@@ -682,16 +690,10 @@ static void sky2_mac_init(struct sky2_hw
}
-/* Assign Ram Buffer allocation.
- * start and end are in units of 4k bytes
- * ram registers are in units of 64bit words
- */
-static void sky2_ramset(struct sky2_hw *hw, u16 q, u8 startk, u8 endk)
-{
- u32 start, end;
-
- start = startk * 4096/8;
- end = (endk * 4096/8) - 1;
+/* Assign Ram Buffer allocation in units of 64bit (8 bytes) */
+static void sky2_ramset(struct sky2_hw *hw, u16 q, u32 start, u32 end)
+{
+ pr_debug(PFX "q %d %#x %#x\n", q, start, end);
sky2_write8(hw, RB_ADDR(q, RB_CTRL), RB_RST_CLR);
sky2_write32(hw, RB_ADDR(q, RB_START), start);
@@ -700,7 +702,7 @@ static void sky2_ramset(struct sky2_hw *
sky2_write32(hw, RB_ADDR(q, RB_RP), start);
if (q == Q_R1 || q == Q_R2) {
- u32 space = (endk - startk) * 4096/8;
+ u32 space = end - start + 1;
u32 tp = space - space/4;
/* On receive queue's set the thresholds
@@ -1082,19 +1084,16 @@ static int sky2_up(struct net_device *de
sky2_mac_init(hw, port);
- /* Determine available ram buffer space (in 4K blocks).
- * Note: not sure about the FE setting below yet
- */
- if (hw->chip_id == CHIP_ID_YUKON_FE)
- ramsize = 4;
+ /* Determine available ram buffer space in qwords. */
+ ramsize = sky2_read8(hw, B2_E_0) * 4096/8;
+
+ if (ramsize > 6*1024/8)
+ rxspace = ramsize - (ramsize + 2) / 3;
else
- ramsize = sky2_read8(hw, B2_E_0);
-
- /* Give transmitter one third (rounded up) */
- rxspace = ramsize - (ramsize + 2) / 3;
-
- sky2_ramset(hw, rxqaddr[port], 0, rxspace);
- sky2_ramset(hw, txqaddr[port], rxspace, ramsize);
+ rxspace = ramsize / 2;
+
+ sky2_ramset(hw, rxqaddr[port], 0, rxspace-1);
+ sky2_ramset(hw, txqaddr[port], rxspace, ramsize-1);
/* Make sure SyncQ is disabled */
sky2_write8(hw, RB_ADDR(port == 0 ? Q_XS1 : Q_XS2, RB_CTRL),
@@ -1421,6 +1420,11 @@ static int sky2_down(struct net_device *
/* Stop more packets from being queued */
netif_stop_queue(dev);
+ /* Disable port IRQ */
+ imask = sky2_read32(hw, B0_IMSK);
+ imask &= ~portirq_msk[port];
+ sky2_write32(hw, B0_IMSK, imask);
+
sky2_phy_reset(hw, port);
/* Stop transmitter */
@@ -1463,11 +1467,6 @@ static int sky2_down(struct net_device *
sky2_write8(hw, SK_REG(port, RX_GMF_CTRL_T), GMF_RST_SET);
sky2_write8(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_RST_SET);
-
- /* Disable port IRQ */
- imask = sky2_read32(hw, B0_IMSK);
- imask &= ~portirq_msk[port];
- sky2_write32(hw, B0_IMSK, imask);
/* turn off LED's */
sky2_write16(hw, B0_Y2LED, LED_STAT_OFF);
@@ -1679,12 +1678,12 @@ static void sky2_phy_intr(struct sky2_hw
struct sky2_port *sky2 = netdev_priv(dev);
u16 istatus, phystat;
+ if (!netif_running(dev))
+ return;
+
spin_lock(&sky2->phy_lock);
istatus = gm_phy_read(hw, port, PHY_MARV_INT_STAT);
phystat = gm_phy_read(hw, port, PHY_MARV_PHY_STAT);
-
- if (!netif_running(dev))
- goto out;
if (netif_msg_intr(sky2))
printk(KERN_INFO PFX "%s: phy interrupt status 0x%x 0x%x\n",
@@ -2737,6 +2736,14 @@ static int sky2_set_mac_address(struct n
return 0;
}
+static void inline sky2_add_filter(u8 filter[8], const u8 *addr)
+{
+ u32 bit;
+
+ bit = ether_crc(ETH_ALEN, addr) & 63;
+ filter[bit >> 3] |= 1 << (bit & 7);
+}
+
static void sky2_set_multicast(struct net_device *dev)
{
struct sky2_port *sky2 = netdev_priv(dev);
@@ -2745,6 +2752,7 @@ static void sky2_set_multicast(struct ne
struct dev_mc_list *list = dev->mc_list;
u16 reg;
u8 filter[8];
+ static const u8 pause_mc_addr[ETH_ALEN] = { 0x1, 0x80, 0xc2, 0x0, 0x0,
0x1 };
memset(filter, 0, sizeof(filter));
@@ -2755,16 +2763,17 @@ static void sky2_set_multicast(struct ne
reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
else if ((dev->flags & IFF_ALLMULTI) || dev->mc_count > 16) /* all
multicast */
memset(filter, 0xff, sizeof(filter));
- else if (dev->mc_count == 0) /* no multicast */
+ else if (dev->mc_count == 0 && !sky2->rx_pause)
reg &= ~GM_RXCR_MCF_ENA;
else {
int i;
reg |= GM_RXCR_MCF_ENA;
- for (i = 0; list && i < dev->mc_count; i++, list = list->next) {
- u32 bit = ether_crc(ETH_ALEN, list->dmi_addr) & 0x3f;
- filter[bit / 8] |= 1 << (bit % 8);
- }
+ if (sky2->rx_pause)
+ sky2_add_filter(filter, pause_mc_addr);
+
+ for (i = 0; list && i < dev->mc_count; i++, list = list->next)
+ sky2_add_filter(filter, list->dmi_addr);
}
gma_write16(hw, port, GM_MC_ADDR_H1,
@@ -3200,6 +3209,8 @@ static int __devinit sky2_test_msi(struc
struct pci_dev *pdev = hw->pdev;
int err;
+ init_waitqueue_head (&hw->msi_wait);
+
sky2_write32(hw, B0_IMSK, Y2_IS_IRQ_SW);
err = request_irq(pdev->irq, sky2_test_intr, IRQF_SHARED, DRV_NAME, hw);
@@ -3209,18 +3220,15 @@ static int __devinit sky2_test_msi(struc
return err;
}
- init_waitqueue_head (&hw->msi_wait);
-
sky2_write8(hw, B0_CTST, CS_ST_SW_IRQ);
- wmb();
+ sky2_read8(hw, B0_CTST);
wait_event_timeout(hw->msi_wait, hw->msi_detected, HZ/10);
if (!hw->msi_detected) {
/* MSI test failed, go back to INTx mode */
- printk(KERN_WARNING PFX "%s: No interrupt was generated using
MSI, "
- "switching to INTx mode. Please report this failure to "
- "the PCI maintainer and include system chipset
information.\n",
+ printk(KERN_INFO PFX "%s: No interrupt generated using MSI, "
+ "switching to INTx mode.\n",
pci_name(pdev));
err = -EOPNOTSUPP;
@@ -3228,6 +3236,7 @@ static int __devinit sky2_test_msi(struc
}
sky2_write32(hw, B0_IMSK, 0);
+ sky2_read32(hw, B0_IMSK);
free_irq(pdev->irq, hw);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/sky2.h
--- a/drivers/net/sky2.h Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/sky2.h Wed Oct 03 10:00:44 2007 +0100
@@ -1566,7 +1566,7 @@ enum {
GMR_FS_ANY_ERR = GMR_FS_RX_FF_OV | GMR_FS_CRC_ERR |
GMR_FS_FRAGMENT | GMR_FS_LONG_ERR |
- GMR_FS_MII_ERR | GMR_FS_BAD_FC | GMR_FS_GOOD_FC |
+ GMR_FS_MII_ERR | GMR_FS_GOOD_FC | GMR_FS_BAD_FC |
GMR_FS_UN_SIZE | GMR_FS_JABBER,
};
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/sunhme.c
--- a/drivers/net/sunhme.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/sunhme.c Wed Oct 03 10:00:44 2007 +0100
@@ -3012,6 +3012,11 @@ static int __devinit happy_meal_pci_prob
#endif
err = -ENODEV;
+
+ if (pci_enable_device(pdev))
+ goto err_out;
+ pci_set_master(pdev);
+
if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
qp = quattro_pci_find(pdev);
if (qp == NULL)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/tg3.c
--- a/drivers/net/tg3.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/tg3.c Wed Oct 03 10:00:44 2007 +0100
@@ -6889,8 +6889,10 @@ static int tg3_open(struct net_device *d
tg3_full_lock(tp, 0);
err = tg3_set_power_state(tp, PCI_D0);
- if (err)
+ if (err) {
+ tg3_full_unlock(tp);
return err;
+ }
tg3_disable_ints(tp);
tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx.h Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx.h Wed Oct 03 10:00:44 2007 +0100
@@ -21,7 +21,7 @@
#define PFX KBUILD_MODNAME ": "
#define BCM43xx_SWITCH_CORE_MAX_RETRIES 50
-#define BCM43xx_IRQWAIT_MAX_RETRIES 50
+#define BCM43xx_IRQWAIT_MAX_RETRIES 100
#define BCM43xx_IO_SIZE 8192
@@ -33,14 +33,18 @@
#define BCM43xx_PCICFG_ICR 0x94
/* MMIO offsets */
-#define BCM43xx_MMIO_DMA1_REASON 0x20
-#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x24
-#define BCM43xx_MMIO_DMA2_REASON 0x28
-#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x2C
-#define BCM43xx_MMIO_DMA3_REASON 0x30
-#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x34
-#define BCM43xx_MMIO_DMA4_REASON 0x38
-#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x3C
+#define BCM43xx_MMIO_DMA0_REASON 0x20
+#define BCM43xx_MMIO_DMA0_IRQ_MASK 0x24
+#define BCM43xx_MMIO_DMA1_REASON 0x28
+#define BCM43xx_MMIO_DMA1_IRQ_MASK 0x2C
+#define BCM43xx_MMIO_DMA2_REASON 0x30
+#define BCM43xx_MMIO_DMA2_IRQ_MASK 0x34
+#define BCM43xx_MMIO_DMA3_REASON 0x38
+#define BCM43xx_MMIO_DMA3_IRQ_MASK 0x3C
+#define BCM43xx_MMIO_DMA4_REASON 0x40
+#define BCM43xx_MMIO_DMA4_IRQ_MASK 0x44
+#define BCM43xx_MMIO_DMA5_REASON 0x48
+#define BCM43xx_MMIO_DMA5_IRQ_MASK 0x4C
#define BCM43xx_MMIO_STATUS_BITFIELD 0x120
#define BCM43xx_MMIO_STATUS2_BITFIELD 0x124
#define BCM43xx_MMIO_GEN_IRQ_REASON 0x128
@@ -56,14 +60,27 @@
#define BCM43xx_MMIO_XMITSTAT_1 0x174
#define BCM43xx_MMIO_REV3PLUS_TSF_LOW 0x180 /* core rev >= 3 only */
#define BCM43xx_MMIO_REV3PLUS_TSF_HIGH 0x184 /* core rev >= 3 only */
-#define BCM43xx_MMIO_DMA1_BASE 0x200
-#define BCM43xx_MMIO_DMA2_BASE 0x220
-#define BCM43xx_MMIO_DMA3_BASE 0x240
-#define BCM43xx_MMIO_DMA4_BASE 0x260
+
+/* 32-bit DMA */
+#define BCM43xx_MMIO_DMA32_BASE0 0x200
+#define BCM43xx_MMIO_DMA32_BASE1 0x220
+#define BCM43xx_MMIO_DMA32_BASE2 0x240
+#define BCM43xx_MMIO_DMA32_BASE3 0x260
+#define BCM43xx_MMIO_DMA32_BASE4 0x280
+#define BCM43xx_MMIO_DMA32_BASE5 0x2A0
+/* 64-bit DMA */
+#define BCM43xx_MMIO_DMA64_BASE0 0x200
+#define BCM43xx_MMIO_DMA64_BASE1 0x240
+#define BCM43xx_MMIO_DMA64_BASE2 0x280
+#define BCM43xx_MMIO_DMA64_BASE3 0x2C0
+#define BCM43xx_MMIO_DMA64_BASE4 0x300
+#define BCM43xx_MMIO_DMA64_BASE5 0x340
+/* PIO */
#define BCM43xx_MMIO_PIO1_BASE 0x300
#define BCM43xx_MMIO_PIO2_BASE 0x310
#define BCM43xx_MMIO_PIO3_BASE 0x320
#define BCM43xx_MMIO_PIO4_BASE 0x330
+
#define BCM43xx_MMIO_PHY_VER 0x3E0
#define BCM43xx_MMIO_PHY_RADIO 0x3E2
#define BCM43xx_MMIO_ANTENNA 0x3E8
@@ -233,8 +250,14 @@
#define BCM43xx_SBTMSTATELOW_FORCE_GATE_CLOCK 0x20000
/* sbtmstatehigh state flags */
-#define BCM43xx_SBTMSTATEHIGH_SERROR 0x1
-#define BCM43xx_SBTMSTATEHIGH_BUSY 0x4
+#define BCM43xx_SBTMSTATEHIGH_SERROR 0x00000001
+#define BCM43xx_SBTMSTATEHIGH_BUSY 0x00000004
+#define BCM43xx_SBTMSTATEHIGH_TIMEOUT 0x00000020
+#define BCM43xx_SBTMSTATEHIGH_COREFLAGS 0x1FFF0000
+#define BCM43xx_SBTMSTATEHIGH_DMA64BIT 0x10000000
+#define BCM43xx_SBTMSTATEHIGH_GATEDCLK 0x20000000
+#define BCM43xx_SBTMSTATEHIGH_BISTFAILED 0x40000000
+#define BCM43xx_SBTMSTATEHIGH_BISTCOMPLETE 0x80000000
/* sbimstate flags */
#define BCM43xx_SBIMSTATE_IB_ERROR 0x20000
@@ -282,6 +305,13 @@
#define BCM43xx_SBF_NO_SSID_BCAST 0x08000000
#define BCM43xx_SBF_TIME_UPDATE 0x10000000
#define BCM43xx_SBF_80000000 0x80000000 /*FIXME: fix name*/
+
+/* Microcode */
+#define BCM43xx_UCODE_REVISION 0x0000
+#define BCM43xx_UCODE_PATCHLEVEL 0x0002
+#define BCM43xx_UCODE_DATE 0x0004
+#define BCM43xx_UCODE_TIME 0x0006
+#define BCM43xx_UCODE_STATUS 0x0040
/* MicrocodeFlagsBitfield (addr + lo-word values?)*/
#define BCM43xx_UCODEFLAGS_OFFSET 0x005E
@@ -504,6 +534,12 @@ struct bcm43xx_phyinfo {
* This lock is only used by bcm43xx_phy_{un}lock()
*/
spinlock_t lock;
+
+ /* Firmware. */
+ const struct firmware *ucode;
+ const struct firmware *pcm;
+ const struct firmware *initvals0;
+ const struct firmware *initvals1;
};
@@ -568,8 +604,11 @@ struct bcm43xx_dma {
struct bcm43xx_dmaring *tx_ring1;
struct bcm43xx_dmaring *tx_ring2;
struct bcm43xx_dmaring *tx_ring3;
+ struct bcm43xx_dmaring *tx_ring4;
+ struct bcm43xx_dmaring *tx_ring5;
+
struct bcm43xx_dmaring *rx_ring0;
- struct bcm43xx_dmaring *rx_ring1; /* only available on core.rev < 5 */
+ struct bcm43xx_dmaring *rx_ring3; /* only available on core.rev < 5 */
};
/* Data structures for PIO transmission, per 80211 core. */
@@ -593,12 +632,14 @@ struct bcm43xx_coreinfo {
u8 available:1,
enabled:1,
initialized:1;
- /** core_id ID number */
- u16 id;
/** core_rev revision number */
u8 rev;
/** Index number for _switch_core() */
u8 index;
+ /** core_id ID number */
+ u16 id;
+ /** Core-specific data. */
+ void *priv;
};
/* Additional information for each 80211 core. */
@@ -647,7 +688,23 @@ enum {
BCM43xx_STAT_RESTARTING, /* controller_restart() called. */
};
#define bcm43xx_status(bcm) atomic_read(&(bcm)->init_status)
-#define bcm43xx_set_status(bcm, stat) atomic_set(&(bcm)->init_status, (stat))
+#define bcm43xx_set_status(bcm, stat) do { \
+ atomic_set(&(bcm)->init_status, (stat)); \
+ smp_wmb(); \
+ } while (0)
+
+/* *** THEORY OF LOCKING ***
+ *
+ * We have two different locks in the bcm43xx driver.
+ * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
+ * and the device registers. This mutex does _not_ protect
+ * against concurrency from the IRQ handler.
+ * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
+ *
+ * Please note that, if you only take the irq_lock, you are not protected
+ * against concurrency from the periodic work handlers.
+ * Most times you want to take _both_ locks.
+ */
struct bcm43xx_private {
struct ieee80211_device *ieee;
@@ -659,7 +716,6 @@ struct bcm43xx_private {
void __iomem *mmio_addr;
- /* Locking, see "theory of locking" text below. */
spinlock_t irq_lock;
struct mutex mutex;
@@ -691,6 +747,7 @@ struct bcm43xx_private {
struct bcm43xx_sprominfo sprom;
#define BCM43xx_NR_LEDS 4
struct bcm43xx_led leds[BCM43xx_NR_LEDS];
+ spinlock_t leds_lock;
/* The currently active core. */
struct bcm43xx_coreinfo *current_core;
@@ -708,10 +765,6 @@ struct bcm43xx_private {
struct bcm43xx_coreinfo core_80211[ BCM43xx_MAX_80211_CORES ];
/* Additional information, specific to the 80211 cores. */
struct bcm43xx_coreinfo_80211 core_80211_ext[ BCM43xx_MAX_80211_CORES ];
- /* Index of the current 80211 core. If current_core is not
- * an 80211 core, this is -1.
- */
- int current_80211_core_idx;
/* Number of available 80211 cores. */
int nr_80211_available;
@@ -719,11 +772,13 @@ struct bcm43xx_private {
/* Reason code of the last interrupt. */
u32 irq_reason;
- u32 dma_reason[4];
+ u32 dma_reason[6];
/* saved irq enable/disable state bitfield. */
u32 irq_savedstate;
/* Link Quality calculation context. */
struct bcm43xx_noise_calculation noisecalc;
+ /* if > 0 MAC is suspended. if == 0 MAC is enabled. */
+ int mac_suspended;
/* Threshold values. */
//TODO: The RTS thr has to be _used_. Currently, it is only set via WX.
@@ -746,12 +801,6 @@ struct bcm43xx_private {
struct bcm43xx_key key[54];
u8 default_key_idx;
- /* Firmware. */
- const struct firmware *ucode;
- const struct firmware *pcm;
- const struct firmware *initvals0;
- const struct firmware *initvals1;
-
/* Random Number Generator. */
struct hwrng rng;
char rng_name[20 + 1];
@@ -761,55 +810,6 @@ struct bcm43xx_private {
struct bcm43xx_dfsentry *dfsentry;
#endif
};
-
-
-/* *** THEORY OF LOCKING ***
- *
- * We have two different locks in the bcm43xx driver.
- * => bcm->mutex: General sleeping mutex. Protects struct bcm43xx_private
- * and the device registers.
- * => bcm->irq_lock: IRQ spinlock. Protects against IRQ handler concurrency.
- *
- * We have three types of helper function pairs to utilize these locks.
- * (Always use the helper functions.)
- * 1) bcm43xx_{un}lock_noirq():
- * Takes bcm->mutex. Does _not_ protect against IRQ concurrency,
- * so it is almost always unsafe, if device IRQs are enabled.
- * So only use this, if device IRQs are masked.
- * Locking may sleep.
- * You can sleep within the critical section.
- * 2) bcm43xx_{un}lock_irqonly():
- * Takes bcm->irq_lock. Does _not_ protect against
- * bcm43xx_lock_noirq() critical sections.
- * Does only protect against the IRQ handler path and other
- * irqonly() critical sections.
- * Locking does not sleep.
- * You must not sleep within the critical section.
- * 3) bcm43xx_{un}lock_irqsafe():
- * This is the cummulative lock and takes both, mutex and irq_lock.
- * Protects against noirq() and irqonly() critical sections (and
- * the IRQ handler path).
- * Locking may sleep.
- * You must not sleep within the critical section.
- */
-
-/* Lock type 1 */
-#define bcm43xx_lock_noirq(bcm) mutex_lock(&(bcm)->mutex)
-#define bcm43xx_unlock_noirq(bcm) mutex_unlock(&(bcm)->mutex)
-/* Lock type 2 */
-#define bcm43xx_lock_irqonly(bcm, flags) \
- spin_lock_irqsave(&(bcm)->irq_lock, flags)
-#define bcm43xx_unlock_irqonly(bcm, flags) \
- spin_unlock_irqrestore(&(bcm)->irq_lock, flags)
-/* Lock type 3 */
-#define bcm43xx_lock_irqsafe(bcm, flags) do { \
- bcm43xx_lock_noirq(bcm); \
- bcm43xx_lock_irqonly(bcm, flags); \
- } while (0)
-#define bcm43xx_unlock_irqsafe(bcm, flags) do { \
- bcm43xx_unlock_irqonly(bcm, flags); \
- bcm43xx_unlock_noirq(bcm); \
- } while (0)
static inline
@@ -863,34 +863,33 @@ int bcm43xx_using_pio(struct bcm43xx_pri
* any of these functions.
*/
static inline
+struct bcm43xx_coreinfo_80211 *
+bcm43xx_current_80211_priv(struct bcm43xx_private *bcm)
+{
+ assert(bcm->current_core->id == BCM43xx_COREID_80211);
+ return bcm->current_core->priv;
+}
+static inline
struct bcm43xx_pio * bcm43xx_current_pio(struct bcm43xx_private *bcm)
{
assert(bcm43xx_using_pio(bcm));
- assert(bcm->current_80211_core_idx >= 0);
- assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
- return &(bcm->core_80211_ext[bcm->current_80211_core_idx].pio);
+ return &(bcm43xx_current_80211_priv(bcm)->pio);
}
static inline
struct bcm43xx_dma * bcm43xx_current_dma(struct bcm43xx_private *bcm)
{
assert(!bcm43xx_using_pio(bcm));
- assert(bcm->current_80211_core_idx >= 0);
- assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
- return &(bcm->core_80211_ext[bcm->current_80211_core_idx].dma);
+ return &(bcm43xx_current_80211_priv(bcm)->dma);
}
static inline
struct bcm43xx_phyinfo * bcm43xx_current_phy(struct bcm43xx_private *bcm)
{
- assert(bcm->current_80211_core_idx >= 0);
- assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
- return &(bcm->core_80211_ext[bcm->current_80211_core_idx].phy);
+ return &(bcm43xx_current_80211_priv(bcm)->phy);
}
static inline
struct bcm43xx_radioinfo * bcm43xx_current_radio(struct bcm43xx_private *bcm)
{
- assert(bcm->current_80211_core_idx >= 0);
- assert(bcm->current_80211_core_idx < BCM43xx_MAX_80211_CORES);
- return &(bcm->core_80211_ext[bcm->current_80211_core_idx].radio);
+ return &(bcm43xx_current_80211_priv(bcm)->radio);
}
diff -r aafef975e518 -r 3e8752eb6d9c
drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c Wed Oct 03 10:00:44
2007 +0100
@@ -77,7 +77,8 @@ static ssize_t devinfo_read_file(struct
down(&big_buffer_sem);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
fappend("Board not initialized.\n");
goto out;
@@ -121,7 +122,8 @@ static ssize_t devinfo_read_file(struct
fappend("\n");
out:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
@@ -159,7 +161,8 @@ static ssize_t spromdump_read_file(struc
unsigned long flags;
down(&big_buffer_sem);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
fappend("Board not initialized.\n");
goto out;
@@ -169,7 +172,8 @@ static ssize_t spromdump_read_file(struc
fappend("boardflags: 0x%04x\n", bcm->sprom.boardflags);
out:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
@@ -188,7 +192,8 @@ static ssize_t tsf_read_file(struct file
u64 tsf;
down(&big_buffer_sem);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
fappend("Board not initialized.\n");
goto out;
@@ -199,7 +204,8 @@ static ssize_t tsf_read_file(struct file
(unsigned int)(tsf & 0xFFFFFFFFULL));
out:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
up(&big_buffer_sem);
return res;
@@ -221,7 +227,8 @@ static ssize_t tsf_write_file(struct fil
res = -EFAULT;
goto out_up;
}
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
res = -EFAULT;
@@ -237,7 +244,8 @@ static ssize_t tsf_write_file(struct fil
res = buf_size;
out_unlock:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
out_up:
up(&big_buffer_sem);
return res;
@@ -258,7 +266,8 @@ static ssize_t txstat_read_file(struct f
int i, cnt, j = 0;
down(&big_buffer_sem);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
fappend("Last %d logged xmitstatus blobs (Latest first):\n\n",
BCM43xx_NR_LOGGED_XMITSTATUS);
@@ -294,14 +303,51 @@ static ssize_t txstat_read_file(struct f
i = BCM43xx_NR_LOGGED_XMITSTATUS - 1;
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
res = simple_read_from_buffer(userbuf, count, ppos, buf, pos);
- bcm43xx_lock_irqsafe(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (*ppos == pos) {
/* Done. Drop the copied data. */
e->xmitstatus_printing = 0;
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
+ up(&big_buffer_sem);
+ return res;
+}
+
+static ssize_t restart_write_file(struct file *file, const char __user
*user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct bcm43xx_private *bcm = file->private_data;
+ char *buf = really_big_buffer;
+ ssize_t buf_size;
+ ssize_t res;
+ unsigned long flags;
+
+ buf_size = min(count, sizeof (really_big_buffer) - 1);
+ down(&big_buffer_sem);
+ if (copy_from_user(buf, user_buf, buf_size)) {
+ res = -EFAULT;
+ goto out_up;
+ }
+ mutex_lock(&(bcm)->mutex);
+ spin_lock_irqsave(&(bcm)->irq_lock, flags);
+ if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED) {
+ printk(KERN_INFO PFX "debugfs: Board not initialized.\n");
+ res = -EFAULT;
+ goto out_unlock;
+ }
+ if (count > 0 && buf[0] == '1') {
+ bcm43xx_controller_restart(bcm, "manually restarted");
+ res = count;
+ } else
+ res = -EINVAL;
+
+out_unlock:
+ spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
+ mutex_unlock(&(bcm)->mutex);
+out_up:
up(&big_buffer_sem);
return res;
}
@@ -336,6 +382,11 @@ static struct file_operations txstat_fop
static struct file_operations txstat_fops = {
.read = txstat_read_file,
.write = write_file_dummy,
+ .open = open_file_generic,
+};
+
+static struct file_operations restart_fops = {
+ .write = restart_write_file,
.open = open_file_generic,
};
@@ -390,6 +441,10 @@ void bcm43xx_debugfs_add_device(struct b
bcm, &txstat_fops);
if (!e->dentry_txstat)
printk(KERN_ERR PFX "debugfs: creating \"tx_status\" for \"%s\"
failed!\n", devdir);
+ e->dentry_restart = debugfs_create_file("restart", 0222, e->subdir,
+ bcm, &restart_fops);
+ if (!e->dentry_restart)
+ printk(KERN_ERR PFX "debugfs: creating \"restart\" for \"%s\"
failed!\n", devdir);
}
void bcm43xx_debugfs_remove_device(struct bcm43xx_private *bcm)
@@ -405,6 +460,7 @@ void bcm43xx_debugfs_remove_device(struc
debugfs_remove(e->dentry_devinfo);
debugfs_remove(e->dentry_tsf);
debugfs_remove(e->dentry_txstat);
+ debugfs_remove(e->dentry_restart);
debugfs_remove(e->subdir);
kfree(e->xmitstatus_buffer);
kfree(e->xmitstatus_print_buffer);
diff -r aafef975e518 -r 3e8752eb6d9c
drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.h Wed Oct 03 10:00:44
2007 +0100
@@ -20,6 +20,7 @@ struct bcm43xx_dfsentry {
struct dentry *dentry_spromdump;
struct dentry *dentry_tsf;
struct dentry *dentry_txstat;
+ struct dentry *dentry_restart;
struct bcm43xx_private *bcm;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_dma.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c Wed Oct 03 10:00:44
2007 +0100
@@ -4,7 +4,7 @@
DMA ringbuffer and descriptor allocation/management
- Copyright (c) 2005 Michael Buesch <mbuesch@xxxxxxxxxx>
+ Copyright (c) 2005, 2006 Michael Buesch <mbuesch@xxxxxxxxxx>
Some code in this file is derived from the b44.c driver
Copyright (C) 2002 David S. Miller
@@ -107,6 +107,35 @@ void return_slot(struct bcm43xx_dmaring
netif_wake_queue(ring->bcm->net_dev);
}
}
+}
+
+u16 bcm43xx_dmacontroller_base(int dma64bit, int controller_idx)
+{
+ static const u16 map64[] = {
+ BCM43xx_MMIO_DMA64_BASE0,
+ BCM43xx_MMIO_DMA64_BASE1,
+ BCM43xx_MMIO_DMA64_BASE2,
+ BCM43xx_MMIO_DMA64_BASE3,
+ BCM43xx_MMIO_DMA64_BASE4,
+ BCM43xx_MMIO_DMA64_BASE5,
+ };
+ static const u16 map32[] = {
+ BCM43xx_MMIO_DMA32_BASE0,
+ BCM43xx_MMIO_DMA32_BASE1,
+ BCM43xx_MMIO_DMA32_BASE2,
+ BCM43xx_MMIO_DMA32_BASE3,
+ BCM43xx_MMIO_DMA32_BASE4,
+ BCM43xx_MMIO_DMA32_BASE5,
+ };
+
+ if (dma64bit) {
+ assert(controller_idx >= 0 &&
+ controller_idx < ARRAY_SIZE(map64));
+ return map64[controller_idx];
+ }
+ assert(controller_idx >= 0 &&
+ controller_idx < ARRAY_SIZE(map32));
+ return map32[controller_idx];
}
static inline
@@ -172,7 +201,6 @@ void sync_descbuffer_for_device(struct b
/* Unmap and free a descriptor buffer. */
static inline
void free_descriptor_buffer(struct bcm43xx_dmaring *ring,
- struct bcm43xx_dmadesc *desc,
struct bcm43xx_dmadesc_meta *meta,
int irq_context)
{
@@ -188,23 +216,13 @@ static int alloc_ringmemory(struct bcm43
{
struct device *dev = &(ring->bcm->pci_dev->dev);
- ring->vbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
- &(ring->dmabase), GFP_KERNEL);
- if (!ring->vbase) {
+ ring->descbase = dma_alloc_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
+ &(ring->dmabase), GFP_KERNEL);
+ if (!ring->descbase) {
printk(KERN_ERR PFX "DMA ringmemory allocation failed\n");
return -ENOMEM;
}
- if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) {
- printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G "
- "(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;
- }
- assert(!(ring->dmabase & 0x000003FF));
- memset(ring->vbase, 0, BCM43xx_DMA_RINGMEMSIZE);
+ memset(ring->descbase, 0, BCM43xx_DMA_RINGMEMSIZE);
return 0;
}
@@ -214,26 +232,34 @@ static void free_ringmemory(struct bcm43
struct device *dev = &(ring->bcm->pci_dev->dev);
dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE,
- ring->vbase, ring->dmabase);
+ ring->descbase, ring->dmabase);
}
/* Reset the RX DMA channel */
int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
- u16 mmio_base)
+ u16 mmio_base, int dma64)
{
int i;
u32 value;
-
- bcm43xx_write32(bcm,
- mmio_base + BCM43xx_DMA_RX_CONTROL,
- 0x00000000);
+ u16 offset;
+
+ offset = dma64 ? BCM43xx_DMA64_RXCTL : BCM43xx_DMA32_RXCTL;
+ bcm43xx_write32(bcm, mmio_base + offset, 0);
for (i = 0; i < 1000; i++) {
- value = bcm43xx_read32(bcm,
- mmio_base + BCM43xx_DMA_RX_STATUS);
- value &= BCM43xx_DMA_RXSTAT_STAT_MASK;
- if (value == BCM43xx_DMA_RXSTAT_STAT_DISABLED) {
- i = -1;
- break;
+ offset = dma64 ? BCM43xx_DMA64_RXSTATUS :
BCM43xx_DMA32_RXSTATUS;
+ value = bcm43xx_read32(bcm, mmio_base + offset);
+ if (dma64) {
+ value &= BCM43xx_DMA64_RXSTAT;
+ if (value == BCM43xx_DMA64_RXSTAT_DISABLED) {
+ i = -1;
+ break;
+ }
+ } else {
+ value &= BCM43xx_DMA32_RXSTATE;
+ if (value == BCM43xx_DMA32_RXSTAT_DISABLED) {
+ i = -1;
+ break;
+ }
}
udelay(10);
}
@@ -247,31 +273,47 @@ int bcm43xx_dmacontroller_rx_reset(struc
/* Reset the RX DMA channel */
int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
- u16 mmio_base)
+ u16 mmio_base, int dma64)
{
int i;
u32 value;
+ u16 offset;
for (i = 0; i < 1000; i++) {
- value = bcm43xx_read32(bcm,
- mmio_base + BCM43xx_DMA_TX_STATUS);
- value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
- if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED ||
- value == BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT ||
- value == BCM43xx_DMA_TXSTAT_STAT_STOPPED)
- break;
+ offset = dma64 ? BCM43xx_DMA64_TXSTATUS :
BCM43xx_DMA32_TXSTATUS;
+ value = bcm43xx_read32(bcm, mmio_base + offset);
+ if (dma64) {
+ value &= BCM43xx_DMA64_TXSTAT;
+ if (value == BCM43xx_DMA64_TXSTAT_DISABLED ||
+ value == BCM43xx_DMA64_TXSTAT_IDLEWAIT ||
+ value == BCM43xx_DMA64_TXSTAT_STOPPED)
+ break;
+ } else {
+ value &= BCM43xx_DMA32_TXSTATE;
+ if (value == BCM43xx_DMA32_TXSTAT_DISABLED ||
+ value == BCM43xx_DMA32_TXSTAT_IDLEWAIT ||
+ value == BCM43xx_DMA32_TXSTAT_STOPPED)
+ break;
+ }
udelay(10);
}
- bcm43xx_write32(bcm,
- mmio_base + BCM43xx_DMA_TX_CONTROL,
- 0x00000000);
+ offset = dma64 ? BCM43xx_DMA64_TXCTL : BCM43xx_DMA32_TXCTL;
+ bcm43xx_write32(bcm, mmio_base + offset, 0);
for (i = 0; i < 1000; i++) {
- value = bcm43xx_read32(bcm,
- mmio_base + BCM43xx_DMA_TX_STATUS);
- value &= BCM43xx_DMA_TXSTAT_STAT_MASK;
- if (value == BCM43xx_DMA_TXSTAT_STAT_DISABLED) {
- i = -1;
- break;
+ offset = dma64 ? BCM43xx_DMA64_TXSTATUS :
BCM43xx_DMA32_TXSTATUS;
+ value = bcm43xx_read32(bcm, mmio_base + offset);
+ if (dma64) {
+ value &= BCM43xx_DMA64_TXSTAT;
+ if (value == BCM43xx_DMA64_TXSTAT_DISABLED) {
+ i = -1;
+ break;
+ }
+ } else {
+ value &= BCM43xx_DMA32_TXSTATE;
+ if (value == BCM43xx_DMA32_TXSTAT_DISABLED) {
+ i = -1;
+ break;
+ }
}
udelay(10);
}
@@ -285,47 +327,98 @@ int bcm43xx_dmacontroller_tx_reset(struc
return 0;
}
+static void fill_descriptor(struct bcm43xx_dmaring *ring,
+ struct bcm43xx_dmadesc_generic *desc,
+ dma_addr_t dmaaddr,
+ u16 bufsize,
+ int start, int end, int irq)
+{
+ int slot;
+
+ slot = bcm43xx_dma_desc2idx(ring, desc);
+ assert(slot >= 0 && slot < ring->nr_slots);
+
+ if (ring->dma64) {
+ u32 ctl0 = 0, ctl1 = 0;
+ u32 addrlo, addrhi;
+ u32 addrext;
+
+ addrlo = (u32)(dmaaddr & 0xFFFFFFFF);
+ addrhi = (((u64)dmaaddr >> 32) & ~BCM43xx_DMA64_ROUTING);
+ addrext = (((u64)dmaaddr >> 32) >> BCM43xx_DMA64_ROUTING_SHIFT);
+ addrhi |= ring->routing;
+ if (slot == ring->nr_slots - 1)
+ ctl0 |= BCM43xx_DMA64_DCTL0_DTABLEEND;
+ if (start)
+ ctl0 |= BCM43xx_DMA64_DCTL0_FRAMESTART;
+ if (end)
+ ctl0 |= BCM43xx_DMA64_DCTL0_FRAMEEND;
+ if (irq)
+ ctl0 |= BCM43xx_DMA64_DCTL0_IRQ;
+ ctl1 |= (bufsize - ring->frameoffset)
+ & BCM43xx_DMA64_DCTL1_BYTECNT;
+ ctl1 |= (addrext << BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT)
+ & BCM43xx_DMA64_DCTL1_ADDREXT_MASK;
+
+ desc->dma64.control0 = cpu_to_le32(ctl0);
+ desc->dma64.control1 = cpu_to_le32(ctl1);
+ desc->dma64.address_low = cpu_to_le32(addrlo);
+ desc->dma64.address_high = cpu_to_le32(addrhi);
+ } else {
+ u32 ctl;
+ u32 addr;
+ u32 addrext;
+
+ addr = (u32)(dmaaddr & ~BCM43xx_DMA32_ROUTING);
+ addrext = (u32)(dmaaddr & BCM43xx_DMA32_ROUTING)
+ >> BCM43xx_DMA32_ROUTING_SHIFT;
+ addr |= ring->routing;
+ ctl = (bufsize - ring->frameoffset)
+ & BCM43xx_DMA32_DCTL_BYTECNT;
+ if (slot == ring->nr_slots - 1)
+ ctl |= BCM43xx_DMA32_DCTL_DTABLEEND;
+ if (start)
+ ctl |= BCM43xx_DMA32_DCTL_FRAMESTART;
+ if (end)
+ ctl |= BCM43xx_DMA32_DCTL_FRAMEEND;
+ if (irq)
+ ctl |= BCM43xx_DMA32_DCTL_IRQ;
+ ctl |= (addrext << BCM43xx_DMA32_DCTL_ADDREXT_SHIFT)
+ & BCM43xx_DMA32_DCTL_ADDREXT_MASK;
+
+ desc->dma32.control = cpu_to_le32(ctl);
+ desc->dma32.address = cpu_to_le32(addr);
+ }
+}
+
static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring,
- struct bcm43xx_dmadesc *desc,
+ struct bcm43xx_dmadesc_generic *desc,
struct bcm43xx_dmadesc_meta *meta,
gfp_t gfp_flags)
{
struct bcm43xx_rxhdr *rxhdr;
+ struct bcm43xx_hwxmitstatus *xmitstat;
dma_addr_t dmaaddr;
- u32 desc_addr;
- u32 desc_ctl;
- const int slot = (int)(desc - ring->vbase);
struct sk_buff *skb;
- assert(slot >= 0 && slot < ring->nr_slots);
assert(!ring->tx);
skb = __dev_alloc_skb(ring->rx_buffersize, gfp_flags);
if (unlikely(!skb))
return -ENOMEM;
dmaaddr = map_descbuffer(ring, skb->data, ring->rx_buffersize, 0);
- if (unlikely(dmaaddr + ring->rx_buffersize > BCM43xx_DMA_BUSADDRMAX)) {
- unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0);
- dev_kfree_skb_any(skb);
- printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G "
- "(0x%llx, len: %u)\n",
- (unsigned long long)dmaaddr, ring->rx_buffersize);
- return -ENOMEM;
- }
meta->skb = skb;
meta->dmaaddr = dmaaddr;
skb->dev = ring->bcm->net_dev;
- desc_addr = (u32)(dmaaddr + ring->memoffset);
- desc_ctl = (BCM43xx_DMADTOR_BYTECNT_MASK &
- (u32)(ring->rx_buffersize - ring->frameoffset));
- if (slot == ring->nr_slots - 1)
- desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
- set_desc_addr(desc, desc_addr);
- set_desc_ctl(desc, desc_ctl);
+
+ fill_descriptor(ring, desc, dmaaddr,
+ ring->rx_buffersize, 0, 0, 0);
rxhdr = (struct bcm43xx_rxhdr *)(skb->data);
rxhdr->frame_length = 0;
rxhdr->flags1 = 0;
+ xmitstat = (struct bcm43xx_hwxmitstatus *)(skb->data);
+ xmitstat->cookie = 0;
return 0;
}
@@ -336,17 +429,17 @@ static int alloc_initial_descbuffers(str
static int alloc_initial_descbuffers(struct bcm43xx_dmaring *ring)
{
int i, err = -ENOMEM;
- struct bcm43xx_dmadesc *desc;
+ struct bcm43xx_dmadesc_generic *desc;
struct bcm43xx_dmadesc_meta *meta;
for (i = 0; i < ring->nr_slots; i++) {
- desc = ring->vbase + i;
- meta = ring->meta + i;
+ desc = bcm43xx_dma_idx2desc(ring, i, &meta);
err = setup_rx_descbuffer(ring, desc, meta, GFP_KERNEL);
if (err)
goto err_unwind;
}
+ mb();
ring->used_slots = ring->nr_slots;
err = 0;
out:
@@ -354,8 +447,7 @@ out:
err_unwind:
for (i--; i >= 0; i--) {
- desc = ring->vbase + i;
- meta = ring->meta + i;
+ desc = bcm43xx_dma_idx2desc(ring, i, &meta);
unmap_descbuffer(ring, meta->dmaaddr, ring->rx_buffersize, 0);
dev_kfree_skb(meta->skb);
@@ -371,27 +463,67 @@ static int dmacontroller_setup(struct bc
{
int err = 0;
u32 value;
+ u32 addrext;
if (ring->tx) {
- /* Set Transmit Control register to "transmit enable" */
- bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
- BCM43xx_DMA_TXCTRL_ENABLE);
- /* Set Transmit Descriptor ring address. */
- bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING,
- ring->dmabase + ring->memoffset);
+ if (ring->dma64) {
+ u64 ringbase = (u64)(ring->dmabase);
+
+ addrext = ((ringbase >> 32) >>
BCM43xx_DMA64_ROUTING_SHIFT);
+ value = BCM43xx_DMA64_TXENABLE;
+ value |= (addrext << BCM43xx_DMA64_TXADDREXT_SHIFT)
+ & BCM43xx_DMA64_TXADDREXT_MASK;
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL, value);
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO,
+ (ringbase & 0xFFFFFFFF));
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI,
+ ((ringbase >> 32) &
~BCM43xx_DMA64_ROUTING)
+ | ring->routing);
+ } else {
+ u32 ringbase = (u32)(ring->dmabase);
+
+ addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
+ value = BCM43xx_DMA32_TXENABLE;
+ value |= (addrext << BCM43xx_DMA32_TXADDREXT_SHIFT)
+ & BCM43xx_DMA32_TXADDREXT_MASK;
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL, value);
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING,
+ (ringbase & ~BCM43xx_DMA32_ROUTING)
+ | ring->routing);
+ }
} else {
err = alloc_initial_descbuffers(ring);
if (err)
goto out;
- /* Set Receive Control "receive enable" and frame offset */
- value = (ring->frameoffset <<
BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT);
- value |= BCM43xx_DMA_RXCTRL_ENABLE;
- bcm43xx_dma_write(ring, BCM43xx_DMA_RX_CONTROL, value);
- /* Set Receive Descriptor ring address. */
- bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING,
- ring->dmabase + ring->memoffset);
- /* Init the descriptor pointer. */
- bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX, 200);
+ if (ring->dma64) {
+ u64 ringbase = (u64)(ring->dmabase);
+
+ addrext = ((ringbase >> 32) >>
BCM43xx_DMA64_ROUTING_SHIFT);
+ value = (ring->frameoffset <<
BCM43xx_DMA64_RXFROFF_SHIFT);
+ value |= BCM43xx_DMA64_RXENABLE;
+ value |= (addrext << BCM43xx_DMA64_RXADDREXT_SHIFT)
+ & BCM43xx_DMA64_RXADDREXT_MASK;
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_RXCTL, value);
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO,
+ (ringbase & 0xFFFFFFFF));
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI,
+ ((ringbase >> 32) &
~BCM43xx_DMA64_ROUTING)
+ | ring->routing);
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX, 200);
+ } else {
+ u32 ringbase = (u32)(ring->dmabase);
+
+ addrext = (ringbase >> BCM43xx_DMA32_ROUTING_SHIFT);
+ value = (ring->frameoffset <<
BCM43xx_DMA32_RXFROFF_SHIFT);
+ value |= BCM43xx_DMA32_RXENABLE;
+ value |= (addrext << BCM43xx_DMA32_RXADDREXT_SHIFT)
+ & BCM43xx_DMA32_RXADDREXT_MASK;
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_RXCTL, value);
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING,
+ (ringbase & ~BCM43xx_DMA32_ROUTING)
+ | ring->routing);
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX, 200);
+ }
}
out:
@@ -402,27 +534,32 @@ static void dmacontroller_cleanup(struct
static void dmacontroller_cleanup(struct bcm43xx_dmaring *ring)
{
if (ring->tx) {
- bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base);
- /* Zero out Transmit Descriptor ring address. */
- bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_RING, 0);
+ bcm43xx_dmacontroller_tx_reset(ring->bcm, ring->mmio_base,
ring->dma64);
+ if (ring->dma64) {
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGLO, 0);
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_TXRINGHI, 0);
+ } else
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_TXRING, 0);
} else {
- bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base);
- /* Zero out Receive Descriptor ring address. */
- bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_RING, 0);
+ bcm43xx_dmacontroller_rx_reset(ring->bcm, ring->mmio_base,
ring->dma64);
+ if (ring->dma64) {
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGLO, 0);
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_RXRINGHI, 0);
+ } else
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_RXRING, 0);
}
}
static void free_all_descbuffers(struct bcm43xx_dmaring *ring)
{
- struct bcm43xx_dmadesc *desc;
+ struct bcm43xx_dmadesc_generic *desc;
struct bcm43xx_dmadesc_meta *meta;
int i;
if (!ring->used_slots)
return;
for (i = 0; i < ring->nr_slots; i++) {
- desc = ring->vbase + i;
- meta = ring->meta + i;
+ desc = bcm43xx_dma_idx2desc(ring, i, &meta);
if (!meta->skb) {
assert(ring->tx);
@@ -430,62 +567,67 @@ static void free_all_descbuffers(struct
}
if (ring->tx) {
unmap_descbuffer(ring, meta->dmaaddr,
- meta->skb->len, 1);
+ meta->skb->len, 1);
} else {
unmap_descbuffer(ring, meta->dmaaddr,
- ring->rx_buffersize, 0);
- }
- free_descriptor_buffer(ring, desc, meta, 0);
+ ring->rx_buffersize, 0);
+ }
+ free_descriptor_buffer(ring, meta, 0);
}
}
/* Main initialization function. */
static
struct bcm43xx_dmaring * bcm43xx_setup_dmaring(struct bcm43xx_private *bcm,
- u16 dma_controller_base,
- int nr_descriptor_slots,
- int tx)
+ int controller_index,
+ int for_tx,
+ int dma64)
{
struct bcm43xx_dmaring *ring;
int err;
+ int nr_slots;
ring = kzalloc(sizeof(*ring), GFP_KERNEL);
if (!ring)
goto out;
- ring->meta = kzalloc(sizeof(*ring->meta) * nr_descriptor_slots,
+ nr_slots = BCM43xx_RXRING_SLOTS;
+ if (for_tx)
+ nr_slots = BCM43xx_TXRING_SLOTS;
+
+ ring->meta = kcalloc(nr_slots, sizeof(struct bcm43xx_dmadesc_meta),
GFP_KERNEL);
if (!ring->meta)
goto err_kfree_ring;
- ring->memoffset = BCM43xx_DMA_DMABUSADDROFFSET;
+ ring->routing = BCM43xx_DMA32_CLIENTTRANS;
+ if (dma64)
+ ring->routing = BCM43xx_DMA64_CLIENTTRANS;
#ifdef CONFIG_BCM947XX
if (bcm->pci_dev->bus->number == 0)
- ring->memoffset = 0;
+ ring->routing = dma64 ? BCM43xx_DMA64_NOTRANS :
BCM43xx_DMA32_NOTRANS;
#endif
ring->bcm = bcm;
- ring->nr_slots = nr_descriptor_slots;
+ ring->nr_slots = nr_slots;
ring->suspend_mark = ring->nr_slots * BCM43xx_TXSUSPEND_PERCENT / 100;
ring->resume_mark = ring->nr_slots * BCM43xx_TXRESUME_PERCENT / 100;
assert(ring->suspend_mark < ring->resume_mark);
- ring->mmio_base = dma_controller_base;
- if (tx) {
+ ring->mmio_base = bcm43xx_dmacontroller_base(dma64, controller_index);
+ ring->index = controller_index;
+ ring->dma64 = !!dma64;
+ if (for_tx) {
ring->tx = 1;
ring->current_slot = -1;
} else {
- switch (dma_controller_base) {
- case BCM43xx_MMIO_DMA1_BASE:
- ring->rx_buffersize = BCM43xx_DMA1_RXBUFFERSIZE;
- ring->frameoffset = BCM43xx_DMA1_RX_FRAMEOFFSET;
- break;
- case BCM43xx_MMIO_DMA4_BASE:
- ring->rx_buffersize = BCM43xx_DMA4_RXBUFFERSIZE;
- ring->frameoffset = BCM43xx_DMA4_RX_FRAMEOFFSET;
- break;
- default:
+ if (ring->index == 0) {
+ ring->rx_buffersize = BCM43xx_DMA0_RX_BUFFERSIZE;
+ ring->frameoffset = BCM43xx_DMA0_RX_FRAMEOFFSET;
+ } else if (ring->index == 3) {
+ ring->rx_buffersize = BCM43xx_DMA3_RX_BUFFERSIZE;
+ ring->frameoffset = BCM43xx_DMA3_RX_FRAMEOFFSET;
+ } else
assert(0);
- }
}
err = alloc_ringmemory(ring);
@@ -514,7 +656,8 @@ static void bcm43xx_destroy_dmaring(stru
if (!ring)
return;
- dprintk(KERN_INFO PFX "DMA 0x%04x (%s) max used slots: %d/%d\n",
+ dprintk(KERN_INFO PFX "DMA-%s 0x%04X (%s) max used slots: %d/%d\n",
+ (ring->dma64) ? "64" : "32",
ring->mmio_base,
(ring->tx) ? "TX" : "RX",
ring->max_used_slots, ring->nr_slots);
@@ -537,10 +680,15 @@ void bcm43xx_dma_free(struct bcm43xx_pri
return;
dma = bcm43xx_current_dma(bcm);
- bcm43xx_destroy_dmaring(dma->rx_ring1);
- dma->rx_ring1 = NULL;
+ bcm43xx_destroy_dmaring(dma->rx_ring3);
+ dma->rx_ring3 = NULL;
bcm43xx_destroy_dmaring(dma->rx_ring0);
dma->rx_ring0 = NULL;
+
+ bcm43xx_destroy_dmaring(dma->tx_ring5);
+ dma->tx_ring5 = NULL;
+ bcm43xx_destroy_dmaring(dma->tx_ring4);
+ dma->tx_ring4 = NULL;
bcm43xx_destroy_dmaring(dma->tx_ring3);
dma->tx_ring3 = NULL;
bcm43xx_destroy_dmaring(dma->tx_ring2);
@@ -556,48 +704,59 @@ int bcm43xx_dma_init(struct bcm43xx_priv
struct bcm43xx_dma *dma = bcm43xx_current_dma(bcm);
struct bcm43xx_dmaring *ring;
int err = -ENOMEM;
+ int dma64 = 0;
+ u32 sbtmstatehi;
+
+ sbtmstatehi = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATEHIGH);
+ if (sbtmstatehi & BCM43xx_SBTMSTATEHIGH_DMA64BIT)
+ dma64 = 1;
/* setup TX DMA channels. */
- ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
- BCM43xx_TXRING_SLOTS, 1);
+ ring = bcm43xx_setup_dmaring(bcm, 0, 1, dma64);
if (!ring)
goto out;
dma->tx_ring0 = ring;
- ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA2_BASE,
- BCM43xx_TXRING_SLOTS, 1);
+ ring = bcm43xx_setup_dmaring(bcm, 1, 1, dma64);
if (!ring)
goto err_destroy_tx0;
dma->tx_ring1 = ring;
- ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA3_BASE,
- BCM43xx_TXRING_SLOTS, 1);
+ ring = bcm43xx_setup_dmaring(bcm, 2, 1, dma64);
if (!ring)
goto err_destroy_tx1;
dma->tx_ring2 = ring;
- ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
- BCM43xx_TXRING_SLOTS, 1);
+ ring = bcm43xx_setup_dmaring(bcm, 3, 1, dma64);
if (!ring)
goto err_destroy_tx2;
dma->tx_ring3 = ring;
- /* setup RX DMA channels. */
- ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA1_BASE,
- BCM43xx_RXRING_SLOTS, 0);
+ ring = bcm43xx_setup_dmaring(bcm, 4, 1, dma64);
if (!ring)
goto err_destroy_tx3;
+ dma->tx_ring4 = ring;
+
+ ring = bcm43xx_setup_dmaring(bcm, 5, 1, dma64);
+ if (!ring)
+ goto err_destroy_tx4;
+ dma->tx_ring5 = ring;
+
+ /* setup RX DMA channels. */
+ ring = bcm43xx_setup_dmaring(bcm, 0, 0, dma64);
+ if (!ring)
+ goto err_destroy_tx5;
dma->rx_ring0 = ring;
if (bcm->current_core->rev < 5) {
- ring = bcm43xx_setup_dmaring(bcm, BCM43xx_MMIO_DMA4_BASE,
- BCM43xx_RXRING_SLOTS, 0);
+ ring = bcm43xx_setup_dmaring(bcm, 3, 0, dma64);
if (!ring)
goto err_destroy_rx0;
- dma->rx_ring1 = ring;
- }
-
- dprintk(KERN_INFO PFX "DMA initialized\n");
+ dma->rx_ring3 = ring;
+ }
+
+ dprintk(KERN_INFO PFX "%s DMA initialized\n",
+ dma64 ? "64-bit" : "32-bit");
err = 0;
out:
return err;
@@ -605,6 +764,12 @@ err_destroy_rx0:
err_destroy_rx0:
bcm43xx_destroy_dmaring(dma->rx_ring0);
dma->rx_ring0 = NULL;
+err_destroy_tx5:
+ bcm43xx_destroy_dmaring(dma->tx_ring5);
+ dma->tx_ring5 = NULL;
+err_destroy_tx4:
+ bcm43xx_destroy_dmaring(dma->tx_ring4);
+ dma->tx_ring4 = NULL;
err_destroy_tx3:
bcm43xx_destroy_dmaring(dma->tx_ring3);
dma->tx_ring3 = NULL;
@@ -624,7 +789,7 @@ static u16 generate_cookie(struct bcm43x
static u16 generate_cookie(struct bcm43xx_dmaring *ring,
int slot)
{
- u16 cookie = 0xF000;
+ u16 cookie = 0x1000;
/* Use the upper 4 bits of the cookie as
* DMA controller ID and store the slot number
@@ -632,20 +797,24 @@ static u16 generate_cookie(struct bcm43x
* Note that the cookie must never be 0, as this
* is a special value used in RX path.
*/
- switch (ring->mmio_base) {
- default:
- assert(0);
- case BCM43xx_MMIO_DMA1_BASE:
+ switch (ring->index) {
+ case 0:
cookie = 0xA000;
break;
- case BCM43xx_MMIO_DMA2_BASE:
+ case 1:
cookie = 0xB000;
break;
- case BCM43xx_MMIO_DMA3_BASE:
+ case 2:
cookie = 0xC000;
break;
- case BCM43xx_MMIO_DMA4_BASE:
+ case 3:
cookie = 0xD000;
+ break;
+ case 4:
+ cookie = 0xE000;
+ break;
+ case 5:
+ cookie = 0xF000;
break;
}
assert(((u16)slot & 0xF000) == 0x0000);
@@ -675,6 +844,12 @@ struct bcm43xx_dmaring * parse_cookie(st
case 0xD000:
ring = dma->tx_ring3;
break;
+ case 0xE000:
+ ring = dma->tx_ring4;
+ break;
+ case 0xF000:
+ ring = dma->tx_ring5;
+ break;
default:
assert(0);
}
@@ -687,6 +862,9 @@ static void dmacontroller_poke_tx(struct
static void dmacontroller_poke_tx(struct bcm43xx_dmaring *ring,
int slot)
{
+ u16 offset;
+ int descsize;
+
/* Everything is ready to start. Buffers are DMA mapped and
* associated with slots.
* "slot" is the last slot of the new frame we want to transmit.
@@ -694,25 +872,26 @@ static void dmacontroller_poke_tx(struct
*/
wmb();
slot = next_slot(ring, slot);
- bcm43xx_dma_write(ring, BCM43xx_DMA_TX_DESC_INDEX,
- (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
-}
-
-static int dma_tx_fragment(struct bcm43xx_dmaring *ring,
- struct sk_buff *skb,
- u8 cur_frag)
+ offset = (ring->dma64) ? BCM43xx_DMA64_TXINDEX : BCM43xx_DMA32_TXINDEX;
+ descsize = (ring->dma64) ? sizeof(struct bcm43xx_dmadesc64)
+ : sizeof(struct bcm43xx_dmadesc32);
+ bcm43xx_dma_write(ring, offset,
+ (u32)(slot * descsize));
+}
+
+static void dma_tx_fragment(struct bcm43xx_dmaring *ring,
+ struct sk_buff *skb,
+ u8 cur_frag)
{
int slot;
- struct bcm43xx_dmadesc *desc;
+ struct bcm43xx_dmadesc_generic *desc;
struct bcm43xx_dmadesc_meta *meta;
- u32 desc_ctl;
- u32 desc_addr;
+ dma_addr_t dmaaddr;
assert(skb_shinfo(skb)->nr_frags == 0);
slot = request_slot(ring);
- desc = ring->vbase + slot;
- meta = ring->meta + slot;
+ desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
/* Add a device specific TX header. */
assert(skb_headroom(skb) >= sizeof(struct bcm43xx_txhdr));
@@ -729,29 +908,14 @@ static int dma_tx_fragment(struct bcm43x
generate_cookie(ring, slot));
meta->skb = skb;
- meta->dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
- if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) {
- return_slot(ring, slot);
- printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G "
- "(0x%llx, len: %u)\n",
- (unsigned long long)meta->dmaaddr, skb->len);
- return -ENOMEM;
- }
-
- desc_addr = (u32)(meta->dmaaddr + ring->memoffset);
- desc_ctl = BCM43xx_DMADTOR_FRAMESTART | BCM43xx_DMADTOR_FRAMEEND;
- desc_ctl |= BCM43xx_DMADTOR_COMPIRQ;
- desc_ctl |= (BCM43xx_DMADTOR_BYTECNT_MASK &
- (u32)(meta->skb->len - ring->frameoffset));
- if (slot == ring->nr_slots - 1)
- desc_ctl |= BCM43xx_DMADTOR_DTABLEEND;
-
- set_desc_ctl(desc, desc_ctl);
- set_desc_addr(desc, desc_addr);
+ dmaaddr = map_descbuffer(ring, skb->data, skb->len, 1);
+ meta->dmaaddr = dmaaddr;
+
+ fill_descriptor(ring, desc, dmaaddr,
+ skb->len, 1, 1, 1);
+
/* Now transfer the whole frame. */
dmacontroller_poke_tx(ring, slot);
-
- return 0;
}
int bcm43xx_dma_tx(struct bcm43xx_private *bcm,
@@ -781,7 +945,6 @@ int bcm43xx_dma_tx(struct bcm43xx_privat
/* Take skb from ieee80211_txb_free */
txb->fragments[i] = NULL;
dma_tx_fragment(ring, skb, i);
- //TODO: handle failure of dma_tx_fragment
}
ieee80211_txb_free(txb);
@@ -792,23 +955,28 @@ void bcm43xx_dma_handle_xmitstatus(struc
struct bcm43xx_xmitstatus *status)
{
struct bcm43xx_dmaring *ring;
- struct bcm43xx_dmadesc *desc;
+ struct bcm43xx_dmadesc_generic *desc;
struct bcm43xx_dmadesc_meta *meta;
int is_last_fragment;
int slot;
+ u32 tmp;
ring = parse_cookie(bcm, status->cookie, &slot);
assert(ring);
assert(ring->tx);
- assert(get_desc_ctl(ring->vbase + slot) & BCM43xx_DMADTOR_FRAMESTART);
while (1) {
assert(slot >= 0 && slot < ring->nr_slots);
- desc = ring->vbase + slot;
- meta = ring->meta + slot;
-
- is_last_fragment = !!(get_desc_ctl(desc) &
BCM43xx_DMADTOR_FRAMEEND);
+ desc = bcm43xx_dma_idx2desc(ring, slot, &meta);
+
+ if (ring->dma64) {
+ tmp = le32_to_cpu(desc->dma64.control0);
+ is_last_fragment = !!(tmp &
BCM43xx_DMA64_DCTL0_FRAMEEND);
+ } else {
+ tmp = le32_to_cpu(desc->dma32.control);
+ is_last_fragment = !!(tmp &
BCM43xx_DMA32_DCTL_FRAMEEND);
+ }
unmap_descbuffer(ring, meta->dmaaddr, meta->skb->len, 1);
- free_descriptor_buffer(ring, desc, meta, 1);
+ free_descriptor_buffer(ring, meta, 1);
/* Everything belonging to the slot is unmapped
* and freed, so we can return it.
*/
@@ -824,7 +992,7 @@ static void dma_rx(struct bcm43xx_dmarin
static void dma_rx(struct bcm43xx_dmaring *ring,
int *slot)
{
- struct bcm43xx_dmadesc *desc;
+ struct bcm43xx_dmadesc_generic *desc;
struct bcm43xx_dmadesc_meta *meta;
struct bcm43xx_rxhdr *rxhdr;
struct sk_buff *skb;
@@ -832,13 +1000,12 @@ static void dma_rx(struct bcm43xx_dmarin
int err;
dma_addr_t dmaaddr;
- desc = ring->vbase + *slot;
- meta = ring->meta + *slot;
+ desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
sync_descbuffer_for_cpu(ring, meta->dmaaddr, ring->rx_buffersize);
skb = meta->skb;
- if (ring->mmio_base == BCM43xx_MMIO_DMA4_BASE) {
+ if (ring->index == 3) {
/* We received an xmit status. */
struct bcm43xx_hwxmitstatus *hw = (struct bcm43xx_hwxmitstatus
*)skb->data;
struct bcm43xx_xmitstatus stat;
@@ -894,8 +1061,7 @@ static void dma_rx(struct bcm43xx_dmarin
s32 tmp = len;
while (1) {
- desc = ring->vbase + *slot;
- meta = ring->meta + *slot;
+ desc = bcm43xx_dma_idx2desc(ring, *slot, &meta);
/* recycle the descriptor buffer. */
sync_descbuffer_for_device(ring, meta->dmaaddr,
ring->rx_buffersize);
@@ -906,8 +1072,8 @@ static void dma_rx(struct bcm43xx_dmarin
break;
}
printkl(KERN_ERR PFX "DMA RX buffer too small "
- "(len: %u, buffer: %u, nr-dropped: %d)\n",
- len, ring->rx_buffersize, cnt);
+ "(len: %u, buffer: %u, nr-dropped: %d)\n",
+ len, ring->rx_buffersize, cnt);
goto drop;
}
len -= IEEE80211_FCS_LEN;
@@ -945,9 +1111,15 @@ void bcm43xx_dma_rx(struct bcm43xx_dmari
#endif
assert(!ring->tx);
- status = bcm43xx_dma_read(ring, BCM43xx_DMA_RX_STATUS);
- descptr = (status & BCM43xx_DMA_RXSTAT_DPTR_MASK);
- current_slot = descptr / sizeof(struct bcm43xx_dmadesc);
+ if (ring->dma64) {
+ status = bcm43xx_dma_read(ring, BCM43xx_DMA64_RXSTATUS);
+ descptr = (status & BCM43xx_DMA64_RXSTATDPTR);
+ current_slot = descptr / sizeof(struct bcm43xx_dmadesc64);
+ } else {
+ status = bcm43xx_dma_read(ring, BCM43xx_DMA32_RXSTATUS);
+ descptr = (status & BCM43xx_DMA32_RXDPTR);
+ current_slot = descptr / sizeof(struct bcm43xx_dmadesc32);
+ }
assert(current_slot >= 0 && current_slot < ring->nr_slots);
slot = ring->current_slot;
@@ -958,8 +1130,13 @@ void bcm43xx_dma_rx(struct bcm43xx_dmari
ring->max_used_slots = used_slots;
#endif
}
- bcm43xx_dma_write(ring, BCM43xx_DMA_RX_DESC_INDEX,
- (u32)(slot * sizeof(struct bcm43xx_dmadesc)));
+ if (ring->dma64) {
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_RXINDEX,
+ (u32)(slot * sizeof(struct bcm43xx_dmadesc64)));
+ } else {
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_RXINDEX,
+ (u32)(slot * sizeof(struct bcm43xx_dmadesc32)));
+ }
ring->current_slot = slot;
}
@@ -967,16 +1144,28 @@ void bcm43xx_dma_tx_suspend(struct bcm43
{
assert(ring->tx);
bcm43xx_power_saving_ctl_bits(ring->bcm, -1, 1);
- bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
- bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
- | BCM43xx_DMA_TXCTRL_SUSPEND);
+ if (ring->dma64) {
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
+ bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
+ | BCM43xx_DMA64_TXSUSPEND);
+ } else {
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
+ bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
+ | BCM43xx_DMA32_TXSUSPEND);
+ }
}
void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring)
{
assert(ring->tx);
- bcm43xx_dma_write(ring, BCM43xx_DMA_TX_CONTROL,
- bcm43xx_dma_read(ring, BCM43xx_DMA_TX_CONTROL)
- & ~BCM43xx_DMA_TXCTRL_SUSPEND);
+ if (ring->dma64) {
+ bcm43xx_dma_write(ring, BCM43xx_DMA64_TXCTL,
+ bcm43xx_dma_read(ring, BCM43xx_DMA64_TXCTL)
+ & ~BCM43xx_DMA64_TXSUSPEND);
+ } else {
+ bcm43xx_dma_write(ring, BCM43xx_DMA32_TXCTL,
+ bcm43xx_dma_read(ring, BCM43xx_DMA32_TXCTL)
+ & ~BCM43xx_DMA32_TXSUSPEND);
+ }
bcm43xx_power_saving_ctl_bits(ring->bcm, -1, -1);
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_dma.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h Wed Oct 03 10:00:44
2007 +0100
@@ -14,63 +14,179 @@
#define BCM43xx_DMAIRQ_NONFATALMASK (1 << 13)
#define BCM43xx_DMAIRQ_RX_DONE (1 << 16)
-/* DMA controller register offsets. (relative to BCM43xx_DMA#_BASE) */
-#define BCM43xx_DMA_TX_CONTROL 0x00
-#define BCM43xx_DMA_TX_DESC_RING 0x04
-#define BCM43xx_DMA_TX_DESC_INDEX 0x08
-#define BCM43xx_DMA_TX_STATUS 0x0c
-#define BCM43xx_DMA_RX_CONTROL 0x10
-#define BCM43xx_DMA_RX_DESC_RING 0x14
-#define BCM43xx_DMA_RX_DESC_INDEX 0x18
-#define BCM43xx_DMA_RX_STATUS 0x1c
-
-/* DMA controller channel control word values. */
-#define BCM43xx_DMA_TXCTRL_ENABLE (1 << 0)
-#define BCM43xx_DMA_TXCTRL_SUSPEND (1 << 1)
-#define BCM43xx_DMA_TXCTRL_LOOPBACK (1 << 2)
-#define BCM43xx_DMA_TXCTRL_FLUSH (1 << 4)
-#define BCM43xx_DMA_RXCTRL_ENABLE (1 << 0)
-#define BCM43xx_DMA_RXCTRL_FRAMEOFF_MASK 0x000000fe
-#define BCM43xx_DMA_RXCTRL_FRAMEOFF_SHIFT 1
-#define BCM43xx_DMA_RXCTRL_PIO (1 << 8)
-/* DMA controller channel status word values. */
-#define BCM43xx_DMA_TXSTAT_DPTR_MASK 0x00000fff
-#define BCM43xx_DMA_TXSTAT_STAT_MASK 0x0000f000
-#define BCM43xx_DMA_TXSTAT_STAT_DISABLED 0x00000000
-#define BCM43xx_DMA_TXSTAT_STAT_ACTIVE 0x00001000
-#define BCM43xx_DMA_TXSTAT_STAT_IDLEWAIT 0x00002000
-#define BCM43xx_DMA_TXSTAT_STAT_STOPPED 0x00003000
-#define BCM43xx_DMA_TXSTAT_STAT_SUSP 0x00004000
-#define BCM43xx_DMA_TXSTAT_ERROR_MASK 0x000f0000
-#define BCM43xx_DMA_TXSTAT_FLUSHED (1 << 20)
-#define BCM43xx_DMA_RXSTAT_DPTR_MASK 0x00000fff
-#define BCM43xx_DMA_RXSTAT_STAT_MASK 0x0000f000
-#define BCM43xx_DMA_RXSTAT_STAT_DISABLED 0x00000000
-#define BCM43xx_DMA_RXSTAT_STAT_ACTIVE 0x00001000
-#define BCM43xx_DMA_RXSTAT_STAT_IDLEWAIT 0x00002000
-#define BCM43xx_DMA_RXSTAT_STAT_RESERVED 0x00003000
-#define BCM43xx_DMA_RXSTAT_STAT_ERRORS 0x00004000
-#define BCM43xx_DMA_RXSTAT_ERROR_MASK 0x000f0000
-
-/* DMA descriptor control field values. */
-#define BCM43xx_DMADTOR_BYTECNT_MASK 0x00001fff
-#define BCM43xx_DMADTOR_DTABLEEND (1 << 28) /* End of descriptor
table */
-#define BCM43xx_DMADTOR_COMPIRQ (1 << 29) /* IRQ on
completion request */
-#define BCM43xx_DMADTOR_FRAMEEND (1 << 30)
-#define BCM43xx_DMADTOR_FRAMESTART (1 << 31)
+
+/*** 32-bit DMA Engine. ***/
+
+/* 32-bit DMA controller registers. */
+#define BCM43xx_DMA32_TXCTL 0x00
+#define BCM43xx_DMA32_TXENABLE 0x00000001
+#define BCM43xx_DMA32_TXSUSPEND 0x00000002
+#define BCM43xx_DMA32_TXLOOPBACK 0x00000004
+#define BCM43xx_DMA32_TXFLUSH 0x00000010
+#define BCM43xx_DMA32_TXADDREXT_MASK 0x00030000
+#define BCM43xx_DMA32_TXADDREXT_SHIFT 16
+#define BCM43xx_DMA32_TXRING 0x04
+#define BCM43xx_DMA32_TXINDEX 0x08
+#define BCM43xx_DMA32_TXSTATUS 0x0C
+#define BCM43xx_DMA32_TXDPTR 0x00000FFF
+#define BCM43xx_DMA32_TXSTATE 0x0000F000
+#define BCM43xx_DMA32_TXSTAT_DISABLED 0x00000000
+#define BCM43xx_DMA32_TXSTAT_ACTIVE 0x00001000
+#define BCM43xx_DMA32_TXSTAT_IDLEWAIT 0x00002000
+#define BCM43xx_DMA32_TXSTAT_STOPPED 0x00003000
+#define BCM43xx_DMA32_TXSTAT_SUSP 0x00004000
+#define BCM43xx_DMA32_TXERROR 0x000F0000
+#define BCM43xx_DMA32_TXERR_NOERR 0x00000000
+#define BCM43xx_DMA32_TXERR_PROT 0x00010000
+#define BCM43xx_DMA32_TXERR_UNDERRUN 0x00020000
+#define BCM43xx_DMA32_TXERR_BUFREAD 0x00030000
+#define BCM43xx_DMA32_TXERR_DESCREAD 0x00040000
+#define BCM43xx_DMA32_TXACTIVE 0xFFF00000
+#define BCM43xx_DMA32_RXCTL 0x10
+#define BCM43xx_DMA32_RXENABLE 0x00000001
+#define BCM43xx_DMA32_RXFROFF_MASK 0x000000FE
+#define BCM43xx_DMA32_RXFROFF_SHIFT 1
+#define BCM43xx_DMA32_RXDIRECTFIFO 0x00000100
+#define BCM43xx_DMA32_RXADDREXT_MASK 0x00030000
+#define BCM43xx_DMA32_RXADDREXT_SHIFT 16
+#define BCM43xx_DMA32_RXRING 0x14
+#define BCM43xx_DMA32_RXINDEX 0x18
+#define BCM43xx_DMA32_RXSTATUS 0x1C
+#define BCM43xx_DMA32_RXDPTR 0x00000FFF
+#define BCM43xx_DMA32_RXSTATE 0x0000F000
+#define BCM43xx_DMA32_RXSTAT_DISABLED 0x00000000
+#define BCM43xx_DMA32_RXSTAT_ACTIVE 0x00001000
+#define BCM43xx_DMA32_RXSTAT_IDLEWAIT 0x00002000
+#define BCM43xx_DMA32_RXSTAT_STOPPED 0x00003000
+#define BCM43xx_DMA32_RXERROR 0x000F0000
+#define BCM43xx_DMA32_RXERR_NOERR 0x00000000
+#define BCM43xx_DMA32_RXERR_PROT 0x00010000
+#define BCM43xx_DMA32_RXERR_OVERFLOW 0x00020000
+#define BCM43xx_DMA32_RXERR_BUFWRITE 0x00030000
+#define BCM43xx_DMA32_RXERR_DESCREAD 0x00040000
+#define BCM43xx_DMA32_RXACTIVE 0xFFF00000
+
+/* 32-bit DMA descriptor. */
+struct bcm43xx_dmadesc32 {
+ __le32 control;
+ __le32 address;
+} __attribute__((__packed__));
+#define BCM43xx_DMA32_DCTL_BYTECNT 0x00001FFF
+#define BCM43xx_DMA32_DCTL_ADDREXT_MASK 0x00030000
+#define BCM43xx_DMA32_DCTL_ADDREXT_SHIFT 16
+#define BCM43xx_DMA32_DCTL_DTABLEEND 0x10000000
+#define BCM43xx_DMA32_DCTL_IRQ 0x20000000
+#define BCM43xx_DMA32_DCTL_FRAMEEND 0x40000000
+#define BCM43xx_DMA32_DCTL_FRAMESTART 0x80000000
+
+/* Address field Routing value. */
+#define BCM43xx_DMA32_ROUTING 0xC0000000
+#define BCM43xx_DMA32_ROUTING_SHIFT 30
+#define BCM43xx_DMA32_NOTRANS 0x00000000
+#define BCM43xx_DMA32_CLIENTTRANS 0x40000000
+
+
+
+/*** 64-bit DMA Engine. ***/
+
+/* 64-bit DMA controller registers. */
+#define BCM43xx_DMA64_TXCTL 0x00
+#define BCM43xx_DMA64_TXENABLE 0x00000001
+#define BCM43xx_DMA64_TXSUSPEND 0x00000002
+#define BCM43xx_DMA64_TXLOOPBACK 0x00000004
+#define BCM43xx_DMA64_TXFLUSH 0x00000010
+#define BCM43xx_DMA64_TXADDREXT_MASK 0x00030000
+#define BCM43xx_DMA64_TXADDREXT_SHIFT 16
+#define BCM43xx_DMA64_TXINDEX 0x04
+#define BCM43xx_DMA64_TXRINGLO 0x08
+#define BCM43xx_DMA64_TXRINGHI 0x0C
+#define BCM43xx_DMA64_TXSTATUS 0x10
+#define BCM43xx_DMA64_TXSTATDPTR 0x00001FFF
+#define BCM43xx_DMA64_TXSTAT 0xF0000000
+#define BCM43xx_DMA64_TXSTAT_DISABLED 0x00000000
+#define BCM43xx_DMA64_TXSTAT_ACTIVE 0x10000000
+#define BCM43xx_DMA64_TXSTAT_IDLEWAIT 0x20000000
+#define BCM43xx_DMA64_TXSTAT_STOPPED 0x30000000
+#define BCM43xx_DMA64_TXSTAT_SUSP 0x40000000
+#define BCM43xx_DMA64_TXERROR 0x14
+#define BCM43xx_DMA64_TXERRDPTR 0x0001FFFF
+#define BCM43xx_DMA64_TXERR 0xF0000000
+#define BCM43xx_DMA64_TXERR_NOERR 0x00000000
+#define BCM43xx_DMA64_TXERR_PROT 0x10000000
+#define BCM43xx_DMA64_TXERR_UNDERRUN 0x20000000
+#define BCM43xx_DMA64_TXERR_TRANSFER 0x30000000
+#define BCM43xx_DMA64_TXERR_DESCREAD 0x40000000
+#define BCM43xx_DMA64_TXERR_CORE 0x50000000
+#define BCM43xx_DMA64_RXCTL 0x20
+#define BCM43xx_DMA64_RXENABLE 0x00000001
+#define BCM43xx_DMA64_RXFROFF_MASK 0x000000FE
+#define BCM43xx_DMA64_RXFROFF_SHIFT 1
+#define BCM43xx_DMA64_RXDIRECTFIFO 0x00000100
+#define BCM43xx_DMA64_RXADDREXT_MASK 0x00030000
+#define BCM43xx_DMA64_RXADDREXT_SHIFT 16
+#define BCM43xx_DMA64_RXINDEX 0x24
+#define BCM43xx_DMA64_RXRINGLO 0x28
+#define BCM43xx_DMA64_RXRINGHI 0x2C
+#define BCM43xx_DMA64_RXSTATUS 0x30
+#define BCM43xx_DMA64_RXSTATDPTR 0x00001FFF
+#define BCM43xx_DMA64_RXSTAT 0xF0000000
+#define BCM43xx_DMA64_RXSTAT_DISABLED 0x00000000
+#define BCM43xx_DMA64_RXSTAT_ACTIVE 0x10000000
+#define BCM43xx_DMA64_RXSTAT_IDLEWAIT 0x20000000
+#define BCM43xx_DMA64_RXSTAT_STOPPED 0x30000000
+#define BCM43xx_DMA64_RXSTAT_SUSP 0x40000000
+#define BCM43xx_DMA64_RXERROR 0x34
+#define BCM43xx_DMA64_RXERRDPTR 0x0001FFFF
+#define BCM43xx_DMA64_RXERR 0xF0000000
+#define BCM43xx_DMA64_RXERR_NOERR 0x00000000
+#define BCM43xx_DMA64_RXERR_PROT 0x10000000
+#define BCM43xx_DMA64_RXERR_UNDERRUN 0x20000000
+#define BCM43xx_DMA64_RXERR_TRANSFER 0x30000000
+#define BCM43xx_DMA64_RXERR_DESCREAD 0x40000000
+#define BCM43xx_DMA64_RXERR_CORE 0x50000000
+
+/* 64-bit DMA descriptor. */
+struct bcm43xx_dmadesc64 {
+ __le32 control0;
+ __le32 control1;
+ __le32 address_low;
+ __le32 address_high;
+} __attribute__((__packed__));
+#define BCM43xx_DMA64_DCTL0_DTABLEEND 0x10000000
+#define BCM43xx_DMA64_DCTL0_IRQ 0x20000000
+#define BCM43xx_DMA64_DCTL0_FRAMEEND 0x40000000
+#define BCM43xx_DMA64_DCTL0_FRAMESTART 0x80000000
+#define BCM43xx_DMA64_DCTL1_BYTECNT 0x00001FFF
+#define BCM43xx_DMA64_DCTL1_ADDREXT_MASK 0x00030000
+#define BCM43xx_DMA64_DCTL1_ADDREXT_SHIFT 16
+
+/* Address field Routing value. */
+#define BCM43xx_DMA64_ROUTING 0xC0000000
+#define BCM43xx_DMA64_ROUTING_SHIFT 30
+#define BCM43xx_DMA64_NOTRANS 0x00000000
+#define BCM43xx_DMA64_CLIENTTRANS 0x80000000
+
+
+
+struct bcm43xx_dmadesc_generic {
+ union {
+ struct bcm43xx_dmadesc32 dma32;
+ struct bcm43xx_dmadesc64 dma64;
+ } __attribute__((__packed__));
+} __attribute__((__packed__));
+
/* Misc DMA constants */
#define BCM43xx_DMA_RINGMEMSIZE PAGE_SIZE
-#define BCM43xx_DMA_BUSADDRMAX 0x3FFFFFFF
-#define BCM43xx_DMA_DMABUSADDROFFSET (1 << 30)
-#define BCM43xx_DMA1_RX_FRAMEOFFSET 30
-#define BCM43xx_DMA4_RX_FRAMEOFFSET 0
+#define BCM43xx_DMA0_RX_FRAMEOFFSET 30
+#define BCM43xx_DMA3_RX_FRAMEOFFSET 0
+
/* DMA engine tuning knobs */
#define BCM43xx_TXRING_SLOTS 512
#define BCM43xx_RXRING_SLOTS 64
-#define BCM43xx_DMA1_RXBUFFERSIZE (2304 + 100)
-#define BCM43xx_DMA4_RXBUFFERSIZE 16
+#define BCM43xx_DMA0_RX_BUFFERSIZE (2304 + 100)
+#define BCM43xx_DMA3_RX_BUFFERSIZE 16
/* Suspend the tx queue, if less than this percent slots are free. */
#define BCM43xx_TXSUSPEND_PERCENT 20
/* Resume the tx queue, if more than this percent slots are free. */
@@ -85,17 +201,6 @@ struct bcm43xx_private;
struct bcm43xx_private;
struct bcm43xx_xmitstatus;
-
-struct bcm43xx_dmadesc {
- __le32 _control;
- __le32 _address;
-} __attribute__((__packed__));
-
-/* Macros to access the bcm43xx_dmadesc struct */
-#define get_desc_ctl(desc) le32_to_cpu((desc)->_control)
-#define set_desc_ctl(desc, ctl) do { (desc)->_control =
cpu_to_le32(ctl); } while (0)
-#define get_desc_addr(desc) le32_to_cpu((desc)->_address)
-#define set_desc_addr(desc, addr) do { (desc)->_address =
cpu_to_le32(addr); } while (0)
struct bcm43xx_dmadesc_meta {
/* The kernel DMA-able buffer. */
@@ -105,15 +210,14 @@ struct bcm43xx_dmadesc_meta {
};
struct bcm43xx_dmaring {
- struct bcm43xx_private *bcm;
/* Kernel virtual base address of the ring memory. */
- struct bcm43xx_dmadesc *vbase;
- /* DMA memory offset */
- dma_addr_t memoffset;
+ void *descbase;
+ /* Meta data about all descriptors. */
+ struct bcm43xx_dmadesc_meta *meta;
+ /* DMA Routing value. */
+ u32 routing;
/* (Unadjusted) DMA base bus-address of the ring memory. */
dma_addr_t dmabase;
- /* Meta data about all descriptors. */
- struct bcm43xx_dmadesc_meta *meta;
/* Number of descriptor slots in the ring. */
int nr_slots;
/* Number of used descriptor slots. */
@@ -127,12 +231,17 @@ struct bcm43xx_dmaring {
u32 frameoffset;
/* Descriptor buffer size. */
u16 rx_buffersize;
- /* The MMIO base register of the DMA controller, this
- * ring is posted to.
- */
+ /* The MMIO base register of the DMA controller. */
u16 mmio_base;
- u8 tx:1, /* TRUE, if this is a TX ring. */
- suspended:1; /* TRUE, if transfers are suspended on this ring. */
+ /* DMA controller index number (0-5). */
+ int index;
+ /* Boolean. Is this a TX ring? */
+ u8 tx;
+ /* Boolean. 64bit DMA if true, 32bit DMA otherwise. */
+ u8 dma64;
+ /* Boolean. Are transfers suspended on this ring? */
+ u8 suspended;
+ struct bcm43xx_private *bcm;
#ifdef CONFIG_BCM43XX_DEBUG
/* Maximum number of used slots. */
int max_used_slots;
@@ -141,6 +250,34 @@ struct bcm43xx_dmaring {
static inline
+int bcm43xx_dma_desc2idx(struct bcm43xx_dmaring *ring,
+ struct bcm43xx_dmadesc_generic *desc)
+{
+ if (ring->dma64) {
+ struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
+ return (int)(&(desc->dma64) - dd64);
+ } else {
+ struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
+ return (int)(&(desc->dma32) - dd32);
+ }
+}
+
+static inline
+struct bcm43xx_dmadesc_generic * bcm43xx_dma_idx2desc(struct bcm43xx_dmaring
*ring,
+ int slot,
+ struct
bcm43xx_dmadesc_meta **meta)
+{
+ *meta = &(ring->meta[slot]);
+ if (ring->dma64) {
+ struct bcm43xx_dmadesc64 *dd64 = ring->descbase;
+ return (struct bcm43xx_dmadesc_generic *)(&(dd64[slot]));
+ } else {
+ struct bcm43xx_dmadesc32 *dd32 = ring->descbase;
+ return (struct bcm43xx_dmadesc_generic *)(&(dd32[slot]));
+ }
+}
+
+static inline
u32 bcm43xx_dma_read(struct bcm43xx_dmaring *ring,
u16 offset)
{
@@ -159,9 +296,13 @@ void bcm43xx_dma_free(struct bcm43xx_pri
void bcm43xx_dma_free(struct bcm43xx_private *bcm);
int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
- u16 dmacontroller_mmio_base);
+ u16 dmacontroller_mmio_base,
+ int dma64);
int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
- u16 dmacontroller_mmio_base);
+ u16 dmacontroller_mmio_base,
+ int dma64);
+
+u16 bcm43xx_dmacontroller_base(int dma64bit, int dmacontroller_idx);
void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring);
void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring);
@@ -173,7 +314,6 @@ int bcm43xx_dma_tx(struct bcm43xx_privat
struct ieee80211_txb *txb);
void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring);
-
#else /* CONFIG_BCM43XX_DMA */
@@ -188,13 +328,15 @@ void bcm43xx_dma_free(struct bcm43xx_pri
}
static inline
int bcm43xx_dmacontroller_rx_reset(struct bcm43xx_private *bcm,
- u16 dmacontroller_mmio_base)
+ u16 dmacontroller_mmio_base,
+ int dma64)
{
return 0;
}
static inline
int bcm43xx_dmacontroller_tx_reset(struct bcm43xx_private *bcm,
- u16 dmacontroller_mmio_base)
+ u16 dmacontroller_mmio_base,
+ int dma64)
{
return 0;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_leds.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_leds.c Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_leds.c Wed Oct 03 10:00:44
2007 +0100
@@ -51,12 +51,12 @@ static void bcm43xx_led_blink(unsigned l
struct bcm43xx_private *bcm = led->bcm;
unsigned long flags;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->leds_lock, flags);
if (led->blink_interval) {
bcm43xx_led_changestate(led);
mod_timer(&led->blink_timer, jiffies + led->blink_interval);
}
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->leds_lock, flags);
}
static void bcm43xx_led_blink_start(struct bcm43xx_led *led,
@@ -177,7 +177,9 @@ void bcm43xx_leds_update(struct bcm43xx_
int i, turn_on;
unsigned long interval = 0;
u16 ledctl;
-
+ unsigned long flags;
+
+ spin_lock_irqsave(&bcm->leds_lock, flags);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
@@ -266,6 +268,7 @@ void bcm43xx_leds_update(struct bcm43xx_
ledctl &= ~(1 << i);
}
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
+ spin_unlock_irqrestore(&bcm->leds_lock, flags);
}
void bcm43xx_leds_switch_all(struct bcm43xx_private *bcm, int on)
@@ -274,7 +277,9 @@ void bcm43xx_leds_switch_all(struct bcm4
u16 ledctl;
int i;
int bit_on;
-
+ unsigned long flags;
+
+ spin_lock_irqsave(&bcm->leds_lock, flags);
ledctl = bcm43xx_read16(bcm, BCM43xx_MMIO_GPIO_CONTROL);
for (i = 0; i < BCM43xx_NR_LEDS; i++) {
led = &(bcm->leds[i]);
@@ -290,4 +295,5 @@ void bcm43xx_leds_switch_all(struct bcm4
ledctl &= ~(1 << i);
}
bcm43xx_write16(bcm, BCM43xx_MMIO_GPIO_CONTROL, ledctl);
-}
+ spin_unlock_irqrestore(&bcm->leds_lock, flags);
+}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_main.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c Wed Oct 03 10:00:44
2007 +0100
@@ -509,22 +509,19 @@ static void bcm43xx_synchronize_irq(stru
}
/* Make sure we don't receive more data from the device. */
-static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm, u32
*oldstate)
+static int bcm43xx_disable_interrupts_sync(struct bcm43xx_private *bcm)
{
unsigned long flags;
- u32 old;
-
- bcm43xx_lock_irqonly(bcm, flags);
+
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)) {
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
return -EBUSY;
}
- old = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_unlock_irqonly(bcm, flags);
+ bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
+ bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_MASK); /* flush */
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
bcm43xx_synchronize_irq(bcm);
-
- if (oldstate)
- *oldstate = old;
return 0;
}
@@ -537,7 +534,6 @@ static int bcm43xx_read_radioinfo(struct
u16 manufact;
u16 version;
u8 revision;
- s8 i;
if (bcm->chip_id == 0x4317) {
if (bcm->chip_rev == 0x00)
@@ -580,19 +576,10 @@ static int bcm43xx_read_radioinfo(struct
radio->version = version;
radio->revision = revision;
- /* Set default attenuation values. */
- radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
- radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
- radio->txctl1 = bcm43xx_default_txctl1(bcm);
- radio->txctl2 = 0xFFFF;
if (phy->type == BCM43xx_PHYTYPE_A)
radio->txpower_desired = bcm->sprom.maxpower_aphy;
else
radio->txpower_desired = bcm->sprom.maxpower_bgphy;
-
- /* Initialize the in-memory nrssi Lookup Table. */
- for (i = 0; i < 64; i++)
- radio->nrssi_lt[i] = i;
return 0;
@@ -1250,10 +1237,6 @@ int bcm43xx_switch_core(struct bcm43xx_p
goto out;
bcm->current_core = new_core;
- bcm->current_80211_core_idx = -1;
- if (new_core->id == BCM43xx_COREID_80211)
- bcm->current_80211_core_idx = (int)(new_core -
&(bcm->core_80211[0]));
-
out:
return err;
}
@@ -1389,6 +1372,7 @@ void bcm43xx_wireless_core_reset(struct
if ((bcm43xx_core_enabled(bcm)) &&
!bcm43xx_using_pio(bcm)) {
//FIXME: Do we _really_ want #ifndef CONFIG_BCM947XX here?
+#if 0
#ifndef CONFIG_BCM947XX
/* reset all used DMA controllers. */
bcm43xx_dmacontroller_tx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
@@ -1398,6 +1382,7 @@ void bcm43xx_wireless_core_reset(struct
bcm43xx_dmacontroller_rx_reset(bcm, BCM43xx_MMIO_DMA1_BASE);
if (bcm->current_core->rev < 5)
bcm43xx_dmacontroller_rx_reset(bcm,
BCM43xx_MMIO_DMA4_BASE);
+#endif
#endif
}
if (bcm43xx_status(bcm) == BCM43xx_STAT_SHUTTINGDOWN) {
@@ -1423,43 +1408,23 @@ static void bcm43xx_wireless_core_disabl
bcm43xx_core_disable(bcm, 0);
}
-/* Mark the current 80211 core inactive.
- * "active_80211_core" is the other 80211 core, which is used.
- */
-static int bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm,
- struct bcm43xx_coreinfo
*active_80211_core)
+/* Mark the current 80211 core inactive. */
+static void bcm43xx_wireless_core_mark_inactive(struct bcm43xx_private *bcm)
{
u32 sbtmstatelow;
- struct bcm43xx_coreinfo *old_core;
- int err = 0;
bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
bcm43xx_radio_turn_off(bcm);
sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- sbtmstatelow &= ~0x200a0000;
- sbtmstatelow |= 0xa0000;
+ sbtmstatelow &= 0xDFF5FFFF;
+ sbtmstatelow |= 0x000A0000;
bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
udelay(1);
sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- sbtmstatelow &= ~0xa0000;
- sbtmstatelow |= 0x80000;
+ sbtmstatelow &= 0xFFF5FFFF;
+ sbtmstatelow |= 0x00080000;
bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
udelay(1);
-
- if (bcm43xx_current_phy(bcm)->type == BCM43xx_PHYTYPE_G) {
- old_core = bcm->current_core;
- err = bcm43xx_switch_core(bcm, active_80211_core);
- if (err)
- goto out;
- sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
- sbtmstatelow &= ~0x20000000;
- sbtmstatelow |= 0x20000000;
- bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
- err = bcm43xx_switch_core(bcm, old_core);
- }
-
-out:
- return err;
}
static void handle_irq_transmit_status(struct bcm43xx_private *bcm)
@@ -1484,17 +1449,32 @@ static void handle_irq_transmit_status(s
bcm43xx_debugfs_log_txstat(bcm, &stat);
- if (stat.flags & BCM43xx_TXSTAT_FLAG_IGNORE)
+ if (stat.flags & BCM43xx_TXSTAT_FLAG_AMPDU)
continue;
- if (!(stat.flags & BCM43xx_TXSTAT_FLAG_ACK)) {
- //TODO: packet was not acked (was lost)
- }
- //TODO: There are more (unknown) flags to test. see
bcm43xx_main.h
+ if (stat.flags & BCM43xx_TXSTAT_FLAG_INTER)
+ continue;
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_handle_xmitstatus(bcm, &stat);
else
bcm43xx_dma_handle_xmitstatus(bcm, &stat);
+ }
+}
+
+static void drain_txstatus_queue(struct bcm43xx_private *bcm)
+{
+ u32 dummy;
+
+ if (bcm->current_core->rev < 5)
+ return;
+ /* Read all entries from the microcode TXstatus FIFO
+ * and throw them away.
+ */
+ while (1) {
+ dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_0);
+ if (!dummy)
+ break;
+ dummy = bcm43xx_read32(bcm, BCM43xx_MMIO_XMITSTAT_1);
}
}
@@ -1581,17 +1561,7 @@ static void handle_irq_noise(struct bcm4
else
average -= 48;
-/* FIXME: This is wrong, but people want fancy stats. well... */
-bcm->stats.noise = average;
- if (average > -65)
- bcm->stats.link_quality = 0;
- else if (average > -75)
- bcm->stats.link_quality = 1;
- else if (average > -85)
- bcm->stats.link_quality = 2;
- else
- bcm->stats.link_quality = 3;
-// dprintk(KERN_INFO PFX "Link Quality: %u (avg was %d)\n",
bcm->stats.link_quality, average);
+ bcm->stats.noise = average;
drop_calculation:
bcm->noisecalc.calculation_running = 0;
return;
@@ -1709,8 +1679,9 @@ static void bcm43xx_interrupt_tasklet(st
static void bcm43xx_interrupt_tasklet(struct bcm43xx_private *bcm)
{
u32 reason;
- u32 dma_reason[4];
- int activity = 0;
+ u32 dma_reason[6];
+ u32 merged_dma_reason = 0;
+ int i, activity = 0;
unsigned long flags;
#ifdef CONFIG_BCM43XX_DEBUG
@@ -1720,12 +1691,12 @@ static void bcm43xx_interrupt_tasklet(st
# define bcmirq_handled(irq) do { /* nothing */ } while (0)
#endif /* CONFIG_BCM43XX_DEBUG*/
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
reason = bcm->irq_reason;
- dma_reason[0] = bcm->dma_reason[0];
- dma_reason[1] = bcm->dma_reason[1];
- dma_reason[2] = bcm->dma_reason[2];
- dma_reason[3] = bcm->dma_reason[3];
+ for (i = 5; i >= 0; i--) {
+ dma_reason[i] = bcm->dma_reason[i];
+ merged_dma_reason |= dma_reason[i];
+ }
if (unlikely(reason & BCM43xx_IRQ_XMIT_ERROR)) {
/* TX error. We get this when Template Ram is written in wrong
endianess
@@ -1736,27 +1707,25 @@ static void bcm43xx_interrupt_tasklet(st
printkl(KERN_ERR PFX "FATAL ERROR: BCM43xx_IRQ_XMIT_ERROR\n");
bcmirq_handled(BCM43xx_IRQ_XMIT_ERROR);
}
- if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_FATALMASK) |
- (dma_reason[1] & BCM43xx_DMAIRQ_FATALMASK) |
- (dma_reason[2] & BCM43xx_DMAIRQ_FATALMASK) |
- (dma_reason[3] & BCM43xx_DMAIRQ_FATALMASK))) {
+ if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_FATALMASK)) {
printkl(KERN_ERR PFX "FATAL ERROR: Fatal DMA error: "
- "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
+ "0x%08X, 0x%08X, 0x%08X, "
+ "0x%08X, 0x%08X, 0x%08X\n",
dma_reason[0], dma_reason[1],
- dma_reason[2], dma_reason[3]);
+ dma_reason[2], dma_reason[3],
+ dma_reason[4], dma_reason[5]);
bcm43xx_controller_restart(bcm, "DMA error");
mmiowb();
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
return;
}
- if (unlikely((dma_reason[0] & BCM43xx_DMAIRQ_NONFATALMASK) |
- (dma_reason[1] & BCM43xx_DMAIRQ_NONFATALMASK) |
- (dma_reason[2] & BCM43xx_DMAIRQ_NONFATALMASK) |
- (dma_reason[3] & BCM43xx_DMAIRQ_NONFATALMASK))) {
+ if (unlikely(merged_dma_reason & BCM43xx_DMAIRQ_NONFATALMASK)) {
printkl(KERN_ERR PFX "DMA error: "
- "0x%08X, 0x%08X, 0x%08X, 0x%08X\n",
+ "0x%08X, 0x%08X, 0x%08X, "
+ "0x%08X, 0x%08X, 0x%08X\n",
dma_reason[0], dma_reason[1],
- dma_reason[2], dma_reason[3]);
+ dma_reason[2], dma_reason[3],
+ dma_reason[4], dma_reason[5]);
}
if (reason & BCM43xx_IRQ_PS) {
@@ -1791,8 +1760,6 @@ static void bcm43xx_interrupt_tasklet(st
}
/* Check the DMA reason registers for received data. */
- assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
- assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
if (dma_reason[0] & BCM43xx_DMAIRQ_RX_DONE) {
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue0);
@@ -1800,13 +1767,17 @@ static void bcm43xx_interrupt_tasklet(st
bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring0);
/* We intentionally don't set "activity" to 1, here. */
}
+ assert(!(dma_reason[1] & BCM43xx_DMAIRQ_RX_DONE));
+ assert(!(dma_reason[2] & BCM43xx_DMAIRQ_RX_DONE));
if (dma_reason[3] & BCM43xx_DMAIRQ_RX_DONE) {
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_rx(bcm43xx_current_pio(bcm)->queue3);
else
- bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring1);
+ bcm43xx_dma_rx(bcm43xx_current_dma(bcm)->rx_ring3);
activity = 1;
}
+ assert(!(dma_reason[4] & BCM43xx_DMAIRQ_RX_DONE));
+ assert(!(dma_reason[5] & BCM43xx_DMAIRQ_RX_DONE));
bcmirq_handled(BCM43xx_IRQ_RX);
if (reason & BCM43xx_IRQ_XMIT_STATUS) {
@@ -1834,7 +1805,7 @@ static void bcm43xx_interrupt_tasklet(st
bcm43xx_leds_update(bcm, activity);
bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
mmiowb();
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
}
static void pio_irq_workaround(struct bcm43xx_private *bcm,
@@ -1863,14 +1834,18 @@ static void bcm43xx_interrupt_ack(struct
bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, reason);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_REASON,
+ bcm->dma_reason[0]);
bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_REASON,
- bcm->dma_reason[0]);
+ bcm->dma_reason[1]);
bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_REASON,
- bcm->dma_reason[1]);
+ bcm->dma_reason[2]);
bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_REASON,
- bcm->dma_reason[2]);
+ bcm->dma_reason[3]);
bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_REASON,
- bcm->dma_reason[3]);
+ bcm->dma_reason[4]);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_REASON,
+ bcm->dma_reason[5]);
}
/* Interrupt handler top-half */
@@ -1885,14 +1860,8 @@ static irqreturn_t bcm43xx_interrupt_han
spin_lock(&bcm->irq_lock);
- /* Only accept IRQs, if we are initialized properly.
- * This avoids an RX race while initializing.
- * We should probably not enable IRQs before we are initialized
- * completely, but some careful work is needed to fix this. I think it
- * is best to stay with this cheap workaround for now... .
- */
- if (unlikely(bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED))
- goto out;
+ assert(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
+ assert(bcm->current_core->id == BCM43xx_COREID_80211);
reason = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
if (reason == 0xffffffff) {
@@ -1904,14 +1873,18 @@ static irqreturn_t bcm43xx_interrupt_han
if (!reason)
goto out;
- bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
- & 0x0001dc00;
- bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
- & 0x0000dc00;
- bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
- & 0x0000dc00;
- bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
- & 0x0001dc00;
+ bcm->dma_reason[0] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA0_REASON)
+ & 0x0001DC00;
+ bcm->dma_reason[1] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA1_REASON)
+ & 0x0000DC00;
+ bcm->dma_reason[2] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA2_REASON)
+ & 0x0000DC00;
+ bcm->dma_reason[3] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA3_REASON)
+ & 0x0001DC00;
+ bcm->dma_reason[4] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA4_REASON)
+ & 0x0000DC00;
+ bcm->dma_reason[5] = bcm43xx_read32(bcm, BCM43xx_MMIO_DMA5_REASON)
+ & 0x0000DC00;
bcm43xx_interrupt_ack(bcm, reason);
@@ -1930,16 +1903,18 @@ out:
static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force)
{
+ struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
+
if (bcm->firmware_norelease && !force)
return; /* Suspending or controller reset. */
- release_firmware(bcm->ucode);
- bcm->ucode = NULL;
- release_firmware(bcm->pcm);
- bcm->pcm = NULL;
- release_firmware(bcm->initvals0);
- bcm->initvals0 = NULL;
- release_firmware(bcm->initvals1);
- bcm->initvals1 = NULL;
+ release_firmware(phy->ucode);
+ phy->ucode = NULL;
+ release_firmware(phy->pcm);
+ phy->pcm = NULL;
+ release_firmware(phy->initvals0);
+ phy->initvals0 = NULL;
+ release_firmware(phy->initvals1);
+ phy->initvals1 = NULL;
}
static int bcm43xx_request_firmware(struct bcm43xx_private *bcm)
@@ -1950,11 +1925,11 @@ static int bcm43xx_request_firmware(stru
int nr;
char buf[22 + sizeof(modparam_fwpostfix) - 1] = { 0 };
- if (!bcm->ucode) {
+ if (!phy->ucode) {
snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_microcode%d%s.fw",
(rev >= 5 ? 5 : rev),
modparam_fwpostfix);
- err = request_firmware(&bcm->ucode, buf, &bcm->pci_dev->dev);
+ err = request_firmware(&phy->ucode, buf, &bcm->pci_dev->dev);
if (err) {
printk(KERN_ERR PFX
"Error: Microcode \"%s\" not available or load
failed.\n",
@@ -1963,12 +1938,12 @@ static int bcm43xx_request_firmware(stru
}
}
- if (!bcm->pcm) {
+ if (!phy->pcm) {
snprintf(buf, ARRAY_SIZE(buf),
"bcm43xx_pcm%d%s.fw",
(rev < 5 ? 4 : 5),
modparam_fwpostfix);
- err = request_firmware(&bcm->pcm, buf, &bcm->pci_dev->dev);
+ err = request_firmware(&phy->pcm, buf, &bcm->pci_dev->dev);
if (err) {
printk(KERN_ERR PFX
"Error: PCM \"%s\" not available or load
failed.\n",
@@ -1977,7 +1952,7 @@ static int bcm43xx_request_firmware(stru
}
}
- if (!bcm->initvals0) {
+ if (!phy->initvals0) {
if (rev == 2 || rev == 4) {
switch (phy->type) {
case BCM43xx_PHYTYPE_A:
@@ -2008,20 +1983,20 @@ static int bcm43xx_request_firmware(stru
snprintf(buf, ARRAY_SIZE(buf), "bcm43xx_initval%02d%s.fw",
nr, modparam_fwpostfix);
- err = request_firmware(&bcm->initvals0, buf,
&bcm->pci_dev->dev);
+ err = request_firmware(&phy->initvals0, buf,
&bcm->pci_dev->dev);
if (err) {
printk(KERN_ERR PFX
"Error: InitVals \"%s\" not available or load
failed.\n",
buf);
goto error;
}
- if (bcm->initvals0->size % sizeof(struct bcm43xx_initval)) {
+ if (phy->initvals0->size % sizeof(struct bcm43xx_initval)) {
printk(KERN_ERR PFX "InitVals fileformat error.\n");
goto error;
}
}
- if (!bcm->initvals1) {
+ if (!phy->initvals1) {
if (rev >= 5) {
u32 sbtmstatehigh;
@@ -2043,14 +2018,14 @@ static int bcm43xx_request_firmware(stru
snprintf(buf, ARRAY_SIZE(buf),
"bcm43xx_initval%02d%s.fw",
nr, modparam_fwpostfix);
- err = request_firmware(&bcm->initvals1, buf,
&bcm->pci_dev->dev);
+ err = request_firmware(&phy->initvals1, buf,
&bcm->pci_dev->dev);
if (err) {
printk(KERN_ERR PFX
"Error: InitVals \"%s\" not available or
load failed.\n",
buf);
goto error;
}
- if (bcm->initvals1->size % sizeof(struct
bcm43xx_initval)) {
+ if (phy->initvals1->size % sizeof(struct
bcm43xx_initval)) {
printk(KERN_ERR PFX "InitVals fileformat
error.\n");
goto error;
}
@@ -2070,12 +2045,13 @@ err_noinitval:
static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm)
{
+ struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
const u32 *data;
unsigned int i, len;
/* Upload Microcode. */
- data = (u32 *)(bcm->ucode->data);
- len = bcm->ucode->size / sizeof(u32);
+ data = (u32 *)(phy->ucode->data);
+ len = phy->ucode->size / sizeof(u32);
bcm43xx_shm_control_word(bcm, BCM43xx_SHM_UCODE, 0x0000);
for (i = 0; i < len; i++) {
bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA,
@@ -2084,8 +2060,8 @@ static void bcm43xx_upload_microcode(str
}
/* Upload PCM data. */
- data = (u32 *)(bcm->pcm->data);
- len = bcm->pcm->size / sizeof(u32);
+ data = (u32 *)(phy->pcm->data);
+ len = phy->pcm->size / sizeof(u32);
bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01ea);
bcm43xx_write32(bcm, BCM43xx_MMIO_SHM_DATA, 0x00004000);
bcm43xx_shm_control_word(bcm, BCM43xx_SHM_PCM, 0x01eb);
@@ -2131,15 +2107,16 @@ err_format:
static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm)
{
+ struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
int err;
- err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval
*)bcm->initvals0->data,
- bcm->initvals0->size / sizeof(struct
bcm43xx_initval));
+ err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval
*)phy->initvals0->data,
+ phy->initvals0->size / sizeof(struct
bcm43xx_initval));
if (err)
goto out;
- if (bcm->initvals1) {
- err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval
*)bcm->initvals1->data,
- bcm->initvals1->size /
sizeof(struct bcm43xx_initval));
+ if (phy->initvals1) {
+ err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval
*)phy->initvals1->data,
+ phy->initvals1->size /
sizeof(struct bcm43xx_initval));
if (err)
goto out;
}
@@ -2156,9 +2133,7 @@ static struct pci_device_id bcm43xx_47xx
static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm)
{
- int res;
- unsigned int i;
- u32 data;
+ int err;
bcm->irq = bcm->pci_dev->irq;
#ifdef CONFIG_BCM947XX
@@ -2175,32 +2150,12 @@ static int bcm43xx_initialize_irq(struct
}
}
#endif
- res = request_irq(bcm->irq, bcm43xx_interrupt_handler,
+ err = request_irq(bcm->irq, bcm43xx_interrupt_handler,
IRQF_SHARED, KBUILD_MODNAME, bcm);
- if (res) {
+ if (err)
printk(KERN_ERR PFX "Cannot register IRQ%d\n", bcm->irq);
- return -ENODEV;
- }
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xffffffff);
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
- i = 0;
- while (1) {
- data = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
- if (data == BCM43xx_IRQ_READY)
- break;
- i++;
- if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
- printk(KERN_ERR PFX "Card IRQ register not responding. "
- "Giving up.\n");
- free_irq(bcm->irq, bcm);
- return -ENODEV;
- }
- udelay(10);
- }
- // dummy read
- bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
-
- return 0;
+
+ return err;
}
/* Switch to the core used to write the GPIO register.
@@ -2298,13 +2253,17 @@ static int bcm43xx_gpio_cleanup(struct b
/* http://bcm-specs.sipsolutions.net/EnableMac */
void bcm43xx_mac_enable(struct bcm43xx_private *bcm)
{
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
- | BCM43xx_SBF_MAC_ENABLED);
- bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, BCM43xx_IRQ_READY);
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
- bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
- bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
+ bcm->mac_suspended--;
+ assert(bcm->mac_suspended >= 0);
+ if (bcm->mac_suspended == 0) {
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+ bcm43xx_read32(bcm,
BCM43xx_MMIO_STATUS_BITFIELD)
+ | BCM43xx_SBF_MAC_ENABLED);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON,
BCM43xx_IRQ_READY);
+ bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy
read */
+ bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read
*/
+ bcm43xx_power_saving_ctl_bits(bcm, -1, -1);
+ }
}
/* http://bcm-specs.sipsolutions.net/SuspendMAC */
@@ -2313,18 +2272,23 @@ void bcm43xx_mac_suspend(struct bcm43xx_
int i;
u32 tmp;
- bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
- bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD)
- & ~BCM43xx_SBF_MAC_ENABLED);
- bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
- for (i = 100000; i; i--) {
- tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
- if (tmp & BCM43xx_IRQ_READY)
- return;
- udelay(10);
- }
- printkl(KERN_ERR PFX "MAC suspend failed\n");
+ assert(bcm->mac_suspended >= 0);
+ if (bcm->mac_suspended == 0) {
+ bcm43xx_power_saving_ctl_bits(bcm, -1, 1);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD,
+ bcm43xx_read32(bcm,
BCM43xx_MMIO_STATUS_BITFIELD)
+ & ~BCM43xx_SBF_MAC_ENABLED);
+ bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read
*/
+ for (i = 10000; i; i--) {
+ tmp = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
+ if (tmp & BCM43xx_IRQ_READY)
+ goto out;
+ udelay(1);
+ }
+ printkl(KERN_ERR PFX "MAC suspend failed\n");
+ }
+out:
+ bcm->mac_suspended++;
}
void bcm43xx_set_iwmode(struct bcm43xx_private *bcm,
@@ -2394,7 +2358,6 @@ static void bcm43xx_chip_cleanup(struct
if (!modparam_noleds)
bcm43xx_leds_exit(bcm);
bcm43xx_gpio_cleanup(bcm);
- free_irq(bcm->irq, bcm);
bcm43xx_release_firmware(bcm, 0);
}
@@ -2406,7 +2369,7 @@ static int bcm43xx_chip_init(struct bcm4
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
int err;
- int tmp;
+ int i, tmp;
u32 value32;
u16 value16;
@@ -2419,13 +2382,53 @@ static int bcm43xx_chip_init(struct bcm4
goto out;
bcm43xx_upload_microcode(bcm);
- err = bcm43xx_initialize_irq(bcm);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0xFFFFFFFF);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, 0x00020402);
+ i = 0;
+ while (1) {
+ value32 = bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON);
+ if (value32 == BCM43xx_IRQ_READY)
+ break;
+ i++;
+ if (i >= BCM43xx_IRQWAIT_MAX_RETRIES) {
+ printk(KERN_ERR PFX "IRQ_READY timeout\n");
+ err = -ENODEV;
+ goto err_release_fw;
+ }
+ udelay(10);
+ }
+ bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read */
+
+ value16 = bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODE_REVISION);
+
+ dprintk(KERN_INFO PFX "Microcode rev 0x%x, pl 0x%x "
+ "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", value16,
+ bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODE_PATCHLEVEL),
+ (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODE_DATE) >> 12) & 0xf,
+ (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODE_DATE) >> 8) & 0xf,
+ bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODE_DATE) & 0xff,
+ (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODE_TIME) >> 11) & 0x1f,
+ (bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODE_TIME) >> 5) & 0x3f,
+ bcm43xx_shm_read16(bcm, BCM43xx_SHM_SHARED,
+ BCM43xx_UCODE_TIME) & 0x1f);
+
+ if ( value16 > 0x128 ) {
+ dprintk(KERN_ERR PFX
+ "Firmware: no support for microcode rev > 0x128\n");
+ err = -1;
+ goto err_release_fw;
+ }
+
+ err = bcm43xx_gpio_init(bcm);
if (err)
goto err_release_fw;
-
- err = bcm43xx_gpio_init(bcm);
- if (err)
- goto err_free_irq;
err = bcm43xx_upload_initvals(bcm);
if (err)
@@ -2489,10 +2492,12 @@ static int bcm43xx_chip_init(struct bcm4
bcm43xx_write32(bcm, 0x018C, 0x02000000);
}
bcm43xx_write32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON, 0x00004000);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0001DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA0_IRQ_MASK, 0x0001DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA1_IRQ_MASK, 0x0000DC00);
bcm43xx_write32(bcm, BCM43xx_MMIO_DMA2_IRQ_MASK, 0x0000DC00);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0000DC00);
- bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0001DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA3_IRQ_MASK, 0x0001DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA4_IRQ_MASK, 0x0000DC00);
+ bcm43xx_write32(bcm, BCM43xx_MMIO_DMA5_IRQ_MASK, 0x0000DC00);
value32 = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
value32 |= 0x00100000;
@@ -2509,8 +2514,6 @@ err_radio_off:
bcm43xx_radio_turn_off(bcm);
err_gpio_cleanup:
bcm43xx_gpio_cleanup(bcm);
-err_free_irq:
- free_irq(bcm->irq, bcm);
err_release_fw:
bcm43xx_release_firmware(bcm, 1);
goto out;
@@ -2550,11 +2553,9 @@ static void bcm43xx_init_struct_phyinfo(
{
/* Initialize a "phyinfo" structure. The structure is already
* zeroed out.
+ * This is called on insmod time to initialize members.
*/
- phy->antenna_diversity = 0xFFFF;
phy->savedpctlreg = 0xFFFF;
- phy->minlowsig[0] = 0xFFFF;
- phy->minlowsig[1] = 0xFFFF;
spin_lock_init(&phy->lock);
}
@@ -2562,14 +2563,11 @@ static void bcm43xx_init_struct_radioinf
{
/* Initialize a "radioinfo" structure. The structure is already
* zeroed out.
+ * This is called on insmod time to initialize members.
*/
radio->interfmode = BCM43xx_RADIO_INTERFMODE_NONE;
radio->channel = 0xFF;
radio->initial_channel = 0xFF;
- radio->lofcal = 0xFFFF;
- radio->initval = 0xFFFF;
- radio->nrssi[0] = -1000;
- radio->nrssi[1] = -1000;
}
static int bcm43xx_probe_cores(struct bcm43xx_private *bcm)
@@ -2587,7 +2585,6 @@ static int bcm43xx_probe_cores(struct bc
* BCM43xx_MAX_80211_CORES);
memset(&bcm->core_80211_ext, 0, sizeof(struct bcm43xx_coreinfo_80211)
* BCM43xx_MAX_80211_CORES);
- bcm->current_80211_core_idx = -1;
bcm->nr_80211_available = 0;
bcm->current_core = NULL;
bcm->active_80211_core = NULL;
@@ -2757,6 +2754,7 @@ static int bcm43xx_probe_cores(struct bc
goto out;
}
bcm->nr_80211_available++;
+ core->priv = ext_80211;
bcm43xx_init_struct_phyinfo(&ext_80211->phy);
bcm43xx_init_struct_radioinfo(&ext_80211->radio);
break;
@@ -2857,7 +2855,8 @@ static void bcm43xx_wireless_core_cleanu
}
/* http://bcm-specs.sipsolutions.net/80211Init */
-static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm)
+static int bcm43xx_wireless_core_init(struct bcm43xx_private *bcm,
+ int active_wlcore)
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
struct bcm43xx_radioinfo *radio = bcm43xx_current_radio(bcm);
@@ -2939,19 +2938,26 @@ static int bcm43xx_wireless_core_init(st
if (bcm->current_core->rev >= 5)
bcm43xx_write16(bcm, 0x043C, 0x000C);
- if (bcm43xx_using_pio(bcm))
- err = bcm43xx_pio_init(bcm);
- else
- err = bcm43xx_dma_init(bcm);
- if (err)
- goto err_chip_cleanup;
+ if (active_wlcore) {
+ if (bcm43xx_using_pio(bcm))
+ err = bcm43xx_pio_init(bcm);
+ else
+ err = bcm43xx_dma_init(bcm);
+ if (err)
+ goto err_chip_cleanup;
+ }
bcm43xx_write16(bcm, 0x0612, 0x0050);
bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0416, 0x0050);
bcm43xx_shm_write16(bcm, BCM43xx_SHM_SHARED, 0x0414, 0x01F4);
- bcm43xx_mac_enable(bcm);
- bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
-
+ if (active_wlcore) {
+ if (radio->initial_channel != 0xFF)
+ bcm43xx_radio_selectchannel(bcm,
radio->initial_channel, 0);
+ }
+
+ /* Don't enable MAC/IRQ here, as it will race with the IRQ handler.
+ * We enable it later.
+ */
bcm->current_core->initialized = 1;
out:
return err;
@@ -3064,11 +3070,6 @@ out_switch_back:
err = bcm43xx_switch_core(bcm, old_core);
out:
return err;
-}
-
-static void bcm43xx_softmac_init(struct bcm43xx_private *bcm)
-{
- ieee80211softmac_start(bcm->net_dev);
}
static void bcm43xx_periodic_every120sec(struct bcm43xx_private *bcm)
@@ -3178,51 +3179,51 @@ static void bcm43xx_periodic_work_handle
int badness;
badness = estimate_periodic_work_badness(bcm->periodic_state);
+ mutex_lock(&bcm->mutex);
+
+ /* We must fake a started transmission here, as we are going to
+ * disable TX. If we wouldn't fake a TX, it would be possible to
+ * trigger the netdev watchdog, if the last real TX is already
+ * some time on the past (slightly less than 5secs)
+ */
+ bcm->net_dev->trans_start = jiffies;
+ netif_tx_disable(bcm->net_dev);
+
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (badness > BADNESS_LIMIT) {
/* Periodic work will take a long time, so we want it to
* be preemtible.
*/
- bcm43xx_lock_irqonly(bcm, flags);
- netif_stop_queue(bcm->net_dev);
+ bcm43xx_mac_suspend(bcm);
if (bcm43xx_using_pio(bcm))
bcm43xx_pio_freeze_txqueues(bcm);
savedirqs = bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_unlock_irqonly(bcm, flags);
- bcm43xx_lock_noirq(bcm);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
bcm43xx_synchronize_irq(bcm);
- } else {
- /* Periodic work should take short time, so we want low
- * locking overhead.
- */
- bcm43xx_lock_irqsafe(bcm, flags);
}
do_periodic_work(bcm);
if (badness > BADNESS_LIMIT) {
- bcm43xx_lock_irqonly(bcm, flags);
- if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)) {
- tasklet_enable(&bcm->isr_tasklet);
- bcm43xx_interrupt_enable(bcm, savedirqs);
- if (bcm43xx_using_pio(bcm))
- bcm43xx_pio_thaw_txqueues(bcm);
- }
- netif_wake_queue(bcm->net_dev);
- mmiowb();
- bcm43xx_unlock_irqonly(bcm, flags);
- bcm43xx_unlock_noirq(bcm);
- } else {
- mmiowb();
- bcm43xx_unlock_irqsafe(bcm, flags);
- }
-}
-
-static void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
+ spin_lock_irqsave(&bcm->irq_lock, flags);
+ tasklet_enable(&bcm->isr_tasklet);
+ bcm43xx_interrupt_enable(bcm, savedirqs);
+ if (bcm43xx_using_pio(bcm))
+ bcm43xx_pio_thaw_txqueues(bcm);
+ bcm43xx_mac_enable(bcm);
+ }
+ mmiowb();
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ netif_wake_queue(bcm->net_dev);
+ mutex_unlock(&bcm->mutex);
+}
+
+void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm)
{
cancel_rearming_delayed_work(&bcm->periodic_work);
}
-static void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
+void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm)
{
struct work_struct *work = &(bcm->periodic_work);
@@ -3243,9 +3244,9 @@ static int bcm43xx_rng_read(struct hwrng
struct bcm43xx_private *bcm = (struct bcm43xx_private *)rng->priv;
unsigned long flags;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&(bcm)->irq_lock, flags);
*data = bcm43xx_read16(bcm, BCM43xx_MMIO_RNG);
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&(bcm)->irq_lock, flags);
return (sizeof(u16));
}
@@ -3271,139 +3272,330 @@ static int bcm43xx_rng_init(struct bcm43
return err;
}
+static int bcm43xx_shutdown_all_wireless_cores(struct bcm43xx_private *bcm)
+{
+ int ret = 0;
+ int i, err;
+ struct bcm43xx_coreinfo *core;
+
+ bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
+ for (i = 0; i < bcm->nr_80211_available; i++) {
+ core = &(bcm->core_80211[i]);
+ assert(core->available);
+ if (!core->initialized)
+ continue;
+ err = bcm43xx_switch_core(bcm, core);
+ if (err) {
+ dprintk(KERN_ERR PFX "shutdown_all_wireless_cores "
+ "switch_core failed (%d)\n", err);
+ ret = err;
+ continue;
+ }
+ bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
+ bcm43xx_read32(bcm, BCM43xx_MMIO_GEN_IRQ_REASON); /* dummy read
*/
+ bcm43xx_wireless_core_cleanup(bcm);
+ if (core == bcm->active_80211_core)
+ bcm->active_80211_core = NULL;
+ }
+ free_irq(bcm->irq, bcm);
+ bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
+
+ return ret;
+}
+
/* This is the opposite of bcm43xx_init_board() */
static void bcm43xx_free_board(struct bcm43xx_private *bcm)
{
- int i, err;
-
- bcm43xx_lock_noirq(bcm);
+ bcm43xx_rng_exit(bcm);
bcm43xx_sysfs_unregister(bcm);
bcm43xx_periodic_tasks_delete(bcm);
- bcm43xx_set_status(bcm, BCM43xx_STAT_SHUTTINGDOWN);
-
- bcm43xx_rng_exit(bcm);
+ mutex_lock(&(bcm)->mutex);
+ bcm43xx_shutdown_all_wireless_cores(bcm);
+ bcm43xx_pctl_set_crystal(bcm, 0);
+ mutex_unlock(&(bcm)->mutex);
+}
+
+static void prepare_phydata_for_init(struct bcm43xx_phyinfo *phy)
+{
+ phy->antenna_diversity = 0xFFFF;
+ memset(phy->minlowsig, 0xFF, sizeof(phy->minlowsig));
+ memset(phy->minlowsigpos, 0, sizeof(phy->minlowsigpos));
+
+ /* Flags */
+ phy->calibrated = 0;
+ phy->is_locked = 0;
+
+ if (phy->_lo_pairs) {
+ memset(phy->_lo_pairs, 0,
+ sizeof(struct bcm43xx_lopair) * BCM43xx_LO_COUNT);
+ }
+ memset(phy->loopback_gain, 0, sizeof(phy->loopback_gain));
+}
+
+static void prepare_radiodata_for_init(struct bcm43xx_private *bcm,
+ struct bcm43xx_radioinfo *radio)
+{
+ int i;
+
+ /* Set default attenuation values. */
+ radio->baseband_atten = bcm43xx_default_baseband_attenuation(bcm);
+ radio->radio_atten = bcm43xx_default_radio_attenuation(bcm);
+ radio->txctl1 = bcm43xx_default_txctl1(bcm);
+ radio->txctl2 = 0xFFFF;
+ radio->txpwr_offset = 0;
+
+ /* NRSSI */
+ radio->nrssislope = 0;
+ for (i = 0; i < ARRAY_SIZE(radio->nrssi); i++)
+ radio->nrssi[i] = -1000;
+ for (i = 0; i < ARRAY_SIZE(radio->nrssi_lt); i++)
+ radio->nrssi_lt[i] = i;
+
+ radio->lofcal = 0xFFFF;
+ radio->initval = 0xFFFF;
+
+ radio->aci_enable = 0;
+ radio->aci_wlan_automatic = 0;
+ radio->aci_hw_rssi = 0;
+}
+
+static void prepare_priv_for_init(struct bcm43xx_private *bcm)
+{
+ int i;
+ struct bcm43xx_coreinfo *core;
+ struct bcm43xx_coreinfo_80211 *wlext;
+
+ assert(!bcm->active_80211_core);
+
+ bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
+
+ /* Flags */
+ bcm->was_initialized = 0;
+ bcm->reg124_set_0x4 = 0;
+
+ /* Stats */
+ memset(&bcm->stats, 0, sizeof(bcm->stats));
+
+ /* Wireless core data */
for (i = 0; i < BCM43xx_MAX_80211_CORES; i++) {
- if (!bcm->core_80211[i].available)
+ core = &(bcm->core_80211[i]);
+ wlext = core->priv;
+
+ if (!core->available)
continue;
- if (!bcm->core_80211[i].initialized)
+ assert(wlext == &(bcm->core_80211_ext[i]));
+
+ prepare_phydata_for_init(&wlext->phy);
+ prepare_radiodata_for_init(bcm, &wlext->radio);
+ }
+
+ /* IRQ related flags */
+ bcm->irq_reason = 0;
+ memset(bcm->dma_reason, 0, sizeof(bcm->dma_reason));
+ bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
+
+ bcm->mac_suspended = 1;
+
+ /* Noise calculation context */
+ memset(&bcm->noisecalc, 0, sizeof(bcm->noisecalc));
+
+ /* Periodic work context */
+ bcm->periodic_state = 0;
+}
+
+static int wireless_core_up(struct bcm43xx_private *bcm,
+ int active_wlcore)
+{
+ int err;
+
+ if (!bcm43xx_core_enabled(bcm))
+ bcm43xx_wireless_core_reset(bcm, 1);
+ if (!active_wlcore)
+ bcm43xx_wireless_core_mark_inactive(bcm);
+ err = bcm43xx_wireless_core_init(bcm, active_wlcore);
+ if (err)
+ goto out;
+ if (!active_wlcore)
+ bcm43xx_radio_turn_off(bcm);
+out:
+ return err;
+}
+
+/* Select and enable the "to be used" wireless core.
+ * Locking: bcm->mutex must be aquired before calling this.
+ * bcm->irq_lock must not be aquired.
+ */
+int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
+ int phytype)
+{
+ int i, err;
+ struct bcm43xx_coreinfo *active_core = NULL;
+ struct bcm43xx_coreinfo_80211 *active_wlext = NULL;
+ struct bcm43xx_coreinfo *core;
+ struct bcm43xx_coreinfo_80211 *wlext;
+ int adjust_active_sbtmstatelow = 0;
+
+ might_sleep();
+
+ if (phytype < 0) {
+ /* If no phytype is requested, select the first core. */
+ assert(bcm->core_80211[0].available);
+ wlext = bcm->core_80211[0].priv;
+ phytype = wlext->phy.type;
+ }
+ /* Find the requested core. */
+ for (i = 0; i < bcm->nr_80211_available; i++) {
+ core = &(bcm->core_80211[i]);
+ wlext = core->priv;
+ if (wlext->phy.type == phytype) {
+ active_core = core;
+ active_wlext = wlext;
+ break;
+ }
+ }
+ if (!active_core)
+ return -ESRCH; /* No such PHYTYPE on this board. */
+
+ if (bcm->active_80211_core) {
+ /* We already selected a wl core in the past.
+ * So first clean up everything.
+ */
+ dprintk(KERN_INFO PFX "select_wireless_core: cleanup\n");
+ ieee80211softmac_stop(bcm->net_dev);
+ bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
+ err = bcm43xx_disable_interrupts_sync(bcm);
+ assert(!err);
+ tasklet_enable(&bcm->isr_tasklet);
+ err = bcm43xx_shutdown_all_wireless_cores(bcm);
+ if (err)
+ goto error;
+ /* Ok, everything down, continue to re-initialize. */
+ bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
+ }
+
+ /* Reset all data structures. */
+ prepare_priv_for_init(bcm);
+
+ err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
+ if (err)
+ goto error;
+
+ /* Mark all unused cores "inactive". */
+ for (i = 0; i < bcm->nr_80211_available; i++) {
+ core = &(bcm->core_80211[i]);
+ wlext = core->priv;
+
+ if (core == active_core)
continue;
-
- err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
- assert(err == 0);
- bcm43xx_wireless_core_cleanup(bcm);
- }
-
- bcm43xx_pctl_set_crystal(bcm, 0);
-
+ err = bcm43xx_switch_core(bcm, core);
+ if (err) {
+ dprintk(KERN_ERR PFX "Could not switch to inactive "
+ "802.11 core (%d)\n", err);
+ goto error;
+ }
+ err = wireless_core_up(bcm, 0);
+ if (err) {
+ dprintk(KERN_ERR PFX "core_up for inactive 802.11 core "
+ "failed (%d)\n", err);
+ goto error;
+ }
+ adjust_active_sbtmstatelow = 1;
+ }
+
+ /* Now initialize the active 802.11 core. */
+ err = bcm43xx_switch_core(bcm, active_core);
+ if (err) {
+ dprintk(KERN_ERR PFX "Could not switch to active "
+ "802.11 core (%d)\n", err);
+ goto error;
+ }
+ if (adjust_active_sbtmstatelow &&
+ active_wlext->phy.type == BCM43xx_PHYTYPE_G) {
+ u32 sbtmstatelow;
+
+ sbtmstatelow = bcm43xx_read32(bcm, BCM43xx_CIR_SBTMSTATELOW);
+ sbtmstatelow |= 0x20000000;
+ bcm43xx_write32(bcm, BCM43xx_CIR_SBTMSTATELOW, sbtmstatelow);
+ }
+ err = wireless_core_up(bcm, 1);
+ if (err) {
+ dprintk(KERN_ERR PFX "core_up for active 802.11 core "
+ "failed (%d)\n", err);
+ goto error;
+ }
+ err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
+ if (err)
+ goto error;
+ bcm->active_80211_core = active_core;
+
+ bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
+ bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8
*)(bcm->net_dev->dev_addr));
+ bcm43xx_security_init(bcm);
+ drain_txstatus_queue(bcm);
+ ieee80211softmac_start(bcm->net_dev);
+
+ /* Let's go! Be careful after enabling the IRQs.
+ * Don't switch cores, for example.
+ */
+ bcm43xx_mac_enable(bcm);
+ bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
+ err = bcm43xx_initialize_irq(bcm);
+ if (err)
+ goto error;
+ bcm43xx_interrupt_enable(bcm, bcm->irq_savedstate);
+
+ dprintk(KERN_INFO PFX "Selected 802.11 core (phytype %d)\n",
+ active_wlext->phy.type);
+
+ return 0;
+
+error:
bcm43xx_set_status(bcm, BCM43xx_STAT_UNINIT);
- bcm43xx_unlock_noirq(bcm);
+ bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_SLOW);
+ return err;
}
static int bcm43xx_init_board(struct bcm43xx_private *bcm)
{
- int i, err;
- int connect_phy;
-
- might_sleep();
-
- bcm43xx_lock_noirq(bcm);
- bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZING);
-
+ int err;
+
+ mutex_lock(&(bcm)->mutex);
+
+ tasklet_enable(&bcm->isr_tasklet);
err = bcm43xx_pctl_set_crystal(bcm, 1);
if (err)
- goto out;
+ goto err_tasklet;
err = bcm43xx_pctl_init(bcm);
if (err)
goto err_crystal_off;
- err = bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_FAST);
+ err = bcm43xx_select_wireless_core(bcm, -1);
if (err)
goto err_crystal_off;
-
- tasklet_enable(&bcm->isr_tasklet);
- for (i = 0; i < bcm->nr_80211_available; i++) {
- err = bcm43xx_switch_core(bcm, &bcm->core_80211[i]);
- assert(err != -ENODEV);
- if (err)
- goto err_80211_unwind;
-
- /* Enable the selected wireless core.
- * Connect PHY only on the first core.
- */
- if (!bcm43xx_core_enabled(bcm)) {
- if (bcm->nr_80211_available == 1) {
- connect_phy =
bcm43xx_current_phy(bcm)->connected;
- } else {
- if (i == 0)
- connect_phy = 1;
- else
- connect_phy = 0;
- }
- bcm43xx_wireless_core_reset(bcm, connect_phy);
- }
-
- if (i != 0)
- bcm43xx_wireless_core_mark_inactive(bcm,
&bcm->core_80211[0]);
-
- err = bcm43xx_wireless_core_init(bcm);
- if (err)
- goto err_80211_unwind;
-
- if (i != 0) {
- bcm43xx_mac_suspend(bcm);
- bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_radio_turn_off(bcm);
- }
- }
- bcm->active_80211_core = &bcm->core_80211[0];
- if (bcm->nr_80211_available >= 2) {
- bcm43xx_switch_core(bcm, &bcm->core_80211[0]);
- bcm43xx_mac_enable(bcm);
- }
+ err = bcm43xx_sysfs_register(bcm);
+ if (err)
+ goto err_wlshutdown;
err = bcm43xx_rng_init(bcm);
if (err)
- goto err_80211_unwind;
- bcm43xx_macfilter_clear(bcm, BCM43xx_MACFILTER_ASSOC);
- bcm43xx_macfilter_set(bcm, BCM43xx_MACFILTER_SELF, (u8
*)(bcm->net_dev->dev_addr));
- dprintk(KERN_INFO PFX "80211 cores initialized\n");
- bcm43xx_security_init(bcm);
- bcm43xx_softmac_init(bcm);
-
- bcm43xx_pctl_set_clock(bcm, BCM43xx_PCTL_CLK_DYNAMIC);
-
- if (bcm43xx_current_radio(bcm)->initial_channel != 0xFF) {
- bcm43xx_mac_suspend(bcm);
- bcm43xx_radio_selectchannel(bcm,
bcm43xx_current_radio(bcm)->initial_channel, 0);
- bcm43xx_mac_enable(bcm);
- }
-
- /* Initialization of the board is done. Flag it as such. */
- bcm43xx_set_status(bcm, BCM43xx_STAT_INITIALIZED);
-
+ goto err_sysfs_unreg;
bcm43xx_periodic_tasks_setup(bcm);
- bcm43xx_sysfs_register(bcm);
- //FIXME: check for bcm43xx_sysfs_register failure. This function is a
bit messy regarding unwinding, though...
/*FIXME: This should be handled by softmac instead. */
schedule_work(&bcm->softmac->associnfo.work);
- assert(err == 0);
out:
- bcm43xx_unlock_noirq(bcm);
+ mutex_unlock(&(bcm)->mutex);
return err;
-err_80211_unwind:
- tasklet_disable(&bcm->isr_tasklet);
- /* unwind all 80211 initialization */
- for (i = 0; i < bcm->nr_80211_available; i++) {
- if (!bcm->core_80211[i].initialized)
- continue;
- bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_wireless_core_cleanup(bcm);
- }
+err_sysfs_unreg:
+ bcm43xx_sysfs_unregister(bcm);
+err_wlshutdown:
+ bcm43xx_shutdown_all_wireless_cores(bcm);
err_crystal_off:
bcm43xx_pctl_set_crystal(bcm, 0);
+err_tasklet:
+ tasklet_disable(&bcm->isr_tasklet);
goto out;
}
@@ -3647,7 +3839,8 @@ static void bcm43xx_ieee80211_set_chan(s
struct bcm43xx_radioinfo *radio;
unsigned long flags;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
bcm43xx_mac_suspend(bcm);
bcm43xx_radio_selectchannel(bcm, channel, 0);
@@ -3656,7 +3849,8 @@ static void bcm43xx_ieee80211_set_chan(s
radio = bcm43xx_current_radio(bcm);
radio->initial_channel = channel;
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
}
/* set_security() callback in struct ieee80211_device */
@@ -3670,7 +3864,8 @@ static void bcm43xx_ieee80211_set_securi
dprintk(KERN_INFO PFX "set security called");
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
for (keyidx = 0; keyidx<WEP_KEYS; keyidx++)
if (sec->flags & (1<<keyidx)) {
@@ -3739,7 +3934,8 @@ static void bcm43xx_ieee80211_set_securi
} else
bcm43xx_clear_keys(bcm);
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
}
/* hard_start_xmit() callback in struct ieee80211_device */
@@ -3751,12 +3947,14 @@ static int bcm43xx_ieee80211_hard_start_
int err = -ENODEV;
unsigned long flags;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (likely(bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED))
err = bcm43xx_tx(bcm, txb);
- bcm43xx_unlock_irqonly(bcm, flags);
-
- return err;
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+
+ if (unlikely(err))
+ return NETDEV_TX_BUSY;
+ return NETDEV_TX_OK;
}
static struct net_device_stats * bcm43xx_net_get_stats(struct net_device
*net_dev)
@@ -3769,9 +3967,9 @@ static void bcm43xx_net_tx_timeout(struc
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
unsigned long flags;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
bcm43xx_controller_restart(bcm, "TX timeout");
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
}
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -3781,7 +3979,8 @@ static void bcm43xx_net_poll_controller(
unsigned long flags;
local_irq_save(flags);
- bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
+ bcm43xx_interrupt_handler(bcm->irq, bcm, NULL);
local_irq_restore(flags);
}
#endif /* CONFIG_NET_POLL_CONTROLLER */
@@ -3799,9 +3998,10 @@ static int bcm43xx_net_stop(struct net_d
int err;
ieee80211softmac_stop(net_dev);
- err = bcm43xx_disable_interrupts_sync(bcm, NULL);
+ err = bcm43xx_disable_interrupts_sync(bcm);
assert(!err);
bcm43xx_free_board(bcm);
+ flush_scheduled_work();
return 0;
}
@@ -3818,10 +4018,12 @@ static int bcm43xx_init_private(struct b
bcm->softmac->set_channel = bcm43xx_ieee80211_set_chan;
bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
+ bcm->mac_suspended = 1;
bcm->pci_dev = pci_dev;
bcm->net_dev = net_dev;
bcm->bad_frames_preempt = modparam_bad_frames_preempt;
spin_lock_init(&bcm->irq_lock);
+ spin_lock_init(&bcm->leds_lock);
mutex_init(&bcm->mutex);
tasklet_init(&bcm->isr_tasklet,
(void (*)(unsigned long))bcm43xx_interrupt_tasklet,
@@ -3940,7 +4142,6 @@ static void __devexit bcm43xx_remove_one
bcm43xx_debugfs_remove_device(bcm);
unregister_netdev(net_dev);
bcm43xx_detach_board(bcm);
- assert(bcm->ucode == NULL);
free_ieee80211softmac(net_dev);
}
@@ -3950,47 +4151,31 @@ static void bcm43xx_chip_reset(void *_bc
static void bcm43xx_chip_reset(void *_bcm)
{
struct bcm43xx_private *bcm = _bcm;
- struct net_device *net_dev = bcm->net_dev;
- struct pci_dev *pci_dev = bcm->pci_dev;
- int err;
- int was_initialized = (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED);
-
- netif_stop_queue(bcm->net_dev);
- tasklet_disable(&bcm->isr_tasklet);
-
- bcm->firmware_norelease = 1;
- if (was_initialized)
- bcm43xx_free_board(bcm);
- bcm->firmware_norelease = 0;
- bcm43xx_detach_board(bcm);
- err = bcm43xx_init_private(bcm, net_dev, pci_dev);
- if (err)
- goto failure;
- err = bcm43xx_attach_board(bcm);
- if (err)
- goto failure;
- if (was_initialized) {
- err = bcm43xx_init_board(bcm);
- if (err)
- goto failure;
- }
- netif_wake_queue(bcm->net_dev);
- printk(KERN_INFO PFX "Controller restarted\n");
-
- return;
-failure:
- printk(KERN_ERR PFX "Controller restart failed\n");
+ struct bcm43xx_phyinfo *phy;
+ int err = -ENODEV;
+
+ mutex_lock(&(bcm)->mutex);
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
+ bcm43xx_periodic_tasks_delete(bcm);
+ phy = bcm43xx_current_phy(bcm);
+ err = bcm43xx_select_wireless_core(bcm, phy->type);
+ if (!err)
+ bcm43xx_periodic_tasks_setup(bcm);
+ }
+ mutex_unlock(&(bcm)->mutex);
+
+ printk(KERN_ERR PFX "Controller restart%s\n",
+ (err == 0) ? "ed" : " failed");
}
/* Hard-reset the chip.
* This can be called from interrupt or process context.
- * Make sure to _not_ re-enable device interrupts after this has been called.
-*/
+ * bcm->irq_lock must be locked.
+ */
void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char
*reason)
{
- bcm43xx_set_status(bcm, BCM43xx_STAT_RESTARTING);
- bcm43xx_interrupt_disable(bcm, BCM43xx_IRQ_ALL);
- bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* dummy read */
+ if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
+ return;
printk(KERN_ERR PFX "Controller RESET (%s) ...\n", reason);
INIT_WORK(&bcm->restart_work, bcm43xx_chip_reset, bcm);
schedule_work(&bcm->restart_work);
@@ -4002,21 +4187,16 @@ static int bcm43xx_suspend(struct pci_de
{
struct net_device *net_dev = pci_get_drvdata(pdev);
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
- int try_to_shutdown = 0, err;
+ int err;
dprintk(KERN_INFO PFX "Suspending...\n");
- bcm43xx_lock_irqsafe(bcm, flags);
- bcm->was_initialized = (bcm43xx_status(bcm) ==
BCM43xx_STAT_INITIALIZED);
- if (bcm->was_initialized)
- try_to_shutdown = 1;
- bcm43xx_unlock_irqsafe(bcm, flags);
-
netif_device_detach(net_dev);
- if (try_to_shutdown) {
+ bcm->was_initialized = 0;
+ if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
+ bcm->was_initialized = 1;
ieee80211softmac_stop(net_dev);
- err = bcm43xx_disable_interrupts_sync(bcm,
&bcm->irq_savedstate);
+ err = bcm43xx_disable_interrupts_sync(bcm);
if (unlikely(err)) {
dprintk(KERN_ERR PFX "Suspend failed.\n");
return -EAGAIN;
@@ -4049,17 +4229,14 @@ static int bcm43xx_resume(struct pci_dev
pci_restore_state(pdev);
bcm43xx_chipset_attach(bcm);
- if (bcm->was_initialized) {
- bcm->irq_savedstate = BCM43xx_IRQ_INITIAL;
+ if (bcm->was_initialized)
err = bcm43xx_init_board(bcm);
- }
if (err) {
printk(KERN_ERR PFX "Resume failed!\n");
return err;
}
-
netif_device_attach(net_dev);
-
+
dprintk(KERN_INFO PFX "Device resumed.\n");
return 0;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_main.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx_main.h Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.h Wed Oct 03 10:00:44
2007 +0100
@@ -133,10 +133,16 @@ void bcm43xx_dummy_transmission(struct b
int bcm43xx_switch_core(struct bcm43xx_private *bcm, struct bcm43xx_coreinfo
*new_core);
+int bcm43xx_select_wireless_core(struct bcm43xx_private *bcm,
+ int phytype);
+
void bcm43xx_wireless_core_reset(struct bcm43xx_private *bcm, int connect_phy);
void bcm43xx_mac_suspend(struct bcm43xx_private *bcm);
void bcm43xx_mac_enable(struct bcm43xx_private *bcm);
+
+void bcm43xx_periodic_tasks_delete(struct bcm43xx_private *bcm);
+void bcm43xx_periodic_tasks_setup(struct bcm43xx_private *bcm);
void bcm43xx_controller_restart(struct bcm43xx_private *bcm, const char
*reason);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_phy.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c Wed Oct 03 10:00:44
2007 +0100
@@ -81,6 +81,16 @@ static void bcm43xx_phy_initg(struct bcm
static void bcm43xx_phy_initg(struct bcm43xx_private *bcm);
+static inline
+void bcm43xx_voluntary_preempt(void)
+{
+ assert(!in_atomic() && !in_irq() &&
+ !in_interrupt() && !irqs_disabled());
+#ifndef CONFIG_PREEMPT
+ cond_resched();
+#endif /* CONFIG_PREEMPT */
+}
+
void bcm43xx_raw_phy_lock(struct bcm43xx_private *bcm)
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
@@ -133,22 +143,14 @@ void bcm43xx_phy_calibrate(struct bcm43x
void bcm43xx_phy_calibrate(struct bcm43xx_private *bcm)
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
- unsigned long flags;
bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); /* Dummy read. */
if (phy->calibrated)
return;
if (phy->type == BCM43xx_PHYTYPE_G && phy->rev == 1) {
- /* We do not want to be preempted while calibrating
- * the hardware.
- */
- local_irq_save(flags);
-
bcm43xx_wireless_core_reset(bcm, 0);
bcm43xx_phy_initg(bcm);
bcm43xx_wireless_core_reset(bcm, 1);
-
- local_irq_restore(flags);
}
phy->calibrated = 1;
}
@@ -359,7 +361,7 @@ static void bcm43xx_phy_setupg(struct bc
if (phy->rev <= 2)
for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x1400 + i,
bcm43xx_ilt_noisescaleg1[i]);
- else if ((phy->rev == 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
+ else if ((phy->rev >= 7) && (bcm43xx_phy_read(bcm, 0x0449) & 0x0200))
for (i = 0; i < BCM43xx_ILT_NOISESCALEG_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x1400 + i,
bcm43xx_ilt_noisescaleg3[i]);
else
@@ -369,7 +371,7 @@ static void bcm43xx_phy_setupg(struct bc
if (phy->rev == 2)
for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x5000 + i,
bcm43xx_ilt_sigmasqr1[i]);
- else if ((phy->rev > 2) && (phy->rev <= 7))
+ else if ((phy->rev > 2) && (phy->rev <= 8))
for (i = 0; i < BCM43xx_ILT_SIGMASQR_SIZE; i++)
bcm43xx_ilt_write(bcm, 0x5000 + i,
bcm43xx_ilt_sigmasqr2[i]);
@@ -1195,7 +1197,7 @@ static void bcm43xx_phy_initg(struct bcm
if (phy->rev == 1)
bcm43xx_phy_initb5(bcm);
- else if (phy->rev >= 2 && phy->rev <= 7)
+ else
bcm43xx_phy_initb6(bcm);
if (phy->rev >= 2 || phy->connected)
bcm43xx_phy_inita(bcm);
@@ -1239,23 +1241,22 @@ static void bcm43xx_phy_initg(struct bcm
bcm43xx_phy_lo_g_measure(bcm);
} else {
if (radio->version == 0x2050 && radio->revision == 8) {
- //FIXME
+ bcm43xx_radio_write16(bcm, 0x0052,
+ (radio->txctl1 << 4) |
radio->txctl2);
} else {
bcm43xx_radio_write16(bcm, 0x0052,
(bcm43xx_radio_read16(bcm, 0x0052)
& 0xFFF0) | radio->txctl1);
}
if (phy->rev >= 6) {
- /*
bcm43xx_phy_write(bcm, 0x0036,
(bcm43xx_phy_read(bcm, 0x0036)
- & 0xF000) | (FIXME << 12));
- */
+ & 0xF000) | (radio->txctl2 << 12));
}
if (bcm->sprom.boardflags & BCM43xx_BFL_PACTRL)
bcm43xx_phy_write(bcm, 0x002E, 0x8075);
else
- bcm43xx_phy_write(bcm, 0x003E, 0x807F);
+ bcm43xx_phy_write(bcm, 0x002E, 0x807F);
if (phy->rev < 2)
bcm43xx_phy_write(bcm, 0x002F, 0x0101);
else
@@ -1299,7 +1300,9 @@ static u16 bcm43xx_phy_lo_b_r15_loop(str
{
int i;
u16 ret = 0;
-
+ unsigned long flags;
+
+ local_irq_save(flags);
for (i = 0; i < 10; i++){
bcm43xx_phy_write(bcm, 0x0015, 0xAFA0);
udelay(1);
@@ -1309,6 +1312,8 @@ static u16 bcm43xx_phy_lo_b_r15_loop(str
udelay(40);
ret += bcm43xx_phy_read(bcm, 0x002C);
}
+ local_irq_restore(flags);
+ bcm43xx_voluntary_preempt();
return ret;
}
@@ -1435,6 +1440,7 @@ u16 bcm43xx_phy_lo_g_deviation_subval(st
}
ret = bcm43xx_phy_read(bcm, 0x002D);
local_irq_restore(flags);
+ bcm43xx_voluntary_preempt();
return ret;
}
@@ -1760,6 +1766,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm
bcm43xx_radio_write16(bcm, 0x43, i);
bcm43xx_radio_write16(bcm, 0x52, radio->txctl2);
udelay(10);
+ bcm43xx_voluntary_preempt();
bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
@@ -1803,6 +1810,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm
radio->txctl2
| (3/*txctl1*/ << 4));//FIXME:
shouldn't txctl1 be zero here and 3 in the loop above?
udelay(10);
+ bcm43xx_voluntary_preempt();
bcm43xx_phy_set_baseband_attenuation(bcm, j * 2);
@@ -1824,6 +1832,7 @@ void bcm43xx_phy_lo_g_measure(struct bcm
bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA2);
udelay(2);
bcm43xx_phy_write(bcm, 0x0812, (r27 << 8) | 0xA3);
+ bcm43xx_voluntary_preempt();
} else
bcm43xx_phy_write(bcm, 0x0015, r27 | 0xEFA0);
bcm43xx_phy_lo_adjust(bcm, is_initializing);
@@ -2188,12 +2197,6 @@ int bcm43xx_phy_init(struct bcm43xx_priv
{
struct bcm43xx_phyinfo *phy = bcm43xx_current_phy(bcm);
int err = -ENODEV;
- unsigned long flags;
-
- /* We do not want to be preempted while calibrating
- * the hardware.
- */
- local_irq_save(flags);
switch (phy->type) {
case BCM43xx_PHYTYPE_A:
@@ -2227,7 +2230,6 @@ int bcm43xx_phy_init(struct bcm43xx_priv
err = 0;
break;
}
- local_irq_restore(flags);
if (err)
printk(KERN_WARNING PFX "Unknown PHYTYPE found!\n");
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_pio.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c Wed Oct 03 10:00:44
2007 +0100
@@ -262,7 +262,7 @@ static void tx_tasklet(unsigned long d)
int err;
u16 txctl;
- bcm43xx_lock_irqonly(bcm, flags);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (queue->tx_frozen)
goto out_unlock;
@@ -300,7 +300,7 @@ static void tx_tasklet(unsigned long d)
continue;
}
out_unlock:
- bcm43xx_unlock_irqonly(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
}
static void setup_txqueues(struct bcm43xx_pioqueue *queue)
diff -r aafef975e518 -r 3e8752eb6d9c
drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c Wed Oct 03 10:00:44
2007 +0100
@@ -120,12 +120,14 @@ static ssize_t bcm43xx_attr_sprom_show(s
GFP_KERNEL);
if (!sprom)
return -ENOMEM;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
err = bcm43xx_sprom_read(bcm, sprom);
if (!err)
err = sprom2hex(sprom, buf, PAGE_SIZE);
mmiowb();
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
kfree(sprom);
return err;
@@ -150,10 +152,14 @@ static ssize_t bcm43xx_attr_sprom_store(
err = hex2sprom(sprom, buf, count);
if (err)
goto out_kfree;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
+ spin_lock(&bcm->leds_lock);
err = bcm43xx_sprom_write(bcm, sprom);
mmiowb();
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock(&bcm->leds_lock);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
out_kfree:
kfree(sprom);
@@ -170,13 +176,12 @@ static ssize_t bcm43xx_attr_interfmode_s
char *buf)
{
struct bcm43xx_private *bcm = dev_to_bcm(dev);
- int err;
ssize_t count = 0;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- bcm43xx_lock_noirq(bcm);
+ mutex_lock(&bcm->mutex);
switch (bcm43xx_current_radio(bcm)->interfmode) {
case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -191,11 +196,10 @@ static ssize_t bcm43xx_attr_interfmode_s
default:
assert(0);
}
- err = 0;
-
- bcm43xx_unlock_noirq(bcm);
-
- return err ? err : count;
+
+ mutex_unlock(&bcm->mutex);
+
+ return count;
}
@@ -229,7 +233,8 @@ static ssize_t bcm43xx_attr_interfmode_s
return -EINVAL;
}
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
if (err) {
@@ -237,7 +242,8 @@ static ssize_t bcm43xx_attr_interfmode_s
"supported by device\n");
}
mmiowb();
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return err ? err : count;
}
@@ -251,23 +257,21 @@ static ssize_t bcm43xx_attr_preamble_sho
char *buf)
{
struct bcm43xx_private *bcm = dev_to_bcm(dev);
- int err;
ssize_t count;
if (!capable(CAP_NET_ADMIN))
return -EPERM;
- bcm43xx_lock_noirq(bcm);
+ mutex_lock(&bcm->mutex);
if (bcm->short_preamble)
count = snprintf(buf, PAGE_SIZE, "1 (Short Preamble
enabled)\n");
else
count = snprintf(buf, PAGE_SIZE, "0 (Short Preamble
disabled)\n");
- err = 0;
- bcm43xx_unlock_noirq(bcm);
-
- return err ? err : count;
+ mutex_unlock(&bcm->mutex);
+
+ return count;
}
static ssize_t bcm43xx_attr_preamble_store(struct device *dev,
@@ -276,7 +280,6 @@ static ssize_t bcm43xx_attr_preamble_sto
{
struct bcm43xx_private *bcm = dev_to_bcm(dev);
unsigned long flags;
- int err;
int value;
if (!capable(CAP_NET_ADMIN))
@@ -285,14 +288,15 @@ static ssize_t bcm43xx_attr_preamble_sto
value = get_boolean(buf, count);
if (value < 0)
return value;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
bcm->short_preamble = !!value;
- err = 0;
- bcm43xx_unlock_irqsafe(bcm, flags);
-
- return err ? err : count;
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
+
+ return count;
}
static DEVICE_ATTR(shortpreamble, 0644,
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_wx.c
--- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c Wed Oct 03 10:00:44 2007 +0100
@@ -56,12 +56,11 @@ static int bcm43xx_wx_get_name(struct ne
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
int i;
- unsigned long flags;
struct bcm43xx_phyinfo *phy;
char suffix[7] = { 0 };
int have_a = 0, have_b = 0, have_g = 0;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
for (i = 0; i < bcm->nr_80211_available; i++) {
phy = &(bcm->core_80211_ext[i].phy);
switch (phy->type) {
@@ -77,7 +76,7 @@ static int bcm43xx_wx_get_name(struct ne
assert(0);
}
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
i = 0;
if (have_a) {
@@ -111,7 +110,9 @@ static int bcm43xx_wx_set_channelfreq(st
int freq;
int err = -EINVAL;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
+
if ((data->freq.m >= 0) && (data->freq.m <= 1000)) {
channel = data->freq.m;
freq = bcm43xx_channel_to_freq(bcm, channel);
@@ -131,7 +132,8 @@ static int bcm43xx_wx_set_channelfreq(st
err = 0;
}
out_unlock:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return err;
}
@@ -143,11 +145,10 @@ static int bcm43xx_wx_get_channelfreq(st
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
struct bcm43xx_radioinfo *radio;
- unsigned long flags;
int err = -ENODEV;
u16 channel;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
radio = bcm43xx_current_radio(bcm);
channel = radio->channel;
if (channel == 0xFF) {
@@ -162,7 +163,7 @@ static int bcm43xx_wx_get_channelfreq(st
err = 0;
out_unlock:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
return err;
}
@@ -180,13 +181,15 @@ static int bcm43xx_wx_set_mode(struct ne
if (mode == IW_MODE_AUTO)
mode = BCM43xx_INITIAL_IWMODE;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
if (bcm->ieee->iw_mode != mode)
bcm43xx_set_iwmode(bcm, mode);
} else
bcm->ieee->iw_mode = mode;
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -197,11 +200,10 @@ static int bcm43xx_wx_get_mode(struct ne
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
-
- bcm43xx_lock_irqsafe(bcm, flags);
+
+ mutex_lock(&bcm->mutex);
data->mode = bcm->ieee->iw_mode;
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -214,7 +216,6 @@ static int bcm43xx_wx_get_rangeparams(st
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
struct iw_range *range = (struct iw_range *)extra;
const struct ieee80211_geo *geo;
- unsigned long flags;
int i, j;
struct bcm43xx_phyinfo *phy;
@@ -254,7 +255,7 @@ static int bcm43xx_wx_get_rangeparams(st
IW_ENC_CAPA_CIPHER_TKIP |
IW_ENC_CAPA_CIPHER_CCMP;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
phy = bcm43xx_current_phy(bcm);
range->num_bitrates = 0;
@@ -301,7 +302,7 @@ static int bcm43xx_wx_get_rangeparams(st
}
range->num_frequency = j;
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -314,11 +315,11 @@ static int bcm43xx_wx_set_nick(struct ne
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
size_t len;
- bcm43xx_lock_noirq(bcm);
+ mutex_lock(&bcm->mutex);
len = min((size_t)data->data.length, (size_t)IW_ESSID_MAX_SIZE);
memcpy(bcm->nick, extra, len);
bcm->nick[len] = '\0';
- bcm43xx_unlock_noirq(bcm);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -331,12 +332,12 @@ static int bcm43xx_wx_get_nick(struct ne
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
size_t len;
- bcm43xx_lock_noirq(bcm);
+ mutex_lock(&bcm->mutex);
len = strlen(bcm->nick) + 1;
memcpy(extra, bcm->nick, len);
data->data.length = (__u16)len;
data->data.flags = 1;
- bcm43xx_unlock_noirq(bcm);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -350,7 +351,8 @@ static int bcm43xx_wx_set_rts(struct net
unsigned long flags;
int err = -EINVAL;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (data->rts.disabled) {
bcm->rts_threshold = BCM43xx_MAX_RTS_THRESHOLD;
err = 0;
@@ -361,7 +363,8 @@ static int bcm43xx_wx_set_rts(struct net
err = 0;
}
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return err;
}
@@ -372,13 +375,12 @@ static int bcm43xx_wx_get_rts(struct net
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
-
- bcm43xx_lock_irqsafe(bcm, flags);
+
+ mutex_lock(&bcm->mutex);
data->rts.value = bcm->rts_threshold;
data->rts.fixed = 0;
data->rts.disabled = (bcm->rts_threshold == BCM43xx_MAX_RTS_THRESHOLD);
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -392,7 +394,8 @@ static int bcm43xx_wx_set_frag(struct ne
unsigned long flags;
int err = -EINVAL;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (data->frag.disabled) {
bcm->ieee->fts = MAX_FRAG_THRESHOLD;
err = 0;
@@ -403,7 +406,8 @@ static int bcm43xx_wx_set_frag(struct ne
err = 0;
}
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return err;
}
@@ -414,13 +418,12 @@ static int bcm43xx_wx_get_frag(struct ne
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
-
- bcm43xx_lock_irqsafe(bcm, flags);
+
+ mutex_lock(&bcm->mutex);
data->frag.value = bcm->ieee->fts;
data->frag.fixed = 0;
data->frag.disabled = (bcm->ieee->fts == MAX_FRAG_THRESHOLD);
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -442,7 +445,8 @@ static int bcm43xx_wx_set_xmitpower(stru
return -EOPNOTSUPP;
}
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
goto out_unlock;
radio = bcm43xx_current_radio(bcm);
@@ -466,7 +470,8 @@ static int bcm43xx_wx_set_xmitpower(stru
err = 0;
out_unlock:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return err;
}
@@ -478,10 +483,9 @@ static int bcm43xx_wx_get_xmitpower(stru
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
struct bcm43xx_radioinfo *radio;
- unsigned long flags;
int err = -ENODEV;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
if (bcm43xx_status(bcm) != BCM43xx_STAT_INITIALIZED)
goto out_unlock;
radio = bcm43xx_current_radio(bcm);
@@ -493,7 +497,7 @@ static int bcm43xx_wx_get_xmitpower(stru
err = 0;
out_unlock:
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
return err;
}
@@ -580,7 +584,8 @@ static int bcm43xx_wx_set_interfmode(str
return -EINVAL;
}
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED) {
err = bcm43xx_radio_set_interference_mitigation(bcm, mode);
if (err) {
@@ -595,7 +600,8 @@ static int bcm43xx_wx_set_interfmode(str
} else
bcm43xx_current_radio(bcm)->interfmode = mode;
}
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return err;
}
@@ -606,12 +612,11 @@ static int bcm43xx_wx_get_interfmode(str
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
int mode;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
mode = bcm43xx_current_radio(bcm)->interfmode;
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
switch (mode) {
case BCM43xx_RADIO_INTERFMODE_NONE:
@@ -641,9 +646,11 @@ static int bcm43xx_wx_set_shortpreamble(
int on;
on = *((int *)extra);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
bcm->short_preamble = !!on;
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -654,12 +661,11 @@ static int bcm43xx_wx_get_shortpreamble(
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
int on;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
on = bcm->short_preamble;
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
if (on)
strncpy(extra, "1 (Short Preamble enabled)", MAX_WX_STRING);
@@ -681,11 +687,13 @@ static int bcm43xx_wx_set_swencryption(s
on = *((int *)extra);
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
bcm->ieee->host_encrypt = !!on;
bcm->ieee->host_decrypt = !!on;
bcm->ieee->host_build_iv = !on;
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
return 0;
}
@@ -696,12 +704,11 @@ static int bcm43xx_wx_get_swencryption(s
char *extra)
{
struct bcm43xx_private *bcm = bcm43xx_priv(net_dev);
- unsigned long flags;
int on;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
on = bcm->ieee->host_encrypt;
- bcm43xx_unlock_irqsafe(bcm, flags);
+ mutex_unlock(&bcm->mutex);
if (on)
strncpy(extra, "1 (SW encryption enabled) ", MAX_WX_STRING);
@@ -764,11 +771,13 @@ static int bcm43xx_wx_sprom_read(struct
if (!sprom)
goto out;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
err = -ENODEV;
if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
err = bcm43xx_sprom_read(bcm, sprom);
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
if (!err)
data->data.length = sprom2hex(sprom, extra);
kfree(sprom);
@@ -809,11 +818,15 @@ static int bcm43xx_wx_sprom_write(struct
if (err)
goto out_kfree;
- bcm43xx_lock_irqsafe(bcm, flags);
+ mutex_lock(&bcm->mutex);
+ spin_lock_irqsave(&bcm->irq_lock, flags);
+ spin_lock(&bcm->leds_lock);
err = -ENODEV;
if (bcm43xx_status(bcm) == BCM43xx_STAT_INITIALIZED)
err = bcm43xx_sprom_write(bcm, sprom);
- bcm43xx_unlock_irqsafe(bcm, flags);
+ spin_unlock(&bcm->leds_lock);
+ spin_unlock_irqrestore(&bcm->irq_lock, flags);
+ mutex_unlock(&bcm->mutex);
out_kfree:
kfree(sprom);
out:
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/bcm43xx/bcm43xx_xmit.h
--- a/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h Tue Oct 02 09:52:15
2007 +0100
+++ b/drivers/net/wireless/bcm43xx/bcm43xx_xmit.h Wed Oct 03 10:00:44
2007 +0100
@@ -137,14 +137,8 @@ struct bcm43xx_xmitstatus {
u16 unknown; //FIXME
};
-#define BCM43xx_TXSTAT_FLAG_ACK 0x01
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x02
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x04
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x08
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x10
-#define BCM43xx_TXSTAT_FLAG_IGNORE 0x20
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x40
-//TODO #define BCM43xx_TXSTAT_FLAG_??? 0x80
+#define BCM43xx_TXSTAT_FLAG_AMPDU 0x10
+#define BCM43xx_TXSTAT_FLAG_INTER 0x20
u8 bcm43xx_plcp_get_ratecode_cck(const u8 bitrate);
u8 bcm43xx_plcp_get_ratecode_ofdm(const u8 bitrate);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/net/wireless/zd1211rw/zd_chip.c
--- a/drivers/net/wireless/zd1211rw/zd_chip.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/net/wireless/zd1211rw/zd_chip.c Wed Oct 03 10:00:44 2007 +0100
@@ -717,7 +717,7 @@ static int zd1211b_hw_reset_phy(struct z
{ CR21, 0x0e }, { CR22, 0x23 }, { CR23, 0x90 },
{ CR24, 0x14 }, { CR25, 0x40 }, { CR26, 0x10 },
{ CR27, 0x10 }, { CR28, 0x7f }, { CR29, 0x80 },
- { CR30, 0x49 }, /* jointly decoder, no ASIC */
+ { CR30, 0x4b }, /* ASIC/FWT, no jointly decoder */
{ CR31, 0x60 }, { CR32, 0x43 }, { CR33, 0x08 },
{ CR34, 0x06 }, { CR35, 0x0a }, { CR36, 0x00 },
{ CR37, 0x00 }, { CR38, 0x38 }, { CR39, 0x0c },
diff -r aafef975e518 -r 3e8752eb6d9c drivers/pci/pci-sysfs.c
--- a/drivers/pci/pci-sysfs.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/pci/pci-sysfs.c Wed Oct 03 10:00:44 2007 +0100
@@ -571,6 +571,9 @@ int pci_create_sysfs_dev_files (struct p
*/
void pci_remove_sysfs_dev_files(struct pci_dev *pdev)
{
+ if (!sysfs_initialized)
+ return;
+
if (pdev->cfg_size < 4096)
sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr);
else
diff -r aafef975e518 -r 3e8752eb6d9c drivers/pci/quirks.c
--- a/drivers/pci/quirks.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/pci/quirks.c Wed Oct 03 10:00:44 2007 +0100
@@ -684,33 +684,6 @@ static void __devinit quirk_vt82c598_id(
pci_read_config_word(dev, PCI_DEVICE_ID, &dev->device);
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0,
quirk_vt82c598_id );
-
-#ifdef CONFIG_ACPI_SLEEP
-
-/*
- * Some VIA systems boot with the abnormal status flag set. This can cause
- * the BIOS to re-POST the system on resume rather than passing control
- * back to the OS. Clear the flag on boot
- */
-static void __devinit quirk_via_abnormal_poweroff(struct pci_dev *dev)
-{
- u32 reg;
-
- acpi_hw_register_read(ACPI_MTX_DO_NOT_LOCK, ACPI_REGISTER_PM1_STATUS,
- ®);
-
- if (reg & 0x800) {
- printk("Clearing abnormal poweroff flag\n");
- acpi_hw_register_write(ACPI_MTX_DO_NOT_LOCK,
- ACPI_REGISTER_PM1_STATUS,
- (u16)0x800);
- }
-}
-
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235,
quirk_via_abnormal_poweroff);
-DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237,
quirk_via_abnormal_poweroff);
-
-#endif
/*
* CardBus controllers have a legacy base address that enables them
diff -r aafef975e518 -r 3e8752eb6d9c drivers/pcmcia/ds.c
--- a/drivers/pcmcia/ds.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/pcmcia/ds.c Wed Oct 03 10:00:44 2007 +0100
@@ -1264,6 +1264,11 @@ static void pcmcia_bus_remove_socket(str
socket->pcmcia_state.dead = 1;
pccard_register_pcmcia(socket, NULL);
+ /* unregister any unbound devices */
+ mutex_lock(&socket->skt_mutex);
+ pcmcia_card_remove(socket, NULL);
+ mutex_unlock(&socket->skt_mutex);
+
pcmcia_put_socket(socket);
return;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/rtc/rtc-max6902.c
--- a/drivers/rtc/rtc-max6902.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/rtc/rtc-max6902.c Wed Oct 03 10:00:44 2007 +0100
@@ -137,7 +137,7 @@ static int max6902_get_datetime(struct d
dt->tm_min = BCD2BIN(chip->buf[2]);
dt->tm_hour = BCD2BIN(chip->buf[3]);
dt->tm_mday = BCD2BIN(chip->buf[4]);
- dt->tm_mon = BCD2BIN(chip->buf[5] - 1);
+ dt->tm_mon = BCD2BIN(chip->buf[5]) - 1;
dt->tm_wday = BCD2BIN(chip->buf[6]);
dt->tm_year = BCD2BIN(chip->buf[7]);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/rtc/rtc-pcf8563.c
--- a/drivers/rtc/rtc-pcf8563.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/rtc/rtc-pcf8563.c Wed Oct 03 10:00:44 2007 +0100
@@ -95,7 +95,7 @@ static int pcf8563_get_datetime(struct i
tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
tm->tm_mon = BCD2BIN(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
tm->tm_year = BCD2BIN(buf[PCF8563_REG_YR])
- + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 100 : 0);
+ + (buf[PCF8563_REG_MO] & PCF8563_MO_C ? 0 : 100);
dev_dbg(&client->dev, "%s: tm is secs=%d, mins=%d, hours=%d, "
"mday=%d, mon=%d, year=%d, wday=%d\n",
@@ -135,7 +135,7 @@ static int pcf8563_set_datetime(struct i
/* year and century */
buf[PCF8563_REG_YR] = BIN2BCD(tm->tm_year % 100);
- if (tm->tm_year / 100)
+ if (tm->tm_year < 100)
buf[PCF8563_REG_MO] |= PCF8563_MO_C;
buf[PCF8563_REG_DW] = tm->tm_wday & 0x07;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c Wed Oct 03 10:00:44 2007 +0100
@@ -2539,15 +2539,28 @@ static void ahc_linux_get_signalling(str
static void ahc_linux_get_signalling(struct Scsi_Host *shost)
{
struct ahc_softc *ahc = *(struct ahc_softc **)shost->hostdata;
- u8 mode = ahc_inb(ahc, SBLKCTL);
-
- if (mode & ENAB40)
- spi_signalling(shost) = SPI_SIGNAL_LVD;
- else if (mode & ENAB20)
+ unsigned long flags;
+ u8 mode;
+
+ if (!(ahc->features & AHC_ULTRA2)) {
+ /* non-LVD chipset, may not have SBLKCTL reg */
spi_signalling(shost) =
ahc->features & AHC_HVD ?
SPI_SIGNAL_HVD :
SPI_SIGNAL_SE;
+ return;
+ }
+
+ ahc_lock(ahc, &flags);
+ ahc_pause(ahc);
+ mode = ahc_inb(ahc, SBLKCTL);
+ ahc_unpause(ahc);
+ ahc_unlock(ahc, &flags);
+
+ if (mode & ENAB40)
+ spi_signalling(shost) = SPI_SIGNAL_LVD;
+ else if (mode & ENAB20)
+ spi_signalling(shost) = SPI_SIGNAL_SE;
else
spi_signalling(shost) = SPI_SIGNAL_UNKNOWN;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/scsi/sata_mv.c
--- a/drivers/scsi/sata_mv.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/scsi/sata_mv.c Wed Oct 03 10:00:44 2007 +0100
@@ -463,6 +463,7 @@ static const struct ata_port_operations
.qc_prep = mv_qc_prep_iie,
.qc_issue = mv_qc_issue,
+ .data_xfer = ata_mmio_data_xfer,
.eng_timeout = mv_eng_timeout,
diff -r aafef975e518 -r 3e8752eb6d9c drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/scsi/scsi_lib.c Wed Oct 03 10:00:44 2007 +0100
@@ -191,6 +191,7 @@ int scsi_execute(struct scsi_device *sde
goto out;
req->cmd_len = COMMAND_SIZE(cmd[0]);
+ memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
memcpy(req->cmd, cmd, req->cmd_len);
req->sense = sense;
req->sense_len = 0;
@@ -408,6 +409,7 @@ int scsi_execute_async(struct scsi_devic
goto free_req;
req->cmd_len = cmd_len;
+ memset(req->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
memcpy(req->cmd, cmd, req->cmd_len);
req->sense = sioc->sense;
req->sense_len = 0;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/serial/serial_core.c
--- a/drivers/serial/serial_core.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/serial/serial_core.c Wed Oct 03 10:00:44 2007 +0100
@@ -1932,6 +1932,9 @@ int uart_suspend_port(struct uart_driver
if (state->info && state->info->flags & UIF_INITIALIZED) {
const struct uart_ops *ops = port->ops;
+ state->info->flags = (state->info->flags & ~UIF_INITIALIZED)
+ | UIF_SUSPENDED;
+
spin_lock_irq(&port->lock);
ops->stop_tx(port);
ops->set_mctrl(port, 0);
@@ -1991,7 +1994,7 @@ int uart_resume_port(struct uart_driver
console_start(port->cons);
}
- if (state->info && state->info->flags & UIF_INITIALIZED) {
+ if (state->info && state->info->flags & UIF_SUSPENDED) {
const struct uart_ops *ops = port->ops;
int ret;
@@ -2003,15 +2006,17 @@ int uart_resume_port(struct uart_driver
ops->set_mctrl(port, port->mctrl);
ops->start_tx(port);
spin_unlock_irq(&port->lock);
+ state->info->flags |= UIF_INITIALIZED;
} else {
/*
* Failed to resume - maybe hardware went away?
* Clear the "initialized" flag so we won't try
* to call the low level drivers shutdown method.
*/
- state->info->flags &= ~UIF_INITIALIZED;
uart_shutdown(state);
}
+
+ state->info->flags &= ~UIF_SUSPENDED;
}
mutex_unlock(&state->mutex);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/serial/serial_cs.c
--- a/drivers/serial/serial_cs.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/serial/serial_cs.c Wed Oct 03 10:00:44 2007 +0100
@@ -185,14 +185,12 @@ static int serial_suspend(struct pcmcia_
static int serial_resume(struct pcmcia_device *link)
{
- if (pcmcia_dev_present(link)) {
- struct serial_info *info = link->priv;
- int i;
-
- for (i = 0; i < info->ndev; i++)
- serial8250_resume_port(info->line[i]);
- wakeup_card(info);
- }
+ struct serial_info *info = link->priv;
+ int i;
+
+ for (i = 0; i < info->ndev; i++)
+ serial8250_resume_port(info->line[i]);
+ wakeup_card(info);
return 0;
}
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/class/usblp.c Wed Oct 03 10:00:44 2007 +0100
@@ -701,6 +701,7 @@ static ssize_t usblp_write(struct file *
usblp->wcomplete = 0;
err = usb_submit_urb(usblp->writeurb, GFP_KERNEL);
if (err) {
+ usblp->wcomplete = 1;
if (err != -ENOMEM)
count = -EIO;
else
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/core/devio.c
--- a/drivers/usb/core/devio.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/core/devio.c Wed Oct 03 10:00:44 2007 +0100
@@ -59,6 +59,9 @@
#define USB_DEVICE_MAX USB_MAXBUS * 128
static struct class *usb_device_class;
+/* Mutual exclusion for removal, open, and release */
+DEFINE_MUTEX(usbfs_mutex);
+
struct async {
struct list_head asynclist;
struct dev_state *ps;
@@ -541,15 +544,13 @@ static int usbdev_open(struct inode *ino
struct dev_state *ps;
int ret;
- /*
- * no locking necessary here, as chrdev_open has the kernel lock
- * (still acquire the kernel lock for safety)
- */
+ /* Protect against simultaneous removal or release */
+ mutex_lock(&usbfs_mutex);
+
ret = -ENOMEM;
if (!(ps = kmalloc(sizeof(struct dev_state), GFP_KERNEL)))
- goto out_nolock;
-
- lock_kernel();
+ goto out;
+
ret = -ENOENT;
/* check if we are called from a real node or usbfs */
if (imajor(inode) == USB_DEVICE_MAJOR)
@@ -579,9 +580,8 @@ static int usbdev_open(struct inode *ino
list_add_tail(&ps->list, &dev->filelist);
file->private_data = ps;
out:
- unlock_kernel();
- out_nolock:
- return ret;
+ mutex_unlock(&usbfs_mutex);
+ return ret;
}
static int usbdev_release(struct inode *inode, struct file *file)
@@ -591,7 +591,12 @@ static int usbdev_release(struct inode *
unsigned int ifnum;
usb_lock_device(dev);
+
+ /* Protect against simultaneous open */
+ mutex_lock(&usbfs_mutex);
list_del_init(&ps->list);
+ mutex_unlock(&usbfs_mutex);
+
for (ifnum = 0; ps->ifclaimed && ifnum < 8*sizeof(ps->ifclaimed);
ifnum++) {
if (test_bit(ifnum, &ps->ifclaimed))
@@ -600,9 +605,8 @@ static int usbdev_release(struct inode *
destroy_all_async(ps);
usb_unlock_device(dev);
usb_put_dev(dev);
- ps->dev = NULL;
kfree(ps);
- return 0;
+ return 0;
}
static int proc_control(struct dev_state *ps, void __user *arg)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/core/notify.c
--- a/drivers/usb/core/notify.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/core/notify.c Wed Oct 03 10:00:44 2007 +0100
@@ -50,8 +50,11 @@ void usb_notify_add_device(struct usb_de
void usb_notify_remove_device(struct usb_device *udev)
{
+ /* Protect against simultaneous usbfs open */
+ mutex_lock(&usbfs_mutex);
blocking_notifier_call_chain(&usb_notifier_list,
USB_DEVICE_REMOVE, udev);
+ mutex_unlock(&usbfs_mutex);
}
void usb_notify_add_bus(struct usb_bus *ubus)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/core/usb.h
--- a/drivers/usb/core/usb.h Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/core/usb.h Wed Oct 03 10:00:44 2007 +0100
@@ -59,6 +59,7 @@ extern const char *usbcore_name;
extern const char *usbcore_name;
/* usbfs stuff */
+extern struct mutex usbfs_mutex;
extern struct usb_driver usbfs_driver;
extern struct file_operations usbfs_devices_fops;
extern struct file_operations usbfs_device_file_operations;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/gadget/ether.c
--- a/drivers/usb/gadget/ether.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/gadget/ether.c Wed Oct 03 10:00:44 2007 +0100
@@ -262,7 +262,7 @@ MODULE_PARM_DESC(host_addr, "Host Ethern
#define DEV_CONFIG_CDC
#endif
-#ifdef CONFIG_USB_GADGET_MUSBHDRC
+#ifdef CONFIG_USB_GADGET_MUSB_HDRC
#define DEV_CONFIG_CDC
#endif
@@ -2564,7 +2564,7 @@ static struct usb_gadget_driver eth_driv
.function = (char *) driver_desc,
.bind = eth_bind,
- .unbind = __exit_p(eth_unbind),
+ .unbind = eth_unbind,
.setup = eth_setup,
.disconnect = eth_disconnect,
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/input/hid-core.c Wed Oct 03 10:00:44 2007 +0100
@@ -1734,10 +1734,10 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_APPLE, 0x020E, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x020F, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x0214, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x0215, HID_QUIRK_POWERBOOK_HAS_FN |
HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
{ USB_VENDOR_ID_APPLE, 0x0216, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x0217, HID_QUIRK_POWERBOOK_HAS_FN },
- { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN },
+ { USB_VENDOR_ID_APPLE, 0x0218, HID_QUIRK_POWERBOOK_HAS_FN |
HID_QUIRK_POWERBOOK_ISO_KEYBOARD},
{ USB_VENDOR_ID_APPLE, 0x0219, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x030A, HID_QUIRK_POWERBOOK_HAS_FN },
{ USB_VENDOR_ID_APPLE, 0x030B, HID_QUIRK_POWERBOOK_HAS_FN },
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/input/hid-input.c
--- a/drivers/usb/input/hid-input.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/input/hid-input.c Wed Oct 03 10:00:44 2007 +0100
@@ -123,6 +123,12 @@ static struct hidinput_key_translation p
{ }
};
+static struct hidinput_key_translation powerbook_iso_keyboard[] = {
+ { KEY_GRAVE, KEY_102ND },
+ { KEY_102ND, KEY_GRAVE },
+ { }
+};
+
static int usbhid_pb_fnmode = 1;
module_param_named(pb_fnmode, usbhid_pb_fnmode, int, 0644);
MODULE_PARM_DESC(pb_fnmode,
@@ -197,6 +203,14 @@ static int hidinput_pb_event(struct hid_
}
}
+ if (hid->quirks & HID_QUIRK_POWERBOOK_ISO_KEYBOARD) {
+ trans = find_translation(powerbook_iso_keyboard, usage->code);
+ if (trans) {
+ input_event(input, usage->type, trans->to, value);
+ return 1;
+ }
+ }
+
return 0;
}
@@ -211,6 +225,9 @@ static void hidinput_pb_setup(struct inp
set_bit(trans->to, input->keybit);
for (trans = powerbook_numlock_keys; trans->from; trans++)
+ set_bit(trans->to, input->keybit);
+
+ for (trans = powerbook_iso_keyboard; trans->from; trans++)
set_bit(trans->to, input->keybit);
}
#else
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/input/hid.h
--- a/drivers/usb/input/hid.h Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/input/hid.h Wed Oct 03 10:00:44 2007 +0100
@@ -260,6 +260,7 @@ struct hid_item {
#define HID_QUIRK_POWERBOOK_HAS_FN 0x00001000
#define HID_QUIRK_POWERBOOK_FN_ON 0x00002000
#define HID_QUIRK_INVERT_HWHEEL 0x00004000
+#define HID_QUIRK_POWERBOOK_ISO_KEYBOARD 0x00010000
/*
* This is the global environment of the parser. This information is
diff -r aafef975e518 -r 3e8752eb6d9c drivers/usb/input/usbtouchscreen.c
--- a/drivers/usb/input/usbtouchscreen.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/usb/input/usbtouchscreen.c Wed Oct 03 10:00:44 2007 +0100
@@ -522,7 +522,7 @@ static int usbtouch_probe(struct usb_int
type->max_press, 0, 0);
usb_fill_int_urb(usbtouch->irq, usbtouch->udev,
- usb_rcvintpipe(usbtouch->udev, 0x81),
+ usb_rcvintpipe(usbtouch->udev,
endpoint->bEndpointAddress),
usbtouch->data, type->rept_size,
usbtouch_irq, usbtouch, endpoint->bInterval);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/fbmem.c
--- a/drivers/video/fbmem.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/fbmem.c Wed Oct 03 10:00:44 2007 +0100
@@ -554,7 +554,8 @@ static int fbmem_read_proc(char *buf, ch
int clen;
clen = 0;
- for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && len < 4000;
fi++)
+ for (fi = registered_fb; fi < ®istered_fb[FB_MAX] && clen < 4000;
+ fi++)
if (*fi)
clen += sprintf(buf + clen, "%d %s\n",
(*fi)->node,
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/fbsysfs.c
--- a/drivers/video/fbsysfs.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/fbsysfs.c Wed Oct 03 10:00:44 2007 +0100
@@ -396,6 +396,12 @@ static ssize_t store_bl_curve(struct cla
struct fb_info *fb_info = class_get_devdata(class_device);
u8 tmp_curve[FB_BACKLIGHT_LEVELS];
unsigned int i;
+
+ /* Some drivers don't use framebuffer_alloc(), but those also
+ * don't have backlights.
+ */
+ if (!fb_info || !fb_info->bl_dev)
+ return -ENODEV;
if (count != (FB_BACKLIGHT_LEVELS / 8 * 24))
return -EINVAL;
@@ -429,6 +435,12 @@ static ssize_t show_bl_curve(struct clas
struct fb_info *fb_info = class_get_devdata(class_device);
ssize_t len = 0;
unsigned int i;
+
+ /* Some drivers don't use framebuffer_alloc(), but those also
+ * don't have backlights.
+ */
+ if (!fb_info || !fb_info->bl_dev)
+ return -ENODEV;
mutex_lock(&fb_info->bl_mutex);
for (i = 0; i < FB_BACKLIGHT_LEVELS; i += 8)
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/nvidia/nv_hw.c
--- a/drivers/video/nvidia/nv_hw.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/nvidia/nv_hw.c Wed Oct 03 10:00:44 2007 +0100
@@ -145,12 +145,18 @@ static void nvGetClocks(struct nvidia_pa
if (par->Architecture >= NV_ARCH_40) {
pll = NV_RD32(par->PMC, 0x4020);
- P = (pll >> 16) & 0x03;
+ P = (pll >> 16) & 0x07;
pll = NV_RD32(par->PMC, 0x4024);
M = pll & 0xFF;
N = (pll >> 8) & 0xFF;
- MB = (pll >> 16) & 0xFF;
- NB = (pll >> 24) & 0xFF;
+ if (((par->Chipset & 0xfff0) == 0x0290) ||
+ ((par->Chipset & 0xfff0) == 0x0390)) {
+ MB = 1;
+ NB = 1;
+ } else {
+ MB = (pll >> 16) & 0xFF;
+ NB = (pll >> 24) & 0xFF;
+ }
*MClk = ((N * NB * par->CrystalFreqKHz) / (M * MB)) >> P;
pll = NV_RD32(par->PMC, 0x4000);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/nvidia/nv_setup.c
--- a/drivers/video/nvidia/nv_setup.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/nvidia/nv_setup.c Wed Oct 03 10:00:44 2007 +0100
@@ -359,6 +359,7 @@ int NVCommonSetup(struct fb_info *info)
case 0x0186:
case 0x0187:
case 0x018D:
+ case 0x0228:
case 0x0286:
case 0x028C:
case 0x0316:
@@ -382,6 +383,10 @@ int NVCommonSetup(struct fb_info *info)
case 0x034C:
case 0x0160:
case 0x0166:
+ case 0x0169:
+ case 0x016B:
+ case 0x016C:
+ case 0x016D:
case 0x00C8:
case 0x00CC:
case 0x0144:
@@ -639,11 +644,22 @@ int NVCommonSetup(struct fb_info *info)
par->fpHeight = NV_RD32(par->PRAMDAC, 0x0800) + 1;
par->fpSyncs = NV_RD32(par->PRAMDAC, 0x0848) & 0x30000033;
- printk("Panel size is %i x %i\n", par->fpWidth, par->fpHeight);
+ printk("nvidiafb: Panel size is %i x %i\n", par->fpWidth,
par->fpHeight);
}
if (monA)
info->monspecs = *monA;
+
+ if (!par->FlatPanel || !par->twoHeads)
+ par->FPDither = 0;
+
+ par->LVDS = 0;
+ if (par->FlatPanel && par->twoHeads) {
+ NV_WR32(par->PRAMDAC0, 0x08B0, 0x00010004);
+ if (par->PRAMDAC0[0x08b4] & 1)
+ par->LVDS = 1;
+ printk("nvidiafb: Panel is %s\n", par->LVDS ? "LVDS" : "TMDS");
+ }
kfree(edidA);
kfree(edidB);
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/nvidia/nv_type.h
--- a/drivers/video/nvidia/nv_type.h Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/nvidia/nv_type.h Wed Oct 03 10:00:44 2007 +0100
@@ -129,6 +129,7 @@ struct nvidia_par {
int fpHeight;
int PanelTweak;
int paneltweak;
+ int LVDS;
int pm_state;
u32 crtcSync_read;
u32 fpSyncs;
diff -r aafef975e518 -r 3e8752eb6d9c drivers/video/nvidia/nvidia.c
--- a/drivers/video/nvidia/nvidia.c Tue Oct 02 09:52:15 2007 +0100
+++ b/drivers/video/nvidia/nvidia.c Wed Oct 03 10:00:44 2007 +0100
@@ -1145,20 +1145,20 @@ static u32 __devinit nvidia_get_arch(str
case 0x0340: /* GeForceFX 5700 */
arch = NV_ARCH_30;
break;
- case 0x0040:
- case 0x00C0:
- case 0x0120:
+ case 0x0040: /* GeForce 6800 */
+ case 0x00C0: /* GeForce 6800 */
+ case 0x0120: /* GeForce 6800 */
case 0x0130:
- case 0x0140:
- case 0x0160:
- case 0x01D0:
- case 0x0090:
- case 0x0210:
- case 0x0220:
+ case 0x0140: /* GeForce 6600 */
+ case 0x0160: /* GeForce 6200 */
+ case 0x01D0: /* GeForce 7200, 7300, 7400 */
+ case 0x0090: /* GeForce 7800 */
+ case 0x0210: /* GeForce 6800 */
+ case 0x0220: /* GeForce 6200 */
case 0x0230:
- case 0x0240:
- case 0x0290:
- case 0x0390:
+ case 0x0240: /* GeForce 6100 */
+ case 0x0290: /* GeForce 7900 */
+ case 0x0390: /* GeForce 7600 */
arch = NV_ARCH_40;
break;
case 0x0020: /* TNT, TNT2 */
diff -r aafef975e518 -r 3e8752eb6d9c fs/buffer.c
--- a/fs/buffer.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/buffer.c Wed Oct 03 10:00:44 2007 +0100
@@ -838,7 +838,10 @@ EXPORT_SYMBOL(mark_buffer_dirty_inode);
*/
int __set_page_dirty_buffers(struct page *page)
{
- struct address_space * const mapping = page->mapping;
+ struct address_space * const mapping = page_mapping(page);
+
+ if (unlikely(!mapping))
+ return !TestSetPageDirty(page);
spin_lock(&mapping->private_lock);
if (page_has_buffers(page)) {
@@ -1176,8 +1179,21 @@ grow_buffers(struct block_device *bdev,
} while ((size << sizebits) < PAGE_SIZE);
index = block >> sizebits;
+
+ /*
+ * Check for a block which wants to lie outside our maximum possible
+ * pagecache index. (this comparison is done using sector_t types).
+ */
+ if (unlikely(index != block >> sizebits)) {
+ char b[BDEVNAME_SIZE];
+
+ printk(KERN_ERR "%s: requested out-of-range block %llu for "
+ "device %s\n",
+ __FUNCTION__, (unsigned long long)block,
+ bdevname(bdev, b));
+ return -EIO;
+ }
block = index << sizebits;
-
/* Create a page with the proper size buffers.. */
page = grow_dev_page(bdev, block, index, size);
if (!page)
@@ -1204,12 +1220,16 @@ __getblk_slow(struct block_device *bdev,
for (;;) {
struct buffer_head * bh;
+ int ret;
bh = __find_get_block(bdev, block, size);
if (bh)
return bh;
- if (!grow_buffers(bdev, block, size))
+ ret = grow_buffers(bdev, block, size);
+ if (ret < 0)
+ return NULL;
+ if (ret == 0)
free_more_memory();
}
}
diff -r aafef975e518 -r 3e8752eb6d9c fs/cifs/CHANGES
--- a/fs/cifs/CHANGES Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/cifs/CHANGES Wed Oct 03 10:00:44 2007 +0100
@@ -6,7 +6,11 @@ on requests on other threads. Improve P
(lock cancel now works, and unlock of merged range works even
to Windows servers now). Fix oops on mount to lanman servers
(win9x, os/2 etc.) when null password. Do not send listxattr
-(SMB to query all EAs) if nouser_xattr specified.
+(SMB to query all EAs) if nouser_xattr specified. Return error
+in rename 2nd attempt retry (ie report if rename by handle also
+fails, after rename by path fails, we were not reporting whether
+the retry worked or not).
+
Version 1.44
------------
diff -r aafef975e518 -r 3e8752eb6d9c fs/cifs/file.c
--- a/fs/cifs/file.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/cifs/file.c Wed Oct 03 10:00:44 2007 +0100
@@ -752,6 +752,7 @@ int cifs_lock(struct file *file, int cmd
int stored_rc = 0;
struct cifsLockInfo *li, *tmp;
+ rc = 0;
down(&fid->lock_sem);
list_for_each_entry_safe(li, tmp, &fid->llist, llist) {
if (pfLock->fl_start <= li->offset &&
@@ -766,7 +767,7 @@ int cifs_lock(struct file *file, int cmd
kfree(li);
}
}
- up(&fid->lock_sem);
+ up(&fid->lock_sem);
}
}
diff -r aafef975e518 -r 3e8752eb6d9c fs/cifs/inode.c
--- a/fs/cifs/inode.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/cifs/inode.c Wed Oct 03 10:00:44 2007 +0100
@@ -880,10 +880,14 @@ int cifs_rename(struct inode *source_ino
kmalloc(2 * sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL);
if (info_buf_source != NULL) {
info_buf_target = info_buf_source + 1;
- rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
- info_buf_source, cifs_sb_source->local_nls,
- cifs_sb_source->mnt_cifs_flags &
- CIFS_MOUNT_MAP_SPECIAL_CHR);
+ if (pTcon->ses->capabilities & CAP_UNIX)
+ rc = CIFSSMBUnixQPathInfo(xid, pTcon, fromName,
+ info_buf_source,
+ cifs_sb_source->local_nls,
+ cifs_sb_source->mnt_cifs_flags &
+ CIFS_MOUNT_MAP_SPECIAL_CHR);
+ /* else rc is still EEXIST so will fall through to
+ unlink the target and retry rename */
if (rc == 0) {
rc = CIFSSMBUnixQPathInfo(xid, pTcon, toName,
info_buf_target,
@@ -932,7 +936,7 @@ int cifs_rename(struct inode *source_ino
cifs_sb_source->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc==0) {
- CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
+ rc = CIFSSMBRenameOpenFile(xid, pTcon, netfid, toName,
cifs_sb_source->local_nls,
cifs_sb_source->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
diff -r aafef975e518 -r 3e8752eb6d9c fs/compat.c
--- a/fs/compat.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/compat.c Wed Oct 03 10:00:44 2007 +0100
@@ -873,7 +873,7 @@ asmlinkage long compat_sys_mount(char __
retval = -EINVAL;
- if (type_page) {
+ if (type_page && data_page) {
if (!strcmp((char *)type_page, SMBFS_NAME)) {
do_smb_super_data_conv((void *)data_page);
} else if (!strcmp((char *)type_page, NCPFS_NAME)) {
diff -r aafef975e518 -r 3e8752eb6d9c fs/ext2/super.c
--- a/fs/ext2/super.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/ext2/super.c Wed Oct 03 10:00:44 2007 +0100
@@ -701,10 +701,14 @@ static int ext2_fill_super(struct super_
set_opt(sbi->s_mount_opt, GRPID);
if (def_mount_opts & EXT2_DEFM_UID16)
set_opt(sbi->s_mount_opt, NO_UID32);
+#ifdef CONFIG_EXT2_FS_XATTR
if (def_mount_opts & EXT2_DEFM_XATTR_USER)
set_opt(sbi->s_mount_opt, XATTR_USER);
+#endif
+#ifdef CONFIG_EXT2_FS_POSIX_ACL
if (def_mount_opts & EXT2_DEFM_ACL)
set_opt(sbi->s_mount_opt, POSIX_ACL);
+#endif
if (le16_to_cpu(sbi->s_es->s_errors) == EXT2_ERRORS_PANIC)
set_opt(sbi->s_mount_opt, ERRORS_PANIC);
diff -r aafef975e518 -r 3e8752eb6d9c fs/ext3/super.c
--- a/fs/ext3/super.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/ext3/super.c Wed Oct 03 10:00:44 2007 +0100
@@ -1451,10 +1451,14 @@ static int ext3_fill_super (struct super
set_opt(sbi->s_mount_opt, GRPID);
if (def_mount_opts & EXT3_DEFM_UID16)
set_opt(sbi->s_mount_opt, NO_UID32);
+#ifdef CONFIG_EXT3_FS_XATTR
if (def_mount_opts & EXT3_DEFM_XATTR_USER)
set_opt(sbi->s_mount_opt, XATTR_USER);
+#endif
+#ifdef CONFIG_EXT3_FS_POSIX_ACL
if (def_mount_opts & EXT3_DEFM_ACL)
set_opt(sbi->s_mount_opt, POSIX_ACL);
+#endif
if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_DATA)
sbi->s_mount_opt |= EXT3_MOUNT_JOURNAL_DATA;
else if ((def_mount_opts & EXT3_DEFM_JMODE) == EXT3_DEFM_JMODE_ORDERED)
diff -r aafef975e518 -r 3e8752eb6d9c fs/fuse/dir.c
--- a/fs/fuse/dir.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/fuse/dir.c Wed Oct 03 10:00:44 2007 +0100
@@ -138,6 +138,7 @@ static int fuse_dentry_revalidate(struct
struct fuse_entry_out outarg;
struct fuse_conn *fc;
struct fuse_req *req;
+ struct fuse_req *forget_req;
/* Doesn't hurt to "reset" the validity timeout */
fuse_invalidate_entry_cache(entry);
@@ -151,21 +152,29 @@ static int fuse_dentry_revalidate(struct
if (IS_ERR(req))
return 0;
+ forget_req = fuse_get_req(fc);
+ if (IS_ERR(forget_req)) {
+ fuse_put_request(fc, req);
+ return 0;
+ }
+
fuse_lookup_init(req, entry->d_parent->d_inode, entry, &outarg);
request_send(fc, req);
err = req->out.h.error;
+ fuse_put_request(fc, req);
/* Zero nodeid is same as -ENOENT */
if (!err && !outarg.nodeid)
err = -ENOENT;
if (!err) {
struct fuse_inode *fi = get_fuse_inode(inode);
if (outarg.nodeid != get_node_id(inode)) {
- fuse_send_forget(fc, req, outarg.nodeid, 1);
+ fuse_send_forget(fc, forget_req,
+ outarg.nodeid, 1);
return 0;
}
fi->nlookup ++;
}
- fuse_put_request(fc, req);
+ fuse_put_request(fc, forget_req);
if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
return 0;
@@ -214,6 +223,7 @@ static struct dentry *fuse_lookup(struct
struct inode *inode = NULL;
struct fuse_conn *fc = get_fuse_conn(dir);
struct fuse_req *req;
+ struct fuse_req *forget_req;
if (entry->d_name.len > FUSE_NAME_MAX)
return ERR_PTR(-ENAMETOOLONG);
@@ -222,9 +232,16 @@ static struct dentry *fuse_lookup(struct
if (IS_ERR(req))
return ERR_PTR(PTR_ERR(req));
+ forget_req = fuse_get_req(fc);
+ if (IS_ERR(forget_req)) {
+ fuse_put_request(fc, req);
+ return ERR_PTR(PTR_ERR(forget_req));
+ }
+
fuse_lookup_init(req, dir, entry, &outarg);
request_send(fc, req);
err = req->out.h.error;
+ fuse_put_request(fc, req);
/* Zero nodeid is same as -ENOENT, but with valid timeout */
if (!err && outarg.nodeid &&
(invalid_nodeid(outarg.nodeid) || !valid_mode(outarg.attr.mode)))
@@ -233,11 +250,11 @@ static struct dentry *fuse_lookup(struct
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
&outarg.attr);
if (!inode) {
- fuse_send_forget(fc, req, outarg.nodeid, 1);
+ fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
return ERR_PTR(-ENOMEM);
}
}
- fuse_put_request(fc, req);
+ fuse_put_request(fc, forget_req);
if (err && err != -ENOENT)
return ERR_PTR(err);
@@ -375,6 +392,13 @@ static int create_new_entry(struct fuse_
struct fuse_entry_out outarg;
struct inode *inode;
int err;
+ struct fuse_req *forget_req;
+
+ forget_req = fuse_get_req(fc);
+ if (IS_ERR(forget_req)) {
+ fuse_put_request(fc, req);
+ return PTR_ERR(forget_req);
+ }
req->in.h.nodeid = get_node_id(dir);
req->out.numargs = 1;
@@ -382,24 +406,24 @@ static int create_new_entry(struct fuse_
req->out.args[0].value = &outarg;
request_send(fc, req);
err = req->out.h.error;
- if (err) {
- fuse_put_request(fc, req);
- return err;
- }
+ fuse_put_request(fc, req);
+ if (err)
+ goto out_put_forget_req;
+
err = -EIO;
if (invalid_nodeid(outarg.nodeid))
- goto out_put_request;
+ goto out_put_forget_req;
if ((outarg.attr.mode ^ mode) & S_IFMT)
- goto out_put_request;
+ goto out_put_forget_req;
inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation,
&outarg.attr);
if (!inode) {
- fuse_send_forget(fc, req, outarg.nodeid, 1);
+ fuse_send_forget(fc, forget_req, outarg.nodeid, 1);
return -ENOMEM;
}
- fuse_put_request(fc, req);
+ fuse_put_request(fc, forget_req);
if (dir_alias(inode)) {
iput(inode);
@@ -411,8 +435,8 @@ static int create_new_entry(struct fuse_
fuse_invalidate_attr(dir);
return 0;
- out_put_request:
- fuse_put_request(fc, req);
+ out_put_forget_req:
+ fuse_put_request(fc, forget_req);
return err;
}
@@ -935,14 +959,30 @@ static void iattr_to_fattr(struct iattr
}
}
+static void fuse_vmtruncate(struct inode *inode, loff_t offset)
+{
+ struct fuse_conn *fc = get_fuse_conn(inode);
+ int need_trunc;
+
+ spin_lock(&fc->lock);
+ need_trunc = inode->i_size > offset;
+ i_size_write(inode, offset);
+ spin_unlock(&fc->lock);
+
+ if (need_trunc) {
+ struct address_space *mapping = inode->i_mapping;
+ unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
+ truncate_inode_pages(mapping, offset);
+ }
+}
+
/*
* Set attributes, and at the same time refresh them.
*
* Truncation is slightly complicated, because the 'truncate' request
* may fail, in which case we don't want to touch the mapping.
- * vmtruncate() doesn't allow for this case. So do the rlimit
- * checking by hand and call vmtruncate() only after the file has
- * actually been truncated.
+ * vmtruncate() doesn't allow for this case, so do the rlimit checking
+ * and the actual truncation by hand.
*/
static int fuse_setattr(struct dentry *entry, struct iattr *attr)
{
@@ -993,12 +1033,8 @@ static int fuse_setattr(struct dentry *e
make_bad_inode(inode);
err = -EIO;
} else {
- if (is_truncate) {
- loff_t origsize = i_size_read(inode);
- i_size_write(inode, outarg.attr.size);
- if (origsize > outarg.attr.size)
- vmtruncate(inode, outarg.attr.size);
- }
+ if (is_truncate)
+ fuse_vmtruncate(inode, outarg.attr.size);
fuse_change_attributes(inode, &outarg.attr);
fi->i_time = time_to_jiffies(outarg.attr_valid,
outarg.attr_valid_nsec);
diff -r aafef975e518 -r 3e8752eb6d9c fs/fuse/file.c
--- a/fs/fuse/file.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/fuse/file.c Wed Oct 03 10:00:44 2007 +0100
@@ -481,8 +481,10 @@ static int fuse_commit_write(struct file
err = -EIO;
if (!err) {
pos += count;
- if (pos > i_size_read(inode))
+ spin_lock(&fc->lock);
+ if (pos > inode->i_size)
i_size_write(inode, pos);
+ spin_unlock(&fc->lock);
if (offset == 0 && to == PAGE_CACHE_SIZE) {
clear_page_dirty(page);
@@ -586,8 +588,12 @@ static ssize_t fuse_direct_io(struct fil
}
fuse_put_request(fc, req);
if (res > 0) {
- if (write && pos > i_size_read(inode))
- i_size_write(inode, pos);
+ if (write) {
+ spin_lock(&fc->lock);
+ if (pos > inode->i_size)
+ i_size_write(inode, pos);
+ spin_unlock(&fc->lock);
+ }
*ppos = pos;
}
fuse_invalidate_attr(inode);
diff -r aafef975e518 -r 3e8752eb6d9c fs/fuse/inode.c
--- a/fs/fuse/inode.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/fuse/inode.c Wed Oct 03 10:00:44 2007 +0100
@@ -109,6 +109,7 @@ static int fuse_remount_fs(struct super_
void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr)
{
+ struct fuse_conn *fc = get_fuse_conn(inode);
if (S_ISREG(inode->i_mode) && i_size_read(inode) != attr->size)
invalidate_inode_pages(inode->i_mapping);
@@ -117,7 +118,9 @@ void fuse_change_attributes(struct inode
inode->i_nlink = attr->nlink;
inode->i_uid = attr->uid;
inode->i_gid = attr->gid;
+ spin_lock(&fc->lock);
i_size_write(inode, attr->size);
+ spin_unlock(&fc->lock);
inode->i_blksize = PAGE_CACHE_SIZE;
inode->i_blocks = attr->blocks;
inode->i_atime.tv_sec = attr->atime;
@@ -131,7 +134,7 @@ static void fuse_init_inode(struct inode
static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr)
{
inode->i_mode = attr->mode & S_IFMT;
- i_size_write(inode, attr->size);
+ inode->i_size = attr->size;
if (S_ISREG(inode->i_mode)) {
fuse_init_common(inode);
fuse_init_file_inode(inode);
diff -r aafef975e518 -r 3e8752eb6d9c fs/hfs/super.c
--- a/fs/hfs/super.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/hfs/super.c Wed Oct 03 10:00:44 2007 +0100
@@ -391,11 +391,13 @@ static int hfs_fill_super(struct super_b
hfs_find_exit(&fd);
goto bail_no_root;
}
+ res = -EINVAL;
root_inode = hfs_iget(sb, &fd.search_key->cat, &rec);
hfs_find_exit(&fd);
if (!root_inode)
goto bail_no_root;
+ res = -ENOMEM;
sb->s_root = d_alloc_root(root_inode);
if (!sb->s_root)
goto bail_iput;
diff -r aafef975e518 -r 3e8752eb6d9c fs/jbd/commit.c
--- a/fs/jbd/commit.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/jbd/commit.c Wed Oct 03 10:00:44 2007 +0100
@@ -158,6 +158,117 @@ static int journal_write_commit_record(j
journal_put_journal_head(descriptor);
return (ret == -EIO);
+}
+
+void journal_do_submit_data(struct buffer_head **wbuf, int bufs)
+{
+ int i;
+
+ for (i = 0; i < bufs; i++) {
+ wbuf[i]->b_end_io = end_buffer_write_sync;
+ /* We use-up our safety reference in submit_bh() */
+ submit_bh(WRITE, wbuf[i]);
+ }
+}
+
+/*
+ * Submit all the data buffers to disk
+ */
+static void journal_submit_data_buffers(journal_t *journal,
+ transaction_t *commit_transaction)
+{
+ struct journal_head *jh;
+ struct buffer_head *bh;
+ int locked;
+ int bufs = 0;
+ struct buffer_head **wbuf = journal->j_wbuf;
+
+ /*
+ * Whenever we unlock the journal and sleep, things can get added
+ * onto ->t_sync_datalist, so we have to keep looping back to
+ * write_out_data until we *know* that the list is empty.
+ *
+ * Cleanup any flushed data buffers from the data list. Even in
+ * abort mode, we want to flush this out as soon as possible.
+ */
+write_out_data:
+ cond_resched();
+ spin_lock(&journal->j_list_lock);
+
+ while (commit_transaction->t_sync_datalist) {
+ jh = commit_transaction->t_sync_datalist;
+ bh = jh2bh(jh);
+ locked = 0;
+
+ /* Get reference just to make sure buffer does not disappear
+ * when we are forced to drop various locks */
+ get_bh(bh);
+ /* If the buffer is dirty, we need to submit IO and hence
+ * we need the buffer lock. We try to lock the buffer without
+ * blocking. If we fail, we need to drop j_list_lock and do
+ * blocking lock_buffer().
+ */
+ if (buffer_dirty(bh)) {
+ if (test_set_buffer_locked(bh)) {
+ BUFFER_TRACE(bh, "needs blocking lock");
+ spin_unlock(&journal->j_list_lock);
+ /* Write out all data to prevent deadlocks */
+ journal_do_submit_data(wbuf, bufs);
+ bufs = 0;
+ lock_buffer(bh);
+ spin_lock(&journal->j_list_lock);
+ }
+ locked = 1;
+ }
+ /* We have to get bh_state lock. Again out of order, sigh. */
+ if (!inverted_lock(journal, bh)) {
+ jbd_lock_bh_state(bh);
+ spin_lock(&journal->j_list_lock);
+ }
+ /* Someone already cleaned up the buffer? */
+ if (!buffer_jbd(bh)
+ || jh->b_transaction != commit_transaction
+ || jh->b_jlist != BJ_SyncData) {
+ jbd_unlock_bh_state(bh);
+ if (locked)
+ unlock_buffer(bh);
+ BUFFER_TRACE(bh, "already cleaned up");
+ put_bh(bh);
+ continue;
+ }
+ if (locked && test_clear_buffer_dirty(bh)) {
+ BUFFER_TRACE(bh, "needs writeout, adding to array");
+ wbuf[bufs++] = bh;
+ __journal_file_buffer(jh, commit_transaction,
+ BJ_Locked);
+ jbd_unlock_bh_state(bh);
+ if (bufs == journal->j_wbufsize) {
+ spin_unlock(&journal->j_list_lock);
+ journal_do_submit_data(wbuf, bufs);
+ bufs = 0;
+ goto write_out_data;
+ }
+ }
+ else {
+ BUFFER_TRACE(bh, "writeout complete: unfile");
+ __journal_unfile_buffer(jh);
+ jbd_unlock_bh_state(bh);
+ if (locked)
+ unlock_buffer(bh);
+ journal_remove_journal_head(bh);
+ /* Once for our safety reference, once for
+ * journal_remove_journal_head() */
+ put_bh(bh);
+ put_bh(bh);
+ }
+
+ if (lock_need_resched(&journal->j_list_lock)) {
+ spin_unlock(&journal->j_list_lock);
+ goto write_out_data;
+ }
+ }
+ spin_unlock(&journal->j_list_lock);
+ journal_do_submit_data(wbuf, bufs);
}
/*
@@ -313,80 +424,13 @@ void journal_commit_transaction(journal_
* Now start flushing things to disk, in the order they appear
* on the transaction lists. Data blocks go first.
*/
-
err = 0;
- /*
- * Whenever we unlock the journal and sleep, things can get added
- * onto ->t_sync_datalist, so we have to keep looping back to
- * write_out_data until we *know* that the list is empty.
- */
- bufs = 0;
- /*
- * Cleanup any flushed data buffers from the data list. Even in
- * abort mode, we want to flush this out as soon as possible.
- */
-write_out_data:
- cond_resched();
+ journal_submit_data_buffers(journal, commit_transaction);
+
+ /*
+ * Wait for all previously submitted IO to complete.
+ */
spin_lock(&journal->j_list_lock);
-
- while (commit_transaction->t_sync_datalist) {
- struct buffer_head *bh;
-
- jh = commit_transaction->t_sync_datalist;
- commit_transaction->t_sync_datalist = jh->b_tnext;
- bh = jh2bh(jh);
- if (buffer_locked(bh)) {
- BUFFER_TRACE(bh, "locked");
- if (!inverted_lock(journal, bh))
- goto write_out_data;
- __journal_temp_unlink_buffer(jh);
- __journal_file_buffer(jh, commit_transaction,
- BJ_Locked);
- jbd_unlock_bh_state(bh);
- if (lock_need_resched(&journal->j_list_lock)) {
- spin_unlock(&journal->j_list_lock);
- goto write_out_data;
- }
- } else {
- if (buffer_dirty(bh)) {
- BUFFER_TRACE(bh, "start journal writeout");
- get_bh(bh);
- wbuf[bufs++] = bh;
- if (bufs == journal->j_wbufsize) {
- jbd_debug(2, "submit %d writes\n",
- bufs);
- spin_unlock(&journal->j_list_lock);
- ll_rw_block(SWRITE, bufs, wbuf);
- journal_brelse_array(wbuf, bufs);
- bufs = 0;
- goto write_out_data;
- }
- } else {
- BUFFER_TRACE(bh, "writeout complete: unfile");
- if (!inverted_lock(journal, bh))
- goto write_out_data;
- __journal_unfile_buffer(jh);
- jbd_unlock_bh_state(bh);
- journal_remove_journal_head(bh);
- put_bh(bh);
- if (lock_need_resched(&journal->j_list_lock)) {
- spin_unlock(&journal->j_list_lock);
- goto write_out_data;
- }
- }
- }
- }
-
- if (bufs) {
- spin_unlock(&journal->j_list_lock);
- ll_rw_block(SWRITE, bufs, wbuf);
- journal_brelse_array(wbuf, bufs);
- spin_lock(&journal->j_list_lock);
- }
-
- /*
- * Wait for all previously submitted IO to complete.
- */
while (commit_transaction->t_locked_list) {
struct buffer_head *bh;
diff -r aafef975e518 -r 3e8752eb6d9c fs/jfs/jfs_imap.c
--- a/fs/jfs/jfs_imap.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/jfs/jfs_imap.c Wed Oct 03 10:00:44 2007 +0100
@@ -318,7 +318,7 @@ int diRead(struct inode *ip)
struct inomap *imap;
int block_offset;
int inodes_left;
- uint pageno;
+ unsigned long pageno;
int rel_inode;
jfs_info("diRead: ino = %ld", ip->i_ino);
@@ -606,7 +606,7 @@ int diWrite(tid_t tid, struct inode *ip)
int block_offset;
int inodes_left;
struct metapage *mp;
- uint pageno;
+ unsigned long pageno;
int rel_inode;
int dioffset;
struct inode *ipimap;
diff -r aafef975e518 -r 3e8752eb6d9c fs/nfs/dir.c
--- a/fs/nfs/dir.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/nfs/dir.c Wed Oct 03 10:00:44 2007 +0100
@@ -902,9 +902,15 @@ static struct dentry *nfs_lookup(struct
lock_kernel();
- /* If we're doing an exclusive create, optimize away the lookup */
- if (nfs_is_exclusive_create(dir, nd))
- goto no_entry;
+ /*
+ * If we're doing an exclusive create, optimize away the lookup
+ * but don't hash the dentry.
+ */
+ if (nfs_is_exclusive_create(dir, nd)) {
+ d_instantiate(dentry, NULL);
+ res = NULL;
+ goto out_unlock;
+ }
error = NFS_PROTO(dir)->lookup(dir, &dentry->d_name, &fhandle, &fattr);
if (error == -ENOENT)
@@ -1156,6 +1162,8 @@ int nfs_instantiate(struct dentry *dentr
if (IS_ERR(inode))
goto out_err;
d_instantiate(dentry, inode);
+ if (d_unhashed(dentry))
+ d_rehash(dentry);
return 0;
out_err:
d_drop(dentry);
diff -r aafef975e518 -r 3e8752eb6d9c fs/nfsd/nfs2acl.c
--- a/fs/nfsd/nfs2acl.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/nfsd/nfs2acl.c Wed Oct 03 10:00:44 2007 +0100
@@ -287,11 +287,18 @@ static int nfsaclsvc_release_getacl(stru
return 1;
}
-static int nfsaclsvc_release_fhandle(struct svc_rqst *rqstp, u32 *p,
- struct nfsd_fhandle *resp)
+static int nfsaclsvc_release_attrstat(struct svc_rqst *rqstp, u32 *p,
+ struct nfsd_attrstat *resp)
{
fh_put(&resp->fh);
return 1;
+}
+
+static int nfsaclsvc_release_access(struct svc_rqst *rqstp, u32 *p,
+ struct nfsd3_accessres *resp)
+{
+ fh_put(&resp->fh);
+ return 1;
}
#define nfsaclsvc_decode_voidargs NULL
@@ -322,9 +329,9 @@ static struct svc_procedure nfsd_acl_pr
static struct svc_procedure nfsd_acl_procedures2[] = {
PROC(null, void, void, void, RC_NOCACHE, ST),
PROC(getacl, getacl, getacl, getacl, RC_NOCACHE,
ST+1+2*(1+ACL)),
- PROC(setacl, setacl, attrstat, fhandle, RC_NOCACHE, ST+AT),
- PROC(getattr, fhandle, attrstat, fhandle, RC_NOCACHE, ST+AT),
- PROC(access, access, access, fhandle, RC_NOCACHE, ST+AT+1),
+ PROC(setacl, setacl, attrstat, attrstat, RC_NOCACHE, ST+AT),
+ PROC(getattr, fhandle, attrstat, attrstat, RC_NOCACHE, ST+AT),
+ PROC(access, access, access, access, RC_NOCACHE, ST+AT+1),
};
struct svc_version nfsd_acl_version2 = {
diff -r aafef975e518 -r 3e8752eb6d9c fs/splice.c
--- a/fs/splice.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/splice.c Wed Oct 03 10:00:44 2007 +0100
@@ -607,7 +607,7 @@ find_page:
ret = -ENOMEM;
page = page_cache_alloc_cold(mapping);
if (unlikely(!page))
- goto out_nomem;
+ goto out_ret;
/*
* This will also lock the page
@@ -666,7 +666,7 @@ find_page:
if (sd->pos + this_len > isize)
vmtruncate(mapping->host, isize);
- goto out;
+ goto out_ret;
}
if (buf->page != page) {
@@ -698,7 +698,7 @@ out:
out:
page_cache_release(page);
unlock_page(page);
-out_nomem:
+out_ret:
return ret;
}
diff -r aafef975e518 -r 3e8752eb6d9c fs/sysfs/file.c
--- a/fs/sysfs/file.c Tue Oct 02 09:52:15 2007 +0100
+++ b/fs/sysfs/file.c Wed Oct 03 10:00:44 2007 +0100
@@ -483,11 +483,6 @@ int sysfs_update_file(struct kobject * k
(victim->d_parent->d_inode == dir->d_inode)) {
victim->d_inode->i_mtime = CURRENT_TIME;
fsnotify_modify(victim);
-
- /**
- * Drop reference from initial sysfs_get_dentry().
- */
- dput(victim);
res = 0;
} else
d_drop(victim);
diff -r aafef975e518 -r 3e8752eb6d9c include/Kbuild
--- a/include/Kbuild Tue Oct 02 09:52:15 2007 +0100
+++ b/include/Kbuild Wed Oct 03 10:00:44 2007 +0100
@@ -1,2 +1,9 @@ header-y += asm-generic/ linux/ scsi/ so
-header-y += asm-generic/ linux/ scsi/ sound/ mtd/ rdma/ video/
-header-y += asm-$(ARCH)/
+header-y += asm-generic/
+header-y += linux/
+header-y += scsi/
+header-y += sound/
+header-y += mtd/
+header-y += rdma/
+header-y += video/
+
+header-y += asm-$(ARCH)/
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-alpha/Kbuild
--- a/include/asm-alpha/Kbuild Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-alpha/Kbuild Wed Oct 03 10:00:44 2007 +0100
@@ -1,5 +1,11 @@ include include/asm-generic/Kbuild.asm
include include/asm-generic/Kbuild.asm
-unifdef-y += console.h fpu.h sysinfo.h compiler.h
+header-y += gentrap.h
+header-y += regdef.h
+header-y += pal.h
+header-y += reg.h
-header-y += gentrap.h regdef.h pal.h reg.h
+unifdef-y += console.h
+unifdef-y += fpu.h
+unifdef-y += sysinfo.h
+unifdef-y += compiler.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-arm/elf.h
--- a/include/asm-arm/elf.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-arm/elf.h Wed Oct 03 10:00:44 2007 +0100
@@ -8,9 +8,6 @@
#include <asm/ptrace.h>
#include <asm/user.h>
-#ifdef __KERNEL
-#include <asm/procinfo.h>
-#endif
typedef unsigned long elf_greg_t;
typedef unsigned long elf_freg_t[3];
@@ -32,11 +29,6 @@ typedef struct user_fp elf_fpregset_t;
typedef struct user_fp elf_fpregset_t;
/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ( ((x)->e_machine == EM_ARM) && (ELF_PROC_OK((x))) )
-
-/*
* These are used to set parameters in the core dumps.
*/
#define ELF_CLASS ELFCLASS32
@@ -46,6 +38,14 @@ typedef struct user_fp elf_fpregset_t;
#define ELF_DATA ELFDATA2LSB
#endif
#define ELF_ARCH EM_ARM
+
+#ifdef __KERNEL__
+#include <asm/procinfo.h>
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ( ((x)->e_machine == EM_ARM) && (ELF_PROC_OK((x))) )
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
@@ -82,8 +82,6 @@ typedef struct user_fp elf_fpregset_t;
#define ELF_PLATFORM_SIZE 8
extern char elf_platform[];
#define ELF_PLATFORM (elf_platform)
-
-#ifdef __KERNEL__
/*
* 32-bit code is always OK. Some cpus can do 26-bit, some can't.
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-arm/page.h
--- a/include/asm-arm/page.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-arm/page.h Wed Oct 03 10:00:44 2007 +0100
@@ -10,13 +10,13 @@
#ifndef _ASMARM_PAGE_H
#define _ASMARM_PAGE_H
+
+#ifdef __KERNEL__
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT 12
#define PAGE_SIZE (1UL << PAGE_SHIFT)
#define PAGE_MASK (~(PAGE_SIZE-1))
-
-#ifdef __KERNEL__
/* to align the pointer to the (next) page boundary */
#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK)
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-arm/unistd.h
--- a/include/asm-arm/unistd.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-arm/unistd.h Wed Oct 03 10:00:44 2007 +0100
@@ -347,6 +347,19 @@
#define __NR_mbind (__NR_SYSCALL_BASE+319)
#define __NR_get_mempolicy (__NR_SYSCALL_BASE+320)
#define __NR_set_mempolicy (__NR_SYSCALL_BASE+321)
+#define __NR_openat (__NR_SYSCALL_BASE+322)
+#define __NR_mkdirat (__NR_SYSCALL_BASE+323)
+#define __NR_mknodat (__NR_SYSCALL_BASE+324)
+#define __NR_fchownat (__NR_SYSCALL_BASE+325)
+#define __NR_futimesat (__NR_SYSCALL_BASE+326)
+#define __NR_fstatat64 (__NR_SYSCALL_BASE+327)
+#define __NR_unlinkat (__NR_SYSCALL_BASE+328)
+#define __NR_renameat (__NR_SYSCALL_BASE+329)
+#define __NR_linkat (__NR_SYSCALL_BASE+330)
+#define __NR_symlinkat (__NR_SYSCALL_BASE+331)
+#define __NR_readlinkat (__NR_SYSCALL_BASE+332)
+#define __NR_fchmodat (__NR_SYSCALL_BASE+333)
+#define __NR_faccessat (__NR_SYSCALL_BASE+334)
/*
* The following SWIs are ARM private.
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-arm26/Kbuild
--- a/include/asm-arm26/Kbuild Tue Oct 02 09:52:15 2007 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-include include/asm-generic/Kbuild.asm
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/Kbuild
--- a/include/asm-cris/Kbuild Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/Kbuild Wed Oct 03 10:00:44 2007 +0100
@@ -1,1 +1,5 @@ include include/asm-generic/Kbuild.asm
include include/asm-generic/Kbuild.asm
+
+header-y += arch-v10/ arch-v32/
+
+unifdef-y += rs485.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/arch-v10/Kbuild
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/asm-cris/arch-v10/Kbuild Wed Oct 03 10:00:44 2007 +0100
@@ -0,0 +1,2 @@
+header-y += ptrace.h
+header-y += user.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/arch-v32/Kbuild
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/asm-cris/arch-v32/Kbuild Wed Oct 03 10:00:44 2007 +0100
@@ -0,0 +1,2 @@
+header-y += ptrace.h
+header-y += user.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/byteorder.h
--- a/include/asm-cris/byteorder.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/byteorder.h Wed Oct 03 10:00:44 2007 +0100
@@ -3,14 +3,15 @@
#ifdef __GNUC__
+#ifdef __KERNEL__
#include <asm/arch/byteorder.h>
/* defines are necessary because the other files detect the presence
* of a defined __arch_swab32, not an inline
*/
-
#define __arch__swab32(x) ___arch__swab32(x)
#define __arch__swab16(x) ___arch__swab16(x)
+#endif /* __KERNEL__ */
#if !defined(__STRICT_ANSI__) || defined(__KERNEL__)
# define __BYTEORDER_HAS_U64__
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/elf.h
--- a/include/asm-cris/elf.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/elf.h Wed Oct 03 10:00:44 2007 +0100
@@ -5,7 +5,6 @@
* ELF register definitions..
*/
-#include <asm/arch/elf.h>
#include <asm/user.h>
#define R_CRIS_NONE 0
@@ -45,6 +44,9 @@ typedef unsigned long elf_fpregset_t;
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2LSB
#define ELF_ARCH EM_CRIS
+
+#ifdef __KERNEL__
+#include <asm/arch/elf.h>
/* The master for these definitions is {binutils}/include/elf/cris.h: */
/* User symbols in this file have a leading underscore. */
@@ -87,8 +89,8 @@ typedef unsigned long elf_fpregset_t;
#define ELF_PLATFORM (NULL)
-#ifdef __KERNEL__
#define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX)
-#endif
+
+#endif /* __KERNEL__ */
#endif
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/page.h
--- a/include/asm-cris/page.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/page.h Wed Oct 03 10:00:44 2007 +0100
@@ -1,5 +1,7 @@
#ifndef _CRIS_PAGE_H
#define _CRIS_PAGE_H
+
+#ifdef __KERNEL__
#include <asm/arch/page.h>
@@ -11,8 +13,6 @@
#define PAGE_SIZE (1 << PAGE_SHIFT)
#endif
#define PAGE_MASK (~(PAGE_SIZE-1))
-
-#ifdef __KERNEL__
#define clear_page(page) memset((void *)(page), 0, PAGE_SIZE)
#define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE)
@@ -73,10 +73,10 @@ typedef struct { unsigned long pgprot; }
#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \
VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
-#endif /* __KERNEL__ */
-
#include <asm-generic/memory_model.h>
#include <asm-generic/page.h>
+#endif /* __KERNEL__ */
+
#endif /* _CRIS_PAGE_H */
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/posix_types.h
--- a/include/asm-cris/posix_types.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/posix_types.h Wed Oct 03 10:00:44 2007 +0100
@@ -5,8 +5,6 @@
#ifndef __ARCH_CRIS_POSIX_TYPES_H
#define __ARCH_CRIS_POSIX_TYPES_H
-
-#include <asm/bitops.h>
/*
* This file is generally used by user-level software, so you need to
@@ -53,9 +51,8 @@ typedef struct {
#endif /* !defined(__KERNEL__) && !defined(__USE_ALL) */
} __kernel_fsid_t;
-/* should this ifdef be here ? */
-
-#if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
+#ifdef __KERNEL__
+#include <asm/bitops.h>
#undef __FD_SET
#define __FD_SET(fd,fdsetp) set_bit(fd, (void *)(fdsetp))
@@ -69,6 +66,6 @@ typedef struct {
#undef __FD_ZERO
#define __FD_ZERO(fdsetp) memset((void *)(fdsetp), 0, __FDSET_LONGS << 2)
-#endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) */
+#endif /* __KERNEL__ */
#endif /* __ARCH_CRIS_POSIX_TYPES_H */
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-cris/unistd.h
--- a/include/asm-cris/unistd.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-cris/unistd.h Wed Oct 03 10:00:44 2007 +0100
@@ -1,7 +1,5 @@
#ifndef _ASM_CRIS_UNISTD_H_
#define _ASM_CRIS_UNISTD_H_
-
-#include <asm/arch/unistd.h>
/*
* This file contains the system call numbers, and stub macros for libc.
@@ -299,6 +297,7 @@
#define NR_syscalls 289
+#include <asm/arch/unistd.h>
#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
@@ -322,7 +321,6 @@
#define __ARCH_WANT_SYS_SIGPENDING
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-#endif
#ifdef __KERNEL_SYSCALLS__
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-generic/Kbuild
--- a/include/asm-generic/Kbuild Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-generic/Kbuild Wed Oct 03 10:00:44 2007 +0100
@@ -1,3 +1,12 @@ header-y += atomic.h errno-base.h errno.
-header-y += atomic.h errno-base.h errno.h fcntl.h ioctl.h ipc.h mman.h \
- signal.h statfs.h
-unifdef-y := resource.h siginfo.h
+header-y += atomic.h
+header-y += errno-base.h
+header-y += errno.h
+header-y += fcntl.h
+header-y += ioctl.h
+header-y += ipc.h
+header-y += mman.h
+header-y += signal.h
+header-y += statfs.h
+
+unifdef-y += resource.h
+unifdef-y += siginfo.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-generic/Kbuild.asm
--- a/include/asm-generic/Kbuild.asm Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-generic/Kbuild.asm Wed Oct 03 10:00:44 2007 +0100
@@ -1,8 +1,34 @@ unifdef-y += a.out.h auxvec.h byteorder.
-unifdef-y += a.out.h auxvec.h byteorder.h errno.h fcntl.h ioctl.h \
- ioctls.h ipcbuf.h mman.h msgbuf.h param.h poll.h \
- posix_types.h ptrace.h resource.h sembuf.h shmbuf.h shmparam.h \
- sigcontext.h siginfo.h signal.h socket.h sockios.h stat.h \
- statfs.h termbits.h termios.h types.h unistd.h user.h
+unifdef-y += a.out.h
+unifdef-y += auxvec.h
+unifdef-y += byteorder.h
+unifdef-y += errno.h
+unifdef-y += fcntl.h
+unifdef-y += ioctl.h
+unifdef-y += ioctls.h
+unifdef-y += ipcbuf.h
+unifdef-y += mman.h
+unifdef-y += msgbuf.h
+unifdef-y += param.h
+unifdef-y += poll.h
+unifdef-y += posix_types.h
+unifdef-y += ptrace.h
+unifdef-y += resource.h
+unifdef-y += sembuf.h
+unifdef-y += shmbuf.h
+unifdef-y += sigcontext.h
+unifdef-y += siginfo.h
+unifdef-y += signal.h
+unifdef-y += socket.h
+unifdef-y += sockios.h
+unifdef-y += stat.h
+unifdef-y += statfs.h
+unifdef-y += termbits.h
+unifdef-y += termios.h
+unifdef-y += types.h
+unifdef-y += unistd.h
+unifdef-y += user.h
# These probably shouldn't be exported
-unifdef-y += elf.h page.h
+unifdef-y += shmparam.h
+unifdef-y += elf.h
+unifdef-y += page.h
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-generic/audit_change_attr.h
--- a/include/asm-generic/audit_change_attr.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-generic/audit_change_attr.h Wed Oct 03 10:00:44 2007 +0100
@@ -1,16 +1,20 @@ __NR_chmod,
__NR_chmod,
__NR_fchmod,
+#ifdef __NR_chown
__NR_chown,
__NR_fchown,
__NR_lchown,
+#endif
__NR_setxattr,
__NR_lsetxattr,
__NR_fsetxattr,
__NR_removexattr,
__NR_lremovexattr,
__NR_fremovexattr,
+#ifdef __NR_fchownat
__NR_fchownat,
__NR_fchmodat,
+#endif
#ifdef __NR_chown32
__NR_chown32,
__NR_fchown32,
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-generic/audit_dir_write.h
--- a/include/asm-generic/audit_dir_write.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-generic/audit_dir_write.h Wed Oct 03 10:00:44 2007 +0100
@@ -1,14 +1,18 @@ __NR_rename,
__NR_rename,
__NR_mkdir,
__NR_rmdir,
+#ifdef __NR_creat
__NR_creat,
+#endif
__NR_link,
__NR_unlink,
__NR_symlink,
__NR_mknod,
+#ifdef __NR_mkdirat
__NR_mkdirat,
__NR_mknodat,
__NR_unlinkat,
__NR_renameat,
__NR_linkat,
__NR_symlinkat,
+#endif
diff -r aafef975e518 -r 3e8752eb6d9c include/asm-h8300/page.h
--- a/include/asm-h8300/page.h Tue Oct 02 09:52:15 2007 +0100
+++ b/include/asm-h8300/page.h Wed Oct 03 10:00:44 2007 +0100
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|