diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-04-27 04:55:53 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-04-27 04:55:53 -0400 |
commit | 7894eaf291238a62a565e9e9777483beeb00eeae (patch) | |
tree | 43c08830d2030d39d719f3f3d54a0e9b36554770 | |
parent | 9e73972cef1c0961c78b0e0b61c4ecc275b29f04 (diff) | |
parent | acc696d93dcf993dec123d69d599979e1456ffec (diff) |
Merge branch 'upstream' into irq-pio
566 files changed, 13602 insertions, 7288 deletions
diff --git a/Documentation/block/switching-sched.txt b/Documentation/block/switching-sched.txt new file mode 100644 index 000000000000..5fa130a67531 --- /dev/null +++ b/Documentation/block/switching-sched.txt | |||
@@ -0,0 +1,22 @@ | |||
1 | As of the Linux 2.6.10 kernel, it is now possible to change the | ||
2 | IO scheduler for a given block device on the fly (thus making it possible, | ||
3 | for instance, to set the CFQ scheduler for the system default, but | ||
4 | set a specific device to use the anticipatory or noop schedulers - which | ||
5 | can improve that device's throughput). | ||
6 | |||
7 | To set a specific scheduler, simply do this: | ||
8 | |||
9 | echo SCHEDNAME > /sys/block/DEV/queue/scheduler | ||
10 | |||
11 | where SCHEDNAME is the name of a defined IO scheduler, and DEV is the | ||
12 | device name (hda, hdb, sga, or whatever you happen to have). | ||
13 | |||
14 | The list of defined schedulers can be found by simply doing | ||
15 | a "cat /sys/block/DEV/queue/scheduler" - the list of valid names | ||
16 | will be displayed, with the currently selected scheduler in brackets: | ||
17 | |||
18 | # cat /sys/block/hda/queue/scheduler | ||
19 | noop anticipatory deadline [cfq] | ||
20 | # echo anticipatory > /sys/block/hda/queue/scheduler | ||
21 | # cat /sys/block/hda/queue/scheduler | ||
22 | noop [anticipatory] deadline cfq | ||
diff --git a/Documentation/cpu-freq/index.txt b/Documentation/cpu-freq/index.txt index 5009805f9378..ffdb5323df37 100644 --- a/Documentation/cpu-freq/index.txt +++ b/Documentation/cpu-freq/index.txt | |||
@@ -53,4 +53,4 @@ the CPUFreq Mailing list: | |||
53 | * http://lists.linux.org.uk/mailman/listinfo/cpufreq | 53 | * http://lists.linux.org.uk/mailman/listinfo/cpufreq |
54 | 54 | ||
55 | Clock and voltage scaling for the SA-1100: | 55 | Clock and voltage scaling for the SA-1100: |
56 | * http://www.lart.tudelft.nl/projects/scaling | 56 | * http://www.lartmaker.nl/projects/scaling |
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 293fed113dff..421bcfff6ad2 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt | |||
@@ -25,8 +25,9 @@ Who: Adrian Bunk <bunk@stusta.de> | |||
25 | 25 | ||
26 | --------------------------- | 26 | --------------------------- |
27 | 27 | ||
28 | What: drivers depending on OBSOLETE_OSS_DRIVER | 28 | What: drivers that were depending on OBSOLETE_OSS_DRIVER |
29 | When: January 2006 | 29 | (config options already removed) |
30 | When: before 2.6.19 | ||
30 | Why: OSS drivers with ALSA replacements | 31 | Why: OSS drivers with ALSA replacements |
31 | Who: Adrian Bunk <bunk@stusta.de> | 32 | Who: Adrian Bunk <bunk@stusta.de> |
32 | 33 | ||
diff --git a/Documentation/filesystems/sysfs.txt b/Documentation/filesystems/sysfs.txt index c8bce82ddcac..89b1d196ca80 100644 --- a/Documentation/filesystems/sysfs.txt +++ b/Documentation/filesystems/sysfs.txt | |||
@@ -246,6 +246,7 @@ class/ | |||
246 | devices/ | 246 | devices/ |
247 | firmware/ | 247 | firmware/ |
248 | net/ | 248 | net/ |
249 | fs/ | ||
249 | 250 | ||
250 | devices/ contains a filesystem representation of the device tree. It maps | 251 | devices/ contains a filesystem representation of the device tree. It maps |
251 | directly to the internal kernel device tree, which is a hierarchy of | 252 | directly to the internal kernel device tree, which is a hierarchy of |
@@ -264,6 +265,10 @@ drivers/ contains a directory for each device driver that is loaded | |||
264 | for devices on that particular bus (this assumes that drivers do not | 265 | for devices on that particular bus (this assumes that drivers do not |
265 | span multiple bus types). | 266 | span multiple bus types). |
266 | 267 | ||
268 | fs/ contains a directory for some filesystems. Currently each | ||
269 | filesystem wanting to export attributes must create its own hierarchy | ||
270 | below fs/ (see ./fuse.txt for an example). | ||
271 | |||
267 | 272 | ||
268 | More information can driver-model specific features can be found in | 273 | More information can driver-model specific features can be found in |
269 | Documentation/driver-model/. | 274 | Documentation/driver-model/. |
diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt index 2803f63c1a27..687104bfd09a 100644 --- a/Documentation/vm/hugetlbpage.txt +++ b/Documentation/vm/hugetlbpage.txt | |||
@@ -32,7 +32,16 @@ The output of "cat /proc/meminfo" will have lines like: | |||
32 | ..... | 32 | ..... |
33 | HugePages_Total: xxx | 33 | HugePages_Total: xxx |
34 | HugePages_Free: yyy | 34 | HugePages_Free: yyy |
35 | Hugepagesize: zzz KB | 35 | HugePages_Rsvd: www |
36 | Hugepagesize: zzz kB | ||
37 | |||
38 | where: | ||
39 | HugePages_Total is the size of the pool of hugepages. | ||
40 | HugePages_Free is the number of hugepages in the pool that are not yet | ||
41 | allocated. | ||
42 | HugePages_Rsvd is short for "reserved," and is the number of hugepages | ||
43 | for which a commitment to allocate from the pool has been made, but no | ||
44 | allocation has yet been made. It's vaguely analogous to overcommit. | ||
36 | 45 | ||
37 | /proc/filesystems should also show a filesystem of type "hugetlbfs" configured | 46 | /proc/filesystems should also show a filesystem of type "hugetlbfs" configured |
38 | in the kernel. | 47 | in the kernel. |
diff --git a/MAINTAINERS b/MAINTAINERS index 6d3c401ccdb6..d6a8e5b434ec 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -411,6 +411,7 @@ AX.25 NETWORK LAYER | |||
411 | P: Ralf Baechle | 411 | P: Ralf Baechle |
412 | M: ralf@linux-mips.org | 412 | M: ralf@linux-mips.org |
413 | L: linux-hams@vger.kernel.org | 413 | L: linux-hams@vger.kernel.org |
414 | W: http://www.linux-ax25.org/ | ||
414 | S: Maintained | 415 | S: Maintained |
415 | 416 | ||
416 | BAYCOM/HDLCDRV DRIVERS FOR AX.25 | 417 | BAYCOM/HDLCDRV DRIVERS FOR AX.25 |
@@ -420,6 +421,14 @@ L: linux-hams@vger.kernel.org | |||
420 | W: http://www.baycom.org/~tom/ham/ham.html | 421 | W: http://www.baycom.org/~tom/ham/ham.html |
421 | S: Maintained | 422 | S: Maintained |
422 | 423 | ||
424 | BCM43XX WIRELESS DRIVER | ||
425 | P: Michael Buesch | ||
426 | M: mb@bu3sch.de | ||
427 | P: Stefano Brivio | ||
428 | M: st3@riseup.net | ||
429 | W: http://bcm43xx.berlios.de/ | ||
430 | S: Maintained | ||
431 | |||
423 | BEFS FILE SYSTEM | 432 | BEFS FILE SYSTEM |
424 | P: Sergey S. Kostyliov | 433 | P: Sergey S. Kostyliov |
425 | M: rathamahata@php4.ru | 434 | M: rathamahata@php4.ru |
@@ -1457,6 +1466,13 @@ M: support@pathscale.com | |||
1457 | L: openib-general@openib.org | 1466 | L: openib-general@openib.org |
1458 | S: Supported | 1467 | S: Supported |
1459 | 1468 | ||
1469 | IPMI SUBSYSTEM | ||
1470 | P: Corey Minyard | ||
1471 | M: minyard@acm.org | ||
1472 | L: openipmi-developer@lists.sourceforge.net | ||
1473 | W: http://openipmi.sourceforge.net/ | ||
1474 | S: Supported | ||
1475 | |||
1460 | IPX NETWORK LAYER | 1476 | IPX NETWORK LAYER |
1461 | P: Arnaldo Carvalho de Melo | 1477 | P: Arnaldo Carvalho de Melo |
1462 | M: acme@conectiva.com.br | 1478 | M: acme@conectiva.com.br |
@@ -1869,6 +1885,7 @@ NETROM NETWORK LAYER | |||
1869 | P: Ralf Baechle | 1885 | P: Ralf Baechle |
1870 | M: ralf@linux-mips.org | 1886 | M: ralf@linux-mips.org |
1871 | L: linux-hams@vger.kernel.org | 1887 | L: linux-hams@vger.kernel.org |
1888 | W: http://www.linux-ax25.org/ | ||
1872 | S: Maintained | 1889 | S: Maintained |
1873 | 1890 | ||
1874 | NETWORK BLOCK DEVICE | 1891 | NETWORK BLOCK DEVICE |
@@ -2056,8 +2073,12 @@ P: Matthew Wilcox | |||
2056 | M: matthew@wil.cx | 2073 | M: matthew@wil.cx |
2057 | P: Grant Grundler | 2074 | P: Grant Grundler |
2058 | M: grundler@parisc-linux.org | 2075 | M: grundler@parisc-linux.org |
2076 | P: Kyle McMartin | ||
2077 | M: kyle@parisc-linux.org | ||
2059 | L: parisc-linux@parisc-linux.org | 2078 | L: parisc-linux@parisc-linux.org |
2060 | W: http://www.parisc-linux.org/ | 2079 | W: http://www.parisc-linux.org/ |
2080 | T: git kernel.org:/pub/scm/linux/kernel/git/kyle/parisc-2.6.git | ||
2081 | T: cvs cvs.parisc-linux.org:/var/cvs/linux-2.6 | ||
2061 | S: Maintained | 2082 | S: Maintained |
2062 | 2083 | ||
2063 | PCI ERROR RECOVERY | 2084 | PCI ERROR RECOVERY |
@@ -2260,6 +2281,7 @@ ROSE NETWORK LAYER | |||
2260 | P: Ralf Baechle | 2281 | P: Ralf Baechle |
2261 | M: ralf@linux-mips.org | 2282 | M: ralf@linux-mips.org |
2262 | L: linux-hams@vger.kernel.org | 2283 | L: linux-hams@vger.kernel.org |
2284 | W: http://www.linux-ax25.org/ | ||
2263 | S: Maintained | 2285 | S: Maintained |
2264 | 2286 | ||
2265 | RISCOM8 DRIVER | 2287 | RISCOM8 DRIVER |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 2 | 1 | VERSION = 2 |
2 | PATCHLEVEL = 6 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 17 | 3 | SUBLEVEL = 17 |
4 | EXTRAVERSION =-rc1 | 4 | EXTRAVERSION =-rc3 |
5 | NAME=Sliding Snow Leopard | 5 | NAME=Sliding Snow Leopard |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
@@ -165,10 +165,31 @@ CONFIGURING the kernel: | |||
165 | "make xconfig" X windows (Qt) based configuration tool. | 165 | "make xconfig" X windows (Qt) based configuration tool. |
166 | "make gconfig" X windows (Gtk) based configuration tool. | 166 | "make gconfig" X windows (Gtk) based configuration tool. |
167 | "make oldconfig" Default all questions based on the contents of | 167 | "make oldconfig" Default all questions based on the contents of |
168 | your existing ./.config file. | 168 | your existing ./.config file and asking about |
169 | new config symbols. | ||
169 | "make silentoldconfig" | 170 | "make silentoldconfig" |
170 | Like above, but avoids cluttering the screen | 171 | Like above, but avoids cluttering the screen |
171 | with questions already answered. | 172 | with questions already answered. |
173 | "make defconfig" Create a ./.config file by using the default | ||
174 | symbol values from arch/$ARCH/defconfig. | ||
175 | "make allyesconfig" | ||
176 | Create a ./.config file by setting symbol | ||
177 | values to 'y' as much as possible. | ||
178 | "make allmodconfig" | ||
179 | Create a ./.config file by setting symbol | ||
180 | values to 'm' as much as possible. | ||
181 | "make allnoconfig" Create a ./.config file by setting symbol | ||
182 | values to 'n' as much as possible. | ||
183 | "make randconfig" Create a ./.config file by setting symbol | ||
184 | values to random values. | ||
185 | |||
186 | The allyesconfig/allmodconfig/allnoconfig/randconfig variants can | ||
187 | also use the environment variable KCONFIG_ALLCONFIG to specify a | ||
188 | filename that contains config options that the user requires to be | ||
189 | set to a specific value. If KCONFIG_ALLCONFIG=filename is not used, | ||
190 | "make *config" checks for a file named "all{yes/mod/no/random}.config" | ||
191 | for symbol values that are to be forced. If this file is not found, | ||
192 | it checks for a file named "all.config" to contain forced values. | ||
172 | 193 | ||
173 | NOTES on "make config": | 194 | NOTES on "make config": |
174 | - having unnecessary drivers will make the kernel bigger, and can | 195 | - having unnecessary drivers will make the kernel bigger, and can |
diff --git a/arch/alpha/lib/strncpy.S b/arch/alpha/lib/strncpy.S index 338551c7113c..bbdef1be5f95 100644 --- a/arch/alpha/lib/strncpy.S +++ b/arch/alpha/lib/strncpy.S | |||
@@ -43,8 +43,8 @@ strncpy: | |||
43 | 43 | ||
44 | .align 4 | 44 | .align 4 |
45 | $multiword: | 45 | $multiword: |
46 | subq $24, 1, $2 # clear the final bits in the prev word | 46 | subq $27, 1, $2 # clear the final bits in the prev word |
47 | or $2, $24, $2 | 47 | or $2, $27, $2 |
48 | zapnot $1, $2, $1 | 48 | zapnot $1, $2, $1 |
49 | subq $18, 1, $18 | 49 | subq $18, 1, $18 |
50 | 50 | ||
@@ -70,8 +70,8 @@ $multiword: | |||
70 | bne $18, 0b | 70 | bne $18, 0b |
71 | 71 | ||
72 | 1: ldq_u $1, 0($16) # clear the leading bits in the final word | 72 | 1: ldq_u $1, 0($16) # clear the leading bits in the final word |
73 | subq $27, 1, $2 | 73 | subq $24, 1, $2 |
74 | or $2, $27, $2 | 74 | or $2, $24, $2 |
75 | 75 | ||
76 | zap $1, $2, $1 | 76 | zap $1, $2, $1 |
77 | stq_u $1, 0($16) | 77 | stq_u $1, 0($16) |
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 95a96275f88a..6f8e84c1c1f2 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile | |||
@@ -66,7 +66,7 @@ tune-$(CONFIG_CPU_XSC3) :=$(call cc-option,-mtune=xscale,-mtune=strongarm110) - | |||
66 | tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) | 66 | tune-$(CONFIG_CPU_V6) :=$(call cc-option,-mtune=arm1136j-s,-mtune=strongarm) |
67 | 67 | ||
68 | ifeq ($(CONFIG_AEABI),y) | 68 | ifeq ($(CONFIG_AEABI),y) |
69 | CFLAGS_ABI :=-mabi=aapcs -mno-thumb-interwork | 69 | CFLAGS_ABI :=-mabi=aapcs-linux -mno-thumb-interwork |
70 | else | 70 | else |
71 | CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) | 71 | CFLAGS_ABI :=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) $(call cc-option,-mno-thumb-interwork,) |
72 | endif | 72 | endif |
diff --git a/arch/arm/common/scoop.c b/arch/arm/common/scoop.c index 5e830f444c6c..314ebd3a1d71 100644 --- a/arch/arm/common/scoop.c +++ b/arch/arm/common/scoop.c | |||
@@ -18,6 +18,18 @@ | |||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | #include <asm/hardware/scoop.h> | 19 | #include <asm/hardware/scoop.h> |
20 | 20 | ||
21 | /* PCMCIA to Scoop linkage | ||
22 | |||
23 | There is no easy way to link multiple scoop devices into one | ||
24 | single entity for the pxa2xx_pcmcia device so this structure | ||
25 | is used which is setup by the platform code. | ||
26 | |||
27 | This file is never modular so this symbol is always | ||
28 | accessile to the board support files. | ||
29 | */ | ||
30 | struct scoop_pcmcia_config *platform_scoop_config; | ||
31 | EXPORT_SYMBOL(platform_scoop_config); | ||
32 | |||
21 | #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) | 33 | #define SCOOP_REG(d,adr) (*(volatile unsigned short*)(d +(adr))) |
22 | 34 | ||
23 | struct scoop_dev { | 35 | struct scoop_dev { |
diff --git a/arch/arm/configs/ep93xx_defconfig b/arch/arm/configs/ep93xx_defconfig index 8dcc8e8ec813..b69e88bbc909 100644 --- a/arch/arm/configs/ep93xx_defconfig +++ b/arch/arm/configs/ep93xx_defconfig | |||
@@ -1,12 +1,14 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16 | 3 | # Linux kernel version: 2.6.17-rc2 |
4 | # Mon Mar 20 14:54:51 2006 | 4 | # Wed Apr 19 21:21:01 2006 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
9 | CONFIG_GENERIC_HWEIGHT=y | ||
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_VECTORS_BASE=0xffff0000 | ||
10 | 12 | ||
11 | # | 13 | # |
12 | # Code maturity level options | 14 | # Code maturity level options |
@@ -28,6 +30,7 @@ CONFIG_SYSCTL=y | |||
28 | # CONFIG_AUDIT is not set | 30 | # CONFIG_AUDIT is not set |
29 | CONFIG_IKCONFIG=y | 31 | CONFIG_IKCONFIG=y |
30 | CONFIG_IKCONFIG_PROC=y | 32 | CONFIG_IKCONFIG_PROC=y |
33 | # CONFIG_RELAY is not set | ||
31 | CONFIG_INITRAMFS_SOURCE="" | 34 | CONFIG_INITRAMFS_SOURCE="" |
32 | CONFIG_UID16=y | 35 | CONFIG_UID16=y |
33 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 36 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
@@ -43,10 +46,6 @@ CONFIG_BASE_FULL=y | |||
43 | CONFIG_FUTEX=y | 46 | CONFIG_FUTEX=y |
44 | CONFIG_EPOLL=y | 47 | CONFIG_EPOLL=y |
45 | CONFIG_SHMEM=y | 48 | CONFIG_SHMEM=y |
46 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
47 | CONFIG_CC_ALIGN_LABELS=0 | ||
48 | CONFIG_CC_ALIGN_LOOPS=0 | ||
49 | CONFIG_CC_ALIGN_JUMPS=0 | ||
50 | CONFIG_SLAB=y | 49 | CONFIG_SLAB=y |
51 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
52 | CONFIG_BASE_SMALL=0 | 51 | CONFIG_BASE_SMALL=0 |
@@ -59,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y | |||
59 | CONFIG_MODULES=y | 58 | CONFIG_MODULES=y |
60 | CONFIG_MODULE_UNLOAD=y | 59 | CONFIG_MODULE_UNLOAD=y |
61 | CONFIG_MODULE_FORCE_UNLOAD=y | 60 | CONFIG_MODULE_FORCE_UNLOAD=y |
62 | CONFIG_OBSOLETE_MODPARM=y | ||
63 | # CONFIG_MODVERSIONS is not set | 61 | # CONFIG_MODVERSIONS is not set |
64 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 62 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
65 | CONFIG_KMOD=y | 63 | CONFIG_KMOD=y |
@@ -67,6 +65,7 @@ CONFIG_KMOD=y | |||
67 | # | 65 | # |
68 | # Block layer | 66 | # Block layer |
69 | # | 67 | # |
68 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
70 | 69 | ||
71 | # | 70 | # |
72 | # IO Schedulers | 71 | # IO Schedulers |
@@ -94,6 +93,7 @@ CONFIG_ARCH_EP93XX=y | |||
94 | # CONFIG_ARCH_IOP3XX is not set | 93 | # CONFIG_ARCH_IOP3XX is not set |
95 | # CONFIG_ARCH_IXP4XX is not set | 94 | # CONFIG_ARCH_IXP4XX is not set |
96 | # CONFIG_ARCH_IXP2000 is not set | 95 | # CONFIG_ARCH_IXP2000 is not set |
96 | # CONFIG_ARCH_IXP23XX is not set | ||
97 | # CONFIG_ARCH_L7200 is not set | 97 | # CONFIG_ARCH_L7200 is not set |
98 | # CONFIG_ARCH_PXA is not set | 98 | # CONFIG_ARCH_PXA is not set |
99 | # CONFIG_ARCH_RPC is not set | 99 | # CONFIG_ARCH_RPC is not set |
@@ -112,7 +112,6 @@ CONFIG_ARCH_EP93XX=y | |||
112 | # | 112 | # |
113 | # Cirrus EP93xx Implementation Options | 113 | # Cirrus EP93xx Implementation Options |
114 | # | 114 | # |
115 | CONFIG_CRUNCH=y | ||
116 | 115 | ||
117 | # | 116 | # |
118 | # EP93xx Platforms | 117 | # EP93xx Platforms |
@@ -232,12 +231,15 @@ CONFIG_SYN_COOKIES=y | |||
232 | # CONFIG_INET_AH is not set | 231 | # CONFIG_INET_AH is not set |
233 | # CONFIG_INET_ESP is not set | 232 | # CONFIG_INET_ESP is not set |
234 | # CONFIG_INET_IPCOMP is not set | 233 | # CONFIG_INET_IPCOMP is not set |
234 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
235 | # CONFIG_INET_TUNNEL is not set | 235 | # CONFIG_INET_TUNNEL is not set |
236 | CONFIG_INET_DIAG=y | 236 | CONFIG_INET_DIAG=y |
237 | CONFIG_INET_TCP_DIAG=y | 237 | CONFIG_INET_TCP_DIAG=y |
238 | # CONFIG_TCP_CONG_ADVANCED is not set | 238 | # CONFIG_TCP_CONG_ADVANCED is not set |
239 | CONFIG_TCP_CONG_BIC=y | 239 | CONFIG_TCP_CONG_BIC=y |
240 | # CONFIG_IPV6 is not set | 240 | # CONFIG_IPV6 is not set |
241 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
242 | # CONFIG_INET6_TUNNEL is not set | ||
241 | # CONFIG_NETFILTER is not set | 243 | # CONFIG_NETFILTER is not set |
242 | 244 | ||
243 | # | 245 | # |
@@ -346,7 +348,6 @@ CONFIG_MTD_CFI_I2=y | |||
346 | # CONFIG_MTD_OTP is not set | 348 | # CONFIG_MTD_OTP is not set |
347 | CONFIG_MTD_CFI_INTELEXT=y | 349 | CONFIG_MTD_CFI_INTELEXT=y |
348 | CONFIG_MTD_CFI_AMDSTD=y | 350 | CONFIG_MTD_CFI_AMDSTD=y |
349 | CONFIG_MTD_CFI_AMDSTD_RETRY=0 | ||
350 | CONFIG_MTD_CFI_STAA=y | 351 | CONFIG_MTD_CFI_STAA=y |
351 | CONFIG_MTD_CFI_UTIL=y | 352 | CONFIG_MTD_CFI_UTIL=y |
352 | # CONFIG_MTD_RAM is not set | 353 | # CONFIG_MTD_RAM is not set |
@@ -371,7 +372,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 | |||
371 | # CONFIG_MTD_SLRAM is not set | 372 | # CONFIG_MTD_SLRAM is not set |
372 | # CONFIG_MTD_PHRAM is not set | 373 | # CONFIG_MTD_PHRAM is not set |
373 | # CONFIG_MTD_MTDRAM is not set | 374 | # CONFIG_MTD_MTDRAM is not set |
374 | # CONFIG_MTD_BLKMTD is not set | ||
375 | # CONFIG_MTD_BLOCK2MTD is not set | 375 | # CONFIG_MTD_BLOCK2MTD is not set |
376 | 376 | ||
377 | # | 377 | # |
@@ -412,7 +412,7 @@ CONFIG_MTD_NAND_IDS=y | |||
412 | # CONFIG_BLK_DEV_NBD is not set | 412 | # CONFIG_BLK_DEV_NBD is not set |
413 | # CONFIG_BLK_DEV_UB is not set | 413 | # CONFIG_BLK_DEV_UB is not set |
414 | # CONFIG_BLK_DEV_RAM is not set | 414 | # CONFIG_BLK_DEV_RAM is not set |
415 | CONFIG_BLK_DEV_RAM_COUNT=16 | 415 | # CONFIG_BLK_DEV_INITRD is not set |
416 | # CONFIG_CDROM_PKTCDVD is not set | 416 | # CONFIG_CDROM_PKTCDVD is not set |
417 | # CONFIG_ATA_OVER_ETH is not set | 417 | # CONFIG_ATA_OVER_ETH is not set |
418 | 418 | ||
@@ -576,13 +576,13 @@ CONFIG_WATCHDOG=y | |||
576 | # Watchdog Device Drivers | 576 | # Watchdog Device Drivers |
577 | # | 577 | # |
578 | # CONFIG_SOFT_WATCHDOG is not set | 578 | # CONFIG_SOFT_WATCHDOG is not set |
579 | CONFIG_EP93XX_WATCHDOG=y | ||
579 | 580 | ||
580 | # | 581 | # |
581 | # USB-based Watchdog Cards | 582 | # USB-based Watchdog Cards |
582 | # | 583 | # |
583 | # CONFIG_USBPCWATCHDOG is not set | 584 | # CONFIG_USBPCWATCHDOG is not set |
584 | # CONFIG_NVRAM is not set | 585 | # CONFIG_NVRAM is not set |
585 | # CONFIG_RTC is not set | ||
586 | # CONFIG_DTLK is not set | 586 | # CONFIG_DTLK is not set |
587 | # CONFIG_R3964 is not set | 587 | # CONFIG_R3964 is not set |
588 | 588 | ||
@@ -626,9 +626,7 @@ CONFIG_I2C_ALGOBIT=y | |||
626 | # CONFIG_SENSORS_PCF8574 is not set | 626 | # CONFIG_SENSORS_PCF8574 is not set |
627 | # CONFIG_SENSORS_PCA9539 is not set | 627 | # CONFIG_SENSORS_PCA9539 is not set |
628 | # CONFIG_SENSORS_PCF8591 is not set | 628 | # CONFIG_SENSORS_PCF8591 is not set |
629 | # CONFIG_SENSORS_RTC8564 is not set | ||
630 | # CONFIG_SENSORS_MAX6875 is not set | 629 | # CONFIG_SENSORS_MAX6875 is not set |
631 | # CONFIG_RTC_X1205_I2C is not set | ||
632 | CONFIG_I2C_DEBUG_CORE=y | 630 | CONFIG_I2C_DEBUG_CORE=y |
633 | CONFIG_I2C_DEBUG_ALGO=y | 631 | CONFIG_I2C_DEBUG_ALGO=y |
634 | CONFIG_I2C_DEBUG_BUS=y | 632 | CONFIG_I2C_DEBUG_BUS=y |
@@ -690,7 +688,16 @@ CONFIG_HWMON=y | |||
690 | # | 688 | # |
691 | 689 | ||
692 | # | 690 | # |
693 | # Multimedia Capabilities Port drivers | 691 | # LED devices |
692 | # | ||
693 | # CONFIG_NEW_LEDS is not set | ||
694 | |||
695 | # | ||
696 | # LED drivers | ||
697 | # | ||
698 | |||
699 | # | ||
700 | # LED Triggers | ||
694 | # | 701 | # |
695 | 702 | ||
696 | # | 703 | # |
@@ -702,6 +709,7 @@ CONFIG_HWMON=y | |||
702 | # Digital Video Broadcasting Devices | 709 | # Digital Video Broadcasting Devices |
703 | # | 710 | # |
704 | # CONFIG_DVB is not set | 711 | # CONFIG_DVB is not set |
712 | # CONFIG_USB_DABUSB is not set | ||
705 | 713 | ||
706 | # | 714 | # |
707 | # Graphics support | 715 | # Graphics support |
@@ -718,6 +726,7 @@ CONFIG_HWMON=y | |||
718 | # | 726 | # |
719 | CONFIG_USB_ARCH_HAS_HCD=y | 727 | CONFIG_USB_ARCH_HAS_HCD=y |
720 | # CONFIG_USB_ARCH_HAS_OHCI is not set | 728 | # CONFIG_USB_ARCH_HAS_OHCI is not set |
729 | # CONFIG_USB_ARCH_HAS_EHCI is not set | ||
721 | CONFIG_USB=y | 730 | CONFIG_USB=y |
722 | CONFIG_USB_DEBUG=y | 731 | CONFIG_USB_DEBUG=y |
723 | 732 | ||
@@ -776,15 +785,6 @@ CONFIG_USB_STORAGE=y | |||
776 | # CONFIG_USB_MICROTEK is not set | 785 | # CONFIG_USB_MICROTEK is not set |
777 | 786 | ||
778 | # | 787 | # |
779 | # USB Multimedia devices | ||
780 | # | ||
781 | # CONFIG_USB_DABUSB is not set | ||
782 | |||
783 | # | ||
784 | # Video4Linux support is needed for USB Multimedia device support | ||
785 | # | ||
786 | |||
787 | # | ||
788 | # USB Network Adapters | 788 | # USB Network Adapters |
789 | # | 789 | # |
790 | # CONFIG_USB_CATC is not set | 790 | # CONFIG_USB_CATC is not set |
@@ -813,6 +813,7 @@ CONFIG_USB_SERIAL_CONSOLE=y | |||
813 | # CONFIG_USB_SERIAL_CYPRESS_M8 is not set | 813 | # CONFIG_USB_SERIAL_CYPRESS_M8 is not set |
814 | # CONFIG_USB_SERIAL_EMPEG is not set | 814 | # CONFIG_USB_SERIAL_EMPEG is not set |
815 | # CONFIG_USB_SERIAL_FTDI_SIO is not set | 815 | # CONFIG_USB_SERIAL_FTDI_SIO is not set |
816 | # CONFIG_USB_SERIAL_FUNSOFT is not set | ||
816 | # CONFIG_USB_SERIAL_VISOR is not set | 817 | # CONFIG_USB_SERIAL_VISOR is not set |
817 | # CONFIG_USB_SERIAL_IPAQ is not set | 818 | # CONFIG_USB_SERIAL_IPAQ is not set |
818 | # CONFIG_USB_SERIAL_IR is not set | 819 | # CONFIG_USB_SERIAL_IR is not set |
@@ -825,6 +826,7 @@ CONFIG_USB_SERIAL_CONSOLE=y | |||
825 | # CONFIG_USB_SERIAL_KLSI is not set | 826 | # CONFIG_USB_SERIAL_KLSI is not set |
826 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set | 827 | # CONFIG_USB_SERIAL_KOBIL_SCT is not set |
827 | # CONFIG_USB_SERIAL_MCT_U232 is not set | 828 | # CONFIG_USB_SERIAL_MCT_U232 is not set |
829 | # CONFIG_USB_SERIAL_NAVMAN is not set | ||
828 | CONFIG_USB_SERIAL_PL2303=y | 830 | CONFIG_USB_SERIAL_PL2303=y |
829 | # CONFIG_USB_SERIAL_HP4X is not set | 831 | # CONFIG_USB_SERIAL_HP4X is not set |
830 | # CONFIG_USB_SERIAL_SAFE is not set | 832 | # CONFIG_USB_SERIAL_SAFE is not set |
@@ -865,6 +867,32 @@ CONFIG_USB_SERIAL_PL2303=y | |||
865 | # CONFIG_MMC is not set | 867 | # CONFIG_MMC is not set |
866 | 868 | ||
867 | # | 869 | # |
870 | # Real Time Clock | ||
871 | # | ||
872 | CONFIG_RTC_LIB=y | ||
873 | CONFIG_RTC_CLASS=y | ||
874 | CONFIG_RTC_HCTOSYS=y | ||
875 | CONFIG_RTC_HCTOSYS_DEVICE="rtc0" | ||
876 | |||
877 | # | ||
878 | # RTC interfaces | ||
879 | # | ||
880 | CONFIG_RTC_INTF_SYSFS=y | ||
881 | CONFIG_RTC_INTF_PROC=y | ||
882 | CONFIG_RTC_INTF_DEV=y | ||
883 | |||
884 | # | ||
885 | # RTC drivers | ||
886 | # | ||
887 | # CONFIG_RTC_DRV_X1205 is not set | ||
888 | # CONFIG_RTC_DRV_DS1672 is not set | ||
889 | # CONFIG_RTC_DRV_PCF8563 is not set | ||
890 | # CONFIG_RTC_DRV_RS5C372 is not set | ||
891 | CONFIG_RTC_DRV_M48T86=y | ||
892 | CONFIG_RTC_DRV_EP93XX=y | ||
893 | # CONFIG_RTC_DRV_TEST is not set | ||
894 | |||
895 | # | ||
868 | # File systems | 896 | # File systems |
869 | # | 897 | # |
870 | CONFIG_EXT2_FS=y | 898 | CONFIG_EXT2_FS=y |
@@ -912,7 +940,6 @@ CONFIG_SYSFS=y | |||
912 | CONFIG_TMPFS=y | 940 | CONFIG_TMPFS=y |
913 | # CONFIG_HUGETLB_PAGE is not set | 941 | # CONFIG_HUGETLB_PAGE is not set |
914 | CONFIG_RAMFS=y | 942 | CONFIG_RAMFS=y |
915 | # CONFIG_RELAYFS_FS is not set | ||
916 | # CONFIG_CONFIGFS_FS is not set | 943 | # CONFIG_CONFIGFS_FS is not set |
917 | 944 | ||
918 | # | 945 | # |
@@ -1044,6 +1071,7 @@ CONFIG_LOG_BUF_SHIFT=14 | |||
1044 | CONFIG_DETECT_SOFTLOCKUP=y | 1071 | CONFIG_DETECT_SOFTLOCKUP=y |
1045 | # CONFIG_SCHEDSTATS is not set | 1072 | # CONFIG_SCHEDSTATS is not set |
1046 | CONFIG_DEBUG_SLAB=y | 1073 | CONFIG_DEBUG_SLAB=y |
1074 | # CONFIG_DEBUG_SLAB_LEAK is not set | ||
1047 | CONFIG_DEBUG_MUTEXES=y | 1075 | CONFIG_DEBUG_MUTEXES=y |
1048 | CONFIG_DEBUG_SPINLOCK=y | 1076 | CONFIG_DEBUG_SPINLOCK=y |
1049 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set | 1077 | # CONFIG_DEBUG_SPINLOCK_SLEEP is not set |
@@ -1053,6 +1081,7 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
1053 | # CONFIG_DEBUG_FS is not set | 1081 | # CONFIG_DEBUG_FS is not set |
1054 | # CONFIG_DEBUG_VM is not set | 1082 | # CONFIG_DEBUG_VM is not set |
1055 | CONFIG_FRAME_POINTER=y | 1083 | CONFIG_FRAME_POINTER=y |
1084 | # CONFIG_UNWIND_INFO is not set | ||
1056 | CONFIG_FORCED_INLINING=y | 1085 | CONFIG_FORCED_INLINING=y |
1057 | # CONFIG_RCU_TORTURE_TEST is not set | 1086 | # CONFIG_RCU_TORTURE_TEST is not set |
1058 | CONFIG_DEBUG_USER=y | 1087 | CONFIG_DEBUG_USER=y |
diff --git a/arch/arm/configs/ixp2000_defconfig b/arch/arm/configs/ixp2000_defconfig index 7b02ca04c3ee..e6f3e4873d6c 100644 --- a/arch/arm/configs/ixp2000_defconfig +++ b/arch/arm/configs/ixp2000_defconfig | |||
@@ -1,18 +1,19 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-rc2 | 3 | # Linux kernel version: 2.6.17-rc2 |
4 | # Wed Feb 8 04:49:11 2006 | 4 | # Wed Apr 19 21:12:49 2006 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
9 | CONFIG_GENERIC_HWEIGHT=y | ||
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_VECTORS_BASE=0xffff0000 | ||
10 | 12 | ||
11 | # | 13 | # |
12 | # Code maturity level options | 14 | # Code maturity level options |
13 | # | 15 | # |
14 | CONFIG_EXPERIMENTAL=y | 16 | CONFIG_EXPERIMENTAL=y |
15 | CONFIG_CLEAN_COMPILE=y | ||
16 | CONFIG_BROKEN_ON_SMP=y | 17 | CONFIG_BROKEN_ON_SMP=y |
17 | CONFIG_INIT_ENV_ARG_LIMIT=32 | 18 | CONFIG_INIT_ENV_ARG_LIMIT=32 |
18 | 19 | ||
@@ -29,6 +30,7 @@ CONFIG_BSD_PROCESS_ACCT=y | |||
29 | CONFIG_SYSCTL=y | 30 | CONFIG_SYSCTL=y |
30 | # CONFIG_AUDIT is not set | 31 | # CONFIG_AUDIT is not set |
31 | # CONFIG_IKCONFIG is not set | 32 | # CONFIG_IKCONFIG is not set |
33 | # CONFIG_RELAY is not set | ||
32 | CONFIG_INITRAMFS_SOURCE="" | 34 | CONFIG_INITRAMFS_SOURCE="" |
33 | CONFIG_UID16=y | 35 | CONFIG_UID16=y |
34 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 36 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
@@ -44,10 +46,6 @@ CONFIG_BASE_FULL=y | |||
44 | CONFIG_FUTEX=y | 46 | CONFIG_FUTEX=y |
45 | CONFIG_EPOLL=y | 47 | CONFIG_EPOLL=y |
46 | CONFIG_SHMEM=y | 48 | CONFIG_SHMEM=y |
47 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
48 | CONFIG_CC_ALIGN_LABELS=0 | ||
49 | CONFIG_CC_ALIGN_LOOPS=0 | ||
50 | CONFIG_CC_ALIGN_JUMPS=0 | ||
51 | CONFIG_SLAB=y | 49 | CONFIG_SLAB=y |
52 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
53 | CONFIG_BASE_SMALL=0 | 51 | CONFIG_BASE_SMALL=0 |
@@ -60,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y | |||
60 | CONFIG_MODULES=y | 58 | CONFIG_MODULES=y |
61 | CONFIG_MODULE_UNLOAD=y | 59 | CONFIG_MODULE_UNLOAD=y |
62 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 60 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
63 | CONFIG_OBSOLETE_MODPARM=y | ||
64 | # CONFIG_MODVERSIONS is not set | 61 | # CONFIG_MODVERSIONS is not set |
65 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 62 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
66 | CONFIG_KMOD=y | 63 | CONFIG_KMOD=y |
@@ -68,6 +65,7 @@ CONFIG_KMOD=y | |||
68 | # | 65 | # |
69 | # Block layer | 66 | # Block layer |
70 | # | 67 | # |
68 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
71 | 69 | ||
72 | # | 70 | # |
73 | # IO Schedulers | 71 | # IO Schedulers |
@@ -89,11 +87,13 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" | |||
89 | # CONFIG_ARCH_CLPS711X is not set | 87 | # CONFIG_ARCH_CLPS711X is not set |
90 | # CONFIG_ARCH_CO285 is not set | 88 | # CONFIG_ARCH_CO285 is not set |
91 | # CONFIG_ARCH_EBSA110 is not set | 89 | # CONFIG_ARCH_EBSA110 is not set |
90 | # CONFIG_ARCH_EP93XX is not set | ||
92 | # CONFIG_ARCH_FOOTBRIDGE is not set | 91 | # CONFIG_ARCH_FOOTBRIDGE is not set |
93 | # CONFIG_ARCH_INTEGRATOR is not set | 92 | # CONFIG_ARCH_INTEGRATOR is not set |
94 | # CONFIG_ARCH_IOP3XX is not set | 93 | # CONFIG_ARCH_IOP3XX is not set |
95 | # CONFIG_ARCH_IXP4XX is not set | 94 | # CONFIG_ARCH_IXP4XX is not set |
96 | CONFIG_ARCH_IXP2000=y | 95 | CONFIG_ARCH_IXP2000=y |
96 | # CONFIG_ARCH_IXP23XX is not set | ||
97 | # CONFIG_ARCH_L7200 is not set | 97 | # CONFIG_ARCH_L7200 is not set |
98 | # CONFIG_ARCH_PXA is not set | 98 | # CONFIG_ARCH_PXA is not set |
99 | # CONFIG_ARCH_RPC is not set | 99 | # CONFIG_ARCH_RPC is not set |
@@ -123,6 +123,7 @@ CONFIG_ARCH_IXDP2800=y | |||
123 | CONFIG_ARCH_IXDP2X00=y | 123 | CONFIG_ARCH_IXDP2X00=y |
124 | CONFIG_ARCH_IXDP2401=y | 124 | CONFIG_ARCH_IXDP2401=y |
125 | CONFIG_ARCH_IXDP2801=y | 125 | CONFIG_ARCH_IXDP2801=y |
126 | CONFIG_MACH_IXDP28X5=y | ||
126 | CONFIG_ARCH_IXDP2X01=y | 127 | CONFIG_ARCH_IXDP2X01=y |
127 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set | 128 | # CONFIG_IXP2000_SUPPORT_BROKEN_PCI_IO is not set |
128 | 129 | ||
@@ -147,7 +148,6 @@ CONFIG_XSCALE_PMU=y | |||
147 | # Bus support | 148 | # Bus support |
148 | # | 149 | # |
149 | CONFIG_PCI=y | 150 | CONFIG_PCI=y |
150 | CONFIG_PCI_LEGACY_PROC=y | ||
151 | # CONFIG_PCI_DEBUG is not set | 151 | # CONFIG_PCI_DEBUG is not set |
152 | 152 | ||
153 | # | 153 | # |
@@ -160,6 +160,7 @@ CONFIG_PCI_LEGACY_PROC=y | |||
160 | # | 160 | # |
161 | # CONFIG_PREEMPT is not set | 161 | # CONFIG_PREEMPT is not set |
162 | # CONFIG_NO_IDLE_HZ is not set | 162 | # CONFIG_NO_IDLE_HZ is not set |
163 | CONFIG_HZ=100 | ||
163 | # CONFIG_AEABI is not set | 164 | # CONFIG_AEABI is not set |
164 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set | 165 | # CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set |
165 | CONFIG_SELECT_MEMORY_MODEL=y | 166 | CONFIG_SELECT_MEMORY_MODEL=y |
@@ -213,6 +214,7 @@ CONFIG_NET=y | |||
213 | # | 214 | # |
214 | # Networking options | 215 | # Networking options |
215 | # | 216 | # |
217 | # CONFIG_NETDEBUG is not set | ||
216 | CONFIG_PACKET=y | 218 | CONFIG_PACKET=y |
217 | CONFIG_PACKET_MMAP=y | 219 | CONFIG_PACKET_MMAP=y |
218 | CONFIG_UNIX=y | 220 | CONFIG_UNIX=y |
@@ -232,12 +234,15 @@ CONFIG_SYN_COOKIES=y | |||
232 | # CONFIG_INET_AH is not set | 234 | # CONFIG_INET_AH is not set |
233 | # CONFIG_INET_ESP is not set | 235 | # CONFIG_INET_ESP is not set |
234 | # CONFIG_INET_IPCOMP is not set | 236 | # CONFIG_INET_IPCOMP is not set |
237 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
235 | # CONFIG_INET_TUNNEL is not set | 238 | # CONFIG_INET_TUNNEL is not set |
236 | CONFIG_INET_DIAG=y | 239 | CONFIG_INET_DIAG=y |
237 | CONFIG_INET_TCP_DIAG=y | 240 | CONFIG_INET_TCP_DIAG=y |
238 | # CONFIG_TCP_CONG_ADVANCED is not set | 241 | # CONFIG_TCP_CONG_ADVANCED is not set |
239 | CONFIG_TCP_CONG_BIC=y | 242 | CONFIG_TCP_CONG_BIC=y |
240 | # CONFIG_IPV6 is not set | 243 | # CONFIG_IPV6 is not set |
244 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
245 | # CONFIG_INET6_TUNNEL is not set | ||
241 | # CONFIG_NETFILTER is not set | 246 | # CONFIG_NETFILTER is not set |
242 | 247 | ||
243 | # | 248 | # |
@@ -347,7 +352,6 @@ CONFIG_MTD_CFI_UTIL=y | |||
347 | # CONFIG_MTD_ROM is not set | 352 | # CONFIG_MTD_ROM is not set |
348 | # CONFIG_MTD_ABSENT is not set | 353 | # CONFIG_MTD_ABSENT is not set |
349 | # CONFIG_MTD_OBSOLETE_CHIPS is not set | 354 | # CONFIG_MTD_OBSOLETE_CHIPS is not set |
350 | # CONFIG_MTD_XIP is not set | ||
351 | 355 | ||
352 | # | 356 | # |
353 | # Mapping drivers for chip access | 357 | # Mapping drivers for chip access |
@@ -366,7 +370,6 @@ CONFIG_MTD_IXP2000=y | |||
366 | # CONFIG_MTD_SLRAM is not set | 370 | # CONFIG_MTD_SLRAM is not set |
367 | # CONFIG_MTD_PHRAM is not set | 371 | # CONFIG_MTD_PHRAM is not set |
368 | # CONFIG_MTD_MTDRAM is not set | 372 | # CONFIG_MTD_MTDRAM is not set |
369 | # CONFIG_MTD_BLKMTD is not set | ||
370 | # CONFIG_MTD_BLOCK2MTD is not set | 373 | # CONFIG_MTD_BLOCK2MTD is not set |
371 | 374 | ||
372 | # | 375 | # |
@@ -614,8 +617,9 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
614 | # | 617 | # |
615 | CONFIG_SERIAL_8250=y | 618 | CONFIG_SERIAL_8250=y |
616 | CONFIG_SERIAL_8250_CONSOLE=y | 619 | CONFIG_SERIAL_8250_CONSOLE=y |
620 | CONFIG_SERIAL_8250_PCI=y | ||
617 | CONFIG_SERIAL_8250_NR_UARTS=3 | 621 | CONFIG_SERIAL_8250_NR_UARTS=3 |
618 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | 622 | CONFIG_SERIAL_8250_RUNTIME_UARTS=3 |
619 | # CONFIG_SERIAL_8250_EXTENDED is not set | 623 | # CONFIG_SERIAL_8250_EXTENDED is not set |
620 | 624 | ||
621 | # | 625 | # |
@@ -623,6 +627,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | |||
623 | # | 627 | # |
624 | CONFIG_SERIAL_CORE=y | 628 | CONFIG_SERIAL_CORE=y |
625 | CONFIG_SERIAL_CORE_CONSOLE=y | 629 | CONFIG_SERIAL_CORE_CONSOLE=y |
630 | # CONFIG_SERIAL_JSM is not set | ||
626 | CONFIG_UNIX98_PTYS=y | 631 | CONFIG_UNIX98_PTYS=y |
627 | CONFIG_LEGACY_PTYS=y | 632 | CONFIG_LEGACY_PTYS=y |
628 | CONFIG_LEGACY_PTY_COUNT=256 | 633 | CONFIG_LEGACY_PTY_COUNT=256 |
@@ -650,7 +655,6 @@ CONFIG_IXP2000_WATCHDOG=y | |||
650 | # CONFIG_PCIPCWATCHDOG is not set | 655 | # CONFIG_PCIPCWATCHDOG is not set |
651 | # CONFIG_WDTPCI is not set | 656 | # CONFIG_WDTPCI is not set |
652 | # CONFIG_NVRAM is not set | 657 | # CONFIG_NVRAM is not set |
653 | # CONFIG_RTC is not set | ||
654 | # CONFIG_DTLK is not set | 658 | # CONFIG_DTLK is not set |
655 | # CONFIG_R3964 is not set | 659 | # CONFIG_R3964 is not set |
656 | # CONFIG_APPLICOM is not set | 660 | # CONFIG_APPLICOM is not set |
@@ -696,7 +700,6 @@ CONFIG_I2C_IXP2000=y | |||
696 | # CONFIG_I2C_PARPORT_LIGHT is not set | 700 | # CONFIG_I2C_PARPORT_LIGHT is not set |
697 | # CONFIG_I2C_PROSAVAGE is not set | 701 | # CONFIG_I2C_PROSAVAGE is not set |
698 | # CONFIG_I2C_SAVAGE4 is not set | 702 | # CONFIG_I2C_SAVAGE4 is not set |
699 | # CONFIG_SCx200_ACB is not set | ||
700 | # CONFIG_I2C_SIS5595 is not set | 703 | # CONFIG_I2C_SIS5595 is not set |
701 | # CONFIG_I2C_SIS630 is not set | 704 | # CONFIG_I2C_SIS630 is not set |
702 | # CONFIG_I2C_SIS96X is not set | 705 | # CONFIG_I2C_SIS96X is not set |
@@ -715,9 +718,7 @@ CONFIG_SENSORS_EEPROM=y | |||
715 | # CONFIG_SENSORS_PCF8574 is not set | 718 | # CONFIG_SENSORS_PCF8574 is not set |
716 | # CONFIG_SENSORS_PCA9539 is not set | 719 | # CONFIG_SENSORS_PCA9539 is not set |
717 | # CONFIG_SENSORS_PCF8591 is not set | 720 | # CONFIG_SENSORS_PCF8591 is not set |
718 | # CONFIG_SENSORS_RTC8564 is not set | ||
719 | # CONFIG_SENSORS_MAX6875 is not set | 721 | # CONFIG_SENSORS_MAX6875 is not set |
720 | # CONFIG_RTC_X1205_I2C is not set | ||
721 | # CONFIG_I2C_DEBUG_CORE is not set | 722 | # CONFIG_I2C_DEBUG_CORE is not set |
722 | # CONFIG_I2C_DEBUG_ALGO is not set | 723 | # CONFIG_I2C_DEBUG_ALGO is not set |
723 | # CONFIG_I2C_DEBUG_BUS is not set | 724 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -730,6 +731,11 @@ CONFIG_SENSORS_EEPROM=y | |||
730 | # CONFIG_SPI_MASTER is not set | 731 | # CONFIG_SPI_MASTER is not set |
731 | 732 | ||
732 | # | 733 | # |
734 | # Dallas's 1-wire bus | ||
735 | # | ||
736 | # CONFIG_W1 is not set | ||
737 | |||
738 | # | ||
733 | # Hardware Monitoring support | 739 | # Hardware Monitoring support |
734 | # | 740 | # |
735 | CONFIG_HWMON=y | 741 | CONFIG_HWMON=y |
@@ -742,6 +748,7 @@ CONFIG_HWMON=y | |||
742 | # CONFIG_SENSORS_ASB100 is not set | 748 | # CONFIG_SENSORS_ASB100 is not set |
743 | # CONFIG_SENSORS_ATXP1 is not set | 749 | # CONFIG_SENSORS_ATXP1 is not set |
744 | # CONFIG_SENSORS_DS1621 is not set | 750 | # CONFIG_SENSORS_DS1621 is not set |
751 | # CONFIG_SENSORS_F71805F is not set | ||
745 | # CONFIG_SENSORS_FSCHER is not set | 752 | # CONFIG_SENSORS_FSCHER is not set |
746 | # CONFIG_SENSORS_FSCPOS is not set | 753 | # CONFIG_SENSORS_FSCPOS is not set |
747 | # CONFIG_SENSORS_GL518SM is not set | 754 | # CONFIG_SENSORS_GL518SM is not set |
@@ -776,7 +783,16 @@ CONFIG_HWMON=y | |||
776 | # | 783 | # |
777 | 784 | ||
778 | # | 785 | # |
779 | # Multimedia Capabilities Port drivers | 786 | # LED devices |
787 | # | ||
788 | # CONFIG_NEW_LEDS is not set | ||
789 | |||
790 | # | ||
791 | # LED drivers | ||
792 | # | ||
793 | |||
794 | # | ||
795 | # LED Triggers | ||
780 | # | 796 | # |
781 | 797 | ||
782 | # | 798 | # |
@@ -804,6 +820,7 @@ CONFIG_HWMON=y | |||
804 | # | 820 | # |
805 | CONFIG_USB_ARCH_HAS_HCD=y | 821 | CONFIG_USB_ARCH_HAS_HCD=y |
806 | CONFIG_USB_ARCH_HAS_OHCI=y | 822 | CONFIG_USB_ARCH_HAS_OHCI=y |
823 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
807 | # CONFIG_USB is not set | 824 | # CONFIG_USB is not set |
808 | 825 | ||
809 | # | 826 | # |
@@ -821,6 +838,12 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
821 | # CONFIG_MMC is not set | 838 | # CONFIG_MMC is not set |
822 | 839 | ||
823 | # | 840 | # |
841 | # Real Time Clock | ||
842 | # | ||
843 | CONFIG_RTC_LIB=y | ||
844 | # CONFIG_RTC_CLASS is not set | ||
845 | |||
846 | # | ||
824 | # File systems | 847 | # File systems |
825 | # | 848 | # |
826 | CONFIG_EXT2_FS=y | 849 | CONFIG_EXT2_FS=y |
@@ -870,7 +893,6 @@ CONFIG_SYSFS=y | |||
870 | CONFIG_TMPFS=y | 893 | CONFIG_TMPFS=y |
871 | # CONFIG_HUGETLB_PAGE is not set | 894 | # CONFIG_HUGETLB_PAGE is not set |
872 | CONFIG_RAMFS=y | 895 | CONFIG_RAMFS=y |
873 | # CONFIG_RELAYFS_FS is not set | ||
874 | # CONFIG_CONFIGFS_FS is not set | 896 | # CONFIG_CONFIGFS_FS is not set |
875 | 897 | ||
876 | # | 898 | # |
@@ -972,6 +994,7 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
972 | # CONFIG_DEBUG_FS is not set | 994 | # CONFIG_DEBUG_FS is not set |
973 | # CONFIG_DEBUG_VM is not set | 995 | # CONFIG_DEBUG_VM is not set |
974 | CONFIG_FRAME_POINTER=y | 996 | CONFIG_FRAME_POINTER=y |
997 | # CONFIG_UNWIND_INFO is not set | ||
975 | CONFIG_FORCED_INLINING=y | 998 | CONFIG_FORCED_INLINING=y |
976 | # CONFIG_RCU_TORTURE_TEST is not set | 999 | # CONFIG_RCU_TORTURE_TEST is not set |
977 | CONFIG_DEBUG_USER=y | 1000 | CONFIG_DEBUG_USER=y |
diff --git a/arch/arm/configs/ixp23xx_defconfig b/arch/arm/configs/ixp23xx_defconfig index 1a2751e9ab05..9ce898a6cf87 100644 --- a/arch/arm/configs/ixp23xx_defconfig +++ b/arch/arm/configs/ixp23xx_defconfig | |||
@@ -1,12 +1,14 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16 | 3 | # Linux kernel version: 2.6.17-rc2 |
4 | # Tue Mar 21 03:27:20 2006 | 4 | # Wed Apr 19 21:13:50 2006 |
5 | # | 5 | # |
6 | CONFIG_ARM=y | 6 | CONFIG_ARM=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | 8 | CONFIG_RWSEM_GENERIC_SPINLOCK=y |
9 | CONFIG_GENERIC_HWEIGHT=y | ||
9 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 10 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
11 | CONFIG_VECTORS_BASE=0xffff0000 | ||
10 | 12 | ||
11 | # | 13 | # |
12 | # Code maturity level options | 14 | # Code maturity level options |
@@ -28,6 +30,7 @@ CONFIG_BSD_PROCESS_ACCT=y | |||
28 | CONFIG_SYSCTL=y | 30 | CONFIG_SYSCTL=y |
29 | # CONFIG_AUDIT is not set | 31 | # CONFIG_AUDIT is not set |
30 | # CONFIG_IKCONFIG is not set | 32 | # CONFIG_IKCONFIG is not set |
33 | # CONFIG_RELAY is not set | ||
31 | CONFIG_INITRAMFS_SOURCE="" | 34 | CONFIG_INITRAMFS_SOURCE="" |
32 | CONFIG_UID16=y | 35 | CONFIG_UID16=y |
33 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 36 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
@@ -43,10 +46,6 @@ CONFIG_BASE_FULL=y | |||
43 | CONFIG_FUTEX=y | 46 | CONFIG_FUTEX=y |
44 | CONFIG_EPOLL=y | 47 | CONFIG_EPOLL=y |
45 | CONFIG_SHMEM=y | 48 | CONFIG_SHMEM=y |
46 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
47 | CONFIG_CC_ALIGN_LABELS=0 | ||
48 | CONFIG_CC_ALIGN_LOOPS=0 | ||
49 | CONFIG_CC_ALIGN_JUMPS=0 | ||
50 | CONFIG_SLAB=y | 49 | CONFIG_SLAB=y |
51 | # CONFIG_TINY_SHMEM is not set | 50 | # CONFIG_TINY_SHMEM is not set |
52 | CONFIG_BASE_SMALL=0 | 51 | CONFIG_BASE_SMALL=0 |
@@ -59,7 +58,6 @@ CONFIG_OBSOLETE_INTERMODULE=y | |||
59 | CONFIG_MODULES=y | 58 | CONFIG_MODULES=y |
60 | CONFIG_MODULE_UNLOAD=y | 59 | CONFIG_MODULE_UNLOAD=y |
61 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 60 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
62 | CONFIG_OBSOLETE_MODPARM=y | ||
63 | # CONFIG_MODVERSIONS is not set | 61 | # CONFIG_MODVERSIONS is not set |
64 | # CONFIG_MODULE_SRCVERSION_ALL is not set | 62 | # CONFIG_MODULE_SRCVERSION_ALL is not set |
65 | CONFIG_KMOD=y | 63 | CONFIG_KMOD=y |
@@ -67,6 +65,7 @@ CONFIG_KMOD=y | |||
67 | # | 65 | # |
68 | # Block layer | 66 | # Block layer |
69 | # | 67 | # |
68 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
70 | 69 | ||
71 | # | 70 | # |
72 | # IO Schedulers | 71 | # IO Schedulers |
@@ -143,7 +142,6 @@ CONFIG_CPU_BIG_ENDIAN=y | |||
143 | # Bus support | 142 | # Bus support |
144 | # | 143 | # |
145 | CONFIG_PCI=y | 144 | CONFIG_PCI=y |
146 | CONFIG_PCI_LEGACY_PROC=y | ||
147 | # CONFIG_PCI_DEBUG is not set | 145 | # CONFIG_PCI_DEBUG is not set |
148 | 146 | ||
149 | # | 147 | # |
@@ -230,12 +228,15 @@ CONFIG_SYN_COOKIES=y | |||
230 | # CONFIG_INET_AH is not set | 228 | # CONFIG_INET_AH is not set |
231 | # CONFIG_INET_ESP is not set | 229 | # CONFIG_INET_ESP is not set |
232 | # CONFIG_INET_IPCOMP is not set | 230 | # CONFIG_INET_IPCOMP is not set |
231 | # CONFIG_INET_XFRM_TUNNEL is not set | ||
233 | # CONFIG_INET_TUNNEL is not set | 232 | # CONFIG_INET_TUNNEL is not set |
234 | CONFIG_INET_DIAG=y | 233 | CONFIG_INET_DIAG=y |
235 | CONFIG_INET_TCP_DIAG=y | 234 | CONFIG_INET_TCP_DIAG=y |
236 | # CONFIG_TCP_CONG_ADVANCED is not set | 235 | # CONFIG_TCP_CONG_ADVANCED is not set |
237 | CONFIG_TCP_CONG_BIC=y | 236 | CONFIG_TCP_CONG_BIC=y |
238 | # CONFIG_IPV6 is not set | 237 | # CONFIG_IPV6 is not set |
238 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
239 | # CONFIG_INET6_TUNNEL is not set | ||
239 | # CONFIG_NETFILTER is not set | 240 | # CONFIG_NETFILTER is not set |
240 | 241 | ||
241 | # | 242 | # |
@@ -365,7 +366,6 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=1 | |||
365 | # CONFIG_MTD_SLRAM is not set | 366 | # CONFIG_MTD_SLRAM is not set |
366 | # CONFIG_MTD_PHRAM is not set | 367 | # CONFIG_MTD_PHRAM is not set |
367 | # CONFIG_MTD_MTDRAM is not set | 368 | # CONFIG_MTD_MTDRAM is not set |
368 | # CONFIG_MTD_BLKMTD is not set | ||
369 | # CONFIG_MTD_BLOCK2MTD is not set | 369 | # CONFIG_MTD_BLOCK2MTD is not set |
370 | 370 | ||
371 | # | 371 | # |
@@ -527,7 +527,6 @@ CONFIG_BLK_DEV_SD=y | |||
527 | # CONFIG_SCSI_INIA100 is not set | 527 | # CONFIG_SCSI_INIA100 is not set |
528 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 528 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
529 | # CONFIG_SCSI_IPR is not set | 529 | # CONFIG_SCSI_IPR is not set |
530 | # CONFIG_SCSI_QLOGIC_FC is not set | ||
531 | # CONFIG_SCSI_QLOGIC_1280 is not set | 530 | # CONFIG_SCSI_QLOGIC_1280 is not set |
532 | # CONFIG_SCSI_QLA_FC is not set | 531 | # CONFIG_SCSI_QLA_FC is not set |
533 | # CONFIG_SCSI_LPFC is not set | 532 | # CONFIG_SCSI_LPFC is not set |
@@ -735,6 +734,7 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | |||
735 | # | 734 | # |
736 | CONFIG_SERIAL_8250=y | 735 | CONFIG_SERIAL_8250=y |
737 | CONFIG_SERIAL_8250_CONSOLE=y | 736 | CONFIG_SERIAL_8250_CONSOLE=y |
737 | CONFIG_SERIAL_8250_PCI=y | ||
738 | CONFIG_SERIAL_8250_NR_UARTS=4 | 738 | CONFIG_SERIAL_8250_NR_UARTS=4 |
739 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | 739 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 |
740 | # CONFIG_SERIAL_8250_EXTENDED is not set | 740 | # CONFIG_SERIAL_8250_EXTENDED is not set |
@@ -776,7 +776,6 @@ CONFIG_WATCHDOG=y | |||
776 | # | 776 | # |
777 | # CONFIG_USBPCWATCHDOG is not set | 777 | # CONFIG_USBPCWATCHDOG is not set |
778 | # CONFIG_NVRAM is not set | 778 | # CONFIG_NVRAM is not set |
779 | # CONFIG_RTC is not set | ||
780 | # CONFIG_DTLK is not set | 779 | # CONFIG_DTLK is not set |
781 | # CONFIG_R3964 is not set | 780 | # CONFIG_R3964 is not set |
782 | # CONFIG_APPLICOM is not set | 781 | # CONFIG_APPLICOM is not set |
@@ -821,7 +820,6 @@ CONFIG_I2C_ALGOBIT=y | |||
821 | # CONFIG_I2C_PARPORT_LIGHT is not set | 820 | # CONFIG_I2C_PARPORT_LIGHT is not set |
822 | # CONFIG_I2C_PROSAVAGE is not set | 821 | # CONFIG_I2C_PROSAVAGE is not set |
823 | # CONFIG_I2C_SAVAGE4 is not set | 822 | # CONFIG_I2C_SAVAGE4 is not set |
824 | # CONFIG_SCx200_ACB is not set | ||
825 | # CONFIG_I2C_SIS5595 is not set | 823 | # CONFIG_I2C_SIS5595 is not set |
826 | # CONFIG_I2C_SIS630 is not set | 824 | # CONFIG_I2C_SIS630 is not set |
827 | # CONFIG_I2C_SIS96X is not set | 825 | # CONFIG_I2C_SIS96X is not set |
@@ -840,9 +838,7 @@ CONFIG_SENSORS_EEPROM=y | |||
840 | # CONFIG_SENSORS_PCF8574 is not set | 838 | # CONFIG_SENSORS_PCF8574 is not set |
841 | # CONFIG_SENSORS_PCA9539 is not set | 839 | # CONFIG_SENSORS_PCA9539 is not set |
842 | # CONFIG_SENSORS_PCF8591 is not set | 840 | # CONFIG_SENSORS_PCF8591 is not set |
843 | # CONFIG_SENSORS_RTC8564 is not set | ||
844 | # CONFIG_SENSORS_MAX6875 is not set | 841 | # CONFIG_SENSORS_MAX6875 is not set |
845 | # CONFIG_RTC_X1205_I2C is not set | ||
846 | # CONFIG_I2C_DEBUG_CORE is not set | 842 | # CONFIG_I2C_DEBUG_CORE is not set |
847 | # CONFIG_I2C_DEBUG_ALGO is not set | 843 | # CONFIG_I2C_DEBUG_ALGO is not set |
848 | # CONFIG_I2C_DEBUG_BUS is not set | 844 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -907,7 +903,16 @@ CONFIG_HWMON=y | |||
907 | # | 903 | # |
908 | 904 | ||
909 | # | 905 | # |
910 | # Multimedia Capabilities Port drivers | 906 | # LED devices |
907 | # | ||
908 | # CONFIG_NEW_LEDS is not set | ||
909 | |||
910 | # | ||
911 | # LED drivers | ||
912 | # | ||
913 | |||
914 | # | ||
915 | # LED Triggers | ||
911 | # | 916 | # |
912 | 917 | ||
913 | # | 918 | # |
@@ -919,6 +924,7 @@ CONFIG_HWMON=y | |||
919 | # Digital Video Broadcasting Devices | 924 | # Digital Video Broadcasting Devices |
920 | # | 925 | # |
921 | # CONFIG_DVB is not set | 926 | # CONFIG_DVB is not set |
927 | # CONFIG_USB_DABUSB is not set | ||
922 | 928 | ||
923 | # | 929 | # |
924 | # Graphics support | 930 | # Graphics support |
@@ -935,6 +941,7 @@ CONFIG_HWMON=y | |||
935 | # | 941 | # |
936 | CONFIG_USB_ARCH_HAS_HCD=y | 942 | CONFIG_USB_ARCH_HAS_HCD=y |
937 | CONFIG_USB_ARCH_HAS_OHCI=y | 943 | CONFIG_USB_ARCH_HAS_OHCI=y |
944 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
938 | CONFIG_USB=y | 945 | CONFIG_USB=y |
939 | # CONFIG_USB_DEBUG is not set | 946 | # CONFIG_USB_DEBUG is not set |
940 | 947 | ||
@@ -1000,9 +1007,7 @@ CONFIG_USB_STORAGE=y | |||
1000 | # CONFIG_USB_ACECAD is not set | 1007 | # CONFIG_USB_ACECAD is not set |
1001 | # CONFIG_USB_KBTAB is not set | 1008 | # CONFIG_USB_KBTAB is not set |
1002 | # CONFIG_USB_POWERMATE is not set | 1009 | # CONFIG_USB_POWERMATE is not set |
1003 | # CONFIG_USB_MTOUCH is not set | 1010 | # CONFIG_USB_TOUCHSCREEN is not set |
1004 | # CONFIG_USB_ITMTOUCH is not set | ||
1005 | # CONFIG_USB_EGALAX is not set | ||
1006 | # CONFIG_USB_YEALINK is not set | 1011 | # CONFIG_USB_YEALINK is not set |
1007 | # CONFIG_USB_XPAD is not set | 1012 | # CONFIG_USB_XPAD is not set |
1008 | # CONFIG_USB_ATI_REMOTE is not set | 1013 | # CONFIG_USB_ATI_REMOTE is not set |
@@ -1017,15 +1022,6 @@ CONFIG_USB_STORAGE=y | |||
1017 | # CONFIG_USB_MICROTEK is not set | 1022 | # CONFIG_USB_MICROTEK is not set |
1018 | 1023 | ||
1019 | # | 1024 | # |
1020 | # USB Multimedia devices | ||
1021 | # | ||
1022 | # CONFIG_USB_DABUSB is not set | ||
1023 | |||
1024 | # | ||
1025 | # Video4Linux support is needed for USB Multimedia device support | ||
1026 | # | ||
1027 | |||
1028 | # | ||
1029 | # USB Network Adapters | 1025 | # USB Network Adapters |
1030 | # | 1026 | # |
1031 | # CONFIG_USB_CATC is not set | 1027 | # CONFIG_USB_CATC is not set |
@@ -1076,6 +1072,12 @@ CONFIG_USB_MON=y | |||
1076 | # CONFIG_MMC is not set | 1072 | # CONFIG_MMC is not set |
1077 | 1073 | ||
1078 | # | 1074 | # |
1075 | # Real Time Clock | ||
1076 | # | ||
1077 | CONFIG_RTC_LIB=y | ||
1078 | # CONFIG_RTC_CLASS is not set | ||
1079 | |||
1080 | # | ||
1079 | # File systems | 1081 | # File systems |
1080 | # | 1082 | # |
1081 | CONFIG_EXT2_FS=y | 1083 | CONFIG_EXT2_FS=y |
@@ -1127,7 +1129,6 @@ CONFIG_SYSFS=y | |||
1127 | CONFIG_TMPFS=y | 1129 | CONFIG_TMPFS=y |
1128 | # CONFIG_HUGETLB_PAGE is not set | 1130 | # CONFIG_HUGETLB_PAGE is not set |
1129 | CONFIG_RAMFS=y | 1131 | CONFIG_RAMFS=y |
1130 | # CONFIG_RELAYFS_FS is not set | ||
1131 | # CONFIG_CONFIGFS_FS is not set | 1132 | # CONFIG_CONFIGFS_FS is not set |
1132 | 1133 | ||
1133 | # | 1134 | # |
@@ -1268,6 +1269,7 @@ CONFIG_DEBUG_BUGVERBOSE=y | |||
1268 | # CONFIG_DEBUG_FS is not set | 1269 | # CONFIG_DEBUG_FS is not set |
1269 | # CONFIG_DEBUG_VM is not set | 1270 | # CONFIG_DEBUG_VM is not set |
1270 | CONFIG_FRAME_POINTER=y | 1271 | CONFIG_FRAME_POINTER=y |
1272 | # CONFIG_UNWIND_INFO is not set | ||
1271 | CONFIG_FORCED_INLINING=y | 1273 | CONFIG_FORCED_INLINING=y |
1272 | # CONFIG_RCU_TORTURE_TEST is not set | 1274 | # CONFIG_RCU_TORTURE_TEST is not set |
1273 | CONFIG_DEBUG_USER=y | 1275 | CONFIG_DEBUG_USER=y |
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index 2ce0e3a27a45..a601b8b55f35 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile | |||
@@ -29,7 +29,7 @@ ifneq ($(CONFIG_ARCH_EBSA110),y) | |||
29 | obj-y += io.o | 29 | obj-y += io.o |
30 | endif | 30 | endif |
31 | 31 | ||
32 | head-y := head.o | 32 | head-y := head$(MMUEXT).o |
33 | obj-$(CONFIG_DEBUG_LL) += debug.o | 33 | obj-$(CONFIG_DEBUG_LL) += debug.o |
34 | 34 | ||
35 | extra-y := $(head-y) init_task.o vmlinux.lds | 35 | extra-y := $(head-y) init_task.o vmlinux.lds |
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index b093ab8738b5..0bea65864051 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S | |||
@@ -20,10 +20,11 @@ | |||
20 | #include <asm/mach-types.h> | 20 | #include <asm/mach-types.h> |
21 | #include <asm/procinfo.h> | 21 | #include <asm/procinfo.h> |
22 | #include <asm/ptrace.h> | 22 | #include <asm/ptrace.h> |
23 | #include <asm/constants.h> | 23 | #include <asm/thread_info.h> |
24 | #include <asm/system.h> | 24 | #include <asm/system.h> |
25 | 25 | ||
26 | #define PROCINFO_INITFUNC 12 | 26 | #define PROCINFO_INITFUNC 12 |
27 | #define MACHINFO_TYPE 0 | ||
27 | 28 | ||
28 | /* | 29 | /* |
29 | * Kernel startup entry point. | 30 | * Kernel startup entry point. |
@@ -79,5 +80,6 @@ __after_proc_init: | |||
79 | 80 | ||
80 | mov pc, r13 @ clear the BSS and jump | 81 | mov pc, r13 @ clear the BSS and jump |
81 | @ to start_kernel | 82 | @ to start_kernel |
83 | .ltorg | ||
82 | 84 | ||
83 | #include "head-common.S" | 85 | #include "head-common.S" |
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index 8cff73e668b3..9fc9af88c60c 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c | |||
@@ -407,7 +407,7 @@ static void __init early_initrd(char **p) | |||
407 | } | 407 | } |
408 | __early_param("initrd=", early_initrd); | 408 | __early_param("initrd=", early_initrd); |
409 | 409 | ||
410 | static void __init add_memory(unsigned long start, unsigned long size) | 410 | static void __init arm_add_memory(unsigned long start, unsigned long size) |
411 | { | 411 | { |
412 | /* | 412 | /* |
413 | * Ensure that start/size are aligned to a page boundary. | 413 | * Ensure that start/size are aligned to a page boundary. |
@@ -445,7 +445,7 @@ static void __init early_mem(char **p) | |||
445 | if (**p == '@') | 445 | if (**p == '@') |
446 | start = memparse(*p + 1, p); | 446 | start = memparse(*p + 1, p); |
447 | 447 | ||
448 | add_memory(start, size); | 448 | arm_add_memory(start, size); |
449 | } | 449 | } |
450 | __early_param("mem=", early_mem); | 450 | __early_param("mem=", early_mem); |
451 | 451 | ||
@@ -587,7 +587,7 @@ static int __init parse_tag_mem32(const struct tag *tag) | |||
587 | tag->u.mem.start, tag->u.mem.size / 1024); | 587 | tag->u.mem.start, tag->u.mem.size / 1024); |
588 | return -EINVAL; | 588 | return -EINVAL; |
589 | } | 589 | } |
590 | add_memory(tag->u.mem.start, tag->u.mem.size); | 590 | arm_add_memory(tag->u.mem.start, tag->u.mem.size); |
591 | return 0; | 591 | return 0; |
592 | } | 592 | } |
593 | 593 | ||
@@ -807,7 +807,7 @@ static int __init topology_init(void) | |||
807 | { | 807 | { |
808 | int cpu; | 808 | int cpu; |
809 | 809 | ||
810 | for_each_cpu(cpu) | 810 | for_each_possible_cpu(cpu) |
811 | register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); | 811 | register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu, NULL); |
812 | 812 | ||
813 | return 0; | 813 | return 0; |
diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index a0888e160e3b..00b761ff0f9c 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c | |||
@@ -91,7 +91,7 @@ static void ixp4xx_config_irq(unsigned irq, enum ixp4xx_irq_type type); | |||
91 | /* | 91 | /* |
92 | * IRQ -> GPIO mapping table | 92 | * IRQ -> GPIO mapping table |
93 | */ | 93 | */ |
94 | static char irq2gpio[32] = { | 94 | static signed char irq2gpio[32] = { |
95 | -1, -1, -1, -1, -1, -1, 0, 1, | 95 | -1, -1, -1, -1, -1, -1, 0, 1, |
96 | -1, -1, -1, -1, -1, -1, -1, -1, | 96 | -1, -1, -1, -1, -1, -1, -1, -1, |
97 | -1, -1, -1, 2, 3, 4, 5, 6, | 97 | -1, -1, -1, 2, 3, 4, 5, 6, |
diff --git a/arch/arm/mach-pxa/corgi_ssp.c b/arch/arm/mach-pxa/corgi_ssp.c index b371d723635f..8a25a1c8019f 100644 --- a/arch/arm/mach-pxa/corgi_ssp.c +++ b/arch/arm/mach-pxa/corgi_ssp.c | |||
@@ -196,12 +196,9 @@ static int __init corgi_ssp_probe(struct platform_device *dev) | |||
196 | int ret; | 196 | int ret; |
197 | 197 | ||
198 | /* Chip Select - Disable All */ | 198 | /* Chip Select - Disable All */ |
199 | GPDR(ssp_machinfo->cs_lcdcon) |= GPIO_bit(ssp_machinfo->cs_lcdcon); /* output */ | 199 | pxa_gpio_mode(ssp_machinfo->cs_lcdcon | GPIO_OUT | GPIO_DFLT_HIGH); |
200 | GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */ | 200 | pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH); |
201 | GPDR(ssp_machinfo->cs_max1111) |= GPIO_bit(ssp_machinfo->cs_max1111); /* output */ | 201 | pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH); |
202 | GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/ | ||
203 | GPDR(ssp_machinfo->cs_ads7846) |= GPIO_bit(ssp_machinfo->cs_ads7846); /* output */ | ||
204 | GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/ | ||
205 | 202 | ||
206 | ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0); | 203 | ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0); |
207 | 204 | ||
diff --git a/arch/arm/vfp/vfpdouble.c b/arch/arm/vfp/vfpdouble.c index febd115dba28..009038c8113e 100644 --- a/arch/arm/vfp/vfpdouble.c +++ b/arch/arm/vfp/vfpdouble.c | |||
@@ -197,7 +197,7 @@ u32 vfp_double_normaliseround(int dd, struct vfp_double *vd, u32 fpscr, u32 exce | |||
197 | dd, d, exceptions); | 197 | dd, d, exceptions); |
198 | vfp_put_double(dd, d); | 198 | vfp_put_double(dd, d); |
199 | } | 199 | } |
200 | return exceptions & ~VFP_NAN_FLAG; | 200 | return exceptions; |
201 | } | 201 | } |
202 | 202 | ||
203 | /* | 203 | /* |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index 22f3da4e0829..37ff8145b5b5 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -180,7 +180,7 @@ static u32 vfp_emulate_instruction(u32 inst, u32 fpscr, struct pt_regs *regs) | |||
180 | * emulate it. | 180 | * emulate it. |
181 | */ | 181 | */ |
182 | } | 182 | } |
183 | return exceptions; | 183 | return exceptions & ~VFP_NAN_FLAG; |
184 | } | 184 | } |
185 | 185 | ||
186 | /* | 186 | /* |
diff --git a/arch/arm/vfp/vfpsingle.c b/arch/arm/vfp/vfpsingle.c index 4ac27f193934..dae2c2f46052 100644 --- a/arch/arm/vfp/vfpsingle.c +++ b/arch/arm/vfp/vfpsingle.c | |||
@@ -203,7 +203,7 @@ u32 vfp_single_normaliseround(int sd, struct vfp_single *vs, u32 fpscr, u32 exce | |||
203 | vfp_put_float(sd, d); | 203 | vfp_put_float(sd, d); |
204 | } | 204 | } |
205 | 205 | ||
206 | return exceptions & ~VFP_NAN_FLAG; | 206 | return exceptions; |
207 | } | 207 | } |
208 | 208 | ||
209 | /* | 209 | /* |
diff --git a/arch/i386/Kconfig.debug b/arch/i386/Kconfig.debug index 6e97df6979e8..c92191b1fb67 100644 --- a/arch/i386/Kconfig.debug +++ b/arch/i386/Kconfig.debug | |||
@@ -81,4 +81,13 @@ config X86_MPPARSE | |||
81 | depends on X86_LOCAL_APIC && !X86_VISWS | 81 | depends on X86_LOCAL_APIC && !X86_VISWS |
82 | default y | 82 | default y |
83 | 83 | ||
84 | config DOUBLEFAULT | ||
85 | default y | ||
86 | bool "Enable doublefault exception handler" if EMBEDDED | ||
87 | help | ||
88 | This option allows trapping of rare doublefault exceptions that | ||
89 | would otherwise cause a system to silently reboot. Disabling this | ||
90 | option saves about 4k and might cause you much additional grey | ||
91 | hair. | ||
92 | |||
84 | endmenu | 93 | endmenu |
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c index 030a0007a4e0..049a25583793 100644 --- a/arch/i386/kernel/acpi/boot.c +++ b/arch/i386/kernel/acpi/boot.c | |||
@@ -168,7 +168,7 @@ int __init acpi_parse_mcfg(unsigned long phys_addr, unsigned long size) | |||
168 | unsigned long i; | 168 | unsigned long i; |
169 | int config_size; | 169 | int config_size; |
170 | 170 | ||
171 | if (!phys_addr || !size || !cpu_has_apic) | 171 | if (!phys_addr || !size) |
172 | return -EINVAL; | 172 | return -EINVAL; |
173 | 173 | ||
174 | mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); | 174 | mcfg = (struct acpi_table_mcfg *)__acpi_map_table(phys_addr, size); |
@@ -1102,6 +1102,9 @@ int __init acpi_boot_table_init(void) | |||
1102 | dmi_check_system(acpi_dmi_table); | 1102 | dmi_check_system(acpi_dmi_table); |
1103 | #endif | 1103 | #endif |
1104 | 1104 | ||
1105 | if (!cpu_has_apic) | ||
1106 | return -ENODEV; | ||
1107 | |||
1105 | /* | 1108 | /* |
1106 | * If acpi_disabled, bail out | 1109 | * If acpi_disabled, bail out |
1107 | * One exception: acpi=ht continues far enough to enumerate LAPICs | 1110 | * One exception: acpi=ht continues far enough to enumerate LAPICs |
diff --git a/arch/i386/kernel/apm.c b/arch/i386/kernel/apm.c index da30a374dd4e..df0e1745f189 100644 --- a/arch/i386/kernel/apm.c +++ b/arch/i386/kernel/apm.c | |||
@@ -1079,7 +1079,7 @@ static int apm_console_blank(int blank) | |||
1079 | break; | 1079 | break; |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | if (error == APM_NOT_ENGAGED && state != APM_STATE_READY) { | 1082 | if (error == APM_NOT_ENGAGED) { |
1083 | static int tried; | 1083 | static int tried; |
1084 | int eng_error; | 1084 | int eng_error; |
1085 | if (tried++ == 0) { | 1085 | if (tried++ == 0) { |
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index ff2b2154ac1b..786d1a57048b 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -207,6 +207,8 @@ static void __init init_amd(struct cpuinfo_x86 *c) | |||
207 | set_bit(X86_FEATURE_K7, c->x86_capability); | 207 | set_bit(X86_FEATURE_K7, c->x86_capability); |
208 | break; | 208 | break; |
209 | } | 209 | } |
210 | if (c->x86 >= 6) | ||
211 | set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability); | ||
210 | 212 | ||
211 | display_cacheinfo(c); | 213 | display_cacheinfo(c); |
212 | 214 | ||
diff --git a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c index 7c0e160a2145..71fffa174425 100644 --- a/arch/i386/kernel/cpu/cpufreq/powernow-k8.c +++ b/arch/i386/kernel/cpu/cpufreq/powernow-k8.c | |||
@@ -905,14 +905,17 @@ static int powernowk8_target(struct cpufreq_policy *pol, unsigned targfreq, unsi | |||
905 | { | 905 | { |
906 | cpumask_t oldmask = CPU_MASK_ALL; | 906 | cpumask_t oldmask = CPU_MASK_ALL; |
907 | struct powernow_k8_data *data = powernow_data[pol->cpu]; | 907 | struct powernow_k8_data *data = powernow_data[pol->cpu]; |
908 | u32 checkfid = data->currfid; | 908 | u32 checkfid; |
909 | u32 checkvid = data->currvid; | 909 | u32 checkvid; |
910 | unsigned int newstate; | 910 | unsigned int newstate; |
911 | int ret = -EIO; | 911 | int ret = -EIO; |
912 | 912 | ||
913 | if (!data) | 913 | if (!data) |
914 | return -EINVAL; | 914 | return -EINVAL; |
915 | 915 | ||
916 | checkfid = data->currfid; | ||
917 | checkvid = data->currvid; | ||
918 | |||
916 | /* only run on specific CPU from here on */ | 919 | /* only run on specific CPU from here on */ |
917 | oldmask = current->cpus_allowed; | 920 | oldmask = current->cpus_allowed; |
918 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); | 921 | set_cpus_allowed(current, cpumask_of_cpu(pol->cpu)); |
@@ -1109,9 +1112,6 @@ static unsigned int powernowk8_get (unsigned int cpu) | |||
1109 | if (!data) | 1112 | if (!data) |
1110 | return -EINVAL; | 1113 | return -EINVAL; |
1111 | 1114 | ||
1112 | if (!data) | ||
1113 | return -EINVAL; | ||
1114 | |||
1115 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); | 1115 | set_cpus_allowed(current, cpumask_of_cpu(cpu)); |
1116 | if (smp_processor_id() != cpu) { | 1116 | if (smp_processor_id() != cpu) { |
1117 | printk(KERN_ERR PFX "limiting to CPU %d failed in powernowk8_get\n", cpu); | 1117 | printk(KERN_ERR PFX "limiting to CPU %d failed in powernowk8_get\n", cpu); |
diff --git a/arch/i386/kernel/cpu/intel_cacheinfo.c b/arch/i386/kernel/cpu/intel_cacheinfo.c index 9df87b03612c..c8547a6fa7e6 100644 --- a/arch/i386/kernel/cpu/intel_cacheinfo.c +++ b/arch/i386/kernel/cpu/intel_cacheinfo.c | |||
@@ -642,7 +642,7 @@ static void __cpuexit cache_remove_dev(struct sys_device * sys_dev) | |||
642 | return; | 642 | return; |
643 | } | 643 | } |
644 | 644 | ||
645 | static int __cpuinit cacheinfo_cpu_callback(struct notifier_block *nfb, | 645 | static int cacheinfo_cpu_callback(struct notifier_block *nfb, |
646 | unsigned long action, void *hcpu) | 646 | unsigned long action, void *hcpu) |
647 | { | 647 | { |
648 | unsigned int cpu = (unsigned long)hcpu; | 648 | unsigned int cpu = (unsigned long)hcpu; |
diff --git a/arch/i386/kernel/cpuid.c b/arch/i386/kernel/cpuid.c index 006141d1c12a..1d9a4abcdfc7 100644 --- a/arch/i386/kernel/cpuid.c +++ b/arch/i386/kernel/cpuid.c | |||
@@ -168,7 +168,7 @@ static int cpuid_class_device_create(int i) | |||
168 | return err; | 168 | return err; |
169 | } | 169 | } |
170 | 170 | ||
171 | static int __devinit cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 171 | static int cpuid_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
172 | { | 172 | { |
173 | unsigned int cpu = (unsigned long)hcpu; | 173 | unsigned int cpu = (unsigned long)hcpu; |
174 | 174 | ||
diff --git a/arch/i386/kernel/kprobes.c b/arch/i386/kernel/kprobes.c index f19768789e8a..043f5292e70a 100644 --- a/arch/i386/kernel/kprobes.c +++ b/arch/i386/kernel/kprobes.c | |||
@@ -43,7 +43,7 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; | |||
43 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | 43 | DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); |
44 | 44 | ||
45 | /* insert a jmp code */ | 45 | /* insert a jmp code */ |
46 | static inline void set_jmp_op(void *from, void *to) | 46 | static __always_inline void set_jmp_op(void *from, void *to) |
47 | { | 47 | { |
48 | struct __arch_jmp_op { | 48 | struct __arch_jmp_op { |
49 | char op; | 49 | char op; |
@@ -57,7 +57,7 @@ static inline void set_jmp_op(void *from, void *to) | |||
57 | /* | 57 | /* |
58 | * returns non-zero if opcodes can be boosted. | 58 | * returns non-zero if opcodes can be boosted. |
59 | */ | 59 | */ |
60 | static inline int can_boost(kprobe_opcode_t opcode) | 60 | static __always_inline int can_boost(kprobe_opcode_t opcode) |
61 | { | 61 | { |
62 | switch (opcode & 0xf0 ) { | 62 | switch (opcode & 0xf0 ) { |
63 | case 0x70: | 63 | case 0x70: |
@@ -88,7 +88,7 @@ static inline int can_boost(kprobe_opcode_t opcode) | |||
88 | /* | 88 | /* |
89 | * returns non-zero if opcode modifies the interrupt flag. | 89 | * returns non-zero if opcode modifies the interrupt flag. |
90 | */ | 90 | */ |
91 | static inline int is_IF_modifier(kprobe_opcode_t opcode) | 91 | static int __kprobes is_IF_modifier(kprobe_opcode_t opcode) |
92 | { | 92 | { |
93 | switch (opcode) { | 93 | switch (opcode) { |
94 | case 0xfa: /* cli */ | 94 | case 0xfa: /* cli */ |
@@ -138,7 +138,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) | |||
138 | mutex_unlock(&kprobe_mutex); | 138 | mutex_unlock(&kprobe_mutex); |
139 | } | 139 | } |
140 | 140 | ||
141 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 141 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
142 | { | 142 | { |
143 | kcb->prev_kprobe.kp = kprobe_running(); | 143 | kcb->prev_kprobe.kp = kprobe_running(); |
144 | kcb->prev_kprobe.status = kcb->kprobe_status; | 144 | kcb->prev_kprobe.status = kcb->kprobe_status; |
@@ -146,7 +146,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
146 | kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags; | 146 | kcb->prev_kprobe.saved_eflags = kcb->kprobe_saved_eflags; |
147 | } | 147 | } |
148 | 148 | ||
149 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 149 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
150 | { | 150 | { |
151 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 151 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
152 | kcb->kprobe_status = kcb->prev_kprobe.status; | 152 | kcb->kprobe_status = kcb->prev_kprobe.status; |
@@ -154,7 +154,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
154 | kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags; | 154 | kcb->kprobe_saved_eflags = kcb->prev_kprobe.saved_eflags; |
155 | } | 155 | } |
156 | 156 | ||
157 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | 157 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
158 | struct kprobe_ctlblk *kcb) | 158 | struct kprobe_ctlblk *kcb) |
159 | { | 159 | { |
160 | __get_cpu_var(current_kprobe) = p; | 160 | __get_cpu_var(current_kprobe) = p; |
@@ -164,7 +164,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | |||
164 | kcb->kprobe_saved_eflags &= ~IF_MASK; | 164 | kcb->kprobe_saved_eflags &= ~IF_MASK; |
165 | } | 165 | } |
166 | 166 | ||
167 | static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 167 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) |
168 | { | 168 | { |
169 | regs->eflags |= TF_MASK; | 169 | regs->eflags |= TF_MASK; |
170 | regs->eflags &= ~IF_MASK; | 170 | regs->eflags &= ~IF_MASK; |
@@ -507,7 +507,7 @@ no_change: | |||
507 | * Interrupts are disabled on entry as trap1 is an interrupt gate and they | 507 | * Interrupts are disabled on entry as trap1 is an interrupt gate and they |
508 | * remain disabled thoroughout this function. | 508 | * remain disabled thoroughout this function. |
509 | */ | 509 | */ |
510 | static inline int post_kprobe_handler(struct pt_regs *regs) | 510 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
511 | { | 511 | { |
512 | struct kprobe *cur = kprobe_running(); | 512 | struct kprobe *cur = kprobe_running(); |
513 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 513 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -543,7 +543,7 @@ out: | |||
543 | return 1; | 543 | return 1; |
544 | } | 544 | } |
545 | 545 | ||
546 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 546 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
547 | { | 547 | { |
548 | struct kprobe *cur = kprobe_running(); | 548 | struct kprobe *cur = kprobe_running(); |
549 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 549 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
diff --git a/arch/i386/kernel/msr.c b/arch/i386/kernel/msr.c index 1d0a55e68760..7a328230e540 100644 --- a/arch/i386/kernel/msr.c +++ b/arch/i386/kernel/msr.c | |||
@@ -251,7 +251,7 @@ static int msr_class_device_create(int i) | |||
251 | return err; | 251 | return err; |
252 | } | 252 | } |
253 | 253 | ||
254 | static int __devinit msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 254 | static int msr_class_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
255 | { | 255 | { |
256 | unsigned int cpu = (unsigned long)hcpu; | 256 | unsigned int cpu = (unsigned long)hcpu; |
257 | 257 | ||
diff --git a/arch/i386/mach-voyager/voyager_cat.c b/arch/i386/mach-voyager/voyager_cat.c index 3039539de51e..10d21df14531 100644 --- a/arch/i386/mach-voyager/voyager_cat.c +++ b/arch/i386/mach-voyager/voyager_cat.c | |||
@@ -120,7 +120,6 @@ static struct resource qic_res = { | |||
120 | * It writes num_bits of the data buffer in msg starting at start_bit. | 120 | * It writes num_bits of the data buffer in msg starting at start_bit. |
121 | * Note: This function assumes that any unused bit in the data stream | 121 | * Note: This function assumes that any unused bit in the data stream |
122 | * is set to zero so that the ors will work correctly */ | 122 | * is set to zero so that the ors will work correctly */ |
123 | #define BITS_PER_BYTE 8 | ||
124 | static void | 123 | static void |
125 | cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits) | 124 | cat_pack(__u8 *msg, const __u16 start_bit, __u8 *data, const __u16 num_bits) |
126 | { | 125 | { |
diff --git a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S index e30798811216..bcb80ca5cf40 100644 --- a/arch/ia64/kernel/entry.S +++ b/arch/ia64/kernel/entry.S | |||
@@ -1610,5 +1610,6 @@ sys_call_table: | |||
1610 | data8 sys_get_robust_list | 1610 | data8 sys_get_robust_list |
1611 | data8 sys_sync_file_range // 1300 | 1611 | data8 sys_sync_file_range // 1300 |
1612 | data8 sys_tee | 1612 | data8 sys_tee |
1613 | data8 sys_vmsplice | ||
1613 | 1614 | ||
1614 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls | 1615 | .org sys_call_table + 8*NR_syscalls // guard against failures to increase NR_syscalls |
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c index 789881ca83d4..f9039f88d01d 100644 --- a/arch/ia64/kernel/kprobes.c +++ b/arch/ia64/kernel/kprobes.c | |||
@@ -251,7 +251,7 @@ static void __kprobes prepare_break_inst(uint template, uint slot, | |||
251 | update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p); | 251 | update_kprobe_inst_flag(template, slot, major_opcode, kprobe_inst, p); |
252 | } | 252 | } |
253 | 253 | ||
254 | static inline void get_kprobe_inst(bundle_t *bundle, uint slot, | 254 | static void __kprobes get_kprobe_inst(bundle_t *bundle, uint slot, |
255 | unsigned long *kprobe_inst, uint *major_opcode) | 255 | unsigned long *kprobe_inst, uint *major_opcode) |
256 | { | 256 | { |
257 | unsigned long kprobe_inst_p0, kprobe_inst_p1; | 257 | unsigned long kprobe_inst_p0, kprobe_inst_p1; |
@@ -278,7 +278,7 @@ static inline void get_kprobe_inst(bundle_t *bundle, uint slot, | |||
278 | } | 278 | } |
279 | 279 | ||
280 | /* Returns non-zero if the addr is in the Interrupt Vector Table */ | 280 | /* Returns non-zero if the addr is in the Interrupt Vector Table */ |
281 | static inline int in_ivt_functions(unsigned long addr) | 281 | static int __kprobes in_ivt_functions(unsigned long addr) |
282 | { | 282 | { |
283 | return (addr >= (unsigned long)__start_ivt_text | 283 | return (addr >= (unsigned long)__start_ivt_text |
284 | && addr < (unsigned long)__end_ivt_text); | 284 | && addr < (unsigned long)__end_ivt_text); |
@@ -308,19 +308,19 @@ static int __kprobes valid_kprobe_addr(int template, int slot, | |||
308 | return 0; | 308 | return 0; |
309 | } | 309 | } |
310 | 310 | ||
311 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 311 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
312 | { | 312 | { |
313 | kcb->prev_kprobe.kp = kprobe_running(); | 313 | kcb->prev_kprobe.kp = kprobe_running(); |
314 | kcb->prev_kprobe.status = kcb->kprobe_status; | 314 | kcb->prev_kprobe.status = kcb->kprobe_status; |
315 | } | 315 | } |
316 | 316 | ||
317 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 317 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
318 | { | 318 | { |
319 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 319 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
320 | kcb->kprobe_status = kcb->prev_kprobe.status; | 320 | kcb->kprobe_status = kcb->prev_kprobe.status; |
321 | } | 321 | } |
322 | 322 | ||
323 | static inline void set_current_kprobe(struct kprobe *p, | 323 | static void __kprobes set_current_kprobe(struct kprobe *p, |
324 | struct kprobe_ctlblk *kcb) | 324 | struct kprobe_ctlblk *kcb) |
325 | { | 325 | { |
326 | __get_cpu_var(current_kprobe) = p; | 326 | __get_cpu_var(current_kprobe) = p; |
diff --git a/arch/ia64/kernel/palinfo.c b/arch/ia64/kernel/palinfo.c index 6386f63c413e..859fb37ff49b 100644 --- a/arch/ia64/kernel/palinfo.c +++ b/arch/ia64/kernel/palinfo.c | |||
@@ -959,7 +959,7 @@ remove_palinfo_proc_entries(unsigned int hcpu) | |||
959 | } | 959 | } |
960 | } | 960 | } |
961 | 961 | ||
962 | static int __devinit palinfo_cpu_callback(struct notifier_block *nfb, | 962 | static int palinfo_cpu_callback(struct notifier_block *nfb, |
963 | unsigned long action, | 963 | unsigned long action, |
964 | void *hcpu) | 964 | void *hcpu) |
965 | { | 965 | { |
diff --git a/arch/ia64/kernel/salinfo.c b/arch/ia64/kernel/salinfo.c index 9d5a823479a3..663a186ad194 100644 --- a/arch/ia64/kernel/salinfo.c +++ b/arch/ia64/kernel/salinfo.c | |||
@@ -572,7 +572,7 @@ static struct file_operations salinfo_data_fops = { | |||
572 | }; | 572 | }; |
573 | 573 | ||
574 | #ifdef CONFIG_HOTPLUG_CPU | 574 | #ifdef CONFIG_HOTPLUG_CPU |
575 | static int __devinit | 575 | static int |
576 | salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) | 576 | salinfo_cpu_callback(struct notifier_block *nb, unsigned long action, void *hcpu) |
577 | { | 577 | { |
578 | unsigned int i, cpu = (unsigned long)hcpu; | 578 | unsigned int i, cpu = (unsigned long)hcpu; |
diff --git a/arch/ia64/kernel/topology.c b/arch/ia64/kernel/topology.c index b47476d655f1..7da4739f536e 100644 --- a/arch/ia64/kernel/topology.c +++ b/arch/ia64/kernel/topology.c | |||
@@ -429,7 +429,7 @@ static int __cpuinit cache_remove_dev(struct sys_device * sys_dev) | |||
429 | * When a cpu is hot-plugged, do a check and initiate | 429 | * When a cpu is hot-plugged, do a check and initiate |
430 | * cache kobject if necessary | 430 | * cache kobject if necessary |
431 | */ | 431 | */ |
432 | static int __cpuinit cache_cpu_callback(struct notifier_block *nfb, | 432 | static int cache_cpu_callback(struct notifier_block *nfb, |
433 | unsigned long action, void *hcpu) | 433 | unsigned long action, void *hcpu) |
434 | { | 434 | { |
435 | unsigned int cpu = (unsigned long)hcpu; | 435 | unsigned int cpu = (unsigned long)hcpu; |
diff --git a/arch/m32r/kernel/entry.S b/arch/m32r/kernel/entry.S index 3871b65f0c82..920bb742b7a2 100644 --- a/arch/m32r/kernel/entry.S +++ b/arch/m32r/kernel/entry.S | |||
@@ -20,7 +20,7 @@ | |||
20 | * Stack layout in 'ret_from_system_call': | 20 | * Stack layout in 'ret_from_system_call': |
21 | * ptrace needs to have all regs on the stack. | 21 | * ptrace needs to have all regs on the stack. |
22 | * if the order here is changed, it needs to be | 22 | * if the order here is changed, it needs to be |
23 | * updated in fork.c:copy_process, signal.c:do_signal, | 23 | * updated in fork.c:copy_thread, signal.c:do_signal, |
24 | * ptrace.c and ptrace.h | 24 | * ptrace.c and ptrace.h |
25 | * | 25 | * |
26 | * M32Rx/M32R2 M32R | 26 | * M32Rx/M32R2 M32R |
@@ -41,18 +41,17 @@ | |||
41 | * @(0x38,sp) - syscall_nr ditto | 41 | * @(0x38,sp) - syscall_nr ditto |
42 | * @(0x3c,sp) - acc0h @(0x3c,sp) - acch | 42 | * @(0x3c,sp) - acc0h @(0x3c,sp) - acch |
43 | * @(0x40,sp) - acc0l @(0x40,sp) - accl | 43 | * @(0x40,sp) - acc0l @(0x40,sp) - accl |
44 | * @(0x44,sp) - acc1h @(0x44,sp) - psw | 44 | * @(0x44,sp) - acc1h @(0x44,sp) - dummy_acc1h |
45 | * @(0x48,sp) - acc1l @(0x48,sp) - bpc | 45 | * @(0x48,sp) - acc1l @(0x48,sp) - dummy_acc1l |
46 | * @(0x4c,sp) - psw @(0x4c,sp) - bbpsw | 46 | * @(0x4c,sp) - psw ditto |
47 | * @(0x50,sp) - bpc @(0x50,sp) - bbpc | 47 | * @(0x50,sp) - bpc ditto |
48 | * @(0x54,sp) - bbpsw @(0x54,sp) - spu (cr3) | 48 | * @(0x54,sp) - bbpsw ditto |
49 | * @(0x58,sp) - bbpc @(0x58,sp) - fp (r13) | 49 | * @(0x58,sp) - bbpc ditto |
50 | * @(0x5c,sp) - spu (cr3) @(0x5c,sp) - lr (r14) | 50 | * @(0x5c,sp) - spu (cr3) ditto |
51 | * @(0x60,sp) - fp (r13) @(0x60,sp) - spi (cr12) | 51 | * @(0x60,sp) - fp (r13) ditto |
52 | * @(0x64,sp) - lr (r14) @(0x64,sp) - orig_r0 | 52 | * @(0x64,sp) - lr (r14) ditto |
53 | * @(0x68,sp) - spi (cr2) | 53 | * @(0x68,sp) - spi (cr2) ditto |
54 | * @(0x6c,sp) - orig_r0 | 54 | * @(0x6c,sp) - orig_r0 ditto |
55 | * | ||
56 | */ | 55 | */ |
57 | 56 | ||
58 | #include <linux/config.h> | 57 | #include <linux/config.h> |
@@ -102,6 +101,12 @@ | |||
102 | #define ACC0L(reg) @(0x40,reg) | 101 | #define ACC0L(reg) @(0x40,reg) |
103 | #define ACC1H(reg) @(0x44,reg) | 102 | #define ACC1H(reg) @(0x44,reg) |
104 | #define ACC1L(reg) @(0x48,reg) | 103 | #define ACC1L(reg) @(0x48,reg) |
104 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | ||
105 | #define ACCH(reg) @(0x3C,reg) | ||
106 | #define ACCL(reg) @(0x40,reg) | ||
107 | #else | ||
108 | #error unknown isa configuration | ||
109 | #endif | ||
105 | #define PSW(reg) @(0x4C,reg) | 110 | #define PSW(reg) @(0x4C,reg) |
106 | #define BPC(reg) @(0x50,reg) | 111 | #define BPC(reg) @(0x50,reg) |
107 | #define BBPSW(reg) @(0x54,reg) | 112 | #define BBPSW(reg) @(0x54,reg) |
@@ -111,21 +116,6 @@ | |||
111 | #define LR(reg) @(0x64,reg) | 116 | #define LR(reg) @(0x64,reg) |
112 | #define SP(reg) @(0x68,reg) | 117 | #define SP(reg) @(0x68,reg) |
113 | #define ORIG_R0(reg) @(0x6C,reg) | 118 | #define ORIG_R0(reg) @(0x6C,reg) |
114 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | ||
115 | #define ACCH(reg) @(0x3C,reg) | ||
116 | #define ACCL(reg) @(0x40,reg) | ||
117 | #define PSW(reg) @(0x44,reg) | ||
118 | #define BPC(reg) @(0x48,reg) | ||
119 | #define BBPSW(reg) @(0x4C,reg) | ||
120 | #define BBPC(reg) @(0x50,reg) | ||
121 | #define SPU(reg) @(0x54,reg) | ||
122 | #define FP(reg) @(0x58,reg) /* FP = R13 */ | ||
123 | #define LR(reg) @(0x5C,reg) | ||
124 | #define SP(reg) @(0x60,reg) | ||
125 | #define ORIG_R0(reg) @(0x64,reg) | ||
126 | #else | ||
127 | #error unknown isa configuration | ||
128 | #endif | ||
129 | 119 | ||
130 | CF_MASK = 0x00000001 | 120 | CF_MASK = 0x00000001 |
131 | TF_MASK = 0x00000100 | 121 | TF_MASK = 0x00000100 |
@@ -142,7 +132,7 @@ VM_MASK = 0x00020000 | |||
142 | #endif | 132 | #endif |
143 | 133 | ||
144 | ENTRY(ret_from_fork) | 134 | ENTRY(ret_from_fork) |
145 | ld r0, @sp+ | 135 | pop r0 |
146 | bl schedule_tail | 136 | bl schedule_tail |
147 | GET_THREAD_INFO(r8) | 137 | GET_THREAD_INFO(r8) |
148 | bra syscall_exit | 138 | bra syscall_exit |
@@ -231,7 +221,7 @@ restore_all: | |||
231 | RESTORE_ALL | 221 | RESTORE_ALL |
232 | 222 | ||
233 | # perform work that needs to be done immediately before resumption | 223 | # perform work that needs to be done immediately before resumption |
234 | # r9 : frags | 224 | # r9 : flags |
235 | ALIGN | 225 | ALIGN |
236 | work_pending: | 226 | work_pending: |
237 | and3 r4, r9, #_TIF_NEED_RESCHED | 227 | and3 r4, r9, #_TIF_NEED_RESCHED |
@@ -320,7 +310,7 @@ ENTRY(ei_handler) | |||
320 | ; GET_ICU_STATUS; | 310 | ; GET_ICU_STATUS; |
321 | seth r0, #shigh(M32R_ICU_ISTS_ADDR) | 311 | seth r0, #shigh(M32R_ICU_ISTS_ADDR) |
322 | ld r0, @(low(M32R_ICU_ISTS_ADDR),r0) | 312 | ld r0, @(low(M32R_ICU_ISTS_ADDR),r0) |
323 | st r0, @-sp | 313 | push r0 |
324 | #if defined(CONFIG_SMP) | 314 | #if defined(CONFIG_SMP) |
325 | /* | 315 | /* |
326 | * If IRQ == 0 --> Nothing to do, Not write IMASK | 316 | * If IRQ == 0 --> Nothing to do, Not write IMASK |
@@ -557,7 +547,7 @@ check_end: | |||
557 | #endif /* CONFIG_PLAT_M32104UT */ | 547 | #endif /* CONFIG_PLAT_M32104UT */ |
558 | bl do_IRQ | 548 | bl do_IRQ |
559 | #endif /* CONFIG_SMP */ | 549 | #endif /* CONFIG_SMP */ |
560 | ld r14, @sp+ | 550 | pop r14 |
561 | seth r0, #shigh(M32R_ICU_IMASK_ADDR) | 551 | seth r0, #shigh(M32R_ICU_IMASK_ADDR) |
562 | st r14, @(low(M32R_ICU_IMASK_ADDR),r0) | 552 | st r14, @(low(M32R_ICU_IMASK_ADDR),r0) |
563 | #else | 553 | #else |
@@ -1015,4 +1005,3 @@ ENTRY(sys_call_table) | |||
1015 | .long sys_waitid | 1005 | .long sys_waitid |
1016 | 1006 | ||
1017 | syscall_table_size=(.-sys_call_table) | 1007 | syscall_table_size=(.-sys_call_table) |
1018 | |||
diff --git a/arch/m32r/kernel/process.c b/arch/m32r/kernel/process.c index 5dfc7ea45cf7..065f5e719058 100644 --- a/arch/m32r/kernel/process.c +++ b/arch/m32r/kernel/process.c | |||
@@ -116,6 +116,10 @@ void cpu_idle (void) | |||
116 | 116 | ||
117 | void machine_restart(char *__unused) | 117 | void machine_restart(char *__unused) |
118 | { | 118 | { |
119 | #if defined(CONFIG_PLAT_MAPPI3) | ||
120 | outw(1, (unsigned long)PLD_REBOOT); | ||
121 | #endif | ||
122 | |||
119 | printk("Please push reset button!\n"); | 123 | printk("Please push reset button!\n"); |
120 | while (1) | 124 | while (1) |
121 | cpu_relax(); | 125 | cpu_relax(); |
diff --git a/arch/m32r/kernel/signal.c b/arch/m32r/kernel/signal.c index cb33097fefc4..6498ee70bb73 100644 --- a/arch/m32r/kernel/signal.c +++ b/arch/m32r/kernel/signal.c | |||
@@ -118,6 +118,8 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc, | |||
118 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | 118 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) |
119 | COPY(acch); | 119 | COPY(acch); |
120 | COPY(accl); | 120 | COPY(accl); |
121 | COPY(dummy_acc1h); | ||
122 | COPY(dummy_acc1l); | ||
121 | #else | 123 | #else |
122 | #error unknown isa configuration | 124 | #error unknown isa configuration |
123 | #endif | 125 | #endif |
@@ -203,6 +205,8 @@ setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs, | |||
203 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | 205 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) |
204 | COPY(acch); | 206 | COPY(acch); |
205 | COPY(accl); | 207 | COPY(accl); |
208 | COPY(dummy_acc1h); | ||
209 | COPY(dummy_acc1l); | ||
206 | #else | 210 | #else |
207 | #error unknown isa configuration | 211 | #error unknown isa configuration |
208 | #endif | 212 | #endif |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 7aec60d40420..87f0b79c6b15 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -816,6 +816,10 @@ config GENERIC_CALIBRATE_DELAY | |||
816 | bool | 816 | bool |
817 | default y | 817 | default y |
818 | 818 | ||
819 | config SCHED_NO_NO_OMIT_FRAME_POINTER | ||
820 | bool | ||
821 | default y | ||
822 | |||
819 | # | 823 | # |
820 | # Select some configuration options automatically based on user selections. | 824 | # Select some configuration options automatically based on user selections. |
821 | # | 825 | # |
@@ -1443,6 +1447,10 @@ choice | |||
1443 | prompt "MIPS MT options" | 1447 | prompt "MIPS MT options" |
1444 | depends on MIPS_MT | 1448 | depends on MIPS_MT |
1445 | 1449 | ||
1450 | config MIPS_MT_SMTC | ||
1451 | bool "SMTC: Use all TCs on all VPEs for SMP" | ||
1452 | select SMP | ||
1453 | |||
1446 | config MIPS_MT_SMP | 1454 | config MIPS_MT_SMP |
1447 | bool "Use 1 TC on each available VPE for SMP" | 1455 | bool "Use 1 TC on each available VPE for SMP" |
1448 | select SMP | 1456 | select SMP |
@@ -1456,6 +1464,11 @@ config MIPS_VPE_LOADER | |||
1456 | 1464 | ||
1457 | endchoice | 1465 | endchoice |
1458 | 1466 | ||
1467 | config MIPS_MT_FPAFF | ||
1468 | bool "Dynamic FPU affinity for FP-intensive threads" | ||
1469 | depends on MIPS_MT | ||
1470 | default y | ||
1471 | |||
1459 | config MIPS_VPE_LOADER_TOM | 1472 | config MIPS_VPE_LOADER_TOM |
1460 | bool "Load VPE program into memory hidden from linux" | 1473 | bool "Load VPE program into memory hidden from linux" |
1461 | depends on MIPS_VPE_LOADER | 1474 | depends on MIPS_VPE_LOADER |
@@ -1472,6 +1485,16 @@ config MIPS_VPE_APSP_API | |||
1472 | depends on MIPS_VPE_LOADER | 1485 | depends on MIPS_VPE_LOADER |
1473 | help | 1486 | help |
1474 | 1487 | ||
1488 | config MIPS_APSP_KSPD | ||
1489 | bool "Enable KSPD" | ||
1490 | depends on MIPS_VPE_APSP_API | ||
1491 | default y | ||
1492 | help | ||
1493 | KSPD is a kernel daemon that accepts syscall requests from the SP | ||
1494 | side, actions them and returns the results. It also handles the | ||
1495 | "exit" syscall notifying other kernel modules the SP program is | ||
1496 | exiting. You probably want to say yes here. | ||
1497 | |||
1475 | config SB1_PASS_1_WORKAROUNDS | 1498 | config SB1_PASS_1_WORKAROUNDS |
1476 | bool | 1499 | bool |
1477 | depends on CPU_SB1_PASS_1 | 1500 | depends on CPU_SB1_PASS_1 |
@@ -1599,7 +1622,7 @@ source "mm/Kconfig" | |||
1599 | 1622 | ||
1600 | config SMP | 1623 | config SMP |
1601 | bool "Multi-Processing support" | 1624 | bool "Multi-Processing support" |
1602 | depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250 || QEMU) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP | 1625 | depends on CPU_RM9000 || ((SIBYTE_BCM1x80 || SIBYTE_BCM1x55 || SIBYTE_SB1250 || QEMU) && !SIBYTE_STANDALONE) || SGI_IP27 || MIPS_MT_SMP || MIPS_MT_SMTC |
1603 | ---help--- | 1626 | ---help--- |
1604 | This enables support for systems with more than one CPU. If you have | 1627 | This enables support for systems with more than one CPU. If you have |
1605 | a system with only one CPU, like most personal computers, say N. If | 1628 | a system with only one CPU, like most personal computers, say N. If |
diff --git a/arch/mips/Makefile b/arch/mips/Makefile index 9a69e0f0ab76..69b9c1b8fafc 100644 --- a/arch/mips/Makefile +++ b/arch/mips/Makefile | |||
@@ -105,18 +105,18 @@ cflags-$(CONFIG_CPU_R4300) += -march=r4300 -Wa,--trap | |||
105 | cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap | 105 | cflags-$(CONFIG_CPU_VR41XX) += -march=r4100 -Wa,--trap |
106 | cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap | 106 | cflags-$(CONFIG_CPU_R4X00) += -march=r4600 -Wa,--trap |
107 | cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap | 107 | cflags-$(CONFIG_CPU_TX49XX) += -march=r4600 -Wa,--trap |
108 | cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips2 -mtune=r4600) \ | 108 | cflags-$(CONFIG_CPU_MIPS32_R1) += $(call cc-option,-march=mips32,-mips32 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ |
109 | -Wa,-mips32 -Wa,--trap | 109 | -Wa,-mips32 -Wa,--trap |
110 | cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips2 -mtune=r4600) \ | 110 | cflags-$(CONFIG_CPU_MIPS32_R2) += $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \ |
111 | -Wa,-mips32r2 -Wa,--trap | 111 | -Wa,-mips32r2 -Wa,--trap |
112 | cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips2 -mtune=r4600) \ | 112 | cflags-$(CONFIG_CPU_MIPS64_R1) += $(call cc-option,-march=mips64,-mips64 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \ |
113 | -Wa,-mips64 -Wa,--trap | 113 | -Wa,-mips64 -Wa,--trap |
114 | cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips2 -mtune=r4600 ) \ | 114 | cflags-$(CONFIG_CPU_MIPS64_R2) += $(call cc-option,-march=mips64r2,-mips64r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS64) \ |
115 | -Wa,-mips64r2 -Wa,--trap | 115 | -Wa,-mips64r2 -Wa,--trap |
116 | cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap | 116 | cflags-$(CONFIG_CPU_R5000) += -march=r5000 -Wa,--trap |
117 | cflags-$(CONFIG_CPU_R5432) += $(call cc-options,-march=r5400,-march=r5000) \ | 117 | cflags-$(CONFIG_CPU_R5432) += $(call cc-option,-march=r5400,-march=r5000) \ |
118 | -Wa,--trap | 118 | -Wa,--trap |
119 | cflags-$(CONFIG_CPU_NEVADA) += $(call cc-options,-march=rm5200,-march=r5000) \ | 119 | cflags-$(CONFIG_CPU_NEVADA) += $(call cc-option,-march=rm5200,-march=r5000) \ |
120 | -Wa,--trap | 120 | -Wa,--trap |
121 | cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ | 121 | cflags-$(CONFIG_CPU_RM7000) += $(call cc-option,-march=rm7000,-march=r5000) \ |
122 | -Wa,--trap | 122 | -Wa,--trap |
diff --git a/arch/mips/au1000/common/Makefile b/arch/mips/au1000/common/Makefile index a1edfd1f643c..bf682f50b859 100644 --- a/arch/mips/au1000/common/Makefile +++ b/arch/mips/au1000/common/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | # Makefile for the Alchemy Au1000 CPU, generic files. | 6 | # Makefile for the Alchemy Au1000 CPU, generic files. |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += prom.o int-handler.o irq.o puts.o time.o reset.o \ | 9 | obj-y += prom.o irq.o puts.o time.o reset.o \ |
10 | au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ | 10 | au1xxx_irqmap.o clocks.o platform.o power.o setup.o \ |
11 | sleeper.o cputable.o dma.o dbdma.o gpio.o | 11 | sleeper.o cputable.o dma.o dbdma.o gpio.o |
12 | 12 | ||
diff --git a/arch/mips/au1000/common/int-handler.S b/arch/mips/au1000/common/int-handler.S deleted file mode 100644 index 1c4ca883321e..000000000000 --- a/arch/mips/au1000/common/int-handler.S +++ /dev/null | |||
@@ -1,68 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: ppopov@mvista.com | ||
4 | * | ||
5 | * Interrupt dispatcher for Au1000 boards. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | |||
18 | .text | ||
19 | .set macro | ||
20 | .set noat | ||
21 | .align 5 | ||
22 | |||
23 | NESTED(au1000_IRQ, PT_SIZE, sp) | ||
24 | SAVE_ALL | ||
25 | CLI # Important: mark KERNEL mode ! | ||
26 | |||
27 | mfc0 t0,CP0_CAUSE # get pending interrupts | ||
28 | mfc0 t1,CP0_STATUS # get enabled interrupts | ||
29 | and t0,t1 # isolate allowed ones | ||
30 | |||
31 | andi t0,0xff00 # isolate pending bits | ||
32 | beqz t0, 3f # spurious interrupt | ||
33 | |||
34 | andi a0, t0, CAUSEF_IP7 | ||
35 | beq a0, zero, 1f | ||
36 | move a0, sp | ||
37 | jal mips_timer_interrupt | ||
38 | j ret_from_irq | ||
39 | |||
40 | 1: | ||
41 | andi a0, t0, CAUSEF_IP2 # Interrupt Controller 0, Request 0 | ||
42 | beq a0, zero, 2f | ||
43 | move a0,sp | ||
44 | jal intc0_req0_irqdispatch | ||
45 | j ret_from_irq | ||
46 | 2: | ||
47 | andi a0, t0, CAUSEF_IP3 # Interrupt Controller 0, Request 1 | ||
48 | beq a0, zero, 3f | ||
49 | move a0,sp | ||
50 | jal intc0_req1_irqdispatch | ||
51 | j ret_from_irq | ||
52 | 3: | ||
53 | andi a0, t0, CAUSEF_IP4 # Interrupt Controller 1, Request 0 | ||
54 | beq a0, zero, 4f | ||
55 | move a0,sp | ||
56 | jal intc1_req0_irqdispatch | ||
57 | j ret_from_irq | ||
58 | 4: | ||
59 | andi a0, t0, CAUSEF_IP5 # Interrupt Controller 1, Request 1 | ||
60 | beq a0, zero, 5f | ||
61 | move a0, sp | ||
62 | jal intc1_req1_irqdispatch | ||
63 | j ret_from_irq | ||
64 | |||
65 | 5: | ||
66 | move a0, sp | ||
67 | j spurious_interrupt | ||
68 | END(au1000_IRQ) | ||
diff --git a/arch/mips/au1000/common/irq.c b/arch/mips/au1000/common/irq.c index 1339a0979f66..da61de776154 100644 --- a/arch/mips/au1000/common/irq.c +++ b/arch/mips/au1000/common/irq.c | |||
@@ -66,7 +66,6 @@ | |||
66 | #define EXT_INTC1_REQ1 5 /* IP 5 */ | 66 | #define EXT_INTC1_REQ1 5 /* IP 5 */ |
67 | #define MIPS_TIMER_IP 7 /* IP 7 */ | 67 | #define MIPS_TIMER_IP 7 /* IP 7 */ |
68 | 68 | ||
69 | extern asmlinkage void au1000_IRQ(void); | ||
70 | extern void set_debug_traps(void); | 69 | extern void set_debug_traps(void); |
71 | extern irq_cpustat_t irq_stat [NR_CPUS]; | 70 | extern irq_cpustat_t irq_stat [NR_CPUS]; |
72 | 71 | ||
@@ -446,7 +445,6 @@ void __init arch_init_irq(void) | |||
446 | extern int au1xxx_ic0_nr_irqs; | 445 | extern int au1xxx_ic0_nr_irqs; |
447 | 446 | ||
448 | cp0_status = read_c0_status(); | 447 | cp0_status = read_c0_status(); |
449 | set_except_vector(0, au1000_IRQ); | ||
450 | 448 | ||
451 | /* Initialize interrupt controllers to a safe state. | 449 | /* Initialize interrupt controllers to a safe state. |
452 | */ | 450 | */ |
@@ -661,3 +659,21 @@ restore_au1xxx_intctl(void) | |||
661 | au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); | 659 | au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync(); |
662 | } | 660 | } |
663 | #endif /* CONFIG_PM */ | 661 | #endif /* CONFIG_PM */ |
662 | |||
663 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
664 | { | ||
665 | unsigned int pending = read_c0_status() & read_c0_cause() & ST0_IM; | ||
666 | |||
667 | if (pending & CAUSEF_IP7) | ||
668 | mips_timer_interrupt(regs); | ||
669 | else if (pending & CAUSEF_IP2) | ||
670 | intc0_req0_irqdispatch(regs); | ||
671 | else if (pending & CAUSEF_IP3) | ||
672 | intc0_req1_irqdispatch(regs); | ||
673 | else if (pending & CAUSEF_IP4) | ||
674 | intc1_req0_irqdispatch(regs); | ||
675 | else if (pending & CAUSEF_IP5) | ||
676 | intc1_req1_irqdispatch(regs); | ||
677 | else | ||
678 | spurious_interrupt(regs); | ||
679 | } | ||
diff --git a/arch/mips/cobalt/Makefile b/arch/mips/cobalt/Makefile index 720e757b2b64..225ac8f34ccd 100644 --- a/arch/mips/cobalt/Makefile +++ b/arch/mips/cobalt/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the Cobalt micro systems family specific parts of the kernel | 2 | # Makefile for the Cobalt micro systems family specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := irq.o int-handler.o reset.o setup.o | 5 | obj-y := irq.o reset.o setup.o |
6 | 6 | ||
7 | obj-$(CONFIG_EARLY_PRINTK) += console.o | 7 | obj-$(CONFIG_EARLY_PRINTK) += console.o |
8 | 8 | ||
diff --git a/arch/mips/cobalt/int-handler.S b/arch/mips/cobalt/int-handler.S deleted file mode 100644 index e75d5e3ca868..000000000000 --- a/arch/mips/cobalt/int-handler.S +++ /dev/null | |||
@@ -1,25 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1995, 1996, 1997, 2003 by Ralf Baechle | ||
7 | * Copyright (C) 2001, 2002, 2003 by Liam Davies (ldavies@agile.tv) | ||
8 | */ | ||
9 | #include <asm/asm.h> | ||
10 | #include <asm/mipsregs.h> | ||
11 | #include <asm/mach-cobalt/cobalt.h> | ||
12 | #include <asm/regdef.h> | ||
13 | #include <asm/stackframe.h> | ||
14 | |||
15 | .text | ||
16 | .align 5 | ||
17 | NESTED(cobalt_handle_int, PT_SIZE, sp) | ||
18 | SAVE_ALL | ||
19 | CLI | ||
20 | |||
21 | PTR_LA ra, ret_from_irq | ||
22 | move a0, sp | ||
23 | j cobalt_irq | ||
24 | |||
25 | END(cobalt_handle_int) | ||
diff --git a/arch/mips/cobalt/irq.c b/arch/mips/cobalt/irq.c index f9a108820d6e..0b75f4fb7195 100644 --- a/arch/mips/cobalt/irq.c +++ b/arch/mips/cobalt/irq.c | |||
@@ -20,8 +20,6 @@ | |||
20 | 20 | ||
21 | #include <asm/mach-cobalt/cobalt.h> | 21 | #include <asm/mach-cobalt/cobalt.h> |
22 | 22 | ||
23 | extern void cobalt_handle_int(void); | ||
24 | |||
25 | /* | 23 | /* |
26 | * We have two types of interrupts that we handle, ones that come in through | 24 | * We have two types of interrupts that we handle, ones that come in through |
27 | * the CPU interrupt lines, and ones that come in on the via chip. The CPU | 25 | * the CPU interrupt lines, and ones that come in on the via chip. The CPU |
@@ -79,7 +77,7 @@ static inline void via_pic_irq(struct pt_regs *regs) | |||
79 | do_IRQ(irq, regs); | 77 | do_IRQ(irq, regs); |
80 | } | 78 | } |
81 | 79 | ||
82 | asmlinkage void cobalt_irq(struct pt_regs *regs) | 80 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
83 | { | 81 | { |
84 | unsigned pending; | 82 | unsigned pending; |
85 | 83 | ||
@@ -122,8 +120,6 @@ void __init arch_init_irq(void) | |||
122 | */ | 120 | */ |
123 | GALILEO_OUTL(0, GT_INTRMASK_OFS); | 121 | GALILEO_OUTL(0, GT_INTRMASK_OFS); |
124 | 122 | ||
125 | set_except_vector(0, cobalt_handle_int); | ||
126 | |||
127 | init_i8259_irqs(); /* 0 ... 15 */ | 123 | init_i8259_irqs(); /* 0 ... 15 */ |
128 | mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */ | 124 | mips_cpu_irq_init(COBALT_CPU_IRQ); /* 16 ... 23 */ |
129 | 125 | ||
diff --git a/arch/mips/configs/tb0287_defconfig b/arch/mips/configs/tb0287_defconfig new file mode 100644 index 000000000000..8a1e3ace0b2c --- /dev/null +++ b/arch/mips/configs/tb0287_defconfig | |||
@@ -0,0 +1,1096 @@ | |||
1 | # | ||
2 | # Automatically generated make config: don't edit | ||
3 | # Linux kernel version: 2.6.16 | ||
4 | # Wed Mar 22 11:07:34 2006 | ||
5 | # | ||
6 | CONFIG_MIPS=y | ||
7 | |||
8 | # | ||
9 | # Machine selection | ||
10 | # | ||
11 | # CONFIG_MIPS_MTX1 is not set | ||
12 | # CONFIG_MIPS_BOSPORUS is not set | ||
13 | # CONFIG_MIPS_PB1000 is not set | ||
14 | # CONFIG_MIPS_PB1100 is not set | ||
15 | # CONFIG_MIPS_PB1500 is not set | ||
16 | # CONFIG_MIPS_PB1550 is not set | ||
17 | # CONFIG_MIPS_PB1200 is not set | ||
18 | # CONFIG_MIPS_DB1000 is not set | ||
19 | # CONFIG_MIPS_DB1100 is not set | ||
20 | # CONFIG_MIPS_DB1500 is not set | ||
21 | # CONFIG_MIPS_DB1550 is not set | ||
22 | # CONFIG_MIPS_DB1200 is not set | ||
23 | # CONFIG_MIPS_MIRAGE is not set | ||
24 | # CONFIG_MIPS_COBALT is not set | ||
25 | # CONFIG_MACH_DECSTATION is not set | ||
26 | # CONFIG_MIPS_EV64120 is not set | ||
27 | # CONFIG_MIPS_EV96100 is not set | ||
28 | # CONFIG_MIPS_IVR is not set | ||
29 | # CONFIG_MIPS_ITE8172 is not set | ||
30 | # CONFIG_MACH_JAZZ is not set | ||
31 | # CONFIG_LASAT is not set | ||
32 | # CONFIG_MIPS_ATLAS is not set | ||
33 | # CONFIG_MIPS_MALTA is not set | ||
34 | # CONFIG_MIPS_SEAD is not set | ||
35 | # CONFIG_MIPS_SIM is not set | ||
36 | # CONFIG_MOMENCO_JAGUAR_ATX is not set | ||
37 | # CONFIG_MOMENCO_OCELOT is not set | ||
38 | # CONFIG_MOMENCO_OCELOT_3 is not set | ||
39 | # CONFIG_MOMENCO_OCELOT_C is not set | ||
40 | # CONFIG_MOMENCO_OCELOT_G is not set | ||
41 | # CONFIG_MIPS_XXS1500 is not set | ||
42 | # CONFIG_PNX8550_V2PCI is not set | ||
43 | # CONFIG_PNX8550_JBS is not set | ||
44 | # CONFIG_DDB5074 is not set | ||
45 | # CONFIG_DDB5476 is not set | ||
46 | # CONFIG_DDB5477 is not set | ||
47 | CONFIG_MACH_VR41XX=y | ||
48 | # CONFIG_PMC_YOSEMITE is not set | ||
49 | # CONFIG_QEMU is not set | ||
50 | # CONFIG_SGI_IP22 is not set | ||
51 | # CONFIG_SGI_IP27 is not set | ||
52 | # CONFIG_SGI_IP32 is not set | ||
53 | # CONFIG_SIBYTE_BIGSUR is not set | ||
54 | # CONFIG_SIBYTE_SWARM is not set | ||
55 | # CONFIG_SIBYTE_SENTOSA is not set | ||
56 | # CONFIG_SIBYTE_RHONE is not set | ||
57 | # CONFIG_SIBYTE_CARMEL is not set | ||
58 | # CONFIG_SIBYTE_PTSWARM is not set | ||
59 | # CONFIG_SIBYTE_LITTLESUR is not set | ||
60 | # CONFIG_SIBYTE_CRHINE is not set | ||
61 | # CONFIG_SIBYTE_CRHONE is not set | ||
62 | # CONFIG_SNI_RM200_PCI is not set | ||
63 | # CONFIG_TOSHIBA_JMR3927 is not set | ||
64 | # CONFIG_TOSHIBA_RBTX4927 is not set | ||
65 | # CONFIG_TOSHIBA_RBTX4938 is not set | ||
66 | # CONFIG_CASIO_E55 is not set | ||
67 | # CONFIG_IBM_WORKPAD is not set | ||
68 | # CONFIG_NEC_CMBVR4133 is not set | ||
69 | CONFIG_TANBAC_TB022X=y | ||
70 | # CONFIG_TANBAC_TB0226 is not set | ||
71 | CONFIG_TANBAC_TB0287=y | ||
72 | # CONFIG_VICTOR_MPC30X is not set | ||
73 | # CONFIG_ZAO_CAPCELLA is not set | ||
74 | CONFIG_PCI_VR41XX=y | ||
75 | # CONFIG_VRC4173 is not set | ||
76 | CONFIG_RWSEM_GENERIC_SPINLOCK=y | ||
77 | CONFIG_GENERIC_CALIBRATE_DELAY=y | ||
78 | CONFIG_DMA_NONCOHERENT=y | ||
79 | CONFIG_DMA_NEED_PCI_MAP_STATE=y | ||
80 | # CONFIG_CPU_BIG_ENDIAN is not set | ||
81 | CONFIG_CPU_LITTLE_ENDIAN=y | ||
82 | CONFIG_SYS_SUPPORTS_LITTLE_ENDIAN=y | ||
83 | CONFIG_IRQ_CPU=y | ||
84 | CONFIG_MIPS_L1_CACHE_SHIFT=5 | ||
85 | |||
86 | # | ||
87 | # CPU selection | ||
88 | # | ||
89 | # CONFIG_CPU_MIPS32_R1 is not set | ||
90 | # CONFIG_CPU_MIPS32_R2 is not set | ||
91 | # CONFIG_CPU_MIPS64_R1 is not set | ||
92 | # CONFIG_CPU_MIPS64_R2 is not set | ||
93 | # CONFIG_CPU_R3000 is not set | ||
94 | # CONFIG_CPU_TX39XX is not set | ||
95 | CONFIG_CPU_VR41XX=y | ||
96 | # CONFIG_CPU_R4300 is not set | ||
97 | # CONFIG_CPU_R4X00 is not set | ||
98 | # CONFIG_CPU_TX49XX is not set | ||
99 | # CONFIG_CPU_R5000 is not set | ||
100 | # CONFIG_CPU_R5432 is not set | ||
101 | # CONFIG_CPU_R6000 is not set | ||
102 | # CONFIG_CPU_NEVADA is not set | ||
103 | # CONFIG_CPU_R8000 is not set | ||
104 | # CONFIG_CPU_R10000 is not set | ||
105 | # CONFIG_CPU_RM7000 is not set | ||
106 | # CONFIG_CPU_RM9000 is not set | ||
107 | # CONFIG_CPU_SB1 is not set | ||
108 | CONFIG_SYS_HAS_CPU_VR41XX=y | ||
109 | CONFIG_SYS_SUPPORTS_32BIT_KERNEL=y | ||
110 | CONFIG_SYS_SUPPORTS_64BIT_KERNEL=y | ||
111 | CONFIG_CPU_SUPPORTS_32BIT_KERNEL=y | ||
112 | CONFIG_CPU_SUPPORTS_64BIT_KERNEL=y | ||
113 | |||
114 | # | ||
115 | # Kernel type | ||
116 | # | ||
117 | CONFIG_32BIT=y | ||
118 | # CONFIG_64BIT is not set | ||
119 | CONFIG_PAGE_SIZE_4KB=y | ||
120 | # CONFIG_PAGE_SIZE_8KB is not set | ||
121 | # CONFIG_PAGE_SIZE_16KB is not set | ||
122 | # CONFIG_PAGE_SIZE_64KB is not set | ||
123 | # CONFIG_MIPS_MT is not set | ||
124 | # CONFIG_CPU_ADVANCED is not set | ||
125 | CONFIG_CPU_HAS_SYNC=y | ||
126 | CONFIG_GENERIC_HARDIRQS=y | ||
127 | CONFIG_GENERIC_IRQ_PROBE=y | ||
128 | CONFIG_ARCH_FLATMEM_ENABLE=y | ||
129 | CONFIG_SELECT_MEMORY_MODEL=y | ||
130 | CONFIG_FLATMEM_MANUAL=y | ||
131 | # CONFIG_DISCONTIGMEM_MANUAL is not set | ||
132 | # CONFIG_SPARSEMEM_MANUAL is not set | ||
133 | CONFIG_FLATMEM=y | ||
134 | CONFIG_FLAT_NODE_MEM_MAP=y | ||
135 | # CONFIG_SPARSEMEM_STATIC is not set | ||
136 | CONFIG_SPLIT_PTLOCK_CPUS=4 | ||
137 | CONFIG_PREEMPT_NONE=y | ||
138 | # CONFIG_PREEMPT_VOLUNTARY is not set | ||
139 | # CONFIG_PREEMPT is not set | ||
140 | |||
141 | # | ||
142 | # Code maturity level options | ||
143 | # | ||
144 | CONFIG_EXPERIMENTAL=y | ||
145 | CONFIG_BROKEN_ON_SMP=y | ||
146 | CONFIG_INIT_ENV_ARG_LIMIT=32 | ||
147 | |||
148 | # | ||
149 | # General setup | ||
150 | # | ||
151 | CONFIG_LOCALVERSION="" | ||
152 | CONFIG_LOCALVERSION_AUTO=y | ||
153 | CONFIG_SWAP=y | ||
154 | CONFIG_SYSVIPC=y | ||
155 | # CONFIG_POSIX_MQUEUE is not set | ||
156 | # CONFIG_BSD_PROCESS_ACCT is not set | ||
157 | CONFIG_SYSCTL=y | ||
158 | # CONFIG_AUDIT is not set | ||
159 | # CONFIG_IKCONFIG is not set | ||
160 | CONFIG_INITRAMFS_SOURCE="" | ||
161 | # CONFIG_CC_OPTIMIZE_FOR_SIZE is not set | ||
162 | CONFIG_EMBEDDED=y | ||
163 | CONFIG_KALLSYMS=y | ||
164 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | ||
165 | # CONFIG_HOTPLUG is not set | ||
166 | CONFIG_PRINTK=y | ||
167 | CONFIG_BUG=y | ||
168 | CONFIG_ELF_CORE=y | ||
169 | CONFIG_BASE_FULL=y | ||
170 | CONFIG_FUTEX=y | ||
171 | CONFIG_EPOLL=y | ||
172 | CONFIG_SHMEM=y | ||
173 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
174 | CONFIG_CC_ALIGN_LABELS=0 | ||
175 | CONFIG_CC_ALIGN_LOOPS=0 | ||
176 | CONFIG_CC_ALIGN_JUMPS=0 | ||
177 | CONFIG_SLAB=y | ||
178 | # CONFIG_TINY_SHMEM is not set | ||
179 | CONFIG_BASE_SMALL=0 | ||
180 | # CONFIG_SLOB is not set | ||
181 | |||
182 | # | ||
183 | # Loadable module support | ||
184 | # | ||
185 | CONFIG_MODULES=y | ||
186 | CONFIG_MODULE_UNLOAD=y | ||
187 | # CONFIG_MODULE_FORCE_UNLOAD is not set | ||
188 | CONFIG_OBSOLETE_MODPARM=y | ||
189 | CONFIG_MODVERSIONS=y | ||
190 | CONFIG_MODULE_SRCVERSION_ALL=y | ||
191 | CONFIG_KMOD=y | ||
192 | |||
193 | # | ||
194 | # Block layer | ||
195 | # | ||
196 | # CONFIG_LBD is not set | ||
197 | |||
198 | # | ||
199 | # IO Schedulers | ||
200 | # | ||
201 | CONFIG_IOSCHED_NOOP=y | ||
202 | CONFIG_IOSCHED_AS=y | ||
203 | CONFIG_IOSCHED_DEADLINE=y | ||
204 | CONFIG_IOSCHED_CFQ=y | ||
205 | CONFIG_DEFAULT_AS=y | ||
206 | # CONFIG_DEFAULT_DEADLINE is not set | ||
207 | # CONFIG_DEFAULT_CFQ is not set | ||
208 | # CONFIG_DEFAULT_NOOP is not set | ||
209 | CONFIG_DEFAULT_IOSCHED="anticipatory" | ||
210 | |||
211 | # | ||
212 | # Bus options (PCI, PCMCIA, EISA, ISA, TC) | ||
213 | # | ||
214 | CONFIG_HW_HAS_PCI=y | ||
215 | CONFIG_PCI=y | ||
216 | # CONFIG_PCI_LEGACY_PROC is not set | ||
217 | CONFIG_MMU=y | ||
218 | |||
219 | # | ||
220 | # PCCARD (PCMCIA/CardBus) support | ||
221 | # | ||
222 | # CONFIG_PCCARD is not set | ||
223 | |||
224 | # | ||
225 | # PCI Hotplug Support | ||
226 | # | ||
227 | # CONFIG_HOTPLUG_PCI is not set | ||
228 | |||
229 | # | ||
230 | # Executable file formats | ||
231 | # | ||
232 | CONFIG_BINFMT_ELF=y | ||
233 | # CONFIG_BINFMT_MISC is not set | ||
234 | CONFIG_TRAD_SIGNALS=y | ||
235 | |||
236 | # | ||
237 | # Networking | ||
238 | # | ||
239 | CONFIG_NET=y | ||
240 | |||
241 | # | ||
242 | # Networking options | ||
243 | # | ||
244 | # CONFIG_NETDEBUG is not set | ||
245 | CONFIG_PACKET=y | ||
246 | # CONFIG_PACKET_MMAP is not set | ||
247 | CONFIG_UNIX=y | ||
248 | CONFIG_XFRM=y | ||
249 | CONFIG_XFRM_USER=m | ||
250 | # CONFIG_NET_KEY is not set | ||
251 | CONFIG_INET=y | ||
252 | CONFIG_IP_MULTICAST=y | ||
253 | CONFIG_IP_ADVANCED_ROUTER=y | ||
254 | CONFIG_ASK_IP_FIB_HASH=y | ||
255 | # CONFIG_IP_FIB_TRIE is not set | ||
256 | CONFIG_IP_FIB_HASH=y | ||
257 | CONFIG_IP_MULTIPLE_TABLES=y | ||
258 | CONFIG_IP_ROUTE_MULTIPATH=y | ||
259 | # CONFIG_IP_ROUTE_MULTIPATH_CACHED is not set | ||
260 | CONFIG_IP_ROUTE_VERBOSE=y | ||
261 | CONFIG_IP_PNP=y | ||
262 | # CONFIG_IP_PNP_DHCP is not set | ||
263 | CONFIG_IP_PNP_BOOTP=y | ||
264 | # CONFIG_IP_PNP_RARP is not set | ||
265 | CONFIG_NET_IPIP=m | ||
266 | CONFIG_NET_IPGRE=m | ||
267 | # CONFIG_NET_IPGRE_BROADCAST is not set | ||
268 | # CONFIG_IP_MROUTE is not set | ||
269 | # CONFIG_ARPD is not set | ||
270 | CONFIG_SYN_COOKIES=y | ||
271 | # CONFIG_INET_AH is not set | ||
272 | # CONFIG_INET_ESP is not set | ||
273 | # CONFIG_INET_IPCOMP is not set | ||
274 | CONFIG_INET_TUNNEL=m | ||
275 | CONFIG_INET_DIAG=y | ||
276 | CONFIG_INET_TCP_DIAG=y | ||
277 | CONFIG_TCP_CONG_ADVANCED=y | ||
278 | |||
279 | # | ||
280 | # TCP congestion control | ||
281 | # | ||
282 | CONFIG_TCP_CONG_BIC=y | ||
283 | CONFIG_TCP_CONG_CUBIC=m | ||
284 | CONFIG_TCP_CONG_WESTWOOD=m | ||
285 | CONFIG_TCP_CONG_HTCP=m | ||
286 | # CONFIG_TCP_CONG_HSTCP is not set | ||
287 | # CONFIG_TCP_CONG_HYBLA is not set | ||
288 | # CONFIG_TCP_CONG_VEGAS is not set | ||
289 | # CONFIG_TCP_CONG_SCALABLE is not set | ||
290 | # CONFIG_IPV6 is not set | ||
291 | # CONFIG_NETFILTER is not set | ||
292 | |||
293 | # | ||
294 | # DCCP Configuration (EXPERIMENTAL) | ||
295 | # | ||
296 | # CONFIG_IP_DCCP is not set | ||
297 | |||
298 | # | ||
299 | # SCTP Configuration (EXPERIMENTAL) | ||
300 | # | ||
301 | # CONFIG_IP_SCTP is not set | ||
302 | |||
303 | # | ||
304 | # TIPC Configuration (EXPERIMENTAL) | ||
305 | # | ||
306 | # CONFIG_TIPC is not set | ||
307 | # CONFIG_ATM is not set | ||
308 | # CONFIG_BRIDGE is not set | ||
309 | # CONFIG_VLAN_8021Q is not set | ||
310 | # CONFIG_DECNET is not set | ||
311 | # CONFIG_LLC2 is not set | ||
312 | # CONFIG_IPX is not set | ||
313 | # CONFIG_ATALK is not set | ||
314 | # CONFIG_X25 is not set | ||
315 | # CONFIG_LAPB is not set | ||
316 | # CONFIG_NET_DIVERT is not set | ||
317 | # CONFIG_ECONET is not set | ||
318 | # CONFIG_WAN_ROUTER is not set | ||
319 | |||
320 | # | ||
321 | # QoS and/or fair queueing | ||
322 | # | ||
323 | # CONFIG_NET_SCHED is not set | ||
324 | |||
325 | # | ||
326 | # Network testing | ||
327 | # | ||
328 | # CONFIG_NET_PKTGEN is not set | ||
329 | # CONFIG_HAMRADIO is not set | ||
330 | # CONFIG_IRDA is not set | ||
331 | # CONFIG_BT is not set | ||
332 | # CONFIG_IEEE80211 is not set | ||
333 | |||
334 | # | ||
335 | # Device Drivers | ||
336 | # | ||
337 | |||
338 | # | ||
339 | # Generic Driver Options | ||
340 | # | ||
341 | CONFIG_STANDALONE=y | ||
342 | CONFIG_PREVENT_FIRMWARE_BUILD=y | ||
343 | # CONFIG_FW_LOADER is not set | ||
344 | |||
345 | # | ||
346 | # Connector - unified userspace <-> kernelspace linker | ||
347 | # | ||
348 | # CONFIG_CONNECTOR is not set | ||
349 | |||
350 | # | ||
351 | # Memory Technology Devices (MTD) | ||
352 | # | ||
353 | # CONFIG_MTD is not set | ||
354 | |||
355 | # | ||
356 | # Parallel port support | ||
357 | # | ||
358 | # CONFIG_PARPORT is not set | ||
359 | |||
360 | # | ||
361 | # Plug and Play support | ||
362 | # | ||
363 | |||
364 | # | ||
365 | # Block devices | ||
366 | # | ||
367 | # CONFIG_BLK_CPQ_DA is not set | ||
368 | # CONFIG_BLK_CPQ_CISS_DA is not set | ||
369 | # CONFIG_BLK_DEV_DAC960 is not set | ||
370 | # CONFIG_BLK_DEV_UMEM is not set | ||
371 | # CONFIG_BLK_DEV_COW_COMMON is not set | ||
372 | CONFIG_BLK_DEV_LOOP=m | ||
373 | # CONFIG_BLK_DEV_CRYPTOLOOP is not set | ||
374 | CONFIG_BLK_DEV_NBD=m | ||
375 | # CONFIG_BLK_DEV_SX8 is not set | ||
376 | # CONFIG_BLK_DEV_UB is not set | ||
377 | CONFIG_BLK_DEV_RAM=y | ||
378 | CONFIG_BLK_DEV_RAM_COUNT=16 | ||
379 | CONFIG_BLK_DEV_RAM_SIZE=4096 | ||
380 | # CONFIG_BLK_DEV_INITRD is not set | ||
381 | # CONFIG_CDROM_PKTCDVD is not set | ||
382 | # CONFIG_ATA_OVER_ETH is not set | ||
383 | |||
384 | # | ||
385 | # ATA/ATAPI/MFM/RLL support | ||
386 | # | ||
387 | CONFIG_IDE=y | ||
388 | CONFIG_BLK_DEV_IDE=y | ||
389 | |||
390 | # | ||
391 | # Please see Documentation/ide.txt for help/info on IDE drives | ||
392 | # | ||
393 | # CONFIG_BLK_DEV_IDE_SATA is not set | ||
394 | CONFIG_BLK_DEV_IDEDISK=y | ||
395 | # CONFIG_IDEDISK_MULTI_MODE is not set | ||
396 | # CONFIG_BLK_DEV_IDECD is not set | ||
397 | # CONFIG_BLK_DEV_IDETAPE is not set | ||
398 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
399 | # CONFIG_BLK_DEV_IDESCSI is not set | ||
400 | # CONFIG_IDE_TASK_IOCTL is not set | ||
401 | |||
402 | # | ||
403 | # IDE chipset support/bugfixes | ||
404 | # | ||
405 | CONFIG_IDE_GENERIC=y | ||
406 | CONFIG_BLK_DEV_IDEPCI=y | ||
407 | # CONFIG_IDEPCI_SHARE_IRQ is not set | ||
408 | # CONFIG_BLK_DEV_OFFBOARD is not set | ||
409 | # CONFIG_BLK_DEV_GENERIC is not set | ||
410 | # CONFIG_BLK_DEV_OPTI621 is not set | ||
411 | CONFIG_BLK_DEV_IDEDMA_PCI=y | ||
412 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | ||
413 | # CONFIG_IDEDMA_PCI_AUTO is not set | ||
414 | # CONFIG_BLK_DEV_AEC62XX is not set | ||
415 | # CONFIG_BLK_DEV_ALI15X3 is not set | ||
416 | # CONFIG_BLK_DEV_AMD74XX is not set | ||
417 | # CONFIG_BLK_DEV_CMD64X is not set | ||
418 | # CONFIG_BLK_DEV_TRIFLEX is not set | ||
419 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
420 | # CONFIG_BLK_DEV_CS5520 is not set | ||
421 | # CONFIG_BLK_DEV_CS5530 is not set | ||
422 | # CONFIG_BLK_DEV_HPT34X is not set | ||
423 | # CONFIG_BLK_DEV_HPT366 is not set | ||
424 | # CONFIG_BLK_DEV_SC1200 is not set | ||
425 | # CONFIG_BLK_DEV_PIIX is not set | ||
426 | # CONFIG_BLK_DEV_IT821X is not set | ||
427 | # CONFIG_BLK_DEV_NS87415 is not set | ||
428 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | ||
429 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | ||
430 | # CONFIG_BLK_DEV_SVWKS is not set | ||
431 | CONFIG_BLK_DEV_SIIMAGE=y | ||
432 | # CONFIG_BLK_DEV_SLC90E66 is not set | ||
433 | # CONFIG_BLK_DEV_TRM290 is not set | ||
434 | # CONFIG_BLK_DEV_VIA82CXXX is not set | ||
435 | # CONFIG_IDE_ARM is not set | ||
436 | CONFIG_BLK_DEV_IDEDMA=y | ||
437 | # CONFIG_IDEDMA_IVB is not set | ||
438 | # CONFIG_IDEDMA_AUTO is not set | ||
439 | # CONFIG_BLK_DEV_HD is not set | ||
440 | |||
441 | # | ||
442 | # SCSI device support | ||
443 | # | ||
444 | # CONFIG_RAID_ATTRS is not set | ||
445 | CONFIG_SCSI=y | ||
446 | CONFIG_SCSI_PROC_FS=y | ||
447 | |||
448 | # | ||
449 | # SCSI support type (disk, tape, CD-ROM) | ||
450 | # | ||
451 | CONFIG_BLK_DEV_SD=y | ||
452 | # CONFIG_CHR_DEV_ST is not set | ||
453 | # CONFIG_CHR_DEV_OSST is not set | ||
454 | # CONFIG_BLK_DEV_SR is not set | ||
455 | # CONFIG_CHR_DEV_SG is not set | ||
456 | # CONFIG_CHR_DEV_SCH is not set | ||
457 | |||
458 | # | ||
459 | # Some SCSI devices (e.g. CD jukebox) support multiple LUNs | ||
460 | # | ||
461 | # CONFIG_SCSI_MULTI_LUN is not set | ||
462 | # CONFIG_SCSI_CONSTANTS is not set | ||
463 | # CONFIG_SCSI_LOGGING is not set | ||
464 | |||
465 | # | ||
466 | # SCSI Transport Attributes | ||
467 | # | ||
468 | # CONFIG_SCSI_SPI_ATTRS is not set | ||
469 | # CONFIG_SCSI_FC_ATTRS is not set | ||
470 | # CONFIG_SCSI_ISCSI_ATTRS is not set | ||
471 | # CONFIG_SCSI_SAS_ATTRS is not set | ||
472 | |||
473 | # | ||
474 | # SCSI low-level drivers | ||
475 | # | ||
476 | # CONFIG_ISCSI_TCP is not set | ||
477 | # CONFIG_BLK_DEV_3W_XXXX_RAID is not set | ||
478 | # CONFIG_SCSI_3W_9XXX is not set | ||
479 | # CONFIG_SCSI_ACARD is not set | ||
480 | # CONFIG_SCSI_AACRAID is not set | ||
481 | # CONFIG_SCSI_AIC7XXX is not set | ||
482 | # CONFIG_SCSI_AIC7XXX_OLD is not set | ||
483 | # CONFIG_SCSI_AIC79XX is not set | ||
484 | # CONFIG_SCSI_DPT_I2O is not set | ||
485 | # CONFIG_MEGARAID_NEWGEN is not set | ||
486 | # CONFIG_MEGARAID_LEGACY is not set | ||
487 | # CONFIG_MEGARAID_SAS is not set | ||
488 | # CONFIG_SCSI_SATA is not set | ||
489 | # CONFIG_SCSI_DMX3191D is not set | ||
490 | # CONFIG_SCSI_FUTURE_DOMAIN is not set | ||
491 | # CONFIG_SCSI_IPS is not set | ||
492 | # CONFIG_SCSI_INITIO is not set | ||
493 | # CONFIG_SCSI_INIA100 is not set | ||
494 | # CONFIG_SCSI_SYM53C8XX_2 is not set | ||
495 | # CONFIG_SCSI_IPR is not set | ||
496 | # CONFIG_SCSI_QLOGIC_FC is not set | ||
497 | # CONFIG_SCSI_QLOGIC_1280 is not set | ||
498 | # CONFIG_SCSI_QLA_FC is not set | ||
499 | # CONFIG_SCSI_LPFC is not set | ||
500 | # CONFIG_SCSI_DC395x is not set | ||
501 | # CONFIG_SCSI_DC390T is not set | ||
502 | # CONFIG_SCSI_NSP32 is not set | ||
503 | # CONFIG_SCSI_DEBUG is not set | ||
504 | |||
505 | # | ||
506 | # Multi-device support (RAID and LVM) | ||
507 | # | ||
508 | # CONFIG_MD is not set | ||
509 | |||
510 | # | ||
511 | # Fusion MPT device support | ||
512 | # | ||
513 | # CONFIG_FUSION is not set | ||
514 | # CONFIG_FUSION_SPI is not set | ||
515 | # CONFIG_FUSION_FC is not set | ||
516 | # CONFIG_FUSION_SAS is not set | ||
517 | |||
518 | # | ||
519 | # IEEE 1394 (FireWire) support | ||
520 | # | ||
521 | CONFIG_IEEE1394=m | ||
522 | |||
523 | # | ||
524 | # Subsystem Options | ||
525 | # | ||
526 | # CONFIG_IEEE1394_VERBOSEDEBUG is not set | ||
527 | # CONFIG_IEEE1394_OUI_DB is not set | ||
528 | CONFIG_IEEE1394_EXTRA_CONFIG_ROMS=y | ||
529 | CONFIG_IEEE1394_CONFIG_ROM_IP1394=y | ||
530 | # CONFIG_IEEE1394_EXPORT_FULL_API is not set | ||
531 | |||
532 | # | ||
533 | # Device Drivers | ||
534 | # | ||
535 | |||
536 | # | ||
537 | # Texas Instruments PCILynx requires I2C | ||
538 | # | ||
539 | CONFIG_IEEE1394_OHCI1394=m | ||
540 | |||
541 | # | ||
542 | # Protocol Drivers | ||
543 | # | ||
544 | CONFIG_IEEE1394_VIDEO1394=m | ||
545 | CONFIG_IEEE1394_SBP2=m | ||
546 | # CONFIG_IEEE1394_SBP2_PHYS_DMA is not set | ||
547 | CONFIG_IEEE1394_ETH1394=m | ||
548 | CONFIG_IEEE1394_DV1394=m | ||
549 | CONFIG_IEEE1394_RAWIO=m | ||
550 | |||
551 | # | ||
552 | # I2O device support | ||
553 | # | ||
554 | # CONFIG_I2O is not set | ||
555 | |||
556 | # | ||
557 | # Network device support | ||
558 | # | ||
559 | CONFIG_NETDEVICES=y | ||
560 | CONFIG_DUMMY=m | ||
561 | # CONFIG_BONDING is not set | ||
562 | # CONFIG_EQUALIZER is not set | ||
563 | # CONFIG_TUN is not set | ||
564 | |||
565 | # | ||
566 | # ARCnet devices | ||
567 | # | ||
568 | # CONFIG_ARCNET is not set | ||
569 | |||
570 | # | ||
571 | # PHY device support | ||
572 | # | ||
573 | # CONFIG_PHYLIB is not set | ||
574 | |||
575 | # | ||
576 | # Ethernet (10 or 100Mbit) | ||
577 | # | ||
578 | CONFIG_NET_ETHERNET=y | ||
579 | CONFIG_MII=y | ||
580 | # CONFIG_HAPPYMEAL is not set | ||
581 | # CONFIG_SUNGEM is not set | ||
582 | # CONFIG_CASSINI is not set | ||
583 | # CONFIG_NET_VENDOR_3COM is not set | ||
584 | # CONFIG_DM9000 is not set | ||
585 | |||
586 | # | ||
587 | # Tulip family network device support | ||
588 | # | ||
589 | # CONFIG_NET_TULIP is not set | ||
590 | # CONFIG_HP100 is not set | ||
591 | # CONFIG_NET_PCI is not set | ||
592 | |||
593 | # | ||
594 | # Ethernet (1000 Mbit) | ||
595 | # | ||
596 | # CONFIG_ACENIC is not set | ||
597 | # CONFIG_DL2K is not set | ||
598 | # CONFIG_E1000 is not set | ||
599 | # CONFIG_NS83820 is not set | ||
600 | # CONFIG_HAMACHI is not set | ||
601 | # CONFIG_YELLOWFIN is not set | ||
602 | CONFIG_R8169=y | ||
603 | # CONFIG_R8169_NAPI is not set | ||
604 | # CONFIG_SIS190 is not set | ||
605 | # CONFIG_SKGE is not set | ||
606 | # CONFIG_SKY2 is not set | ||
607 | # CONFIG_SK98LIN is not set | ||
608 | # CONFIG_TIGON3 is not set | ||
609 | # CONFIG_BNX2 is not set | ||
610 | |||
611 | # | ||
612 | # Ethernet (10000 Mbit) | ||
613 | # | ||
614 | # CONFIG_CHELSIO_T1 is not set | ||
615 | # CONFIG_IXGB is not set | ||
616 | # CONFIG_S2IO is not set | ||
617 | |||
618 | # | ||
619 | # Token Ring devices | ||
620 | # | ||
621 | # CONFIG_TR is not set | ||
622 | |||
623 | # | ||
624 | # Wireless LAN (non-hamradio) | ||
625 | # | ||
626 | # CONFIG_NET_RADIO is not set | ||
627 | |||
628 | # | ||
629 | # Wan interfaces | ||
630 | # | ||
631 | # CONFIG_WAN is not set | ||
632 | # CONFIG_FDDI is not set | ||
633 | # CONFIG_HIPPI is not set | ||
634 | # CONFIG_PPP is not set | ||
635 | # CONFIG_SLIP is not set | ||
636 | # CONFIG_NET_FC is not set | ||
637 | # CONFIG_SHAPER is not set | ||
638 | # CONFIG_NETCONSOLE is not set | ||
639 | # CONFIG_NETPOLL is not set | ||
640 | # CONFIG_NET_POLL_CONTROLLER is not set | ||
641 | |||
642 | # | ||
643 | # ISDN subsystem | ||
644 | # | ||
645 | # CONFIG_ISDN is not set | ||
646 | |||
647 | # | ||
648 | # Telephony Support | ||
649 | # | ||
650 | # CONFIG_PHONE is not set | ||
651 | |||
652 | # | ||
653 | # Input device support | ||
654 | # | ||
655 | CONFIG_INPUT=y | ||
656 | |||
657 | # | ||
658 | # Userland interfaces | ||
659 | # | ||
660 | # CONFIG_INPUT_MOUSEDEV is not set | ||
661 | # CONFIG_INPUT_JOYDEV is not set | ||
662 | # CONFIG_INPUT_TSDEV is not set | ||
663 | # CONFIG_INPUT_EVDEV is not set | ||
664 | # CONFIG_INPUT_EVBUG is not set | ||
665 | |||
666 | # | ||
667 | # Input Device Drivers | ||
668 | # | ||
669 | # CONFIG_INPUT_KEYBOARD is not set | ||
670 | # CONFIG_INPUT_MOUSE is not set | ||
671 | # CONFIG_INPUT_JOYSTICK is not set | ||
672 | # CONFIG_INPUT_TOUCHSCREEN is not set | ||
673 | # CONFIG_INPUT_MISC is not set | ||
674 | |||
675 | # | ||
676 | # Hardware I/O ports | ||
677 | # | ||
678 | # CONFIG_SERIO is not set | ||
679 | # CONFIG_GAMEPORT is not set | ||
680 | |||
681 | # | ||
682 | # Character devices | ||
683 | # | ||
684 | CONFIG_VT=y | ||
685 | CONFIG_VT_CONSOLE=y | ||
686 | CONFIG_HW_CONSOLE=y | ||
687 | # CONFIG_SERIAL_NONSTANDARD is not set | ||
688 | |||
689 | # | ||
690 | # Serial drivers | ||
691 | # | ||
692 | # CONFIG_SERIAL_8250 is not set | ||
693 | |||
694 | # | ||
695 | # Non-8250 serial port support | ||
696 | # | ||
697 | CONFIG_SERIAL_CORE=y | ||
698 | CONFIG_SERIAL_CORE_CONSOLE=y | ||
699 | CONFIG_SERIAL_VR41XX=y | ||
700 | CONFIG_SERIAL_VR41XX_CONSOLE=y | ||
701 | # CONFIG_SERIAL_JSM is not set | ||
702 | CONFIG_UNIX98_PTYS=y | ||
703 | CONFIG_LEGACY_PTYS=y | ||
704 | CONFIG_LEGACY_PTY_COUNT=256 | ||
705 | |||
706 | # | ||
707 | # IPMI | ||
708 | # | ||
709 | # CONFIG_IPMI_HANDLER is not set | ||
710 | |||
711 | # | ||
712 | # Watchdog Cards | ||
713 | # | ||
714 | # CONFIG_WATCHDOG is not set | ||
715 | # CONFIG_RTC is not set | ||
716 | # CONFIG_GEN_RTC is not set | ||
717 | # CONFIG_RTC_VR41XX is not set | ||
718 | # CONFIG_DTLK is not set | ||
719 | # CONFIG_R3964 is not set | ||
720 | # CONFIG_APPLICOM is not set | ||
721 | # CONFIG_TANBAC_TB0219 is not set | ||
722 | |||
723 | # | ||
724 | # Ftape, the floppy tape device driver | ||
725 | # | ||
726 | # CONFIG_DRM is not set | ||
727 | CONFIG_GPIO_VR41XX=y | ||
728 | # CONFIG_RAW_DRIVER is not set | ||
729 | |||
730 | # | ||
731 | # TPM devices | ||
732 | # | ||
733 | # CONFIG_TCG_TPM is not set | ||
734 | # CONFIG_TELCLOCK is not set | ||
735 | |||
736 | # | ||
737 | # I2C support | ||
738 | # | ||
739 | # CONFIG_I2C is not set | ||
740 | |||
741 | # | ||
742 | # SPI support | ||
743 | # | ||
744 | # CONFIG_SPI is not set | ||
745 | # CONFIG_SPI_MASTER is not set | ||
746 | |||
747 | # | ||
748 | # Dallas's 1-wire bus | ||
749 | # | ||
750 | # CONFIG_W1 is not set | ||
751 | |||
752 | # | ||
753 | # Hardware Monitoring support | ||
754 | # | ||
755 | # CONFIG_HWMON is not set | ||
756 | # CONFIG_HWMON_VID is not set | ||
757 | |||
758 | # | ||
759 | # Misc devices | ||
760 | # | ||
761 | |||
762 | # | ||
763 | # Multimedia Capabilities Port drivers | ||
764 | # | ||
765 | |||
766 | # | ||
767 | # Multimedia devices | ||
768 | # | ||
769 | # CONFIG_VIDEO_DEV is not set | ||
770 | |||
771 | # | ||
772 | # Digital Video Broadcasting Devices | ||
773 | # | ||
774 | # CONFIG_DVB is not set | ||
775 | |||
776 | # | ||
777 | # Graphics support | ||
778 | # | ||
779 | # CONFIG_FB is not set | ||
780 | |||
781 | # | ||
782 | # Console display driver support | ||
783 | # | ||
784 | # CONFIG_VGA_CONSOLE is not set | ||
785 | CONFIG_DUMMY_CONSOLE=y | ||
786 | |||
787 | # | ||
788 | # Sound | ||
789 | # | ||
790 | # CONFIG_SOUND is not set | ||
791 | |||
792 | # | ||
793 | # USB support | ||
794 | # | ||
795 | CONFIG_USB_ARCH_HAS_HCD=y | ||
796 | CONFIG_USB_ARCH_HAS_OHCI=y | ||
797 | CONFIG_USB=m | ||
798 | # CONFIG_USB_DEBUG is not set | ||
799 | |||
800 | # | ||
801 | # Miscellaneous USB options | ||
802 | # | ||
803 | # CONFIG_USB_DEVICEFS is not set | ||
804 | # CONFIG_USB_BANDWIDTH is not set | ||
805 | # CONFIG_USB_DYNAMIC_MINORS is not set | ||
806 | # CONFIG_USB_OTG is not set | ||
807 | |||
808 | # | ||
809 | # USB Host Controller Drivers | ||
810 | # | ||
811 | CONFIG_USB_EHCI_HCD=m | ||
812 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | ||
813 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | ||
814 | # CONFIG_USB_ISP116X_HCD is not set | ||
815 | CONFIG_USB_OHCI_HCD=m | ||
816 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | ||
817 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | ||
818 | # CONFIG_USB_UHCI_HCD is not set | ||
819 | # CONFIG_USB_SL811_HCD is not set | ||
820 | |||
821 | # | ||
822 | # USB Device Class drivers | ||
823 | # | ||
824 | # CONFIG_USB_ACM is not set | ||
825 | # CONFIG_USB_PRINTER is not set | ||
826 | |||
827 | # | ||
828 | # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' | ||
829 | # | ||
830 | |||
831 | # | ||
832 | # may also be needed; see USB_STORAGE Help for more information | ||
833 | # | ||
834 | CONFIG_USB_STORAGE=m | ||
835 | # CONFIG_USB_STORAGE_DEBUG is not set | ||
836 | # CONFIG_USB_STORAGE_DATAFAB is not set | ||
837 | # CONFIG_USB_STORAGE_FREECOM is not set | ||
838 | # CONFIG_USB_STORAGE_ISD200 is not set | ||
839 | # CONFIG_USB_STORAGE_DPCM is not set | ||
840 | # CONFIG_USB_STORAGE_USBAT is not set | ||
841 | # CONFIG_USB_STORAGE_SDDR09 is not set | ||
842 | # CONFIG_USB_STORAGE_SDDR55 is not set | ||
843 | # CONFIG_USB_STORAGE_JUMPSHOT is not set | ||
844 | # CONFIG_USB_STORAGE_ALAUDA is not set | ||
845 | # CONFIG_USB_LIBUSUAL is not set | ||
846 | |||
847 | # | ||
848 | # USB Input Devices | ||
849 | # | ||
850 | CONFIG_USB_HID=m | ||
851 | CONFIG_USB_HIDINPUT=y | ||
852 | # CONFIG_USB_HIDINPUT_POWERBOOK is not set | ||
853 | # CONFIG_HID_FF is not set | ||
854 | # CONFIG_USB_HIDDEV is not set | ||
855 | |||
856 | # | ||
857 | # USB HID Boot Protocol drivers | ||
858 | # | ||
859 | # CONFIG_USB_KBD is not set | ||
860 | # CONFIG_USB_MOUSE is not set | ||
861 | # CONFIG_USB_AIPTEK is not set | ||
862 | # CONFIG_USB_WACOM is not set | ||
863 | # CONFIG_USB_ACECAD is not set | ||
864 | # CONFIG_USB_KBTAB is not set | ||
865 | # CONFIG_USB_POWERMATE is not set | ||
866 | # CONFIG_USB_MTOUCH is not set | ||
867 | # CONFIG_USB_ITMTOUCH is not set | ||
868 | # CONFIG_USB_EGALAX is not set | ||
869 | # CONFIG_USB_YEALINK is not set | ||
870 | # CONFIG_USB_XPAD is not set | ||
871 | # CONFIG_USB_ATI_REMOTE is not set | ||
872 | # CONFIG_USB_ATI_REMOTE2 is not set | ||
873 | # CONFIG_USB_KEYSPAN_REMOTE is not set | ||
874 | # CONFIG_USB_APPLETOUCH is not set | ||
875 | |||
876 | # | ||
877 | # USB Imaging devices | ||
878 | # | ||
879 | # CONFIG_USB_MDC800 is not set | ||
880 | # CONFIG_USB_MICROTEK is not set | ||
881 | |||
882 | # | ||
883 | # USB Multimedia devices | ||
884 | # | ||
885 | # CONFIG_USB_DABUSB is not set | ||
886 | |||
887 | # | ||
888 | # Video4Linux support is needed for USB Multimedia device support | ||
889 | # | ||
890 | |||
891 | # | ||
892 | # USB Network Adapters | ||
893 | # | ||
894 | # CONFIG_USB_CATC is not set | ||
895 | # CONFIG_USB_KAWETH is not set | ||
896 | # CONFIG_USB_PEGASUS is not set | ||
897 | # CONFIG_USB_RTL8150 is not set | ||
898 | # CONFIG_USB_USBNET is not set | ||
899 | CONFIG_USB_MON=y | ||
900 | |||
901 | # | ||
902 | # USB port drivers | ||
903 | # | ||
904 | |||
905 | # | ||
906 | # USB Serial Converter support | ||
907 | # | ||
908 | # CONFIG_USB_SERIAL is not set | ||
909 | |||
910 | # | ||
911 | # USB Miscellaneous drivers | ||
912 | # | ||
913 | # CONFIG_USB_EMI62 is not set | ||
914 | # CONFIG_USB_EMI26 is not set | ||
915 | # CONFIG_USB_AUERSWALD is not set | ||
916 | # CONFIG_USB_RIO500 is not set | ||
917 | # CONFIG_USB_LEGOTOWER is not set | ||
918 | # CONFIG_USB_LCD is not set | ||
919 | # CONFIG_USB_LED is not set | ||
920 | # CONFIG_USB_CYTHERM is not set | ||
921 | # CONFIG_USB_PHIDGETKIT is not set | ||
922 | # CONFIG_USB_PHIDGETSERVO is not set | ||
923 | # CONFIG_USB_IDMOUSE is not set | ||
924 | # CONFIG_USB_SISUSBVGA is not set | ||
925 | # CONFIG_USB_LD is not set | ||
926 | |||
927 | # | ||
928 | # USB DSL modem support | ||
929 | # | ||
930 | |||
931 | # | ||
932 | # USB Gadget Support | ||
933 | # | ||
934 | # CONFIG_USB_GADGET is not set | ||
935 | |||
936 | # | ||
937 | # MMC/SD Card support | ||
938 | # | ||
939 | # CONFIG_MMC is not set | ||
940 | |||
941 | # | ||
942 | # InfiniBand support | ||
943 | # | ||
944 | # CONFIG_INFINIBAND is not set | ||
945 | |||
946 | # | ||
947 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) | ||
948 | # | ||
949 | |||
950 | # | ||
951 | # File systems | ||
952 | # | ||
953 | CONFIG_EXT2_FS=y | ||
954 | # CONFIG_EXT2_FS_XATTR is not set | ||
955 | # CONFIG_EXT2_FS_XIP is not set | ||
956 | CONFIG_EXT3_FS=y | ||
957 | CONFIG_EXT3_FS_XATTR=y | ||
958 | # CONFIG_EXT3_FS_POSIX_ACL is not set | ||
959 | # CONFIG_EXT3_FS_SECURITY is not set | ||
960 | CONFIG_JBD=y | ||
961 | # CONFIG_JBD_DEBUG is not set | ||
962 | CONFIG_FS_MBCACHE=y | ||
963 | # CONFIG_REISERFS_FS is not set | ||
964 | # CONFIG_JFS_FS is not set | ||
965 | # CONFIG_FS_POSIX_ACL is not set | ||
966 | CONFIG_XFS_FS=y | ||
967 | CONFIG_XFS_QUOTA=y | ||
968 | # CONFIG_XFS_SECURITY is not set | ||
969 | CONFIG_XFS_POSIX_ACL=y | ||
970 | # CONFIG_XFS_RT is not set | ||
971 | # CONFIG_OCFS2_FS is not set | ||
972 | # CONFIG_MINIX_FS is not set | ||
973 | CONFIG_ROMFS_FS=m | ||
974 | CONFIG_INOTIFY=y | ||
975 | # CONFIG_QUOTA is not set | ||
976 | CONFIG_QUOTACTL=y | ||
977 | # CONFIG_DNOTIFY is not set | ||
978 | # CONFIG_AUTOFS_FS is not set | ||
979 | CONFIG_AUTOFS4_FS=y | ||
980 | # CONFIG_FUSE_FS is not set | ||
981 | |||
982 | # | ||
983 | # CD-ROM/DVD Filesystems | ||
984 | # | ||
985 | # CONFIG_ISO9660_FS is not set | ||
986 | # CONFIG_UDF_FS is not set | ||
987 | |||
988 | # | ||
989 | # DOS/FAT/NT Filesystems | ||
990 | # | ||
991 | # CONFIG_MSDOS_FS is not set | ||
992 | # CONFIG_VFAT_FS is not set | ||
993 | # CONFIG_NTFS_FS is not set | ||
994 | |||
995 | # | ||
996 | # Pseudo filesystems | ||
997 | # | ||
998 | CONFIG_PROC_FS=y | ||
999 | CONFIG_PROC_KCORE=y | ||
1000 | CONFIG_SYSFS=y | ||
1001 | CONFIG_TMPFS=y | ||
1002 | # CONFIG_HUGETLB_PAGE is not set | ||
1003 | CONFIG_RAMFS=y | ||
1004 | # CONFIG_RELAYFS_FS is not set | ||
1005 | # CONFIG_CONFIGFS_FS is not set | ||
1006 | |||
1007 | # | ||
1008 | # Miscellaneous filesystems | ||
1009 | # | ||
1010 | # CONFIG_ADFS_FS is not set | ||
1011 | # CONFIG_AFFS_FS is not set | ||
1012 | # CONFIG_HFS_FS is not set | ||
1013 | # CONFIG_HFSPLUS_FS is not set | ||
1014 | # CONFIG_BEFS_FS is not set | ||
1015 | # CONFIG_BFS_FS is not set | ||
1016 | # CONFIG_EFS_FS is not set | ||
1017 | CONFIG_CRAMFS=m | ||
1018 | # CONFIG_VXFS_FS is not set | ||
1019 | # CONFIG_HPFS_FS is not set | ||
1020 | # CONFIG_QNX4FS_FS is not set | ||
1021 | # CONFIG_SYSV_FS is not set | ||
1022 | # CONFIG_UFS_FS is not set | ||
1023 | |||
1024 | # | ||
1025 | # Network File Systems | ||
1026 | # | ||
1027 | CONFIG_NFS_FS=y | ||
1028 | CONFIG_NFS_V3=y | ||
1029 | # CONFIG_NFS_V3_ACL is not set | ||
1030 | # CONFIG_NFS_V4 is not set | ||
1031 | # CONFIG_NFS_DIRECTIO is not set | ||
1032 | # CONFIG_NFSD is not set | ||
1033 | CONFIG_ROOT_NFS=y | ||
1034 | CONFIG_LOCKD=y | ||
1035 | CONFIG_LOCKD_V4=y | ||
1036 | CONFIG_NFS_COMMON=y | ||
1037 | CONFIG_SUNRPC=y | ||
1038 | # CONFIG_RPCSEC_GSS_KRB5 is not set | ||
1039 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | ||
1040 | # CONFIG_SMB_FS is not set | ||
1041 | # CONFIG_CIFS is not set | ||
1042 | # CONFIG_NCP_FS is not set | ||
1043 | # CONFIG_CODA_FS is not set | ||
1044 | # CONFIG_AFS_FS is not set | ||
1045 | # CONFIG_9P_FS is not set | ||
1046 | |||
1047 | # | ||
1048 | # Partition Types | ||
1049 | # | ||
1050 | # CONFIG_PARTITION_ADVANCED is not set | ||
1051 | CONFIG_MSDOS_PARTITION=y | ||
1052 | |||
1053 | # | ||
1054 | # Native Language Support | ||
1055 | # | ||
1056 | # CONFIG_NLS is not set | ||
1057 | |||
1058 | # | ||
1059 | # Profiling support | ||
1060 | # | ||
1061 | # CONFIG_PROFILING is not set | ||
1062 | |||
1063 | # | ||
1064 | # Kernel hacking | ||
1065 | # | ||
1066 | # CONFIG_PRINTK_TIME is not set | ||
1067 | # CONFIG_MAGIC_SYSRQ is not set | ||
1068 | # CONFIG_DEBUG_KERNEL is not set | ||
1069 | CONFIG_LOG_BUF_SHIFT=14 | ||
1070 | CONFIG_CROSSCOMPILE=y | ||
1071 | CONFIG_CMDLINE="mem=64M console=ttyVR0,115200 ip=any root=/dev/nfs" | ||
1072 | |||
1073 | # | ||
1074 | # Security options | ||
1075 | # | ||
1076 | CONFIG_KEYS=y | ||
1077 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
1078 | # CONFIG_SECURITY is not set | ||
1079 | |||
1080 | # | ||
1081 | # Cryptographic options | ||
1082 | # | ||
1083 | # CONFIG_CRYPTO is not set | ||
1084 | |||
1085 | # | ||
1086 | # Hardware crypto devices | ||
1087 | # | ||
1088 | |||
1089 | # | ||
1090 | # Library routines | ||
1091 | # | ||
1092 | # CONFIG_CRC_CCITT is not set | ||
1093 | # CONFIG_CRC16 is not set | ||
1094 | CONFIG_CRC32=y | ||
1095 | # CONFIG_LIBCRC32C is not set | ||
1096 | CONFIG_ZLIB_INFLATE=m | ||
diff --git a/arch/mips/ddb5xxx/ddb5074/Makefile b/arch/mips/ddb5xxx/ddb5074/Makefile index 488206b8d94e..304c02107b46 100644 --- a/arch/mips/ddb5xxx/ddb5074/Makefile +++ b/arch/mips/ddb5xxx/ddb5074/Makefile | |||
@@ -3,6 +3,6 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += setup.o irq.o int-handler.o nile4_pic.o | 6 | obj-y += setup.o irq.o nile4_pic.o |
7 | 7 | ||
8 | EXTRA_AFLAGS := $(CFLAGS) | 8 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/ddb5xxx/ddb5074/int-handler.S b/arch/mips/ddb5xxx/ddb5074/int-handler.S deleted file mode 100644 index a78644150b37..000000000000 --- a/arch/mips/ddb5xxx/ddb5074/int-handler.S +++ /dev/null | |||
@@ -1,120 +0,0 @@ | |||
1 | /* | ||
2 | * arch/mips/ddb5074/int-handler.S -- NEC DDB Vrc-5074 interrupt handler | ||
3 | * | ||
4 | * Based on arch/mips/sgi/kernel/indyIRQ.S | ||
5 | * | ||
6 | * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) | ||
7 | * | ||
8 | * Copyright (C) 2000 Geert Uytterhoeven <geert@sonycom.com> | ||
9 | * Sony Software Development Center Europe (SDCE), Brussels | ||
10 | */ | ||
11 | #include <asm/asm.h> | ||
12 | #include <asm/mipsregs.h> | ||
13 | #include <asm/regdef.h> | ||
14 | #include <asm/stackframe.h> | ||
15 | |||
16 | /* A lot of complication here is taken away because: | ||
17 | * | ||
18 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
19 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
20 | * common case is one pending IRQ so optimize in that direction. | ||
21 | * | ||
22 | * 2) We need not check against bits in the status register IRQ mask, that | ||
23 | * would make this routine slow as hell. | ||
24 | * | ||
25 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
26 | * between like BSD spl() brain-damage. | ||
27 | * | ||
28 | * Furthermore, the IRQs on the INDY look basically (barring software IRQs | ||
29 | * which we don't use at all) like: | ||
30 | * | ||
31 | * MIPS IRQ Source | ||
32 | * -------- ------ | ||
33 | * 0 Software (ignored) | ||
34 | * 1 Software (ignored) | ||
35 | * 2 Local IRQ level zero | ||
36 | * 3 Local IRQ level one | ||
37 | * 4 8254 Timer zero | ||
38 | * 5 8254 Timer one | ||
39 | * 6 Bus Error | ||
40 | * 7 R4k timer (what we use) | ||
41 | * | ||
42 | * We handle the IRQ according to _our_ priority which is: | ||
43 | * | ||
44 | * Highest ---- R4k Timer | ||
45 | * Local IRQ zero | ||
46 | * Local IRQ one | ||
47 | * Bus Error | ||
48 | * 8254 Timer zero | ||
49 | * Lowest ---- 8254 Timer one | ||
50 | * | ||
51 | * then we just return, if multiple IRQs are pending then we will just take | ||
52 | * another exception, big deal. | ||
53 | */ | ||
54 | |||
55 | .text | ||
56 | .set noreorder | ||
57 | .set noat | ||
58 | .align 5 | ||
59 | NESTED(ddbIRQ, PT_SIZE, sp) | ||
60 | SAVE_ALL | ||
61 | CLI | ||
62 | .set at | ||
63 | mfc0 s0, CP0_CAUSE # get irq mask | ||
64 | |||
65 | #if 1 | ||
66 | mfc0 t2,CP0_STATUS # get enabled interrupts | ||
67 | and s0,t2 # isolate allowed ones | ||
68 | #endif | ||
69 | /* First we check for r4k counter/timer IRQ. */ | ||
70 | andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero | ||
71 | beq a0, zero, 1f | ||
72 | andi a0, s0, CAUSEF_IP3 # delay slot, check local level one | ||
73 | |||
74 | /* Wheee, local level zero interrupt. */ | ||
75 | jal ddb_local0_irqdispatch | ||
76 | move a0, sp # delay slot | ||
77 | |||
78 | j ret_from_irq | ||
79 | nop # delay slot | ||
80 | |||
81 | 1: | ||
82 | beq a0, zero, 1f | ||
83 | andi a0, s0, CAUSEF_IP6 # delay slot, check bus error | ||
84 | |||
85 | /* Wheee, local level one interrupt. */ | ||
86 | move a0, sp | ||
87 | jal ddb_local1_irqdispatch | ||
88 | nop | ||
89 | |||
90 | j ret_from_irq | ||
91 | nop | ||
92 | |||
93 | 1: | ||
94 | beq a0, zero, 1f | ||
95 | nop | ||
96 | |||
97 | /* Wheee, an asynchronous bus error... */ | ||
98 | move a0, sp | ||
99 | jal ddb_buserror_irq | ||
100 | nop | ||
101 | |||
102 | j ret_from_irq | ||
103 | nop | ||
104 | |||
105 | 1: | ||
106 | /* Here by mistake? This is possible, what can happen | ||
107 | * is that by the time we take the exception the IRQ | ||
108 | * pin goes low, so just leave if this is the case. | ||
109 | */ | ||
110 | andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) | ||
111 | beq a0, zero, 1f | ||
112 | |||
113 | /* Must be one of the 8254 timers... */ | ||
114 | move a0, sp | ||
115 | jal ddb_8254timer_irq | ||
116 | nop | ||
117 | 1: | ||
118 | j ret_from_irq | ||
119 | nop | ||
120 | END(ddbIRQ) | ||
diff --git a/arch/mips/ddb5xxx/ddb5074/irq.c b/arch/mips/ddb5xxx/ddb5074/irq.c index 45088a1be414..60c087b7738c 100644 --- a/arch/mips/ddb5xxx/ddb5074/irq.c +++ b/arch/mips/ddb5xxx/ddb5074/irq.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <asm/ddb5xxx/ddb5074.h> | 21 | #include <asm/ddb5xxx/ddb5074.h> |
22 | 22 | ||
23 | 23 | ||
24 | extern asmlinkage void ddbIRQ(void); | ||
25 | |||
26 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; | 24 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; |
27 | 25 | ||
28 | #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ | 26 | #define M1543_PNP_CONFIG 0x03f0 /* PnP Config Port */ |
@@ -90,7 +88,7 @@ static void m1543_irq_setup(void) | |||
90 | 88 | ||
91 | } | 89 | } |
92 | 90 | ||
93 | void ddb_local0_irqdispatch(struct pt_regs *regs) | 91 | static void ddb_local0_irqdispatch(struct pt_regs *regs) |
94 | { | 92 | { |
95 | u32 mask; | 93 | u32 mask; |
96 | int nile4_irq; | 94 | int nile4_irq; |
@@ -118,29 +116,41 @@ void ddb_local0_irqdispatch(struct pt_regs *regs) | |||
118 | } | 116 | } |
119 | } | 117 | } |
120 | 118 | ||
121 | void ddb_local1_irqdispatch(void) | 119 | static void ddb_local1_irqdispatch(void) |
122 | { | 120 | { |
123 | printk("ddb_local1_irqdispatch called\n"); | 121 | printk("ddb_local1_irqdispatch called\n"); |
124 | } | 122 | } |
125 | 123 | ||
126 | void ddb_buserror_irq(void) | 124 | static void ddb_buserror_irq(void) |
127 | { | 125 | { |
128 | printk("ddb_buserror_irq called\n"); | 126 | printk("ddb_buserror_irq called\n"); |
129 | } | 127 | } |
130 | 128 | ||
131 | void ddb_8254timer_irq(void) | 129 | static void ddb_8254timer_irq(void) |
132 | { | 130 | { |
133 | printk("ddb_8254timer_irq called\n"); | 131 | printk("ddb_8254timer_irq called\n"); |
134 | } | 132 | } |
135 | 133 | ||
134 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
135 | { | ||
136 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
137 | |||
138 | if (pending & CAUSEF_IP2) | ||
139 | ddb_local0_irqdispatch(regs); | ||
140 | else if (pending & CAUSEF_IP3) | ||
141 | ddb_local1_irqdispatch(); | ||
142 | else if (pending & CAUSEF_IP6) | ||
143 | ddb_buserror_irq(); | ||
144 | else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) | ||
145 | ddb_8254timer_irq(); | ||
146 | } | ||
147 | |||
136 | void __init arch_init_irq(void) | 148 | void __init arch_init_irq(void) |
137 | { | 149 | { |
138 | /* setup cascade interrupts */ | 150 | /* setup cascade interrupts */ |
139 | setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade); | 151 | setup_irq(NILE4_IRQ_BASE + NILE4_INT_INTE, &irq_cascade); |
140 | setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade); | 152 | setup_irq(CPU_IRQ_BASE + CPU_NILE4_CASCADE, &irq_cascade); |
141 | 153 | ||
142 | set_except_vector(0, ddbIRQ); | ||
143 | |||
144 | nile4_irq_setup(NILE4_IRQ_BASE); | 154 | nile4_irq_setup(NILE4_IRQ_BASE); |
145 | m1543_irq_setup(); | 155 | m1543_irq_setup(); |
146 | init_i8259_irqs(); | 156 | init_i8259_irqs(); |
diff --git a/arch/mips/ddb5xxx/ddb5476/Makefile b/arch/mips/ddb5xxx/ddb5476/Makefile index 61eec363cb02..ab0312cb47b4 100644 --- a/arch/mips/ddb5xxx/ddb5476/Makefile +++ b/arch/mips/ddb5xxx/ddb5476/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += setup.o irq.o int-handler.o nile4_pic.o vrc5476_irq.o | 6 | obj-y += setup.o irq.o nile4_pic.o vrc5476_irq.o |
7 | obj-$(CONFIG_KGDB) += dbg_io.o | 7 | obj-$(CONFIG_KGDB) += dbg_io.o |
8 | 8 | ||
9 | EXTRA_AFLAGS := $(CFLAGS) | 9 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/ddb5xxx/ddb5476/int-handler.S b/arch/mips/ddb5xxx/ddb5476/int-handler.S deleted file mode 100644 index 12c292e189ba..000000000000 --- a/arch/mips/ddb5xxx/ddb5476/int-handler.S +++ /dev/null | |||
@@ -1,112 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ddb5476 | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | |||
18 | #include <asm/ddb5xxx/ddb5476.h> | ||
19 | |||
20 | /* | ||
21 | * first level interrupt dispatcher for ocelot board - | ||
22 | * We check for the timer first, then check PCI ints A and D. | ||
23 | * Then check for serial IRQ and fall through. | ||
24 | */ | ||
25 | .align 5 | ||
26 | NESTED(ddb5476_handle_int, PT_SIZE, sp) | ||
27 | SAVE_ALL | ||
28 | CLI | ||
29 | .set at | ||
30 | .set noreorder | ||
31 | mfc0 t0, CP0_CAUSE | ||
32 | mfc0 t2, CP0_STATUS | ||
33 | |||
34 | and t0, t2 | ||
35 | |||
36 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
37 | bnez t1, ll_cpu_ip7 | ||
38 | andi t1, t0, STATUSF_IP2 /* vrc5476 & i8259 */ | ||
39 | bnez t1, ll_cpu_ip2 | ||
40 | andi t1, t0, STATUSF_IP3 | ||
41 | bnez t1, ll_cpu_ip3 | ||
42 | andi t1, t0, STATUSF_IP4 | ||
43 | bnez t1, ll_cpu_ip4 | ||
44 | andi t1, t0, STATUSF_IP5 | ||
45 | bnez t1, ll_cpu_ip5 | ||
46 | andi t1, t0, STATUSF_IP6 | ||
47 | bnez t1, ll_cpu_ip6 | ||
48 | andi t1, t0, STATUSF_IP0 /* software int 0 */ | ||
49 | bnez t1, ll_cpu_ip0 | ||
50 | andi t1, t0, STATUSF_IP1 /* software int 1 */ | ||
51 | bnez t1, ll_cpu_ip1 | ||
52 | nop | ||
53 | |||
54 | .set reorder | ||
55 | |||
56 | /* wrong alarm or masked ... */ | ||
57 | // j spurious_interrupt | ||
58 | move a0, sp | ||
59 | jal vrc5476_irq_dispatch | ||
60 | j ret_from_irq | ||
61 | nop | ||
62 | |||
63 | .align 5 | ||
64 | |||
65 | ll_cpu_ip0: | ||
66 | li a0, CPU_IRQ_BASE + 0 | ||
67 | move a1, sp | ||
68 | jal do_IRQ | ||
69 | j ret_from_irq | ||
70 | |||
71 | ll_cpu_ip1: | ||
72 | li a0, CPU_IRQ_BASE + 1 | ||
73 | move a1, sp | ||
74 | jal do_IRQ | ||
75 | j ret_from_irq | ||
76 | |||
77 | ll_cpu_ip2: /* jump to second-level dispatching */ | ||
78 | move a0, sp | ||
79 | jal vrc5476_irq_dispatch | ||
80 | j ret_from_irq | ||
81 | |||
82 | ll_cpu_ip3: | ||
83 | li a0, CPU_IRQ_BASE + 3 | ||
84 | move a1, sp | ||
85 | jal do_IRQ | ||
86 | j ret_from_irq | ||
87 | |||
88 | ll_cpu_ip4: | ||
89 | li a0, CPU_IRQ_BASE + 4 | ||
90 | move a1, sp | ||
91 | jal do_IRQ | ||
92 | j ret_from_irq | ||
93 | |||
94 | ll_cpu_ip5: | ||
95 | li a0, CPU_IRQ_BASE + 5 | ||
96 | move a1, sp | ||
97 | jal do_IRQ | ||
98 | j ret_from_irq | ||
99 | |||
100 | ll_cpu_ip6: | ||
101 | li a0, CPU_IRQ_BASE + 6 | ||
102 | move a1, sp | ||
103 | jal do_IRQ | ||
104 | j ret_from_irq | ||
105 | |||
106 | ll_cpu_ip7: | ||
107 | li a0, CPU_IRQ_BASE + 7 | ||
108 | move a1, sp | ||
109 | jal do_IRQ | ||
110 | j ret_from_irq | ||
111 | |||
112 | END(ddb5476_handle_int) | ||
diff --git a/arch/mips/ddb5xxx/ddb5476/irq.c b/arch/mips/ddb5xxx/ddb5476/irq.c index 5388b5868c4a..7583a1f30711 100644 --- a/arch/mips/ddb5xxx/ddb5476/irq.c +++ b/arch/mips/ddb5xxx/ddb5476/irq.c | |||
@@ -110,11 +110,36 @@ static void nile4_irq_setup(void) | |||
110 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; | 110 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; |
111 | static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; | 111 | static struct irqaction irq_error = { no_action, 0, CPU_MASK_NONE, "error", NULL, NULL }; |
112 | 112 | ||
113 | extern asmlinkage void ddb5476_handle_int(void); | ||
114 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); | 113 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); |
115 | extern void mips_cpu_irq_init(u32 irq_base); | 114 | extern void mips_cpu_irq_init(u32 irq_base); |
116 | extern void vrc5476_irq_init(u32 irq_base); | 115 | extern void vrc5476_irq_init(u32 irq_base); |
117 | 116 | ||
117 | extern void vrc5476_irq_dispatch(struct pt_regs *regs); | ||
118 | |||
119 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
120 | { | ||
121 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
122 | |||
123 | if (pending & STATUSF_IP7) | ||
124 | do_IRQ(CPU_IRQ_BASE + 7, regs); | ||
125 | else if (pending & STATUSF_IP2) | ||
126 | vrc5476_irq_dispatch(regs); | ||
127 | else if (pending & STATUSF_IP3) | ||
128 | do_IRQ(CPU_IRQ_BASE + 3, regs); | ||
129 | else if (pending & STATUSF_IP4) | ||
130 | do_IRQ(CPU_IRQ_BASE + 4, regs); | ||
131 | else if (pending & STATUSF_IP5) | ||
132 | do_IRQ(CPU_IRQ_BASE + 5, regs); | ||
133 | else if (pending & STATUSF_IP6) | ||
134 | do_IRQ(CPU_IRQ_BASE + 6, regs); | ||
135 | else if (pending & STATUSF_IP0) | ||
136 | do_IRQ(CPU_IRQ_BASE, regs); | ||
137 | else if (pending & STATUSF_IP1) | ||
138 | do_IRQ(CPU_IRQ_BASE + 1, regs); | ||
139 | |||
140 | vrc5476_irq_dispatch(regs); | ||
141 | } | ||
142 | |||
118 | void __init arch_init_irq(void) | 143 | void __init arch_init_irq(void) |
119 | { | 144 | { |
120 | /* hardware initialization */ | 145 | /* hardware initialization */ |
@@ -137,7 +162,4 @@ void __init arch_init_irq(void) | |||
137 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error); | 162 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_LBRT, &irq_error); |
138 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error); | 163 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCIS, &irq_error); |
139 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error); | 164 | setup_irq(VRC5476_IRQ_BASE + VRC5476_IRQ_PCI, &irq_error); |
140 | |||
141 | /* setup the grandpa intr vector */ | ||
142 | set_except_vector(0, ddb5476_handle_int); | ||
143 | } | 165 | } |
diff --git a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c index f66fe5b58636..a3c5e7b18018 100644 --- a/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c +++ b/arch/mips/ddb5xxx/ddb5476/vrc5476_irq.c | |||
@@ -77,11 +77,9 @@ vrc5476_irq_init(u32 base) | |||
77 | } | 77 | } |
78 | 78 | ||
79 | 79 | ||
80 | asmlinkage void | 80 | void |
81 | vrc5476_irq_dispatch(struct pt_regs *regs) | 81 | vrc5476_irq_dispatch(struct pt_regs *regs) |
82 | { | 82 | { |
83 | extern void spurious_interrupt(void); | ||
84 | |||
85 | u32 mask; | 83 | u32 mask; |
86 | int nile4_irq; | 84 | int nile4_irq; |
87 | 85 | ||
@@ -107,5 +105,5 @@ vrc5476_irq_dispatch(struct pt_regs *regs) | |||
107 | return; | 105 | return; |
108 | } | 106 | } |
109 | } | 107 | } |
110 | spurious_interrupt(); | 108 | spurious_interrupt(regs); |
111 | } | 109 | } |
diff --git a/arch/mips/ddb5xxx/ddb5477/Makefile b/arch/mips/ddb5xxx/ddb5477/Makefile index b79b43c9f93b..ea68815ad17a 100644 --- a/arch/mips/ddb5xxx/ddb5477/Makefile +++ b/arch/mips/ddb5xxx/ddb5477/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for NEC DDB-Vrc5477 board | 2 | # Makefile for NEC DDB-Vrc5477 board |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += int-handler.o irq.o irq_5477.o setup.o lcd44780.o | 5 | obj-y += irq.o irq_5477.o setup.o lcd44780.o |
6 | 6 | ||
7 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o | 7 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o |
8 | obj-$(CONFIG_KGDB) += kgdb_io.o | 8 | obj-$(CONFIG_KGDB) += kgdb_io.o |
diff --git a/arch/mips/ddb5xxx/ddb5477/int-handler.S b/arch/mips/ddb5xxx/ddb5477/int-handler.S deleted file mode 100644 index a2502a14400e..000000000000 --- a/arch/mips/ddb5xxx/ddb5477/int-handler.S +++ /dev/null | |||
@@ -1,75 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ddb5477 | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | #include <asm/ddb5xxx/ddb5477.h> | ||
18 | |||
19 | /* | ||
20 | * first level interrupt dispatcher for ocelot board - | ||
21 | * We check for the timer first, then check PCI ints A and D. | ||
22 | * Then check for serial IRQ and fall through. | ||
23 | */ | ||
24 | .align 5 | ||
25 | NESTED(ddb5477_handle_int, PT_SIZE, sp) | ||
26 | SAVE_ALL | ||
27 | CLI | ||
28 | .set at | ||
29 | .set noreorder | ||
30 | mfc0 t0, CP0_CAUSE | ||
31 | mfc0 t2, CP0_STATUS | ||
32 | |||
33 | and t0, t2 | ||
34 | |||
35 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
36 | bnez t1, ll_cputimer_irq | ||
37 | andi t1, t0, (STATUSF_IP2 | STATUSF_IP3 | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 ) | ||
38 | bnez t1, ll_vrc5477_irq | ||
39 | andi t1, t0, STATUSF_IP0 /* software int 0 */ | ||
40 | bnez t1, ll_cpu_ip0 | ||
41 | andi t1, t0, STATUSF_IP1 /* software int 1 */ | ||
42 | bnez t1, ll_cpu_ip1 | ||
43 | nop | ||
44 | .set reorder | ||
45 | |||
46 | /* wrong alarm or masked ... */ | ||
47 | j spurious_interrupt | ||
48 | nop | ||
49 | END(ddb5477_handle_int) | ||
50 | |||
51 | .align 5 | ||
52 | |||
53 | ll_vrc5477_irq: | ||
54 | move a0, sp | ||
55 | jal vrc5477_irq_dispatch | ||
56 | j ret_from_irq | ||
57 | |||
58 | ll_cputimer_irq: | ||
59 | li a0, CPU_IRQ_BASE + 7 | ||
60 | move a1, sp | ||
61 | jal do_IRQ | ||
62 | j ret_from_irq | ||
63 | |||
64 | |||
65 | ll_cpu_ip0: | ||
66 | li a0, CPU_IRQ_BASE + 0 | ||
67 | move a1, sp | ||
68 | jal do_IRQ | ||
69 | j ret_from_irq | ||
70 | |||
71 | ll_cpu_ip1: | ||
72 | li a0, CPU_IRQ_BASE + 1 | ||
73 | move a1, sp | ||
74 | jal do_IRQ | ||
75 | j ret_from_irq | ||
diff --git a/arch/mips/ddb5xxx/ddb5477/irq.c b/arch/mips/ddb5xxx/ddb5477/irq.c index 9ffe1a9142ca..de433cf9fb50 100644 --- a/arch/mips/ddb5xxx/ddb5477/irq.c +++ b/arch/mips/ddb5xxx/ddb5477/irq.c | |||
@@ -75,7 +75,6 @@ set_pci_int_attr(u32 pci, u32 intn, u32 active, u32 trigger) | |||
75 | 75 | ||
76 | extern void vrc5477_irq_init(u32 base); | 76 | extern void vrc5477_irq_init(u32 base); |
77 | extern void mips_cpu_irq_init(u32 base); | 77 | extern void mips_cpu_irq_init(u32 base); |
78 | extern asmlinkage void ddb5477_handle_int(void); | ||
79 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); | 78 | extern int setup_irq(unsigned int irq, struct irqaction *irqaction); |
80 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; | 79 | static struct irqaction irq_cascade = { no_action, 0, CPU_MASK_NONE, "cascade", NULL, NULL }; |
81 | 80 | ||
@@ -135,9 +134,6 @@ void __init arch_init_irq(void) | |||
135 | /* setup cascade interrupts */ | 134 | /* setup cascade interrupts */ |
136 | setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); | 135 | setup_irq(VRC5477_IRQ_BASE + VRC5477_I8259_CASCADE, &irq_cascade); |
137 | setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); | 136 | setup_irq(CPU_IRQ_BASE + CPU_VRC5477_CASCADE, &irq_cascade); |
138 | |||
139 | /* hook up the first-level interrupt handler */ | ||
140 | set_except_vector(0, ddb5477_handle_int); | ||
141 | } | 137 | } |
142 | 138 | ||
143 | u8 i8259_interrupt_ack(void) | 139 | u8 i8259_interrupt_ack(void) |
@@ -159,7 +155,7 @@ u8 i8259_interrupt_ack(void) | |||
159 | * the first level int-handler will jump here if it is a vrc5477 irq | 155 | * the first level int-handler will jump here if it is a vrc5477 irq |
160 | */ | 156 | */ |
161 | #define NUM_5477_IRQS 32 | 157 | #define NUM_5477_IRQS 32 |
162 | asmlinkage void | 158 | static void |
163 | vrc5477_irq_dispatch(struct pt_regs *regs) | 159 | vrc5477_irq_dispatch(struct pt_regs *regs) |
164 | { | 160 | { |
165 | u32 intStatus; | 161 | u32 intStatus; |
@@ -197,3 +193,21 @@ vrc5477_irq_dispatch(struct pt_regs *regs) | |||
197 | } | 193 | } |
198 | } | 194 | } |
199 | } | 195 | } |
196 | |||
197 | #define VR5477INTS (STATUSF_IP2|STATUSF_IP3|STATUSF_IP4|STATUSF_IP5|STATUSF_IP6) | ||
198 | |||
199 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
200 | { | ||
201 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
202 | |||
203 | if (pending & STATUSF_IP7) | ||
204 | do_IRQ(CPU_IRQ_BASE + 7, regs); | ||
205 | else if (pending & VR5477INTS) | ||
206 | vrc5477_irq_dispatch(regs); | ||
207 | else if (pending & STATUSF_IP0) | ||
208 | do_IRQ(CPU_IRQ_BASE, regs); | ||
209 | else if (pending & STATUSF_IP1) | ||
210 | do_IRQ(CPU_IRQ_BASE + 1, regs); | ||
211 | else | ||
212 | spurious_interrupt(regs); | ||
213 | } | ||
diff --git a/arch/mips/dec/boot/decstation.c b/arch/mips/dec/boot/decstation.c index 56fd4277555e..4db8bacaf22d 100644 --- a/arch/mips/dec/boot/decstation.c +++ b/arch/mips/dec/boot/decstation.c | |||
@@ -1,6 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * arch/mips/dec/decstation.c | 2 | * arch/mips/dec/decstation.c |
3 | */ | 3 | */ |
4 | #include <asm/sections.h> | ||
4 | 5 | ||
5 | #define RELOC | 6 | #define RELOC |
6 | #define INITRD | 7 | #define INITRD |
@@ -24,7 +25,7 @@ | |||
24 | #define INITRD_START (*(unsigned long *) (PARAM+0x218)) | 25 | #define INITRD_START (*(unsigned long *) (PARAM+0x218)) |
25 | #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) | 26 | #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c)) |
26 | 27 | ||
27 | extern int _ftext, _end; /* begin and end of kernel image */ | 28 | extern int _ftext; /* begin and end of kernel image */ |
28 | extern void kernel_entry(int, char **, unsigned long, int *); | 29 | extern void kernel_entry(int, char **, unsigned long, int *); |
29 | 30 | ||
30 | void * memcpy(void * dest, const void *src, unsigned int count) | 31 | void * memcpy(void * dest, const void *src, unsigned int count) |
diff --git a/arch/mips/dec/int-handler.S b/arch/mips/dec/int-handler.S index 41fa372007bf..e8ec93e33fe6 100644 --- a/arch/mips/dec/int-handler.S +++ b/arch/mips/dec/int-handler.S | |||
@@ -36,7 +36,7 @@ | |||
36 | .text | 36 | .text |
37 | .set noreorder | 37 | .set noreorder |
38 | /* | 38 | /* |
39 | * decstation_handle_int: Interrupt handler for DECstations | 39 | * plat_irq_dispatch: Interrupt handler for DECstations |
40 | * | 40 | * |
41 | * We follow the model in the Indy interrupt code by David Miller, where he | 41 | * We follow the model in the Indy interrupt code by David Miller, where he |
42 | * says: a lot of complication here is taken away because: | 42 | * says: a lot of complication here is taken away because: |
@@ -125,11 +125,7 @@ | |||
125 | * just take another exception, big deal. | 125 | * just take another exception, big deal. |
126 | */ | 126 | */ |
127 | .align 5 | 127 | .align 5 |
128 | NESTED(decstation_handle_int, PT_SIZE, ra) | 128 | NESTED(plat_irq_dispatch, PT_SIZE, ra) |
129 | .set noat | ||
130 | SAVE_ALL | ||
131 | CLI # TEST: interrupts should be off | ||
132 | .set at | ||
133 | .set noreorder | 129 | .set noreorder |
134 | 130 | ||
135 | /* | 131 | /* |
@@ -282,9 +278,11 @@ fpu: | |||
282 | #endif | 278 | #endif |
283 | 279 | ||
284 | spurious: | 280 | spurious: |
285 | j spurious_interrupt | 281 | jal spurious_interrupt |
286 | nop | 282 | nop |
287 | END(decstation_handle_int) | 283 | j ret_from_irq |
284 | nop | ||
285 | END(plat_irq_dispatch) | ||
288 | 286 | ||
289 | /* | 287 | /* |
290 | * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl | 288 | * Generic unimplemented interrupt routines -- cpu_mask_nr_tbl |
diff --git a/arch/mips/dec/setup.c b/arch/mips/dec/setup.c index 7c1ca8f6330e..ad5d436d80c1 100644 --- a/arch/mips/dec/setup.c +++ b/arch/mips/dec/setup.c | |||
@@ -48,8 +48,6 @@ extern void dec_machine_halt(void); | |||
48 | extern void dec_machine_power_off(void); | 48 | extern void dec_machine_power_off(void); |
49 | extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs); | 49 | extern irqreturn_t dec_intr_halt(int irq, void *dev_id, struct pt_regs *regs); |
50 | 50 | ||
51 | extern asmlinkage void decstation_handle_int(void); | ||
52 | |||
53 | unsigned long dec_kn_slot_base, dec_kn_slot_size; | 51 | unsigned long dec_kn_slot_base, dec_kn_slot_size; |
54 | 52 | ||
55 | EXPORT_SYMBOL(dec_kn_slot_base); | 53 | EXPORT_SYMBOL(dec_kn_slot_base); |
@@ -744,7 +742,6 @@ void __init arch_init_irq(void) | |||
744 | panic("Don't know how to set this up!"); | 742 | panic("Don't know how to set this up!"); |
745 | break; | 743 | break; |
746 | } | 744 | } |
747 | set_except_vector(0, decstation_handle_int); | ||
748 | 745 | ||
749 | /* Free the FPU interrupt if the exception is present. */ | 746 | /* Free the FPU interrupt if the exception is present. */ |
750 | if (!cpu_has_nofpuex) { | 747 | if (!cpu_has_nofpuex) { |
diff --git a/arch/mips/galileo-boards/ev96100/Makefile b/arch/mips/galileo-boards/ev96100/Makefile index 58c02f9db69d..cd868ec78cbc 100644 --- a/arch/mips/galileo-boards/ev96100/Makefile +++ b/arch/mips/galileo-boards/ev96100/Makefile | |||
@@ -6,4 +6,4 @@ | |||
6 | # Makefile for the Galileo EV96100 board. | 6 | # Makefile for the Galileo EV96100 board. |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += init.o irq.o puts.o reset.o time.o int-handler.o setup.o | 9 | obj-y += init.o irq.o puts.o reset.o time.o setup.o |
diff --git a/arch/mips/galileo-boards/ev96100/int-handler.S b/arch/mips/galileo-boards/ev96100/int-handler.S deleted file mode 100644 index ff4d10a38859..000000000000 --- a/arch/mips/galileo-boards/ev96100/int-handler.S +++ /dev/null | |||
@@ -1,33 +0,0 @@ | |||
1 | #include <asm/asm.h> | ||
2 | #include <asm/mipsregs.h> | ||
3 | #include <asm/regdef.h> | ||
4 | #include <asm/stackframe.h> | ||
5 | |||
6 | .set noat | ||
7 | .align 5 | ||
8 | |||
9 | NESTED(ev96100IRQ, PT_SIZE, sp) | ||
10 | SAVE_ALL | ||
11 | CLI # Important: mark KERNEL mode ! | ||
12 | |||
13 | mfc0 t0, CP0_CAUSE # get pending interrupts | ||
14 | mfc0 t1, CP0_STATUS # get enabled interrupts | ||
15 | and t0, t1 # isolate allowed ones | ||
16 | |||
17 | # FIX ME add R7000 extensions | ||
18 | andi t0,0xff00 # isolate pending bits | ||
19 | andi a0, t0, CAUSEF_IP7 | ||
20 | beq a0, zero, 1f | ||
21 | move a0, sp | ||
22 | jal mips_timer_interrupt | ||
23 | j ret_from_irq | ||
24 | |||
25 | 1: beqz t0, 3f # spurious interrupt | ||
26 | |||
27 | move a0, t0 | ||
28 | move a1, sp | ||
29 | jal ev96100_cpu_irq | ||
30 | j ret_from_irq | ||
31 | |||
32 | 3: j spurious_interrupt | ||
33 | END(ev96100IRQ) | ||
diff --git a/arch/mips/galileo-boards/ev96100/irq.c b/arch/mips/galileo-boards/ev96100/irq.c index 97bf094da4fe..ee5d6720f23b 100644 --- a/arch/mips/galileo-boards/ev96100/irq.c +++ b/arch/mips/galileo-boards/ev96100/irq.c | |||
@@ -40,8 +40,6 @@ | |||
40 | #include <linux/interrupt.h> | 40 | #include <linux/interrupt.h> |
41 | #include <asm/irq_cpu.h> | 41 | #include <asm/irq_cpu.h> |
42 | 42 | ||
43 | extern asmlinkage void ev96100IRQ(void); | ||
44 | |||
45 | static inline unsigned int ffz8(unsigned int word) | 43 | static inline unsigned int ffz8(unsigned int word) |
46 | { | 44 | { |
47 | unsigned long k; | 45 | unsigned long k; |
@@ -54,13 +52,26 @@ static inline unsigned int ffz8(unsigned int word) | |||
54 | return k; | 52 | return k; |
55 | } | 53 | } |
56 | 54 | ||
57 | asmlinkage void ev96100_cpu_irq(unsigned int pendin) | 55 | extern void mips_timer_interrupt(struct pt_regs *regs); |
56 | |||
57 | asmlinkage void ev96100_cpu_irq(unsigned int pending, struct pt_regs *regs) | ||
58 | { | 58 | { |
59 | do_IRQ(ffz8(pending >> 8), regs); | 59 | do_IRQ(ffz8(pending >> 8), regs); |
60 | } | 60 | } |
61 | 61 | ||
62 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
63 | { | ||
64 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
65 | |||
66 | if (pending & CAUSEF_IP7) | ||
67 | mips_timer_interrupt(regs); | ||
68 | else if (pending) | ||
69 | ev96100_cpu_irq(pending, regs); | ||
70 | else | ||
71 | spurious_interrupt(regs); | ||
72 | } | ||
73 | |||
62 | void __init arch_init_irq(void) | 74 | void __init arch_init_irq(void) |
63 | { | 75 | { |
64 | set_except_vector(0, ev96100IRQ); | ||
65 | mips_cpu_irq_init(0); | 76 | mips_cpu_irq_init(0); |
66 | } | 77 | } |
diff --git a/arch/mips/gt64120/ev64120/Makefile b/arch/mips/gt64120/ev64120/Makefile index ebe91c57e173..b2c53a8f8718 100644 --- a/arch/mips/gt64120/ev64120/Makefile +++ b/arch/mips/gt64120/ev64120/Makefile | |||
@@ -6,6 +6,6 @@ | |||
6 | # Makefile for the Galileo EV64120 board. | 6 | # Makefile for the Galileo EV64120 board. |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += int-handler.o irq.o promcon.o reset.o serialGT.o setup.o | 9 | obj-y += irq.o promcon.o reset.o serialGT.o setup.o |
10 | 10 | ||
11 | EXTRA_AFLAGS := $(CFLAGS) | 11 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/gt64120/ev64120/int-handler.S b/arch/mips/gt64120/ev64120/int-handler.S deleted file mode 100644 index 752435faf2de..000000000000 --- a/arch/mips/gt64120/ev64120/int-handler.S +++ /dev/null | |||
@@ -1,113 +0,0 @@ | |||
1 | /* | ||
2 | * int-handler.S | ||
3 | * | ||
4 | * Based on the cobalt handler. | ||
5 | */ | ||
6 | #include <asm/asm.h> | ||
7 | #include <asm/mipsregs.h> | ||
8 | #include <asm/addrspace.h> | ||
9 | #include <asm/regdef.h> | ||
10 | #include <asm/stackframe.h> | ||
11 | |||
12 | /* | ||
13 | * galileo_handle_int - | ||
14 | * We check for the timer first, then check PCI ints A and D. | ||
15 | * Then check for serial IRQ and fall through. | ||
16 | */ | ||
17 | .align 5 | ||
18 | .set reorder | ||
19 | .set noat | ||
20 | NESTED(galileo_handle_int, PT_SIZE, sp) | ||
21 | SAVE_ALL | ||
22 | CLI | ||
23 | .set at | ||
24 | mfc0 t0,CP0_CAUSE | ||
25 | mfc0 t2,CP0_STATUS | ||
26 | |||
27 | and t0,t2 | ||
28 | |||
29 | andi t1,t0,STATUSF_IP4 /* int2 hardware line (timer) */ | ||
30 | bnez t1,ll_gt64120_irq | ||
31 | andi t1,t0,STATUSF_IP2 /* int0 hardware line */ | ||
32 | bnez t1,ll_pci_intA | ||
33 | andi t1,t0,STATUSF_IP5 /* int3 hardware line */ | ||
34 | bnez t1,ll_pci_intD | ||
35 | andi t1,t0,STATUSF_IP6 /* int4 hardware line */ | ||
36 | bnez t1,ll_serial_irq | ||
37 | andi t1,t0,STATUSF_IP7 /* compare int */ | ||
38 | bnez t1,ll_compare_irq | ||
39 | nop | ||
40 | |||
41 | /* wrong alarm or masked ... */ | ||
42 | j spurious_interrupt | ||
43 | nop | ||
44 | END(galileo_handle_int) | ||
45 | |||
46 | |||
47 | .align 5 | ||
48 | .set reorder | ||
49 | ll_gt64120_irq: | ||
50 | li a0,4 | ||
51 | move a1,sp | ||
52 | jal do_IRQ | ||
53 | nop | ||
54 | j ret_from_irq | ||
55 | nop | ||
56 | |||
57 | .align 5 | ||
58 | .set reorder | ||
59 | ll_compare_irq: | ||
60 | li a0,7 | ||
61 | move a1,sp | ||
62 | jal do_IRQ | ||
63 | nop | ||
64 | j ret_from_irq | ||
65 | nop | ||
66 | |||
67 | .align 5 | ||
68 | .set reorder | ||
69 | ll_pci_intA: | ||
70 | move a0,sp | ||
71 | jal pci_intA | ||
72 | nop | ||
73 | j ret_from_irq | ||
74 | nop | ||
75 | |||
76 | #if 0 | ||
77 | .align 5 | ||
78 | .set reorder | ||
79 | ll_pci_intB: | ||
80 | move a0,sp | ||
81 | jal pci_intB | ||
82 | nop | ||
83 | j ret_from_irq | ||
84 | nop | ||
85 | |||
86 | .align 5 | ||
87 | .set reorder | ||
88 | ll_pci_intC: | ||
89 | move a0,sp | ||
90 | jal pci_intC | ||
91 | nop | ||
92 | j ret_from_irq | ||
93 | nop | ||
94 | #endif | ||
95 | |||
96 | .align 5 | ||
97 | .set reorder | ||
98 | ll_pci_intD: | ||
99 | move a0,sp | ||
100 | jal pci_intD | ||
101 | nop | ||
102 | j ret_from_irq | ||
103 | nop | ||
104 | |||
105 | .align 5 | ||
106 | .set reorder | ||
107 | ll_serial_irq: | ||
108 | li a0,6 | ||
109 | move a1,sp | ||
110 | jal do_IRQ | ||
111 | nop | ||
112 | j ret_from_irq | ||
113 | nop | ||
diff --git a/arch/mips/gt64120/ev64120/irq.c b/arch/mips/gt64120/ev64120/irq.c index 3b186159b21a..46c468b26b30 100644 --- a/arch/mips/gt64120/ev64120/irq.c +++ b/arch/mips/gt64120/ev64120/irq.c | |||
@@ -46,14 +46,22 @@ | |||
46 | #include <asm/system.h> | 46 | #include <asm/system.h> |
47 | #include <asm/gt64120.h> | 47 | #include <asm/gt64120.h> |
48 | 48 | ||
49 | asmlinkage inline void pci_intA(struct pt_regs *regs) | 49 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
50 | { | 50 | { |
51 | do_IRQ(GT_INTA, regs); | 51 | unsigned int pending = read_c0_status() & read_c0_cause(); |
52 | } | 52 | |
53 | 53 | if (pending & STATUSF_IP4) /* int2 hardware line (timer) */ | |
54 | asmlinkage inline void pci_intD(struct pt_regs *regs) | 54 | do_IRQ(4, regs); |
55 | { | 55 | else if (pending & STATUSF_IP2) /* int0 hardware line */ |
56 | do_IRQ(GT_INTD, regs); | 56 | do_IRQ(GT_INTA, regs); |
57 | else if (pending & STATUSF_IP5) /* int3 hardware line */ | ||
58 | do_IRQ(GT_INTD, regs); | ||
59 | else if (pending & STATUSF_IP6) /* int4 hardware line */ | ||
60 | do_IRQ(6, regs); | ||
61 | else if (pending & STATUSF_IP7) /* compare int */ | ||
62 | do_IRQ(7, regs); | ||
63 | else | ||
64 | spurious_interrupt(regs); | ||
57 | } | 65 | } |
58 | 66 | ||
59 | static void disable_ev64120_irq(unsigned int irq_nr) | 67 | static void disable_ev64120_irq(unsigned int irq_nr) |
@@ -109,16 +117,11 @@ static struct hw_interrupt_type ev64120_irq_type = { | |||
109 | 117 | ||
110 | void gt64120_irq_setup(void) | 118 | void gt64120_irq_setup(void) |
111 | { | 119 | { |
112 | extern asmlinkage void galileo_handle_int(void); | ||
113 | |||
114 | /* | 120 | /* |
115 | * Clear all of the interrupts while we change the able around a bit. | 121 | * Clear all of the interrupts while we change the able around a bit. |
116 | */ | 122 | */ |
117 | clear_c0_status(ST0_IM); | 123 | clear_c0_status(ST0_IM); |
118 | 124 | ||
119 | /* Sets the exception_handler array. */ | ||
120 | set_except_vector(0, galileo_handle_int); | ||
121 | |||
122 | local_irq_disable(); | 125 | local_irq_disable(); |
123 | 126 | ||
124 | /* | 127 | /* |
diff --git a/arch/mips/gt64120/momenco_ocelot/Makefile b/arch/mips/gt64120/momenco_ocelot/Makefile index 7b59c6567c79..6f708df8373b 100644 --- a/arch/mips/gt64120/momenco_ocelot/Makefile +++ b/arch/mips/gt64120/momenco_ocelot/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for Momentum's Ocelot board. | 2 | # Makefile for Momentum's Ocelot board. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += int-handler.o irq.o prom.o reset.o setup.o | 5 | obj-y += irq.o prom.o reset.o setup.o |
6 | 6 | ||
7 | obj-$(CONFIG_KGDB) += dbg_io.o | 7 | obj-$(CONFIG_KGDB) += dbg_io.o |
8 | 8 | ||
diff --git a/arch/mips/gt64120/momenco_ocelot/int-handler.S b/arch/mips/gt64120/momenco_ocelot/int-handler.S deleted file mode 100644 index 808acef248cc..000000000000 --- a/arch/mips/gt64120/momenco_ocelot/int-handler.S +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ocelot board. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | |||
18 | /* | ||
19 | * first level interrupt dispatcher for ocelot board - | ||
20 | * We check for the timer first, then check PCI ints A and D. | ||
21 | * Then check for serial IRQ and fall through. | ||
22 | */ | ||
23 | .align 5 | ||
24 | NESTED(ocelot_handle_int, PT_SIZE, sp) | ||
25 | SAVE_ALL | ||
26 | CLI | ||
27 | .set at | ||
28 | mfc0 t0, CP0_CAUSE | ||
29 | mfc0 t2, CP0_STATUS | ||
30 | |||
31 | and t0, t2 | ||
32 | |||
33 | andi t1, t0, STATUSF_IP2 /* int0 hardware line */ | ||
34 | bnez t1, ll_pri_enet_irq | ||
35 | andi t1, t0, STATUSF_IP3 /* int1 hardware line */ | ||
36 | bnez t1, ll_sec_enet_irq | ||
37 | andi t1, t0, STATUSF_IP4 /* int2 hardware line */ | ||
38 | bnez t1, ll_uart1_irq | ||
39 | andi t1, t0, STATUSF_IP5 /* int3 hardware line */ | ||
40 | bnez t1, ll_cpci_irq | ||
41 | andi t1, t0, STATUSF_IP6 /* int4 hardware line */ | ||
42 | bnez t1, ll_galileo_irq | ||
43 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
44 | bnez t1, ll_cputimer_irq | ||
45 | |||
46 | /* now look at the extended interrupts */ | ||
47 | mfc0 t0, CP0_CAUSE | ||
48 | cfc0 t1, CP0_S1_INTCONTROL | ||
49 | |||
50 | /* shift the mask 8 bits left to line up the bits */ | ||
51 | sll t2, t1, 8 | ||
52 | |||
53 | and t0, t2 | ||
54 | srl t0, t0, 16 | ||
55 | |||
56 | andi t1, t0, STATUSF_IP8 /* int6 hardware line */ | ||
57 | bnez t1, ll_pmc1_irq | ||
58 | andi t1, t0, STATUSF_IP9 /* int7 hardware line */ | ||
59 | bnez t1, ll_pmc2_irq | ||
60 | andi t1, t0, STATUSF_IP10 /* int8 hardware line */ | ||
61 | bnez t1, ll_cpci_abcd_irq | ||
62 | andi t1, t0, STATUSF_IP11 /* int9 hardware line */ | ||
63 | bnez t1, ll_uart2_irq | ||
64 | |||
65 | .set reorder | ||
66 | |||
67 | /* wrong alarm or masked ... */ | ||
68 | j spurious_interrupt | ||
69 | nop | ||
70 | END(ocelot_handle_int) | ||
71 | |||
72 | .align 5 | ||
73 | ll_pri_enet_irq: | ||
74 | li a0, 2 | ||
75 | move a1, sp | ||
76 | jal do_IRQ | ||
77 | j ret_from_irq | ||
78 | |||
79 | ll_sec_enet_irq: | ||
80 | li a0, 3 | ||
81 | move a1, sp | ||
82 | jal do_IRQ | ||
83 | j ret_from_irq | ||
84 | |||
85 | ll_uart1_irq: | ||
86 | li a0, 4 | ||
87 | move a1, sp | ||
88 | jal do_IRQ | ||
89 | j ret_from_irq | ||
90 | |||
91 | ll_cpci_irq: | ||
92 | li a0, 5 | ||
93 | move a1, sp | ||
94 | jal do_IRQ | ||
95 | j ret_from_irq | ||
96 | |||
97 | ll_galileo_irq: | ||
98 | li a0, 6 | ||
99 | move a1, sp | ||
100 | jal do_IRQ | ||
101 | j ret_from_irq | ||
102 | |||
103 | ll_cputimer_irq: | ||
104 | li a0, 7 | ||
105 | move a1, sp | ||
106 | jal do_IRQ | ||
107 | j ret_from_irq | ||
108 | |||
109 | ll_pmc1_irq: | ||
110 | li a0, 8 | ||
111 | move a1, sp | ||
112 | jal do_IRQ | ||
113 | j ret_from_irq | ||
114 | |||
115 | ll_pmc2_irq: | ||
116 | li a0, 9 | ||
117 | move a1, sp | ||
118 | jal do_IRQ | ||
119 | j ret_from_irq | ||
120 | |||
121 | ll_cpci_abcd_irq: | ||
122 | li a0, 10 | ||
123 | move a1, sp | ||
124 | jal do_IRQ | ||
125 | j ret_from_irq | ||
126 | |||
127 | ll_uart2_irq: | ||
128 | li a0, 11 | ||
129 | move a1, sp | ||
130 | jal do_IRQ | ||
131 | j ret_from_irq | ||
diff --git a/arch/mips/gt64120/momenco_ocelot/irq.c b/arch/mips/gt64120/momenco_ocelot/irq.c index 4f108da71b23..885f67f32ea3 100644 --- a/arch/mips/gt64120/momenco_ocelot/irq.c +++ b/arch/mips/gt64120/momenco_ocelot/irq.c | |||
@@ -48,7 +48,38 @@ | |||
48 | #include <asm/mipsregs.h> | 48 | #include <asm/mipsregs.h> |
49 | #include <asm/system.h> | 49 | #include <asm/system.h> |
50 | 50 | ||
51 | extern asmlinkage void ocelot_handle_int(void); | 51 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
52 | { | ||
53 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
54 | |||
55 | if (pending & STATUSF_IP2) /* int0 hardware line */ | ||
56 | do_IRQ(2, regs); | ||
57 | else if (pending & STATUSF_IP3) /* int1 hardware line */ | ||
58 | do_IRQ(3, regs); | ||
59 | else if (pending & STATUSF_IP4) /* int2 hardware line */ | ||
60 | do_IRQ(4, regs); | ||
61 | else if (pending & STATUSF_IP5) /* int3 hardware line */ | ||
62 | do_IRQ(5, regs); | ||
63 | else if (pending & STATUSF_IP6) /* int4 hardware line */ | ||
64 | do_IRQ(6, regs); | ||
65 | else if (pending & STATUSF_IP7) /* cpu timer */ | ||
66 | do_IRQ(7, regs); | ||
67 | else { | ||
68 | /* | ||
69 | * Now look at the extended interrupts | ||
70 | */ | ||
71 | pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; | ||
72 | |||
73 | if (pending & STATUSF_IP8) /* int6 hardware line */ | ||
74 | do_IRQ(8, regs); | ||
75 | else if (pending & STATUSF_IP9) /* int7 hardware line */ | ||
76 | do_IRQ(9, regs); | ||
77 | else if (pending & STATUSF_IP10) /* int8 hardware line */ | ||
78 | do_IRQ(10, regs); | ||
79 | else if (pending & STATUSF_IP11) /* int9 hardware line */ | ||
80 | do_IRQ(11, regs); | ||
81 | } | ||
82 | } | ||
52 | 83 | ||
53 | void __init arch_init_irq(void) | 84 | void __init arch_init_irq(void) |
54 | { | 85 | { |
@@ -59,9 +90,6 @@ void __init arch_init_irq(void) | |||
59 | clear_c0_status(ST0_IM); | 90 | clear_c0_status(ST0_IM); |
60 | local_irq_disable(); | 91 | local_irq_disable(); |
61 | 92 | ||
62 | /* Sets the first-level interrupt dispatcher. */ | ||
63 | set_except_vector(0, ocelot_handle_int); | ||
64 | |||
65 | mips_cpu_irq_init(0); | 93 | mips_cpu_irq_init(0); |
66 | rm7k_cpu_irq_init(8); | 94 | rm7k_cpu_irq_init(8); |
67 | } | 95 | } |
diff --git a/arch/mips/ite-boards/generic/Makefile b/arch/mips/ite-boards/generic/Makefile index 0e7853f43983..63431538d0ec 100644 --- a/arch/mips/ite-boards/generic/Makefile +++ b/arch/mips/ite-boards/generic/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | # Makefile for the ITE 8172 (qed-4n-s01b) board, generic files. | 6 | # Makefile for the ITE 8172 (qed-4n-s01b) board, generic files. |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += it8172_setup.o irq.o int-handler.o pmon_prom.o \ | 9 | obj-y += it8172_setup.o irq.o pmon_prom.o \ |
10 | time.o lpc.o puts.o reset.o | 10 | time.o lpc.o puts.o reset.o |
11 | 11 | ||
12 | obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o | 12 | obj-$(CONFIG_IT8172_CIR)+= it8172_cir.o |
diff --git a/arch/mips/ite-boards/generic/int-handler.S b/arch/mips/ite-boards/generic/int-handler.S deleted file mode 100644 index d190d8add9cb..000000000000 --- a/arch/mips/ite-boards/generic/int-handler.S +++ /dev/null | |||
@@ -1,63 +0,0 @@ | |||
1 | #include <asm/asm.h> | ||
2 | #include <asm/mipsregs.h> | ||
3 | #include <asm/regdef.h> | ||
4 | #include <asm/stackframe.h> | ||
5 | |||
6 | .text | ||
7 | .set macro | ||
8 | .set noat | ||
9 | .align 5 | ||
10 | |||
11 | NESTED(it8172_IRQ, PT_SIZE, sp) | ||
12 | SAVE_ALL | ||
13 | CLI # Important: mark KERNEL mode ! | ||
14 | |||
15 | /* We're working with 'reorder' set at this point. */ | ||
16 | /* | ||
17 | * Get pending interrupts | ||
18 | */ | ||
19 | |||
20 | mfc0 t0,CP0_CAUSE # get pending interrupts | ||
21 | mfc0 t1,CP0_STATUS # get enabled interrupts | ||
22 | and t0,t1 # isolate allowed ones | ||
23 | |||
24 | andi t0,0xff00 # isolate pending bits | ||
25 | beqz t0, 3f # spurious interrupt | ||
26 | |||
27 | andi a0, t0, CAUSEF_IP7 | ||
28 | beq a0, zero, 1f | ||
29 | |||
30 | li a0, 127 # MIPS_CPU_TIMER_IRQ = (NR_IRQS-1) | ||
31 | move a1, sp | ||
32 | jal ll_timer_interrupt | ||
33 | j ret_from_irq | ||
34 | nop | ||
35 | |||
36 | 1: | ||
37 | andi a0, t0, CAUSEF_IP2 # the only int we expect at this time | ||
38 | beq a0, zero, 3f | ||
39 | move a0,sp | ||
40 | jal it8172_hw0_irqdispatch | ||
41 | |||
42 | mfc0 t0,CP0_STATUS # disable interrupts | ||
43 | ori t0,1 | ||
44 | xori t0,1 | ||
45 | mtc0 t0,CP0_STATUS | ||
46 | nop | ||
47 | nop | ||
48 | nop | ||
49 | |||
50 | la a1, ret_from_irq | ||
51 | jr a1 | ||
52 | nop | ||
53 | |||
54 | 3: | ||
55 | move a0, sp | ||
56 | jal mips_spurious_interrupt | ||
57 | nop | ||
58 | la a1, ret_from_irq | ||
59 | jr a1 | ||
60 | nop | ||
61 | |||
62 | END(it8172_IRQ) | ||
63 | |||
diff --git a/arch/mips/ite-boards/generic/irq.c b/arch/mips/ite-boards/generic/irq.c index e67f96129491..77be7216bdd0 100644 --- a/arch/mips/ite-boards/generic/irq.c +++ b/arch/mips/ite-boards/generic/irq.c | |||
@@ -62,12 +62,8 @@ | |||
62 | 62 | ||
63 | #define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) | 63 | #define ALLINTS_NOTIMER (IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4) |
64 | 64 | ||
65 | void disable_it8172_irq(unsigned int irq_nr); | ||
66 | void enable_it8172_irq(unsigned int irq_nr); | ||
67 | |||
68 | extern void set_debug_traps(void); | 65 | extern void set_debug_traps(void); |
69 | extern void mips_timer_interrupt(int irq, struct pt_regs *regs); | 66 | extern void mips_timer_interrupt(int irq, struct pt_regs *regs); |
70 | extern asmlinkage void it8172_IRQ(void); | ||
71 | 67 | ||
72 | struct it8172_intc_regs volatile *it8172_hw0_icregs = | 68 | struct it8172_intc_regs volatile *it8172_hw0_icregs = |
73 | (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE)); | 69 | (struct it8172_intc_regs volatile *)(KSEG1ADDR(IT8172_PCI_IO_BASE + IT_INTC_BASE)); |
@@ -181,8 +177,6 @@ void __init arch_init_irq(void) | |||
181 | int i; | 177 | int i; |
182 | unsigned long flags; | 178 | unsigned long flags; |
183 | 179 | ||
184 | set_except_vector(0, it8172_IRQ); | ||
185 | |||
186 | /* mask all interrupts */ | 180 | /* mask all interrupts */ |
187 | it8172_hw0_icregs->lb_mask = 0xffff; | 181 | it8172_hw0_icregs->lb_mask = 0xffff; |
188 | it8172_hw0_icregs->lpc_mask = 0xffff; | 182 | it8172_hw0_icregs->lpc_mask = 0xffff; |
@@ -282,6 +276,18 @@ void it8172_hw0_irqdispatch(struct pt_regs *regs) | |||
282 | do_IRQ(irq, regs); | 276 | do_IRQ(irq, regs); |
283 | } | 277 | } |
284 | 278 | ||
279 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
280 | { | ||
281 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
282 | |||
283 | if (!pending) | ||
284 | mips_spurious_interrupt(regs); | ||
285 | else if (pending & CAUSEF_IP7) | ||
286 | ll_timer_interrupt(127, regs); | ||
287 | else if (pending & CAUSEF_IP2) | ||
288 | it8172_hw0_irqdispatch(regs); | ||
289 | } | ||
290 | |||
285 | void show_pending_irqs(void) | 291 | void show_pending_irqs(void) |
286 | { | 292 | { |
287 | fputs("intstatus: "); | 293 | fputs("intstatus: "); |
diff --git a/arch/mips/ite-boards/generic/time.c b/arch/mips/ite-boards/generic/time.c index b79817bb6cce..dee497a91807 100644 --- a/arch/mips/ite-boards/generic/time.c +++ b/arch/mips/ite-boards/generic/time.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include <linux/sched.h> | 29 | #include <linux/sched.h> |
30 | #include <linux/time.h> | 30 | #include <linux/time.h> |
31 | #include <linux/spinlock.h> | 31 | #include <linux/spinlock.h> |
32 | #include <linux/mc146818rtc.h> | ||
32 | 33 | ||
33 | #include <asm/time.h> | 34 | #include <asm/time.h> |
34 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
diff --git a/arch/mips/ite-boards/ivr/init.c b/arch/mips/ite-boards/ivr/init.c index b774db035b31..05cf9218c432 100644 --- a/arch/mips/ite-boards/ivr/init.c +++ b/arch/mips/ite-boards/ivr/init.c | |||
@@ -34,13 +34,13 @@ | |||
34 | #include <asm/bootinfo.h> | 34 | #include <asm/bootinfo.h> |
35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <asm/sections.h> | ||
37 | #include <asm/it8172/it8172.h> | 38 | #include <asm/it8172/it8172.h> |
38 | #include <asm/it8172/it8172_dbg.h> | 39 | #include <asm/it8172/it8172_dbg.h> |
39 | 40 | ||
40 | int prom_argc; | 41 | int prom_argc; |
41 | char **prom_argv, **prom_envp; | 42 | char **prom_argv, **prom_envp; |
42 | 43 | ||
43 | extern char _end; | ||
44 | extern void __init prom_init_cmdline(void); | 44 | extern void __init prom_init_cmdline(void); |
45 | extern unsigned long __init prom_get_memsize(void); | 45 | extern unsigned long __init prom_get_memsize(void); |
46 | extern void __init it8172_init_ram_resource(unsigned long memsize); | 46 | extern void __init it8172_init_ram_resource(unsigned long memsize); |
diff --git a/arch/mips/ite-boards/qed-4n-s01b/init.c b/arch/mips/ite-boards/qed-4n-s01b/init.c index e8ec8be66a80..ea2a754cafe5 100644 --- a/arch/mips/ite-boards/qed-4n-s01b/init.c +++ b/arch/mips/ite-boards/qed-4n-s01b/init.c | |||
@@ -34,13 +34,13 @@ | |||
34 | #include <asm/bootinfo.h> | 34 | #include <asm/bootinfo.h> |
35 | #include <linux/string.h> | 35 | #include <linux/string.h> |
36 | #include <linux/kernel.h> | 36 | #include <linux/kernel.h> |
37 | #include <asm/sections.h> | ||
37 | #include <asm/it8172/it8172.h> | 38 | #include <asm/it8172/it8172.h> |
38 | #include <asm/it8172/it8172_dbg.h> | 39 | #include <asm/it8172/it8172_dbg.h> |
39 | 40 | ||
40 | int prom_argc; | 41 | int prom_argc; |
41 | char **prom_argv, **prom_envp; | 42 | char **prom_argv, **prom_envp; |
42 | 43 | ||
43 | extern char _end; | ||
44 | extern void __init prom_init_cmdline(void); | 44 | extern void __init prom_init_cmdline(void); |
45 | extern unsigned long __init prom_get_memsize(void); | 45 | extern unsigned long __init prom_get_memsize(void); |
46 | extern void __init it8172_init_ram_resource(unsigned long memsize); | 46 | extern void __init it8172_init_ram_resource(unsigned long memsize); |
diff --git a/arch/mips/jazz/Makefile b/arch/mips/jazz/Makefile index 85749246a671..02bd39add891 100644 --- a/arch/mips/jazz/Makefile +++ b/arch/mips/jazz/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for the Jazz family specific parts of the kernel | 2 | # Makefile for the Jazz family specific parts of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := int-handler.o irq.o jazzdma.o reset.o setup.o | 5 | obj-y := irq.o jazzdma.o reset.o setup.o |
6 | 6 | ||
7 | EXTRA_AFLAGS := $(CFLAGS) | 7 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/jazz/int-handler.S b/arch/mips/jazz/int-handler.S deleted file mode 100644 index dc752c67b528..000000000000 --- a/arch/mips/jazz/int-handler.S +++ /dev/null | |||
@@ -1,282 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1995, 1996, 1997, 1998 by Ralf Baechle and Andreas Busse | ||
7 | * | ||
8 | * Jazz family specific interrupt stuff | ||
9 | * | ||
10 | * To do: On Jazz machines we remap some non-ISA interrupts to ISA | ||
11 | * interrupts. These interrupts should use their own vectors. | ||
12 | * Squeeze the last cycles out of the handlers. Only a dead | ||
13 | * cycle is a good cycle. | ||
14 | */ | ||
15 | #include <asm/asm.h> | ||
16 | #include <asm/mipsregs.h> | ||
17 | #include <asm/jazz.h> | ||
18 | #include <asm/regdef.h> | ||
19 | #include <asm/stackframe.h> | ||
20 | |||
21 | /* | ||
22 | * jazz_handle_int: Interrupt handler for the ACER Pica-61 boards | ||
23 | */ | ||
24 | .set noreorder | ||
25 | |||
26 | NESTED(jazz_handle_int, PT_SIZE, ra) | ||
27 | .set noat | ||
28 | SAVE_ALL | ||
29 | CLI | ||
30 | .set at | ||
31 | |||
32 | /* | ||
33 | * Get pending interrupts | ||
34 | */ | ||
35 | mfc0 t0,CP0_CAUSE # get pending interrupts | ||
36 | mfc0 t1,CP0_STATUS # get enabled interrupts | ||
37 | and t0,t1 # isolate allowed ones | ||
38 | andi t0,0xff00 # isolate pending bits | ||
39 | beqz t0,3f | ||
40 | sll t0,16 # delay slot | ||
41 | |||
42 | /* | ||
43 | * Find irq with highest priority | ||
44 | * FIXME: This is slow - use binary search | ||
45 | */ | ||
46 | la t1,ll_vectors | ||
47 | 1: bltz t0,2f # found pending irq | ||
48 | sll t0,1 | ||
49 | b 1b | ||
50 | subu t1,PTRSIZE # delay slot | ||
51 | |||
52 | /* | ||
53 | * Do the low-level stuff | ||
54 | */ | ||
55 | 2: lw t0,(t1) | ||
56 | jr t0 | ||
57 | nop # delay slot | ||
58 | END(jazz_handle_int) | ||
59 | |||
60 | ll_sw0: li s1,~IE_SW0 | ||
61 | mfc0 t0,CP0_CAUSE | ||
62 | and t0,s1 | ||
63 | mtc0 t0,CP0_CAUSE | ||
64 | PANIC("Unimplemented sw0 handler") | ||
65 | |||
66 | ll_sw1: li s1,~IE_SW1 | ||
67 | mfc0 t0,CP0_CAUSE | ||
68 | and t0,s1 | ||
69 | mtc0 t0,CP0_CAUSE | ||
70 | PANIC("Unimplemented sw1 handler") | ||
71 | |||
72 | ll_local_dma: li s1,~IE_IRQ0 | ||
73 | PANIC("Unimplemented local_dma handler") | ||
74 | |||
75 | ll_local_dev: lbu t0,JAZZ_IO_IRQ_SOURCE | ||
76 | #if PTRSIZE == 8 /* True 64 bit kernel */ | ||
77 | dsll t0,1 | ||
78 | #endif | ||
79 | .set reorder | ||
80 | LONG_L t0,local_vector(t0) | ||
81 | jr t0 | ||
82 | .set noreorder | ||
83 | |||
84 | /* | ||
85 | * The braindead PICA hardware gives us no way to distinguish if we really | ||
86 | * received interrupt 7 from the (E)ISA bus or if we just received an | ||
87 | * interrupt with no findable cause. This sometimes happens with braindead | ||
88 | * cards. Oh well - for all the Jazz boxes slots are more or less just | ||
89 | * whistles and bells and we're aware of the problem. | ||
90 | */ | ||
91 | ll_isa_irq: lw a0, JAZZ_EISA_IRQ_ACK | ||
92 | |||
93 | jal do_IRQ | ||
94 | move a1,sp | ||
95 | |||
96 | j ret_from_irq | ||
97 | nop | ||
98 | |||
99 | /* | ||
100 | * Hmm... This is not just a plain PC clone so the question is | ||
101 | * which devices on Jazz machines can generate an (E)ISA NMI? | ||
102 | * (Writing to nonexistent memory?) | ||
103 | */ | ||
104 | ll_isa_nmi: li s1,~IE_IRQ3 | ||
105 | PANIC("Unimplemented isa_nmi handler") | ||
106 | |||
107 | /* | ||
108 | * Timer IRQ - remapped to be more similar to an IBM compatible. | ||
109 | * | ||
110 | * The timer interrupt is handled specially to ensure that the jiffies | ||
111 | * variable is updated at all times. Specifically, the timer interrupt is | ||
112 | * just like the complete handlers except that it is invoked with interrupts | ||
113 | * disabled and should never re-enable them. If other interrupts were | ||
114 | * allowed to be processed while the timer interrupt is active, then the | ||
115 | * other interrupts would have to avoid using the jiffies variable for delay | ||
116 | * and interval timing operations to avoid hanging the system. | ||
117 | */ | ||
118 | ll_timer: lw zero,JAZZ_TIMER_REGISTER # timer irq cleared on read | ||
119 | li s1,~IE_IRQ4 | ||
120 | |||
121 | li a0, JAZZ_TIMER_IRQ | ||
122 | jal do_IRQ | ||
123 | move a1,sp | ||
124 | |||
125 | mfc0 t0,CP0_STATUS # disable interrupts again | ||
126 | ori t0,1 | ||
127 | xori t0,1 | ||
128 | mtc0 t0,CP0_STATUS | ||
129 | |||
130 | j ret_from_irq | ||
131 | nop | ||
132 | |||
133 | /* | ||
134 | * CPU count/compare IRQ (unused) | ||
135 | */ | ||
136 | ll_count: j ret_from_irq | ||
137 | mtc0 zero,CP0_COMPARE | ||
138 | |||
139 | #if 0 | ||
140 | /* | ||
141 | * Call the handler for the interrupt | ||
142 | * (Currently unused) | ||
143 | */ | ||
144 | call_real: /* | ||
145 | * temporarily disable interrupt | ||
146 | */ | ||
147 | mfc0 t2,CP0_STATUS | ||
148 | and t2,s1 | ||
149 | mtc0 t2,CP0_STATUS | ||
150 | nor s1,zero,s1 | ||
151 | jal do_IRQ | ||
152 | |||
153 | /* | ||
154 | * reenable interrupt | ||
155 | */ | ||
156 | mfc0 t2,CP0_STATUS | ||
157 | or t2,s1 | ||
158 | mtc0 t2,CP0_STATUS | ||
159 | j ret_from_irq | ||
160 | #endif | ||
161 | |||
162 | .data | ||
163 | PTR ll_sw0 # SW0 | ||
164 | PTR ll_sw1 # SW1 | ||
165 | PTR ll_local_dma # Local DMA | ||
166 | PTR ll_local_dev # Local devices | ||
167 | PTR ll_isa_irq # ISA IRQ | ||
168 | PTR ll_isa_nmi # ISA NMI | ||
169 | PTR ll_timer # Timer | ||
170 | ll_vectors: PTR ll_count # Count/Compare IRQ | ||
171 | |||
172 | /* | ||
173 | * Interrupt handlers for local devices. | ||
174 | */ | ||
175 | .text | ||
176 | .set reorder | ||
177 | loc_no_irq: PANIC("Unimplemented loc_no_irq handler") | ||
178 | /* | ||
179 | * Parallel port IRQ | ||
180 | */ | ||
181 | loc_parallel: li s1,~JAZZ_IE_PARALLEL | ||
182 | li a0,JAZZ_PARALLEL_IRQ | ||
183 | b loc_call | ||
184 | |||
185 | /* | ||
186 | * Floppy IRQ | ||
187 | */ | ||
188 | loc_floppy: li s1,~JAZZ_IE_FLOPPY | ||
189 | li a0,JAZZ_FLOPPY_IRQ | ||
190 | b loc_call | ||
191 | |||
192 | /* | ||
193 | * Sound IRQ | ||
194 | */ | ||
195 | loc_sound: PANIC("Unimplemented loc_sound handler") | ||
196 | loc_video: PANIC("Unimplemented loc_video handler") | ||
197 | |||
198 | /* | ||
199 | * Ethernet interrupt handler | ||
200 | */ | ||
201 | loc_ethernet: li s1,~JAZZ_IE_ETHERNET | ||
202 | li a0,JAZZ_ETHERNET_IRQ | ||
203 | b loc_call | ||
204 | |||
205 | /* | ||
206 | * SCSI interrupt handler | ||
207 | */ | ||
208 | loc_scsi: li s1,~JAZZ_IE_SCSI | ||
209 | li a0,JAZZ_SCSI_IRQ | ||
210 | b loc_call | ||
211 | |||
212 | /* | ||
213 | * Keyboard interrupt handler | ||
214 | */ | ||
215 | loc_keyboard: li s1,~JAZZ_IE_KEYBOARD | ||
216 | li a0,JAZZ_KEYBOARD_IRQ | ||
217 | b loc_call | ||
218 | |||
219 | /* | ||
220 | * Mouse interrupt handler | ||
221 | */ | ||
222 | loc_mouse: li s1,~JAZZ_IE_MOUSE | ||
223 | li a0,JAZZ_MOUSE_IRQ | ||
224 | b loc_call | ||
225 | |||
226 | /* | ||
227 | * Serial port 1 IRQ | ||
228 | */ | ||
229 | loc_serial1: li s1,~JAZZ_IE_SERIAL1 | ||
230 | li a0,JAZZ_SERIAL1_IRQ | ||
231 | b loc_call | ||
232 | |||
233 | /* | ||
234 | * Serial port 2 IRQ | ||
235 | */ | ||
236 | loc_serial2: li s1,~JAZZ_IE_SERIAL2 | ||
237 | li a0,JAZZ_SERIAL2_IRQ | ||
238 | b loc_call | ||
239 | |||
240 | /* | ||
241 | * Call the interrupt handler for an interrupt generated by a | ||
242 | * local device. | ||
243 | */ | ||
244 | loc_call: /* | ||
245 | * Temporarily disable interrupt source | ||
246 | */ | ||
247 | lhu t2,JAZZ_IO_IRQ_ENABLE | ||
248 | and t2,s1 | ||
249 | sh t2,JAZZ_IO_IRQ_ENABLE | ||
250 | |||
251 | nor s1,zero,s1 | ||
252 | jal do_IRQ | ||
253 | |||
254 | /* | ||
255 | * Reenable interrupt | ||
256 | */ | ||
257 | lhu t2,JAZZ_IO_IRQ_ENABLE | ||
258 | or t2,s1 | ||
259 | sh t2,JAZZ_IO_IRQ_ENABLE | ||
260 | |||
261 | j ret_from_irq | ||
262 | |||
263 | /* | ||
264 | * "Jump extender" to reach spurious_interrupt | ||
265 | */ | ||
266 | 3: j spurious_interrupt | ||
267 | |||
268 | /* | ||
269 | * Vectors for interrupts generated by local devices | ||
270 | */ | ||
271 | .data | ||
272 | local_vector: PTR loc_no_irq | ||
273 | PTR loc_parallel | ||
274 | PTR loc_floppy | ||
275 | PTR loc_sound | ||
276 | PTR loc_video | ||
277 | PTR loc_ethernet | ||
278 | PTR loc_scsi | ||
279 | PTR loc_keyboard | ||
280 | PTR loc_mouse | ||
281 | PTR loc_serial1 | ||
282 | PTR loc_serial2 | ||
diff --git a/arch/mips/jazz/irq.c b/arch/mips/jazz/irq.c index b309b1bcf2e8..becc9accd495 100644 --- a/arch/mips/jazz/irq.c +++ b/arch/mips/jazz/irq.c | |||
@@ -15,8 +15,6 @@ | |||
15 | #include <asm/io.h> | 15 | #include <asm/io.h> |
16 | #include <asm/jazz.h> | 16 | #include <asm/jazz.h> |
17 | 17 | ||
18 | extern asmlinkage void jazz_handle_int(void); | ||
19 | |||
20 | static DEFINE_SPINLOCK(r4030_lock); | 18 | static DEFINE_SPINLOCK(r4030_lock); |
21 | 19 | ||
22 | static void enable_r4030_irq(unsigned int irq) | 20 | static void enable_r4030_irq(unsigned int irq) |
@@ -90,10 +88,82 @@ void __init init_r4030_ints(void) | |||
90 | */ | 88 | */ |
91 | void __init arch_init_irq(void) | 89 | void __init arch_init_irq(void) |
92 | { | 90 | { |
93 | set_except_vector(0, jazz_handle_int); | ||
94 | |||
95 | init_i8259_irqs(); /* Integrated i8259 */ | 91 | init_i8259_irqs(); /* Integrated i8259 */ |
96 | init_r4030_ints(); | 92 | init_r4030_ints(); |
97 | 93 | ||
98 | change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); | 94 | change_c0_status(ST0_IM, IE_IRQ4 | IE_IRQ3 | IE_IRQ2 | IE_IRQ1); |
99 | } | 95 | } |
96 | |||
97 | static void loc_call(unsigned int irq, struct pt_regs *regs, unsigned int mask) | ||
98 | { | ||
99 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, | ||
100 | r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) & mask); | ||
101 | do_IRQ(irq, regs); | ||
102 | r4030_write_reg16(JAZZ_IO_IRQ_ENABLE, | ||
103 | r4030_read_reg16(JAZZ_IO_IRQ_ENABLE) | mask); | ||
104 | } | ||
105 | |||
106 | static void ll_local_dev(struct pt_regs *regs) | ||
107 | { | ||
108 | switch (r4030_read_reg32(JAZZ_IO_IRQ_SOURCE)) { | ||
109 | case 0: | ||
110 | panic("Unimplemented loc_no_irq handler"); | ||
111 | break; | ||
112 | case 4: | ||
113 | loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_PARALLEL); | ||
114 | break; | ||
115 | case 8: | ||
116 | loc_call(JAZZ_PARALLEL_IRQ, regs, JAZZ_IE_FLOPPY); | ||
117 | break; | ||
118 | case 12: | ||
119 | panic("Unimplemented loc_sound handler"); | ||
120 | break; | ||
121 | case 16: | ||
122 | panic("Unimplemented loc_video handler"); | ||
123 | break; | ||
124 | case 20: | ||
125 | loc_call(JAZZ_ETHERNET_IRQ, regs, JAZZ_IE_ETHERNET); | ||
126 | break; | ||
127 | case 24: | ||
128 | loc_call(JAZZ_SCSI_IRQ, regs, JAZZ_IE_SCSI); | ||
129 | break; | ||
130 | case 28: | ||
131 | loc_call(JAZZ_KEYBOARD_IRQ, regs, JAZZ_IE_KEYBOARD); | ||
132 | break; | ||
133 | case 32: | ||
134 | loc_call(JAZZ_MOUSE_IRQ, regs, JAZZ_IE_MOUSE); | ||
135 | break; | ||
136 | case 36: | ||
137 | loc_call(JAZZ_SERIAL1_IRQ, regs, JAZZ_IE_SERIAL1); | ||
138 | break; | ||
139 | case 40: | ||
140 | loc_call(JAZZ_SERIAL2_IRQ, regs, JAZZ_IE_SERIAL2); | ||
141 | break; | ||
142 | } | ||
143 | } | ||
144 | |||
145 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
146 | { | ||
147 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
148 | |||
149 | if (pending & IE_IRQ5) | ||
150 | write_c0_compare(0); | ||
151 | else if (pending & IE_IRQ4) { | ||
152 | r4030_read_reg32(JAZZ_TIMER_REGISTER); | ||
153 | do_IRQ(JAZZ_TIMER_IRQ, regs); | ||
154 | } else if (pending & IE_IRQ3) | ||
155 | panic("Unimplemented ISA NMI handler"); | ||
156 | else if (pending & IE_IRQ2) | ||
157 | do_IRQ(r4030_read_reg32(JAZZ_EISA_IRQ_ACK), regs); | ||
158 | else if (pending & IE_IRQ1) { | ||
159 | ll_local_dev(regs); | ||
160 | } else if (unlikely(pending & IE_IRQ0)) | ||
161 | panic("Unimplemented local_dma handler"); | ||
162 | else if (pending & IE_SW1) { | ||
163 | clear_c0_cause(IE_SW1); | ||
164 | panic("Unimplemented sw1 handler"); | ||
165 | } else if (pending & IE_SW0) { | ||
166 | clear_c0_cause(IE_SW0); | ||
167 | panic("Unimplemented sw0 handler"); | ||
168 | } | ||
169 | } | ||
diff --git a/arch/mips/jmr3927/common/rtc_ds1742.c b/arch/mips/jmr3927/common/rtc_ds1742.c index a6bd3f4d3049..e6561345d12a 100644 --- a/arch/mips/jmr3927/common/rtc_ds1742.c +++ b/arch/mips/jmr3927/common/rtc_ds1742.c | |||
@@ -60,15 +60,15 @@ rtc_ds1742_get_time(void) | |||
60 | unsigned long flags; | 60 | unsigned long flags; |
61 | 61 | ||
62 | spin_lock_irqsave(&rtc_lock, flags); | 62 | spin_lock_irqsave(&rtc_lock, flags); |
63 | CMOS_WRITE(RTC_READ, RTC_CONTROL); | 63 | rtc_write(RTC_READ, RTC_CONTROL); |
64 | second = BCD2BIN(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); | 64 | second = BCD2BIN(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK); |
65 | minute = BCD2BIN(CMOS_READ(RTC_MINUTES)); | 65 | minute = BCD2BIN(rtc_read(RTC_MINUTES)); |
66 | hour = BCD2BIN(CMOS_READ(RTC_HOURS)); | 66 | hour = BCD2BIN(rtc_read(RTC_HOURS)); |
67 | day = BCD2BIN(CMOS_READ(RTC_DATE)); | 67 | day = BCD2BIN(rtc_read(RTC_DATE)); |
68 | month = BCD2BIN(CMOS_READ(RTC_MONTH)); | 68 | month = BCD2BIN(rtc_read(RTC_MONTH)); |
69 | year = BCD2BIN(CMOS_READ(RTC_YEAR)); | 69 | year = BCD2BIN(rtc_read(RTC_YEAR)); |
70 | century = BCD2BIN(CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK); | 70 | century = BCD2BIN(rtc_read(RTC_CENTURY) & RTC_CENTURY_MASK); |
71 | CMOS_WRITE(0, RTC_CONTROL); | 71 | rtc_write(0, RTC_CONTROL); |
72 | spin_unlock_irqrestore(&rtc_lock, flags); | 72 | spin_unlock_irqrestore(&rtc_lock, flags); |
73 | 73 | ||
74 | year += century * 100; | 74 | year += century * 100; |
@@ -87,16 +87,16 @@ rtc_ds1742_set_time(unsigned long t) | |||
87 | unsigned long flags; | 87 | unsigned long flags; |
88 | 88 | ||
89 | spin_lock_irqsave(&rtc_lock, flags); | 89 | spin_lock_irqsave(&rtc_lock, flags); |
90 | CMOS_WRITE(RTC_READ, RTC_CONTROL); | 90 | rtc_write(RTC_READ, RTC_CONTROL); |
91 | cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); | 91 | cmos_second = (u8)(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK); |
92 | cmos_minute = (u8)CMOS_READ(RTC_MINUTES); | 92 | cmos_minute = (u8)rtc_read(RTC_MINUTES); |
93 | cmos_hour = (u8)CMOS_READ(RTC_HOURS); | 93 | cmos_hour = (u8)rtc_read(RTC_HOURS); |
94 | cmos_day = (u8)CMOS_READ(RTC_DATE); | 94 | cmos_day = (u8)rtc_read(RTC_DATE); |
95 | cmos_month = (u8)CMOS_READ(RTC_MONTH); | 95 | cmos_month = (u8)rtc_read(RTC_MONTH); |
96 | cmos_year = (u8)CMOS_READ(RTC_YEAR); | 96 | cmos_year = (u8)rtc_read(RTC_YEAR); |
97 | cmos_century = CMOS_READ(RTC_CENTURY) & RTC_CENTURY_MASK; | 97 | cmos_century = rtc_read(RTC_CENTURY) & RTC_CENTURY_MASK; |
98 | 98 | ||
99 | CMOS_WRITE(RTC_WRITE, RTC_CONTROL); | 99 | rtc_write(RTC_WRITE, RTC_CONTROL); |
100 | 100 | ||
101 | /* convert */ | 101 | /* convert */ |
102 | to_tm(t, &tm); | 102 | to_tm(t, &tm); |
@@ -104,18 +104,18 @@ rtc_ds1742_set_time(unsigned long t) | |||
104 | /* check each field one by one */ | 104 | /* check each field one by one */ |
105 | year = BIN2BCD(tm.tm_year - EPOCH); | 105 | year = BIN2BCD(tm.tm_year - EPOCH); |
106 | if (year != cmos_year) { | 106 | if (year != cmos_year) { |
107 | CMOS_WRITE(year,RTC_YEAR); | 107 | rtc_write(year,RTC_YEAR); |
108 | } | 108 | } |
109 | 109 | ||
110 | month = BIN2BCD(tm.tm_mon); | 110 | month = BIN2BCD(tm.tm_mon); |
111 | if (month != (cmos_month & 0x1f)) { | 111 | if (month != (cmos_month & 0x1f)) { |
112 | CMOS_WRITE((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); | 112 | rtc_write((month & 0x1f) | (cmos_month & ~0x1f),RTC_MONTH); |
113 | } | 113 | } |
114 | 114 | ||
115 | day = BIN2BCD(tm.tm_mday); | 115 | day = BIN2BCD(tm.tm_mday); |
116 | if (day != cmos_day) { | 116 | if (day != cmos_day) { |
117 | 117 | ||
118 | CMOS_WRITE(day, RTC_DATE); | 118 | rtc_write(day, RTC_DATE); |
119 | } | 119 | } |
120 | 120 | ||
121 | if (cmos_hour & 0x40) { | 121 | if (cmos_hour & 0x40) { |
@@ -130,20 +130,20 @@ rtc_ds1742_set_time(unsigned long t) | |||
130 | /* 24 hour format */ | 130 | /* 24 hour format */ |
131 | hour = BIN2BCD(tm.tm_hour) & 0x3f; | 131 | hour = BIN2BCD(tm.tm_hour) & 0x3f; |
132 | } | 132 | } |
133 | if (hour != cmos_hour) CMOS_WRITE(hour, RTC_HOURS); | 133 | if (hour != cmos_hour) rtc_write(hour, RTC_HOURS); |
134 | 134 | ||
135 | minute = BIN2BCD(tm.tm_min); | 135 | minute = BIN2BCD(tm.tm_min); |
136 | if (minute != cmos_minute) { | 136 | if (minute != cmos_minute) { |
137 | CMOS_WRITE(minute, RTC_MINUTES); | 137 | rtc_write(minute, RTC_MINUTES); |
138 | } | 138 | } |
139 | 139 | ||
140 | second = BIN2BCD(tm.tm_sec); | 140 | second = BIN2BCD(tm.tm_sec); |
141 | if (second != cmos_second) { | 141 | if (second != cmos_second) { |
142 | CMOS_WRITE(second & RTC_SECONDS_MASK,RTC_SECONDS); | 142 | rtc_write(second & RTC_SECONDS_MASK,RTC_SECONDS); |
143 | } | 143 | } |
144 | 144 | ||
145 | /* RTC_CENTURY and RTC_CONTROL share same address... */ | 145 | /* RTC_CENTURY and RTC_CONTROL share same address... */ |
146 | CMOS_WRITE(cmos_century, RTC_CONTROL); | 146 | rtc_write(cmos_century, RTC_CONTROL); |
147 | spin_unlock_irqrestore(&rtc_lock, flags); | 147 | spin_unlock_irqrestore(&rtc_lock, flags); |
148 | 148 | ||
149 | return 0; | 149 | return 0; |
@@ -163,9 +163,9 @@ rtc_ds1742_init(unsigned long base) | |||
163 | rtc_mips_set_time = rtc_ds1742_set_time; | 163 | rtc_mips_set_time = rtc_ds1742_set_time; |
164 | 164 | ||
165 | /* clear oscillator stop bit */ | 165 | /* clear oscillator stop bit */ |
166 | CMOS_WRITE(RTC_READ, RTC_CONTROL); | 166 | rtc_write(RTC_READ, RTC_CONTROL); |
167 | cmos_second = (u8)(CMOS_READ(RTC_SECONDS) & RTC_SECONDS_MASK); | 167 | cmos_second = (u8)(rtc_read(RTC_SECONDS) & RTC_SECONDS_MASK); |
168 | CMOS_WRITE(RTC_WRITE, RTC_CONTROL); | 168 | rtc_write(RTC_WRITE, RTC_CONTROL); |
169 | CMOS_WRITE(cmos_second, RTC_SECONDS); /* clear msb */ | 169 | rtc_write(cmos_second, RTC_SECONDS); /* clear msb */ |
170 | CMOS_WRITE(0, RTC_CONTROL); | 170 | rtc_write(0, RTC_CONTROL); |
171 | } | 171 | } |
diff --git a/arch/mips/jmr3927/rbhma3100/Makefile b/arch/mips/jmr3927/rbhma3100/Makefile index 75bf418b94c0..baf5077813c1 100644 --- a/arch/mips/jmr3927/rbhma3100/Makefile +++ b/arch/mips/jmr3927/rbhma3100/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for TOSHIBA JMR-TX3927 board | 2 | # Makefile for TOSHIBA JMR-TX3927 board |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += init.o int-handler.o irq.o setup.o | 5 | obj-y += init.o irq.o setup.o |
6 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o | 6 | obj-$(CONFIG_RUNTIME_DEBUG) += debug.o |
7 | obj-$(CONFIG_KGDB) += kgdb_io.o | 7 | obj-$(CONFIG_KGDB) += kgdb_io.o |
8 | 8 | ||
diff --git a/arch/mips/jmr3927/rbhma3100/int-handler.S b/arch/mips/jmr3927/rbhma3100/int-handler.S deleted file mode 100644 index f85bbf407542..000000000000 --- a/arch/mips/jmr3927/rbhma3100/int-handler.S +++ /dev/null | |||
@@ -1,74 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: MontaVista Software, Inc. | ||
4 | * ahennessy@mvista.com | ||
5 | * | ||
6 | * Based on arch/mips/tsdb/kernel/int-handler.S | ||
7 | * | ||
8 | * Copyright (C) 2000-2001 Toshiba Corporation | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
16 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
17 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
18 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
21 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
22 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
25 | * | ||
26 | * You should have received a copy of the GNU General Public License along | ||
27 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
28 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
29 | */ | ||
30 | |||
31 | #include <asm/asm.h> | ||
32 | #include <asm/mipsregs.h> | ||
33 | #include <asm/regdef.h> | ||
34 | #include <asm/stackframe.h> | ||
35 | #include <asm/jmr3927/jmr3927.h> | ||
36 | |||
37 | /* A lot of complication here is taken away because: | ||
38 | * | ||
39 | * 1) We handle one interrupt and return, sitting in a loop | ||
40 | * and moving across all the pending IRQ bits in the cause | ||
41 | * register is _NOT_ the answer, the common case is one | ||
42 | * pending IRQ so optimize in that direction. | ||
43 | * | ||
44 | * 2) We need not check against bits in the status register | ||
45 | * IRQ mask, that would make this routine slow as hell. | ||
46 | * | ||
47 | * 3) Linux only thinks in terms of all IRQs on or all IRQs | ||
48 | * off, nothing in between like BSD spl() brain-damage. | ||
49 | * | ||
50 | */ | ||
51 | |||
52 | /* Flush write buffer (needed?) | ||
53 | * NOTE: TX39xx performs "non-blocking load", so explicitly use the target | ||
54 | * register of LBU to flush immediately. | ||
55 | */ | ||
56 | #define FLUSH_WB(tmp) \ | ||
57 | la tmp, JMR3927_IOC_REV_ADDR; \ | ||
58 | lbu tmp, (tmp); \ | ||
59 | move tmp, zero; | ||
60 | |||
61 | .text | ||
62 | .set noreorder | ||
63 | .set noat | ||
64 | .align 5 | ||
65 | NESTED(jmr3927_IRQ, PT_SIZE, sp) | ||
66 | SAVE_ALL | ||
67 | CLI | ||
68 | .set at | ||
69 | jal jmr3927_irc_irqdispatch | ||
70 | move a0, sp | ||
71 | FLUSH_WB(t0) | ||
72 | j ret_from_irq | ||
73 | nop | ||
74 | END(jmr3927_IRQ) | ||
diff --git a/arch/mips/jmr3927/rbhma3100/irq.c b/arch/mips/jmr3927/rbhma3100/irq.c index 2810727f1d4e..11304d1354f4 100644 --- a/arch/mips/jmr3927/rbhma3100/irq.c +++ b/arch/mips/jmr3927/rbhma3100/irq.c | |||
@@ -77,8 +77,6 @@ static int jmr3927_gen_iack(void) | |||
77 | } | 77 | } |
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | extern asmlinkage void jmr3927_IRQ(void); | ||
81 | |||
82 | #define irc_dlevel 0 | 80 | #define irc_dlevel 0 |
83 | #define irc_elevel 1 | 81 | #define irc_elevel 1 |
84 | 82 | ||
@@ -262,7 +260,7 @@ void jmr3927_spurious(struct pt_regs *regs) | |||
262 | regs->cp0_cause, regs->cp0_epc, regs->regs[31]); | 260 | regs->cp0_cause, regs->cp0_epc, regs->regs[31]); |
263 | } | 261 | } |
264 | 262 | ||
265 | void jmr3927_irc_irqdispatch(struct pt_regs *regs) | 263 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
266 | { | 264 | { |
267 | int irq; | 265 | int irq; |
268 | 266 | ||
@@ -398,8 +396,6 @@ void __init arch_init_irq(void) | |||
398 | 396 | ||
399 | jmr3927_irq_init(NR_ISA_IRQS); | 397 | jmr3927_irq_init(NR_ISA_IRQS); |
400 | 398 | ||
401 | set_except_vector(0, jmr3927_IRQ); | ||
402 | |||
403 | /* setup irq space */ | 399 | /* setup irq space */ |
404 | add_tb_irq_space(&jmr3927_isac_irqspace); | 400 | add_tb_irq_space(&jmr3927_isac_irqspace); |
405 | add_tb_irq_space(&jmr3927_ioc_irqspace); | 401 | add_tb_irq_space(&jmr3927_ioc_irqspace); |
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile index 309d54cceda3..34e8a256765c 100644 --- a/arch/mips/kernel/Makefile +++ b/arch/mips/kernel/Makefile | |||
@@ -34,8 +34,11 @@ obj-$(CONFIG_CPU_R6000) += r6000_fpu.o r4k_switch.o | |||
34 | 34 | ||
35 | obj-$(CONFIG_SMP) += smp.o | 35 | obj-$(CONFIG_SMP) += smp.o |
36 | 36 | ||
37 | obj-$(CONFIG_MIPS_MT_SMP) += smp_mt.o | 37 | obj-$(CONFIG_MIPS_MT) += mips-mt.o |
38 | obj-$(CONFIG_MIPS_MT_SMTC) += smtc.o smtc-asm.o smtc-proc.o | ||
39 | obj-$(CONFIG_MIPS_MT_SMP) += smp-mt.o | ||
38 | 40 | ||
41 | obj-$(CONFIG_MIPS_APSP_KSPD) += kspd.o | ||
39 | obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o | 42 | obj-$(CONFIG_MIPS_VPE_LOADER) += vpe.o |
40 | obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o | 43 | obj-$(CONFIG_MIPS_VPE_APSP_API) += rtlx.o |
41 | 44 | ||
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c index ca6b03c773be..92b28b674d6f 100644 --- a/arch/mips/kernel/asm-offsets.c +++ b/arch/mips/kernel/asm-offsets.c | |||
@@ -69,6 +69,9 @@ void output_ptreg_defines(void) | |||
69 | offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); | 69 | offset("#define PT_BVADDR ", struct pt_regs, cp0_badvaddr); |
70 | offset("#define PT_STATUS ", struct pt_regs, cp0_status); | 70 | offset("#define PT_STATUS ", struct pt_regs, cp0_status); |
71 | offset("#define PT_CAUSE ", struct pt_regs, cp0_cause); | 71 | offset("#define PT_CAUSE ", struct pt_regs, cp0_cause); |
72 | #ifdef CONFIG_MIPS_MT_SMTC | ||
73 | offset("#define PT_TCSTATUS ", struct pt_regs, cp0_tcstatus); | ||
74 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
72 | size("#define PT_SIZE ", struct pt_regs); | 75 | size("#define PT_SIZE ", struct pt_regs); |
73 | linefeed; | 76 | linefeed; |
74 | } | 77 | } |
diff --git a/arch/mips/kernel/entry.S b/arch/mips/kernel/entry.S index 83c87fe4ee4f..d101d2fb24ca 100644 --- a/arch/mips/kernel/entry.S +++ b/arch/mips/kernel/entry.S | |||
@@ -17,6 +17,9 @@ | |||
17 | #include <asm/isadep.h> | 17 | #include <asm/isadep.h> |
18 | #include <asm/thread_info.h> | 18 | #include <asm/thread_info.h> |
19 | #include <asm/war.h> | 19 | #include <asm/war.h> |
20 | #ifdef CONFIG_MIPS_MT_SMTC | ||
21 | #include <asm/mipsmtregs.h> | ||
22 | #endif | ||
20 | 23 | ||
21 | #ifdef CONFIG_PREEMPT | 24 | #ifdef CONFIG_PREEMPT |
22 | .macro preempt_stop | 25 | .macro preempt_stop |
@@ -75,6 +78,37 @@ FEXPORT(syscall_exit) | |||
75 | bnez t0, syscall_exit_work | 78 | bnez t0, syscall_exit_work |
76 | 79 | ||
77 | FEXPORT(restore_all) # restore full frame | 80 | FEXPORT(restore_all) # restore full frame |
81 | #ifdef CONFIG_MIPS_MT_SMTC | ||
82 | /* Detect and execute deferred IPI "interrupts" */ | ||
83 | move a0,sp | ||
84 | jal deferred_smtc_ipi | ||
85 | /* Re-arm any temporarily masked interrupts not explicitly "acked" */ | ||
86 | mfc0 v0, CP0_TCSTATUS | ||
87 | ori v1, v0, TCSTATUS_IXMT | ||
88 | mtc0 v1, CP0_TCSTATUS | ||
89 | andi v0, TCSTATUS_IXMT | ||
90 | ehb | ||
91 | mfc0 t0, CP0_TCCONTEXT | ||
92 | DMT 9 # dmt t1 | ||
93 | jal mips_ihb | ||
94 | mfc0 t2, CP0_STATUS | ||
95 | andi t3, t0, 0xff00 | ||
96 | or t2, t2, t3 | ||
97 | mtc0 t2, CP0_STATUS | ||
98 | ehb | ||
99 | andi t1, t1, VPECONTROL_TE | ||
100 | beqz t1, 1f | ||
101 | EMT | ||
102 | 1: | ||
103 | mfc0 v1, CP0_TCSTATUS | ||
104 | /* We set IXMT above, XOR should cler it here */ | ||
105 | xori v1, v1, TCSTATUS_IXMT | ||
106 | or v1, v0, v1 | ||
107 | mtc0 v1, CP0_TCSTATUS | ||
108 | ehb | ||
109 | xor t0, t0, t3 | ||
110 | mtc0 t0, CP0_TCCONTEXT | ||
111 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
78 | .set noat | 112 | .set noat |
79 | RESTORE_TEMP | 113 | RESTORE_TEMP |
80 | RESTORE_AT | 114 | RESTORE_AT |
@@ -120,28 +154,17 @@ syscall_exit_work: | |||
120 | jal do_syscall_trace | 154 | jal do_syscall_trace |
121 | b resume_userspace | 155 | b resume_userspace |
122 | 156 | ||
157 | #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_MIPS_MT) | ||
158 | |||
123 | /* | 159 | /* |
124 | * Common spurious interrupt handler. | 160 | * MIPS32R2 Instruction Hazard Barrier - must be called |
161 | * | ||
162 | * For C code use the inline version named instruction_hazard(). | ||
125 | */ | 163 | */ |
126 | LEAF(spurious_interrupt) | 164 | LEAF(mips_ihb) |
127 | /* | 165 | .set mips32r2 |
128 | * Someone tried to fool us by sending an interrupt but we | 166 | jr.hb ra |
129 | * couldn't find a cause for it. | 167 | nop |
130 | */ | 168 | END(mips_ihb) |
131 | PTR_LA t1, irq_err_count | 169 | |
132 | #ifdef CONFIG_SMP | 170 | #endif /* CONFIG_CPU_MIPSR2 or CONFIG_MIPS_MT */ |
133 | 1: ll t0, (t1) | ||
134 | addiu t0, 1 | ||
135 | sc t0, (t1) | ||
136 | #if R10000_LLSC_WAR | ||
137 | beqzl t0, 1b | ||
138 | #else | ||
139 | beqz t0, 1b | ||
140 | #endif | ||
141 | #else | ||
142 | lw t0, (t1) | ||
143 | addiu t0, 1 | ||
144 | sw t0, (t1) | ||
145 | #endif | ||
146 | j ret_from_irq | ||
147 | END(spurious_interrupt) | ||
diff --git a/arch/mips/kernel/gdb-low.S b/arch/mips/kernel/gdb-low.S index 235ad9f6bd35..10f28fb9f008 100644 --- a/arch/mips/kernel/gdb-low.S +++ b/arch/mips/kernel/gdb-low.S | |||
@@ -283,11 +283,33 @@ | |||
283 | */ | 283 | */ |
284 | 284 | ||
285 | 3: | 285 | 3: |
286 | #ifdef CONFIG_MIPS_MT_SMTC | ||
287 | /* Read-modify write of Status must be atomic */ | ||
288 | mfc0 t2, CP0_TCSTATUS | ||
289 | ori t1, t2, TCSTATUS_IXMT | ||
290 | mtc0 t1, CP0_TCSTATUS | ||
291 | andi t2, t2, TCSTATUS_IXMT | ||
292 | ehb | ||
293 | DMT 9 # dmt t1 | ||
294 | jal mips_ihb | ||
295 | nop | ||
296 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
286 | mfc0 t0, CP0_STATUS | 297 | mfc0 t0, CP0_STATUS |
287 | ori t0, 0x1f | 298 | ori t0, 0x1f |
288 | xori t0, 0x1f | 299 | xori t0, 0x1f |
289 | mtc0 t0, CP0_STATUS | 300 | mtc0 t0, CP0_STATUS |
290 | 301 | #ifdef CONFIG_MIPS_MT_SMTC | |
302 | andi t1, t1, VPECONTROL_TE | ||
303 | beqz t1, 9f | ||
304 | nop | ||
305 | EMT # emt | ||
306 | 9: | ||
307 | mfc0 t1, CP0_TCSTATUS | ||
308 | xori t1, t1, TCSTATUS_IXMT | ||
309 | or t1, t1, t2 | ||
310 | mtc0 t1, CP0_TCSTATUS | ||
311 | ehb | ||
312 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
291 | LONG_L v0, GDB_FR_STATUS(sp) | 313 | LONG_L v0, GDB_FR_STATUS(sp) |
292 | LONG_L v1, GDB_FR_EPC(sp) | 314 | LONG_L v1, GDB_FR_EPC(sp) |
293 | mtc0 v0, CP0_STATUS | 315 | mtc0 v0, CP0_STATUS |
diff --git a/arch/mips/kernel/gdb-stub.c b/arch/mips/kernel/gdb-stub.c index d4f88e0af24c..6ecbdc1fefd1 100644 --- a/arch/mips/kernel/gdb-stub.c +++ b/arch/mips/kernel/gdb-stub.c | |||
@@ -140,6 +140,7 @@ | |||
140 | #include <asm/system.h> | 140 | #include <asm/system.h> |
141 | #include <asm/gdb-stub.h> | 141 | #include <asm/gdb-stub.h> |
142 | #include <asm/inst.h> | 142 | #include <asm/inst.h> |
143 | #include <asm/smp.h> | ||
143 | 144 | ||
144 | /* | 145 | /* |
145 | * external low-level support routines | 146 | * external low-level support routines |
@@ -669,6 +670,64 @@ static void kgdb_wait(void *arg) | |||
669 | local_irq_restore(flags); | 670 | local_irq_restore(flags); |
670 | } | 671 | } |
671 | 672 | ||
673 | /* | ||
674 | * GDB stub needs to call kgdb_wait on all processor with interrupts | ||
675 | * disabled, so it uses it's own special variant. | ||
676 | */ | ||
677 | static int kgdb_smp_call_kgdb_wait(void) | ||
678 | { | ||
679 | #ifdef CONFIG_SMP | ||
680 | struct call_data_struct data; | ||
681 | int i, cpus = num_online_cpus() - 1; | ||
682 | int cpu = smp_processor_id(); | ||
683 | |||
684 | /* | ||
685 | * Can die spectacularly if this CPU isn't yet marked online | ||
686 | */ | ||
687 | BUG_ON(!cpu_online(cpu)); | ||
688 | |||
689 | if (!cpus) | ||
690 | return 0; | ||
691 | |||
692 | if (spin_is_locked(&smp_call_lock)) { | ||
693 | /* | ||
694 | * Some other processor is trying to make us do something | ||
695 | * but we're not going to respond... give up | ||
696 | */ | ||
697 | return -1; | ||
698 | } | ||
699 | |||
700 | /* | ||
701 | * We will continue here, accepting the fact that | ||
702 | * the kernel may deadlock if another CPU attempts | ||
703 | * to call smp_call_function now... | ||
704 | */ | ||
705 | |||
706 | data.func = kgdb_wait; | ||
707 | data.info = NULL; | ||
708 | atomic_set(&data.started, 0); | ||
709 | data.wait = 0; | ||
710 | |||
711 | spin_lock(&smp_call_lock); | ||
712 | call_data = &data; | ||
713 | mb(); | ||
714 | |||
715 | /* Send a message to all other CPUs and wait for them to respond */ | ||
716 | for (i = 0; i < NR_CPUS; i++) | ||
717 | if (cpu_online(i) && i != cpu) | ||
718 | core_send_ipi(i, SMP_CALL_FUNCTION); | ||
719 | |||
720 | /* Wait for response */ | ||
721 | /* FIXME: lock-up detection, backtrace on lock-up */ | ||
722 | while (atomic_read(&data.started) != cpus) | ||
723 | barrier(); | ||
724 | |||
725 | call_data = NULL; | ||
726 | spin_unlock(&smp_call_lock); | ||
727 | #endif | ||
728 | |||
729 | return 0; | ||
730 | } | ||
672 | 731 | ||
673 | /* | 732 | /* |
674 | * This function does all command processing for interfacing to gdb. It | 733 | * This function does all command processing for interfacing to gdb. It |
@@ -718,7 +777,7 @@ void handle_exception (struct gdb_regs *regs) | |||
718 | /* | 777 | /* |
719 | * force other cpus to enter kgdb | 778 | * force other cpus to enter kgdb |
720 | */ | 779 | */ |
721 | smp_call_function(kgdb_wait, NULL, 0, 0); | 780 | kgdb_smp_call_kgdb_wait(); |
722 | 781 | ||
723 | /* | 782 | /* |
724 | * If we're in breakpoint() increment the PC | 783 | * If we're in breakpoint() increment the PC |
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S index 13f22d1d0e8b..ff7af369f286 100644 --- a/arch/mips/kernel/genex.S +++ b/arch/mips/kernel/genex.S | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | 13 | ||
14 | #include <asm/asm.h> | 14 | #include <asm/asm.h> |
15 | #include <asm/asmmacro.h> | ||
15 | #include <asm/cacheops.h> | 16 | #include <asm/cacheops.h> |
16 | #include <asm/regdef.h> | 17 | #include <asm/regdef.h> |
17 | #include <asm/fpregdef.h> | 18 | #include <asm/fpregdef.h> |
@@ -122,6 +123,20 @@ handle_vcei: | |||
122 | .set pop | 123 | .set pop |
123 | END(except_vec3_r4000) | 124 | END(except_vec3_r4000) |
124 | 125 | ||
126 | __FINIT | ||
127 | |||
128 | .align 5 | ||
129 | NESTED(handle_int, PT_SIZE, sp) | ||
130 | SAVE_ALL | ||
131 | CLI | ||
132 | |||
133 | PTR_LA ra, ret_from_irq | ||
134 | move a0, sp | ||
135 | j plat_irq_dispatch | ||
136 | END(handle_int) | ||
137 | |||
138 | __INIT | ||
139 | |||
125 | /* | 140 | /* |
126 | * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. | 141 | * Special interrupt vector for MIPS64 ISA & embedded MIPS processors. |
127 | * This is a dedicated interrupt exception vector which reduces the | 142 | * This is a dedicated interrupt exception vector which reduces the |
@@ -157,6 +172,15 @@ NESTED(except_vec_vi, 0, sp) | |||
157 | SAVE_AT | 172 | SAVE_AT |
158 | .set push | 173 | .set push |
159 | .set noreorder | 174 | .set noreorder |
175 | #ifdef CONFIG_MIPS_MT_SMTC | ||
176 | /* | ||
177 | * To keep from blindly blocking *all* interrupts | ||
178 | * during service by SMTC kernel, we also want to | ||
179 | * pass the IM value to be cleared. | ||
180 | */ | ||
181 | EXPORT(except_vec_vi_mori) | ||
182 | ori a0, $0, 0 | ||
183 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
160 | EXPORT(except_vec_vi_lui) | 184 | EXPORT(except_vec_vi_lui) |
161 | lui v0, 0 /* Patched */ | 185 | lui v0, 0 /* Patched */ |
162 | j except_vec_vi_handler | 186 | j except_vec_vi_handler |
@@ -173,6 +197,25 @@ EXPORT(except_vec_vi_end) | |||
173 | NESTED(except_vec_vi_handler, 0, sp) | 197 | NESTED(except_vec_vi_handler, 0, sp) |
174 | SAVE_TEMP | 198 | SAVE_TEMP |
175 | SAVE_STATIC | 199 | SAVE_STATIC |
200 | #ifdef CONFIG_MIPS_MT_SMTC | ||
201 | /* | ||
202 | * SMTC has an interesting problem that interrupts are level-triggered, | ||
203 | * and the CLI macro will clear EXL, potentially causing a duplicate | ||
204 | * interrupt service invocation. So we need to clear the associated | ||
205 | * IM bit of Status prior to doing CLI, and restore it after the | ||
206 | * service routine has been invoked - we must assume that the | ||
207 | * service routine will have cleared the state, and any active | ||
208 | * level represents a new or otherwised unserviced event... | ||
209 | */ | ||
210 | mfc0 t1, CP0_STATUS | ||
211 | and t0, a0, t1 | ||
212 | mfc0 t2, CP0_TCCONTEXT | ||
213 | or t0, t0, t2 | ||
214 | mtc0 t0, CP0_TCCONTEXT | ||
215 | xor t1, t1, t0 | ||
216 | mtc0 t1, CP0_STATUS | ||
217 | ehb | ||
218 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
176 | CLI | 219 | CLI |
177 | move a0, sp | 220 | move a0, sp |
178 | jalr v0 | 221 | jalr v0 |
diff --git a/arch/mips/kernel/head.S b/arch/mips/kernel/head.S index 2e9122a4213a..bdf6f6eff721 100644 --- a/arch/mips/kernel/head.S +++ b/arch/mips/kernel/head.S | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/threads.h> | 18 | #include <linux/threads.h> |
19 | 19 | ||
20 | #include <asm/asm.h> | 20 | #include <asm/asm.h> |
21 | #include <asm/asmmacro.h> | ||
21 | #include <asm/regdef.h> | 22 | #include <asm/regdef.h> |
22 | #include <asm/page.h> | 23 | #include <asm/page.h> |
23 | #include <asm/mipsregs.h> | 24 | #include <asm/mipsregs.h> |
@@ -82,12 +83,33 @@ | |||
82 | */ | 83 | */ |
83 | .macro setup_c0_status set clr | 84 | .macro setup_c0_status set clr |
84 | .set push | 85 | .set push |
86 | #ifdef CONFIG_MIPS_MT_SMTC | ||
87 | /* | ||
88 | * For SMTC, we need to set privilege and disable interrupts only for | ||
89 | * the current TC, using the TCStatus register. | ||
90 | */ | ||
91 | mfc0 t0, CP0_TCSTATUS | ||
92 | /* Fortunately CU 0 is in the same place in both registers */ | ||
93 | /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */ | ||
94 | li t1, ST0_CU0 | 0x08001c00 | ||
95 | or t0, t1 | ||
96 | /* Clear TKSU, leave IXMT */ | ||
97 | xori t0, 0x00001800 | ||
98 | mtc0 t0, CP0_TCSTATUS | ||
99 | ehb | ||
100 | /* We need to leave the global IE bit set, but clear EXL...*/ | ||
101 | mfc0 t0, CP0_STATUS | ||
102 | or t0, ST0_CU0 | ST0_EXL | ST0_ERL | \set | \clr | ||
103 | xor t0, ST0_EXL | ST0_ERL | \clr | ||
104 | mtc0 t0, CP0_STATUS | ||
105 | #else | ||
85 | mfc0 t0, CP0_STATUS | 106 | mfc0 t0, CP0_STATUS |
86 | or t0, ST0_CU0|\set|0x1f|\clr | 107 | or t0, ST0_CU0|\set|0x1f|\clr |
87 | xor t0, 0x1f|\clr | 108 | xor t0, 0x1f|\clr |
88 | mtc0 t0, CP0_STATUS | 109 | mtc0 t0, CP0_STATUS |
89 | .set noreorder | 110 | .set noreorder |
90 | sll zero,3 # ehb | 111 | sll zero,3 # ehb |
112 | #endif | ||
91 | .set pop | 113 | .set pop |
92 | .endm | 114 | .endm |
93 | 115 | ||
@@ -134,6 +156,24 @@ NESTED(kernel_entry, 16, sp) # kernel entry point | |||
134 | 156 | ||
135 | ARC64_TWIDDLE_PC | 157 | ARC64_TWIDDLE_PC |
136 | 158 | ||
159 | #ifdef CONFIG_MIPS_MT_SMTC | ||
160 | /* | ||
161 | * In SMTC kernel, "CLI" is thread-specific, in TCStatus. | ||
162 | * We still need to enable interrupts globally in Status, | ||
163 | * and clear EXL/ERL. | ||
164 | * | ||
165 | * TCContext is used to track interrupt levels under | ||
166 | * service in SMTC kernel. Clear for boot TC before | ||
167 | * allowing any interrupts. | ||
168 | */ | ||
169 | mtc0 zero, CP0_TCCONTEXT | ||
170 | |||
171 | mfc0 t0, CP0_STATUS | ||
172 | ori t0, t0, 0xff1f | ||
173 | xori t0, t0, 0x001e | ||
174 | mtc0 t0, CP0_STATUS | ||
175 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
176 | |||
137 | PTR_LA t0, __bss_start # clear .bss | 177 | PTR_LA t0, __bss_start # clear .bss |
138 | LONG_S zero, (t0) | 178 | LONG_S zero, (t0) |
139 | PTR_LA t1, __bss_stop - LONGSIZE | 179 | PTR_LA t1, __bss_stop - LONGSIZE |
@@ -166,8 +206,25 @@ NESTED(kernel_entry, 16, sp) # kernel entry point | |||
166 | * function after setting up the stack and gp registers. | 206 | * function after setting up the stack and gp registers. |
167 | */ | 207 | */ |
168 | NESTED(smp_bootstrap, 16, sp) | 208 | NESTED(smp_bootstrap, 16, sp) |
209 | #ifdef CONFIG_MIPS_MT_SMTC | ||
210 | /* | ||
211 | * Read-modify-writes of Status must be atomic, and this | ||
212 | * is one case where CLI is invoked without EXL being | ||
213 | * necessarily set. The CLI and setup_c0_status will | ||
214 | * in fact be redundant for all but the first TC of | ||
215 | * each VPE being booted. | ||
216 | */ | ||
217 | DMT 10 # dmt t2 /* t0, t1 are used by CLI and setup_c0_status() */ | ||
218 | jal mips_ihb | ||
219 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
169 | setup_c0_status_sec | 220 | setup_c0_status_sec |
170 | smp_slave_setup | 221 | smp_slave_setup |
222 | #ifdef CONFIG_MIPS_MT_SMTC | ||
223 | andi t2, t2, VPECONTROL_TE | ||
224 | beqz t2, 2f | ||
225 | EMT # emt | ||
226 | 2: | ||
227 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
171 | j start_secondary | 228 | j start_secondary |
172 | END(smp_bootstrap) | 229 | END(smp_bootstrap) |
173 | #endif /* CONFIG_SMP */ | 230 | #endif /* CONFIG_SMP */ |
diff --git a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c index b974ac9057f6..2125ba5f1d9b 100644 --- a/arch/mips/kernel/i8259.c +++ b/arch/mips/kernel/i8259.c | |||
@@ -187,6 +187,10 @@ handle_real_irq: | |||
187 | outb(cached_21,0x21); | 187 | outb(cached_21,0x21); |
188 | outb(0x60+irq,0x20); /* 'Specific EOI' to master */ | 188 | outb(0x60+irq,0x20); /* 'Specific EOI' to master */ |
189 | } | 189 | } |
190 | #ifdef CONFIG_MIPS_MT_SMTC | ||
191 | if (irq_hwmask[irq] & ST0_IM) | ||
192 | set_c0_status(irq_hwmask[irq] & ST0_IM); | ||
193 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
190 | spin_unlock_irqrestore(&i8259A_lock, flags); | 194 | spin_unlock_irqrestore(&i8259A_lock, flags); |
191 | return; | 195 | return; |
192 | 196 | ||
diff --git a/arch/mips/kernel/irq-msc01.c b/arch/mips/kernel/irq-msc01.c index 3f653c7cfbf3..97ebdc754b9e 100644 --- a/arch/mips/kernel/irq-msc01.c +++ b/arch/mips/kernel/irq-msc01.c | |||
@@ -76,6 +76,11 @@ static void level_mask_and_ack_msc_irq(unsigned int irq) | |||
76 | mask_msc_irq(irq); | 76 | mask_msc_irq(irq); |
77 | if (!cpu_has_veic) | 77 | if (!cpu_has_veic) |
78 | MSCIC_WRITE(MSC01_IC_EOI, 0); | 78 | MSCIC_WRITE(MSC01_IC_EOI, 0); |
79 | #ifdef CONFIG_MIPS_MT_SMTC | ||
80 | /* This actually needs to be a call into platform code */ | ||
81 | if (irq_hwmask[irq] & ST0_IM) | ||
82 | set_c0_status(irq_hwmask[irq] & ST0_IM); | ||
83 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
79 | } | 84 | } |
80 | 85 | ||
81 | /* | 86 | /* |
@@ -92,6 +97,10 @@ static void edge_mask_and_ack_msc_irq(unsigned int irq) | |||
92 | MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT); | 97 | MSCIC_WRITE(MSC01_IC_SUP+irq*8, r | ~MSC01_IC_SUP_EDGE_BIT); |
93 | MSCIC_WRITE(MSC01_IC_SUP+irq*8, r); | 98 | MSCIC_WRITE(MSC01_IC_SUP+irq*8, r); |
94 | } | 99 | } |
100 | #ifdef CONFIG_MIPS_MT_SMTC | ||
101 | if (irq_hwmask[irq] & ST0_IM) | ||
102 | set_c0_status(irq_hwmask[irq] & ST0_IM); | ||
103 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
95 | } | 104 | } |
96 | 105 | ||
97 | /* | 106 | /* |
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c index 3dd76b3d2967..3dce742e716f 100644 --- a/arch/mips/kernel/irq.c +++ b/arch/mips/kernel/irq.c | |||
@@ -38,6 +38,15 @@ void ack_bad_irq(unsigned int irq) | |||
38 | 38 | ||
39 | atomic_t irq_err_count; | 39 | atomic_t irq_err_count; |
40 | 40 | ||
41 | #ifdef CONFIG_MIPS_MT_SMTC | ||
42 | /* | ||
43 | * SMTC Kernel needs to manipulate low-level CPU interrupt mask | ||
44 | * in do_IRQ. These are passed in setup_irq_smtc() and stored | ||
45 | * in this table. | ||
46 | */ | ||
47 | unsigned long irq_hwmask[NR_IRQS]; | ||
48 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
49 | |||
41 | #undef do_IRQ | 50 | #undef do_IRQ |
42 | 51 | ||
43 | /* | 52 | /* |
@@ -49,6 +58,7 @@ asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs) | |||
49 | { | 58 | { |
50 | irq_enter(); | 59 | irq_enter(); |
51 | 60 | ||
61 | __DO_IRQ_SMTC_HOOK(); | ||
52 | __do_IRQ(irq, regs); | 62 | __do_IRQ(irq, regs); |
53 | 63 | ||
54 | irq_exit(); | 64 | irq_exit(); |
@@ -101,6 +111,11 @@ skip: | |||
101 | return 0; | 111 | return 0; |
102 | } | 112 | } |
103 | 113 | ||
114 | asmlinkage void spurious_interrupt(struct pt_regs *regs) | ||
115 | { | ||
116 | atomic_inc(&irq_err_count); | ||
117 | } | ||
118 | |||
104 | #ifdef CONFIG_KGDB | 119 | #ifdef CONFIG_KGDB |
105 | extern void breakpoint(void); | 120 | extern void breakpoint(void); |
106 | extern void set_debug_traps(void); | 121 | extern void set_debug_traps(void); |
@@ -124,6 +139,9 @@ void __init init_IRQ(void) | |||
124 | irq_desc[i].depth = 1; | 139 | irq_desc[i].depth = 1; |
125 | irq_desc[i].handler = &no_irq_type; | 140 | irq_desc[i].handler = &no_irq_type; |
126 | spin_lock_init(&irq_desc[i].lock); | 141 | spin_lock_init(&irq_desc[i].lock); |
142 | #ifdef CONFIG_MIPS_MT_SMTC | ||
143 | irq_hwmask[i] = 0; | ||
144 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
127 | } | 145 | } |
128 | 146 | ||
129 | arch_init_irq(); | 147 | arch_init_irq(); |
diff --git a/arch/mips/kernel/kspd.c b/arch/mips/kernel/kspd.c new file mode 100644 index 000000000000..f06a144c7881 --- /dev/null +++ b/arch/mips/kernel/kspd.c | |||
@@ -0,0 +1,398 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can distribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License (Version 2) as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
11 | * for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
16 | * | ||
17 | */ | ||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/unistd.h> | ||
21 | #include <linux/file.h> | ||
22 | #include <linux/fs.h> | ||
23 | #include <linux/syscalls.h> | ||
24 | #include <linux/workqueue.h> | ||
25 | #include <linux/errno.h> | ||
26 | #include <linux/list.h> | ||
27 | |||
28 | #include <asm/vpe.h> | ||
29 | #include <asm/rtlx.h> | ||
30 | #include <asm/kspd.h> | ||
31 | |||
32 | static struct workqueue_struct *workqueue = NULL; | ||
33 | static struct work_struct work; | ||
34 | |||
35 | extern unsigned long cpu_khz; | ||
36 | |||
37 | struct mtsp_syscall { | ||
38 | int cmd; | ||
39 | unsigned char abi; | ||
40 | unsigned char size; | ||
41 | }; | ||
42 | |||
43 | struct mtsp_syscall_ret { | ||
44 | int retval; | ||
45 | int errno; | ||
46 | }; | ||
47 | |||
48 | struct mtsp_syscall_generic { | ||
49 | int arg0; | ||
50 | int arg1; | ||
51 | int arg2; | ||
52 | int arg3; | ||
53 | int arg4; | ||
54 | int arg5; | ||
55 | int arg6; | ||
56 | }; | ||
57 | |||
58 | static struct list_head kspd_notifylist; | ||
59 | static int sp_stopping = 0; | ||
60 | |||
61 | /* these should match with those in the SDE kit */ | ||
62 | #define MTSP_SYSCALL_BASE 0 | ||
63 | #define MTSP_SYSCALL_EXIT (MTSP_SYSCALL_BASE + 0) | ||
64 | #define MTSP_SYSCALL_OPEN (MTSP_SYSCALL_BASE + 1) | ||
65 | #define MTSP_SYSCALL_READ (MTSP_SYSCALL_BASE + 2) | ||
66 | #define MTSP_SYSCALL_WRITE (MTSP_SYSCALL_BASE + 3) | ||
67 | #define MTSP_SYSCALL_CLOSE (MTSP_SYSCALL_BASE + 4) | ||
68 | #define MTSP_SYSCALL_LSEEK32 (MTSP_SYSCALL_BASE + 5) | ||
69 | #define MTSP_SYSCALL_ISATTY (MTSP_SYSCALL_BASE + 6) | ||
70 | #define MTSP_SYSCALL_GETTIME (MTSP_SYSCALL_BASE + 7) | ||
71 | #define MTSP_SYSCALL_PIPEFREQ (MTSP_SYSCALL_BASE + 8) | ||
72 | #define MTSP_SYSCALL_GETTOD (MTSP_SYSCALL_BASE + 9) | ||
73 | |||
74 | #define MTSP_O_RDONLY 0x0000 | ||
75 | #define MTSP_O_WRONLY 0x0001 | ||
76 | #define MTSP_O_RDWR 0x0002 | ||
77 | #define MTSP_O_NONBLOCK 0x0004 | ||
78 | #define MTSP_O_APPEND 0x0008 | ||
79 | #define MTSP_O_SHLOCK 0x0010 | ||
80 | #define MTSP_O_EXLOCK 0x0020 | ||
81 | #define MTSP_O_ASYNC 0x0040 | ||
82 | #define MTSP_O_FSYNC O_SYNC | ||
83 | #define MTSP_O_NOFOLLOW 0x0100 | ||
84 | #define MTSP_O_SYNC 0x0080 | ||
85 | #define MTSP_O_CREAT 0x0200 | ||
86 | #define MTSP_O_TRUNC 0x0400 | ||
87 | #define MTSP_O_EXCL 0x0800 | ||
88 | #define MTSP_O_BINARY 0x8000 | ||
89 | |||
90 | #define SP_VPE 1 | ||
91 | |||
92 | struct apsp_table { | ||
93 | int sp; | ||
94 | int ap; | ||
95 | }; | ||
96 | |||
97 | /* we might want to do the mode flags too */ | ||
98 | struct apsp_table open_flags_table[] = { | ||
99 | { MTSP_O_RDWR, O_RDWR }, | ||
100 | { MTSP_O_WRONLY, O_WRONLY }, | ||
101 | { MTSP_O_CREAT, O_CREAT }, | ||
102 | { MTSP_O_TRUNC, O_TRUNC }, | ||
103 | { MTSP_O_NONBLOCK, O_NONBLOCK }, | ||
104 | { MTSP_O_APPEND, O_APPEND }, | ||
105 | { MTSP_O_NOFOLLOW, O_NOFOLLOW } | ||
106 | }; | ||
107 | |||
108 | struct apsp_table syscall_command_table[] = { | ||
109 | { MTSP_SYSCALL_OPEN, __NR_open }, | ||
110 | { MTSP_SYSCALL_CLOSE, __NR_close }, | ||
111 | { MTSP_SYSCALL_READ, __NR_read }, | ||
112 | { MTSP_SYSCALL_WRITE, __NR_write }, | ||
113 | { MTSP_SYSCALL_LSEEK32, __NR_lseek } | ||
114 | }; | ||
115 | |||
116 | static int sp_syscall(int num, int arg0, int arg1, int arg2, int arg3) | ||
117 | { | ||
118 | register long int _num __asm__ ("$2") = num; | ||
119 | register long int _arg0 __asm__ ("$4") = arg0; | ||
120 | register long int _arg1 __asm__ ("$5") = arg1; | ||
121 | register long int _arg2 __asm__ ("$6") = arg2; | ||
122 | register long int _arg3 __asm__ ("$7") = arg3; | ||
123 | |||
124 | mm_segment_t old_fs; | ||
125 | |||
126 | old_fs = get_fs(); | ||
127 | set_fs(KERNEL_DS); | ||
128 | |||
129 | __asm__ __volatile__ ( | ||
130 | " syscall \n" | ||
131 | : "=r" (_num), "=r" (_arg3) | ||
132 | : "r" (_num), "r" (_arg0), "r" (_arg1), "r" (_arg2), "r" (_arg3)); | ||
133 | |||
134 | set_fs(old_fs); | ||
135 | |||
136 | /* $a3 is error flag */ | ||
137 | if (_arg3) | ||
138 | return -_num; | ||
139 | |||
140 | return _num; | ||
141 | } | ||
142 | |||
143 | static int translate_syscall_command(int cmd) | ||
144 | { | ||
145 | int i; | ||
146 | int ret = -1; | ||
147 | |||
148 | for (i = 0; i < ARRAY_SIZE(syscall_command_table); i++) { | ||
149 | if ((cmd == syscall_command_table[i].sp)) | ||
150 | return syscall_command_table[i].ap; | ||
151 | } | ||
152 | |||
153 | return ret; | ||
154 | } | ||
155 | |||
156 | static unsigned int translate_open_flags(int flags) | ||
157 | { | ||
158 | int i; | ||
159 | unsigned int ret = 0; | ||
160 | |||
161 | for (i = 0; i < (sizeof(open_flags_table) / sizeof(struct apsp_table)); | ||
162 | i++) { | ||
163 | if( (flags & open_flags_table[i].sp) ) { | ||
164 | ret |= open_flags_table[i].ap; | ||
165 | } | ||
166 | } | ||
167 | |||
168 | return ret; | ||
169 | } | ||
170 | |||
171 | |||
172 | static void sp_setfsuidgid( uid_t uid, gid_t gid) | ||
173 | { | ||
174 | current->fsuid = uid; | ||
175 | current->fsgid = gid; | ||
176 | |||
177 | key_fsuid_changed(current); | ||
178 | key_fsgid_changed(current); | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * Expects a request to be on the sysio channel. Reads it. Decides whether | ||
183 | * its a linux syscall and runs it, or whatever. Puts the return code back | ||
184 | * into the request and sends the whole thing back. | ||
185 | */ | ||
186 | void sp_work_handle_request(void) | ||
187 | { | ||
188 | struct mtsp_syscall sc; | ||
189 | struct mtsp_syscall_generic generic; | ||
190 | struct mtsp_syscall_ret ret; | ||
191 | struct kspd_notifications *n; | ||
192 | struct timeval tv; | ||
193 | struct timezone tz; | ||
194 | int cmd; | ||
195 | |||
196 | char *vcwd; | ||
197 | mm_segment_t old_fs; | ||
198 | int size; | ||
199 | |||
200 | ret.retval = -1; | ||
201 | |||
202 | if (!rtlx_read(RTLX_CHANNEL_SYSIO, &sc, sizeof(struct mtsp_syscall), 0)) { | ||
203 | printk(KERN_ERR "Expected request but nothing to read\n"); | ||
204 | return; | ||
205 | } | ||
206 | |||
207 | size = sc.size; | ||
208 | |||
209 | if (size) { | ||
210 | if (!rtlx_read(RTLX_CHANNEL_SYSIO, &generic, size, 0)) { | ||
211 | printk(KERN_ERR "Expected request but nothing to read\n"); | ||
212 | return; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | /* Run the syscall at the priviledge of the user who loaded the | ||
217 | SP program */ | ||
218 | |||
219 | if (vpe_getuid(SP_VPE)) | ||
220 | sp_setfsuidgid( vpe_getuid(SP_VPE), vpe_getgid(SP_VPE)); | ||
221 | |||
222 | switch (sc.cmd) { | ||
223 | /* needs the flags argument translating from SDE kit to | ||
224 | linux */ | ||
225 | case MTSP_SYSCALL_PIPEFREQ: | ||
226 | ret.retval = cpu_khz * 1000; | ||
227 | ret.errno = 0; | ||
228 | break; | ||
229 | |||
230 | case MTSP_SYSCALL_GETTOD: | ||
231 | memset(&tz, 0, sizeof(tz)); | ||
232 | if ((ret.retval = sp_syscall(__NR_gettimeofday, (int)&tv, | ||
233 | (int)&tz, 0,0)) == 0) | ||
234 | ret.retval = tv.tv_sec; | ||
235 | |||
236 | ret.errno = errno; | ||
237 | break; | ||
238 | |||
239 | case MTSP_SYSCALL_EXIT: | ||
240 | list_for_each_entry(n, &kspd_notifylist, list) | ||
241 | n->kspd_sp_exit(SP_VPE); | ||
242 | sp_stopping = 1; | ||
243 | |||
244 | printk(KERN_DEBUG "KSPD got exit syscall from SP exitcode %d\n", | ||
245 | generic.arg0); | ||
246 | break; | ||
247 | |||
248 | case MTSP_SYSCALL_OPEN: | ||
249 | generic.arg1 = translate_open_flags(generic.arg1); | ||
250 | |||
251 | vcwd = vpe_getcwd(SP_VPE); | ||
252 | |||
253 | /* change to the cwd of the process that loaded the SP program */ | ||
254 | old_fs = get_fs(); | ||
255 | set_fs(KERNEL_DS); | ||
256 | sys_chdir(vcwd); | ||
257 | set_fs(old_fs); | ||
258 | |||
259 | sc.cmd = __NR_open; | ||
260 | |||
261 | /* fall through */ | ||
262 | |||
263 | default: | ||
264 | if ((sc.cmd >= __NR_Linux) && | ||
265 | (sc.cmd <= (__NR_Linux + __NR_Linux_syscalls)) ) | ||
266 | cmd = sc.cmd; | ||
267 | else | ||
268 | cmd = translate_syscall_command(sc.cmd); | ||
269 | |||
270 | if (cmd >= 0) { | ||
271 | ret.retval = sp_syscall(cmd, generic.arg0, generic.arg1, | ||
272 | generic.arg2, generic.arg3); | ||
273 | ret.errno = errno; | ||
274 | } else | ||
275 | printk(KERN_WARNING | ||
276 | "KSPD: Unknown SP syscall number %d\n", sc.cmd); | ||
277 | break; | ||
278 | } /* switch */ | ||
279 | |||
280 | if (vpe_getuid(SP_VPE)) | ||
281 | sp_setfsuidgid( 0, 0); | ||
282 | |||
283 | if ((rtlx_write(RTLX_CHANNEL_SYSIO, &ret, sizeof(struct mtsp_syscall_ret), 0)) | ||
284 | < sizeof(struct mtsp_syscall_ret)) | ||
285 | printk("KSPD: sp_work_handle_request failed to send to SP\n"); | ||
286 | } | ||
287 | |||
288 | static void sp_cleanup(void) | ||
289 | { | ||
290 | struct files_struct *files = current->files; | ||
291 | int i, j; | ||
292 | struct fdtable *fdt; | ||
293 | |||
294 | j = 0; | ||
295 | |||
296 | /* | ||
297 | * It is safe to dereference the fd table without RCU or | ||
298 | * ->file_lock | ||
299 | */ | ||
300 | fdt = files_fdtable(files); | ||
301 | for (;;) { | ||
302 | unsigned long set; | ||
303 | i = j * __NFDBITS; | ||
304 | if (i >= fdt->max_fdset || i >= fdt->max_fds) | ||
305 | break; | ||
306 | set = fdt->open_fds->fds_bits[j++]; | ||
307 | while (set) { | ||
308 | if (set & 1) { | ||
309 | struct file * file = xchg(&fdt->fd[i], NULL); | ||
310 | if (file) | ||
311 | filp_close(file, files); | ||
312 | } | ||
313 | i++; | ||
314 | set >>= 1; | ||
315 | } | ||
316 | } | ||
317 | } | ||
318 | |||
319 | static int channel_open = 0; | ||
320 | |||
321 | /* the work handler */ | ||
322 | static void sp_work(void *data) | ||
323 | { | ||
324 | if (!channel_open) { | ||
325 | if( rtlx_open(RTLX_CHANNEL_SYSIO, 1) != 0) { | ||
326 | printk("KSPD: unable to open sp channel\n"); | ||
327 | sp_stopping = 1; | ||
328 | } else { | ||
329 | channel_open++; | ||
330 | printk(KERN_DEBUG "KSPD: SP channel opened\n"); | ||
331 | } | ||
332 | } else { | ||
333 | /* wait for some data, allow it to sleep */ | ||
334 | rtlx_read_poll(RTLX_CHANNEL_SYSIO, 1); | ||
335 | |||
336 | /* Check we haven't been woken because we are stopping */ | ||
337 | if (!sp_stopping) | ||
338 | sp_work_handle_request(); | ||
339 | } | ||
340 | |||
341 | if (!sp_stopping) | ||
342 | queue_work(workqueue, &work); | ||
343 | else | ||
344 | sp_cleanup(); | ||
345 | } | ||
346 | |||
347 | static void startwork(int vpe) | ||
348 | { | ||
349 | sp_stopping = channel_open = 0; | ||
350 | |||
351 | if (workqueue == NULL) { | ||
352 | if ((workqueue = create_singlethread_workqueue("kspd")) == NULL) { | ||
353 | printk(KERN_ERR "unable to start kspd\n"); | ||
354 | return; | ||
355 | } | ||
356 | |||
357 | INIT_WORK(&work, sp_work, NULL); | ||
358 | queue_work(workqueue, &work); | ||
359 | } else | ||
360 | queue_work(workqueue, &work); | ||
361 | |||
362 | } | ||
363 | |||
364 | static void stopwork(int vpe) | ||
365 | { | ||
366 | sp_stopping = 1; | ||
367 | |||
368 | printk(KERN_DEBUG "KSPD: SP stopping\n"); | ||
369 | } | ||
370 | |||
371 | void kspd_notify(struct kspd_notifications *notify) | ||
372 | { | ||
373 | list_add(¬ify->list, &kspd_notifylist); | ||
374 | } | ||
375 | |||
376 | static struct vpe_notifications notify; | ||
377 | static int kspd_module_init(void) | ||
378 | { | ||
379 | INIT_LIST_HEAD(&kspd_notifylist); | ||
380 | |||
381 | notify.start = startwork; | ||
382 | notify.stop = stopwork; | ||
383 | vpe_notify(SP_VPE, ¬ify); | ||
384 | |||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | static void kspd_module_exit(void) | ||
389 | { | ||
390 | |||
391 | } | ||
392 | |||
393 | module_init(kspd_module_init); | ||
394 | module_exit(kspd_module_exit); | ||
395 | |||
396 | MODULE_DESCRIPTION("MIPS KSPD"); | ||
397 | MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc."); | ||
398 | MODULE_LICENSE("GPL"); | ||
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c index 3f40c37a9ee6..a7d2bb3cf835 100644 --- a/arch/mips/kernel/linux32.c +++ b/arch/mips/kernel/linux32.c | |||
@@ -356,73 +356,13 @@ asmlinkage int sys32_llseek(unsigned int fd, unsigned int offset_high, | |||
356 | asmlinkage ssize_t sys32_pread(unsigned int fd, char __user * buf, | 356 | asmlinkage ssize_t sys32_pread(unsigned int fd, char __user * buf, |
357 | size_t count, u32 unused, u64 a4, u64 a5) | 357 | size_t count, u32 unused, u64 a4, u64 a5) |
358 | { | 358 | { |
359 | ssize_t ret; | 359 | return sys_pread64(fd, buf, count, merge_64(a4, a5)); |
360 | struct file * file; | ||
361 | ssize_t (*read)(struct file *, char __user *, size_t, loff_t *); | ||
362 | loff_t pos; | ||
363 | |||
364 | ret = -EBADF; | ||
365 | file = fget(fd); | ||
366 | if (!file) | ||
367 | goto bad_file; | ||
368 | if (!(file->f_mode & FMODE_READ)) | ||
369 | goto out; | ||
370 | pos = merge_64(a4, a5); | ||
371 | ret = rw_verify_area(READ, file, &pos, count); | ||
372 | if (ret < 0) | ||
373 | goto out; | ||
374 | ret = -EINVAL; | ||
375 | if (!file->f_op || !(read = file->f_op->read)) | ||
376 | goto out; | ||
377 | if (pos < 0) | ||
378 | goto out; | ||
379 | ret = -ESPIPE; | ||
380 | if (!(file->f_mode & FMODE_PREAD)) | ||
381 | goto out; | ||
382 | ret = read(file, buf, count, &pos); | ||
383 | if (ret > 0) | ||
384 | dnotify_parent(file->f_dentry, DN_ACCESS); | ||
385 | out: | ||
386 | fput(file); | ||
387 | bad_file: | ||
388 | return ret; | ||
389 | } | 360 | } |
390 | 361 | ||
391 | asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf, | 362 | asmlinkage ssize_t sys32_pwrite(unsigned int fd, const char __user * buf, |
392 | size_t count, u32 unused, u64 a4, u64 a5) | 363 | size_t count, u32 unused, u64 a4, u64 a5) |
393 | { | 364 | { |
394 | ssize_t ret; | 365 | return sys_pwrite64(fd, buf, count, merge_64(a4, a5)); |
395 | struct file * file; | ||
396 | ssize_t (*write)(struct file *, const char __user *, size_t, loff_t *); | ||
397 | loff_t pos; | ||
398 | |||
399 | ret = -EBADF; | ||
400 | file = fget(fd); | ||
401 | if (!file) | ||
402 | goto bad_file; | ||
403 | if (!(file->f_mode & FMODE_WRITE)) | ||
404 | goto out; | ||
405 | pos = merge_64(a4, a5); | ||
406 | ret = rw_verify_area(WRITE, file, &pos, count); | ||
407 | if (ret < 0) | ||
408 | goto out; | ||
409 | ret = -EINVAL; | ||
410 | if (!file->f_op || !(write = file->f_op->write)) | ||
411 | goto out; | ||
412 | if (pos < 0) | ||
413 | goto out; | ||
414 | |||
415 | ret = -ESPIPE; | ||
416 | if (!(file->f_mode & FMODE_PWRITE)) | ||
417 | goto out; | ||
418 | |||
419 | ret = write(file, buf, count, &pos); | ||
420 | if (ret > 0) | ||
421 | dnotify_parent(file->f_dentry, DN_MODIFY); | ||
422 | out: | ||
423 | fput(file); | ||
424 | bad_file: | ||
425 | return ret; | ||
426 | } | 366 | } |
427 | 367 | ||
428 | asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, | 368 | asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid, |
@@ -1182,6 +1122,16 @@ asmlinkage ssize_t sys32_readahead(int fd, u32 pad0, u64 a2, u64 a3, | |||
1182 | return sys_readahead(fd, merge_64(a2, a3), count); | 1122 | return sys_readahead(fd, merge_64(a2, a3), count); |
1183 | } | 1123 | } |
1184 | 1124 | ||
1125 | asmlinkage long sys32_sync_file_range(int fd, int __pad, | ||
1126 | unsigned long a2, unsigned long a3, | ||
1127 | unsigned long a4, unsigned long a5, | ||
1128 | int flags) | ||
1129 | { | ||
1130 | return sys_sync_file_range(fd, | ||
1131 | merge_64(a2, a3), merge_64(a4, a5), | ||
1132 | flags); | ||
1133 | } | ||
1134 | |||
1185 | /* Argument list sizes for sys_socketcall */ | 1135 | /* Argument list sizes for sys_socketcall */ |
1186 | #define AL(x) ((x) * sizeof(unsigned int)) | 1136 | #define AL(x) ((x) * sizeof(unsigned int)) |
1187 | static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), | 1137 | static unsigned char socketcall_nargs[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3), |
diff --git a/arch/mips/kernel/mips-mt.c b/arch/mips/kernel/mips-mt.c new file mode 100644 index 000000000000..02237a685ec7 --- /dev/null +++ b/arch/mips/kernel/mips-mt.c | |||
@@ -0,0 +1,449 @@ | |||
1 | /* | ||
2 | * General MIPS MT support routines, usable in AP/SP, SMVP, or SMTC kernels | ||
3 | * Copyright (C) 2005 Mips Technologies, Inc | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/sched.h> | ||
8 | #include <linux/cpumask.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | |||
11 | #include <asm/cpu.h> | ||
12 | #include <asm/processor.h> | ||
13 | #include <asm/atomic.h> | ||
14 | #include <asm/system.h> | ||
15 | #include <asm/hardirq.h> | ||
16 | #include <asm/mmu_context.h> | ||
17 | #include <asm/smp.h> | ||
18 | #include <asm/mipsmtregs.h> | ||
19 | #include <asm/r4kcache.h> | ||
20 | #include <asm/cacheflush.h> | ||
21 | |||
22 | /* | ||
23 | * CPU mask used to set process affinity for MT VPEs/TCs with FPUs | ||
24 | */ | ||
25 | |||
26 | cpumask_t mt_fpu_cpumask; | ||
27 | |||
28 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
29 | |||
30 | #include <linux/cpu.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <asm/uaccess.h> | ||
33 | |||
34 | unsigned long mt_fpemul_threshold = 0; | ||
35 | |||
36 | /* | ||
37 | * Replacement functions for the sys_sched_setaffinity() and | ||
38 | * sys_sched_getaffinity() system calls, so that we can integrate | ||
39 | * FPU affinity with the user's requested processor affinity. | ||
40 | * This code is 98% identical with the sys_sched_setaffinity() | ||
41 | * and sys_sched_getaffinity() system calls, and should be | ||
42 | * updated when kernel/sched.c changes. | ||
43 | */ | ||
44 | |||
45 | /* | ||
46 | * find_process_by_pid - find a process with a matching PID value. | ||
47 | * used in sys_sched_set/getaffinity() in kernel/sched.c, so | ||
48 | * cloned here. | ||
49 | */ | ||
50 | static inline task_t *find_process_by_pid(pid_t pid) | ||
51 | { | ||
52 | return pid ? find_task_by_pid(pid) : current; | ||
53 | } | ||
54 | |||
55 | |||
56 | /* | ||
57 | * mipsmt_sys_sched_setaffinity - set the cpu affinity of a process | ||
58 | */ | ||
59 | asmlinkage long mipsmt_sys_sched_setaffinity(pid_t pid, unsigned int len, | ||
60 | unsigned long __user *user_mask_ptr) | ||
61 | { | ||
62 | cpumask_t new_mask; | ||
63 | cpumask_t effective_mask; | ||
64 | int retval; | ||
65 | task_t *p; | ||
66 | |||
67 | if (len < sizeof(new_mask)) | ||
68 | return -EINVAL; | ||
69 | |||
70 | if (copy_from_user(&new_mask, user_mask_ptr, sizeof(new_mask))) | ||
71 | return -EFAULT; | ||
72 | |||
73 | lock_cpu_hotplug(); | ||
74 | read_lock(&tasklist_lock); | ||
75 | |||
76 | p = find_process_by_pid(pid); | ||
77 | if (!p) { | ||
78 | read_unlock(&tasklist_lock); | ||
79 | unlock_cpu_hotplug(); | ||
80 | return -ESRCH; | ||
81 | } | ||
82 | |||
83 | /* | ||
84 | * It is not safe to call set_cpus_allowed with the | ||
85 | * tasklist_lock held. We will bump the task_struct's | ||
86 | * usage count and drop tasklist_lock before invoking | ||
87 | * set_cpus_allowed. | ||
88 | */ | ||
89 | get_task_struct(p); | ||
90 | |||
91 | retval = -EPERM; | ||
92 | if ((current->euid != p->euid) && (current->euid != p->uid) && | ||
93 | !capable(CAP_SYS_NICE)) { | ||
94 | read_unlock(&tasklist_lock); | ||
95 | goto out_unlock; | ||
96 | } | ||
97 | |||
98 | /* Record new user-specified CPU set for future reference */ | ||
99 | p->thread.user_cpus_allowed = new_mask; | ||
100 | |||
101 | /* Unlock the task list */ | ||
102 | read_unlock(&tasklist_lock); | ||
103 | |||
104 | /* Compute new global allowed CPU set if necessary */ | ||
105 | if( (p->thread.mflags & MF_FPUBOUND) | ||
106 | && cpus_intersects(new_mask, mt_fpu_cpumask)) { | ||
107 | cpus_and(effective_mask, new_mask, mt_fpu_cpumask); | ||
108 | retval = set_cpus_allowed(p, effective_mask); | ||
109 | } else { | ||
110 | p->thread.mflags &= ~MF_FPUBOUND; | ||
111 | retval = set_cpus_allowed(p, new_mask); | ||
112 | } | ||
113 | |||
114 | |||
115 | out_unlock: | ||
116 | put_task_struct(p); | ||
117 | unlock_cpu_hotplug(); | ||
118 | return retval; | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * mipsmt_sys_sched_getaffinity - get the cpu affinity of a process | ||
123 | */ | ||
124 | asmlinkage long mipsmt_sys_sched_getaffinity(pid_t pid, unsigned int len, | ||
125 | unsigned long __user *user_mask_ptr) | ||
126 | { | ||
127 | unsigned int real_len; | ||
128 | cpumask_t mask; | ||
129 | int retval; | ||
130 | task_t *p; | ||
131 | |||
132 | real_len = sizeof(mask); | ||
133 | if (len < real_len) | ||
134 | return -EINVAL; | ||
135 | |||
136 | lock_cpu_hotplug(); | ||
137 | read_lock(&tasklist_lock); | ||
138 | |||
139 | retval = -ESRCH; | ||
140 | p = find_process_by_pid(pid); | ||
141 | if (!p) | ||
142 | goto out_unlock; | ||
143 | |||
144 | retval = 0; | ||
145 | |||
146 | cpus_and(mask, p->thread.user_cpus_allowed, cpu_possible_map); | ||
147 | |||
148 | out_unlock: | ||
149 | read_unlock(&tasklist_lock); | ||
150 | unlock_cpu_hotplug(); | ||
151 | if (retval) | ||
152 | return retval; | ||
153 | if (copy_to_user(user_mask_ptr, &mask, real_len)) | ||
154 | return -EFAULT; | ||
155 | return real_len; | ||
156 | } | ||
157 | |||
158 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
159 | |||
160 | /* | ||
161 | * Dump new MIPS MT state for the core. Does not leave TCs halted. | ||
162 | * Takes an argument which taken to be a pre-call MVPControl value. | ||
163 | */ | ||
164 | |||
165 | void mips_mt_regdump(unsigned long mvpctl) | ||
166 | { | ||
167 | unsigned long flags; | ||
168 | unsigned long vpflags; | ||
169 | unsigned long mvpconf0; | ||
170 | int nvpe; | ||
171 | int ntc; | ||
172 | int i; | ||
173 | int tc; | ||
174 | unsigned long haltval; | ||
175 | unsigned long tcstatval; | ||
176 | #ifdef CONFIG_MIPS_MT_SMTC | ||
177 | void smtc_soft_dump(void); | ||
178 | #endif /* CONFIG_MIPT_MT_SMTC */ | ||
179 | |||
180 | local_irq_save(flags); | ||
181 | vpflags = dvpe(); | ||
182 | printk("=== MIPS MT State Dump ===\n"); | ||
183 | printk("-- Global State --\n"); | ||
184 | printk(" MVPControl Passed: %08lx\n", mvpctl); | ||
185 | printk(" MVPControl Read: %08lx\n", vpflags); | ||
186 | printk(" MVPConf0 : %08lx\n", (mvpconf0 = read_c0_mvpconf0())); | ||
187 | nvpe = ((mvpconf0 & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; | ||
188 | ntc = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; | ||
189 | printk("-- per-VPE State --\n"); | ||
190 | for(i = 0; i < nvpe; i++) { | ||
191 | for(tc = 0; tc < ntc; tc++) { | ||
192 | settc(tc); | ||
193 | if((read_tc_c0_tcbind() & TCBIND_CURVPE) == i) { | ||
194 | printk(" VPE %d\n", i); | ||
195 | printk(" VPEControl : %08lx\n", read_vpe_c0_vpecontrol()); | ||
196 | printk(" VPEConf0 : %08lx\n", read_vpe_c0_vpeconf0()); | ||
197 | printk(" VPE%d.Status : %08lx\n", | ||
198 | i, read_vpe_c0_status()); | ||
199 | printk(" VPE%d.EPC : %08lx\n", i, read_vpe_c0_epc()); | ||
200 | printk(" VPE%d.Cause : %08lx\n", i, read_vpe_c0_cause()); | ||
201 | printk(" VPE%d.Config7 : %08lx\n", | ||
202 | i, read_vpe_c0_config7()); | ||
203 | break; /* Next VPE */ | ||
204 | } | ||
205 | } | ||
206 | } | ||
207 | printk("-- per-TC State --\n"); | ||
208 | for(tc = 0; tc < ntc; tc++) { | ||
209 | settc(tc); | ||
210 | if(read_tc_c0_tcbind() == read_c0_tcbind()) { | ||
211 | /* Are we dumping ourself? */ | ||
212 | haltval = 0; /* Then we're not halted, and mustn't be */ | ||
213 | tcstatval = flags; /* And pre-dump TCStatus is flags */ | ||
214 | printk(" TC %d (current TC with VPE EPC above)\n", tc); | ||
215 | } else { | ||
216 | haltval = read_tc_c0_tchalt(); | ||
217 | write_tc_c0_tchalt(1); | ||
218 | tcstatval = read_tc_c0_tcstatus(); | ||
219 | printk(" TC %d\n", tc); | ||
220 | } | ||
221 | printk(" TCStatus : %08lx\n", tcstatval); | ||
222 | printk(" TCBind : %08lx\n", read_tc_c0_tcbind()); | ||
223 | printk(" TCRestart : %08lx\n", read_tc_c0_tcrestart()); | ||
224 | printk(" TCHalt : %08lx\n", haltval); | ||
225 | printk(" TCContext : %08lx\n", read_tc_c0_tccontext()); | ||
226 | if (!haltval) | ||
227 | write_tc_c0_tchalt(0); | ||
228 | } | ||
229 | #ifdef CONFIG_MIPS_MT_SMTC | ||
230 | smtc_soft_dump(); | ||
231 | #endif /* CONFIG_MIPT_MT_SMTC */ | ||
232 | printk("===========================\n"); | ||
233 | evpe(vpflags); | ||
234 | local_irq_restore(flags); | ||
235 | } | ||
236 | |||
237 | static int mt_opt_norps = 0; | ||
238 | static int mt_opt_rpsctl = -1; | ||
239 | static int mt_opt_nblsu = -1; | ||
240 | static int mt_opt_forceconfig7 = 0; | ||
241 | static int mt_opt_config7 = -1; | ||
242 | |||
243 | static int __init rps_disable(char *s) | ||
244 | { | ||
245 | mt_opt_norps = 1; | ||
246 | return 1; | ||
247 | } | ||
248 | __setup("norps", rps_disable); | ||
249 | |||
250 | static int __init rpsctl_set(char *str) | ||
251 | { | ||
252 | get_option(&str, &mt_opt_rpsctl); | ||
253 | return 1; | ||
254 | } | ||
255 | __setup("rpsctl=", rpsctl_set); | ||
256 | |||
257 | static int __init nblsu_set(char *str) | ||
258 | { | ||
259 | get_option(&str, &mt_opt_nblsu); | ||
260 | return 1; | ||
261 | } | ||
262 | __setup("nblsu=", nblsu_set); | ||
263 | |||
264 | static int __init config7_set(char *str) | ||
265 | { | ||
266 | get_option(&str, &mt_opt_config7); | ||
267 | mt_opt_forceconfig7 = 1; | ||
268 | return 1; | ||
269 | } | ||
270 | __setup("config7=", config7_set); | ||
271 | |||
272 | /* Experimental cache flush control parameters that should go away some day */ | ||
273 | int mt_protiflush = 0; | ||
274 | int mt_protdflush = 0; | ||
275 | int mt_n_iflushes = 1; | ||
276 | int mt_n_dflushes = 1; | ||
277 | |||
278 | static int __init set_protiflush(char *s) | ||
279 | { | ||
280 | mt_protiflush = 1; | ||
281 | return 1; | ||
282 | } | ||
283 | __setup("protiflush", set_protiflush); | ||
284 | |||
285 | static int __init set_protdflush(char *s) | ||
286 | { | ||
287 | mt_protdflush = 1; | ||
288 | return 1; | ||
289 | } | ||
290 | __setup("protdflush", set_protdflush); | ||
291 | |||
292 | static int __init niflush(char *s) | ||
293 | { | ||
294 | get_option(&s, &mt_n_iflushes); | ||
295 | return 1; | ||
296 | } | ||
297 | __setup("niflush=", niflush); | ||
298 | |||
299 | static int __init ndflush(char *s) | ||
300 | { | ||
301 | get_option(&s, &mt_n_dflushes); | ||
302 | return 1; | ||
303 | } | ||
304 | __setup("ndflush=", ndflush); | ||
305 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
306 | static int fpaff_threshold = -1; | ||
307 | |||
308 | static int __init fpaff_thresh(char *str) | ||
309 | { | ||
310 | get_option(&str, &fpaff_threshold); | ||
311 | return 1; | ||
312 | } | ||
313 | |||
314 | __setup("fpaff=", fpaff_thresh); | ||
315 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
316 | |||
317 | static unsigned int itc_base = 0; | ||
318 | |||
319 | static int __init set_itc_base(char *str) | ||
320 | { | ||
321 | get_option(&str, &itc_base); | ||
322 | return 1; | ||
323 | } | ||
324 | |||
325 | __setup("itcbase=", set_itc_base); | ||
326 | |||
327 | void mips_mt_set_cpuoptions(void) | ||
328 | { | ||
329 | unsigned int oconfig7 = read_c0_config7(); | ||
330 | unsigned int nconfig7 = oconfig7; | ||
331 | |||
332 | if (mt_opt_norps) { | ||
333 | printk("\"norps\" option deprectated: use \"rpsctl=\"\n"); | ||
334 | } | ||
335 | if (mt_opt_rpsctl >= 0) { | ||
336 | printk("34K return prediction stack override set to %d.\n", | ||
337 | mt_opt_rpsctl); | ||
338 | if (mt_opt_rpsctl) | ||
339 | nconfig7 |= (1 << 2); | ||
340 | else | ||
341 | nconfig7 &= ~(1 << 2); | ||
342 | } | ||
343 | if (mt_opt_nblsu >= 0) { | ||
344 | printk("34K ALU/LSU sync override set to %d.\n", mt_opt_nblsu); | ||
345 | if (mt_opt_nblsu) | ||
346 | nconfig7 |= (1 << 5); | ||
347 | else | ||
348 | nconfig7 &= ~(1 << 5); | ||
349 | } | ||
350 | if (mt_opt_forceconfig7) { | ||
351 | printk("CP0.Config7 forced to 0x%08x.\n", mt_opt_config7); | ||
352 | nconfig7 = mt_opt_config7; | ||
353 | } | ||
354 | if (oconfig7 != nconfig7) { | ||
355 | __asm__ __volatile("sync"); | ||
356 | write_c0_config7(nconfig7); | ||
357 | ehb (); | ||
358 | printk("Config7: 0x%08x\n", read_c0_config7()); | ||
359 | } | ||
360 | |||
361 | /* Report Cache management debug options */ | ||
362 | if (mt_protiflush) | ||
363 | printk("I-cache flushes single-threaded\n"); | ||
364 | if (mt_protdflush) | ||
365 | printk("D-cache flushes single-threaded\n"); | ||
366 | if (mt_n_iflushes != 1) | ||
367 | printk("I-Cache Flushes Repeated %d times\n", mt_n_iflushes); | ||
368 | if (mt_n_dflushes != 1) | ||
369 | printk("D-Cache Flushes Repeated %d times\n", mt_n_dflushes); | ||
370 | |||
371 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
372 | /* FPU Use Factor empirically derived from experiments on 34K */ | ||
373 | #define FPUSEFACTOR 333 | ||
374 | |||
375 | if (fpaff_threshold >= 0) { | ||
376 | mt_fpemul_threshold = fpaff_threshold; | ||
377 | } else { | ||
378 | mt_fpemul_threshold = | ||
379 | (FPUSEFACTOR * (loops_per_jiffy/(500000/HZ))) / HZ; | ||
380 | } | ||
381 | printk("FPU Affinity set after %ld emulations\n", | ||
382 | mt_fpemul_threshold); | ||
383 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
384 | |||
385 | if (itc_base != 0) { | ||
386 | /* | ||
387 | * Configure ITC mapping. This code is very | ||
388 | * specific to the 34K core family, which uses | ||
389 | * a special mode bit ("ITC") in the ErrCtl | ||
390 | * register to enable access to ITC control | ||
391 | * registers via cache "tag" operations. | ||
392 | */ | ||
393 | unsigned long ectlval; | ||
394 | unsigned long itcblkgrn; | ||
395 | |||
396 | /* ErrCtl register is known as "ecc" to Linux */ | ||
397 | ectlval = read_c0_ecc(); | ||
398 | write_c0_ecc(ectlval | (0x1 << 26)); | ||
399 | ehb(); | ||
400 | #define INDEX_0 (0x80000000) | ||
401 | #define INDEX_8 (0x80000008) | ||
402 | /* Read "cache tag" for Dcache pseudo-index 8 */ | ||
403 | cache_op(Index_Load_Tag_D, INDEX_8); | ||
404 | ehb(); | ||
405 | itcblkgrn = read_c0_dtaglo(); | ||
406 | itcblkgrn &= 0xfffe0000; | ||
407 | /* Set for 128 byte pitch of ITC cells */ | ||
408 | itcblkgrn |= 0x00000c00; | ||
409 | /* Stage in Tag register */ | ||
410 | write_c0_dtaglo(itcblkgrn); | ||
411 | ehb(); | ||
412 | /* Write out to ITU with CACHE op */ | ||
413 | cache_op(Index_Store_Tag_D, INDEX_8); | ||
414 | /* Now set base address, and turn ITC on with 0x1 bit */ | ||
415 | write_c0_dtaglo((itc_base & 0xfffffc00) | 0x1 ); | ||
416 | ehb(); | ||
417 | /* Write out to ITU with CACHE op */ | ||
418 | cache_op(Index_Store_Tag_D, INDEX_0); | ||
419 | write_c0_ecc(ectlval); | ||
420 | ehb(); | ||
421 | printk("Mapped %ld ITC cells starting at 0x%08x\n", | ||
422 | ((itcblkgrn & 0x7fe00000) >> 20), itc_base); | ||
423 | } | ||
424 | } | ||
425 | |||
426 | /* | ||
427 | * Function to protect cache flushes from concurrent execution | ||
428 | * depends on MP software model chosen. | ||
429 | */ | ||
430 | |||
431 | void mt_cflush_lockdown(void) | ||
432 | { | ||
433 | #ifdef CONFIG_MIPS_MT_SMTC | ||
434 | void smtc_cflush_lockdown(void); | ||
435 | |||
436 | smtc_cflush_lockdown(); | ||
437 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
438 | /* FILL IN VSMP and AP/SP VERSIONS HERE */ | ||
439 | } | ||
440 | |||
441 | void mt_cflush_release(void) | ||
442 | { | ||
443 | #ifdef CONFIG_MIPS_MT_SMTC | ||
444 | void smtc_cflush_release(void); | ||
445 | |||
446 | smtc_cflush_release(); | ||
447 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
448 | /* FILL IN VSMP and AP/SP VERSIONS HERE */ | ||
449 | } | ||
diff --git a/arch/mips/kernel/mips_ksyms.c b/arch/mips/kernel/mips_ksyms.c index e042f9d2ba31..0a71a4c33716 100644 --- a/arch/mips/kernel/mips_ksyms.c +++ b/arch/mips/kernel/mips_ksyms.c | |||
@@ -28,21 +28,9 @@ extern long __strnlen_user_asm(const char *s); | |||
28 | /* | 28 | /* |
29 | * String functions | 29 | * String functions |
30 | */ | 30 | */ |
31 | EXPORT_SYMBOL(memchr); | ||
32 | EXPORT_SYMBOL(memcmp); | ||
33 | EXPORT_SYMBOL(memset); | 31 | EXPORT_SYMBOL(memset); |
34 | EXPORT_SYMBOL(memcpy); | 32 | EXPORT_SYMBOL(memcpy); |
35 | EXPORT_SYMBOL(memmove); | 33 | EXPORT_SYMBOL(memmove); |
36 | EXPORT_SYMBOL(strcat); | ||
37 | EXPORT_SYMBOL(strchr); | ||
38 | #ifdef CONFIG_64BIT | ||
39 | EXPORT_SYMBOL(strncmp); | ||
40 | #endif | ||
41 | EXPORT_SYMBOL(strlen); | ||
42 | EXPORT_SYMBOL(strncat); | ||
43 | EXPORT_SYMBOL(strnlen); | ||
44 | EXPORT_SYMBOL(strrchr); | ||
45 | EXPORT_SYMBOL(strstr); | ||
46 | 34 | ||
47 | EXPORT_SYMBOL(kernel_thread); | 35 | EXPORT_SYMBOL(kernel_thread); |
48 | 36 | ||
@@ -61,6 +49,3 @@ EXPORT_SYMBOL(__strnlen_user_asm); | |||
61 | EXPORT_SYMBOL(csum_partial); | 49 | EXPORT_SYMBOL(csum_partial); |
62 | 50 | ||
63 | EXPORT_SYMBOL(invalid_pte_table); | 51 | EXPORT_SYMBOL(invalid_pte_table); |
64 | #ifdef CONFIG_GENERIC_IRQ_PROBE | ||
65 | EXPORT_SYMBOL(probe_irq_mask); | ||
66 | #endif | ||
diff --git a/arch/mips/kernel/process.c b/arch/mips/kernel/process.c index c66db5e5ab62..199a06e873c6 100644 --- a/arch/mips/kernel/process.c +++ b/arch/mips/kernel/process.c | |||
@@ -41,6 +41,10 @@ | |||
41 | #include <asm/elf.h> | 41 | #include <asm/elf.h> |
42 | #include <asm/isadep.h> | 42 | #include <asm/isadep.h> |
43 | #include <asm/inst.h> | 43 | #include <asm/inst.h> |
44 | #ifdef CONFIG_MIPS_MT_SMTC | ||
45 | #include <asm/mipsmtregs.h> | ||
46 | extern void smtc_idle_loop_hook(void); | ||
47 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
44 | 48 | ||
45 | /* | 49 | /* |
46 | * The idle thread. There's no useful work to be done, so just try to conserve | 50 | * The idle thread. There's no useful work to be done, so just try to conserve |
@@ -51,9 +55,13 @@ ATTRIB_NORET void cpu_idle(void) | |||
51 | { | 55 | { |
52 | /* endless idle loop with no priority at all */ | 56 | /* endless idle loop with no priority at all */ |
53 | while (1) { | 57 | while (1) { |
54 | while (!need_resched()) | 58 | while (!need_resched()) { |
59 | #ifdef CONFIG_MIPS_MT_SMTC | ||
60 | smtc_idle_loop_hook(); | ||
61 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
55 | if (cpu_wait) | 62 | if (cpu_wait) |
56 | (*cpu_wait)(); | 63 | (*cpu_wait)(); |
64 | } | ||
57 | preempt_enable_no_resched(); | 65 | preempt_enable_no_resched(); |
58 | schedule(); | 66 | schedule(); |
59 | preempt_disable(); | 67 | preempt_disable(); |
@@ -177,6 +185,17 @@ int copy_thread(int nr, unsigned long clone_flags, unsigned long usp, | |||
177 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); | 185 | childregs->cp0_status &= ~(ST0_CU2|ST0_CU1); |
178 | clear_tsk_thread_flag(p, TIF_USEDFPU); | 186 | clear_tsk_thread_flag(p, TIF_USEDFPU); |
179 | 187 | ||
188 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
189 | /* | ||
190 | * FPU affinity support is cleaner if we track the | ||
191 | * user-visible CPU affinity from the very beginning. | ||
192 | * The generic cpus_allowed mask will already have | ||
193 | * been copied from the parent before copy_thread | ||
194 | * is invoked. | ||
195 | */ | ||
196 | p->thread.user_cpus_allowed = p->cpus_allowed; | ||
197 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
198 | |||
180 | if (clone_flags & CLONE_SETTLS) | 199 | if (clone_flags & CLONE_SETTLS) |
181 | ti->tp_value = regs->regs[7]; | 200 | ti->tp_value = regs->regs[7]; |
182 | 201 | ||
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c index f838b36cc765..f3106d0771b0 100644 --- a/arch/mips/kernel/ptrace.c +++ b/arch/mips/kernel/ptrace.c | |||
@@ -248,10 +248,20 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
248 | break; | 248 | break; |
249 | case FPC_EIR: { /* implementation / version register */ | 249 | case FPC_EIR: { /* implementation / version register */ |
250 | unsigned int flags; | 250 | unsigned int flags; |
251 | #ifdef CONFIG_MIPS_MT_SMTC | ||
252 | unsigned int irqflags; | ||
253 | unsigned int mtflags; | ||
254 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
251 | 255 | ||
252 | if (!cpu_has_fpu) | 256 | if (!cpu_has_fpu) |
253 | break; | 257 | break; |
254 | 258 | ||
259 | #ifdef CONFIG_MIPS_MT_SMTC | ||
260 | /* Read-modify-write of Status must be atomic */ | ||
261 | local_irq_save(irqflags); | ||
262 | mtflags = dmt(); | ||
263 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
264 | |||
255 | preempt_disable(); | 265 | preempt_disable(); |
256 | if (cpu_has_mipsmt) { | 266 | if (cpu_has_mipsmt) { |
257 | unsigned int vpflags = dvpe(); | 267 | unsigned int vpflags = dvpe(); |
@@ -266,6 +276,10 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) | |||
266 | __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); | 276 | __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); |
267 | write_c0_status(flags); | 277 | write_c0_status(flags); |
268 | } | 278 | } |
279 | #ifdef CONFIG_MIPS_MT_SMTC | ||
280 | emt(mtflags); | ||
281 | local_irq_restore(irqflags); | ||
282 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
269 | preempt_enable(); | 283 | preempt_enable(); |
270 | break; | 284 | break; |
271 | } | 285 | } |
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c index 0d5cf97af727..8704dc0496ea 100644 --- a/arch/mips/kernel/ptrace32.c +++ b/arch/mips/kernel/ptrace32.c | |||
@@ -173,12 +173,22 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
173 | break; | 173 | break; |
174 | case FPC_EIR: { /* implementation / version register */ | 174 | case FPC_EIR: { /* implementation / version register */ |
175 | unsigned int flags; | 175 | unsigned int flags; |
176 | #ifdef CONFIG_MIPS_MT_SMTC | ||
177 | unsigned int irqflags; | ||
178 | unsigned int mtflags; | ||
179 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
176 | 180 | ||
177 | if (!cpu_has_fpu) { | 181 | if (!cpu_has_fpu) { |
178 | tmp = 0; | 182 | tmp = 0; |
179 | break; | 183 | break; |
180 | } | 184 | } |
181 | 185 | ||
186 | #ifdef CONFIG_MIPS_MT_SMTC | ||
187 | /* Read-modify-write of Status must be atomic */ | ||
188 | local_irq_save(irqflags); | ||
189 | mtflags = dmt(); | ||
190 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
191 | |||
182 | preempt_disable(); | 192 | preempt_disable(); |
183 | if (cpu_has_mipsmt) { | 193 | if (cpu_has_mipsmt) { |
184 | unsigned int vpflags = dvpe(); | 194 | unsigned int vpflags = dvpe(); |
@@ -193,6 +203,10 @@ asmlinkage int sys32_ptrace(int request, int pid, int addr, int data) | |||
193 | __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); | 203 | __asm__ __volatile__("cfc1\t%0,$0": "=r" (tmp)); |
194 | write_c0_status(flags); | 204 | write_c0_status(flags); |
195 | } | 205 | } |
206 | #ifdef CONFIG_MIPS_MT_SMTC | ||
207 | emt(mtflags); | ||
208 | local_irq_restore(irqflags); | ||
209 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
196 | preempt_enable(); | 210 | preempt_enable(); |
197 | break; | 211 | break; |
198 | } | 212 | } |
diff --git a/arch/mips/kernel/r4k_switch.S b/arch/mips/kernel/r4k_switch.S index d2afbd19a9c8..0b1b54acee9f 100644 --- a/arch/mips/kernel/r4k_switch.S +++ b/arch/mips/kernel/r4k_switch.S | |||
@@ -88,7 +88,18 @@ | |||
88 | 88 | ||
89 | PTR_ADDIU t0, $28, _THREAD_SIZE - 32 | 89 | PTR_ADDIU t0, $28, _THREAD_SIZE - 32 |
90 | set_saved_sp t0, t1, t2 | 90 | set_saved_sp t0, t1, t2 |
91 | 91 | #ifdef CONFIG_MIPS_MT_SMTC | |
92 | /* Read-modify-writes of Status must be atomic on a VPE */ | ||
93 | mfc0 t2, CP0_TCSTATUS | ||
94 | ori t1, t2, TCSTATUS_IXMT | ||
95 | mtc0 t1, CP0_TCSTATUS | ||
96 | andi t2, t2, TCSTATUS_IXMT | ||
97 | ehb | ||
98 | DMT 8 # dmt t0 | ||
99 | move t1,ra | ||
100 | jal mips_ihb | ||
101 | move ra,t1 | ||
102 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
92 | mfc0 t1, CP0_STATUS /* Do we really need this? */ | 103 | mfc0 t1, CP0_STATUS /* Do we really need this? */ |
93 | li a3, 0xff01 | 104 | li a3, 0xff01 |
94 | and t1, a3 | 105 | and t1, a3 |
@@ -97,6 +108,18 @@ | |||
97 | and a2, a3 | 108 | and a2, a3 |
98 | or a2, t1 | 109 | or a2, t1 |
99 | mtc0 a2, CP0_STATUS | 110 | mtc0 a2, CP0_STATUS |
111 | #ifdef CONFIG_MIPS_MT_SMTC | ||
112 | ehb | ||
113 | andi t0, t0, VPECONTROL_TE | ||
114 | beqz t0, 1f | ||
115 | emt | ||
116 | 1: | ||
117 | mfc0 t1, CP0_TCSTATUS | ||
118 | xori t1, t1, TCSTATUS_IXMT | ||
119 | or t1, t1, t2 | ||
120 | mtc0 t1, CP0_TCSTATUS | ||
121 | ehb | ||
122 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
100 | move v0, a0 | 123 | move v0, a0 |
101 | jr ra | 124 | jr ra |
102 | END(resume) | 125 | END(resume) |
@@ -131,10 +154,19 @@ LEAF(_restore_fp) | |||
131 | #define FPU_DEFAULT 0x00000000 | 154 | #define FPU_DEFAULT 0x00000000 |
132 | 155 | ||
133 | LEAF(_init_fpu) | 156 | LEAF(_init_fpu) |
157 | #ifdef CONFIG_MIPS_MT_SMTC | ||
158 | /* Rather than manipulate per-VPE Status, set per-TC bit in TCStatus */ | ||
159 | mfc0 t0, CP0_TCSTATUS | ||
160 | /* Bit position is the same for Status, TCStatus */ | ||
161 | li t1, ST0_CU1 | ||
162 | or t0, t1 | ||
163 | mtc0 t0, CP0_TCSTATUS | ||
164 | #else /* Normal MIPS CU1 enable */ | ||
134 | mfc0 t0, CP0_STATUS | 165 | mfc0 t0, CP0_STATUS |
135 | li t1, ST0_CU1 | 166 | li t1, ST0_CU1 |
136 | or t0, t1 | 167 | or t0, t1 |
137 | mtc0 t0, CP0_STATUS | 168 | mtc0 t0, CP0_STATUS |
169 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
138 | fpu_enable_hazard | 170 | fpu_enable_hazard |
139 | 171 | ||
140 | li t1, FPU_DEFAULT | 172 | li t1, FPU_DEFAULT |
diff --git a/arch/mips/kernel/rtlx.c b/arch/mips/kernel/rtlx.c index 986a9cf23067..6179805af9f0 100644 --- a/arch/mips/kernel/rtlx.c +++ b/arch/mips/kernel/rtlx.c | |||
@@ -21,45 +21,44 @@ | |||
21 | #include <linux/module.h> | 21 | #include <linux/module.h> |
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <asm/uaccess.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/list.h> | ||
27 | #include <linux/vmalloc.h> | ||
28 | #include <linux/elf.h> | ||
29 | #include <linux/seq_file.h> | ||
30 | #include <linux/syscalls.h> | ||
31 | #include <linux/moduleloader.h> | ||
24 | #include <linux/interrupt.h> | 32 | #include <linux/interrupt.h> |
25 | #include <linux/irq.h> | ||
26 | #include <linux/poll.h> | 33 | #include <linux/poll.h> |
27 | #include <linux/sched.h> | 34 | #include <linux/sched.h> |
28 | #include <linux/wait.h> | 35 | #include <linux/wait.h> |
29 | |||
30 | #include <asm/mipsmtregs.h> | 36 | #include <asm/mipsmtregs.h> |
31 | #include <asm/bitops.h> | 37 | #include <asm/cacheflush.h> |
38 | #include <asm/atomic.h> | ||
32 | #include <asm/cpu.h> | 39 | #include <asm/cpu.h> |
33 | #include <asm/processor.h> | 40 | #include <asm/processor.h> |
41 | #include <asm/system.h> | ||
42 | #include <asm/vpe.h> | ||
34 | #include <asm/rtlx.h> | 43 | #include <asm/rtlx.h> |
35 | #include <asm/uaccess.h> | ||
36 | 44 | ||
37 | #define RTLX_TARG_VPE 1 | 45 | #define RTLX_TARG_VPE 1 |
38 | 46 | ||
39 | static struct rtlx_info *rtlx; | 47 | static struct rtlx_info *rtlx; |
40 | static int major; | 48 | static int major; |
41 | static char module_name[] = "rtlx"; | 49 | static char module_name[] = "rtlx"; |
42 | static struct irqaction irq; | ||
43 | static int irq_num; | ||
44 | |||
45 | static inline int spacefree(int read, int write, int size) | ||
46 | { | ||
47 | if (read == write) { | ||
48 | /* | ||
49 | * never fill the buffer completely, so indexes are always | ||
50 | * equal if empty and only empty, or !equal if data available | ||
51 | */ | ||
52 | return size - 1; | ||
53 | } | ||
54 | |||
55 | return ((read + size - write) % size) - 1; | ||
56 | } | ||
57 | 50 | ||
58 | static struct chan_waitqueues { | 51 | static struct chan_waitqueues { |
59 | wait_queue_head_t rt_queue; | 52 | wait_queue_head_t rt_queue; |
60 | wait_queue_head_t lx_queue; | 53 | wait_queue_head_t lx_queue; |
54 | int in_open; | ||
61 | } channel_wqs[RTLX_CHANNELS]; | 55 | } channel_wqs[RTLX_CHANNELS]; |
62 | 56 | ||
57 | static struct irqaction irq; | ||
58 | static int irq_num; | ||
59 | static struct vpe_notifications notify; | ||
60 | static int sp_stopping = 0; | ||
61 | |||
63 | extern void *vpe_get_shared(int index); | 62 | extern void *vpe_get_shared(int index); |
64 | 63 | ||
65 | static void rtlx_dispatch(struct pt_regs *regs) | 64 | static void rtlx_dispatch(struct pt_regs *regs) |
@@ -67,174 +66,298 @@ static void rtlx_dispatch(struct pt_regs *regs) | |||
67 | do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs); | 66 | do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ, regs); |
68 | } | 67 | } |
69 | 68 | ||
69 | |||
70 | /* Interrupt handler may be called before rtlx_init has otherwise had | ||
71 | a chance to run. | ||
72 | */ | ||
70 | static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 73 | static irqreturn_t rtlx_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
71 | { | 74 | { |
72 | int i; | 75 | int i; |
73 | 76 | ||
74 | for (i = 0; i < RTLX_CHANNELS; i++) { | 77 | for (i = 0; i < RTLX_CHANNELS; i++) { |
75 | struct rtlx_channel *chan = &rtlx->channel[i]; | 78 | wake_up(&channel_wqs[i].lx_queue); |
76 | 79 | wake_up(&channel_wqs[i].rt_queue); | |
77 | if (chan->lx_read != chan->lx_write) | ||
78 | wake_up_interruptible(&channel_wqs[i].lx_queue); | ||
79 | } | 80 | } |
80 | 81 | ||
81 | return IRQ_HANDLED; | 82 | return IRQ_HANDLED; |
82 | } | 83 | } |
83 | 84 | ||
84 | /* call when we have the address of the shared structure from the SP side. */ | 85 | static __attribute_used__ void dump_rtlx(void) |
85 | static int rtlx_init(struct rtlx_info *rtlxi) | ||
86 | { | 86 | { |
87 | int i; | 87 | int i; |
88 | 88 | ||
89 | if (rtlxi->id != RTLX_ID) { | 89 | printk("id 0x%lx state %d\n", rtlx->id, rtlx->state); |
90 | printk(KERN_WARNING "no valid RTLX id at 0x%p\n", rtlxi); | ||
91 | return -ENOEXEC; | ||
92 | } | ||
93 | 90 | ||
94 | /* initialise the wait queues */ | ||
95 | for (i = 0; i < RTLX_CHANNELS; i++) { | 91 | for (i = 0; i < RTLX_CHANNELS; i++) { |
96 | init_waitqueue_head(&channel_wqs[i].rt_queue); | 92 | struct rtlx_channel *chan = &rtlx->channel[i]; |
97 | init_waitqueue_head(&channel_wqs[i].lx_queue); | ||
98 | } | ||
99 | 93 | ||
100 | /* set up for interrupt handling */ | 94 | printk(" rt_state %d lx_state %d buffer_size %d\n", |
101 | memset(&irq, 0, sizeof(struct irqaction)); | 95 | chan->rt_state, chan->lx_state, chan->buffer_size); |
102 | 96 | ||
103 | if (cpu_has_vint) | 97 | printk(" rt_read %d rt_write %d\n", |
104 | set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); | 98 | chan->rt_read, chan->rt_write); |
105 | 99 | ||
106 | irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ; | 100 | printk(" lx_read %d lx_write %d\n", |
107 | irq.handler = rtlx_interrupt; | 101 | chan->lx_read, chan->lx_write); |
108 | irq.flags = SA_INTERRUPT; | 102 | |
109 | irq.name = "RTLX"; | 103 | printk(" rt_buffer <%s>\n", chan->rt_buffer); |
110 | irq.dev_id = rtlx; | 104 | printk(" lx_buffer <%s>\n", chan->lx_buffer); |
111 | setup_irq(irq_num, &irq); | 105 | } |
106 | } | ||
107 | |||
108 | /* call when we have the address of the shared structure from the SP side. */ | ||
109 | static int rtlx_init(struct rtlx_info *rtlxi) | ||
110 | { | ||
111 | if (rtlxi->id != RTLX_ID) { | ||
112 | printk(KERN_ERR "no valid RTLX id at 0x%p 0x%x\n", rtlxi, rtlxi->id); | ||
113 | return -ENOEXEC; | ||
114 | } | ||
112 | 115 | ||
113 | rtlx = rtlxi; | 116 | rtlx = rtlxi; |
114 | 117 | ||
115 | return 0; | 118 | return 0; |
116 | } | 119 | } |
117 | 120 | ||
118 | /* only allow one open process at a time to open each channel */ | 121 | /* notifications */ |
119 | static int rtlx_open(struct inode *inode, struct file *filp) | 122 | static void starting(int vpe) |
120 | { | 123 | { |
121 | int minor, ret; | 124 | int i; |
125 | sp_stopping = 0; | ||
126 | |||
127 | /* force a reload of rtlx */ | ||
128 | rtlx=NULL; | ||
129 | |||
130 | /* wake up any sleeping rtlx_open's */ | ||
131 | for (i = 0; i < RTLX_CHANNELS; i++) | ||
132 | wake_up_interruptible(&channel_wqs[i].lx_queue); | ||
133 | } | ||
134 | |||
135 | static void stopping(int vpe) | ||
136 | { | ||
137 | int i; | ||
138 | |||
139 | sp_stopping = 1; | ||
140 | for (i = 0; i < RTLX_CHANNELS; i++) | ||
141 | wake_up_interruptible(&channel_wqs[i].lx_queue); | ||
142 | } | ||
143 | |||
144 | |||
145 | int rtlx_open(int index, int can_sleep) | ||
146 | { | ||
147 | int ret; | ||
122 | struct rtlx_channel *chan; | 148 | struct rtlx_channel *chan; |
149 | volatile struct rtlx_info **p; | ||
123 | 150 | ||
124 | /* assume only 1 device at the mo. */ | 151 | if (index >= RTLX_CHANNELS) { |
125 | minor = MINOR(inode->i_rdev); | 152 | printk(KERN_DEBUG "rtlx_open index out of range\n"); |
153 | return -ENOSYS; | ||
154 | } | ||
155 | |||
156 | if (channel_wqs[index].in_open) { | ||
157 | printk(KERN_DEBUG "rtlx_open channel %d already opened\n", index); | ||
158 | return -EBUSY; | ||
159 | } | ||
160 | |||
161 | channel_wqs[index].in_open++; | ||
126 | 162 | ||
127 | if (rtlx == NULL) { | 163 | if (rtlx == NULL) { |
128 | struct rtlx_info **p; | ||
129 | if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { | 164 | if( (p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { |
130 | printk(KERN_ERR "vpe_get_shared is NULL. " | 165 | if (can_sleep) { |
131 | "Has an SP program been loaded?\n"); | 166 | DECLARE_WAITQUEUE(wait, current); |
132 | return -EFAULT; | 167 | |
168 | /* go to sleep */ | ||
169 | add_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
170 | |||
171 | set_current_state(TASK_INTERRUPTIBLE); | ||
172 | while ((p = vpe_get_shared(RTLX_TARG_VPE)) == NULL) { | ||
173 | schedule(); | ||
174 | set_current_state(TASK_INTERRUPTIBLE); | ||
175 | } | ||
176 | |||
177 | set_current_state(TASK_RUNNING); | ||
178 | remove_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
179 | |||
180 | /* back running */ | ||
181 | } else { | ||
182 | printk( KERN_DEBUG "No SP program loaded, and device " | ||
183 | "opened with O_NONBLOCK\n"); | ||
184 | channel_wqs[index].in_open = 0; | ||
185 | return -ENOSYS; | ||
186 | } | ||
133 | } | 187 | } |
134 | 188 | ||
135 | if (*p == NULL) { | 189 | if (*p == NULL) { |
136 | printk(KERN_ERR "vpe_shared %p %p\n", p, *p); | 190 | if (can_sleep) { |
137 | return -EFAULT; | 191 | DECLARE_WAITQUEUE(wait, current); |
192 | |||
193 | /* go to sleep */ | ||
194 | add_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
195 | |||
196 | set_current_state(TASK_INTERRUPTIBLE); | ||
197 | while (*p == NULL) { | ||
198 | schedule(); | ||
199 | |||
200 | /* reset task state to interruptable otherwise | ||
201 | we'll whizz round here like a very fast loopy | ||
202 | thing. schedule() appears to return with state | ||
203 | set to TASK_RUNNING. | ||
204 | |||
205 | If the loaded SP program, for whatever reason, | ||
206 | doesn't set up the shared structure *p will never | ||
207 | become true. So whoever connected to either /dev/rt? | ||
208 | or if it was kspd, will then take up rather a lot of | ||
209 | processor cycles. | ||
210 | */ | ||
211 | |||
212 | set_current_state(TASK_INTERRUPTIBLE); | ||
213 | } | ||
214 | |||
215 | set_current_state(TASK_RUNNING); | ||
216 | remove_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
217 | |||
218 | /* back running */ | ||
219 | } | ||
220 | else { | ||
221 | printk(" *vpe_get_shared is NULL. " | ||
222 | "Has an SP program been loaded?\n"); | ||
223 | channel_wqs[index].in_open = 0; | ||
224 | return -ENOSYS; | ||
225 | } | ||
226 | } | ||
227 | |||
228 | if ((unsigned int)*p < KSEG0) { | ||
229 | printk(KERN_WARNING "vpe_get_shared returned an invalid pointer " | ||
230 | "maybe an error code %d\n", (int)*p); | ||
231 | channel_wqs[index].in_open = 0; | ||
232 | return -ENOSYS; | ||
138 | } | 233 | } |
139 | 234 | ||
140 | if ((ret = rtlx_init(*p)) < 0) | 235 | if ((ret = rtlx_init(*p)) < 0) { |
141 | return ret; | 236 | channel_wqs[index].in_open = 0; |
237 | return ret; | ||
238 | } | ||
142 | } | 239 | } |
143 | 240 | ||
144 | chan = &rtlx->channel[minor]; | 241 | chan = &rtlx->channel[index]; |
145 | 242 | ||
146 | if (test_and_set_bit(RTLX_STATE_OPENED, &chan->lx_state)) | 243 | if (chan->lx_state == RTLX_STATE_OPENED) { |
147 | return -EBUSY; | 244 | channel_wqs[index].in_open = 0; |
245 | return -EBUSY; | ||
246 | } | ||
148 | 247 | ||
248 | chan->lx_state = RTLX_STATE_OPENED; | ||
249 | channel_wqs[index].in_open = 0; | ||
149 | return 0; | 250 | return 0; |
150 | } | 251 | } |
151 | 252 | ||
152 | static int rtlx_release(struct inode *inode, struct file *filp) | 253 | int rtlx_release(int index) |
153 | { | 254 | { |
154 | int minor = MINOR(inode->i_rdev); | 255 | rtlx->channel[index].lx_state = RTLX_STATE_UNUSED; |
155 | |||
156 | clear_bit(RTLX_STATE_OPENED, &rtlx->channel[minor].lx_state); | ||
157 | smp_mb__after_clear_bit(); | ||
158 | |||
159 | return 0; | 256 | return 0; |
160 | } | 257 | } |
161 | 258 | ||
162 | static unsigned int rtlx_poll(struct file *file, poll_table * wait) | 259 | unsigned int rtlx_read_poll(int index, int can_sleep) |
163 | { | 260 | { |
164 | int minor; | 261 | struct rtlx_channel *chan; |
165 | unsigned int mask = 0; | ||
166 | struct rtlx_channel *chan; | ||
167 | 262 | ||
168 | minor = MINOR(file->f_dentry->d_inode->i_rdev); | 263 | if (rtlx == NULL) |
169 | chan = &rtlx->channel[minor]; | 264 | return 0; |
170 | 265 | ||
171 | poll_wait(file, &channel_wqs[minor].rt_queue, wait); | 266 | chan = &rtlx->channel[index]; |
172 | poll_wait(file, &channel_wqs[minor].lx_queue, wait); | ||
173 | 267 | ||
174 | /* data available to read? */ | 268 | /* data available to read? */ |
175 | if (chan->lx_read != chan->lx_write) | 269 | if (chan->lx_read == chan->lx_write) { |
176 | mask |= POLLIN | POLLRDNORM; | 270 | if (can_sleep) { |
271 | DECLARE_WAITQUEUE(wait, current); | ||
177 | 272 | ||
178 | /* space to write */ | 273 | /* go to sleep */ |
179 | if (spacefree(chan->rt_read, chan->rt_write, chan->buffer_size)) | 274 | add_wait_queue(&channel_wqs[index].lx_queue, &wait); |
180 | mask |= POLLOUT | POLLWRNORM; | ||
181 | 275 | ||
182 | return mask; | 276 | set_current_state(TASK_INTERRUPTIBLE); |
277 | while (chan->lx_read == chan->lx_write) { | ||
278 | schedule(); | ||
279 | |||
280 | set_current_state(TASK_INTERRUPTIBLE); | ||
281 | |||
282 | if (sp_stopping) { | ||
283 | set_current_state(TASK_RUNNING); | ||
284 | remove_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
285 | return 0; | ||
286 | } | ||
287 | } | ||
288 | |||
289 | set_current_state(TASK_RUNNING); | ||
290 | remove_wait_queue(&channel_wqs[index].lx_queue, &wait); | ||
291 | |||
292 | /* back running */ | ||
293 | } | ||
294 | else | ||
295 | return 0; | ||
296 | } | ||
297 | |||
298 | return (chan->lx_write + chan->buffer_size - chan->lx_read) | ||
299 | % chan->buffer_size; | ||
183 | } | 300 | } |
184 | 301 | ||
185 | static ssize_t rtlx_read(struct file *file, char __user * buffer, size_t count, | 302 | static inline int write_spacefree(int read, int write, int size) |
186 | loff_t * ppos) | ||
187 | { | 303 | { |
188 | unsigned long failed; | 304 | if (read == write) { |
189 | size_t fl = 0L; | 305 | /* |
190 | int minor; | 306 | * Never fill the buffer completely, so indexes are always |
191 | struct rtlx_channel *lx; | 307 | * equal if empty and only empty, or !equal if data available |
192 | DECLARE_WAITQUEUE(wait, current); | 308 | */ |
309 | return size - 1; | ||
310 | } | ||
193 | 311 | ||
194 | minor = MINOR(file->f_dentry->d_inode->i_rdev); | 312 | return ((read + size - write) % size) - 1; |
195 | lx = &rtlx->channel[minor]; | 313 | } |
196 | 314 | ||
197 | /* data available? */ | 315 | unsigned int rtlx_write_poll(int index) |
198 | if (lx->lx_write == lx->lx_read) { | 316 | { |
199 | if (file->f_flags & O_NONBLOCK) | 317 | struct rtlx_channel *chan = &rtlx->channel[index]; |
200 | return 0; /* -EAGAIN makes cat whinge */ | 318 | return write_spacefree(chan->rt_read, chan->rt_write, chan->buffer_size); |
319 | } | ||
201 | 320 | ||
202 | /* go to sleep */ | 321 | static inline void copy_to(void *dst, void *src, size_t count, int user) |
203 | add_wait_queue(&channel_wqs[minor].lx_queue, &wait); | 322 | { |
204 | set_current_state(TASK_INTERRUPTIBLE); | 323 | if (user) |
324 | copy_to_user(dst, src, count); | ||
325 | else | ||
326 | memcpy(dst, src, count); | ||
327 | } | ||
205 | 328 | ||
206 | while (lx->lx_write == lx->lx_read) | 329 | static inline void copy_from(void *dst, void *src, size_t count, int user) |
207 | schedule(); | 330 | { |
331 | if (user) | ||
332 | copy_from_user(dst, src, count); | ||
333 | else | ||
334 | memcpy(dst, src, count); | ||
335 | } | ||
208 | 336 | ||
209 | set_current_state(TASK_RUNNING); | 337 | ssize_t rtlx_read(int index, void *buff, size_t count, int user) |
210 | remove_wait_queue(&channel_wqs[minor].lx_queue, &wait); | 338 | { |
339 | size_t fl = 0L; | ||
340 | struct rtlx_channel *lx; | ||
211 | 341 | ||
212 | /* back running */ | 342 | if (rtlx == NULL) |
213 | } | 343 | return -ENOSYS; |
344 | |||
345 | lx = &rtlx->channel[index]; | ||
214 | 346 | ||
215 | /* find out how much in total */ | 347 | /* find out how much in total */ |
216 | count = min(count, | 348 | count = min(count, |
217 | (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) % lx->buffer_size); | 349 | (size_t)(lx->lx_write + lx->buffer_size - lx->lx_read) |
350 | % lx->buffer_size); | ||
218 | 351 | ||
219 | /* then how much from the read pointer onwards */ | 352 | /* then how much from the read pointer onwards */ |
220 | fl = min(count, (size_t)lx->buffer_size - lx->lx_read); | 353 | fl = min( count, (size_t)lx->buffer_size - lx->lx_read); |
221 | 354 | ||
222 | failed = copy_to_user (buffer, &lx->lx_buffer[lx->lx_read], fl); | 355 | copy_to(buff, &lx->lx_buffer[lx->lx_read], fl, user); |
223 | if (failed) { | ||
224 | count = fl - failed; | ||
225 | goto out; | ||
226 | } | ||
227 | 356 | ||
228 | /* and if there is anything left at the beginning of the buffer */ | 357 | /* and if there is anything left at the beginning of the buffer */ |
229 | if (count - fl) { | 358 | if ( count - fl ) |
230 | failed = copy_to_user (buffer + fl, lx->lx_buffer, count - fl); | 359 | copy_to (buff + fl, lx->lx_buffer, count - fl, user); |
231 | if (failed) { | ||
232 | count -= failed; | ||
233 | goto out; | ||
234 | } | ||
235 | } | ||
236 | 360 | ||
237 | out: | ||
238 | /* update the index */ | 361 | /* update the index */ |
239 | lx->lx_read += count; | 362 | lx->lx_read += count; |
240 | lx->lx_read %= lx->buffer_size; | 363 | lx->lx_read %= lx->buffer_size; |
@@ -242,20 +365,101 @@ out: | |||
242 | return count; | 365 | return count; |
243 | } | 366 | } |
244 | 367 | ||
245 | static ssize_t rtlx_write(struct file *file, const char __user * buffer, | 368 | ssize_t rtlx_write(int index, void *buffer, size_t count, int user) |
369 | { | ||
370 | struct rtlx_channel *rt; | ||
371 | size_t fl; | ||
372 | |||
373 | if (rtlx == NULL) | ||
374 | return(-ENOSYS); | ||
375 | |||
376 | rt = &rtlx->channel[index]; | ||
377 | |||
378 | /* total number of bytes to copy */ | ||
379 | count = min(count, | ||
380 | (size_t)write_spacefree(rt->rt_read, rt->rt_write, | ||
381 | rt->buffer_size)); | ||
382 | |||
383 | /* first bit from write pointer to the end of the buffer, or count */ | ||
384 | fl = min(count, (size_t) rt->buffer_size - rt->rt_write); | ||
385 | |||
386 | copy_from (&rt->rt_buffer[rt->rt_write], buffer, fl, user); | ||
387 | |||
388 | /* if there's any left copy to the beginning of the buffer */ | ||
389 | if( count - fl ) | ||
390 | copy_from (rt->rt_buffer, buffer + fl, count - fl, user); | ||
391 | |||
392 | rt->rt_write += count; | ||
393 | rt->rt_write %= rt->buffer_size; | ||
394 | |||
395 | return(count); | ||
396 | } | ||
397 | |||
398 | |||
399 | static int file_open(struct inode *inode, struct file *filp) | ||
400 | { | ||
401 | int minor = MINOR(inode->i_rdev); | ||
402 | |||
403 | return rtlx_open(minor, (filp->f_flags & O_NONBLOCK) ? 0 : 1); | ||
404 | } | ||
405 | |||
406 | static int file_release(struct inode *inode, struct file *filp) | ||
407 | { | ||
408 | int minor; | ||
409 | minor = MINOR(inode->i_rdev); | ||
410 | |||
411 | return rtlx_release(minor); | ||
412 | } | ||
413 | |||
414 | static unsigned int file_poll(struct file *file, poll_table * wait) | ||
415 | { | ||
416 | int minor; | ||
417 | unsigned int mask = 0; | ||
418 | |||
419 | minor = MINOR(file->f_dentry->d_inode->i_rdev); | ||
420 | |||
421 | poll_wait(file, &channel_wqs[minor].rt_queue, wait); | ||
422 | poll_wait(file, &channel_wqs[minor].lx_queue, wait); | ||
423 | |||
424 | if (rtlx == NULL) | ||
425 | return 0; | ||
426 | |||
427 | /* data available to read? */ | ||
428 | if (rtlx_read_poll(minor, 0)) | ||
429 | mask |= POLLIN | POLLRDNORM; | ||
430 | |||
431 | /* space to write */ | ||
432 | if (rtlx_write_poll(minor)) | ||
433 | mask |= POLLOUT | POLLWRNORM; | ||
434 | |||
435 | return mask; | ||
436 | } | ||
437 | |||
438 | static ssize_t file_read(struct file *file, char __user * buffer, size_t count, | ||
439 | loff_t * ppos) | ||
440 | { | ||
441 | int minor = MINOR(file->f_dentry->d_inode->i_rdev); | ||
442 | |||
443 | /* data available? */ | ||
444 | if (!rtlx_read_poll(minor, (file->f_flags & O_NONBLOCK) ? 0 : 1)) { | ||
445 | return 0; // -EAGAIN makes cat whinge | ||
446 | } | ||
447 | |||
448 | return rtlx_read(minor, buffer, count, 1); | ||
449 | } | ||
450 | |||
451 | static ssize_t file_write(struct file *file, const char __user * buffer, | ||
246 | size_t count, loff_t * ppos) | 452 | size_t count, loff_t * ppos) |
247 | { | 453 | { |
248 | unsigned long failed; | ||
249 | int minor; | 454 | int minor; |
250 | struct rtlx_channel *rt; | 455 | struct rtlx_channel *rt; |
251 | size_t fl; | ||
252 | DECLARE_WAITQUEUE(wait, current); | 456 | DECLARE_WAITQUEUE(wait, current); |
253 | 457 | ||
254 | minor = MINOR(file->f_dentry->d_inode->i_rdev); | 458 | minor = MINOR(file->f_dentry->d_inode->i_rdev); |
255 | rt = &rtlx->channel[minor]; | 459 | rt = &rtlx->channel[minor]; |
256 | 460 | ||
257 | /* any space left... */ | 461 | /* any space left... */ |
258 | if (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) { | 462 | if (!rtlx_write_poll(minor)) { |
259 | 463 | ||
260 | if (file->f_flags & O_NONBLOCK) | 464 | if (file->f_flags & O_NONBLOCK) |
261 | return -EAGAIN; | 465 | return -EAGAIN; |
@@ -263,61 +467,64 @@ static ssize_t rtlx_write(struct file *file, const char __user * buffer, | |||
263 | add_wait_queue(&channel_wqs[minor].rt_queue, &wait); | 467 | add_wait_queue(&channel_wqs[minor].rt_queue, &wait); |
264 | set_current_state(TASK_INTERRUPTIBLE); | 468 | set_current_state(TASK_INTERRUPTIBLE); |
265 | 469 | ||
266 | while (!spacefree(rt->rt_read, rt->rt_write, rt->buffer_size)) | 470 | while (!rtlx_write_poll(minor)) |
267 | schedule(); | 471 | schedule(); |
268 | 472 | ||
269 | set_current_state(TASK_RUNNING); | 473 | set_current_state(TASK_RUNNING); |
270 | remove_wait_queue(&channel_wqs[minor].rt_queue, &wait); | 474 | remove_wait_queue(&channel_wqs[minor].rt_queue, &wait); |
271 | } | 475 | } |
272 | 476 | ||
273 | /* total number of bytes to copy */ | 477 | return rtlx_write(minor, (void *)buffer, count, 1); |
274 | count = min(count, (size_t)spacefree(rt->rt_read, rt->rt_write, rt->buffer_size) ); | ||
275 | |||
276 | /* first bit from write pointer to the end of the buffer, or count */ | ||
277 | fl = min(count, (size_t) rt->buffer_size - rt->rt_write); | ||
278 | |||
279 | failed = copy_from_user(&rt->rt_buffer[rt->rt_write], buffer, fl); | ||
280 | if (failed) { | ||
281 | count = fl - failed; | ||
282 | goto out; | ||
283 | } | ||
284 | |||
285 | /* if there's any left copy to the beginning of the buffer */ | ||
286 | if (count - fl) { | ||
287 | failed = copy_from_user(rt->rt_buffer, buffer + fl, count - fl); | ||
288 | if (failed) { | ||
289 | count -= failed; | ||
290 | goto out; | ||
291 | } | ||
292 | } | ||
293 | |||
294 | out: | ||
295 | rt->rt_write += count; | ||
296 | rt->rt_write %= rt->buffer_size; | ||
297 | |||
298 | return count; | ||
299 | } | 478 | } |
300 | 479 | ||
301 | static struct file_operations rtlx_fops = { | 480 | static struct file_operations rtlx_fops = { |
302 | .owner = THIS_MODULE, | 481 | .owner = THIS_MODULE, |
303 | .open = rtlx_open, | 482 | .open = file_open, |
304 | .release = rtlx_release, | 483 | .release = file_release, |
305 | .write = rtlx_write, | 484 | .write = file_write, |
306 | .read = rtlx_read, | 485 | .read = file_read, |
307 | .poll = rtlx_poll | 486 | .poll = file_poll |
308 | }; | 487 | }; |
309 | 488 | ||
489 | static struct irqaction rtlx_irq = { | ||
490 | .handler = rtlx_interrupt, | ||
491 | .flags = SA_INTERRUPT, | ||
492 | .name = "RTLX", | ||
493 | }; | ||
494 | |||
495 | static int rtlx_irq_num = MIPSCPU_INT_BASE + MIPS_CPU_RTLX_IRQ; | ||
496 | |||
310 | static char register_chrdev_failed[] __initdata = | 497 | static char register_chrdev_failed[] __initdata = |
311 | KERN_ERR "rtlx_module_init: unable to register device\n"; | 498 | KERN_ERR "rtlx_module_init: unable to register device\n"; |
312 | 499 | ||
313 | static int __init rtlx_module_init(void) | 500 | static int rtlx_module_init(void) |
314 | { | 501 | { |
502 | int i; | ||
503 | |||
315 | major = register_chrdev(0, module_name, &rtlx_fops); | 504 | major = register_chrdev(0, module_name, &rtlx_fops); |
316 | if (major < 0) { | 505 | if (major < 0) { |
317 | printk(register_chrdev_failed); | 506 | printk(register_chrdev_failed); |
318 | return major; | 507 | return major; |
319 | } | 508 | } |
320 | 509 | ||
510 | /* initialise the wait queues */ | ||
511 | for (i = 0; i < RTLX_CHANNELS; i++) { | ||
512 | init_waitqueue_head(&channel_wqs[i].rt_queue); | ||
513 | init_waitqueue_head(&channel_wqs[i].lx_queue); | ||
514 | channel_wqs[i].in_open = 0; | ||
515 | } | ||
516 | |||
517 | /* set up notifiers */ | ||
518 | notify.start = starting; | ||
519 | notify.stop = stopping; | ||
520 | vpe_notify(RTLX_TARG_VPE, ¬ify); | ||
521 | |||
522 | if (cpu_has_vint) | ||
523 | set_vi_handler(MIPS_CPU_RTLX_IRQ, rtlx_dispatch); | ||
524 | |||
525 | rtlx_irq.dev_id = rtlx; | ||
526 | setup_irq(rtlx_irq_num, &rtlx_irq); | ||
527 | |||
321 | return 0; | 528 | return 0; |
322 | } | 529 | } |
323 | 530 | ||
@@ -330,5 +537,5 @@ module_init(rtlx_module_init); | |||
330 | module_exit(rtlx_module_exit); | 537 | module_exit(rtlx_module_exit); |
331 | 538 | ||
332 | MODULE_DESCRIPTION("MIPS RTLX"); | 539 | MODULE_DESCRIPTION("MIPS RTLX"); |
333 | MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc."); | 540 | MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc."); |
334 | MODULE_LICENSE("GPL"); | 541 | MODULE_LICENSE("GPL"); |
diff --git a/arch/mips/kernel/scall32-o32.S b/arch/mips/kernel/scall32-o32.S index 2f2dc54b2e26..a0ac0e5f61ad 100644 --- a/arch/mips/kernel/scall32-o32.S +++ b/arch/mips/kernel/scall32-o32.S | |||
@@ -569,8 +569,19 @@ einval: li v0, -EINVAL | |||
569 | sys sys_tkill 2 | 569 | sys sys_tkill 2 |
570 | sys sys_sendfile64 5 | 570 | sys sys_sendfile64 5 |
571 | sys sys_futex 6 | 571 | sys sys_futex 6 |
572 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
573 | /* | ||
574 | * For FPU affinity scheduling on MIPS MT processors, we need to | ||
575 | * intercept sys_sched_xxxaffinity() calls until we get a proper hook | ||
576 | * in kernel/sched.c. Considered only temporary we only support these | ||
577 | * hooks for the 32-bit kernel - there is no MIPS64 MT processor atm. | ||
578 | */ | ||
579 | sys mipsmt_sys_sched_setaffinity 3 | ||
580 | sys mipsmt_sys_sched_getaffinity 3 | ||
581 | #else | ||
572 | sys sys_sched_setaffinity 3 | 582 | sys sys_sched_setaffinity 3 |
573 | sys sys_sched_getaffinity 3 /* 4240 */ | 583 | sys sys_sched_getaffinity 3 /* 4240 */ |
584 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
574 | sys sys_io_setup 2 | 585 | sys sys_io_setup 2 |
575 | sys sys_io_destroy 1 | 586 | sys sys_io_destroy 1 |
576 | sys sys_io_getevents 5 | 587 | sys sys_io_getevents 5 |
@@ -634,6 +645,8 @@ einval: li v0, -EINVAL | |||
634 | sys sys_pselect6 6 | 645 | sys sys_pselect6 6 |
635 | sys sys_ppoll 5 | 646 | sys sys_ppoll 5 |
636 | sys sys_unshare 1 | 647 | sys sys_unshare 1 |
648 | sys sys_splice 4 | ||
649 | sys sys_sync_file_range 7 /* 4305 */ | ||
637 | .endm | 650 | .endm |
638 | 651 | ||
639 | /* We pre-compute the number of _instruction_ bytes needed to | 652 | /* We pre-compute the number of _instruction_ bytes needed to |
diff --git a/arch/mips/kernel/scall64-64.S b/arch/mips/kernel/scall64-64.S index 98bf25df56f3..9ba750887377 100644 --- a/arch/mips/kernel/scall64-64.S +++ b/arch/mips/kernel/scall64-64.S | |||
@@ -460,3 +460,5 @@ sys_call_table: | |||
460 | PTR sys_pselect6 /* 5260 */ | 460 | PTR sys_pselect6 /* 5260 */ |
461 | PTR sys_ppoll | 461 | PTR sys_ppoll |
462 | PTR sys_unshare | 462 | PTR sys_unshare |
463 | PTR sys_splice | ||
464 | PTR sys_sync_file_range | ||
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S index 05a2c0567dae..942aca26f9c4 100644 --- a/arch/mips/kernel/scall64-n32.S +++ b/arch/mips/kernel/scall64-n32.S | |||
@@ -386,3 +386,5 @@ EXPORT(sysn32_call_table) | |||
386 | PTR sys_pselect6 | 386 | PTR sys_pselect6 |
387 | PTR sys_ppoll /* 6265 */ | 387 | PTR sys_ppoll /* 6265 */ |
388 | PTR sys_unshare | 388 | PTR sys_unshare |
389 | PTR sys_splice | ||
390 | PTR sys_sync_file_range | ||
diff --git a/arch/mips/kernel/scall64-o32.S b/arch/mips/kernel/scall64-o32.S index 19c4ca481b02..b53a9207f530 100644 --- a/arch/mips/kernel/scall64-o32.S +++ b/arch/mips/kernel/scall64-o32.S | |||
@@ -508,4 +508,6 @@ sys_call_table: | |||
508 | PTR sys_pselect6 | 508 | PTR sys_pselect6 |
509 | PTR sys_ppoll | 509 | PTR sys_ppoll |
510 | PTR sys_unshare | 510 | PTR sys_unshare |
511 | PTR sys_splice | ||
512 | PTR sys32_sync_file_range /* 4305 */ | ||
511 | .size sys_call_table,.-sys_call_table | 513 | .size sys_call_table,.-sys_call_table |
diff --git a/arch/mips/kernel/setup.c b/arch/mips/kernel/setup.c index dcbfd27071f0..bcf1b10e518f 100644 --- a/arch/mips/kernel/setup.c +++ b/arch/mips/kernel/setup.c | |||
@@ -529,7 +529,10 @@ void __init setup_arch(char **cmdline_p) | |||
529 | 529 | ||
530 | int __init fpu_disable(char *s) | 530 | int __init fpu_disable(char *s) |
531 | { | 531 | { |
532 | cpu_data[0].options &= ~MIPS_CPU_FPU; | 532 | int i; |
533 | |||
534 | for (i = 0; i < NR_CPUS; i++) | ||
535 | cpu_data[i].options &= ~MIPS_CPU_FPU; | ||
533 | 536 | ||
534 | return 1; | 537 | return 1; |
535 | } | 538 | } |
diff --git a/arch/mips/kernel/smp_mt.c b/arch/mips/kernel/smp-mt.c index 993b8bf56aaf..57770902b9ae 100644 --- a/arch/mips/kernel/smp_mt.c +++ b/arch/mips/kernel/smp-mt.c | |||
@@ -1,8 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2004, 2005 MIPS Technologies, Inc. All rights reserved. | ||
3 | * | ||
4 | * Elizabeth Clarke (beth@mips.com) | ||
5 | * | ||
6 | * This program is free software; you can distribute it and/or modify it | 2 | * This program is free software; you can distribute it and/or modify it |
7 | * under the terms of the GNU General Public License (Version 2) as | 3 | * under the terms of the GNU General Public License (Version 2) as |
8 | * published by the Free Software Foundation. | 4 | * published by the Free Software Foundation. |
@@ -16,6 +12,10 @@ | |||
16 | * with this program; if not, write to the Free Software Foundation, Inc., | 12 | * with this program; if not, write to the Free Software Foundation, Inc., |
17 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 13 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
18 | * | 14 | * |
15 | * Copyright (C) 2004, 05, 06 MIPS Technologies, Inc. | ||
16 | * Elizabeth Clarke (beth@mips.com) | ||
17 | * Ralf Baechle (ralf@linux-mips.org) | ||
18 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | ||
19 | */ | 19 | */ |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/sched.h> | 21 | #include <linux/sched.h> |
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/compiler.h> | 24 | #include <linux/compiler.h> |
25 | 25 | ||
26 | #include <asm/atomic.h> | 26 | #include <asm/atomic.h> |
27 | #include <asm/cacheflush.h> | ||
27 | #include <asm/cpu.h> | 28 | #include <asm/cpu.h> |
28 | #include <asm/processor.h> | 29 | #include <asm/processor.h> |
29 | #include <asm/system.h> | 30 | #include <asm/system.h> |
@@ -33,8 +34,8 @@ | |||
33 | #include <asm/time.h> | 34 | #include <asm/time.h> |
34 | #include <asm/mipsregs.h> | 35 | #include <asm/mipsregs.h> |
35 | #include <asm/mipsmtregs.h> | 36 | #include <asm/mipsmtregs.h> |
36 | #include <asm/cacheflush.h> | 37 | #include <asm/mips_mt.h> |
37 | #include <asm/mips-boards/maltaint.h> | 38 | #include <asm/mips-boards/maltaint.h> /* This is f*cking wrong */ |
38 | 39 | ||
39 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 | 40 | #define MIPS_CPU_IPI_RESCHED_IRQ 0 |
40 | #define MIPS_CPU_IPI_CALL_IRQ 1 | 41 | #define MIPS_CPU_IPI_CALL_IRQ 1 |
@@ -66,6 +67,7 @@ void __init sanitize_tlb_entries(void) | |||
66 | if (!cpu_has_mipsmt) | 67 | if (!cpu_has_mipsmt) |
67 | return; | 68 | return; |
68 | 69 | ||
70 | /* Enable VPC */ | ||
69 | set_c0_mvpcontrol(MVPCONTROL_VPC); | 71 | set_c0_mvpcontrol(MVPCONTROL_VPC); |
70 | 72 | ||
71 | back_to_back_c0_hazard(); | 73 | back_to_back_c0_hazard(); |
@@ -106,12 +108,12 @@ void __init sanitize_tlb_entries(void) | |||
106 | 108 | ||
107 | static void ipi_resched_dispatch (struct pt_regs *regs) | 109 | static void ipi_resched_dispatch (struct pt_regs *regs) |
108 | { | 110 | { |
109 | do_IRQ(MIPS_CPU_IPI_RESCHED_IRQ, regs); | 111 | do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ, regs); |
110 | } | 112 | } |
111 | 113 | ||
112 | static void ipi_call_dispatch (struct pt_regs *regs) | 114 | static void ipi_call_dispatch (struct pt_regs *regs) |
113 | { | 115 | { |
114 | do_IRQ(MIPS_CPU_IPI_CALL_IRQ, regs); | 116 | do_IRQ(MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ, regs); |
115 | } | 117 | } |
116 | 118 | ||
117 | irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 119 | irqreturn_t ipi_resched_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
@@ -148,6 +150,11 @@ void plat_smp_setup(void) | |||
148 | unsigned long val; | 150 | unsigned long val; |
149 | int i, num; | 151 | int i, num; |
150 | 152 | ||
153 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
154 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | ||
155 | if (cpu_has_fpu) | ||
156 | cpu_set(0, mt_fpu_cpumask); | ||
157 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
151 | if (!cpu_has_mipsmt) | 158 | if (!cpu_has_mipsmt) |
152 | return; | 159 | return; |
153 | 160 | ||
@@ -155,6 +162,8 @@ void plat_smp_setup(void) | |||
155 | dvpe(); | 162 | dvpe(); |
156 | dmt(); | 163 | dmt(); |
157 | 164 | ||
165 | mips_mt_set_cpuoptions(); | ||
166 | |||
158 | /* Put MVPE's into 'configuration state' */ | 167 | /* Put MVPE's into 'configuration state' */ |
159 | set_c0_mvpcontrol(MVPCONTROL_VPC); | 168 | set_c0_mvpcontrol(MVPCONTROL_VPC); |
160 | 169 | ||
@@ -189,11 +198,13 @@ void plat_smp_setup(void) | |||
189 | 198 | ||
190 | if (i != 0) { | 199 | if (i != 0) { |
191 | write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); | 200 | write_vpe_c0_status((read_c0_status() & ~(ST0_IM | ST0_IE | ST0_KSU)) | ST0_CU0); |
192 | write_vpe_c0_cause(read_vpe_c0_cause() & ~CAUSEF_IP); | ||
193 | 201 | ||
194 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ | 202 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ |
195 | write_vpe_c0_config( read_c0_config()); | 203 | write_vpe_c0_config( read_c0_config()); |
196 | 204 | ||
205 | /* make sure there are no software interrupts pending */ | ||
206 | write_vpe_c0_cause(read_vpe_c0_cause() & ~(C_SW1|C_SW0)); | ||
207 | |||
197 | /* Propagate Config7 */ | 208 | /* Propagate Config7 */ |
198 | write_vpe_c0_config7(read_c0_config7()); | 209 | write_vpe_c0_config7(read_c0_config7()); |
199 | } | 210 | } |
@@ -233,16 +244,16 @@ void plat_smp_setup(void) | |||
233 | /* We'll wait until starting the secondaries before starting MVPE */ | 244 | /* We'll wait until starting the secondaries before starting MVPE */ |
234 | 245 | ||
235 | printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); | 246 | printk(KERN_INFO "Detected %i available secondary CPU(s)\n", num); |
247 | } | ||
236 | 248 | ||
249 | void __init plat_prepare_cpus(unsigned int max_cpus) | ||
250 | { | ||
237 | /* set up ipi interrupts */ | 251 | /* set up ipi interrupts */ |
238 | if (cpu_has_vint) { | 252 | if (cpu_has_vint) { |
239 | set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); | 253 | set_vi_handler (MIPS_CPU_IPI_RESCHED_IRQ, ipi_resched_dispatch); |
240 | set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); | 254 | set_vi_handler (MIPS_CPU_IPI_CALL_IRQ, ipi_call_dispatch); |
241 | } | 255 | } |
242 | } | ||
243 | 256 | ||
244 | void __init plat_prepare_cpus(unsigned int max_cpus) | ||
245 | { | ||
246 | cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ; | 257 | cpu_ipi_resched_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_RESCHED_IRQ; |
247 | cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ; | 258 | cpu_ipi_call_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_CALL_IRQ; |
248 | 259 | ||
@@ -287,7 +298,8 @@ void prom_boot_secondary(int cpu, struct task_struct *idle) | |||
287 | /* global pointer */ | 298 | /* global pointer */ |
288 | write_tc_gpr_gp((unsigned long)gp); | 299 | write_tc_gpr_gp((unsigned long)gp); |
289 | 300 | ||
290 | flush_icache_range((unsigned long)gp, (unsigned long)(gp + 1)); | 301 | flush_icache_range((unsigned long)gp, |
302 | (unsigned long)(gp + sizeof(struct thread_info))); | ||
291 | 303 | ||
292 | /* finally out of configuration and into chaos */ | 304 | /* finally out of configuration and into chaos */ |
293 | clear_c0_mvpcontrol(MVPCONTROL_VPC); | 305 | clear_c0_mvpcontrol(MVPCONTROL_VPC); |
@@ -305,6 +317,12 @@ void prom_smp_finish(void) | |||
305 | { | 317 | { |
306 | write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); | 318 | write_c0_compare(read_c0_count() + (8* mips_hpt_frequency/HZ)); |
307 | 319 | ||
320 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
321 | /* If we have an FPU, enroll ourselves in the FPU-full mask */ | ||
322 | if (cpu_has_fpu) | ||
323 | cpu_set(smp_processor_id(), mt_fpu_cpumask); | ||
324 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
325 | |||
308 | local_irq_enable(); | 326 | local_irq_enable(); |
309 | } | 327 | } |
310 | 328 | ||
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 78d171bfa331..d42f358754ad 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -38,6 +38,10 @@ | |||
38 | #include <asm/mmu_context.h> | 38 | #include <asm/mmu_context.h> |
39 | #include <asm/smp.h> | 39 | #include <asm/smp.h> |
40 | 40 | ||
41 | #ifdef CONFIG_MIPS_MT_SMTC | ||
42 | #include <asm/mipsmtregs.h> | ||
43 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
44 | |||
41 | cpumask_t phys_cpu_present_map; /* Bitmask of available CPUs */ | 45 | cpumask_t phys_cpu_present_map; /* Bitmask of available CPUs */ |
42 | volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ | 46 | volatile cpumask_t cpu_callin_map; /* Bitmask of started secondaries */ |
43 | cpumask_t cpu_online_map; /* Bitmask of currently online CPUs */ | 47 | cpumask_t cpu_online_map; /* Bitmask of currently online CPUs */ |
@@ -85,6 +89,10 @@ asmlinkage void start_secondary(void) | |||
85 | { | 89 | { |
86 | unsigned int cpu; | 90 | unsigned int cpu; |
87 | 91 | ||
92 | #ifdef CONFIG_MIPS_MT_SMTC | ||
93 | /* Only do cpu_probe for first TC of CPU */ | ||
94 | if ((read_c0_tcbind() & TCBIND_CURTC) == 0) | ||
95 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
88 | cpu_probe(); | 96 | cpu_probe(); |
89 | cpu_report(); | 97 | cpu_report(); |
90 | per_cpu_trap_init(); | 98 | per_cpu_trap_init(); |
@@ -179,11 +187,13 @@ int smp_call_function (void (*func) (void *info), void *info, int retry, | |||
179 | if (wait) | 187 | if (wait) |
180 | while (atomic_read(&data.finished) != cpus) | 188 | while (atomic_read(&data.finished) != cpus) |
181 | barrier(); | 189 | barrier(); |
190 | call_data = NULL; | ||
182 | spin_unlock(&smp_call_lock); | 191 | spin_unlock(&smp_call_lock); |
183 | 192 | ||
184 | return 0; | 193 | return 0; |
185 | } | 194 | } |
186 | 195 | ||
196 | |||
187 | void smp_call_function_interrupt(void) | 197 | void smp_call_function_interrupt(void) |
188 | { | 198 | { |
189 | void (*func) (void *info) = call_data->func; | 199 | void (*func) (void *info) = call_data->func; |
@@ -446,5 +456,3 @@ subsys_initcall(topology_init); | |||
446 | 456 | ||
447 | EXPORT_SYMBOL(flush_tlb_page); | 457 | EXPORT_SYMBOL(flush_tlb_page); |
448 | EXPORT_SYMBOL(flush_tlb_one); | 458 | EXPORT_SYMBOL(flush_tlb_one); |
449 | EXPORT_SYMBOL(cpu_data); | ||
450 | EXPORT_SYMBOL(synchronize_irq); | ||
diff --git a/arch/mips/kernel/smtc-asm.S b/arch/mips/kernel/smtc-asm.S new file mode 100644 index 000000000000..c9d65196d917 --- /dev/null +++ b/arch/mips/kernel/smtc-asm.S | |||
@@ -0,0 +1,130 @@ | |||
1 | /* | ||
2 | * Assembly Language Functions for MIPS MT SMTC support | ||
3 | */ | ||
4 | |||
5 | /* | ||
6 | * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set. */ | ||
7 | |||
8 | #include <asm/regdef.h> | ||
9 | #include <asm/asmmacro.h> | ||
10 | #include <asm/stackframe.h> | ||
11 | #include <asm/stackframe.h> | ||
12 | |||
13 | /* | ||
14 | * "Software Interrupt" linkage. | ||
15 | * | ||
16 | * This is invoked when an "Interrupt" is sent from one TC to another, | ||
17 | * where the TC to be interrupted is halted, has it's Restart address | ||
18 | * and Status values saved by the "remote control" thread, then modified | ||
19 | * to cause execution to begin here, in kenel mode. This code then | ||
20 | * disguises the TC state as that of an exception and transfers | ||
21 | * control to the general exception or vectored interrupt handler. | ||
22 | */ | ||
23 | .set noreorder | ||
24 | |||
25 | /* | ||
26 | The __smtc_ipi_vector would use k0 and k1 as temporaries and | ||
27 | 1) Set EXL (this is per-VPE, so this can't be done by proxy!) | ||
28 | 2) Restore the K/CU and IXMT bits to the pre "exception" state | ||
29 | (EXL means no interrupts and access to the kernel map). | ||
30 | 3) Set EPC to be the saved value of TCRestart. | ||
31 | 4) Jump to the exception handler entry point passed by the sender. | ||
32 | |||
33 | CAN WE PROVE THAT WE WON'T DO THIS IF INTS DISABLED?? | ||
34 | */ | ||
35 | |||
36 | /* | ||
37 | * Reviled and slandered vision: Set EXL and restore K/CU/IXMT | ||
38 | * state of pre-halt thread, then save everything and call | ||
39 | * thought some function pointer to imaginary_exception, which | ||
40 | * will parse a register value or memory message queue to | ||
41 | * deliver things like interprocessor interrupts. On return | ||
42 | * from that function, jump to the global ret_from_irq code | ||
43 | * to invoke the scheduler and return as appropriate. | ||
44 | */ | ||
45 | |||
46 | #define PT_PADSLOT4 (PT_R0-8) | ||
47 | #define PT_PADSLOT5 (PT_R0-4) | ||
48 | |||
49 | .text | ||
50 | .align 5 | ||
51 | FEXPORT(__smtc_ipi_vector) | ||
52 | .set noat | ||
53 | /* Disable thread scheduling to make Status update atomic */ | ||
54 | DMT 27 # dmt k1 | ||
55 | ehb | ||
56 | /* Set EXL */ | ||
57 | mfc0 k0,CP0_STATUS | ||
58 | ori k0,k0,ST0_EXL | ||
59 | mtc0 k0,CP0_STATUS | ||
60 | ehb | ||
61 | /* Thread scheduling now inhibited by EXL. Restore TE state. */ | ||
62 | andi k1,k1,VPECONTROL_TE | ||
63 | beqz k1,1f | ||
64 | emt | ||
65 | 1: | ||
66 | /* | ||
67 | * The IPI sender has put some information on the anticipated | ||
68 | * kernel stack frame. If we were in user mode, this will be | ||
69 | * built above the saved kernel SP. If we were already in the | ||
70 | * kernel, it will be built above the current CPU SP. | ||
71 | * | ||
72 | * Were we in kernel mode, as indicated by CU0? | ||
73 | */ | ||
74 | sll k1,k0,3 | ||
75 | .set noreorder | ||
76 | bltz k1,2f | ||
77 | move k1,sp | ||
78 | .set reorder | ||
79 | /* | ||
80 | * If previously in user mode, set CU0 and use kernel stack. | ||
81 | */ | ||
82 | li k1,ST0_CU0 | ||
83 | or k1,k1,k0 | ||
84 | mtc0 k1,CP0_STATUS | ||
85 | ehb | ||
86 | get_saved_sp | ||
87 | /* Interrupting TC will have pre-set values in slots in the new frame */ | ||
88 | 2: subu k1,k1,PT_SIZE | ||
89 | /* Load TCStatus Value */ | ||
90 | lw k0,PT_TCSTATUS(k1) | ||
91 | /* Write it to TCStatus to restore CU/KSU/IXMT state */ | ||
92 | mtc0 k0,$2,1 | ||
93 | ehb | ||
94 | lw k0,PT_EPC(k1) | ||
95 | mtc0 k0,CP0_EPC | ||
96 | /* Save all will redundantly recompute the SP, but use it for now */ | ||
97 | SAVE_ALL | ||
98 | CLI | ||
99 | move a0,sp | ||
100 | /* Function to be invoked passed stack pad slot 5 */ | ||
101 | lw t0,PT_PADSLOT5(sp) | ||
102 | /* Argument from sender passed in stack pad slot 4 */ | ||
103 | lw a1,PT_PADSLOT4(sp) | ||
104 | jalr t0 | ||
105 | nop | ||
106 | j ret_from_irq | ||
107 | nop | ||
108 | |||
109 | /* | ||
110 | * Called from idle loop to provoke processing of queued IPIs | ||
111 | * First IPI message in queue passed as argument. | ||
112 | */ | ||
113 | |||
114 | LEAF(self_ipi) | ||
115 | /* Before anything else, block interrupts */ | ||
116 | mfc0 t0,CP0_TCSTATUS | ||
117 | ori t1,t0,TCSTATUS_IXMT | ||
118 | mtc0 t1,CP0_TCSTATUS | ||
119 | ehb | ||
120 | /* We know we're in kernel mode, so prepare stack frame */ | ||
121 | subu t1,sp,PT_SIZE | ||
122 | sw ra,PT_EPC(t1) | ||
123 | sw a0,PT_PADSLOT4(t1) | ||
124 | la t2,ipi_decode | ||
125 | sw t2,PT_PADSLOT5(t1) | ||
126 | /* Save pre-disable value of TCStatus */ | ||
127 | sw t0,PT_TCSTATUS(t1) | ||
128 | j __smtc_ipi_vector | ||
129 | nop | ||
130 | END(self_ipi) | ||
diff --git a/arch/mips/kernel/smtc-proc.c b/arch/mips/kernel/smtc-proc.c new file mode 100644 index 000000000000..6f3709996172 --- /dev/null +++ b/arch/mips/kernel/smtc-proc.c | |||
@@ -0,0 +1,93 @@ | |||
1 | /* | ||
2 | * /proc hooks for SMTC kernel | ||
3 | * Copyright (C) 2005 Mips Technologies, Inc | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/sched.h> | ||
8 | #include <linux/cpumask.h> | ||
9 | #include <linux/interrupt.h> | ||
10 | |||
11 | #include <asm/cpu.h> | ||
12 | #include <asm/processor.h> | ||
13 | #include <asm/atomic.h> | ||
14 | #include <asm/system.h> | ||
15 | #include <asm/hardirq.h> | ||
16 | #include <asm/mmu_context.h> | ||
17 | #include <asm/smp.h> | ||
18 | #include <asm/mipsregs.h> | ||
19 | #include <asm/cacheflush.h> | ||
20 | #include <linux/proc_fs.h> | ||
21 | |||
22 | #include <asm/smtc_proc.h> | ||
23 | |||
24 | /* | ||
25 | * /proc diagnostic and statistics hooks | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * Statistics gathered | ||
30 | */ | ||
31 | unsigned long selfipis[NR_CPUS]; | ||
32 | |||
33 | struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS]; | ||
34 | |||
35 | static struct proc_dir_entry *smtc_stats; | ||
36 | |||
37 | atomic_t smtc_fpu_recoveries; | ||
38 | |||
39 | static int proc_read_smtc(char *page, char **start, off_t off, | ||
40 | int count, int *eof, void *data) | ||
41 | { | ||
42 | int totalen = 0; | ||
43 | int len; | ||
44 | int i; | ||
45 | extern unsigned long ebase; | ||
46 | |||
47 | len = sprintf(page, "SMTC Status Word: 0x%08x\n", smtc_status); | ||
48 | totalen += len; | ||
49 | page += len; | ||
50 | len = sprintf(page, "Config7: 0x%08x\n", read_c0_config7()); | ||
51 | totalen += len; | ||
52 | page += len; | ||
53 | len = sprintf(page, "EBASE: 0x%08lx\n", ebase); | ||
54 | totalen += len; | ||
55 | page += len; | ||
56 | len = sprintf(page, "Counter Interrupts taken per CPU (TC)\n"); | ||
57 | totalen += len; | ||
58 | page += len; | ||
59 | for (i=0; i < NR_CPUS; i++) { | ||
60 | len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].timerints); | ||
61 | totalen += len; | ||
62 | page += len; | ||
63 | } | ||
64 | len = sprintf(page, "Self-IPIs by CPU:\n"); | ||
65 | totalen += len; | ||
66 | page += len; | ||
67 | for(i = 0; i < NR_CPUS; i++) { | ||
68 | len = sprintf(page, "%d: %ld\n", i, smtc_cpu_stats[i].selfipis); | ||
69 | totalen += len; | ||
70 | page += len; | ||
71 | } | ||
72 | len = sprintf(page, "%d Recoveries of \"stolen\" FPU\n", | ||
73 | atomic_read(&smtc_fpu_recoveries)); | ||
74 | totalen += len; | ||
75 | page += len; | ||
76 | |||
77 | return totalen; | ||
78 | } | ||
79 | |||
80 | void init_smtc_stats(void) | ||
81 | { | ||
82 | int i; | ||
83 | |||
84 | for (i=0; i<NR_CPUS; i++) { | ||
85 | smtc_cpu_stats[i].timerints = 0; | ||
86 | smtc_cpu_stats[i].selfipis = 0; | ||
87 | } | ||
88 | |||
89 | atomic_set(&smtc_fpu_recoveries, 0); | ||
90 | |||
91 | smtc_stats = create_proc_read_entry("smtc", 0444, NULL, | ||
92 | proc_read_smtc, NULL); | ||
93 | } | ||
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c new file mode 100644 index 000000000000..2e8e52c135e6 --- /dev/null +++ b/arch/mips/kernel/smtc.c | |||
@@ -0,0 +1,1322 @@ | |||
1 | /* Copyright (C) 2004 Mips Technologies, Inc */ | ||
2 | |||
3 | #include <linux/kernel.h> | ||
4 | #include <linux/sched.h> | ||
5 | #include <linux/cpumask.h> | ||
6 | #include <linux/interrupt.h> | ||
7 | |||
8 | #include <asm/cpu.h> | ||
9 | #include <asm/processor.h> | ||
10 | #include <asm/atomic.h> | ||
11 | #include <asm/system.h> | ||
12 | #include <asm/hardirq.h> | ||
13 | #include <asm/hazards.h> | ||
14 | #include <asm/mmu_context.h> | ||
15 | #include <asm/smp.h> | ||
16 | #include <asm/mipsregs.h> | ||
17 | #include <asm/cacheflush.h> | ||
18 | #include <asm/time.h> | ||
19 | #include <asm/addrspace.h> | ||
20 | #include <asm/smtc.h> | ||
21 | #include <asm/smtc_ipi.h> | ||
22 | #include <asm/smtc_proc.h> | ||
23 | |||
24 | /* | ||
25 | * This file should be built into the kernel only if CONFIG_MIPS_MT_SMTC is set. | ||
26 | */ | ||
27 | |||
28 | /* | ||
29 | * MIPSCPU_INT_BASE is identically defined in both | ||
30 | * asm-mips/mips-boards/maltaint.h and asm-mips/mips-boards/simint.h, | ||
31 | * but as yet there's no properly organized include structure that | ||
32 | * will ensure that the right *int.h file will be included for a | ||
33 | * given platform build. | ||
34 | */ | ||
35 | |||
36 | #define MIPSCPU_INT_BASE 16 | ||
37 | |||
38 | #define MIPS_CPU_IPI_IRQ 1 | ||
39 | |||
40 | #define LOCK_MT_PRA() \ | ||
41 | local_irq_save(flags); \ | ||
42 | mtflags = dmt() | ||
43 | |||
44 | #define UNLOCK_MT_PRA() \ | ||
45 | emt(mtflags); \ | ||
46 | local_irq_restore(flags) | ||
47 | |||
48 | #define LOCK_CORE_PRA() \ | ||
49 | local_irq_save(flags); \ | ||
50 | mtflags = dvpe() | ||
51 | |||
52 | #define UNLOCK_CORE_PRA() \ | ||
53 | evpe(mtflags); \ | ||
54 | local_irq_restore(flags) | ||
55 | |||
56 | /* | ||
57 | * Data structures purely associated with SMTC parallelism | ||
58 | */ | ||
59 | |||
60 | |||
61 | /* | ||
62 | * Table for tracking ASIDs whose lifetime is prolonged. | ||
63 | */ | ||
64 | |||
65 | asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; | ||
66 | |||
67 | /* | ||
68 | * Clock interrupt "latch" buffers, per "CPU" | ||
69 | */ | ||
70 | |||
71 | unsigned int ipi_timer_latch[NR_CPUS]; | ||
72 | |||
73 | /* | ||
74 | * Number of InterProcessor Interupt (IPI) message buffers to allocate | ||
75 | */ | ||
76 | |||
77 | #define IPIBUF_PER_CPU 4 | ||
78 | |||
79 | struct smtc_ipi_q IPIQ[NR_CPUS]; | ||
80 | struct smtc_ipi_q freeIPIq; | ||
81 | |||
82 | |||
83 | /* Forward declarations */ | ||
84 | |||
85 | void ipi_decode(struct pt_regs *, struct smtc_ipi *); | ||
86 | void post_direct_ipi(int cpu, struct smtc_ipi *pipi); | ||
87 | void setup_cross_vpe_interrupts(void); | ||
88 | void init_smtc_stats(void); | ||
89 | |||
90 | /* Global SMTC Status */ | ||
91 | |||
92 | unsigned int smtc_status = 0; | ||
93 | |||
94 | /* Boot command line configuration overrides */ | ||
95 | |||
96 | static int vpelimit = 0; | ||
97 | static int tclimit = 0; | ||
98 | static int ipibuffers = 0; | ||
99 | static int nostlb = 0; | ||
100 | static int asidmask = 0; | ||
101 | unsigned long smtc_asid_mask = 0xff; | ||
102 | |||
103 | static int __init maxvpes(char *str) | ||
104 | { | ||
105 | get_option(&str, &vpelimit); | ||
106 | return 1; | ||
107 | } | ||
108 | |||
109 | static int __init maxtcs(char *str) | ||
110 | { | ||
111 | get_option(&str, &tclimit); | ||
112 | return 1; | ||
113 | } | ||
114 | |||
115 | static int __init ipibufs(char *str) | ||
116 | { | ||
117 | get_option(&str, &ipibuffers); | ||
118 | return 1; | ||
119 | } | ||
120 | |||
121 | static int __init stlb_disable(char *s) | ||
122 | { | ||
123 | nostlb = 1; | ||
124 | return 1; | ||
125 | } | ||
126 | |||
127 | static int __init asidmask_set(char *str) | ||
128 | { | ||
129 | get_option(&str, &asidmask); | ||
130 | switch(asidmask) { | ||
131 | case 0x1: | ||
132 | case 0x3: | ||
133 | case 0x7: | ||
134 | case 0xf: | ||
135 | case 0x1f: | ||
136 | case 0x3f: | ||
137 | case 0x7f: | ||
138 | case 0xff: | ||
139 | smtc_asid_mask = (unsigned long)asidmask; | ||
140 | break; | ||
141 | default: | ||
142 | printk("ILLEGAL ASID mask 0x%x from command line\n", asidmask); | ||
143 | } | ||
144 | return 1; | ||
145 | } | ||
146 | |||
147 | __setup("maxvpes=", maxvpes); | ||
148 | __setup("maxtcs=", maxtcs); | ||
149 | __setup("ipibufs=", ipibufs); | ||
150 | __setup("nostlb", stlb_disable); | ||
151 | __setup("asidmask=", asidmask_set); | ||
152 | |||
153 | /* Enable additional debug checks before going into CPU idle loop */ | ||
154 | #define SMTC_IDLE_HOOK_DEBUG | ||
155 | |||
156 | #ifdef SMTC_IDLE_HOOK_DEBUG | ||
157 | |||
158 | static int hang_trig = 0; | ||
159 | |||
160 | static int __init hangtrig_enable(char *s) | ||
161 | { | ||
162 | hang_trig = 1; | ||
163 | return 1; | ||
164 | } | ||
165 | |||
166 | |||
167 | __setup("hangtrig", hangtrig_enable); | ||
168 | |||
169 | #define DEFAULT_BLOCKED_IPI_LIMIT 32 | ||
170 | |||
171 | static int timerq_limit = DEFAULT_BLOCKED_IPI_LIMIT; | ||
172 | |||
173 | static int __init tintq(char *str) | ||
174 | { | ||
175 | get_option(&str, &timerq_limit); | ||
176 | return 1; | ||
177 | } | ||
178 | |||
179 | __setup("tintq=", tintq); | ||
180 | |||
181 | int imstuckcount[2][8]; | ||
182 | /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ | ||
183 | int vpemask[2][8] = {{0,1,1,0,0,0,0,1},{0,1,0,0,0,0,0,1}}; | ||
184 | int tcnoprog[NR_CPUS]; | ||
185 | static atomic_t idle_hook_initialized = {0}; | ||
186 | static int clock_hang_reported[NR_CPUS]; | ||
187 | |||
188 | #endif /* SMTC_IDLE_HOOK_DEBUG */ | ||
189 | |||
190 | /* Initialize shared TLB - the should probably migrate to smtc_setup_cpus() */ | ||
191 | |||
192 | void __init sanitize_tlb_entries(void) | ||
193 | { | ||
194 | printk("Deprecated sanitize_tlb_entries() invoked\n"); | ||
195 | } | ||
196 | |||
197 | |||
198 | /* | ||
199 | * Configure shared TLB - VPC configuration bit must be set by caller | ||
200 | */ | ||
201 | |||
202 | void smtc_configure_tlb(void) | ||
203 | { | ||
204 | int i,tlbsiz,vpes; | ||
205 | unsigned long mvpconf0; | ||
206 | unsigned long config1val; | ||
207 | |||
208 | /* Set up ASID preservation table */ | ||
209 | for (vpes=0; vpes<MAX_SMTC_TLBS; vpes++) { | ||
210 | for(i = 0; i < MAX_SMTC_ASIDS; i++) { | ||
211 | smtc_live_asid[vpes][i] = 0; | ||
212 | } | ||
213 | } | ||
214 | mvpconf0 = read_c0_mvpconf0(); | ||
215 | |||
216 | if ((vpes = ((mvpconf0 & MVPCONF0_PVPE) | ||
217 | >> MVPCONF0_PVPE_SHIFT) + 1) > 1) { | ||
218 | /* If we have multiple VPEs, try to share the TLB */ | ||
219 | if ((mvpconf0 & MVPCONF0_TLBS) && !nostlb) { | ||
220 | /* | ||
221 | * If TLB sizing is programmable, shared TLB | ||
222 | * size is the total available complement. | ||
223 | * Otherwise, we have to take the sum of all | ||
224 | * static VPE TLB entries. | ||
225 | */ | ||
226 | if ((tlbsiz = ((mvpconf0 & MVPCONF0_PTLBE) | ||
227 | >> MVPCONF0_PTLBE_SHIFT)) == 0) { | ||
228 | /* | ||
229 | * If there's more than one VPE, there had better | ||
230 | * be more than one TC, because we need one to bind | ||
231 | * to each VPE in turn to be able to read | ||
232 | * its configuration state! | ||
233 | */ | ||
234 | settc(1); | ||
235 | /* Stop the TC from doing anything foolish */ | ||
236 | write_tc_c0_tchalt(TCHALT_H); | ||
237 | mips_ihb(); | ||
238 | /* No need to un-Halt - that happens later anyway */ | ||
239 | for (i=0; i < vpes; i++) { | ||
240 | write_tc_c0_tcbind(i); | ||
241 | /* | ||
242 | * To be 100% sure we're really getting the right | ||
243 | * information, we exit the configuration state | ||
244 | * and do an IHB after each rebinding. | ||
245 | */ | ||
246 | write_c0_mvpcontrol( | ||
247 | read_c0_mvpcontrol() & ~ MVPCONTROL_VPC ); | ||
248 | mips_ihb(); | ||
249 | /* | ||
250 | * Only count if the MMU Type indicated is TLB | ||
251 | */ | ||
252 | if(((read_vpe_c0_config() & MIPS_CONF_MT) >> 7) == 1) { | ||
253 | config1val = read_vpe_c0_config1(); | ||
254 | tlbsiz += ((config1val >> 25) & 0x3f) + 1; | ||
255 | } | ||
256 | |||
257 | /* Put core back in configuration state */ | ||
258 | write_c0_mvpcontrol( | ||
259 | read_c0_mvpcontrol() | MVPCONTROL_VPC ); | ||
260 | mips_ihb(); | ||
261 | } | ||
262 | } | ||
263 | write_c0_mvpcontrol(read_c0_mvpcontrol() | MVPCONTROL_STLB); | ||
264 | |||
265 | /* | ||
266 | * Setup kernel data structures to use software total, | ||
267 | * rather than read the per-VPE Config1 value. The values | ||
268 | * for "CPU 0" gets copied to all the other CPUs as part | ||
269 | * of their initialization in smtc_cpu_setup(). | ||
270 | */ | ||
271 | |||
272 | tlbsiz = tlbsiz & 0x3f; /* MIPS32 limits TLB indices to 64 */ | ||
273 | cpu_data[0].tlbsize = tlbsiz; | ||
274 | smtc_status |= SMTC_TLB_SHARED; | ||
275 | |||
276 | printk("TLB of %d entry pairs shared by %d VPEs\n", | ||
277 | tlbsiz, vpes); | ||
278 | } else { | ||
279 | printk("WARNING: TLB Not Sharable on SMTC Boot!\n"); | ||
280 | } | ||
281 | } | ||
282 | } | ||
283 | |||
284 | |||
285 | /* | ||
286 | * Incrementally build the CPU map out of constituent MIPS MT cores, | ||
287 | * using the specified available VPEs and TCs. Plaform code needs | ||
288 | * to ensure that each MIPS MT core invokes this routine on reset, | ||
289 | * one at a time(!). | ||
290 | * | ||
291 | * This version of the build_cpu_map and prepare_cpus routines assumes | ||
292 | * that *all* TCs of a MIPS MT core will be used for Linux, and that | ||
293 | * they will be spread across *all* available VPEs (to minimise the | ||
294 | * loss of efficiency due to exception service serialization). | ||
295 | * An improved version would pick up configuration information and | ||
296 | * possibly leave some TCs/VPEs as "slave" processors. | ||
297 | * | ||
298 | * Use c0_MVPConf0 to find out how many TCs are available, setting up | ||
299 | * phys_cpu_present_map and the logical/physical mappings. | ||
300 | */ | ||
301 | |||
302 | int __init mipsmt_build_cpu_map(int start_cpu_slot) | ||
303 | { | ||
304 | int i, ntcs; | ||
305 | |||
306 | /* | ||
307 | * The CPU map isn't actually used for anything at this point, | ||
308 | * so it's not clear what else we should do apart from set | ||
309 | * everything up so that "logical" = "physical". | ||
310 | */ | ||
311 | ntcs = ((read_c0_mvpconf0() & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; | ||
312 | for (i=start_cpu_slot; i<NR_CPUS && i<ntcs; i++) { | ||
313 | cpu_set(i, phys_cpu_present_map); | ||
314 | __cpu_number_map[i] = i; | ||
315 | __cpu_logical_map[i] = i; | ||
316 | } | ||
317 | /* Initialize map of CPUs with FPUs */ | ||
318 | cpus_clear(mt_fpu_cpumask); | ||
319 | |||
320 | /* One of those TC's is the one booting, and not a secondary... */ | ||
321 | printk("%i available secondary CPU TC(s)\n", i - 1); | ||
322 | |||
323 | return i; | ||
324 | } | ||
325 | |||
326 | /* | ||
327 | * Common setup before any secondaries are started | ||
328 | * Make sure all CPU's are in a sensible state before we boot any of the | ||
329 | * secondaries. | ||
330 | * | ||
331 | * For MIPS MT "SMTC" operation, we set up all TCs, spread as evenly | ||
332 | * as possible across the available VPEs. | ||
333 | */ | ||
334 | |||
335 | static void smtc_tc_setup(int vpe, int tc, int cpu) | ||
336 | { | ||
337 | settc(tc); | ||
338 | write_tc_c0_tchalt(TCHALT_H); | ||
339 | mips_ihb(); | ||
340 | write_tc_c0_tcstatus((read_tc_c0_tcstatus() | ||
341 | & ~(TCSTATUS_TKSU | TCSTATUS_DA | TCSTATUS_IXMT)) | ||
342 | | TCSTATUS_A); | ||
343 | write_tc_c0_tccontext(0); | ||
344 | /* Bind tc to vpe */ | ||
345 | write_tc_c0_tcbind(vpe); | ||
346 | /* In general, all TCs should have the same cpu_data indications */ | ||
347 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); | ||
348 | /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ | ||
349 | if (cpu_data[0].cputype == CPU_34K) | ||
350 | cpu_data[cpu].options &= ~MIPS_CPU_FPU; | ||
351 | cpu_data[cpu].vpe_id = vpe; | ||
352 | cpu_data[cpu].tc_id = tc; | ||
353 | } | ||
354 | |||
355 | |||
356 | void mipsmt_prepare_cpus(void) | ||
357 | { | ||
358 | int i, vpe, tc, ntc, nvpe, tcpervpe, slop, cpu; | ||
359 | unsigned long flags; | ||
360 | unsigned long val; | ||
361 | int nipi; | ||
362 | struct smtc_ipi *pipi; | ||
363 | |||
364 | /* disable interrupts so we can disable MT */ | ||
365 | local_irq_save(flags); | ||
366 | /* disable MT so we can configure */ | ||
367 | dvpe(); | ||
368 | dmt(); | ||
369 | |||
370 | freeIPIq.lock = SPIN_LOCK_UNLOCKED; | ||
371 | |||
372 | /* | ||
373 | * We probably don't have as many VPEs as we do SMP "CPUs", | ||
374 | * but it's possible - and in any case we'll never use more! | ||
375 | */ | ||
376 | for (i=0; i<NR_CPUS; i++) { | ||
377 | IPIQ[i].head = IPIQ[i].tail = NULL; | ||
378 | IPIQ[i].lock = SPIN_LOCK_UNLOCKED; | ||
379 | IPIQ[i].depth = 0; | ||
380 | ipi_timer_latch[i] = 0; | ||
381 | } | ||
382 | |||
383 | /* cpu_data index starts at zero */ | ||
384 | cpu = 0; | ||
385 | cpu_data[cpu].vpe_id = 0; | ||
386 | cpu_data[cpu].tc_id = 0; | ||
387 | cpu++; | ||
388 | |||
389 | /* Report on boot-time options */ | ||
390 | mips_mt_set_cpuoptions (); | ||
391 | if (vpelimit > 0) | ||
392 | printk("Limit of %d VPEs set\n", vpelimit); | ||
393 | if (tclimit > 0) | ||
394 | printk("Limit of %d TCs set\n", tclimit); | ||
395 | if (nostlb) { | ||
396 | printk("Shared TLB Use Inhibited - UNSAFE for Multi-VPE Operation\n"); | ||
397 | } | ||
398 | if (asidmask) | ||
399 | printk("ASID mask value override to 0x%x\n", asidmask); | ||
400 | |||
401 | /* Temporary */ | ||
402 | #ifdef SMTC_IDLE_HOOK_DEBUG | ||
403 | if (hang_trig) | ||
404 | printk("Logic Analyser Trigger on suspected TC hang\n"); | ||
405 | #endif /* SMTC_IDLE_HOOK_DEBUG */ | ||
406 | |||
407 | /* Put MVPE's into 'configuration state' */ | ||
408 | write_c0_mvpcontrol( read_c0_mvpcontrol() | MVPCONTROL_VPC ); | ||
409 | |||
410 | val = read_c0_mvpconf0(); | ||
411 | nvpe = ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1; | ||
412 | if (vpelimit > 0 && nvpe > vpelimit) | ||
413 | nvpe = vpelimit; | ||
414 | ntc = ((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; | ||
415 | if (ntc > NR_CPUS) | ||
416 | ntc = NR_CPUS; | ||
417 | if (tclimit > 0 && ntc > tclimit) | ||
418 | ntc = tclimit; | ||
419 | tcpervpe = ntc / nvpe; | ||
420 | slop = ntc % nvpe; /* Residual TCs, < NVPE */ | ||
421 | |||
422 | /* Set up shared TLB */ | ||
423 | smtc_configure_tlb(); | ||
424 | |||
425 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { | ||
426 | /* | ||
427 | * Set the MVP bits. | ||
428 | */ | ||
429 | settc(tc); | ||
430 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_MVP); | ||
431 | if (vpe != 0) | ||
432 | printk(", "); | ||
433 | printk("VPE %d: TC", vpe); | ||
434 | for (i = 0; i < tcpervpe; i++) { | ||
435 | /* | ||
436 | * TC 0 is bound to VPE 0 at reset, | ||
437 | * and is presumably executing this | ||
438 | * code. Leave it alone! | ||
439 | */ | ||
440 | if (tc != 0) { | ||
441 | smtc_tc_setup(vpe,tc, cpu); | ||
442 | cpu++; | ||
443 | } | ||
444 | printk(" %d", tc); | ||
445 | tc++; | ||
446 | } | ||
447 | if (slop) { | ||
448 | if (tc != 0) { | ||
449 | smtc_tc_setup(vpe,tc, cpu); | ||
450 | cpu++; | ||
451 | } | ||
452 | printk(" %d", tc); | ||
453 | tc++; | ||
454 | slop--; | ||
455 | } | ||
456 | if (vpe != 0) { | ||
457 | /* | ||
458 | * Clear any stale software interrupts from VPE's Cause | ||
459 | */ | ||
460 | write_vpe_c0_cause(0); | ||
461 | |||
462 | /* | ||
463 | * Clear ERL/EXL of VPEs other than 0 | ||
464 | * and set restricted interrupt enable/mask. | ||
465 | */ | ||
466 | write_vpe_c0_status((read_vpe_c0_status() | ||
467 | & ~(ST0_BEV | ST0_ERL | ST0_EXL | ST0_IM)) | ||
468 | | (STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP7 | ||
469 | | ST0_IE)); | ||
470 | /* | ||
471 | * set config to be the same as vpe0, | ||
472 | * particularly kseg0 coherency alg | ||
473 | */ | ||
474 | write_vpe_c0_config(read_c0_config()); | ||
475 | /* Clear any pending timer interrupt */ | ||
476 | write_vpe_c0_compare(0); | ||
477 | /* Propagate Config7 */ | ||
478 | write_vpe_c0_config7(read_c0_config7()); | ||
479 | } | ||
480 | /* enable multi-threading within VPE */ | ||
481 | write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() | VPECONTROL_TE); | ||
482 | /* enable the VPE */ | ||
483 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); | ||
484 | } | ||
485 | |||
486 | /* | ||
487 | * Pull any physically present but unused TCs out of circulation. | ||
488 | */ | ||
489 | while (tc < (((val & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1)) { | ||
490 | cpu_clear(tc, phys_cpu_present_map); | ||
491 | cpu_clear(tc, cpu_present_map); | ||
492 | tc++; | ||
493 | } | ||
494 | |||
495 | /* release config state */ | ||
496 | write_c0_mvpcontrol( read_c0_mvpcontrol() & ~ MVPCONTROL_VPC ); | ||
497 | |||
498 | printk("\n"); | ||
499 | |||
500 | /* Set up coprocessor affinity CPU mask(s) */ | ||
501 | |||
502 | for (tc = 0; tc < ntc; tc++) { | ||
503 | if(cpu_data[tc].options & MIPS_CPU_FPU) | ||
504 | cpu_set(tc, mt_fpu_cpumask); | ||
505 | } | ||
506 | |||
507 | /* set up ipi interrupts... */ | ||
508 | |||
509 | /* If we have multiple VPEs running, set up the cross-VPE interrupt */ | ||
510 | |||
511 | if (nvpe > 1) | ||
512 | setup_cross_vpe_interrupts(); | ||
513 | |||
514 | /* Set up queue of free IPI "messages". */ | ||
515 | nipi = NR_CPUS * IPIBUF_PER_CPU; | ||
516 | if (ipibuffers > 0) | ||
517 | nipi = ipibuffers; | ||
518 | |||
519 | pipi = kmalloc(nipi *sizeof(struct smtc_ipi), GFP_KERNEL); | ||
520 | if (pipi == NULL) | ||
521 | panic("kmalloc of IPI message buffers failed\n"); | ||
522 | else | ||
523 | printk("IPI buffer pool of %d buffers\n", nipi); | ||
524 | for (i = 0; i < nipi; i++) { | ||
525 | smtc_ipi_nq(&freeIPIq, pipi); | ||
526 | pipi++; | ||
527 | } | ||
528 | |||
529 | /* Arm multithreading and enable other VPEs - but all TCs are Halted */ | ||
530 | emt(EMT_ENABLE); | ||
531 | evpe(EVPE_ENABLE); | ||
532 | local_irq_restore(flags); | ||
533 | /* Initialize SMTC /proc statistics/diagnostics */ | ||
534 | init_smtc_stats(); | ||
535 | } | ||
536 | |||
537 | |||
538 | /* | ||
539 | * Setup the PC, SP, and GP of a secondary processor and start it | ||
540 | * running! | ||
541 | * smp_bootstrap is the place to resume from | ||
542 | * __KSTK_TOS(idle) is apparently the stack pointer | ||
543 | * (unsigned long)idle->thread_info the gp | ||
544 | * | ||
545 | */ | ||
546 | void smtc_boot_secondary(int cpu, struct task_struct *idle) | ||
547 | { | ||
548 | extern u32 kernelsp[NR_CPUS]; | ||
549 | long flags; | ||
550 | int mtflags; | ||
551 | |||
552 | LOCK_MT_PRA(); | ||
553 | if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { | ||
554 | dvpe(); | ||
555 | } | ||
556 | settc(cpu_data[cpu].tc_id); | ||
557 | |||
558 | /* pc */ | ||
559 | write_tc_c0_tcrestart((unsigned long)&smp_bootstrap); | ||
560 | |||
561 | /* stack pointer */ | ||
562 | kernelsp[cpu] = __KSTK_TOS(idle); | ||
563 | write_tc_gpr_sp(__KSTK_TOS(idle)); | ||
564 | |||
565 | /* global pointer */ | ||
566 | write_tc_gpr_gp((unsigned long)idle->thread_info); | ||
567 | |||
568 | smtc_status |= SMTC_MTC_ACTIVE; | ||
569 | write_tc_c0_tchalt(0); | ||
570 | if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { | ||
571 | evpe(EVPE_ENABLE); | ||
572 | } | ||
573 | UNLOCK_MT_PRA(); | ||
574 | } | ||
575 | |||
576 | void smtc_init_secondary(void) | ||
577 | { | ||
578 | /* | ||
579 | * Start timer on secondary VPEs if necessary. | ||
580 | * mips_timer_setup should already have been invoked by init/main | ||
581 | * on "boot" TC. Like per_cpu_trap_init() hack, this assumes that | ||
582 | * SMTC init code assigns TCs consdecutively and in ascending order | ||
583 | * to across available VPEs. | ||
584 | */ | ||
585 | if(((read_c0_tcbind() & TCBIND_CURTC) != 0) | ||
586 | && ((read_c0_tcbind() & TCBIND_CURVPE) | ||
587 | != cpu_data[smp_processor_id() - 1].vpe_id)){ | ||
588 | write_c0_compare (read_c0_count() + mips_hpt_frequency/HZ); | ||
589 | } | ||
590 | |||
591 | local_irq_enable(); | ||
592 | } | ||
593 | |||
594 | void smtc_smp_finish(void) | ||
595 | { | ||
596 | printk("TC %d going on-line as CPU %d\n", | ||
597 | cpu_data[smp_processor_id()].tc_id, smp_processor_id()); | ||
598 | } | ||
599 | |||
600 | void smtc_cpus_done(void) | ||
601 | { | ||
602 | } | ||
603 | |||
604 | /* | ||
605 | * Support for SMTC-optimized driver IRQ registration | ||
606 | */ | ||
607 | |||
608 | /* | ||
609 | * SMTC Kernel needs to manipulate low-level CPU interrupt mask | ||
610 | * in do_IRQ. These are passed in setup_irq_smtc() and stored | ||
611 | * in this table. | ||
612 | */ | ||
613 | |||
614 | int setup_irq_smtc(unsigned int irq, struct irqaction * new, | ||
615 | unsigned long hwmask) | ||
616 | { | ||
617 | irq_hwmask[irq] = hwmask; | ||
618 | |||
619 | return setup_irq(irq, new); | ||
620 | } | ||
621 | |||
622 | /* | ||
623 | * IPI model for SMTC is tricky, because interrupts aren't TC-specific. | ||
624 | * Within a VPE one TC can interrupt another by different approaches. | ||
625 | * The easiest to get right would probably be to make all TCs except | ||
626 | * the target IXMT and set a software interrupt, but an IXMT-based | ||
627 | * scheme requires that a handler must run before a new IPI could | ||
628 | * be sent, which would break the "broadcast" loops in MIPS MT. | ||
629 | * A more gonzo approach within a VPE is to halt the TC, extract | ||
630 | * its Restart, Status, and a couple of GPRs, and program the Restart | ||
631 | * address to emulate an interrupt. | ||
632 | * | ||
633 | * Within a VPE, one can be confident that the target TC isn't in | ||
634 | * a critical EXL state when halted, since the write to the Halt | ||
635 | * register could not have issued on the writing thread if the | ||
636 | * halting thread had EXL set. So k0 and k1 of the target TC | ||
637 | * can be used by the injection code. Across VPEs, one can't | ||
638 | * be certain that the target TC isn't in a critical exception | ||
639 | * state. So we try a two-step process of sending a software | ||
640 | * interrupt to the target VPE, which either handles the event | ||
641 | * itself (if it was the target) or injects the event within | ||
642 | * the VPE. | ||
643 | */ | ||
644 | |||
645 | void smtc_ipi_qdump(void) | ||
646 | { | ||
647 | int i; | ||
648 | |||
649 | for (i = 0; i < NR_CPUS ;i++) { | ||
650 | printk("IPIQ[%d]: head = 0x%x, tail = 0x%x, depth = %d\n", | ||
651 | i, (unsigned)IPIQ[i].head, (unsigned)IPIQ[i].tail, | ||
652 | IPIQ[i].depth); | ||
653 | } | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * The standard atomic.h primitives don't quite do what we want | ||
658 | * here: We need an atomic add-and-return-previous-value (which | ||
659 | * could be done with atomic_add_return and a decrement) and an | ||
660 | * atomic set/zero-and-return-previous-value (which can't really | ||
661 | * be done with the atomic.h primitives). And since this is | ||
662 | * MIPS MT, we can assume that we have LL/SC. | ||
663 | */ | ||
664 | static __inline__ int atomic_postincrement(unsigned int *pv) | ||
665 | { | ||
666 | unsigned long result; | ||
667 | |||
668 | unsigned long temp; | ||
669 | |||
670 | __asm__ __volatile__( | ||
671 | "1: ll %0, %2 \n" | ||
672 | " addu %1, %0, 1 \n" | ||
673 | " sc %1, %2 \n" | ||
674 | " beqz %1, 1b \n" | ||
675 | " sync \n" | ||
676 | : "=&r" (result), "=&r" (temp), "=m" (*pv) | ||
677 | : "m" (*pv) | ||
678 | : "memory"); | ||
679 | |||
680 | return result; | ||
681 | } | ||
682 | |||
683 | /* No longer used in IPI dispatch, but retained for future recycling */ | ||
684 | |||
685 | static __inline__ int atomic_postclear(unsigned int *pv) | ||
686 | { | ||
687 | unsigned long result; | ||
688 | |||
689 | unsigned long temp; | ||
690 | |||
691 | __asm__ __volatile__( | ||
692 | "1: ll %0, %2 \n" | ||
693 | " or %1, $0, $0 \n" | ||
694 | " sc %1, %2 \n" | ||
695 | " beqz %1, 1b \n" | ||
696 | " sync \n" | ||
697 | : "=&r" (result), "=&r" (temp), "=m" (*pv) | ||
698 | : "m" (*pv) | ||
699 | : "memory"); | ||
700 | |||
701 | return result; | ||
702 | } | ||
703 | |||
704 | |||
705 | void smtc_send_ipi(int cpu, int type, unsigned int action) | ||
706 | { | ||
707 | int tcstatus; | ||
708 | struct smtc_ipi *pipi; | ||
709 | long flags; | ||
710 | int mtflags; | ||
711 | |||
712 | if (cpu == smp_processor_id()) { | ||
713 | printk("Cannot Send IPI to self!\n"); | ||
714 | return; | ||
715 | } | ||
716 | /* Set up a descriptor, to be delivered either promptly or queued */ | ||
717 | pipi = smtc_ipi_dq(&freeIPIq); | ||
718 | if (pipi == NULL) { | ||
719 | bust_spinlocks(1); | ||
720 | mips_mt_regdump(dvpe()); | ||
721 | panic("IPI Msg. Buffers Depleted\n"); | ||
722 | } | ||
723 | pipi->type = type; | ||
724 | pipi->arg = (void *)action; | ||
725 | pipi->dest = cpu; | ||
726 | if (cpu_data[cpu].vpe_id != cpu_data[smp_processor_id()].vpe_id) { | ||
727 | /* If not on same VPE, enqueue and send cross-VPE interupt */ | ||
728 | smtc_ipi_nq(&IPIQ[cpu], pipi); | ||
729 | LOCK_CORE_PRA(); | ||
730 | settc(cpu_data[cpu].tc_id); | ||
731 | write_vpe_c0_cause(read_vpe_c0_cause() | C_SW1); | ||
732 | UNLOCK_CORE_PRA(); | ||
733 | } else { | ||
734 | /* | ||
735 | * Not sufficient to do a LOCK_MT_PRA (dmt) here, | ||
736 | * since ASID shootdown on the other VPE may | ||
737 | * collide with this operation. | ||
738 | */ | ||
739 | LOCK_CORE_PRA(); | ||
740 | settc(cpu_data[cpu].tc_id); | ||
741 | /* Halt the targeted TC */ | ||
742 | write_tc_c0_tchalt(TCHALT_H); | ||
743 | mips_ihb(); | ||
744 | |||
745 | /* | ||
746 | * Inspect TCStatus - if IXMT is set, we have to queue | ||
747 | * a message. Otherwise, we set up the "interrupt" | ||
748 | * of the other TC | ||
749 | */ | ||
750 | tcstatus = read_tc_c0_tcstatus(); | ||
751 | |||
752 | if ((tcstatus & TCSTATUS_IXMT) != 0) { | ||
753 | /* | ||
754 | * Spin-waiting here can deadlock, | ||
755 | * so we queue the message for the target TC. | ||
756 | */ | ||
757 | write_tc_c0_tchalt(0); | ||
758 | UNLOCK_CORE_PRA(); | ||
759 | /* Try to reduce redundant timer interrupt messages */ | ||
760 | if(type == SMTC_CLOCK_TICK) { | ||
761 | if(atomic_postincrement(&ipi_timer_latch[cpu])!=0) { | ||
762 | smtc_ipi_nq(&freeIPIq, pipi); | ||
763 | return; | ||
764 | } | ||
765 | } | ||
766 | smtc_ipi_nq(&IPIQ[cpu], pipi); | ||
767 | } else { | ||
768 | post_direct_ipi(cpu, pipi); | ||
769 | write_tc_c0_tchalt(0); | ||
770 | UNLOCK_CORE_PRA(); | ||
771 | } | ||
772 | } | ||
773 | } | ||
774 | |||
775 | /* | ||
776 | * Send IPI message to Halted TC, TargTC/TargVPE already having been set | ||
777 | */ | ||
778 | void post_direct_ipi(int cpu, struct smtc_ipi *pipi) | ||
779 | { | ||
780 | struct pt_regs *kstack; | ||
781 | unsigned long tcstatus; | ||
782 | unsigned long tcrestart; | ||
783 | extern u32 kernelsp[NR_CPUS]; | ||
784 | extern void __smtc_ipi_vector(void); | ||
785 | |||
786 | /* Extract Status, EPC from halted TC */ | ||
787 | tcstatus = read_tc_c0_tcstatus(); | ||
788 | tcrestart = read_tc_c0_tcrestart(); | ||
789 | /* If TCRestart indicates a WAIT instruction, advance the PC */ | ||
790 | if ((tcrestart & 0x80000000) | ||
791 | && ((*(unsigned int *)tcrestart & 0xfe00003f) == 0x42000020)) { | ||
792 | tcrestart += 4; | ||
793 | } | ||
794 | /* | ||
795 | * Save on TC's future kernel stack | ||
796 | * | ||
797 | * CU bit of Status is indicator that TC was | ||
798 | * already running on a kernel stack... | ||
799 | */ | ||
800 | if(tcstatus & ST0_CU0) { | ||
801 | /* Note that this "- 1" is pointer arithmetic */ | ||
802 | kstack = ((struct pt_regs *)read_tc_gpr_sp()) - 1; | ||
803 | } else { | ||
804 | kstack = ((struct pt_regs *)kernelsp[cpu]) - 1; | ||
805 | } | ||
806 | |||
807 | kstack->cp0_epc = (long)tcrestart; | ||
808 | /* Save TCStatus */ | ||
809 | kstack->cp0_tcstatus = tcstatus; | ||
810 | /* Pass token of operation to be performed kernel stack pad area */ | ||
811 | kstack->pad0[4] = (unsigned long)pipi; | ||
812 | /* Pass address of function to be called likewise */ | ||
813 | kstack->pad0[5] = (unsigned long)&ipi_decode; | ||
814 | /* Set interrupt exempt and kernel mode */ | ||
815 | tcstatus |= TCSTATUS_IXMT; | ||
816 | tcstatus &= ~TCSTATUS_TKSU; | ||
817 | write_tc_c0_tcstatus(tcstatus); | ||
818 | ehb(); | ||
819 | /* Set TC Restart address to be SMTC IPI vector */ | ||
820 | write_tc_c0_tcrestart(__smtc_ipi_vector); | ||
821 | } | ||
822 | |||
823 | void ipi_resched_interrupt(struct pt_regs *regs) | ||
824 | { | ||
825 | /* Return from interrupt should be enough to cause scheduler check */ | ||
826 | } | ||
827 | |||
828 | |||
829 | void ipi_call_interrupt(struct pt_regs *regs) | ||
830 | { | ||
831 | /* Invoke generic function invocation code in smp.c */ | ||
832 | smp_call_function_interrupt(); | ||
833 | } | ||
834 | |||
835 | void ipi_decode(struct pt_regs *regs, struct smtc_ipi *pipi) | ||
836 | { | ||
837 | void *arg_copy = pipi->arg; | ||
838 | int type_copy = pipi->type; | ||
839 | int dest_copy = pipi->dest; | ||
840 | |||
841 | smtc_ipi_nq(&freeIPIq, pipi); | ||
842 | switch (type_copy) { | ||
843 | case SMTC_CLOCK_TICK: | ||
844 | /* Invoke Clock "Interrupt" */ | ||
845 | ipi_timer_latch[dest_copy] = 0; | ||
846 | #ifdef SMTC_IDLE_HOOK_DEBUG | ||
847 | clock_hang_reported[dest_copy] = 0; | ||
848 | #endif /* SMTC_IDLE_HOOK_DEBUG */ | ||
849 | local_timer_interrupt(0, NULL, regs); | ||
850 | break; | ||
851 | case LINUX_SMP_IPI: | ||
852 | switch ((int)arg_copy) { | ||
853 | case SMP_RESCHEDULE_YOURSELF: | ||
854 | ipi_resched_interrupt(regs); | ||
855 | break; | ||
856 | case SMP_CALL_FUNCTION: | ||
857 | ipi_call_interrupt(regs); | ||
858 | break; | ||
859 | default: | ||
860 | printk("Impossible SMTC IPI Argument 0x%x\n", | ||
861 | (int)arg_copy); | ||
862 | break; | ||
863 | } | ||
864 | break; | ||
865 | default: | ||
866 | printk("Impossible SMTC IPI Type 0x%x\n", type_copy); | ||
867 | break; | ||
868 | } | ||
869 | } | ||
870 | |||
871 | void deferred_smtc_ipi(struct pt_regs *regs) | ||
872 | { | ||
873 | struct smtc_ipi *pipi; | ||
874 | unsigned long flags; | ||
875 | /* DEBUG */ | ||
876 | int q = smp_processor_id(); | ||
877 | |||
878 | /* | ||
879 | * Test is not atomic, but much faster than a dequeue, | ||
880 | * and the vast majority of invocations will have a null queue. | ||
881 | */ | ||
882 | if(IPIQ[q].head != NULL) { | ||
883 | while((pipi = smtc_ipi_dq(&IPIQ[q])) != NULL) { | ||
884 | /* ipi_decode() should be called with interrupts off */ | ||
885 | local_irq_save(flags); | ||
886 | ipi_decode(regs, pipi); | ||
887 | local_irq_restore(flags); | ||
888 | } | ||
889 | } | ||
890 | } | ||
891 | |||
892 | /* | ||
893 | * Send clock tick to all TCs except the one executing the funtion | ||
894 | */ | ||
895 | |||
896 | void smtc_timer_broadcast(int vpe) | ||
897 | { | ||
898 | int cpu; | ||
899 | int myTC = cpu_data[smp_processor_id()].tc_id; | ||
900 | int myVPE = cpu_data[smp_processor_id()].vpe_id; | ||
901 | |||
902 | smtc_cpu_stats[smp_processor_id()].timerints++; | ||
903 | |||
904 | for_each_online_cpu(cpu) { | ||
905 | if (cpu_data[cpu].vpe_id == myVPE && | ||
906 | cpu_data[cpu].tc_id != myTC) | ||
907 | smtc_send_ipi(cpu, SMTC_CLOCK_TICK, 0); | ||
908 | } | ||
909 | } | ||
910 | |||
911 | /* | ||
912 | * Cross-VPE interrupts in the SMTC prototype use "software interrupts" | ||
913 | * set via cross-VPE MTTR manipulation of the Cause register. It would be | ||
914 | * in some regards preferable to have external logic for "doorbell" hardware | ||
915 | * interrupts. | ||
916 | */ | ||
917 | |||
918 | static int cpu_ipi_irq = MIPSCPU_INT_BASE + MIPS_CPU_IPI_IRQ; | ||
919 | |||
920 | static irqreturn_t ipi_interrupt(int irq, void *dev_idm, struct pt_regs *regs) | ||
921 | { | ||
922 | int my_vpe = cpu_data[smp_processor_id()].vpe_id; | ||
923 | int my_tc = cpu_data[smp_processor_id()].tc_id; | ||
924 | int cpu; | ||
925 | struct smtc_ipi *pipi; | ||
926 | unsigned long tcstatus; | ||
927 | int sent; | ||
928 | long flags; | ||
929 | unsigned int mtflags; | ||
930 | unsigned int vpflags; | ||
931 | |||
932 | /* | ||
933 | * So long as cross-VPE interrupts are done via | ||
934 | * MFTR/MTTR read-modify-writes of Cause, we need | ||
935 | * to stop other VPEs whenever the local VPE does | ||
936 | * anything similar. | ||
937 | */ | ||
938 | local_irq_save(flags); | ||
939 | vpflags = dvpe(); | ||
940 | clear_c0_cause(0x100 << MIPS_CPU_IPI_IRQ); | ||
941 | set_c0_status(0x100 << MIPS_CPU_IPI_IRQ); | ||
942 | irq_enable_hazard(); | ||
943 | evpe(vpflags); | ||
944 | local_irq_restore(flags); | ||
945 | |||
946 | /* | ||
947 | * Cross-VPE Interrupt handler: Try to directly deliver IPIs | ||
948 | * queued for TCs on this VPE other than the current one. | ||
949 | * Return-from-interrupt should cause us to drain the queue | ||
950 | * for the current TC, so we ought not to have to do it explicitly here. | ||
951 | */ | ||
952 | |||
953 | for_each_online_cpu(cpu) { | ||
954 | if (cpu_data[cpu].vpe_id != my_vpe) | ||
955 | continue; | ||
956 | |||
957 | pipi = smtc_ipi_dq(&IPIQ[cpu]); | ||
958 | if (pipi != NULL) { | ||
959 | if (cpu_data[cpu].tc_id != my_tc) { | ||
960 | sent = 0; | ||
961 | LOCK_MT_PRA(); | ||
962 | settc(cpu_data[cpu].tc_id); | ||
963 | write_tc_c0_tchalt(TCHALT_H); | ||
964 | mips_ihb(); | ||
965 | tcstatus = read_tc_c0_tcstatus(); | ||
966 | if ((tcstatus & TCSTATUS_IXMT) == 0) { | ||
967 | post_direct_ipi(cpu, pipi); | ||
968 | sent = 1; | ||
969 | } | ||
970 | write_tc_c0_tchalt(0); | ||
971 | UNLOCK_MT_PRA(); | ||
972 | if (!sent) { | ||
973 | smtc_ipi_req(&IPIQ[cpu], pipi); | ||
974 | } | ||
975 | } else { | ||
976 | /* | ||
977 | * ipi_decode() should be called | ||
978 | * with interrupts off | ||
979 | */ | ||
980 | local_irq_save(flags); | ||
981 | ipi_decode(regs, pipi); | ||
982 | local_irq_restore(flags); | ||
983 | } | ||
984 | } | ||
985 | } | ||
986 | |||
987 | return IRQ_HANDLED; | ||
988 | } | ||
989 | |||
990 | static void ipi_irq_dispatch(struct pt_regs *regs) | ||
991 | { | ||
992 | do_IRQ(cpu_ipi_irq, regs); | ||
993 | } | ||
994 | |||
995 | static struct irqaction irq_ipi; | ||
996 | |||
997 | void setup_cross_vpe_interrupts(void) | ||
998 | { | ||
999 | if (!cpu_has_vint) | ||
1000 | panic("SMTC Kernel requires Vectored Interupt support"); | ||
1001 | |||
1002 | set_vi_handler(MIPS_CPU_IPI_IRQ, ipi_irq_dispatch); | ||
1003 | |||
1004 | irq_ipi.handler = ipi_interrupt; | ||
1005 | irq_ipi.flags = SA_INTERRUPT; | ||
1006 | irq_ipi.name = "SMTC_IPI"; | ||
1007 | |||
1008 | setup_irq_smtc(cpu_ipi_irq, &irq_ipi, (0x100 << MIPS_CPU_IPI_IRQ)); | ||
1009 | |||
1010 | irq_desc[cpu_ipi_irq].status |= IRQ_PER_CPU; | ||
1011 | } | ||
1012 | |||
1013 | /* | ||
1014 | * SMTC-specific hacks invoked from elsewhere in the kernel. | ||
1015 | */ | ||
1016 | |||
1017 | void smtc_idle_loop_hook(void) | ||
1018 | { | ||
1019 | #ifdef SMTC_IDLE_HOOK_DEBUG | ||
1020 | int im; | ||
1021 | int flags; | ||
1022 | int mtflags; | ||
1023 | int bit; | ||
1024 | int vpe; | ||
1025 | int tc; | ||
1026 | int hook_ntcs; | ||
1027 | /* | ||
1028 | * printk within DMT-protected regions can deadlock, | ||
1029 | * so buffer diagnostic messages for later output. | ||
1030 | */ | ||
1031 | char *pdb_msg; | ||
1032 | char id_ho_db_msg[768]; /* worst-case use should be less than 700 */ | ||
1033 | |||
1034 | if (atomic_read(&idle_hook_initialized) == 0) { /* fast test */ | ||
1035 | if (atomic_add_return(1, &idle_hook_initialized) == 1) { | ||
1036 | int mvpconf0; | ||
1037 | /* Tedious stuff to just do once */ | ||
1038 | mvpconf0 = read_c0_mvpconf0(); | ||
1039 | hook_ntcs = ((mvpconf0 & MVPCONF0_PTC) >> MVPCONF0_PTC_SHIFT) + 1; | ||
1040 | if (hook_ntcs > NR_CPUS) | ||
1041 | hook_ntcs = NR_CPUS; | ||
1042 | for (tc = 0; tc < hook_ntcs; tc++) { | ||
1043 | tcnoprog[tc] = 0; | ||
1044 | clock_hang_reported[tc] = 0; | ||
1045 | } | ||
1046 | for (vpe = 0; vpe < 2; vpe++) | ||
1047 | for (im = 0; im < 8; im++) | ||
1048 | imstuckcount[vpe][im] = 0; | ||
1049 | printk("Idle loop test hook initialized for %d TCs\n", hook_ntcs); | ||
1050 | atomic_set(&idle_hook_initialized, 1000); | ||
1051 | } else { | ||
1052 | /* Someone else is initializing in parallel - let 'em finish */ | ||
1053 | while (atomic_read(&idle_hook_initialized) < 1000) | ||
1054 | ; | ||
1055 | } | ||
1056 | } | ||
1057 | |||
1058 | /* Have we stupidly left IXMT set somewhere? */ | ||
1059 | if (read_c0_tcstatus() & 0x400) { | ||
1060 | write_c0_tcstatus(read_c0_tcstatus() & ~0x400); | ||
1061 | ehb(); | ||
1062 | printk("Dangling IXMT in cpu_idle()\n"); | ||
1063 | } | ||
1064 | |||
1065 | /* Have we stupidly left an IM bit turned off? */ | ||
1066 | #define IM_LIMIT 2000 | ||
1067 | local_irq_save(flags); | ||
1068 | mtflags = dmt(); | ||
1069 | pdb_msg = &id_ho_db_msg[0]; | ||
1070 | im = read_c0_status(); | ||
1071 | vpe = cpu_data[smp_processor_id()].vpe_id; | ||
1072 | for (bit = 0; bit < 8; bit++) { | ||
1073 | /* | ||
1074 | * In current prototype, I/O interrupts | ||
1075 | * are masked for VPE > 0 | ||
1076 | */ | ||
1077 | if (vpemask[vpe][bit]) { | ||
1078 | if (!(im & (0x100 << bit))) | ||
1079 | imstuckcount[vpe][bit]++; | ||
1080 | else | ||
1081 | imstuckcount[vpe][bit] = 0; | ||
1082 | if (imstuckcount[vpe][bit] > IM_LIMIT) { | ||
1083 | set_c0_status(0x100 << bit); | ||
1084 | ehb(); | ||
1085 | imstuckcount[vpe][bit] = 0; | ||
1086 | pdb_msg += sprintf(pdb_msg, | ||
1087 | "Dangling IM %d fixed for VPE %d\n", bit, | ||
1088 | vpe); | ||
1089 | } | ||
1090 | } | ||
1091 | } | ||
1092 | |||
1093 | /* | ||
1094 | * Now that we limit outstanding timer IPIs, check for hung TC | ||
1095 | */ | ||
1096 | for (tc = 0; tc < NR_CPUS; tc++) { | ||
1097 | /* Don't check ourself - we'll dequeue IPIs just below */ | ||
1098 | if ((tc != smp_processor_id()) && | ||
1099 | ipi_timer_latch[tc] > timerq_limit) { | ||
1100 | if (clock_hang_reported[tc] == 0) { | ||
1101 | pdb_msg += sprintf(pdb_msg, | ||
1102 | "TC %d looks hung with timer latch at %d\n", | ||
1103 | tc, ipi_timer_latch[tc]); | ||
1104 | clock_hang_reported[tc]++; | ||
1105 | } | ||
1106 | } | ||
1107 | } | ||
1108 | emt(mtflags); | ||
1109 | local_irq_restore(flags); | ||
1110 | if (pdb_msg != &id_ho_db_msg[0]) | ||
1111 | printk("CPU%d: %s", smp_processor_id(), id_ho_db_msg); | ||
1112 | #endif /* SMTC_IDLE_HOOK_DEBUG */ | ||
1113 | /* | ||
1114 | * To the extent that we've ever turned interrupts off, | ||
1115 | * we may have accumulated deferred IPIs. This is subtle. | ||
1116 | * If we use the smtc_ipi_qdepth() macro, we'll get an | ||
1117 | * exact number - but we'll also disable interrupts | ||
1118 | * and create a window of failure where a new IPI gets | ||
1119 | * queued after we test the depth but before we re-enable | ||
1120 | * interrupts. So long as IXMT never gets set, however, | ||
1121 | * we should be OK: If we pick up something and dispatch | ||
1122 | * it here, that's great. If we see nothing, but concurrent | ||
1123 | * with this operation, another TC sends us an IPI, IXMT | ||
1124 | * is clear, and we'll handle it as a real pseudo-interrupt | ||
1125 | * and not a pseudo-pseudo interrupt. | ||
1126 | */ | ||
1127 | if (IPIQ[smp_processor_id()].depth > 0) { | ||
1128 | struct smtc_ipi *pipi; | ||
1129 | extern void self_ipi(struct smtc_ipi *); | ||
1130 | |||
1131 | if ((pipi = smtc_ipi_dq(&IPIQ[smp_processor_id()])) != NULL) { | ||
1132 | self_ipi(pipi); | ||
1133 | smtc_cpu_stats[smp_processor_id()].selfipis++; | ||
1134 | } | ||
1135 | } | ||
1136 | } | ||
1137 | |||
1138 | void smtc_soft_dump(void) | ||
1139 | { | ||
1140 | int i; | ||
1141 | |||
1142 | printk("Counter Interrupts taken per CPU (TC)\n"); | ||
1143 | for (i=0; i < NR_CPUS; i++) { | ||
1144 | printk("%d: %ld\n", i, smtc_cpu_stats[i].timerints); | ||
1145 | } | ||
1146 | printk("Self-IPI invocations:\n"); | ||
1147 | for (i=0; i < NR_CPUS; i++) { | ||
1148 | printk("%d: %ld\n", i, smtc_cpu_stats[i].selfipis); | ||
1149 | } | ||
1150 | smtc_ipi_qdump(); | ||
1151 | printk("Timer IPI Backlogs:\n"); | ||
1152 | for (i=0; i < NR_CPUS; i++) { | ||
1153 | printk("%d: %d\n", i, ipi_timer_latch[i]); | ||
1154 | } | ||
1155 | printk("%d Recoveries of \"stolen\" FPU\n", | ||
1156 | atomic_read(&smtc_fpu_recoveries)); | ||
1157 | } | ||
1158 | |||
1159 | |||
1160 | /* | ||
1161 | * TLB management routines special to SMTC | ||
1162 | */ | ||
1163 | |||
1164 | void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | ||
1165 | { | ||
1166 | unsigned long flags, mtflags, tcstat, prevhalt, asid; | ||
1167 | int tlb, i; | ||
1168 | |||
1169 | /* | ||
1170 | * It would be nice to be able to use a spinlock here, | ||
1171 | * but this is invoked from within TLB flush routines | ||
1172 | * that protect themselves with DVPE, so if a lock is | ||
1173 | * held by another TC, it'll never be freed. | ||
1174 | * | ||
1175 | * DVPE/DMT must not be done with interrupts enabled, | ||
1176 | * so even so most callers will already have disabled | ||
1177 | * them, let's be really careful... | ||
1178 | */ | ||
1179 | |||
1180 | local_irq_save(flags); | ||
1181 | if (smtc_status & SMTC_TLB_SHARED) { | ||
1182 | mtflags = dvpe(); | ||
1183 | tlb = 0; | ||
1184 | } else { | ||
1185 | mtflags = dmt(); | ||
1186 | tlb = cpu_data[cpu].vpe_id; | ||
1187 | } | ||
1188 | asid = asid_cache(cpu); | ||
1189 | |||
1190 | do { | ||
1191 | if (!((asid += ASID_INC) & ASID_MASK) ) { | ||
1192 | if (cpu_has_vtag_icache) | ||
1193 | flush_icache_all(); | ||
1194 | /* Traverse all online CPUs (hack requires contigous range) */ | ||
1195 | for (i = 0; i < num_online_cpus(); i++) { | ||
1196 | /* | ||
1197 | * We don't need to worry about our own CPU, nor those of | ||
1198 | * CPUs who don't share our TLB. | ||
1199 | */ | ||
1200 | if ((i != smp_processor_id()) && | ||
1201 | ((smtc_status & SMTC_TLB_SHARED) || | ||
1202 | (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id))) { | ||
1203 | settc(cpu_data[i].tc_id); | ||
1204 | prevhalt = read_tc_c0_tchalt() & TCHALT_H; | ||
1205 | if (!prevhalt) { | ||
1206 | write_tc_c0_tchalt(TCHALT_H); | ||
1207 | mips_ihb(); | ||
1208 | } | ||
1209 | tcstat = read_tc_c0_tcstatus(); | ||
1210 | smtc_live_asid[tlb][(tcstat & ASID_MASK)] |= (asiduse)(0x1 << i); | ||
1211 | if (!prevhalt) | ||
1212 | write_tc_c0_tchalt(0); | ||
1213 | } | ||
1214 | } | ||
1215 | if (!asid) /* fix version if needed */ | ||
1216 | asid = ASID_FIRST_VERSION; | ||
1217 | local_flush_tlb_all(); /* start new asid cycle */ | ||
1218 | } | ||
1219 | } while (smtc_live_asid[tlb][(asid & ASID_MASK)]); | ||
1220 | |||
1221 | /* | ||
1222 | * SMTC shares the TLB within VPEs and possibly across all VPEs. | ||
1223 | */ | ||
1224 | for (i = 0; i < num_online_cpus(); i++) { | ||
1225 | if ((smtc_status & SMTC_TLB_SHARED) || | ||
1226 | (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id)) | ||
1227 | cpu_context(i, mm) = asid_cache(i) = asid; | ||
1228 | } | ||
1229 | |||
1230 | if (smtc_status & SMTC_TLB_SHARED) | ||
1231 | evpe(mtflags); | ||
1232 | else | ||
1233 | emt(mtflags); | ||
1234 | local_irq_restore(flags); | ||
1235 | } | ||
1236 | |||
1237 | /* | ||
1238 | * Invoked from macros defined in mmu_context.h | ||
1239 | * which must already have disabled interrupts | ||
1240 | * and done a DVPE or DMT as appropriate. | ||
1241 | */ | ||
1242 | |||
1243 | void smtc_flush_tlb_asid(unsigned long asid) | ||
1244 | { | ||
1245 | int entry; | ||
1246 | unsigned long ehi; | ||
1247 | |||
1248 | entry = read_c0_wired(); | ||
1249 | |||
1250 | /* Traverse all non-wired entries */ | ||
1251 | while (entry < current_cpu_data.tlbsize) { | ||
1252 | write_c0_index(entry); | ||
1253 | ehb(); | ||
1254 | tlb_read(); | ||
1255 | ehb(); | ||
1256 | ehi = read_c0_entryhi(); | ||
1257 | if((ehi & ASID_MASK) == asid) { | ||
1258 | /* | ||
1259 | * Invalidate only entries with specified ASID, | ||
1260 | * makiing sure all entries differ. | ||
1261 | */ | ||
1262 | write_c0_entryhi(CKSEG0 + (entry << (PAGE_SHIFT + 1))); | ||
1263 | write_c0_entrylo0(0); | ||
1264 | write_c0_entrylo1(0); | ||
1265 | mtc0_tlbw_hazard(); | ||
1266 | tlb_write_indexed(); | ||
1267 | } | ||
1268 | entry++; | ||
1269 | } | ||
1270 | write_c0_index(PARKED_INDEX); | ||
1271 | tlbw_use_hazard(); | ||
1272 | } | ||
1273 | |||
1274 | /* | ||
1275 | * Support for single-threading cache flush operations. | ||
1276 | */ | ||
1277 | |||
1278 | int halt_state_save[NR_CPUS]; | ||
1279 | |||
1280 | /* | ||
1281 | * To really, really be sure that nothing is being done | ||
1282 | * by other TCs, halt them all. This code assumes that | ||
1283 | * a DVPE has already been done, so while their Halted | ||
1284 | * state is theoretically architecturally unstable, in | ||
1285 | * practice, it's not going to change while we're looking | ||
1286 | * at it. | ||
1287 | */ | ||
1288 | |||
1289 | void smtc_cflush_lockdown(void) | ||
1290 | { | ||
1291 | int cpu; | ||
1292 | |||
1293 | for_each_online_cpu(cpu) { | ||
1294 | if (cpu != smp_processor_id()) { | ||
1295 | settc(cpu_data[cpu].tc_id); | ||
1296 | halt_state_save[cpu] = read_tc_c0_tchalt(); | ||
1297 | write_tc_c0_tchalt(TCHALT_H); | ||
1298 | } | ||
1299 | } | ||
1300 | mips_ihb(); | ||
1301 | } | ||
1302 | |||
1303 | /* It would be cheating to change the cpu_online states during a flush! */ | ||
1304 | |||
1305 | void smtc_cflush_release(void) | ||
1306 | { | ||
1307 | int cpu; | ||
1308 | |||
1309 | /* | ||
1310 | * Start with a hazard barrier to ensure | ||
1311 | * that all CACHE ops have played through. | ||
1312 | */ | ||
1313 | mips_ihb(); | ||
1314 | |||
1315 | for_each_online_cpu(cpu) { | ||
1316 | if (cpu != smp_processor_id()) { | ||
1317 | settc(cpu_data[cpu].tc_id); | ||
1318 | write_tc_c0_tchalt(halt_state_save[cpu]); | ||
1319 | } | ||
1320 | } | ||
1321 | mips_ihb(); | ||
1322 | } | ||
diff --git a/arch/mips/kernel/time.c b/arch/mips/kernel/time.c index 5e51a2d8f3f0..13ff4da598cd 100644 --- a/arch/mips/kernel/time.c +++ b/arch/mips/kernel/time.c | |||
@@ -116,8 +116,7 @@ static void c0_timer_ack(void) | |||
116 | write_c0_compare(expirelo); | 116 | write_c0_compare(expirelo); |
117 | 117 | ||
118 | /* Check to see if we have missed any timer interrupts. */ | 118 | /* Check to see if we have missed any timer interrupts. */ |
119 | count = read_c0_count(); | 119 | while (((count = read_c0_count()) - expirelo) < 0x7fffffff) { |
120 | if ((count - expirelo) < 0x7fffffff) { | ||
121 | /* missed_timer_count++; */ | 120 | /* missed_timer_count++; */ |
122 | expirelo = count + cycles_per_jiffy; | 121 | expirelo = count + cycles_per_jiffy; |
123 | write_c0_compare(expirelo); | 122 | write_c0_compare(expirelo); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index bed0eb6cf55d..4901f0a37fca 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/watch.h> | 42 | #include <asm/watch.h> |
43 | #include <asm/types.h> | 43 | #include <asm/types.h> |
44 | 44 | ||
45 | extern asmlinkage void handle_int(void); | ||
45 | extern asmlinkage void handle_tlbm(void); | 46 | extern asmlinkage void handle_tlbm(void); |
46 | extern asmlinkage void handle_tlbl(void); | 47 | extern asmlinkage void handle_tlbl(void); |
47 | extern asmlinkage void handle_tlbs(void); | 48 | extern asmlinkage void handle_tlbs(void); |
@@ -279,9 +280,16 @@ static DEFINE_SPINLOCK(die_lock); | |||
279 | NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) | 280 | NORET_TYPE void ATTRIB_NORET die(const char * str, struct pt_regs * regs) |
280 | { | 281 | { |
281 | static int die_counter; | 282 | static int die_counter; |
283 | #ifdef CONFIG_MIPS_MT_SMTC | ||
284 | unsigned long dvpret = dvpe(); | ||
285 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
282 | 286 | ||
283 | console_verbose(); | 287 | console_verbose(); |
284 | spin_lock_irq(&die_lock); | 288 | spin_lock_irq(&die_lock); |
289 | bust_spinlocks(1); | ||
290 | #ifdef CONFIG_MIPS_MT_SMTC | ||
291 | mips_mt_regdump(dvpret); | ||
292 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
285 | printk("%s[#%d]:\n", str, ++die_counter); | 293 | printk("%s[#%d]:\n", str, ++die_counter); |
286 | show_registers(regs); | 294 | show_registers(regs); |
287 | spin_unlock_irq(&die_lock); | 295 | spin_unlock_irq(&die_lock); |
@@ -750,12 +758,43 @@ asmlinkage void do_cpu(struct pt_regs *regs) | |||
750 | ¤t->thread.fpu.soft); | 758 | ¤t->thread.fpu.soft); |
751 | if (sig) | 759 | if (sig) |
752 | force_sig(sig, current); | 760 | force_sig(sig, current); |
761 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
762 | else { | ||
763 | /* | ||
764 | * MIPS MT processors may have fewer FPU contexts | ||
765 | * than CPU threads. If we've emulated more than | ||
766 | * some threshold number of instructions, force | ||
767 | * migration to a "CPU" that has FP support. | ||
768 | */ | ||
769 | if(mt_fpemul_threshold > 0 | ||
770 | && ((current->thread.emulated_fp++ | ||
771 | > mt_fpemul_threshold))) { | ||
772 | /* | ||
773 | * If there's no FPU present, or if the | ||
774 | * application has already restricted | ||
775 | * the allowed set to exclude any CPUs | ||
776 | * with FPUs, we'll skip the procedure. | ||
777 | */ | ||
778 | if (cpus_intersects(current->cpus_allowed, | ||
779 | mt_fpu_cpumask)) { | ||
780 | cpumask_t tmask; | ||
781 | |||
782 | cpus_and(tmask, | ||
783 | current->thread.user_cpus_allowed, | ||
784 | mt_fpu_cpumask); | ||
785 | set_cpus_allowed(current, tmask); | ||
786 | current->thread.mflags |= MF_FPUBOUND; | ||
787 | } | ||
788 | } | ||
789 | } | ||
790 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
753 | } | 791 | } |
754 | 792 | ||
755 | return; | 793 | return; |
756 | 794 | ||
757 | case 2: | 795 | case 2: |
758 | case 3: | 796 | case 3: |
797 | die_if_kernel("do_cpu invoked from kernel context!", regs); | ||
759 | break; | 798 | break; |
760 | } | 799 | } |
761 | 800 | ||
@@ -793,6 +832,36 @@ asmlinkage void do_mcheck(struct pt_regs *regs) | |||
793 | 832 | ||
794 | asmlinkage void do_mt(struct pt_regs *regs) | 833 | asmlinkage void do_mt(struct pt_regs *regs) |
795 | { | 834 | { |
835 | int subcode; | ||
836 | |||
837 | die_if_kernel("MIPS MT Thread exception in kernel", regs); | ||
838 | |||
839 | subcode = (read_vpe_c0_vpecontrol() & VPECONTROL_EXCPT) | ||
840 | >> VPECONTROL_EXCPT_SHIFT; | ||
841 | switch (subcode) { | ||
842 | case 0: | ||
843 | printk(KERN_ERR "Thread Underflow\n"); | ||
844 | break; | ||
845 | case 1: | ||
846 | printk(KERN_ERR "Thread Overflow\n"); | ||
847 | break; | ||
848 | case 2: | ||
849 | printk(KERN_ERR "Invalid YIELD Qualifier\n"); | ||
850 | break; | ||
851 | case 3: | ||
852 | printk(KERN_ERR "Gating Storage Exception\n"); | ||
853 | break; | ||
854 | case 4: | ||
855 | printk(KERN_ERR "YIELD Scheduler Exception\n"); | ||
856 | break; | ||
857 | case 5: | ||
858 | printk(KERN_ERR "Gating Storage Schedulier Exception\n"); | ||
859 | break; | ||
860 | default: | ||
861 | printk(KERN_ERR "*** UNKNOWN THREAD EXCEPTION %d ***\n", | ||
862 | subcode); | ||
863 | break; | ||
864 | } | ||
796 | die_if_kernel("MIPS MT Thread exception in kernel", regs); | 865 | die_if_kernel("MIPS MT Thread exception in kernel", regs); |
797 | 866 | ||
798 | force_sig(SIGILL, current); | 867 | force_sig(SIGILL, current); |
@@ -928,7 +997,15 @@ void ejtag_exception_handler(struct pt_regs *regs) | |||
928 | */ | 997 | */ |
929 | void nmi_exception_handler(struct pt_regs *regs) | 998 | void nmi_exception_handler(struct pt_regs *regs) |
930 | { | 999 | { |
1000 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1001 | unsigned long dvpret = dvpe(); | ||
1002 | bust_spinlocks(1); | ||
1003 | printk("NMI taken!!!!\n"); | ||
1004 | mips_mt_regdump(dvpret); | ||
1005 | #else | ||
1006 | bust_spinlocks(1); | ||
931 | printk("NMI taken!!!!\n"); | 1007 | printk("NMI taken!!!!\n"); |
1008 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
932 | die("NMI", regs); | 1009 | die("NMI", regs); |
933 | while(1) ; | 1010 | while(1) ; |
934 | } | 1011 | } |
@@ -960,27 +1037,29 @@ void *set_except_vector(int n, void *addr) | |||
960 | 1037 | ||
961 | #ifdef CONFIG_CPU_MIPSR2 | 1038 | #ifdef CONFIG_CPU_MIPSR2 |
962 | /* | 1039 | /* |
963 | * Shadow register allocation | 1040 | * MIPSR2 shadow register set allocation |
964 | * FIXME: SMP... | 1041 | * FIXME: SMP... |
965 | */ | 1042 | */ |
966 | 1043 | ||
967 | /* MIPSR2 shadow register sets */ | 1044 | static struct shadow_registers { |
968 | struct shadow_registers { | 1045 | /* |
969 | spinlock_t sr_lock; /* */ | 1046 | * Number of shadow register sets supported |
970 | int sr_supported; /* Number of shadow register sets supported */ | 1047 | */ |
971 | int sr_allocated; /* Bitmap of allocated shadow registers */ | 1048 | unsigned long sr_supported; |
1049 | /* | ||
1050 | * Bitmap of allocated shadow registers | ||
1051 | */ | ||
1052 | unsigned long sr_allocated; | ||
972 | } shadow_registers; | 1053 | } shadow_registers; |
973 | 1054 | ||
974 | void mips_srs_init(void) | 1055 | static void mips_srs_init(void) |
975 | { | 1056 | { |
976 | #ifdef CONFIG_CPU_MIPSR2_SRS | 1057 | #ifdef CONFIG_CPU_MIPSR2_SRS |
977 | shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; | 1058 | shadow_registers.sr_supported = ((read_c0_srsctl() >> 26) & 0x0f) + 1; |
978 | printk ("%d MIPSR2 register sets available\n", shadow_registers.sr_supported); | 1059 | printk(KERN_INFO "%d MIPSR2 register sets available\n", |
979 | #else | 1060 | shadow_registers.sr_supported); |
980 | shadow_registers.sr_supported = 1; | ||
981 | #endif | 1061 | #endif |
982 | shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ | 1062 | shadow_registers.sr_allocated = 1; /* Set 0 used by kernel */ |
983 | spin_lock_init(&shadow_registers.sr_lock); | ||
984 | } | 1063 | } |
985 | 1064 | ||
986 | int mips_srs_max(void) | 1065 | int mips_srs_max(void) |
@@ -988,38 +1067,30 @@ int mips_srs_max(void) | |||
988 | return shadow_registers.sr_supported; | 1067 | return shadow_registers.sr_supported; |
989 | } | 1068 | } |
990 | 1069 | ||
991 | int mips_srs_alloc (void) | 1070 | int mips_srs_alloc(void) |
992 | { | 1071 | { |
993 | struct shadow_registers *sr = &shadow_registers; | 1072 | struct shadow_registers *sr = &shadow_registers; |
994 | unsigned long flags; | ||
995 | int set; | 1073 | int set; |
996 | 1074 | ||
997 | spin_lock_irqsave(&sr->sr_lock, flags); | 1075 | again: |
1076 | set = find_first_zero_bit(&sr->sr_allocated, sr->sr_supported); | ||
1077 | if (set >= sr->sr_supported) | ||
1078 | return -1; | ||
998 | 1079 | ||
999 | for (set = 0; set < sr->sr_supported; set++) { | 1080 | if (test_and_set_bit(set, &sr->sr_allocated)) |
1000 | if ((sr->sr_allocated & (1 << set)) == 0) { | 1081 | goto again; |
1001 | sr->sr_allocated |= 1 << set; | ||
1002 | spin_unlock_irqrestore(&sr->sr_lock, flags); | ||
1003 | return set; | ||
1004 | } | ||
1005 | } | ||
1006 | 1082 | ||
1007 | /* None available */ | 1083 | return set; |
1008 | spin_unlock_irqrestore(&sr->sr_lock, flags); | ||
1009 | return -1; | ||
1010 | } | 1084 | } |
1011 | 1085 | ||
1012 | void mips_srs_free (int set) | 1086 | void mips_srs_free(int set) |
1013 | { | 1087 | { |
1014 | struct shadow_registers *sr = &shadow_registers; | 1088 | struct shadow_registers *sr = &shadow_registers; |
1015 | unsigned long flags; | ||
1016 | 1089 | ||
1017 | spin_lock_irqsave(&sr->sr_lock, flags); | 1090 | clear_bit(set, &sr->sr_allocated); |
1018 | sr->sr_allocated &= ~(1 << set); | ||
1019 | spin_unlock_irqrestore(&sr->sr_lock, flags); | ||
1020 | } | 1091 | } |
1021 | 1092 | ||
1022 | void *set_vi_srs_handler (int n, void *addr, int srs) | 1093 | static void *set_vi_srs_handler(int n, void *addr, int srs) |
1023 | { | 1094 | { |
1024 | unsigned long handler; | 1095 | unsigned long handler; |
1025 | unsigned long old_handler = vi_handlers[n]; | 1096 | unsigned long old_handler = vi_handlers[n]; |
@@ -1032,8 +1103,7 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1032 | if (addr == NULL) { | 1103 | if (addr == NULL) { |
1033 | handler = (unsigned long) do_default_vi; | 1104 | handler = (unsigned long) do_default_vi; |
1034 | srs = 0; | 1105 | srs = 0; |
1035 | } | 1106 | } else |
1036 | else | ||
1037 | handler = (unsigned long) addr; | 1107 | handler = (unsigned long) addr; |
1038 | vi_handlers[n] = (unsigned long) addr; | 1108 | vi_handlers[n] = (unsigned long) addr; |
1039 | 1109 | ||
@@ -1045,8 +1115,7 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1045 | if (cpu_has_veic) { | 1115 | if (cpu_has_veic) { |
1046 | if (board_bind_eic_interrupt) | 1116 | if (board_bind_eic_interrupt) |
1047 | board_bind_eic_interrupt (n, srs); | 1117 | board_bind_eic_interrupt (n, srs); |
1048 | } | 1118 | } else if (cpu_has_vint) { |
1049 | else if (cpu_has_vint) { | ||
1050 | /* SRSMap is only defined if shadow sets are implemented */ | 1119 | /* SRSMap is only defined if shadow sets are implemented */ |
1051 | if (mips_srs_max() > 1) | 1120 | if (mips_srs_max() > 1) |
1052 | change_c0_srsmap (0xf << n*4, srs << n*4); | 1121 | change_c0_srsmap (0xf << n*4, srs << n*4); |
@@ -1060,6 +1129,15 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1060 | 1129 | ||
1061 | extern char except_vec_vi, except_vec_vi_lui; | 1130 | extern char except_vec_vi, except_vec_vi_lui; |
1062 | extern char except_vec_vi_ori, except_vec_vi_end; | 1131 | extern char except_vec_vi_ori, except_vec_vi_end; |
1132 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1133 | /* | ||
1134 | * We need to provide the SMTC vectored interrupt handler | ||
1135 | * not only with the address of the handler, but with the | ||
1136 | * Status.IM bit to be masked before going there. | ||
1137 | */ | ||
1138 | extern char except_vec_vi_mori; | ||
1139 | const int mori_offset = &except_vec_vi_mori - &except_vec_vi; | ||
1140 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1063 | const int handler_len = &except_vec_vi_end - &except_vec_vi; | 1141 | const int handler_len = &except_vec_vi_end - &except_vec_vi; |
1064 | const int lui_offset = &except_vec_vi_lui - &except_vec_vi; | 1142 | const int lui_offset = &except_vec_vi_lui - &except_vec_vi; |
1065 | const int ori_offset = &except_vec_vi_ori - &except_vec_vi; | 1143 | const int ori_offset = &except_vec_vi_ori - &except_vec_vi; |
@@ -1073,6 +1151,12 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1073 | } | 1151 | } |
1074 | 1152 | ||
1075 | memcpy (b, &except_vec_vi, handler_len); | 1153 | memcpy (b, &except_vec_vi, handler_len); |
1154 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1155 | if (n > 7) | ||
1156 | printk("Vector index %d exceeds SMTC maximum\n", n); | ||
1157 | w = (u32 *)(b + mori_offset); | ||
1158 | *w = (*w & 0xffff0000) | (0x100 << n); | ||
1159 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1076 | w = (u32 *)(b + lui_offset); | 1160 | w = (u32 *)(b + lui_offset); |
1077 | *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff); | 1161 | *w = (*w & 0xffff0000) | (((u32)handler >> 16) & 0xffff); |
1078 | w = (u32 *)(b + ori_offset); | 1162 | w = (u32 *)(b + ori_offset); |
@@ -1095,9 +1179,9 @@ void *set_vi_srs_handler (int n, void *addr, int srs) | |||
1095 | return (void *)old_handler; | 1179 | return (void *)old_handler; |
1096 | } | 1180 | } |
1097 | 1181 | ||
1098 | void *set_vi_handler (int n, void *addr) | 1182 | void *set_vi_handler(int n, void *addr) |
1099 | { | 1183 | { |
1100 | return set_vi_srs_handler (n, addr, 0); | 1184 | return set_vi_srs_handler(n, addr, 0); |
1101 | } | 1185 | } |
1102 | #endif | 1186 | #endif |
1103 | 1187 | ||
@@ -1113,8 +1197,29 @@ extern asmlinkage int _restore_fp_context(struct sigcontext *sc); | |||
1113 | extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); | 1197 | extern asmlinkage int fpu_emulator_save_context(struct sigcontext *sc); |
1114 | extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); | 1198 | extern asmlinkage int fpu_emulator_restore_context(struct sigcontext *sc); |
1115 | 1199 | ||
1200 | #ifdef CONFIG_SMP | ||
1201 | static int smp_save_fp_context(struct sigcontext *sc) | ||
1202 | { | ||
1203 | return cpu_has_fpu | ||
1204 | ? _save_fp_context(sc) | ||
1205 | : fpu_emulator_save_context(sc); | ||
1206 | } | ||
1207 | |||
1208 | static int smp_restore_fp_context(struct sigcontext *sc) | ||
1209 | { | ||
1210 | return cpu_has_fpu | ||
1211 | ? _restore_fp_context(sc) | ||
1212 | : fpu_emulator_restore_context(sc); | ||
1213 | } | ||
1214 | #endif | ||
1215 | |||
1116 | static inline void signal_init(void) | 1216 | static inline void signal_init(void) |
1117 | { | 1217 | { |
1218 | #ifdef CONFIG_SMP | ||
1219 | /* For now just do the cpu_has_fpu check when the functions are invoked */ | ||
1220 | save_fp_context = smp_save_fp_context; | ||
1221 | restore_fp_context = smp_restore_fp_context; | ||
1222 | #else | ||
1118 | if (cpu_has_fpu) { | 1223 | if (cpu_has_fpu) { |
1119 | save_fp_context = _save_fp_context; | 1224 | save_fp_context = _save_fp_context; |
1120 | restore_fp_context = _restore_fp_context; | 1225 | restore_fp_context = _restore_fp_context; |
@@ -1122,6 +1227,7 @@ static inline void signal_init(void) | |||
1122 | save_fp_context = fpu_emulator_save_context; | 1227 | save_fp_context = fpu_emulator_save_context; |
1123 | restore_fp_context = fpu_emulator_restore_context; | 1228 | restore_fp_context = fpu_emulator_restore_context; |
1124 | } | 1229 | } |
1230 | #endif | ||
1125 | } | 1231 | } |
1126 | 1232 | ||
1127 | #ifdef CONFIG_MIPS32_COMPAT | 1233 | #ifdef CONFIG_MIPS32_COMPAT |
@@ -1158,6 +1264,20 @@ void __init per_cpu_trap_init(void) | |||
1158 | { | 1264 | { |
1159 | unsigned int cpu = smp_processor_id(); | 1265 | unsigned int cpu = smp_processor_id(); |
1160 | unsigned int status_set = ST0_CU0; | 1266 | unsigned int status_set = ST0_CU0; |
1267 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1268 | int secondaryTC = 0; | ||
1269 | int bootTC = (cpu == 0); | ||
1270 | |||
1271 | /* | ||
1272 | * Only do per_cpu_trap_init() for first TC of Each VPE. | ||
1273 | * Note that this hack assumes that the SMTC init code | ||
1274 | * assigns TCs consecutively and in ascending order. | ||
1275 | */ | ||
1276 | |||
1277 | if (((read_c0_tcbind() & TCBIND_CURTC) != 0) && | ||
1278 | ((read_c0_tcbind() & TCBIND_CURVPE) == cpu_data[cpu - 1].vpe_id)) | ||
1279 | secondaryTC = 1; | ||
1280 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1161 | 1281 | ||
1162 | /* | 1282 | /* |
1163 | * Disable coprocessors and select 32-bit or 64-bit addressing | 1283 | * Disable coprocessors and select 32-bit or 64-bit addressing |
@@ -1180,6 +1300,10 @@ void __init per_cpu_trap_init(void) | |||
1180 | write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */ | 1300 | write_c0_hwrena (0x0000000f); /* Allow rdhwr to all registers */ |
1181 | #endif | 1301 | #endif |
1182 | 1302 | ||
1303 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1304 | if (!secondaryTC) { | ||
1305 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1306 | |||
1183 | /* | 1307 | /* |
1184 | * Interrupt handling. | 1308 | * Interrupt handling. |
1185 | */ | 1309 | */ |
@@ -1196,6 +1320,9 @@ void __init per_cpu_trap_init(void) | |||
1196 | } else | 1320 | } else |
1197 | set_c0_cause(CAUSEF_IV); | 1321 | set_c0_cause(CAUSEF_IV); |
1198 | } | 1322 | } |
1323 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1324 | } | ||
1325 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1199 | 1326 | ||
1200 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; | 1327 | cpu_data[cpu].asid_cache = ASID_FIRST_VERSION; |
1201 | TLBMISS_HANDLER_SETUP(); | 1328 | TLBMISS_HANDLER_SETUP(); |
@@ -1205,8 +1332,14 @@ void __init per_cpu_trap_init(void) | |||
1205 | BUG_ON(current->mm); | 1332 | BUG_ON(current->mm); |
1206 | enter_lazy_tlb(&init_mm, current); | 1333 | enter_lazy_tlb(&init_mm, current); |
1207 | 1334 | ||
1208 | cpu_cache_init(); | 1335 | #ifdef CONFIG_MIPS_MT_SMTC |
1209 | tlb_init(); | 1336 | if (bootTC) { |
1337 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1338 | cpu_cache_init(); | ||
1339 | tlb_init(); | ||
1340 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1341 | } | ||
1342 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
1210 | } | 1343 | } |
1211 | 1344 | ||
1212 | /* Install CPU exception handler */ | 1345 | /* Install CPU exception handler */ |
@@ -1278,7 +1411,7 @@ void __init trap_init(void) | |||
1278 | if (cpu_has_veic || cpu_has_vint) { | 1411 | if (cpu_has_veic || cpu_has_vint) { |
1279 | int nvec = cpu_has_veic ? 64 : 8; | 1412 | int nvec = cpu_has_veic ? 64 : 8; |
1280 | for (i = 0; i < nvec; i++) | 1413 | for (i = 0; i < nvec; i++) |
1281 | set_vi_handler (i, NULL); | 1414 | set_vi_handler(i, NULL); |
1282 | } | 1415 | } |
1283 | else if (cpu_has_divec) | 1416 | else if (cpu_has_divec) |
1284 | set_handler(0x200, &except_vec4, 0x8); | 1417 | set_handler(0x200, &except_vec4, 0x8); |
@@ -1297,6 +1430,7 @@ void __init trap_init(void) | |||
1297 | if (board_be_init) | 1430 | if (board_be_init) |
1298 | board_be_init(); | 1431 | board_be_init(); |
1299 | 1432 | ||
1433 | set_except_vector(0, handle_int); | ||
1300 | set_except_vector(1, handle_tlbm); | 1434 | set_except_vector(1, handle_tlbm); |
1301 | set_except_vector(2, handle_tlbl); | 1435 | set_except_vector(2, handle_tlbl); |
1302 | set_except_vector(3, handle_tlbs); | 1436 | set_except_vector(3, handle_tlbs); |
diff --git a/arch/mips/kernel/vmlinux.lds.S b/arch/mips/kernel/vmlinux.lds.S index 2ad0cedf29fe..14fa00e3cdfa 100644 --- a/arch/mips/kernel/vmlinux.lds.S +++ b/arch/mips/kernel/vmlinux.lds.S | |||
@@ -2,7 +2,7 @@ | |||
2 | #include <asm/asm-offsets.h> | 2 | #include <asm/asm-offsets.h> |
3 | #include <asm-generic/vmlinux.lds.h> | 3 | #include <asm-generic/vmlinux.lds.h> |
4 | 4 | ||
5 | #undef mips /* CPP really sucks for this job */ | 5 | #undef mips |
6 | #define mips mips | 6 | #define mips mips |
7 | OUTPUT_ARCH(mips) | 7 | OUTPUT_ARCH(mips) |
8 | ENTRY(kernel_entry) | 8 | ENTRY(kernel_entry) |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index ae83b755cf4a..80ffaa6d50ad 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -13,7 +13,6 @@ | |||
13 | * You should have received a copy of the GNU General Public License along | 13 | * You should have received a copy of the GNU General Public License along |
14 | * with this program; if not, write to the Free Software Foundation, Inc., | 14 | * with this program; if not, write to the Free Software Foundation, Inc., |
15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | 15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. |
16 | * | ||
17 | */ | 16 | */ |
18 | 17 | ||
19 | /* | 18 | /* |
@@ -27,11 +26,8 @@ | |||
27 | * | 26 | * |
28 | * To load and run, simply cat a SP 'program file' to /dev/vpe1. | 27 | * To load and run, simply cat a SP 'program file' to /dev/vpe1. |
29 | * i.e cat spapp >/dev/vpe1. | 28 | * i.e cat spapp >/dev/vpe1. |
30 | * | ||
31 | * You'll need to have the following device files. | ||
32 | * mknod /dev/vpe0 c 63 0 | ||
33 | * mknod /dev/vpe1 c 63 1 | ||
34 | */ | 29 | */ |
30 | |||
35 | #include <linux/config.h> | 31 | #include <linux/config.h> |
36 | #include <linux/kernel.h> | 32 | #include <linux/kernel.h> |
37 | #include <linux/module.h> | 33 | #include <linux/module.h> |
@@ -55,6 +51,8 @@ | |||
55 | #include <asm/cpu.h> | 51 | #include <asm/cpu.h> |
56 | #include <asm/processor.h> | 52 | #include <asm/processor.h> |
57 | #include <asm/system.h> | 53 | #include <asm/system.h> |
54 | #include <asm/vpe.h> | ||
55 | #include <asm/kspd.h> | ||
58 | 56 | ||
59 | typedef void *vpe_handle; | 57 | typedef void *vpe_handle; |
60 | 58 | ||
@@ -68,6 +66,11 @@ typedef void *vpe_handle; | |||
68 | static char module_name[] = "vpe"; | 66 | static char module_name[] = "vpe"; |
69 | static int major; | 67 | static int major; |
70 | 68 | ||
69 | #ifdef CONFIG_MIPS_APSP_KSPD | ||
70 | static struct kspd_notifications kspd_events; | ||
71 | static int kspd_events_reqd = 0; | ||
72 | #endif | ||
73 | |||
71 | /* grab the likely amount of memory we will need. */ | 74 | /* grab the likely amount of memory we will need. */ |
72 | #ifdef CONFIG_MIPS_VPE_LOADER_TOM | 75 | #ifdef CONFIG_MIPS_VPE_LOADER_TOM |
73 | #define P_SIZE (2 * 1024 * 1024) | 76 | #define P_SIZE (2 * 1024 * 1024) |
@@ -76,7 +79,10 @@ static int major; | |||
76 | #define P_SIZE (256 * 1024) | 79 | #define P_SIZE (256 * 1024) |
77 | #endif | 80 | #endif |
78 | 81 | ||
82 | extern unsigned long physical_memsize; | ||
83 | |||
79 | #define MAX_VPES 16 | 84 | #define MAX_VPES 16 |
85 | #define VPE_PATH_MAX 256 | ||
80 | 86 | ||
81 | enum vpe_state { | 87 | enum vpe_state { |
82 | VPE_STATE_UNUSED = 0, | 88 | VPE_STATE_UNUSED = 0, |
@@ -102,6 +108,8 @@ struct vpe { | |||
102 | unsigned long len; | 108 | unsigned long len; |
103 | char *pbuffer; | 109 | char *pbuffer; |
104 | unsigned long plen; | 110 | unsigned long plen; |
111 | unsigned int uid, gid; | ||
112 | char cwd[VPE_PATH_MAX]; | ||
105 | 113 | ||
106 | unsigned long __start; | 114 | unsigned long __start; |
107 | 115 | ||
@@ -113,6 +121,9 @@ struct vpe { | |||
113 | 121 | ||
114 | /* shared symbol address */ | 122 | /* shared symbol address */ |
115 | void *shared_ptr; | 123 | void *shared_ptr; |
124 | |||
125 | /* the list of who wants to know when something major happens */ | ||
126 | struct list_head notify; | ||
116 | }; | 127 | }; |
117 | 128 | ||
118 | struct tc { | 129 | struct tc { |
@@ -138,7 +149,7 @@ struct vpecontrol_ { | |||
138 | } vpecontrol; | 149 | } vpecontrol; |
139 | 150 | ||
140 | static void release_progmem(void *ptr); | 151 | static void release_progmem(void *ptr); |
141 | static void dump_vpe(struct vpe * v); | 152 | /* static __attribute_used__ void dump_vpe(struct vpe * v); */ |
142 | extern void save_gp_address(unsigned int secbase, unsigned int rel); | 153 | extern void save_gp_address(unsigned int secbase, unsigned int rel); |
143 | 154 | ||
144 | /* get the vpe associated with this minor */ | 155 | /* get the vpe associated with this minor */ |
@@ -146,12 +157,14 @@ struct vpe *get_vpe(int minor) | |||
146 | { | 157 | { |
147 | struct vpe *v; | 158 | struct vpe *v; |
148 | 159 | ||
160 | if (!cpu_has_mipsmt) | ||
161 | return NULL; | ||
162 | |||
149 | list_for_each_entry(v, &vpecontrol.vpe_list, list) { | 163 | list_for_each_entry(v, &vpecontrol.vpe_list, list) { |
150 | if (v->minor == minor) | 164 | if (v->minor == minor) |
151 | return v; | 165 | return v; |
152 | } | 166 | } |
153 | 167 | ||
154 | printk(KERN_DEBUG "VPE: get_vpe minor %d not found\n", minor); | ||
155 | return NULL; | 168 | return NULL; |
156 | } | 169 | } |
157 | 170 | ||
@@ -165,8 +178,6 @@ struct tc *get_tc(int index) | |||
165 | return t; | 178 | return t; |
166 | } | 179 | } |
167 | 180 | ||
168 | printk(KERN_DEBUG "VPE: get_tc index %d not found\n", index); | ||
169 | |||
170 | return NULL; | 181 | return NULL; |
171 | } | 182 | } |
172 | 183 | ||
@@ -179,8 +190,6 @@ struct tc *get_tc_unused(void) | |||
179 | return t; | 190 | return t; |
180 | } | 191 | } |
181 | 192 | ||
182 | printk(KERN_DEBUG "VPE: All TC's are in use\n"); | ||
183 | |||
184 | return NULL; | 193 | return NULL; |
185 | } | 194 | } |
186 | 195 | ||
@@ -190,13 +199,13 @@ struct vpe *alloc_vpe(int minor) | |||
190 | struct vpe *v; | 199 | struct vpe *v; |
191 | 200 | ||
192 | if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { | 201 | if ((v = kzalloc(sizeof(struct vpe), GFP_KERNEL)) == NULL) { |
193 | printk(KERN_WARNING "VPE: alloc_vpe no mem\n"); | ||
194 | return NULL; | 202 | return NULL; |
195 | } | 203 | } |
196 | 204 | ||
197 | INIT_LIST_HEAD(&v->tc); | 205 | INIT_LIST_HEAD(&v->tc); |
198 | list_add_tail(&v->list, &vpecontrol.vpe_list); | 206 | list_add_tail(&v->list, &vpecontrol.vpe_list); |
199 | 207 | ||
208 | INIT_LIST_HEAD(&v->notify); | ||
200 | v->minor = minor; | 209 | v->minor = minor; |
201 | return v; | 210 | return v; |
202 | } | 211 | } |
@@ -207,7 +216,6 @@ struct tc *alloc_tc(int index) | |||
207 | struct tc *t; | 216 | struct tc *t; |
208 | 217 | ||
209 | if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { | 218 | if ((t = kzalloc(sizeof(struct tc), GFP_KERNEL)) == NULL) { |
210 | printk(KERN_WARNING "VPE: alloc_tc no mem\n"); | ||
211 | return NULL; | 219 | return NULL; |
212 | } | 220 | } |
213 | 221 | ||
@@ -236,20 +244,16 @@ void dump_mtregs(void) | |||
236 | printk("config3 0x%lx MT %ld\n", val, | 244 | printk("config3 0x%lx MT %ld\n", val, |
237 | (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT); | 245 | (val & CONFIG3_MT) >> CONFIG3_MT_SHIFT); |
238 | 246 | ||
239 | val = read_c0_mvpconf0(); | ||
240 | printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val, | ||
241 | (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT, | ||
242 | val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT); | ||
243 | |||
244 | val = read_c0_mvpcontrol(); | 247 | val = read_c0_mvpcontrol(); |
245 | printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val, | 248 | printk("MVPControl 0x%lx, STLB %ld VPC %ld EVP %ld\n", val, |
246 | (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT, | 249 | (val & MVPCONTROL_STLB) >> MVPCONTROL_STLB_SHIFT, |
247 | (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT, | 250 | (val & MVPCONTROL_VPC) >> MVPCONTROL_VPC_SHIFT, |
248 | (val & MVPCONTROL_EVP)); | 251 | (val & MVPCONTROL_EVP)); |
249 | 252 | ||
250 | val = read_c0_vpeconf0(); | 253 | val = read_c0_mvpconf0(); |
251 | printk("VPEConf0 0x%lx MVP %ld\n", val, | 254 | printk("mvpconf0 0x%lx, PVPE %ld PTC %ld M %ld\n", val, |
252 | (val & VPECONF0_MVP) >> VPECONF0_MVP_SHIFT); | 255 | (val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT, |
256 | val & MVPCONF0_PTC, (val & MVPCONF0_M) >> MVPCONF0_M_SHIFT); | ||
253 | } | 257 | } |
254 | 258 | ||
255 | /* Find some VPE program space */ | 259 | /* Find some VPE program space */ |
@@ -354,9 +358,9 @@ static int apply_r_mips_gprel16(struct module *me, uint32_t *location, | |||
354 | } | 358 | } |
355 | 359 | ||
356 | if( (rel > 32768) || (rel < -32768) ) { | 360 | if( (rel > 32768) || (rel < -32768) ) { |
357 | printk(KERN_ERR | 361 | printk(KERN_DEBUG "VPE loader: apply_r_mips_gprel16: " |
358 | "apply_r_mips_gprel16: relative address out of range 0x%x %d\n", | 362 | "relative address 0x%x out of range of gp register\n", |
359 | rel, rel); | 363 | rel); |
360 | return -ENOEXEC; | 364 | return -ENOEXEC; |
361 | } | 365 | } |
362 | 366 | ||
@@ -374,8 +378,8 @@ static int apply_r_mips_pc16(struct module *me, uint32_t *location, | |||
374 | rel -= 1; // and one instruction less due to the branch delay slot. | 378 | rel -= 1; // and one instruction less due to the branch delay slot. |
375 | 379 | ||
376 | if( (rel > 32768) || (rel < -32768) ) { | 380 | if( (rel > 32768) || (rel < -32768) ) { |
377 | printk(KERN_ERR | 381 | printk(KERN_DEBUG "VPE loader: " |
378 | "apply_r_mips_pc16: relative address out of range 0x%x\n", rel); | 382 | "apply_r_mips_pc16: relative address out of range 0x%x\n", rel); |
379 | return -ENOEXEC; | 383 | return -ENOEXEC; |
380 | } | 384 | } |
381 | 385 | ||
@@ -396,7 +400,8 @@ static int apply_r_mips_26(struct module *me, uint32_t *location, | |||
396 | Elf32_Addr v) | 400 | Elf32_Addr v) |
397 | { | 401 | { |
398 | if (v % 4) { | 402 | if (v % 4) { |
399 | printk(KERN_ERR "module %s: dangerous relocation mod4\n", me->name); | 403 | printk(KERN_DEBUG "VPE loader: apply_r_mips_26 " |
404 | " unaligned relocation\n"); | ||
400 | return -ENOEXEC; | 405 | return -ENOEXEC; |
401 | } | 406 | } |
402 | 407 | ||
@@ -459,12 +464,13 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
459 | /* | 464 | /* |
460 | * The value for the HI16 had best be the same. | 465 | * The value for the HI16 had best be the same. |
461 | */ | 466 | */ |
462 | if (v != l->value) { | 467 | if (v != l->value) { |
463 | printk("%d != %d\n", v, l->value); | 468 | printk(KERN_DEBUG "VPE loader: " |
464 | goto out_danger; | 469 | "apply_r_mips_lo16/hi16: " |
470 | "inconsistent value information\n"); | ||
471 | return -ENOEXEC; | ||
465 | } | 472 | } |
466 | 473 | ||
467 | |||
468 | /* | 474 | /* |
469 | * Do the HI16 relocation. Note that we actually don't | 475 | * Do the HI16 relocation. Note that we actually don't |
470 | * need to know anything about the LO16 itself, except | 476 | * need to know anything about the LO16 itself, except |
@@ -500,11 +506,6 @@ static int apply_r_mips_lo16(struct module *me, uint32_t *location, | |||
500 | *location = insnlo; | 506 | *location = insnlo; |
501 | 507 | ||
502 | return 0; | 508 | return 0; |
503 | |||
504 | out_danger: | ||
505 | printk(KERN_ERR "module %s: dangerous " "relocation\n", me->name); | ||
506 | |||
507 | return -ENOEXEC; | ||
508 | } | 509 | } |
509 | 510 | ||
510 | static int (*reloc_handlers[]) (struct module *me, uint32_t *location, | 511 | static int (*reloc_handlers[]) (struct module *me, uint32_t *location, |
@@ -518,6 +519,15 @@ static int (*reloc_handlers[]) (struct module *me, uint32_t *location, | |||
518 | [R_MIPS_PC16] = apply_r_mips_pc16 | 519 | [R_MIPS_PC16] = apply_r_mips_pc16 |
519 | }; | 520 | }; |
520 | 521 | ||
522 | static char *rstrs[] = { | ||
523 | [R_MIPS_NONE] = "MIPS_NONE", | ||
524 | [R_MIPS_32] = "MIPS_32", | ||
525 | [R_MIPS_26] = "MIPS_26", | ||
526 | [R_MIPS_HI16] = "MIPS_HI16", | ||
527 | [R_MIPS_LO16] = "MIPS_LO16", | ||
528 | [R_MIPS_GPREL16] = "MIPS_GPREL16", | ||
529 | [R_MIPS_PC16] = "MIPS_PC16" | ||
530 | }; | ||
521 | 531 | ||
522 | int apply_relocations(Elf32_Shdr *sechdrs, | 532 | int apply_relocations(Elf32_Shdr *sechdrs, |
523 | const char *strtab, | 533 | const char *strtab, |
@@ -552,15 +562,13 @@ int apply_relocations(Elf32_Shdr *sechdrs, | |||
552 | 562 | ||
553 | res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v); | 563 | res = reloc_handlers[ELF32_R_TYPE(r_info)](me, location, v); |
554 | if( res ) { | 564 | if( res ) { |
555 | printk(KERN_DEBUG | 565 | char *r = rstrs[ELF32_R_TYPE(r_info)]; |
556 | "relocation error 0x%x sym refer <%s> value 0x%x " | 566 | printk(KERN_WARNING "VPE loader: .text+0x%x " |
557 | "type 0x%x r_info 0x%x\n", | 567 | "relocation type %s for symbol \"%s\" failed\n", |
558 | (unsigned int)location, strtab + sym->st_name, v, | 568 | rel[i].r_offset, r ? r : "UNKNOWN", |
559 | r_info, ELF32_R_TYPE(r_info)); | 569 | strtab + sym->st_name); |
560 | } | ||
561 | |||
562 | if (res) | ||
563 | return res; | 570 | return res; |
571 | } | ||
564 | } | 572 | } |
565 | 573 | ||
566 | return 0; | 574 | return 0; |
@@ -576,7 +584,7 @@ void save_gp_address(unsigned int secbase, unsigned int rel) | |||
576 | 584 | ||
577 | 585 | ||
578 | /* Change all symbols so that sh_value encodes the pointer directly. */ | 586 | /* Change all symbols so that sh_value encodes the pointer directly. */ |
579 | static int simplify_symbols(Elf_Shdr * sechdrs, | 587 | static void simplify_symbols(Elf_Shdr * sechdrs, |
580 | unsigned int symindex, | 588 | unsigned int symindex, |
581 | const char *strtab, | 589 | const char *strtab, |
582 | const char *secstrings, | 590 | const char *secstrings, |
@@ -585,18 +593,21 @@ static int simplify_symbols(Elf_Shdr * sechdrs, | |||
585 | Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; | 593 | Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr; |
586 | unsigned long secbase, bssbase = 0; | 594 | unsigned long secbase, bssbase = 0; |
587 | unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); | 595 | unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym); |
588 | int ret = 0, size; | 596 | int size; |
589 | 597 | ||
590 | /* find the .bss section for COMMON symbols */ | 598 | /* find the .bss section for COMMON symbols */ |
591 | for (i = 0; i < nsecs; i++) { | 599 | for (i = 0; i < nsecs; i++) { |
592 | if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0) | 600 | if (strncmp(secstrings + sechdrs[i].sh_name, ".bss", 4) == 0) { |
593 | bssbase = sechdrs[i].sh_addr; | 601 | bssbase = sechdrs[i].sh_addr; |
602 | break; | ||
603 | } | ||
594 | } | 604 | } |
595 | 605 | ||
596 | for (i = 1; i < n; i++) { | 606 | for (i = 1; i < n; i++) { |
597 | switch (sym[i].st_shndx) { | 607 | switch (sym[i].st_shndx) { |
598 | case SHN_COMMON: | 608 | case SHN_COMMON: |
599 | /* Allocate space for the symbol in the .bss section. st_value is currently size. | 609 | /* Allocate space for the symbol in the .bss section. |
610 | st_value is currently size. | ||
600 | We want it to have the address of the symbol. */ | 611 | We want it to have the address of the symbol. */ |
601 | 612 | ||
602 | size = sym[i].st_value; | 613 | size = sym[i].st_value; |
@@ -614,11 +625,9 @@ static int simplify_symbols(Elf_Shdr * sechdrs, | |||
614 | break; | 625 | break; |
615 | 626 | ||
616 | case SHN_MIPS_SCOMMON: | 627 | case SHN_MIPS_SCOMMON: |
617 | 628 | printk(KERN_DEBUG "simplify_symbols: ignoring SHN_MIPS_SCOMMON" | |
618 | printk(KERN_DEBUG | 629 | "symbol <%s> st_shndx %d\n", strtab + sym[i].st_name, |
619 | "simplify_symbols: ignoring SHN_MIPS_SCOMMON symbol <%s> st_shndx %d\n", | 630 | sym[i].st_shndx); |
620 | strtab + sym[i].st_name, sym[i].st_shndx); | ||
621 | |||
622 | // .sbss section | 631 | // .sbss section |
623 | break; | 632 | break; |
624 | 633 | ||
@@ -632,10 +641,7 @@ static int simplify_symbols(Elf_Shdr * sechdrs, | |||
632 | sym[i].st_value += secbase; | 641 | sym[i].st_value += secbase; |
633 | break; | 642 | break; |
634 | } | 643 | } |
635 | |||
636 | } | 644 | } |
637 | |||
638 | return ret; | ||
639 | } | 645 | } |
640 | 646 | ||
641 | #ifdef DEBUG_ELFLOADER | 647 | #ifdef DEBUG_ELFLOADER |
@@ -655,9 +661,26 @@ static void dump_elfsymbols(Elf_Shdr * sechdrs, unsigned int symindex, | |||
655 | 661 | ||
656 | static void dump_tc(struct tc *t) | 662 | static void dump_tc(struct tc *t) |
657 | { | 663 | { |
658 | printk(KERN_WARNING "VPE: TC index %d TCStatus 0x%lx halt 0x%lx\n", | 664 | unsigned long val; |
659 | t->index, read_tc_c0_tcstatus(), read_tc_c0_tchalt()); | 665 | |
660 | printk(KERN_WARNING "VPE: tcrestart 0x%lx\n", read_tc_c0_tcrestart()); | 666 | settc(t->index); |
667 | printk(KERN_DEBUG "VPE loader: TC index %d targtc %ld " | ||
668 | "TCStatus 0x%lx halt 0x%lx\n", | ||
669 | t->index, read_c0_vpecontrol() & VPECONTROL_TARGTC, | ||
670 | read_tc_c0_tcstatus(), read_tc_c0_tchalt()); | ||
671 | |||
672 | printk(KERN_DEBUG " tcrestart 0x%lx\n", read_tc_c0_tcrestart()); | ||
673 | printk(KERN_DEBUG " tcbind 0x%lx\n", read_tc_c0_tcbind()); | ||
674 | |||
675 | val = read_c0_vpeconf0(); | ||
676 | printk(KERN_DEBUG " VPEConf0 0x%lx MVP %ld\n", val, | ||
677 | (val & VPECONF0_MVP) >> VPECONF0_MVP_SHIFT); | ||
678 | |||
679 | printk(KERN_DEBUG " c0 status 0x%lx\n", read_vpe_c0_status()); | ||
680 | printk(KERN_DEBUG " c0 cause 0x%lx\n", read_vpe_c0_cause()); | ||
681 | |||
682 | printk(KERN_DEBUG " c0 badvaddr 0x%lx\n", read_vpe_c0_badvaddr()); | ||
683 | printk(KERN_DEBUG " c0 epc 0x%lx\n", read_vpe_c0_epc()); | ||
661 | } | 684 | } |
662 | 685 | ||
663 | static void dump_tclist(void) | 686 | static void dump_tclist(void) |
@@ -672,96 +695,108 @@ static void dump_tclist(void) | |||
672 | /* We are prepared so configure and start the VPE... */ | 695 | /* We are prepared so configure and start the VPE... */ |
673 | int vpe_run(struct vpe * v) | 696 | int vpe_run(struct vpe * v) |
674 | { | 697 | { |
675 | unsigned long val; | 698 | struct vpe_notifications *n; |
699 | unsigned long val, dmt_flag; | ||
676 | struct tc *t; | 700 | struct tc *t; |
677 | 701 | ||
678 | /* check we are the Master VPE */ | 702 | /* check we are the Master VPE */ |
679 | val = read_c0_vpeconf0(); | 703 | val = read_c0_vpeconf0(); |
680 | if (!(val & VPECONF0_MVP)) { | 704 | if (!(val & VPECONF0_MVP)) { |
681 | printk(KERN_WARNING | 705 | printk(KERN_WARNING |
682 | "VPE: only Master VPE's are allowed to configure MT\n"); | 706 | "VPE loader: only Master VPE's are allowed to configure MT\n"); |
683 | return -1; | 707 | return -1; |
684 | } | 708 | } |
685 | 709 | ||
686 | /* disable MT (using dvpe) */ | 710 | /* disable MT (using dvpe) */ |
687 | dvpe(); | 711 | dvpe(); |
688 | 712 | ||
713 | if (!list_empty(&v->tc)) { | ||
714 | if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) { | ||
715 | printk(KERN_WARNING "VPE loader: TC %d is already in use.\n", | ||
716 | t->index); | ||
717 | return -ENOEXEC; | ||
718 | } | ||
719 | } else { | ||
720 | printk(KERN_WARNING "VPE loader: No TC's associated with VPE %d\n", | ||
721 | v->minor); | ||
722 | return -ENOEXEC; | ||
723 | } | ||
724 | |||
689 | /* Put MVPE's into 'configuration state' */ | 725 | /* Put MVPE's into 'configuration state' */ |
690 | set_c0_mvpcontrol(MVPCONTROL_VPC); | 726 | set_c0_mvpcontrol(MVPCONTROL_VPC); |
691 | 727 | ||
692 | if (!list_empty(&v->tc)) { | ||
693 | if ((t = list_entry(v->tc.next, struct tc, tc)) == NULL) { | ||
694 | printk(KERN_WARNING "VPE: TC %d is already in use.\n", | ||
695 | t->index); | ||
696 | return -ENOEXEC; | ||
697 | } | ||
698 | } else { | ||
699 | printk(KERN_WARNING "VPE: No TC's associated with VPE %d\n", | ||
700 | v->minor); | ||
701 | return -ENOEXEC; | ||
702 | } | ||
703 | |||
704 | settc(t->index); | 728 | settc(t->index); |
705 | 729 | ||
706 | val = read_vpe_c0_vpeconf0(); | ||
707 | |||
708 | /* should check it is halted, and not activated */ | 730 | /* should check it is halted, and not activated */ |
709 | if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) { | 731 | if ((read_tc_c0_tcstatus() & TCSTATUS_A) || !(read_tc_c0_tchalt() & TCHALT_H)) { |
710 | printk(KERN_WARNING "VPE: TC %d is already doing something!\n", | 732 | printk(KERN_WARNING "VPE loader: TC %d is already doing something!\n", |
711 | t->index); | 733 | t->index); |
712 | |||
713 | dump_tclist(); | 734 | dump_tclist(); |
714 | return -ENOEXEC; | 735 | return -ENOEXEC; |
715 | } | 736 | } |
716 | 737 | ||
738 | /* | ||
739 | * Disable multi-threaded execution whilst we activate, clear the | ||
740 | * halt bit and bound the tc to the other VPE... | ||
741 | */ | ||
742 | dmt_flag = dmt(); | ||
743 | |||
717 | /* Write the address we want it to start running from in the TCPC register. */ | 744 | /* Write the address we want it to start running from in the TCPC register. */ |
718 | write_tc_c0_tcrestart((unsigned long)v->__start); | 745 | write_tc_c0_tcrestart((unsigned long)v->__start); |
719 | |||
720 | /* write the sivc_info address to tccontext */ | ||
721 | write_tc_c0_tccontext((unsigned long)0); | 746 | write_tc_c0_tccontext((unsigned long)0); |
722 | 747 | /* | |
723 | /* Set up the XTC bit in vpeconf0 to point at our tc */ | 748 | * Mark the TC as activated, not interrupt exempt and not dynamically |
724 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | (t->index << VPECONF0_XTC_SHIFT)); | 749 | * allocatable |
725 | 750 | */ | |
726 | /* mark the TC as activated, not interrupt exempt and not dynamically allocatable */ | ||
727 | val = read_tc_c0_tcstatus(); | 751 | val = read_tc_c0_tcstatus(); |
728 | val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A; | 752 | val = (val & ~(TCSTATUS_DA | TCSTATUS_IXMT)) | TCSTATUS_A; |
729 | write_tc_c0_tcstatus(val); | 753 | write_tc_c0_tcstatus(val); |
730 | 754 | ||
731 | write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H); | 755 | write_tc_c0_tchalt(read_tc_c0_tchalt() & ~TCHALT_H); |
732 | 756 | ||
733 | /* set up VPE1 */ | ||
734 | write_vpe_c0_vpecontrol(read_vpe_c0_vpecontrol() & ~VPECONTROL_TE); // no multiple TC's | ||
735 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); // enable this VPE | ||
736 | |||
737 | /* | 757 | /* |
738 | * The sde-kit passes 'memsize' to __start in $a3, so set something | 758 | * The sde-kit passes 'memsize' to __start in $a3, so set something |
739 | * here... | 759 | * here... Or set $a3 to zero and define DFLT_STACK_SIZE and |
740 | * Or set $a3 (register 7) to zero and define DFLT_STACK_SIZE and | ||
741 | * DFLT_HEAP_SIZE when you compile your program | 760 | * DFLT_HEAP_SIZE when you compile your program |
742 | */ | 761 | */ |
762 | mttgpr(7, physical_memsize); | ||
763 | |||
764 | |||
765 | /* set up VPE1 */ | ||
766 | /* | ||
767 | * bind the TC to VPE 1 as late as possible so we only have the final | ||
768 | * VPE registers to set up, and so an EJTAG probe can trigger on it | ||
769 | */ | ||
770 | write_tc_c0_tcbind((read_tc_c0_tcbind() & ~TCBIND_CURVPE) | v->minor); | ||
743 | 771 | ||
744 | mttgpr(7, 0); | 772 | /* Set up the XTC bit in vpeconf0 to point at our tc */ |
773 | write_vpe_c0_vpeconf0( (read_vpe_c0_vpeconf0() & ~(VPECONF0_XTC)) | ||
774 | | (t->index << VPECONF0_XTC_SHIFT)); | ||
745 | 775 | ||
746 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ | 776 | /* enable this VPE */ |
747 | write_vpe_c0_config(read_c0_config()); | 777 | write_vpe_c0_vpeconf0(read_vpe_c0_vpeconf0() | VPECONF0_VPA); |
748 | 778 | ||
749 | /* clear out any left overs from a previous program */ | 779 | /* clear out any left overs from a previous program */ |
780 | write_vpe_c0_status(0); | ||
750 | write_vpe_c0_cause(0); | 781 | write_vpe_c0_cause(0); |
751 | 782 | ||
752 | /* take system out of configuration state */ | 783 | /* take system out of configuration state */ |
753 | clear_c0_mvpcontrol(MVPCONTROL_VPC); | 784 | clear_c0_mvpcontrol(MVPCONTROL_VPC); |
754 | 785 | ||
755 | /* clear interrupts enabled IE, ERL, EXL, and KSU from c0 status */ | 786 | /* now safe to re-enable multi-threading */ |
756 | write_vpe_c0_status(read_vpe_c0_status() & ~(ST0_ERL | ST0_KSU | ST0_IE | ST0_EXL)); | 787 | emt(dmt_flag); |
757 | 788 | ||
758 | /* set it running */ | 789 | /* set it running */ |
759 | evpe(EVPE_ENABLE); | 790 | evpe(EVPE_ENABLE); |
760 | 791 | ||
792 | list_for_each_entry(n, &v->notify, list) { | ||
793 | n->start(v->minor); | ||
794 | } | ||
795 | |||
761 | return 0; | 796 | return 0; |
762 | } | 797 | } |
763 | 798 | ||
764 | static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs, | 799 | static int find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs, |
765 | unsigned int symindex, const char *strtab, | 800 | unsigned int symindex, const char *strtab, |
766 | struct module *mod) | 801 | struct module *mod) |
767 | { | 802 | { |
@@ -778,26 +813,28 @@ static unsigned long find_vpe_symbols(struct vpe * v, Elf_Shdr * sechdrs, | |||
778 | } | 813 | } |
779 | } | 814 | } |
780 | 815 | ||
816 | if ( (v->__start == 0) || (v->shared_ptr == NULL)) | ||
817 | return -1; | ||
818 | |||
781 | return 0; | 819 | return 0; |
782 | } | 820 | } |
783 | 821 | ||
784 | /* | 822 | /* |
785 | * Allocates a VPE with some program code space(the load address), copies | 823 | * Allocates a VPE with some program code space(the load address), copies the |
786 | * the contents of the program (p)buffer performing relocatations/etc, | 824 | * contents of the program (p)buffer performing relocatations/etc, free's it |
787 | * free's it when finished. | 825 | * when finished. |
788 | */ | 826 | */ |
789 | int vpe_elfload(struct vpe * v) | 827 | int vpe_elfload(struct vpe * v) |
790 | { | 828 | { |
791 | Elf_Ehdr *hdr; | 829 | Elf_Ehdr *hdr; |
792 | Elf_Shdr *sechdrs; | 830 | Elf_Shdr *sechdrs; |
793 | long err = 0; | 831 | long err = 0; |
794 | char *secstrings, *strtab = NULL; | 832 | char *secstrings, *strtab = NULL; |
795 | unsigned int len, i, symindex = 0, strindex = 0; | 833 | unsigned int len, i, symindex = 0, strindex = 0, relocate = 0; |
796 | |||
797 | struct module mod; // so we can re-use the relocations code | 834 | struct module mod; // so we can re-use the relocations code |
798 | 835 | ||
799 | memset(&mod, 0, sizeof(struct module)); | 836 | memset(&mod, 0, sizeof(struct module)); |
800 | strcpy(mod.name, "VPE dummy prog module"); | 837 | strcpy(mod.name, "VPE loader"); |
801 | 838 | ||
802 | hdr = (Elf_Ehdr *) v->pbuffer; | 839 | hdr = (Elf_Ehdr *) v->pbuffer; |
803 | len = v->plen; | 840 | len = v->plen; |
@@ -805,16 +842,22 @@ int vpe_elfload(struct vpe * v) | |||
805 | /* Sanity checks against insmoding binaries or wrong arch, | 842 | /* Sanity checks against insmoding binaries or wrong arch, |
806 | weird elf version */ | 843 | weird elf version */ |
807 | if (memcmp(hdr->e_ident, ELFMAG, 4) != 0 | 844 | if (memcmp(hdr->e_ident, ELFMAG, 4) != 0 |
808 | || hdr->e_type != ET_REL || !elf_check_arch(hdr) | 845 | || (hdr->e_type != ET_REL && hdr->e_type != ET_EXEC) |
846 | || !elf_check_arch(hdr) | ||
809 | || hdr->e_shentsize != sizeof(*sechdrs)) { | 847 | || hdr->e_shentsize != sizeof(*sechdrs)) { |
810 | printk(KERN_WARNING | 848 | printk(KERN_WARNING |
811 | "VPE program, wrong arch or weird elf version\n"); | 849 | "VPE loader: program wrong arch or weird elf version\n"); |
812 | 850 | ||
813 | return -ENOEXEC; | 851 | return -ENOEXEC; |
814 | } | 852 | } |
815 | 853 | ||
854 | if (hdr->e_type == ET_REL) | ||
855 | relocate = 1; | ||
856 | |||
816 | if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) { | 857 | if (len < hdr->e_shoff + hdr->e_shnum * sizeof(Elf_Shdr)) { |
817 | printk(KERN_ERR "VPE program length %u truncated\n", len); | 858 | printk(KERN_ERR "VPE loader: program length %u truncated\n", |
859 | len); | ||
860 | |||
818 | return -ENOEXEC; | 861 | return -ENOEXEC; |
819 | } | 862 | } |
820 | 863 | ||
@@ -826,82 +869,126 @@ int vpe_elfload(struct vpe * v) | |||
826 | /* And these should exist, but gcc whinges if we don't init them */ | 869 | /* And these should exist, but gcc whinges if we don't init them */ |
827 | symindex = strindex = 0; | 870 | symindex = strindex = 0; |
828 | 871 | ||
829 | for (i = 1; i < hdr->e_shnum; i++) { | 872 | if (relocate) { |
830 | 873 | for (i = 1; i < hdr->e_shnum; i++) { | |
831 | if (sechdrs[i].sh_type != SHT_NOBITS | 874 | if (sechdrs[i].sh_type != SHT_NOBITS |
832 | && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) { | 875 | && len < sechdrs[i].sh_offset + sechdrs[i].sh_size) { |
833 | printk(KERN_ERR "VPE program length %u truncated\n", | 876 | printk(KERN_ERR "VPE program length %u truncated\n", |
834 | len); | 877 | len); |
835 | return -ENOEXEC; | 878 | return -ENOEXEC; |
836 | } | 879 | } |
837 | 880 | ||
838 | /* Mark all sections sh_addr with their address in the | 881 | /* Mark all sections sh_addr with their address in the |
839 | temporary image. */ | 882 | temporary image. */ |
840 | sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset; | 883 | sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset; |
841 | 884 | ||
842 | /* Internal symbols and strings. */ | 885 | /* Internal symbols and strings. */ |
843 | if (sechdrs[i].sh_type == SHT_SYMTAB) { | 886 | if (sechdrs[i].sh_type == SHT_SYMTAB) { |
844 | symindex = i; | 887 | symindex = i; |
845 | strindex = sechdrs[i].sh_link; | 888 | strindex = sechdrs[i].sh_link; |
846 | strtab = (char *)hdr + sechdrs[strindex].sh_offset; | 889 | strtab = (char *)hdr + sechdrs[strindex].sh_offset; |
890 | } | ||
847 | } | 891 | } |
892 | layout_sections(&mod, hdr, sechdrs, secstrings); | ||
848 | } | 893 | } |
849 | 894 | ||
850 | layout_sections(&mod, hdr, sechdrs, secstrings); | ||
851 | |||
852 | v->load_addr = alloc_progmem(mod.core_size); | 895 | v->load_addr = alloc_progmem(mod.core_size); |
853 | memset(v->load_addr, 0, mod.core_size); | 896 | memset(v->load_addr, 0, mod.core_size); |
854 | 897 | ||
855 | printk("VPE elf_loader: loading to %p\n", v->load_addr); | 898 | printk("VPE loader: loading to %p\n", v->load_addr); |
856 | 899 | ||
857 | for (i = 0; i < hdr->e_shnum; i++) { | 900 | if (relocate) { |
858 | void *dest; | 901 | for (i = 0; i < hdr->e_shnum; i++) { |
902 | void *dest; | ||
859 | 903 | ||
860 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) | 904 | if (!(sechdrs[i].sh_flags & SHF_ALLOC)) |
861 | continue; | 905 | continue; |
862 | 906 | ||
863 | dest = v->load_addr + sechdrs[i].sh_entsize; | 907 | dest = v->load_addr + sechdrs[i].sh_entsize; |
864 | 908 | ||
865 | if (sechdrs[i].sh_type != SHT_NOBITS) | 909 | if (sechdrs[i].sh_type != SHT_NOBITS) |
866 | memcpy(dest, (void *)sechdrs[i].sh_addr, | 910 | memcpy(dest, (void *)sechdrs[i].sh_addr, |
867 | sechdrs[i].sh_size); | 911 | sechdrs[i].sh_size); |
868 | /* Update sh_addr to point to copy in image. */ | 912 | /* Update sh_addr to point to copy in image. */ |
869 | sechdrs[i].sh_addr = (unsigned long)dest; | 913 | sechdrs[i].sh_addr = (unsigned long)dest; |
870 | } | ||
871 | 914 | ||
872 | /* Fix up syms, so that st_value is a pointer to location. */ | 915 | printk(KERN_DEBUG " section sh_name %s sh_addr 0x%x\n", |
873 | err = | 916 | secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr); |
874 | simplify_symbols(sechdrs, symindex, strtab, secstrings, | 917 | } |
875 | hdr->e_shnum, &mod); | ||
876 | if (err < 0) { | ||
877 | printk(KERN_WARNING "VPE: unable to simplify symbols\n"); | ||
878 | goto cleanup; | ||
879 | } | ||
880 | 918 | ||
881 | /* Now do relocations. */ | 919 | /* Fix up syms, so that st_value is a pointer to location. */ |
882 | for (i = 1; i < hdr->e_shnum; i++) { | 920 | simplify_symbols(sechdrs, symindex, strtab, secstrings, |
883 | const char *strtab = (char *)sechdrs[strindex].sh_addr; | 921 | hdr->e_shnum, &mod); |
884 | unsigned int info = sechdrs[i].sh_info; | 922 | |
885 | 923 | /* Now do relocations. */ | |
886 | /* Not a valid relocation section? */ | 924 | for (i = 1; i < hdr->e_shnum; i++) { |
887 | if (info >= hdr->e_shnum) | 925 | const char *strtab = (char *)sechdrs[strindex].sh_addr; |
888 | continue; | 926 | unsigned int info = sechdrs[i].sh_info; |
889 | 927 | ||
890 | /* Don't bother with non-allocated sections */ | 928 | /* Not a valid relocation section? */ |
891 | if (!(sechdrs[info].sh_flags & SHF_ALLOC)) | 929 | if (info >= hdr->e_shnum) |
892 | continue; | 930 | continue; |
893 | 931 | ||
894 | if (sechdrs[i].sh_type == SHT_REL) | 932 | /* Don't bother with non-allocated sections */ |
895 | err = | 933 | if (!(sechdrs[info].sh_flags & SHF_ALLOC)) |
896 | apply_relocations(sechdrs, strtab, symindex, i, &mod); | 934 | continue; |
897 | else if (sechdrs[i].sh_type == SHT_RELA) | 935 | |
898 | err = apply_relocate_add(sechdrs, strtab, symindex, i, | 936 | if (sechdrs[i].sh_type == SHT_REL) |
899 | &mod); | 937 | err = apply_relocations(sechdrs, strtab, symindex, i, |
900 | if (err < 0) { | 938 | &mod); |
901 | printk(KERN_WARNING | 939 | else if (sechdrs[i].sh_type == SHT_RELA) |
902 | "vpe_elfload: error in relocations err %ld\n", | 940 | err = apply_relocate_add(sechdrs, strtab, symindex, i, |
903 | err); | 941 | &mod); |
904 | goto cleanup; | 942 | if (err < 0) |
943 | return err; | ||
944 | |||
945 | } | ||
946 | } else { | ||
947 | for (i = 0; i < hdr->e_shnum; i++) { | ||
948 | |||
949 | /* Internal symbols and strings. */ | ||
950 | if (sechdrs[i].sh_type == SHT_SYMTAB) { | ||
951 | symindex = i; | ||
952 | strindex = sechdrs[i].sh_link; | ||
953 | strtab = (char *)hdr + sechdrs[strindex].sh_offset; | ||
954 | |||
955 | /* mark the symtab's address for when we try to find the | ||
956 | magic symbols */ | ||
957 | sechdrs[i].sh_addr = (size_t) hdr + sechdrs[i].sh_offset; | ||
958 | } | ||
959 | |||
960 | /* filter sections we dont want in the final image */ | ||
961 | if (!(sechdrs[i].sh_flags & SHF_ALLOC) || | ||
962 | (sechdrs[i].sh_type == SHT_MIPS_REGINFO)) { | ||
963 | printk( KERN_DEBUG " ignoring section, " | ||
964 | "name %s type %x address 0x%x \n", | ||
965 | secstrings + sechdrs[i].sh_name, | ||
966 | sechdrs[i].sh_type, sechdrs[i].sh_addr); | ||
967 | continue; | ||
968 | } | ||
969 | |||
970 | if (sechdrs[i].sh_addr < (unsigned int)v->load_addr) { | ||
971 | printk( KERN_WARNING "VPE loader: " | ||
972 | "fully linked image has invalid section, " | ||
973 | "name %s type %x address 0x%x, before load " | ||
974 | "address of 0x%x\n", | ||
975 | secstrings + sechdrs[i].sh_name, | ||
976 | sechdrs[i].sh_type, sechdrs[i].sh_addr, | ||
977 | (unsigned int)v->load_addr); | ||
978 | return -ENOEXEC; | ||
979 | } | ||
980 | |||
981 | printk(KERN_DEBUG " copying section sh_name %s, sh_addr 0x%x " | ||
982 | "size 0x%x0 from x%p\n", | ||
983 | secstrings + sechdrs[i].sh_name, sechdrs[i].sh_addr, | ||
984 | sechdrs[i].sh_size, hdr + sechdrs[i].sh_offset); | ||
985 | |||
986 | if (sechdrs[i].sh_type != SHT_NOBITS) | ||
987 | memcpy((void *)sechdrs[i].sh_addr, | ||
988 | (char *)hdr + sechdrs[i].sh_offset, | ||
989 | sechdrs[i].sh_size); | ||
990 | else | ||
991 | memset((void *)sechdrs[i].sh_addr, 0, sechdrs[i].sh_size); | ||
905 | } | 992 | } |
906 | } | 993 | } |
907 | 994 | ||
@@ -910,71 +997,104 @@ int vpe_elfload(struct vpe * v) | |||
910 | (unsigned long)v->load_addr + v->len); | 997 | (unsigned long)v->load_addr + v->len); |
911 | 998 | ||
912 | if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) { | 999 | if ((find_vpe_symbols(v, sechdrs, symindex, strtab, &mod)) < 0) { |
1000 | if (v->__start == 0) { | ||
1001 | printk(KERN_WARNING "VPE loader: program does not contain " | ||
1002 | "a __start symbol\n"); | ||
1003 | return -ENOEXEC; | ||
1004 | } | ||
913 | 1005 | ||
914 | printk(KERN_WARNING | 1006 | if (v->shared_ptr == NULL) |
915 | "VPE: program doesn't contain __start or vpe_shared symbols\n"); | 1007 | printk(KERN_WARNING "VPE loader: " |
916 | err = -ENOEXEC; | 1008 | "program does not contain vpe_shared symbol.\n" |
1009 | " Unable to use AMVP (AP/SP) facilities.\n"); | ||
917 | } | 1010 | } |
918 | 1011 | ||
919 | printk(" elf loaded\n"); | 1012 | printk(" elf loaded\n"); |
920 | 1013 | return 0; | |
921 | cleanup: | ||
922 | return err; | ||
923 | } | 1014 | } |
924 | 1015 | ||
925 | static void dump_vpe(struct vpe * v) | 1016 | __attribute_used__ void dump_vpe(struct vpe * v) |
926 | { | 1017 | { |
927 | struct tc *t; | 1018 | struct tc *t; |
928 | 1019 | ||
1020 | settc(v->minor); | ||
1021 | |||
929 | printk(KERN_DEBUG "VPEControl 0x%lx\n", read_vpe_c0_vpecontrol()); | 1022 | printk(KERN_DEBUG "VPEControl 0x%lx\n", read_vpe_c0_vpecontrol()); |
930 | printk(KERN_DEBUG "VPEConf0 0x%lx\n", read_vpe_c0_vpeconf0()); | 1023 | printk(KERN_DEBUG "VPEConf0 0x%lx\n", read_vpe_c0_vpeconf0()); |
931 | 1024 | ||
932 | list_for_each_entry(t, &vpecontrol.tc_list, list) { | 1025 | list_for_each_entry(t, &vpecontrol.tc_list, list) |
933 | dump_tc(t); | 1026 | dump_tc(t); |
934 | } | ||
935 | } | 1027 | } |
936 | 1028 | ||
937 | /* checks for VPE is unused and gets ready to load program */ | 1029 | static void cleanup_tc(struct tc *tc) |
1030 | { | ||
1031 | int tmp; | ||
1032 | |||
1033 | /* Put MVPE's into 'configuration state' */ | ||
1034 | set_c0_mvpcontrol(MVPCONTROL_VPC); | ||
1035 | |||
1036 | settc(tc->index); | ||
1037 | tmp = read_tc_c0_tcstatus(); | ||
1038 | |||
1039 | /* mark not allocated and not dynamically allocatable */ | ||
1040 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); | ||
1041 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ | ||
1042 | write_tc_c0_tcstatus(tmp); | ||
1043 | |||
1044 | write_tc_c0_tchalt(TCHALT_H); | ||
1045 | |||
1046 | /* bind it to anything other than VPE1 */ | ||
1047 | write_tc_c0_tcbind(read_tc_c0_tcbind() & ~TCBIND_CURVPE); // | TCBIND_CURVPE | ||
1048 | |||
1049 | clear_c0_mvpcontrol(MVPCONTROL_VPC); | ||
1050 | } | ||
1051 | |||
1052 | static int getcwd(char *buff, int size) | ||
1053 | { | ||
1054 | mm_segment_t old_fs; | ||
1055 | int ret; | ||
1056 | |||
1057 | old_fs = get_fs(); | ||
1058 | set_fs(KERNEL_DS); | ||
1059 | |||
1060 | ret = sys_getcwd(buff,size); | ||
1061 | |||
1062 | set_fs(old_fs); | ||
1063 | |||
1064 | return ret; | ||
1065 | } | ||
1066 | |||
1067 | /* checks VPE is unused and gets ready to load program */ | ||
938 | static int vpe_open(struct inode *inode, struct file *filp) | 1068 | static int vpe_open(struct inode *inode, struct file *filp) |
939 | { | 1069 | { |
940 | int minor; | 1070 | int minor, ret; |
941 | struct vpe *v; | 1071 | struct vpe *v; |
1072 | struct vpe_notifications *not; | ||
942 | 1073 | ||
943 | /* assume only 1 device at the mo. */ | 1074 | /* assume only 1 device at the mo. */ |
944 | if ((minor = MINOR(inode->i_rdev)) != 1) { | 1075 | if ((minor = MINOR(inode->i_rdev)) != 1) { |
945 | printk(KERN_WARNING "VPE: only vpe1 is supported\n"); | 1076 | printk(KERN_WARNING "VPE loader: only vpe1 is supported\n"); |
946 | return -ENODEV; | 1077 | return -ENODEV; |
947 | } | 1078 | } |
948 | 1079 | ||
949 | if ((v = get_vpe(minor)) == NULL) { | 1080 | if ((v = get_vpe(minor)) == NULL) { |
950 | printk(KERN_WARNING "VPE: unable to get vpe\n"); | 1081 | printk(KERN_WARNING "VPE loader: unable to get vpe\n"); |
951 | return -ENODEV; | 1082 | return -ENODEV; |
952 | } | 1083 | } |
953 | 1084 | ||
954 | if (v->state != VPE_STATE_UNUSED) { | 1085 | if (v->state != VPE_STATE_UNUSED) { |
955 | unsigned long tmp; | ||
956 | struct tc *t; | ||
957 | |||
958 | printk(KERN_WARNING "VPE: device %d already in use\n", minor); | ||
959 | |||
960 | dvpe(); | 1086 | dvpe(); |
961 | dump_vpe(v); | ||
962 | |||
963 | printk(KERN_WARNING "VPE: re-initialising %d\n", minor); | ||
964 | |||
965 | release_progmem(v->load_addr); | ||
966 | 1087 | ||
967 | t = get_tc(minor); | 1088 | printk(KERN_DEBUG "VPE loader: tc in use dumping regs\n"); |
968 | settc(minor); | ||
969 | tmp = read_tc_c0_tcstatus(); | ||
970 | 1089 | ||
971 | /* mark not allocated and not dynamically allocatable */ | 1090 | dump_tc(get_tc(minor)); |
972 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); | ||
973 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ | ||
974 | write_tc_c0_tcstatus(tmp); | ||
975 | 1091 | ||
976 | write_tc_c0_tchalt(TCHALT_H); | 1092 | list_for_each_entry(not, &v->notify, list) { |
1093 | not->stop(minor); | ||
1094 | } | ||
977 | 1095 | ||
1096 | release_progmem(v->load_addr); | ||
1097 | cleanup_tc(get_tc(minor)); | ||
978 | } | 1098 | } |
979 | 1099 | ||
980 | // allocate it so when we get write ops we know it's expected. | 1100 | // allocate it so when we get write ops we know it's expected. |
@@ -986,6 +1106,24 @@ static int vpe_open(struct inode *inode, struct file *filp) | |||
986 | v->load_addr = NULL; | 1106 | v->load_addr = NULL; |
987 | v->len = 0; | 1107 | v->len = 0; |
988 | 1108 | ||
1109 | v->uid = filp->f_uid; | ||
1110 | v->gid = filp->f_gid; | ||
1111 | |||
1112 | #ifdef CONFIG_MIPS_APSP_KSPD | ||
1113 | /* get kspd to tell us when a syscall_exit happens */ | ||
1114 | if (!kspd_events_reqd) { | ||
1115 | kspd_notify(&kspd_events); | ||
1116 | kspd_events_reqd++; | ||
1117 | } | ||
1118 | #endif | ||
1119 | |||
1120 | v->cwd[0] = 0; | ||
1121 | ret = getcwd(v->cwd, VPE_PATH_MAX); | ||
1122 | if (ret < 0) | ||
1123 | printk(KERN_WARNING "VPE loader: open, getcwd returned %d\n", ret); | ||
1124 | |||
1125 | v->shared_ptr = NULL; | ||
1126 | v->__start = 0; | ||
989 | return 0; | 1127 | return 0; |
990 | } | 1128 | } |
991 | 1129 | ||
@@ -1006,14 +1144,22 @@ static int vpe_release(struct inode *inode, struct file *filp) | |||
1006 | if (vpe_elfload(v) >= 0) | 1144 | if (vpe_elfload(v) >= 0) |
1007 | vpe_run(v); | 1145 | vpe_run(v); |
1008 | else { | 1146 | else { |
1009 | printk(KERN_WARNING "VPE: ELF load failed.\n"); | 1147 | printk(KERN_WARNING "VPE loader: ELF load failed.\n"); |
1010 | ret = -ENOEXEC; | 1148 | ret = -ENOEXEC; |
1011 | } | 1149 | } |
1012 | } else { | 1150 | } else { |
1013 | printk(KERN_WARNING "VPE: only elf files are supported\n"); | 1151 | printk(KERN_WARNING "VPE loader: only elf files are supported\n"); |
1014 | ret = -ENOEXEC; | 1152 | ret = -ENOEXEC; |
1015 | } | 1153 | } |
1016 | 1154 | ||
1155 | /* It's good to be able to run the SP and if it chokes have a look at | ||
1156 | the /dev/rt?. But if we reset the pointer to the shared struct we | ||
1157 | loose what has happened. So perhaps if garbage is sent to the vpe | ||
1158 | device, use it as a trigger for the reset. Hopefully a nice | ||
1159 | executable will be along shortly. */ | ||
1160 | if (ret < 0) | ||
1161 | v->shared_ptr = NULL; | ||
1162 | |||
1017 | // cleanup any temp buffers | 1163 | // cleanup any temp buffers |
1018 | if (v->pbuffer) | 1164 | if (v->pbuffer) |
1019 | vfree(v->pbuffer); | 1165 | vfree(v->pbuffer); |
@@ -1033,21 +1179,19 @@ static ssize_t vpe_write(struct file *file, const char __user * buffer, | |||
1033 | return -ENODEV; | 1179 | return -ENODEV; |
1034 | 1180 | ||
1035 | if (v->pbuffer == NULL) { | 1181 | if (v->pbuffer == NULL) { |
1036 | printk(KERN_ERR "vpe_write: no pbuffer\n"); | 1182 | printk(KERN_ERR "VPE loader: no buffer for program\n"); |
1037 | return -ENOMEM; | 1183 | return -ENOMEM; |
1038 | } | 1184 | } |
1039 | 1185 | ||
1040 | if ((count + v->len) > v->plen) { | 1186 | if ((count + v->len) > v->plen) { |
1041 | printk(KERN_WARNING | 1187 | printk(KERN_WARNING |
1042 | "VPE Loader: elf size too big. Perhaps strip uneeded symbols\n"); | 1188 | "VPE loader: elf size too big. Perhaps strip uneeded symbols\n"); |
1043 | return -ENOMEM; | 1189 | return -ENOMEM; |
1044 | } | 1190 | } |
1045 | 1191 | ||
1046 | count -= copy_from_user(v->pbuffer + v->len, buffer, count); | 1192 | count -= copy_from_user(v->pbuffer + v->len, buffer, count); |
1047 | if (!count) { | 1193 | if (!count) |
1048 | printk("vpe_write: copy_to_user failed\n"); | ||
1049 | return -EFAULT; | 1194 | return -EFAULT; |
1050 | } | ||
1051 | 1195 | ||
1052 | v->len += count; | 1196 | v->len += count; |
1053 | return ret; | 1197 | return ret; |
@@ -1149,16 +1293,70 @@ void *vpe_get_shared(int index) | |||
1149 | { | 1293 | { |
1150 | struct vpe *v; | 1294 | struct vpe *v; |
1151 | 1295 | ||
1152 | if ((v = get_vpe(index)) == NULL) { | 1296 | if ((v = get_vpe(index)) == NULL) |
1153 | printk(KERN_WARNING "vpe: invalid vpe index %d\n", index); | ||
1154 | return NULL; | 1297 | return NULL; |
1155 | } | ||
1156 | 1298 | ||
1157 | return v->shared_ptr; | 1299 | return v->shared_ptr; |
1158 | } | 1300 | } |
1159 | 1301 | ||
1160 | EXPORT_SYMBOL(vpe_get_shared); | 1302 | EXPORT_SYMBOL(vpe_get_shared); |
1161 | 1303 | ||
1304 | int vpe_getuid(int index) | ||
1305 | { | ||
1306 | struct vpe *v; | ||
1307 | |||
1308 | if ((v = get_vpe(index)) == NULL) | ||
1309 | return -1; | ||
1310 | |||
1311 | return v->uid; | ||
1312 | } | ||
1313 | |||
1314 | EXPORT_SYMBOL(vpe_getuid); | ||
1315 | |||
1316 | int vpe_getgid(int index) | ||
1317 | { | ||
1318 | struct vpe *v; | ||
1319 | |||
1320 | if ((v = get_vpe(index)) == NULL) | ||
1321 | return -1; | ||
1322 | |||
1323 | return v->gid; | ||
1324 | } | ||
1325 | |||
1326 | EXPORT_SYMBOL(vpe_getgid); | ||
1327 | |||
1328 | int vpe_notify(int index, struct vpe_notifications *notify) | ||
1329 | { | ||
1330 | struct vpe *v; | ||
1331 | |||
1332 | if ((v = get_vpe(index)) == NULL) | ||
1333 | return -1; | ||
1334 | |||
1335 | list_add(¬ify->list, &v->notify); | ||
1336 | return 0; | ||
1337 | } | ||
1338 | |||
1339 | EXPORT_SYMBOL(vpe_notify); | ||
1340 | |||
1341 | char *vpe_getcwd(int index) | ||
1342 | { | ||
1343 | struct vpe *v; | ||
1344 | |||
1345 | if ((v = get_vpe(index)) == NULL) | ||
1346 | return NULL; | ||
1347 | |||
1348 | return v->cwd; | ||
1349 | } | ||
1350 | |||
1351 | EXPORT_SYMBOL(vpe_getcwd); | ||
1352 | |||
1353 | #ifdef CONFIG_MIPS_APSP_KSPD | ||
1354 | static void kspd_sp_exit( int sp_id) | ||
1355 | { | ||
1356 | cleanup_tc(get_tc(sp_id)); | ||
1357 | } | ||
1358 | #endif | ||
1359 | |||
1162 | static int __init vpe_module_init(void) | 1360 | static int __init vpe_module_init(void) |
1163 | { | 1361 | { |
1164 | struct vpe *v = NULL; | 1362 | struct vpe *v = NULL; |
@@ -1201,7 +1399,8 @@ static int __init vpe_module_init(void) | |||
1201 | return -ENODEV; | 1399 | return -ENODEV; |
1202 | } | 1400 | } |
1203 | 1401 | ||
1204 | list_add(&t->tc, &v->tc); /* add the tc to the list of this vpe's tc's. */ | 1402 | /* add the tc to the list of this vpe's tc's. */ |
1403 | list_add(&t->tc, &v->tc); | ||
1205 | 1404 | ||
1206 | /* deactivate all but vpe0 */ | 1405 | /* deactivate all but vpe0 */ |
1207 | if (i != 0) { | 1406 | if (i != 0) { |
@@ -1222,10 +1421,12 @@ static int __init vpe_module_init(void) | |||
1222 | ~(ST0_IM | ST0_IE | ST0_KSU)) | 1421 | ~(ST0_IM | ST0_IE | ST0_KSU)) |
1223 | | ST0_CU0); | 1422 | | ST0_CU0); |
1224 | 1423 | ||
1225 | /* set config to be the same as vpe0, particularly kseg0 coherency alg */ | 1424 | /* |
1425 | * Set config to be the same as vpe0, | ||
1426 | * particularly kseg0 coherency alg | ||
1427 | */ | ||
1226 | write_vpe_c0_config(read_c0_config()); | 1428 | write_vpe_c0_config(read_c0_config()); |
1227 | } | 1429 | } |
1228 | |||
1229 | } | 1430 | } |
1230 | 1431 | ||
1231 | /* TC's */ | 1432 | /* TC's */ |
@@ -1234,23 +1435,28 @@ static int __init vpe_module_init(void) | |||
1234 | if (i != 0) { | 1435 | if (i != 0) { |
1235 | unsigned long tmp; | 1436 | unsigned long tmp; |
1236 | 1437 | ||
1237 | /* tc 0 will of course be running.... */ | ||
1238 | if (i == 0) | ||
1239 | t->state = TC_STATE_RUNNING; | ||
1240 | |||
1241 | settc(i); | 1438 | settc(i); |
1242 | 1439 | ||
1243 | /* bind a TC to each VPE, May as well put all excess TC's | 1440 | /* Any TC that is bound to VPE0 gets left as is - in case |
1244 | on the last VPE */ | 1441 | we are running SMTC on VPE0. A TC that is bound to any |
1245 | if (i >= (((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT) + 1)) | 1442 | other VPE gets bound to VPE0, ideally I'd like to make |
1246 | write_tc_c0_tcbind(read_tc_c0_tcbind() | | 1443 | it homeless but it doesn't appear to let me bind a TC |
1247 | ((val & MVPCONF0_PVPE) >> MVPCONF0_PVPE_SHIFT)); | 1444 | to a non-existent VPE. Which is perfectly reasonable. |
1248 | else | 1445 | |
1249 | write_tc_c0_tcbind(read_tc_c0_tcbind() | i); | 1446 | The (un)bound state is visible to an EJTAG probe so may |
1447 | notify GDB... | ||
1448 | */ | ||
1449 | |||
1450 | if (((tmp = read_tc_c0_tcbind()) & TCBIND_CURVPE)) { | ||
1451 | /* tc is bound >vpe0 */ | ||
1452 | write_tc_c0_tcbind(tmp & ~TCBIND_CURVPE); | ||
1453 | |||
1454 | t->pvpe = get_vpe(0); /* set the parent vpe */ | ||
1455 | } | ||
1250 | 1456 | ||
1251 | tmp = read_tc_c0_tcstatus(); | 1457 | tmp = read_tc_c0_tcstatus(); |
1252 | 1458 | ||
1253 | /* mark not allocated and not dynamically allocatable */ | 1459 | /* mark not activated and not dynamically allocatable */ |
1254 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); | 1460 | tmp &= ~(TCSTATUS_A | TCSTATUS_DA); |
1255 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ | 1461 | tmp |= TCSTATUS_IXMT; /* interrupt exempt */ |
1256 | write_tc_c0_tcstatus(tmp); | 1462 | write_tc_c0_tcstatus(tmp); |
@@ -1262,6 +1468,9 @@ static int __init vpe_module_init(void) | |||
1262 | /* release config state */ | 1468 | /* release config state */ |
1263 | clear_c0_mvpcontrol(MVPCONTROL_VPC); | 1469 | clear_c0_mvpcontrol(MVPCONTROL_VPC); |
1264 | 1470 | ||
1471 | #ifdef CONFIG_MIPS_APSP_KSPD | ||
1472 | kspd_events.kspd_sp_exit = kspd_sp_exit; | ||
1473 | #endif | ||
1265 | return 0; | 1474 | return 0; |
1266 | } | 1475 | } |
1267 | 1476 | ||
@@ -1281,5 +1490,5 @@ static void __exit vpe_module_exit(void) | |||
1281 | module_init(vpe_module_init); | 1490 | module_init(vpe_module_init); |
1282 | module_exit(vpe_module_exit); | 1491 | module_exit(vpe_module_exit); |
1283 | MODULE_DESCRIPTION("MIPS VPE Loader"); | 1492 | MODULE_DESCRIPTION("MIPS VPE Loader"); |
1284 | MODULE_AUTHOR("Elizabeth Clarke, MIPS Technologies, Inc"); | 1493 | MODULE_AUTHOR("Elizabeth Oldham, MIPS Technologies, Inc."); |
1285 | MODULE_LICENSE("GPL"); | 1494 | MODULE_LICENSE("GPL"); |
diff --git a/arch/mips/lasat/Makefile b/arch/mips/lasat/Makefile index 0d5aec436725..99f5046fdf49 100644 --- a/arch/mips/lasat/Makefile +++ b/arch/mips/lasat/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += reset.o setup.o prom.o lasat_board.o \ | 5 | obj-y += reset.o setup.o prom.o lasat_board.o \ |
6 | at93c.o interrupt.o lasatIRQ.o | 6 | at93c.o interrupt.o |
7 | 7 | ||
8 | obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o | 8 | obj-$(CONFIG_LASAT_SYSCTL) += sysctl.o |
9 | obj-$(CONFIG_DS1603) += ds1603.o | 9 | obj-$(CONFIG_DS1603) += ds1603.o |
diff --git a/arch/mips/lasat/interrupt.c b/arch/mips/lasat/interrupt.c index 852a41901a5e..2d3472b21ebb 100644 --- a/arch/mips/lasat/interrupt.c +++ b/arch/mips/lasat/interrupt.c | |||
@@ -27,14 +27,13 @@ | |||
27 | #include <asm/bootinfo.h> | 27 | #include <asm/bootinfo.h> |
28 | #include <asm/irq.h> | 28 | #include <asm/irq.h> |
29 | #include <asm/lasat/lasatint.h> | 29 | #include <asm/lasat/lasatint.h> |
30 | #include <asm/time.h> | ||
30 | #include <asm/gdb-stub.h> | 31 | #include <asm/gdb-stub.h> |
31 | 32 | ||
32 | static volatile int *lasat_int_status = NULL; | 33 | static volatile int *lasat_int_status = NULL; |
33 | static volatile int *lasat_int_mask = NULL; | 34 | static volatile int *lasat_int_mask = NULL; |
34 | static volatile int lasat_int_mask_shift; | 35 | static volatile int lasat_int_mask_shift; |
35 | 36 | ||
36 | extern asmlinkage void lasatIRQ(void); | ||
37 | |||
38 | void disable_lasat_irq(unsigned int irq_nr) | 37 | void disable_lasat_irq(unsigned int irq_nr) |
39 | { | 38 | { |
40 | unsigned long flags; | 39 | unsigned long flags; |
@@ -109,11 +108,17 @@ static unsigned long get_int_status_200(void) | |||
109 | return int_status; | 108 | return int_status; |
110 | } | 109 | } |
111 | 110 | ||
112 | void lasat_hw0_irqdispatch(struct pt_regs *regs) | 111 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
113 | { | 112 | { |
114 | unsigned long int_status; | 113 | unsigned long int_status; |
114 | unsigned int cause = read_c0_cause(); | ||
115 | int irq; | 115 | int irq; |
116 | 116 | ||
117 | if (cause & CAUSEF_IP7) { /* R4000 count / compare IRQ */ | ||
118 | ll_timer_interrupt(7, regs); | ||
119 | return; | ||
120 | } | ||
121 | |||
117 | int_status = get_int_status(); | 122 | int_status = get_int_status(); |
118 | 123 | ||
119 | /* if int_status == 0, then the interrupt has already been cleared */ | 124 | /* if int_status == 0, then the interrupt has already been cleared */ |
@@ -147,9 +152,6 @@ void __init arch_init_irq(void) | |||
147 | panic("arch_init_irq: mips_machtype incorrect"); | 152 | panic("arch_init_irq: mips_machtype incorrect"); |
148 | } | 153 | } |
149 | 154 | ||
150 | /* Now safe to set the exception vector. */ | ||
151 | set_except_vector(0, lasatIRQ); | ||
152 | |||
153 | for (i = 0; i <= LASATINT_END; i++) { | 155 | for (i = 0; i <= LASATINT_END; i++) { |
154 | irq_desc[i].status = IRQ_DISABLED; | 156 | irq_desc[i].status = IRQ_DISABLED; |
155 | irq_desc[i].action = 0; | 157 | irq_desc[i].action = 0; |
diff --git a/arch/mips/lasat/lasatIRQ.S b/arch/mips/lasat/lasatIRQ.S deleted file mode 100644 index 2a2b0d056561..000000000000 --- a/arch/mips/lasat/lasatIRQ.S +++ /dev/null | |||
@@ -1,69 +0,0 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Interrupt exception dispatch code. | ||
19 | */ | ||
20 | #include <asm/asm.h> | ||
21 | #include <asm/mipsregs.h> | ||
22 | #include <asm/regdef.h> | ||
23 | #include <asm/stackframe.h> | ||
24 | |||
25 | .text | ||
26 | .set noreorder | ||
27 | .align 5 | ||
28 | NESTED(lasatIRQ, PT_SIZE, sp) | ||
29 | .set noat | ||
30 | SAVE_ALL | ||
31 | CLI | ||
32 | .set at | ||
33 | .set noreorder | ||
34 | |||
35 | mfc0 s0, CP0_CAUSE # get irq mask | ||
36 | |||
37 | /* First we check for r4k counter/timer IRQ. */ | ||
38 | andi a0, s0, CAUSEF_IP7 | ||
39 | beq a0, zero, 1f | ||
40 | andi a0, s0, CAUSEF_IP2 # delay slot, check hw0 interrupt | ||
41 | |||
42 | /* Wheee, a timer interrupt. */ | ||
43 | li a0, 7 | ||
44 | jal ll_timer_interrupt | ||
45 | move a1, sp | ||
46 | |||
47 | j ret_from_irq | ||
48 | nop | ||
49 | |||
50 | 1: | ||
51 | /* Wheee, combined hardware level zero interrupt. */ | ||
52 | jal lasat_hw0_irqdispatch | ||
53 | move a0, sp # delay slot | ||
54 | |||
55 | j ret_from_irq | ||
56 | nop # delay slot | ||
57 | |||
58 | 1: | ||
59 | /* | ||
60 | * Here by mistake? This is possible, what can happen is that by the | ||
61 | * time we take the exception the IRQ pin goes low, so just leave if | ||
62 | * this is the case. | ||
63 | */ | ||
64 | move a1,s0 | ||
65 | mfc0 a1, CP0_EPC | ||
66 | |||
67 | j ret_from_irq | ||
68 | nop | ||
69 | END(lasatIRQ) | ||
diff --git a/arch/mips/mips-boards/atlas/atlas_int.c b/arch/mips/mips-boards/atlas/atlas_int.c index bc0ebc69bfb3..db53950b7cfb 100644 --- a/arch/mips/mips-boards/atlas/atlas_int.c +++ b/arch/mips/mips-boards/atlas/atlas_int.c | |||
@@ -39,8 +39,6 @@ | |||
39 | 39 | ||
40 | static struct atlas_ictrl_regs *atlas_hw0_icregs; | 40 | static struct atlas_ictrl_regs *atlas_hw0_icregs; |
41 | 41 | ||
42 | extern asmlinkage void mipsIRQ(void); | ||
43 | |||
44 | #if 0 | 42 | #if 0 |
45 | #define DEBUG_INT(x...) printk(x) | 43 | #define DEBUG_INT(x...) printk(x) |
46 | #else | 44 | #else |
@@ -98,7 +96,7 @@ static inline int ls1bit32(unsigned int x) | |||
98 | return b; | 96 | return b; |
99 | } | 97 | } |
100 | 98 | ||
101 | void atlas_hw0_irqdispatch(struct pt_regs *regs) | 99 | static inline void atlas_hw0_irqdispatch(struct pt_regs *regs) |
102 | { | 100 | { |
103 | unsigned long int_status; | 101 | unsigned long int_status; |
104 | int irq; | 102 | int irq; |
@@ -116,6 +114,91 @@ void atlas_hw0_irqdispatch(struct pt_regs *regs) | |||
116 | do_IRQ(irq, regs); | 114 | do_IRQ(irq, regs); |
117 | } | 115 | } |
118 | 116 | ||
117 | static inline int clz(unsigned long x) | ||
118 | { | ||
119 | __asm__ ( | ||
120 | " .set push \n" | ||
121 | " .set mips32 \n" | ||
122 | " clz %0, %1 \n" | ||
123 | " .set pop \n" | ||
124 | : "=r" (x) | ||
125 | : "r" (x)); | ||
126 | |||
127 | return x; | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * Version of ffs that only looks at bits 12..15. | ||
132 | */ | ||
133 | static inline unsigned int irq_ffs(unsigned int pending) | ||
134 | { | ||
135 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
136 | return -clz(pending) + 31 - CAUSEB_IP; | ||
137 | #else | ||
138 | unsigned int a0 = 7; | ||
139 | unsigned int t0; | ||
140 | |||
141 | t0 = s0 & 0xf000; | ||
142 | t0 = t0 < 1; | ||
143 | t0 = t0 << 2; | ||
144 | a0 = a0 - t0; | ||
145 | s0 = s0 << t0; | ||
146 | |||
147 | t0 = s0 & 0xc000; | ||
148 | t0 = t0 < 1; | ||
149 | t0 = t0 << 1; | ||
150 | a0 = a0 - t0; | ||
151 | s0 = s0 << t0; | ||
152 | |||
153 | t0 = s0 & 0x8000; | ||
154 | t0 = t0 < 1; | ||
155 | //t0 = t0 << 2; | ||
156 | a0 = a0 - t0; | ||
157 | //s0 = s0 << t0; | ||
158 | |||
159 | return a0; | ||
160 | #endif | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * IRQs on the Atlas board look basically (barring software IRQs which we | ||
165 | * don't use at all and all external interrupt sources are combined together | ||
166 | * on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
167 | * | ||
168 | * MIPS IRQ Source | ||
169 | * -------- ------ | ||
170 | * 0 Software (ignored) | ||
171 | * 1 Software (ignored) | ||
172 | * 2 Combined hardware interrupt (hw0) | ||
173 | * 3 Hardware (ignored) | ||
174 | * 4 Hardware (ignored) | ||
175 | * 5 Hardware (ignored) | ||
176 | * 6 Hardware (ignored) | ||
177 | * 7 R4k timer (what we use) | ||
178 | * | ||
179 | * We handle the IRQ according to _our_ priority which is: | ||
180 | * | ||
181 | * Highest ---- R4k Timer | ||
182 | * Lowest ---- Combined hardware interrupt | ||
183 | * | ||
184 | * then we just return, if multiple IRQs are pending then we will just take | ||
185 | * another exception, big deal. | ||
186 | */ | ||
187 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
188 | { | ||
189 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
190 | int irq; | ||
191 | |||
192 | irq = irq_ffs(pending); | ||
193 | |||
194 | if (irq == MIPSCPU_INT_ATLAS) | ||
195 | atlas_hw0_irqdispatch(regs); | ||
196 | else if (irq > 0) | ||
197 | do_IRQ(MIPSCPU_INT_BASE + irq, regs); | ||
198 | else | ||
199 | spurious_interrupt(regs); | ||
200 | } | ||
201 | |||
119 | void __init arch_init_irq(void) | 202 | void __init arch_init_irq(void) |
120 | { | 203 | { |
121 | int i; | 204 | int i; |
@@ -128,9 +211,6 @@ void __init arch_init_irq(void) | |||
128 | */ | 211 | */ |
129 | atlas_hw0_icregs->intrsten = 0xffffffff; | 212 | atlas_hw0_icregs->intrsten = 0xffffffff; |
130 | 213 | ||
131 | /* Now safe to set the exception vector. */ | ||
132 | set_except_vector(0, mipsIRQ); | ||
133 | |||
134 | for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { | 214 | for (i = ATLASINT_BASE; i <= ATLASINT_END; i++) { |
135 | irq_desc[i].status = IRQ_DISABLED; | 215 | irq_desc[i].status = IRQ_DISABLED; |
136 | irq_desc[i].action = 0; | 216 | irq_desc[i].action = 0; |
diff --git a/arch/mips/mips-boards/generic/Makefile b/arch/mips/mips-boards/generic/Makefile index b21bc6887fa8..be47c1c2bc80 100644 --- a/arch/mips/mips-boards/generic/Makefile +++ b/arch/mips/mips-boards/generic/Makefile | |||
@@ -18,8 +18,8 @@ | |||
18 | # Makefile for the MIPS boards generic routines under Linux. | 18 | # Makefile for the MIPS boards generic routines under Linux. |
19 | # | 19 | # |
20 | 20 | ||
21 | obj-y := mipsIRQ.o reset.o display.o init.o memory.o \ | 21 | obj-y := reset.o display.o init.o memory.o printf.o \ |
22 | printf.o cmdline.o time.o | 22 | cmdline.o time.o |
23 | obj-$(CONFIG_PCI) += pci.o | 23 | obj-$(CONFIG_PCI) += pci.o |
24 | obj-$(CONFIG_KGDB) += gdb_hook.o | 24 | obj-$(CONFIG_KGDB) += gdb_hook.o |
25 | 25 | ||
diff --git a/arch/mips/mips-boards/generic/gdb_hook.c b/arch/mips/mips-boards/generic/gdb_hook.c index 91a2ccbe3730..6a1854de4579 100644 --- a/arch/mips/mips-boards/generic/gdb_hook.c +++ b/arch/mips/mips-boards/generic/gdb_hook.c | |||
@@ -25,7 +25,7 @@ | |||
25 | #include <asm/serial.h> | 25 | #include <asm/serial.h> |
26 | #include <asm/io.h> | 26 | #include <asm/io.h> |
27 | 27 | ||
28 | static struct serial_state rs_table[RS_TABLE_SIZE] = { | 28 | static struct serial_state rs_table[] = { |
29 | SERIAL_PORT_DFNS /* Defined in serial.h */ | 29 | SERIAL_PORT_DFNS /* Defined in serial.h */ |
30 | }; | 30 | }; |
31 | 31 | ||
diff --git a/arch/mips/mips-boards/generic/init.c b/arch/mips/mips-boards/generic/init.c index eab5a705e989..17dfe6a8cab9 100644 --- a/arch/mips/mips-boards/generic/init.c +++ b/arch/mips/mips-boards/generic/init.c | |||
@@ -220,7 +220,6 @@ void __init kgdb_config (void) | |||
220 | generic_putDebugChar (*s++); | 220 | generic_putDebugChar (*s++); |
221 | } | 221 | } |
222 | 222 | ||
223 | kgdb_enabled = 1; | ||
224 | /* Breakpoint is invoked after interrupts are initialised */ | 223 | /* Breakpoint is invoked after interrupts are initialised */ |
225 | } | 224 | } |
226 | } | 225 | } |
diff --git a/arch/mips/mips-boards/generic/memory.c b/arch/mips/mips-boards/generic/memory.c index 32c9210373ac..bc4d093685bb 100644 --- a/arch/mips/mips-boards/generic/memory.c +++ b/arch/mips/mips-boards/generic/memory.c | |||
@@ -22,10 +22,12 @@ | |||
22 | #include <linux/init.h> | 22 | #include <linux/init.h> |
23 | #include <linux/mm.h> | 23 | #include <linux/mm.h> |
24 | #include <linux/bootmem.h> | 24 | #include <linux/bootmem.h> |
25 | #include <linux/pfn.h> | ||
25 | #include <linux/string.h> | 26 | #include <linux/string.h> |
26 | 27 | ||
27 | #include <asm/bootinfo.h> | 28 | #include <asm/bootinfo.h> |
28 | #include <asm/page.h> | 29 | #include <asm/page.h> |
30 | #include <asm/sections.h> | ||
29 | 31 | ||
30 | #include <asm/mips-boards/prom.h> | 32 | #include <asm/mips-boards/prom.h> |
31 | 33 | ||
@@ -46,9 +48,6 @@ static char *mtypes[3] = { | |||
46 | }; | 48 | }; |
47 | #endif | 49 | #endif |
48 | 50 | ||
49 | /* References to section boundaries */ | ||
50 | extern char _end; | ||
51 | |||
52 | struct prom_pmemblock * __init prom_getmdesc(void) | 51 | struct prom_pmemblock * __init prom_getmdesc(void) |
53 | { | 52 | { |
54 | char *memsize_str; | 53 | char *memsize_str; |
@@ -106,10 +105,10 @@ struct prom_pmemblock * __init prom_getmdesc(void) | |||
106 | 105 | ||
107 | mdesc[3].type = yamon_dontuse; | 106 | mdesc[3].type = yamon_dontuse; |
108 | mdesc[3].base = 0x00100000; | 107 | mdesc[3].base = 0x00100000; |
109 | mdesc[3].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[3].base; | 108 | mdesc[3].size = CPHYSADDR(PFN_ALIGN((unsigned long)&_end)) - mdesc[3].base; |
110 | 109 | ||
111 | mdesc[4].type = yamon_free; | 110 | mdesc[4].type = yamon_free; |
112 | mdesc[4].base = CPHYSADDR(PAGE_ALIGN(&_end)); | 111 | mdesc[4].base = CPHYSADDR(PFN_ALIGN(&_end)); |
113 | mdesc[4].size = memsize - mdesc[4].base; | 112 | mdesc[4].size = memsize - mdesc[4].base; |
114 | 113 | ||
115 | return &mdesc[0]; | 114 | return &mdesc[0]; |
diff --git a/arch/mips/mips-boards/generic/mipsIRQ.S b/arch/mips/mips-boards/generic/mipsIRQ.S deleted file mode 100644 index ddd5c73a2971..000000000000 --- a/arch/mips/mips-boards/generic/mipsIRQ.S +++ /dev/null | |||
@@ -1,155 +0,0 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999, 2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * ######################################################################## | ||
6 | * | ||
7 | * This program is free software; you can distribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License (Version 2) as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
14 | * for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along | ||
17 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
18 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
19 | * | ||
20 | * ######################################################################## | ||
21 | * | ||
22 | * Interrupt exception dispatch code. | ||
23 | * | ||
24 | */ | ||
25 | #include <linux/config.h> | ||
26 | |||
27 | #include <asm/asm.h> | ||
28 | #include <asm/mipsregs.h> | ||
29 | #include <asm/regdef.h> | ||
30 | #include <asm/stackframe.h> | ||
31 | |||
32 | #ifdef CONFIG_MIPS_ATLAS | ||
33 | #include <asm/mips-boards/atlasint.h> | ||
34 | #define CASCADE_IRQ MIPSCPU_INT_ATLAS | ||
35 | #define CASCADE_DISPATCH atlas_hw0_irqdispatch | ||
36 | #endif | ||
37 | #ifdef CONFIG_MIPS_MALTA | ||
38 | #include <asm/mips-boards/maltaint.h> | ||
39 | #define CASCADE_IRQ MIPSCPU_INT_I8259A | ||
40 | #define CASCADE_DISPATCH malta_hw0_irqdispatch | ||
41 | #endif | ||
42 | #ifdef CONFIG_MIPS_SEAD | ||
43 | #include <asm/mips-boards/seadint.h> | ||
44 | #endif | ||
45 | |||
46 | /* A lot of complication here is taken away because: | ||
47 | * | ||
48 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
49 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
50 | * common case is one pending IRQ so optimize in that direction. | ||
51 | * | ||
52 | * 2) We need not check against bits in the status register IRQ mask, that | ||
53 | * would make this routine slow as hell. | ||
54 | * | ||
55 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
56 | * between like BSD spl() brain-damage. | ||
57 | * | ||
58 | * Furthermore, the IRQs on the MIPS board look basically (barring software | ||
59 | * IRQs which we don't use at all and all external interrupt sources are | ||
60 | * combined together on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
61 | * | ||
62 | * MIPS IRQ Source | ||
63 | * -------- ------ | ||
64 | * 0 Software (ignored) | ||
65 | * 1 Software (ignored) | ||
66 | * 2 Combined hardware interrupt (hw0) | ||
67 | * 3 Hardware (ignored) | ||
68 | * 4 Hardware (ignored) | ||
69 | * 5 Hardware (ignored) | ||
70 | * 6 Hardware (ignored) | ||
71 | * 7 R4k timer (what we use) | ||
72 | * | ||
73 | * Note: On the SEAD board thing are a little bit different. | ||
74 | * Here IRQ 2 (hw0) is wired to the UART0 and IRQ 3 (hw1) is wired | ||
75 | * wired to UART1. | ||
76 | * | ||
77 | * We handle the IRQ according to _our_ priority which is: | ||
78 | * | ||
79 | * Highest ---- R4k Timer | ||
80 | * Lowest ---- Combined hardware interrupt | ||
81 | * | ||
82 | * then we just return, if multiple IRQs are pending then we will just take | ||
83 | * another exception, big deal. | ||
84 | */ | ||
85 | |||
86 | .text | ||
87 | .set noreorder | ||
88 | .set noat | ||
89 | .align 5 | ||
90 | NESTED(mipsIRQ, PT_SIZE, sp) | ||
91 | SAVE_ALL | ||
92 | CLI | ||
93 | .set at | ||
94 | |||
95 | mfc0 s0, CP0_CAUSE # get irq bits | ||
96 | mfc0 s1, CP0_STATUS # get irq mask | ||
97 | andi s0, ST0_IM # CAUSE.CE may be non-zero! | ||
98 | and s0, s1 | ||
99 | |||
100 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
101 | .set mips32 | ||
102 | clz a0, s0 | ||
103 | .set mips0 | ||
104 | negu a0 | ||
105 | addu a0, 31-CAUSEB_IP | ||
106 | bltz a0, spurious | ||
107 | #else | ||
108 | beqz s0, spurious | ||
109 | li a0, 7 | ||
110 | |||
111 | and t0, s0, 0xf000 | ||
112 | sltiu t0, t0, 1 | ||
113 | sll t0, 2 | ||
114 | subu a0, t0 | ||
115 | sll s0, t0 | ||
116 | |||
117 | and t0, s0, 0xc000 | ||
118 | sltiu t0, t0, 1 | ||
119 | sll t0, 1 | ||
120 | subu a0, t0 | ||
121 | sll s0, t0 | ||
122 | |||
123 | and t0, s0, 0x8000 | ||
124 | sltiu t0, t0, 1 | ||
125 | # sll t0, 0 | ||
126 | subu a0, t0 | ||
127 | # sll s0, t0 | ||
128 | #endif | ||
129 | |||
130 | #ifdef CASCADE_IRQ | ||
131 | li a1, CASCADE_IRQ | ||
132 | bne a0, a1, 1f | ||
133 | addu a0, MIPSCPU_INT_BASE | ||
134 | |||
135 | jal CASCADE_DISPATCH | ||
136 | move a0, sp | ||
137 | |||
138 | j ret_from_irq | ||
139 | nop | ||
140 | 1: | ||
141 | #else | ||
142 | addu a0, MIPSCPU_INT_BASE | ||
143 | #endif | ||
144 | |||
145 | jal do_IRQ | ||
146 | move a1, sp | ||
147 | |||
148 | j ret_from_irq | ||
149 | nop | ||
150 | |||
151 | |||
152 | spurious: | ||
153 | j spurious_interrupt | ||
154 | nop | ||
155 | END(mipsIRQ) | ||
diff --git a/arch/mips/mips-boards/generic/time.c b/arch/mips/mips-boards/generic/time.c index 93f3bf2c2b22..a9f6124b3a22 100644 --- a/arch/mips/mips-boards/generic/time.c +++ b/arch/mips/mips-boards/generic/time.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/mc146818rtc.h> | 30 | #include <linux/mc146818rtc.h> |
31 | 31 | ||
32 | #include <asm/mipsregs.h> | 32 | #include <asm/mipsregs.h> |
33 | #include <asm/mipsmtregs.h> | ||
33 | #include <asm/ptrace.h> | 34 | #include <asm/ptrace.h> |
34 | #include <asm/hardirq.h> | 35 | #include <asm/hardirq.h> |
35 | #include <asm/irq.h> | 36 | #include <asm/irq.h> |
@@ -50,16 +51,23 @@ unsigned long cpu_khz; | |||
50 | static char display_string[] = " LINUX ON ATLAS "; | 51 | static char display_string[] = " LINUX ON ATLAS "; |
51 | #endif | 52 | #endif |
52 | #if defined(CONFIG_MIPS_MALTA) | 53 | #if defined(CONFIG_MIPS_MALTA) |
54 | #if defined(CONFIG_MIPS_MT_SMTC) | ||
55 | static char display_string[] = " SMTC LINUX ON MALTA "; | ||
56 | #else | ||
53 | static char display_string[] = " LINUX ON MALTA "; | 57 | static char display_string[] = " LINUX ON MALTA "; |
58 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
54 | #endif | 59 | #endif |
55 | #if defined(CONFIG_MIPS_SEAD) | 60 | #if defined(CONFIG_MIPS_SEAD) |
56 | static char display_string[] = " LINUX ON SEAD "; | 61 | static char display_string[] = " LINUX ON SEAD "; |
57 | #endif | 62 | #endif |
58 | static unsigned int display_count = 0; | 63 | static unsigned int display_count; |
59 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) | 64 | #define MAX_DISPLAY_COUNT (sizeof(display_string) - 8) |
60 | 65 | ||
61 | static unsigned int timer_tick_count=0; | 66 | #define CPUCTR_IMASKBIT (0x100 << MIPSCPU_INT_CPUCTR) |
67 | |||
68 | static unsigned int timer_tick_count; | ||
62 | static int mips_cpu_timer_irq; | 69 | static int mips_cpu_timer_irq; |
70 | extern void smtc_timer_broadcast(int); | ||
63 | 71 | ||
64 | static inline void scroll_display_message(void) | 72 | static inline void scroll_display_message(void) |
65 | { | 73 | { |
@@ -75,15 +83,55 @@ static void mips_timer_dispatch (struct pt_regs *regs) | |||
75 | do_IRQ (mips_cpu_timer_irq, regs); | 83 | do_IRQ (mips_cpu_timer_irq, regs); |
76 | } | 84 | } |
77 | 85 | ||
86 | /* | ||
87 | * Redeclare until I get around mopping the timer code insanity on MIPS. | ||
88 | */ | ||
78 | extern int null_perf_irq(struct pt_regs *regs); | 89 | extern int null_perf_irq(struct pt_regs *regs); |
79 | 90 | ||
80 | extern int (*perf_irq)(struct pt_regs *regs); | 91 | extern int (*perf_irq)(struct pt_regs *regs); |
81 | 92 | ||
82 | irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | 93 | irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) |
83 | { | 94 | { |
84 | int r2 = cpu_has_mips_r2; | ||
85 | int cpu = smp_processor_id(); | 95 | int cpu = smp_processor_id(); |
96 | int r2 = cpu_has_mips_r2; | ||
97 | |||
98 | #ifdef CONFIG_MIPS_MT_SMTC | ||
99 | /* | ||
100 | * In an SMTC system, one Count/Compare set exists per VPE. | ||
101 | * Which TC within a VPE gets the interrupt is essentially | ||
102 | * random - we only know that it shouldn't be one with | ||
103 | * IXMT set. Whichever TC gets the interrupt needs to | ||
104 | * send special interprocessor interrupts to the other | ||
105 | * TCs to make sure that they schedule, etc. | ||
106 | * | ||
107 | * That code is specific to the SMTC kernel, not to | ||
108 | * the a particular platform, so it's invoked from | ||
109 | * the general MIPS timer_interrupt routine. | ||
110 | */ | ||
111 | |||
112 | /* | ||
113 | * DVPE is necessary so long as cross-VPE interrupts | ||
114 | * are done via read-modify-write of Cause register. | ||
115 | */ | ||
116 | int vpflags = dvpe(); | ||
117 | write_c0_compare (read_c0_count() - 1); | ||
118 | clear_c0_cause(CPUCTR_IMASKBIT); | ||
119 | evpe(vpflags); | ||
120 | |||
121 | if (cpu_data[cpu].vpe_id == 0) { | ||
122 | timer_interrupt(irq, dev_id, regs); | ||
123 | scroll_display_message(); | ||
124 | } else | ||
125 | write_c0_compare (read_c0_count() + ( mips_hpt_frequency/HZ)); | ||
126 | smtc_timer_broadcast(cpu_data[cpu].vpe_id); | ||
86 | 127 | ||
128 | if (cpu != 0) | ||
129 | /* | ||
130 | * Other CPUs should do profiling and process accounting | ||
131 | */ | ||
132 | local_timer_interrupt(irq, dev_id, regs); | ||
133 | |||
134 | #else /* CONFIG_MIPS_MT_SMTC */ | ||
87 | if (cpu == 0) { | 135 | if (cpu == 0) { |
88 | /* | 136 | /* |
89 | * CPU 0 handles the global timer interrupt job and process | 137 | * CPU 0 handles the global timer interrupt job and process |
@@ -107,12 +155,14 @@ irqreturn_t mips_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
107 | * More support needs to be added to kernel/time for | 155 | * More support needs to be added to kernel/time for |
108 | * counter/timer interrupts on multiple CPU's | 156 | * counter/timer interrupts on multiple CPU's |
109 | */ | 157 | */ |
110 | write_c0_compare (read_c0_count() + (mips_hpt_frequency/HZ)); | 158 | write_c0_compare(read_c0_count() + (mips_hpt_frequency/HZ)); |
159 | |||
111 | /* | 160 | /* |
112 | * other CPUs should do profiling and process accounting | 161 | * Other CPUs should do profiling and process accounting |
113 | */ | 162 | */ |
114 | local_timer_interrupt (irq, dev_id, regs); | 163 | local_timer_interrupt(irq, dev_id, regs); |
115 | } | 164 | } |
165 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
116 | 166 | ||
117 | out: | 167 | out: |
118 | return IRQ_HANDLED; | 168 | return IRQ_HANDLED; |
@@ -126,7 +176,7 @@ static unsigned int __init estimate_cpu_frequency(void) | |||
126 | unsigned int prid = read_c0_prid() & 0xffff00; | 176 | unsigned int prid = read_c0_prid() & 0xffff00; |
127 | unsigned int count; | 177 | unsigned int count; |
128 | 178 | ||
129 | #ifdef CONFIG_MIPS_SEAD | 179 | #if defined(CONFIG_MIPS_SEAD) || defined(CONFIG_MIPS_SIM) |
130 | /* | 180 | /* |
131 | * The SEAD board doesn't have a real time clock, so we can't | 181 | * The SEAD board doesn't have a real time clock, so we can't |
132 | * really calculate the timer frequency | 182 | * really calculate the timer frequency |
@@ -211,7 +261,11 @@ void __init mips_timer_setup(struct irqaction *irq) | |||
211 | 261 | ||
212 | /* we are using the cpu counter for timer interrupts */ | 262 | /* we are using the cpu counter for timer interrupts */ |
213 | irq->handler = mips_timer_interrupt; /* we use our own handler */ | 263 | irq->handler = mips_timer_interrupt; /* we use our own handler */ |
264 | #ifdef CONFIG_MIPS_MT_SMTC | ||
265 | setup_irq_smtc(mips_cpu_timer_irq, irq, CPUCTR_IMASKBIT); | ||
266 | #else | ||
214 | setup_irq(mips_cpu_timer_irq, irq); | 267 | setup_irq(mips_cpu_timer_irq, irq); |
268 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
215 | 269 | ||
216 | #ifdef CONFIG_SMP | 270 | #ifdef CONFIG_SMP |
217 | /* irq_desc(riptor) is a global resource, when the interrupt overlaps | 271 | /* irq_desc(riptor) is a global resource, when the interrupt overlaps |
diff --git a/arch/mips/mips-boards/malta/Makefile b/arch/mips/mips-boards/malta/Makefile index fd4c143c0e2f..77ee5c6d33c1 100644 --- a/arch/mips/mips-boards/malta/Makefile +++ b/arch/mips/mips-boards/malta/Makefile | |||
@@ -20,3 +20,4 @@ | |||
20 | # | 20 | # |
21 | 21 | ||
22 | obj-y := malta_int.o malta_setup.o | 22 | obj-y := malta_int.o malta_setup.o |
23 | obj-$(CONFIG_SMP) += malta_smp.o | ||
diff --git a/arch/mips/mips-boards/malta/malta_int.c b/arch/mips/mips-boards/malta/malta_int.c index d06dc5ad6c9e..64db07d4dbe5 100644 --- a/arch/mips/mips-boards/malta/malta_int.c +++ b/arch/mips/mips-boards/malta/malta_int.c | |||
@@ -40,7 +40,6 @@ | |||
40 | #include <asm/mips-boards/msc01_pci.h> | 40 | #include <asm/mips-boards/msc01_pci.h> |
41 | #include <asm/msc01_ic.h> | 41 | #include <asm/msc01_ic.h> |
42 | 42 | ||
43 | extern asmlinkage void mipsIRQ(void); | ||
44 | extern void mips_timer_interrupt(void); | 43 | extern void mips_timer_interrupt(void); |
45 | 44 | ||
46 | static DEFINE_SPINLOCK(mips_irq_lock); | 45 | static DEFINE_SPINLOCK(mips_irq_lock); |
@@ -114,13 +113,14 @@ static inline int get_int(void) | |||
114 | return irq; | 113 | return irq; |
115 | } | 114 | } |
116 | 115 | ||
117 | void malta_hw0_irqdispatch(struct pt_regs *regs) | 116 | static void malta_hw0_irqdispatch(struct pt_regs *regs) |
118 | { | 117 | { |
119 | int irq; | 118 | int irq; |
120 | 119 | ||
121 | irq = get_int(); | 120 | irq = get_int(); |
122 | if (irq < 0) | 121 | if (irq < 0) { |
123 | return; /* interrupt has already been cleared */ | 122 | return; /* interrupt has already been cleared */ |
123 | } | ||
124 | 124 | ||
125 | do_IRQ(MALTA_INT_BASE+irq, regs); | 125 | do_IRQ(MALTA_INT_BASE+irq, regs); |
126 | } | 126 | } |
@@ -182,6 +182,92 @@ void corehi_irqdispatch(struct pt_regs *regs) | |||
182 | die("CoreHi interrupt", regs); | 182 | die("CoreHi interrupt", regs); |
183 | } | 183 | } |
184 | 184 | ||
185 | static inline int clz(unsigned long x) | ||
186 | { | ||
187 | __asm__ ( | ||
188 | " .set push \n" | ||
189 | " .set mips32 \n" | ||
190 | " clz %0, %1 \n" | ||
191 | " .set pop \n" | ||
192 | : "=r" (x) | ||
193 | : "r" (x)); | ||
194 | |||
195 | return x; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Version of ffs that only looks at bits 12..15. | ||
200 | */ | ||
201 | static inline unsigned int irq_ffs(unsigned int pending) | ||
202 | { | ||
203 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
204 | return -clz(pending) + 31 - CAUSEB_IP; | ||
205 | #else | ||
206 | unsigned int a0 = 7; | ||
207 | unsigned int t0; | ||
208 | |||
209 | t0 = s0 & 0xf000; | ||
210 | t0 = t0 < 1; | ||
211 | t0 = t0 << 2; | ||
212 | a0 = a0 - t0; | ||
213 | s0 = s0 << t0; | ||
214 | |||
215 | t0 = s0 & 0xc000; | ||
216 | t0 = t0 < 1; | ||
217 | t0 = t0 << 1; | ||
218 | a0 = a0 - t0; | ||
219 | s0 = s0 << t0; | ||
220 | |||
221 | t0 = s0 & 0x8000; | ||
222 | t0 = t0 < 1; | ||
223 | //t0 = t0 << 2; | ||
224 | a0 = a0 - t0; | ||
225 | //s0 = s0 << t0; | ||
226 | |||
227 | return a0; | ||
228 | #endif | ||
229 | } | ||
230 | |||
231 | /* | ||
232 | * IRQs on the Malta board look basically (barring software IRQs which we | ||
233 | * don't use at all and all external interrupt sources are combined together | ||
234 | * on hardware interrupt 0 (MIPS IRQ 2)) like: | ||
235 | * | ||
236 | * MIPS IRQ Source | ||
237 | * -------- ------ | ||
238 | * 0 Software (ignored) | ||
239 | * 1 Software (ignored) | ||
240 | * 2 Combined hardware interrupt (hw0) | ||
241 | * 3 Hardware (ignored) | ||
242 | * 4 Hardware (ignored) | ||
243 | * 5 Hardware (ignored) | ||
244 | * 6 Hardware (ignored) | ||
245 | * 7 R4k timer (what we use) | ||
246 | * | ||
247 | * We handle the IRQ according to _our_ priority which is: | ||
248 | * | ||
249 | * Highest ---- R4k Timer | ||
250 | * Lowest ---- Combined hardware interrupt | ||
251 | * | ||
252 | * then we just return, if multiple IRQs are pending then we will just take | ||
253 | * another exception, big deal. | ||
254 | */ | ||
255 | |||
256 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
257 | { | ||
258 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
259 | int irq; | ||
260 | |||
261 | irq = irq_ffs(pending); | ||
262 | |||
263 | if (irq == MIPSCPU_INT_I8259A) | ||
264 | malta_hw0_irqdispatch(regs); | ||
265 | else if (irq > 0) | ||
266 | do_IRQ(MIPSCPU_INT_BASE + irq, regs); | ||
267 | else | ||
268 | spurious_interrupt(regs); | ||
269 | } | ||
270 | |||
185 | static struct irqaction i8259irq = { | 271 | static struct irqaction i8259irq = { |
186 | .handler = no_action, | 272 | .handler = no_action, |
187 | .name = "XT-PIC cascade" | 273 | .name = "XT-PIC cascade" |
@@ -214,7 +300,6 @@ int __initdata msc_nr_eicirqs = sizeof(msc_eicirqmap)/sizeof(msc_irqmap_t); | |||
214 | 300 | ||
215 | void __init arch_init_irq(void) | 301 | void __init arch_init_irq(void) |
216 | { | 302 | { |
217 | set_except_vector(0, mipsIRQ); | ||
218 | init_i8259_irqs(); | 303 | init_i8259_irqs(); |
219 | 304 | ||
220 | if (!cpu_has_veic) | 305 | if (!cpu_has_veic) |
@@ -240,12 +325,17 @@ void __init arch_init_irq(void) | |||
240 | else if (cpu_has_vint) { | 325 | else if (cpu_has_vint) { |
241 | set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); | 326 | set_vi_handler (MIPSCPU_INT_I8259A, malta_hw0_irqdispatch); |
242 | set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch); | 327 | set_vi_handler (MIPSCPU_INT_COREHI, corehi_irqdispatch); |
243 | 328 | #ifdef CONFIG_MIPS_MT_SMTC | |
329 | setup_irq_smtc (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq, | ||
330 | (0x100 << MIPSCPU_INT_I8259A)); | ||
331 | setup_irq_smtc (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, | ||
332 | &corehi_irqaction, (0x100 << MIPSCPU_INT_COREHI)); | ||
333 | #else /* Not SMTC */ | ||
244 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); | 334 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); |
245 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); | 335 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); |
336 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
246 | } | 337 | } |
247 | else { | 338 | else { |
248 | set_except_vector(0, mipsIRQ); | ||
249 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); | 339 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_I8259A, &i8259irq); |
250 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); | 340 | setup_irq (MIPSCPU_INT_BASE+MIPSCPU_INT_COREHI, &corehi_irqaction); |
251 | } | 341 | } |
diff --git a/arch/mips/mips-boards/malta/malta_smp.c b/arch/mips/mips-boards/malta/malta_smp.c new file mode 100644 index 000000000000..6c6c8eeedbce --- /dev/null +++ b/arch/mips/mips-boards/malta/malta_smp.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Malta Platform-specific hooks for SMP operation | ||
3 | */ | ||
4 | |||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/sched.h> | ||
7 | #include <linux/cpumask.h> | ||
8 | #include <linux/interrupt.h> | ||
9 | |||
10 | #include <asm/atomic.h> | ||
11 | #include <asm/cpu.h> | ||
12 | #include <asm/processor.h> | ||
13 | #include <asm/system.h> | ||
14 | #include <asm/hardirq.h> | ||
15 | #include <asm/mmu_context.h> | ||
16 | #include <asm/smp.h> | ||
17 | #ifdef CONFIG_MIPS_MT_SMTC | ||
18 | #include <asm/smtc_ipi.h> | ||
19 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
20 | |||
21 | /* VPE/SMP Prototype implements platform interfaces directly */ | ||
22 | #if !defined(CONFIG_MIPS_MT_SMP) | ||
23 | |||
24 | /* | ||
25 | * Cause the specified action to be performed on a targeted "CPU" | ||
26 | */ | ||
27 | |||
28 | void core_send_ipi(int cpu, unsigned int action) | ||
29 | { | ||
30 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ | ||
31 | #ifdef CONFIG_MIPS_MT_SMTC | ||
32 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); | ||
33 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * Detect available CPUs/VPEs/TCs and populate phys_cpu_present_map | ||
38 | */ | ||
39 | |||
40 | void __init prom_build_cpu_map(void) | ||
41 | { | ||
42 | int nextslot; | ||
43 | |||
44 | /* | ||
45 | * As of November, 2004, MIPSsim only simulates one core | ||
46 | * at a time. However, that core may be a MIPS MT core | ||
47 | * with multiple virtual processors and thread contexts. | ||
48 | */ | ||
49 | |||
50 | if (read_c0_config3() & (1<<2)) { | ||
51 | nextslot = mipsmt_build_cpu_map(1); | ||
52 | } | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | * Platform "CPU" startup hook | ||
57 | */ | ||
58 | |||
59 | void prom_boot_secondary(int cpu, struct task_struct *idle) | ||
60 | { | ||
61 | #ifdef CONFIG_MIPS_MT_SMTC | ||
62 | smtc_boot_secondary(cpu, idle); | ||
63 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
64 | } | ||
65 | |||
66 | /* | ||
67 | * Post-config but pre-boot cleanup entry point | ||
68 | */ | ||
69 | |||
70 | void prom_init_secondary(void) | ||
71 | { | ||
72 | #ifdef CONFIG_MIPS_MT_SMTC | ||
73 | void smtc_init_secondary(void); | ||
74 | int myvpe; | ||
75 | |||
76 | /* Don't enable Malta I/O interrupts (IP2) for secondary VPEs */ | ||
77 | myvpe = read_c0_tcbind() & TCBIND_CURVPE; | ||
78 | if (myvpe != 0) { | ||
79 | /* Ideally, this should be done only once per VPE, but... */ | ||
80 | clear_c0_status(STATUSF_IP2); | ||
81 | set_c0_status(STATUSF_IP0 | STATUSF_IP1 | STATUSF_IP3 | ||
82 | | STATUSF_IP4 | STATUSF_IP5 | STATUSF_IP6 | ||
83 | | STATUSF_IP7); | ||
84 | } | ||
85 | |||
86 | smtc_init_secondary(); | ||
87 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Platform SMP pre-initialization | ||
92 | * | ||
93 | * As noted above, we can assume a single CPU for now | ||
94 | * but it may be multithreaded. | ||
95 | */ | ||
96 | |||
97 | void plat_smp_setup(void) | ||
98 | { | ||
99 | if (read_c0_config3() & (1<<2)) | ||
100 | mipsmt_build_cpu_map(0); | ||
101 | } | ||
102 | |||
103 | void __init plat_prepare_cpus(unsigned int max_cpus) | ||
104 | { | ||
105 | if (read_c0_config3() & (1<<2)) | ||
106 | mipsmt_prepare_cpus(); | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * SMP initialization finalization entry point | ||
111 | */ | ||
112 | |||
113 | void prom_smp_finish(void) | ||
114 | { | ||
115 | #ifdef CONFIG_MIPS_MT_SMTC | ||
116 | smtc_smp_finish(); | ||
117 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Hook for after all CPUs are online | ||
122 | */ | ||
123 | |||
124 | void prom_cpus_done(void) | ||
125 | { | ||
126 | } | ||
127 | |||
128 | #endif /* CONFIG_MIPS32R2_MT_SMP */ | ||
diff --git a/arch/mips/mips-boards/sead/sead_int.c b/arch/mips/mips-boards/sead/sead_int.c index 90fda0d9915f..9168d934c661 100644 --- a/arch/mips/mips-boards/sead/sead_int.c +++ b/arch/mips/mips-boards/sead/sead_int.c | |||
@@ -24,16 +24,94 @@ | |||
24 | #include <linux/irq.h> | 24 | #include <linux/irq.h> |
25 | 25 | ||
26 | #include <asm/irq_cpu.h> | 26 | #include <asm/irq_cpu.h> |
27 | #include <asm/mipsregs.h> | ||
27 | #include <asm/system.h> | 28 | #include <asm/system.h> |
28 | 29 | ||
29 | #include <asm/mips-boards/seadint.h> | 30 | #include <asm/mips-boards/seadint.h> |
30 | 31 | ||
31 | extern asmlinkage void mipsIRQ(void); | 32 | static inline int clz(unsigned long x) |
33 | { | ||
34 | __asm__ ( | ||
35 | " .set push \n" | ||
36 | " .set mips32 \n" | ||
37 | " clz %0, %1 \n" | ||
38 | " .set pop \n" | ||
39 | : "=r" (x) | ||
40 | : "r" (x)); | ||
41 | |||
42 | return x; | ||
43 | } | ||
44 | |||
45 | /* | ||
46 | * Version of ffs that only looks at bits 12..15. | ||
47 | */ | ||
48 | static inline unsigned int irq_ffs(unsigned int pending) | ||
49 | { | ||
50 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
51 | return -clz(pending) + 31 - CAUSEB_IP; | ||
52 | #else | ||
53 | unsigned int a0 = 7; | ||
54 | unsigned int t0; | ||
55 | |||
56 | t0 = s0 & 0xf000; | ||
57 | t0 = t0 < 1; | ||
58 | t0 = t0 << 2; | ||
59 | a0 = a0 - t0; | ||
60 | s0 = s0 << t0; | ||
61 | |||
62 | t0 = s0 & 0xc000; | ||
63 | t0 = t0 < 1; | ||
64 | t0 = t0 << 1; | ||
65 | a0 = a0 - t0; | ||
66 | s0 = s0 << t0; | ||
67 | |||
68 | t0 = s0 & 0x8000; | ||
69 | t0 = t0 < 1; | ||
70 | //t0 = t0 << 2; | ||
71 | a0 = a0 - t0; | ||
72 | //s0 = s0 << t0; | ||
73 | |||
74 | return a0; | ||
75 | #endif | ||
76 | } | ||
77 | |||
78 | /* | ||
79 | * IRQs on the SEAD board look basically are combined together on hardware | ||
80 | * interrupt 0 (MIPS IRQ 2)) like: | ||
81 | * | ||
82 | * MIPS IRQ Source | ||
83 | * -------- ------ | ||
84 | * 0 Software (ignored) | ||
85 | * 1 Software (ignored) | ||
86 | * 2 UART0 (hw0) | ||
87 | * 3 UART1 (hw1) | ||
88 | * 4 Hardware (ignored) | ||
89 | * 5 Hardware (ignored) | ||
90 | * 6 Hardware (ignored) | ||
91 | * 7 R4k timer (what we use) | ||
92 | * | ||
93 | * We handle the IRQ according to _our_ priority which is: | ||
94 | * | ||
95 | * Highest ---- R4k Timer | ||
96 | * Lowest ---- Combined hardware interrupt | ||
97 | * | ||
98 | * then we just return, if multiple IRQs are pending then we will just take | ||
99 | * another exception, big deal. | ||
100 | */ | ||
101 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
102 | { | ||
103 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
104 | int irq; | ||
105 | |||
106 | irq = irq_ffs(pending); | ||
107 | |||
108 | if (irq >= 0) | ||
109 | do_IRQ(MIPSCPU_INT_BASE + irq, regs); | ||
110 | else | ||
111 | spurious_interrupt(regs); | ||
112 | } | ||
32 | 113 | ||
33 | void __init arch_init_irq(void) | 114 | void __init arch_init_irq(void) |
34 | { | 115 | { |
35 | mips_cpu_irq_init(MIPSCPU_INT_BASE); | 116 | mips_cpu_irq_init(MIPSCPU_INT_BASE); |
36 | |||
37 | /* Now safe to set the exception vector. */ | ||
38 | set_except_vector(0, mipsIRQ); | ||
39 | } | 117 | } |
diff --git a/arch/mips/mips-boards/sim/cmdline.c b/arch/mips/mips-boards/sim/cmdline.c deleted file mode 100644 index fef9fbd8e710..000000000000 --- a/arch/mips/mips-boards/sim/cmdline.c +++ /dev/null | |||
@@ -1,59 +0,0 @@ | |||
1 | /* | ||
2 | * Carsten Langgaard, carstenl@mips.com | ||
3 | * Copyright (C) 1999,2000 MIPS Technologies, Inc. All rights reserved. | ||
4 | * | ||
5 | * This program is free software; you can distribute it and/or modify it | ||
6 | * under the terms of the GNU General Public License (Version 2) as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
12 | * for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along | ||
15 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
17 | * | ||
18 | * Kernel command line creation using the prom monitor (YAMON) argc/argv. | ||
19 | */ | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/string.h> | ||
22 | |||
23 | #include <asm/bootinfo.h> | ||
24 | |||
25 | extern int prom_argc; | ||
26 | extern int *_prom_argv; | ||
27 | |||
28 | /* | ||
29 | * YAMON (32-bit PROM) pass arguments and environment as 32-bit pointer. | ||
30 | * This macro take care of sign extension. | ||
31 | */ | ||
32 | #define prom_argv(index) ((char *)(((int *)(int)_prom_argv)[(index)])) | ||
33 | |||
34 | char arcs_cmdline[CL_SIZE]; | ||
35 | |||
36 | char * __init prom_getcmdline(void) | ||
37 | { | ||
38 | return &(arcs_cmdline[0]); | ||
39 | } | ||
40 | |||
41 | |||
42 | void __init prom_init_cmdline(void) | ||
43 | { | ||
44 | char *cp; | ||
45 | int actr; | ||
46 | |||
47 | actr = 1; /* Always ignore argv[0] */ | ||
48 | |||
49 | cp = &(arcs_cmdline[0]); | ||
50 | while(actr < prom_argc) { | ||
51 | strcpy(cp, prom_argv(actr)); | ||
52 | cp += strlen(prom_argv(actr)); | ||
53 | *cp++ = ' '; | ||
54 | actr++; | ||
55 | } | ||
56 | if (cp != &(arcs_cmdline[0])) /* get rid of trailing space */ | ||
57 | --cp; | ||
58 | *cp = '\0'; | ||
59 | } | ||
diff --git a/arch/mips/mips-boards/sim/sim_cmdline.c b/arch/mips/mips-boards/sim/sim_cmdline.c index 9df37c6fca36..c63021a5dc6c 100644 --- a/arch/mips/mips-boards/sim/sim_cmdline.c +++ b/arch/mips/mips-boards/sim/sim_cmdline.c | |||
@@ -26,8 +26,10 @@ char * __init prom_getcmdline(void) | |||
26 | return arcs_cmdline; | 26 | return arcs_cmdline; |
27 | } | 27 | } |
28 | 28 | ||
29 | |||
30 | void __init prom_init_cmdline(void) | 29 | void __init prom_init_cmdline(void) |
31 | { | 30 | { |
32 | /* nothing to do */ | 31 | char *cp; |
32 | cp = arcs_cmdline; | ||
33 | /* Get boot line from environment? */ | ||
34 | *cp = '\0'; | ||
33 | } | 35 | } |
diff --git a/arch/mips/mips-boards/sim/sim_int.c b/arch/mips/mips-boards/sim/sim_int.c index a4d0a2c05031..2c15c8efec4e 100644 --- a/arch/mips/mips-boards/sim/sim_int.c +++ b/arch/mips/mips-boards/sim/sim_int.c | |||
@@ -25,17 +25,71 @@ | |||
25 | 25 | ||
26 | extern void mips_cpu_irq_init(int); | 26 | extern void mips_cpu_irq_init(int); |
27 | 27 | ||
28 | extern asmlinkage void simIRQ(void); | 28 | static inline int clz(unsigned long x) |
29 | { | ||
30 | __asm__ ( | ||
31 | " .set push \n" | ||
32 | " .set mips32 \n" | ||
33 | " clz %0, %1 \n" | ||
34 | " .set pop \n" | ||
35 | : "=r" (x) | ||
36 | : "r" (x)); | ||
37 | |||
38 | return x; | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * Version of ffs that only looks at bits 12..15. | ||
43 | */ | ||
44 | static inline unsigned int irq_ffs(unsigned int pending) | ||
45 | { | ||
46 | #if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64) | ||
47 | return -clz(pending) + 31 - CAUSEB_IP; | ||
48 | #else | ||
49 | unsigned int a0 = 7; | ||
50 | unsigned int t0; | ||
51 | |||
52 | t0 = s0 & 0xf000; | ||
53 | t0 = t0 < 1; | ||
54 | t0 = t0 << 2; | ||
55 | a0 = a0 - t0; | ||
56 | s0 = s0 << t0; | ||
57 | |||
58 | t0 = s0 & 0xc000; | ||
59 | t0 = t0 < 1; | ||
60 | t0 = t0 << 1; | ||
61 | a0 = a0 - t0; | ||
62 | s0 = s0 << t0; | ||
29 | 63 | ||
30 | asmlinkage void sim_hw0_irqdispatch(struct pt_regs *regs) | 64 | t0 = s0 & 0x8000; |
65 | t0 = t0 < 1; | ||
66 | //t0 = t0 << 2; | ||
67 | a0 = a0 - t0; | ||
68 | //s0 = s0 << t0; | ||
69 | |||
70 | return a0; | ||
71 | #endif | ||
72 | } | ||
73 | |||
74 | static inline void sim_hw0_irqdispatch(struct pt_regs *regs) | ||
31 | { | 75 | { |
32 | do_IRQ(2, regs); | 76 | do_IRQ(2, regs); |
33 | } | 77 | } |
34 | 78 | ||
35 | void __init arch_init_irq(void) | 79 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
36 | { | 80 | { |
37 | /* Now safe to set the exception vector. */ | 81 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; |
38 | set_except_vector(0, simIRQ); | 82 | int irq; |
83 | |||
84 | irq = irq_ffs(pending); | ||
39 | 85 | ||
86 | if (irq > 0) | ||
87 | do_IRQ(MIPSCPU_INT_BASE + irq, regs); | ||
88 | else | ||
89 | spurious_interrupt(regs); | ||
90 | } | ||
91 | |||
92 | void __init arch_init_irq(void) | ||
93 | { | ||
40 | mips_cpu_irq_init(MIPSCPU_INT_BASE); | 94 | mips_cpu_irq_init(MIPSCPU_INT_BASE); |
41 | } | 95 | } |
diff --git a/arch/mips/mips-boards/sim/sim_irq.S b/arch/mips/mips-boards/sim/sim_irq.S index da52297a2216..d16cf3822076 100644 --- a/arch/mips/mips-boards/sim/sim_irq.S +++ b/arch/mips/mips-boards/sim/sim_irq.S | |||
@@ -94,6 +94,8 @@ | |||
94 | 94 | ||
95 | 95 | ||
96 | spurious: | 96 | spurious: |
97 | j spurious_interrupt | 97 | jal spurious_interrupt |
98 | nop | ||
99 | j ret_from_irq | ||
98 | nop | 100 | nop |
99 | END(simIRQ) | 101 | END(simIRQ) |
diff --git a/arch/mips/mips-boards/sim/sim_mem.c b/arch/mips/mips-boards/sim/sim_mem.c index e57f737bab10..f7ce76983328 100644 --- a/arch/mips/mips-boards/sim/sim_mem.c +++ b/arch/mips/mips-boards/sim/sim_mem.c | |||
@@ -18,9 +18,11 @@ | |||
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/mm.h> | 19 | #include <linux/mm.h> |
20 | #include <linux/bootmem.h> | 20 | #include <linux/bootmem.h> |
21 | #include <linux/pfn.h> | ||
21 | 22 | ||
22 | #include <asm/bootinfo.h> | 23 | #include <asm/bootinfo.h> |
23 | #include <asm/page.h> | 24 | #include <asm/page.h> |
25 | #include <asm/sections.h> | ||
24 | 26 | ||
25 | #include <asm/mips-boards/prom.h> | 27 | #include <asm/mips-boards/prom.h> |
26 | 28 | ||
@@ -39,9 +41,6 @@ static char *mtypes[3] = { | |||
39 | }; | 41 | }; |
40 | #endif | 42 | #endif |
41 | 43 | ||
42 | /* References to section boundaries */ | ||
43 | extern char _end; | ||
44 | |||
45 | struct prom_pmemblock * __init prom_getmdesc(void) | 44 | struct prom_pmemblock * __init prom_getmdesc(void) |
46 | { | 45 | { |
47 | unsigned int memsize; | 46 | unsigned int memsize; |
@@ -61,10 +60,10 @@ struct prom_pmemblock * __init prom_getmdesc(void) | |||
61 | 60 | ||
62 | mdesc[2].type = simmem_reserved; | 61 | mdesc[2].type = simmem_reserved; |
63 | mdesc[2].base = 0x00100000; | 62 | mdesc[2].base = 0x00100000; |
64 | mdesc[2].size = CPHYSADDR(PAGE_ALIGN(&_end)) - mdesc[2].base; | 63 | mdesc[2].size = CPHYSADDR(PFN_ALIGN(&_end)) - mdesc[2].base; |
65 | 64 | ||
66 | mdesc[3].type = simmem_free; | 65 | mdesc[3].type = simmem_free; |
67 | mdesc[3].base = CPHYSADDR(PAGE_ALIGN(&_end)); | 66 | mdesc[3].base = CPHYSADDR(PFN_ALIGN(&_end)); |
68 | mdesc[3].size = memsize - mdesc[3].base; | 67 | mdesc[3].size = memsize - mdesc[3].base; |
69 | 68 | ||
70 | return &mdesc[0]; | 69 | return &mdesc[0]; |
diff --git a/arch/mips/mips-boards/sim/sim_smp.c b/arch/mips/mips-boards/sim/sim_smp.c index a9f0c2bfe4ad..b7084e7c4bf9 100644 --- a/arch/mips/mips-boards/sim/sim_smp.c +++ b/arch/mips/mips-boards/sim/sim_smp.c | |||
@@ -44,8 +44,6 @@ | |||
44 | void core_send_ipi(int cpu, unsigned int action) | 44 | void core_send_ipi(int cpu, unsigned int action) |
45 | { | 45 | { |
46 | #ifdef CONFIG_MIPS_MT_SMTC | 46 | #ifdef CONFIG_MIPS_MT_SMTC |
47 | void smtc_send_ipi(int, int, unsigned int); | ||
48 | |||
49 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); | 47 | smtc_send_ipi(cpu, LINUX_SMP_IPI, action); |
50 | #endif /* CONFIG_MIPS_MT_SMTC */ | 48 | #endif /* CONFIG_MIPS_MT_SMTC */ |
51 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ | 49 | /* "CPU" may be TC of same VPE, VPE of same CPU, or different CPU */ |
@@ -59,15 +57,8 @@ void core_send_ipi(int cpu, unsigned int action) | |||
59 | void __init prom_build_cpu_map(void) | 57 | void __init prom_build_cpu_map(void) |
60 | { | 58 | { |
61 | #ifdef CONFIG_MIPS_MT_SMTC | 59 | #ifdef CONFIG_MIPS_MT_SMTC |
62 | extern int mipsmt_build_cpu_map(int startslot); | ||
63 | int nextslot; | 60 | int nextslot; |
64 | 61 | ||
65 | cpus_clear(phys_cpu_present_map); | ||
66 | |||
67 | /* Register the boot CPU */ | ||
68 | |||
69 | smp_prepare_boot_cpu(); | ||
70 | |||
71 | /* | 62 | /* |
72 | * As of November, 2004, MIPSsim only simulates one core | 63 | * As of November, 2004, MIPSsim only simulates one core |
73 | * at a time. However, that core may be a MIPS MT core | 64 | * at a time. However, that core may be a MIPS MT core |
@@ -87,8 +78,6 @@ void __init prom_build_cpu_map(void) | |||
87 | void prom_boot_secondary(int cpu, struct task_struct *idle) | 78 | void prom_boot_secondary(int cpu, struct task_struct *idle) |
88 | { | 79 | { |
89 | #ifdef CONFIG_MIPS_MT_SMTC | 80 | #ifdef CONFIG_MIPS_MT_SMTC |
90 | extern void smtc_boot_secondary(int cpu, struct task_struct *t); | ||
91 | |||
92 | smtc_boot_secondary(cpu, idle); | 81 | smtc_boot_secondary(cpu, idle); |
93 | #endif /* CONFIG_MIPS_MT_SMTC */ | 82 | #endif /* CONFIG_MIPS_MT_SMTC */ |
94 | } | 83 | } |
@@ -113,7 +102,6 @@ void prom_init_secondary(void) | |||
113 | void prom_prepare_cpus(unsigned int max_cpus) | 102 | void prom_prepare_cpus(unsigned int max_cpus) |
114 | { | 103 | { |
115 | #ifdef CONFIG_MIPS_MT_SMTC | 104 | #ifdef CONFIG_MIPS_MT_SMTC |
116 | void mipsmt_prepare_cpus(int c); | ||
117 | /* | 105 | /* |
118 | * As noted above, we can assume a single CPU for now | 106 | * As noted above, we can assume a single CPU for now |
119 | * but it may be multithreaded. | 107 | * but it may be multithreaded. |
@@ -132,8 +120,6 @@ void prom_prepare_cpus(unsigned int max_cpus) | |||
132 | void prom_smp_finish(void) | 120 | void prom_smp_finish(void) |
133 | { | 121 | { |
134 | #ifdef CONFIG_MIPS_MT_SMTC | 122 | #ifdef CONFIG_MIPS_MT_SMTC |
135 | void smtc_smp_finish(void); | ||
136 | |||
137 | smtc_smp_finish(); | 123 | smtc_smp_finish(); |
138 | #endif /* CONFIG_MIPS_MT_SMTC */ | 124 | #endif /* CONFIG_MIPS_MT_SMTC */ |
139 | } | 125 | } |
diff --git a/arch/mips/mm/c-r3k.c b/arch/mips/mm/c-r3k.c index 9dd1352d5748..bb041a22f20a 100644 --- a/arch/mips/mm/c-r3k.c +++ b/arch/mips/mm/c-r3k.c | |||
@@ -260,6 +260,10 @@ static void r3k_flush_cache_page(struct vm_area_struct *vma, unsigned long page, | |||
260 | { | 260 | { |
261 | } | 261 | } |
262 | 262 | ||
263 | static void local_r3k_flush_data_cache_page(unsigned long addr) | ||
264 | { | ||
265 | } | ||
266 | |||
263 | static void r3k_flush_data_cache_page(unsigned long addr) | 267 | static void r3k_flush_data_cache_page(unsigned long addr) |
264 | { | 268 | { |
265 | } | 269 | } |
@@ -335,6 +339,7 @@ void __init r3k_cache_init(void) | |||
335 | flush_icache_range = r3k_flush_icache_range; | 339 | flush_icache_range = r3k_flush_icache_range; |
336 | 340 | ||
337 | flush_cache_sigtramp = r3k_flush_cache_sigtramp; | 341 | flush_cache_sigtramp = r3k_flush_cache_sigtramp; |
342 | local_flush_data_cache_page = local_r3k_flush_data_cache_page; | ||
338 | flush_data_cache_page = r3k_flush_data_cache_page; | 343 | flush_data_cache_page = r3k_flush_data_cache_page; |
339 | 344 | ||
340 | _dma_cache_wback_inv = r3k_dma_cache_wback_inv; | 345 | _dma_cache_wback_inv = r3k_dma_cache_wback_inv; |
diff --git a/arch/mips/mm/c-r4k.c b/arch/mips/mm/c-r4k.c index 32b7f6aeb983..4182e1176fae 100644 --- a/arch/mips/mm/c-r4k.c +++ b/arch/mips/mm/c-r4k.c | |||
@@ -154,7 +154,8 @@ static inline void blast_icache32_r4600_v1_page_indexed(unsigned long page) | |||
154 | 154 | ||
155 | static inline void tx49_blast_icache32_page_indexed(unsigned long page) | 155 | static inline void tx49_blast_icache32_page_indexed(unsigned long page) |
156 | { | 156 | { |
157 | unsigned long start = page; | 157 | unsigned long indexmask = current_cpu_data.icache.waysize - 1; |
158 | unsigned long start = INDEX_BASE + (page & indexmask); | ||
158 | unsigned long end = start + PAGE_SIZE; | 159 | unsigned long end = start + PAGE_SIZE; |
159 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; | 160 | unsigned long ws_inc = 1UL << current_cpu_data.icache.waybit; |
160 | unsigned long ws_end = current_cpu_data.icache.ways << | 161 | unsigned long ws_end = current_cpu_data.icache.ways << |
@@ -749,12 +750,12 @@ static void __init probe_pcache(void) | |||
749 | icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); | 750 | icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); |
750 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); | 751 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); |
751 | c->icache.ways = 2; | 752 | c->icache.ways = 2; |
752 | c->icache.waybit = ffs(icache_size/2) - 1; | 753 | c->icache.waybit = __ffs(icache_size/2); |
753 | 754 | ||
754 | dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); | 755 | dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); |
755 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); | 756 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); |
756 | c->dcache.ways = 2; | 757 | c->dcache.ways = 2; |
757 | c->dcache.waybit= ffs(dcache_size/2) - 1; | 758 | c->dcache.waybit= __ffs(dcache_size/2); |
758 | 759 | ||
759 | c->options |= MIPS_CPU_CACHE_CDEX_P; | 760 | c->options |= MIPS_CPU_CACHE_CDEX_P; |
760 | break; | 761 | break; |
@@ -837,12 +838,12 @@ static void __init probe_pcache(void) | |||
837 | icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); | 838 | icache_size = 1 << (10 + ((config & CONF_IC) >> 9)); |
838 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); | 839 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); |
839 | c->icache.ways = 2; | 840 | c->icache.ways = 2; |
840 | c->icache.waybit = ffs(icache_size/2) - 1; | 841 | c->icache.waybit = __ffs(icache_size/2); |
841 | 842 | ||
842 | dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); | 843 | dcache_size = 1 << (10 + ((config & CONF_DC) >> 6)); |
843 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); | 844 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); |
844 | c->dcache.ways = 2; | 845 | c->dcache.ways = 2; |
845 | c->dcache.waybit = ffs(dcache_size/2) - 1; | 846 | c->dcache.waybit = __ffs(dcache_size/2); |
846 | 847 | ||
847 | c->options |= MIPS_CPU_CACHE_CDEX_P; | 848 | c->options |= MIPS_CPU_CACHE_CDEX_P; |
848 | break; | 849 | break; |
@@ -873,12 +874,12 @@ static void __init probe_pcache(void) | |||
873 | icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); | 874 | icache_size = 1 << (12 + ((config & CONF_IC) >> 9)); |
874 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); | 875 | c->icache.linesz = 16 << ((config & CONF_IB) >> 5); |
875 | c->icache.ways = 4; | 876 | c->icache.ways = 4; |
876 | c->icache.waybit = ffs(icache_size / c->icache.ways) - 1; | 877 | c->icache.waybit = __ffs(icache_size / c->icache.ways); |
877 | 878 | ||
878 | dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); | 879 | dcache_size = 1 << (12 + ((config & CONF_DC) >> 6)); |
879 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); | 880 | c->dcache.linesz = 16 << ((config & CONF_DB) >> 4); |
880 | c->dcache.ways = 4; | 881 | c->dcache.ways = 4; |
881 | c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1; | 882 | c->dcache.waybit = __ffs(dcache_size / c->dcache.ways); |
882 | 883 | ||
883 | #if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR) | 884 | #if !defined(CONFIG_SMP) || !defined(RM9000_CDEX_SMP_WAR) |
884 | c->options |= MIPS_CPU_CACHE_CDEX_P; | 885 | c->options |= MIPS_CPU_CACHE_CDEX_P; |
@@ -906,7 +907,7 @@ static void __init probe_pcache(void) | |||
906 | icache_size = c->icache.sets * | 907 | icache_size = c->icache.sets * |
907 | c->icache.ways * | 908 | c->icache.ways * |
908 | c->icache.linesz; | 909 | c->icache.linesz; |
909 | c->icache.waybit = ffs(icache_size/c->icache.ways) - 1; | 910 | c->icache.waybit = __ffs(icache_size/c->icache.ways); |
910 | 911 | ||
911 | if (config & 0x8) /* VI bit */ | 912 | if (config & 0x8) /* VI bit */ |
912 | c->icache.flags |= MIPS_CACHE_VTAG; | 913 | c->icache.flags |= MIPS_CACHE_VTAG; |
@@ -926,7 +927,7 @@ static void __init probe_pcache(void) | |||
926 | dcache_size = c->dcache.sets * | 927 | dcache_size = c->dcache.sets * |
927 | c->dcache.ways * | 928 | c->dcache.ways * |
928 | c->dcache.linesz; | 929 | c->dcache.linesz; |
929 | c->dcache.waybit = ffs(dcache_size/c->dcache.ways) - 1; | 930 | c->dcache.waybit = __ffs(dcache_size/c->dcache.ways); |
930 | 931 | ||
931 | c->options |= MIPS_CPU_PREFETCH; | 932 | c->options |= MIPS_CPU_PREFETCH; |
932 | break; | 933 | break; |
@@ -1198,6 +1199,7 @@ void __init r4k_cache_init(void) | |||
1198 | 1199 | ||
1199 | flush_cache_sigtramp = r4k_flush_cache_sigtramp; | 1200 | flush_cache_sigtramp = r4k_flush_cache_sigtramp; |
1200 | flush_icache_all = r4k_flush_icache_all; | 1201 | flush_icache_all = r4k_flush_icache_all; |
1202 | local_flush_data_cache_page = local_r4k_flush_data_cache_page; | ||
1201 | flush_data_cache_page = r4k_flush_data_cache_page; | 1203 | flush_data_cache_page = r4k_flush_data_cache_page; |
1202 | flush_icache_range = r4k_flush_icache_range; | 1204 | flush_icache_range = r4k_flush_icache_range; |
1203 | 1205 | ||
diff --git a/arch/mips/mm/c-sb1.c b/arch/mips/mm/c-sb1.c index 2f08b535f20e..f9b129491b1e 100644 --- a/arch/mips/mm/c-sb1.c +++ b/arch/mips/mm/c-sb1.c | |||
@@ -528,6 +528,7 @@ void sb1_cache_init(void) | |||
528 | flush_cache_page = sb1_flush_cache_page; | 528 | flush_cache_page = sb1_flush_cache_page; |
529 | 529 | ||
530 | flush_cache_sigtramp = sb1_flush_cache_sigtramp; | 530 | flush_cache_sigtramp = sb1_flush_cache_sigtramp; |
531 | local_flush_data_cache_page = (void *) sb1_nop; | ||
531 | flush_data_cache_page = (void *) sb1_nop; | 532 | flush_data_cache_page = (void *) sb1_nop; |
532 | 533 | ||
533 | /* Full flush */ | 534 | /* Full flush */ |
diff --git a/arch/mips/mm/c-tx39.c b/arch/mips/mm/c-tx39.c index fe232e3988e3..5dfc9b1901f6 100644 --- a/arch/mips/mm/c-tx39.c +++ b/arch/mips/mm/c-tx39.c | |||
@@ -216,6 +216,11 @@ static void tx39_flush_cache_page(struct vm_area_struct *vma, unsigned long page | |||
216 | tx39_blast_icache_page_indexed(page); | 216 | tx39_blast_icache_page_indexed(page); |
217 | } | 217 | } |
218 | 218 | ||
219 | static void local_tx39_flush_data_cache_page(void * addr) | ||
220 | { | ||
221 | tx39_blast_dcache_page(addr); | ||
222 | } | ||
223 | |||
219 | static void tx39_flush_data_cache_page(unsigned long addr) | 224 | static void tx39_flush_data_cache_page(unsigned long addr) |
220 | { | 225 | { |
221 | tx39_blast_dcache_page(addr); | 226 | tx39_blast_dcache_page(addr); |
@@ -381,6 +386,7 @@ void __init tx39_cache_init(void) | |||
381 | flush_icache_range = (void *) tx39h_flush_icache_all; | 386 | flush_icache_range = (void *) tx39h_flush_icache_all; |
382 | 387 | ||
383 | flush_cache_sigtramp = (void *) tx39h_flush_icache_all; | 388 | flush_cache_sigtramp = (void *) tx39h_flush_icache_all; |
389 | local_flush_data_cache_page = (void *) tx39h_flush_icache_all; | ||
384 | flush_data_cache_page = (void *) tx39h_flush_icache_all; | 390 | flush_data_cache_page = (void *) tx39h_flush_icache_all; |
385 | 391 | ||
386 | _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; | 392 | _dma_cache_wback_inv = tx39h_dma_cache_wback_inv; |
@@ -406,6 +412,7 @@ void __init tx39_cache_init(void) | |||
406 | flush_icache_range = tx39_flush_icache_range; | 412 | flush_icache_range = tx39_flush_icache_range; |
407 | 413 | ||
408 | flush_cache_sigtramp = tx39_flush_cache_sigtramp; | 414 | flush_cache_sigtramp = tx39_flush_cache_sigtramp; |
415 | local_flush_data_cache_page = local_tx39_flush_data_cache_page; | ||
409 | flush_data_cache_page = tx39_flush_data_cache_page; | 416 | flush_data_cache_page = tx39_flush_data_cache_page; |
410 | 417 | ||
411 | _dma_cache_wback_inv = tx39_dma_cache_wback_inv; | 418 | _dma_cache_wback_inv = tx39_dma_cache_wback_inv; |
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c index 591c22b080e4..83a56296be86 100644 --- a/arch/mips/mm/cache.c +++ b/arch/mips/mm/cache.c | |||
@@ -30,6 +30,7 @@ void (*flush_icache_page)(struct vm_area_struct *vma, struct page *page); | |||
30 | 30 | ||
31 | /* MIPS specific cache operations */ | 31 | /* MIPS specific cache operations */ |
32 | void (*flush_cache_sigtramp)(unsigned long addr); | 32 | void (*flush_cache_sigtramp)(unsigned long addr); |
33 | void (*local_flush_data_cache_page)(void * addr); | ||
33 | void (*flush_data_cache_page)(unsigned long addr); | 34 | void (*flush_data_cache_page)(unsigned long addr); |
34 | void (*flush_icache_all)(void); | 35 | void (*flush_icache_all)(void); |
35 | 36 | ||
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index 2d9624fd10ec..e3a617224868 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c | |||
@@ -157,7 +157,6 @@ no_context: | |||
157 | * Oops. The kernel tried to access some bad page. We'll have to | 157 | * Oops. The kernel tried to access some bad page. We'll have to |
158 | * terminate things with extreme prejudice. | 158 | * terminate things with extreme prejudice. |
159 | */ | 159 | */ |
160 | |||
161 | bust_spinlocks(1); | 160 | bust_spinlocks(1); |
162 | 161 | ||
163 | printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at " | 162 | printk(KERN_ALERT "CPU %d Unable to handle kernel paging request at " |
@@ -188,11 +187,20 @@ do_sigbus: | |||
188 | /* Kernel mode? Handle exceptions or die */ | 187 | /* Kernel mode? Handle exceptions or die */ |
189 | if (!user_mode(regs)) | 188 | if (!user_mode(regs)) |
190 | goto no_context; | 189 | goto no_context; |
191 | 190 | else | |
192 | /* | 191 | /* |
193 | * Send a sigbus, regardless of whether we were in kernel | 192 | * Send a sigbus, regardless of whether we were in kernel |
194 | * or user mode. | 193 | * or user mode. |
195 | */ | 194 | */ |
195 | #if 0 | ||
196 | printk("do_page_fault() #3: sending SIGBUS to %s for " | ||
197 | "invalid %s\n%0*lx (epc == %0*lx, ra == %0*lx)\n", | ||
198 | tsk->comm, | ||
199 | write ? "write access to" : "read access from", | ||
200 | field, address, | ||
201 | field, (unsigned long) regs->cp0_epc, | ||
202 | field, (unsigned long) regs->regs[31]); | ||
203 | #endif | ||
196 | tsk->thread.cp0_badvaddr = address; | 204 | tsk->thread.cp0_badvaddr = address; |
197 | info.si_signo = SIGBUS; | 205 | info.si_signo = SIGBUS; |
198 | info.si_errno = 0; | 206 | info.si_errno = 0; |
@@ -201,7 +209,6 @@ do_sigbus: | |||
201 | force_sig_info(SIGBUS, &info, tsk); | 209 | force_sig_info(SIGBUS, &info, tsk); |
202 | 210 | ||
203 | return; | 211 | return; |
204 | |||
205 | vmalloc_fault: | 212 | vmalloc_fault: |
206 | { | 213 | { |
207 | /* | 214 | /* |
diff --git a/arch/mips/mm/highmem.c b/arch/mips/mm/highmem.c index 1f7b37b38f5c..0c544375b856 100644 --- a/arch/mips/mm/highmem.c +++ b/arch/mips/mm/highmem.c | |||
@@ -83,6 +83,7 @@ void __kunmap_atomic(void *kvaddr, enum km_type type) | |||
83 | preempt_check_resched(); | 83 | preempt_check_resched(); |
84 | } | 84 | } |
85 | 85 | ||
86 | #ifndef CONFIG_LIMITED_DMA | ||
86 | /* | 87 | /* |
87 | * This is the same as kmap_atomic() but can map memory that doesn't | 88 | * This is the same as kmap_atomic() but can map memory that doesn't |
88 | * have a struct page associated with it. | 89 | * have a struct page associated with it. |
@@ -101,6 +102,7 @@ void *kmap_atomic_pfn(unsigned long pfn, enum km_type type) | |||
101 | 102 | ||
102 | return (void*) vaddr; | 103 | return (void*) vaddr; |
103 | } | 104 | } |
105 | #endif /* CONFIG_LIMITED_DMA */ | ||
104 | 106 | ||
105 | struct page *__kmap_atomic_to_page(void *ptr) | 107 | struct page *__kmap_atomic_to_page(void *ptr) |
106 | { | 108 | { |
diff --git a/arch/mips/mm/init.c b/arch/mips/mm/init.c index ad89c442f299..c22308b93ff0 100644 --- a/arch/mips/mm/init.c +++ b/arch/mips/mm/init.c | |||
@@ -276,6 +276,20 @@ void __init mem_init(void) | |||
276 | } | 276 | } |
277 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ | 277 | #endif /* !CONFIG_NEED_MULTIPLE_NODES */ |
278 | 278 | ||
279 | void free_init_pages(char *what, unsigned long begin, unsigned long end) | ||
280 | { | ||
281 | unsigned long addr; | ||
282 | |||
283 | for (addr = begin; addr < end; addr += PAGE_SIZE) { | ||
284 | ClearPageReserved(virt_to_page(addr)); | ||
285 | init_page_count(virt_to_page(addr)); | ||
286 | memset((void *)addr, 0xcc, PAGE_SIZE); | ||
287 | free_page(addr); | ||
288 | totalram_pages++; | ||
289 | } | ||
290 | printk(KERN_INFO "Freeing %s: %ldk freed\n", what, (end - begin) >> 10); | ||
291 | } | ||
292 | |||
279 | #ifdef CONFIG_BLK_DEV_INITRD | 293 | #ifdef CONFIG_BLK_DEV_INITRD |
280 | void free_initrd_mem(unsigned long start, unsigned long end) | 294 | void free_initrd_mem(unsigned long start, unsigned long end) |
281 | { | 295 | { |
@@ -284,16 +298,7 @@ void free_initrd_mem(unsigned long start, unsigned long end) | |||
284 | start = (unsigned long)phys_to_virt(CPHYSADDR(start)); | 298 | start = (unsigned long)phys_to_virt(CPHYSADDR(start)); |
285 | end = (unsigned long)phys_to_virt(CPHYSADDR(end)); | 299 | end = (unsigned long)phys_to_virt(CPHYSADDR(end)); |
286 | #endif | 300 | #endif |
287 | if (start < end) | 301 | free_init_pages("initrd memory", start, end); |
288 | printk(KERN_INFO "Freeing initrd memory: %ldk freed\n", | ||
289 | (end - start) >> 10); | ||
290 | |||
291 | for (; start < end; start += PAGE_SIZE) { | ||
292 | ClearPageReserved(virt_to_page(start)); | ||
293 | init_page_count(virt_to_page(start)); | ||
294 | free_page(start); | ||
295 | totalram_pages++; | ||
296 | } | ||
297 | } | 302 | } |
298 | #endif | 303 | #endif |
299 | 304 | ||
@@ -301,24 +306,17 @@ extern unsigned long prom_free_prom_memory(void); | |||
301 | 306 | ||
302 | void free_initmem(void) | 307 | void free_initmem(void) |
303 | { | 308 | { |
304 | unsigned long addr, page, freed; | 309 | unsigned long start, end, freed; |
305 | 310 | ||
306 | freed = prom_free_prom_memory(); | 311 | freed = prom_free_prom_memory(); |
312 | if (freed) | ||
313 | printk(KERN_INFO "Freeing firmware memory: %ldk freed\n",freed); | ||
307 | 314 | ||
308 | addr = (unsigned long) &__init_begin; | 315 | start = (unsigned long)(&__init_begin); |
309 | while (addr < (unsigned long) &__init_end) { | 316 | end = (unsigned long)(&__init_end); |
310 | #ifdef CONFIG_64BIT | 317 | #ifdef CONFIG_64BIT |
311 | page = PAGE_OFFSET | CPHYSADDR(addr); | 318 | start = PAGE_OFFSET | CPHYSADDR(start); |
312 | #else | 319 | end = PAGE_OFFSET | CPHYSADDR(end); |
313 | page = addr; | ||
314 | #endif | 320 | #endif |
315 | ClearPageReserved(virt_to_page(page)); | 321 | free_init_pages("unused kernel memory", start, end); |
316 | init_page_count(virt_to_page(page)); | ||
317 | free_page(page); | ||
318 | totalram_pages++; | ||
319 | freed += PAGE_SIZE; | ||
320 | addr += PAGE_SIZE; | ||
321 | } | ||
322 | printk(KERN_INFO "Freeing unused kernel memory: %ldk freed\n", | ||
323 | freed >> 10); | ||
324 | } | 322 | } |
diff --git a/arch/mips/mm/sc-rm7k.c b/arch/mips/mm/sc-rm7k.c index 3b6cc9ba1b05..31ec73052423 100644 --- a/arch/mips/mm/sc-rm7k.c +++ b/arch/mips/mm/sc-rm7k.c | |||
@@ -138,7 +138,7 @@ void __init rm7k_sc_init(void) | |||
138 | 138 | ||
139 | c->scache.linesz = sc_lsize; | 139 | c->scache.linesz = sc_lsize; |
140 | c->scache.ways = 4; | 140 | c->scache.ways = 4; |
141 | c->scache.waybit= ffs(scache_size / c->scache.ways) - 1; | 141 | c->scache.waybit= __ffs(scache_size / c->scache.ways); |
142 | c->scache.waysize = scache_size / c->scache.ways; | 142 | c->scache.waysize = scache_size / c->scache.ways; |
143 | c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); | 143 | c->scache.sets = scache_size / (c->scache.linesz * c->scache.ways); |
144 | printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n", | 144 | printk(KERN_INFO "Secondary cache size %dK, linesize %d bytes.\n", |
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c index a865f2394cb0..9dca099ba16b 100644 --- a/arch/mips/mm/tlb-r4k.c +++ b/arch/mips/mm/tlb-r4k.c | |||
@@ -32,13 +32,35 @@ extern void build_tlb_refill_handler(void); | |||
32 | "nop; nop; nop; nop; nop; nop;\n\t" \ | 32 | "nop; nop; nop; nop; nop; nop;\n\t" \ |
33 | ".set reorder\n\t") | 33 | ".set reorder\n\t") |
34 | 34 | ||
35 | /* Atomicity and interruptability */ | ||
36 | #ifdef CONFIG_MIPS_MT_SMTC | ||
37 | |||
38 | #include <asm/smtc.h> | ||
39 | #include <asm/mipsmtregs.h> | ||
40 | |||
41 | #define ENTER_CRITICAL(flags) \ | ||
42 | { \ | ||
43 | unsigned int mvpflags; \ | ||
44 | local_irq_save(flags);\ | ||
45 | mvpflags = dvpe() | ||
46 | #define EXIT_CRITICAL(flags) \ | ||
47 | evpe(mvpflags); \ | ||
48 | local_irq_restore(flags); \ | ||
49 | } | ||
50 | #else | ||
51 | |||
52 | #define ENTER_CRITICAL(flags) local_irq_save(flags) | ||
53 | #define EXIT_CRITICAL(flags) local_irq_restore(flags) | ||
54 | |||
55 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
56 | |||
35 | void local_flush_tlb_all(void) | 57 | void local_flush_tlb_all(void) |
36 | { | 58 | { |
37 | unsigned long flags; | 59 | unsigned long flags; |
38 | unsigned long old_ctx; | 60 | unsigned long old_ctx; |
39 | int entry; | 61 | int entry; |
40 | 62 | ||
41 | local_irq_save(flags); | 63 | ENTER_CRITICAL(flags); |
42 | /* Save old context and create impossible VPN2 value */ | 64 | /* Save old context and create impossible VPN2 value */ |
43 | old_ctx = read_c0_entryhi(); | 65 | old_ctx = read_c0_entryhi(); |
44 | write_c0_entrylo0(0); | 66 | write_c0_entrylo0(0); |
@@ -57,7 +79,7 @@ void local_flush_tlb_all(void) | |||
57 | } | 79 | } |
58 | tlbw_use_hazard(); | 80 | tlbw_use_hazard(); |
59 | write_c0_entryhi(old_ctx); | 81 | write_c0_entryhi(old_ctx); |
60 | local_irq_restore(flags); | 82 | EXIT_CRITICAL(flags); |
61 | } | 83 | } |
62 | 84 | ||
63 | /* All entries common to a mm share an asid. To effectively flush | 85 | /* All entries common to a mm share an asid. To effectively flush |
@@ -87,6 +109,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
87 | unsigned long flags; | 109 | unsigned long flags; |
88 | int size; | 110 | int size; |
89 | 111 | ||
112 | ENTER_CRITICAL(flags); | ||
90 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 113 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
91 | size = (size + 1) >> 1; | 114 | size = (size + 1) >> 1; |
92 | local_irq_save(flags); | 115 | local_irq_save(flags); |
@@ -120,7 +143,7 @@ void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start, | |||
120 | } else { | 143 | } else { |
121 | drop_mmu_context(mm, cpu); | 144 | drop_mmu_context(mm, cpu); |
122 | } | 145 | } |
123 | local_irq_restore(flags); | 146 | EXIT_CRITICAL(flags); |
124 | } | 147 | } |
125 | } | 148 | } |
126 | 149 | ||
@@ -129,9 +152,9 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
129 | unsigned long flags; | 152 | unsigned long flags; |
130 | int size; | 153 | int size; |
131 | 154 | ||
155 | ENTER_CRITICAL(flags); | ||
132 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; | 156 | size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT; |
133 | size = (size + 1) >> 1; | 157 | size = (size + 1) >> 1; |
134 | local_irq_save(flags); | ||
135 | if (size <= current_cpu_data.tlbsize / 2) { | 158 | if (size <= current_cpu_data.tlbsize / 2) { |
136 | int pid = read_c0_entryhi(); | 159 | int pid = read_c0_entryhi(); |
137 | 160 | ||
@@ -162,7 +185,7 @@ void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | |||
162 | } else { | 185 | } else { |
163 | local_flush_tlb_all(); | 186 | local_flush_tlb_all(); |
164 | } | 187 | } |
165 | local_irq_restore(flags); | 188 | EXIT_CRITICAL(flags); |
166 | } | 189 | } |
167 | 190 | ||
168 | void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | 191 | void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) |
@@ -175,7 +198,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
175 | 198 | ||
176 | newpid = cpu_asid(cpu, vma->vm_mm); | 199 | newpid = cpu_asid(cpu, vma->vm_mm); |
177 | page &= (PAGE_MASK << 1); | 200 | page &= (PAGE_MASK << 1); |
178 | local_irq_save(flags); | 201 | ENTER_CRITICAL(flags); |
179 | oldpid = read_c0_entryhi(); | 202 | oldpid = read_c0_entryhi(); |
180 | write_c0_entryhi(page | newpid); | 203 | write_c0_entryhi(page | newpid); |
181 | mtc0_tlbw_hazard(); | 204 | mtc0_tlbw_hazard(); |
@@ -194,7 +217,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
194 | 217 | ||
195 | finish: | 218 | finish: |
196 | write_c0_entryhi(oldpid); | 219 | write_c0_entryhi(oldpid); |
197 | local_irq_restore(flags); | 220 | EXIT_CRITICAL(flags); |
198 | } | 221 | } |
199 | } | 222 | } |
200 | 223 | ||
@@ -207,7 +230,7 @@ void local_flush_tlb_one(unsigned long page) | |||
207 | unsigned long flags; | 230 | unsigned long flags; |
208 | int oldpid, idx; | 231 | int oldpid, idx; |
209 | 232 | ||
210 | local_irq_save(flags); | 233 | ENTER_CRITICAL(flags); |
211 | oldpid = read_c0_entryhi(); | 234 | oldpid = read_c0_entryhi(); |
212 | page &= (PAGE_MASK << 1); | 235 | page &= (PAGE_MASK << 1); |
213 | write_c0_entryhi(page); | 236 | write_c0_entryhi(page); |
@@ -226,7 +249,7 @@ void local_flush_tlb_one(unsigned long page) | |||
226 | } | 249 | } |
227 | write_c0_entryhi(oldpid); | 250 | write_c0_entryhi(oldpid); |
228 | 251 | ||
229 | local_irq_restore(flags); | 252 | EXIT_CRITICAL(flags); |
230 | } | 253 | } |
231 | 254 | ||
232 | /* | 255 | /* |
@@ -249,7 +272,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
249 | if (current->active_mm != vma->vm_mm) | 272 | if (current->active_mm != vma->vm_mm) |
250 | return; | 273 | return; |
251 | 274 | ||
252 | local_irq_save(flags); | 275 | ENTER_CRITICAL(flags); |
253 | 276 | ||
254 | pid = read_c0_entryhi() & ASID_MASK; | 277 | pid = read_c0_entryhi() & ASID_MASK; |
255 | address &= (PAGE_MASK << 1); | 278 | address &= (PAGE_MASK << 1); |
@@ -277,7 +300,7 @@ void __update_tlb(struct vm_area_struct * vma, unsigned long address, pte_t pte) | |||
277 | else | 300 | else |
278 | tlb_write_indexed(); | 301 | tlb_write_indexed(); |
279 | tlbw_use_hazard(); | 302 | tlbw_use_hazard(); |
280 | local_irq_restore(flags); | 303 | EXIT_CRITICAL(flags); |
281 | } | 304 | } |
282 | 305 | ||
283 | #if 0 | 306 | #if 0 |
@@ -291,7 +314,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, | |||
291 | pte_t *ptep; | 314 | pte_t *ptep; |
292 | int idx; | 315 | int idx; |
293 | 316 | ||
294 | local_irq_save(flags); | 317 | ENTER_CRITICAL(flags); |
295 | address &= (PAGE_MASK << 1); | 318 | address &= (PAGE_MASK << 1); |
296 | asid = read_c0_entryhi() & ASID_MASK; | 319 | asid = read_c0_entryhi() & ASID_MASK; |
297 | write_c0_entryhi(address | asid); | 320 | write_c0_entryhi(address | asid); |
@@ -310,7 +333,7 @@ static void r4k_update_mmu_cache_hwbug(struct vm_area_struct * vma, | |||
310 | else | 333 | else |
311 | tlb_write_indexed(); | 334 | tlb_write_indexed(); |
312 | tlbw_use_hazard(); | 335 | tlbw_use_hazard(); |
313 | local_irq_restore(flags); | 336 | EXIT_CRITICAL(flags); |
314 | } | 337 | } |
315 | #endif | 338 | #endif |
316 | 339 | ||
@@ -322,7 +345,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
322 | unsigned long old_pagemask; | 345 | unsigned long old_pagemask; |
323 | unsigned long old_ctx; | 346 | unsigned long old_ctx; |
324 | 347 | ||
325 | local_irq_save(flags); | 348 | ENTER_CRITICAL(flags); |
326 | /* Save old context and create impossible VPN2 value */ | 349 | /* Save old context and create impossible VPN2 value */ |
327 | old_ctx = read_c0_entryhi(); | 350 | old_ctx = read_c0_entryhi(); |
328 | old_pagemask = read_c0_pagemask(); | 351 | old_pagemask = read_c0_pagemask(); |
@@ -342,7 +365,7 @@ void __init add_wired_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
342 | BARRIER; | 365 | BARRIER; |
343 | write_c0_pagemask(old_pagemask); | 366 | write_c0_pagemask(old_pagemask); |
344 | local_flush_tlb_all(); | 367 | local_flush_tlb_all(); |
345 | local_irq_restore(flags); | 368 | EXIT_CRITICAL(flags); |
346 | } | 369 | } |
347 | 370 | ||
348 | /* | 371 | /* |
@@ -362,7 +385,7 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
362 | unsigned long old_pagemask; | 385 | unsigned long old_pagemask; |
363 | unsigned long old_ctx; | 386 | unsigned long old_ctx; |
364 | 387 | ||
365 | local_irq_save(flags); | 388 | ENTER_CRITICAL(flags); |
366 | /* Save old context and create impossible VPN2 value */ | 389 | /* Save old context and create impossible VPN2 value */ |
367 | old_ctx = read_c0_entryhi(); | 390 | old_ctx = read_c0_entryhi(); |
368 | old_pagemask = read_c0_pagemask(); | 391 | old_pagemask = read_c0_pagemask(); |
@@ -386,10 +409,11 @@ __init int add_temporary_entry(unsigned long entrylo0, unsigned long entrylo1, | |||
386 | write_c0_entryhi(old_ctx); | 409 | write_c0_entryhi(old_ctx); |
387 | write_c0_pagemask(old_pagemask); | 410 | write_c0_pagemask(old_pagemask); |
388 | out: | 411 | out: |
389 | local_irq_restore(flags); | 412 | EXIT_CRITICAL(flags); |
390 | return ret; | 413 | return ret; |
391 | } | 414 | } |
392 | 415 | ||
416 | extern void __init sanitize_tlb_entries(void); | ||
393 | static void __init probe_tlb(unsigned long config) | 417 | static void __init probe_tlb(unsigned long config) |
394 | { | 418 | { |
395 | struct cpuinfo_mips *c = ¤t_cpu_data; | 419 | struct cpuinfo_mips *c = ¤t_cpu_data; |
@@ -402,6 +426,14 @@ static void __init probe_tlb(unsigned long config) | |||
402 | */ | 426 | */ |
403 | if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) | 427 | if ((c->processor_id & 0xff0000) == PRID_COMP_LEGACY) |
404 | return; | 428 | return; |
429 | #ifdef CONFIG_MIPS_MT_SMTC | ||
430 | /* | ||
431 | * If TLB is shared in SMTC system, total size already | ||
432 | * has been calculated and written into cpu_data tlbsize | ||
433 | */ | ||
434 | if((smtc_status & SMTC_TLB_SHARED) == SMTC_TLB_SHARED) | ||
435 | return; | ||
436 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
405 | 437 | ||
406 | reg = read_c0_config1(); | 438 | reg = read_c0_config1(); |
407 | if (!((config >> 7) & 3)) | 439 | if (!((config >> 7) & 3)) |
@@ -410,6 +442,15 @@ static void __init probe_tlb(unsigned long config) | |||
410 | c->tlbsize = ((reg >> 25) & 0x3f) + 1; | 442 | c->tlbsize = ((reg >> 25) & 0x3f) + 1; |
411 | } | 443 | } |
412 | 444 | ||
445 | static int __initdata ntlb = 0; | ||
446 | static int __init set_ntlb(char *str) | ||
447 | { | ||
448 | get_option(&str, &ntlb); | ||
449 | return 1; | ||
450 | } | ||
451 | |||
452 | __setup("ntlb=", set_ntlb); | ||
453 | |||
413 | void __init tlb_init(void) | 454 | void __init tlb_init(void) |
414 | { | 455 | { |
415 | unsigned int config = read_c0_config(); | 456 | unsigned int config = read_c0_config(); |
@@ -432,5 +473,15 @@ void __init tlb_init(void) | |||
432 | 473 | ||
433 | /* Did I tell you that ARC SUCKS? */ | 474 | /* Did I tell you that ARC SUCKS? */ |
434 | 475 | ||
476 | if (ntlb) { | ||
477 | if (ntlb > 1 && ntlb <= current_cpu_data.tlbsize) { | ||
478 | int wired = current_cpu_data.tlbsize - ntlb; | ||
479 | write_c0_wired(wired); | ||
480 | write_c0_index(wired-1); | ||
481 | printk ("Restricting TLB to %d entries\n", ntlb); | ||
482 | } else | ||
483 | printk("Ignoring invalid argument ntlb=%d\n", ntlb); | ||
484 | } | ||
485 | |||
435 | build_tlb_refill_handler(); | 486 | build_tlb_refill_handler(); |
436 | } | 487 | } |
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c index 599b3c297186..053dbacac56b 100644 --- a/arch/mips/mm/tlbex.c +++ b/arch/mips/mm/tlbex.c | |||
@@ -7,6 +7,16 @@ | |||
7 | * | 7 | * |
8 | * Copyright (C) 2004,2005 by Thiemo Seufer | 8 | * Copyright (C) 2004,2005 by Thiemo Seufer |
9 | * Copyright (C) 2005 Maciej W. Rozycki | 9 | * Copyright (C) 2005 Maciej W. Rozycki |
10 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | ||
11 | * | ||
12 | * ... and the days got worse and worse and now you see | ||
13 | * I've gone completly out of my mind. | ||
14 | * | ||
15 | * They're coming to take me a away haha | ||
16 | * they're coming to take me a away hoho hihi haha | ||
17 | * to the funny farm where code is beautiful all the time ... | ||
18 | * | ||
19 | * (Condolences to Napoleon XIV) | ||
10 | */ | 20 | */ |
11 | 21 | ||
12 | #include <stdarg.h> | 22 | #include <stdarg.h> |
@@ -68,6 +78,7 @@ enum fields | |||
68 | BIMM = 0x040, | 78 | BIMM = 0x040, |
69 | JIMM = 0x080, | 79 | JIMM = 0x080, |
70 | FUNC = 0x100, | 80 | FUNC = 0x100, |
81 | SET = 0x200 | ||
71 | }; | 82 | }; |
72 | 83 | ||
73 | #define OP_MASK 0x2f | 84 | #define OP_MASK 0x2f |
@@ -86,6 +97,8 @@ enum fields | |||
86 | #define JIMM_SH 0 | 97 | #define JIMM_SH 0 |
87 | #define FUNC_MASK 0x2f | 98 | #define FUNC_MASK 0x2f |
88 | #define FUNC_SH 0 | 99 | #define FUNC_SH 0 |
100 | #define SET_MASK 0x7 | ||
101 | #define SET_SH 0 | ||
89 | 102 | ||
90 | enum opcode { | 103 | enum opcode { |
91 | insn_invalid, | 104 | insn_invalid, |
@@ -129,8 +142,8 @@ static __initdata struct insn insn_table[] = { | |||
129 | { insn_bne, M(bne_op,0,0,0,0,0), RS | RT | BIMM }, | 142 | { insn_bne, M(bne_op,0,0,0,0,0), RS | RT | BIMM }, |
130 | { insn_daddiu, M(daddiu_op,0,0,0,0,0), RS | RT | SIMM }, | 143 | { insn_daddiu, M(daddiu_op,0,0,0,0,0), RS | RT | SIMM }, |
131 | { insn_daddu, M(spec_op,0,0,0,0,daddu_op), RS | RT | RD }, | 144 | { insn_daddu, M(spec_op,0,0,0,0,daddu_op), RS | RT | RD }, |
132 | { insn_dmfc0, M(cop0_op,dmfc_op,0,0,0,0), RT | RD }, | 145 | { insn_dmfc0, M(cop0_op,dmfc_op,0,0,0,0), RT | RD | SET}, |
133 | { insn_dmtc0, M(cop0_op,dmtc_op,0,0,0,0), RT | RD }, | 146 | { insn_dmtc0, M(cop0_op,dmtc_op,0,0,0,0), RT | RD | SET}, |
134 | { insn_dsll, M(spec_op,0,0,0,0,dsll_op), RT | RD | RE }, | 147 | { insn_dsll, M(spec_op,0,0,0,0,dsll_op), RT | RD | RE }, |
135 | { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, | 148 | { insn_dsll32, M(spec_op,0,0,0,0,dsll32_op), RT | RD | RE }, |
136 | { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, | 149 | { insn_dsra, M(spec_op,0,0,0,0,dsra_op), RT | RD | RE }, |
@@ -145,8 +158,8 @@ static __initdata struct insn insn_table[] = { | |||
145 | { insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM }, | 158 | { insn_lld, M(lld_op,0,0,0,0,0), RS | RT | SIMM }, |
146 | { insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM }, | 159 | { insn_lui, M(lui_op,0,0,0,0,0), RT | SIMM }, |
147 | { insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM }, | 160 | { insn_lw, M(lw_op,0,0,0,0,0), RS | RT | SIMM }, |
148 | { insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD }, | 161 | { insn_mfc0, M(cop0_op,mfc_op,0,0,0,0), RT | RD | SET}, |
149 | { insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD }, | 162 | { insn_mtc0, M(cop0_op,mtc_op,0,0,0,0), RT | RD | SET}, |
150 | { insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM }, | 163 | { insn_ori, M(ori_op,0,0,0,0,0), RS | RT | UIMM }, |
151 | { insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 }, | 164 | { insn_rfe, M(cop0_op,cop_op,0,0,0,rfe_op), 0 }, |
152 | { insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM }, | 165 | { insn_sc, M(sc_op,0,0,0,0,0), RS | RT | SIMM }, |
@@ -242,6 +255,14 @@ static __init u32 build_func(u32 arg) | |||
242 | return arg & FUNC_MASK; | 255 | return arg & FUNC_MASK; |
243 | } | 256 | } |
244 | 257 | ||
258 | static __init u32 build_set(u32 arg) | ||
259 | { | ||
260 | if (arg & ~SET_MASK) | ||
261 | printk(KERN_WARNING "TLB synthesizer field overflow\n"); | ||
262 | |||
263 | return arg & SET_MASK; | ||
264 | } | ||
265 | |||
245 | /* | 266 | /* |
246 | * The order of opcode arguments is implicitly left to right, | 267 | * The order of opcode arguments is implicitly left to right, |
247 | * starting with RS and ending with FUNC or IMM. | 268 | * starting with RS and ending with FUNC or IMM. |
@@ -273,6 +294,7 @@ static void __init build_insn(u32 **buf, enum opcode opc, ...) | |||
273 | if (ip->fields & BIMM) op |= build_bimm(va_arg(ap, s32)); | 294 | if (ip->fields & BIMM) op |= build_bimm(va_arg(ap, s32)); |
274 | if (ip->fields & JIMM) op |= build_jimm(va_arg(ap, u32)); | 295 | if (ip->fields & JIMM) op |= build_jimm(va_arg(ap, u32)); |
275 | if (ip->fields & FUNC) op |= build_func(va_arg(ap, u32)); | 296 | if (ip->fields & FUNC) op |= build_func(va_arg(ap, u32)); |
297 | if (ip->fields & SET) op |= build_set(va_arg(ap, u32)); | ||
276 | va_end(ap); | 298 | va_end(ap); |
277 | 299 | ||
278 | **buf = op; | 300 | **buf = op; |
@@ -358,8 +380,8 @@ I_u1s2(_bgezl); | |||
358 | I_u1s2(_bltz); | 380 | I_u1s2(_bltz); |
359 | I_u1s2(_bltzl); | 381 | I_u1s2(_bltzl); |
360 | I_u1u2s3(_bne); | 382 | I_u1u2s3(_bne); |
361 | I_u1u2(_dmfc0); | 383 | I_u1u2u3(_dmfc0); |
362 | I_u1u2(_dmtc0); | 384 | I_u1u2u3(_dmtc0); |
363 | I_u2u1s3(_daddiu); | 385 | I_u2u1s3(_daddiu); |
364 | I_u3u1u2(_daddu); | 386 | I_u3u1u2(_daddu); |
365 | I_u2u1u3(_dsll); | 387 | I_u2u1u3(_dsll); |
@@ -376,8 +398,8 @@ I_u2s3u1(_ll); | |||
376 | I_u2s3u1(_lld); | 398 | I_u2s3u1(_lld); |
377 | I_u1s2(_lui); | 399 | I_u1s2(_lui); |
378 | I_u2s3u1(_lw); | 400 | I_u2s3u1(_lw); |
379 | I_u1u2(_mfc0); | 401 | I_u1u2u3(_mfc0); |
380 | I_u1u2(_mtc0); | 402 | I_u1u2u3(_mtc0); |
381 | I_u2u1u3(_ori); | 403 | I_u2u1u3(_ori); |
382 | I_0(_rfe); | 404 | I_0(_rfe); |
383 | I_u2s3u1(_sc); | 405 | I_u2s3u1(_sc); |
@@ -451,8 +473,8 @@ L_LA(_r3000_write_probe_fail) | |||
451 | # define i_SLL(buf, rs, rt, sh) i_dsll(buf, rs, rt, sh) | 473 | # define i_SLL(buf, rs, rt, sh) i_dsll(buf, rs, rt, sh) |
452 | # define i_SRA(buf, rs, rt, sh) i_dsra(buf, rs, rt, sh) | 474 | # define i_SRA(buf, rs, rt, sh) i_dsra(buf, rs, rt, sh) |
453 | # define i_SRL(buf, rs, rt, sh) i_dsrl(buf, rs, rt, sh) | 475 | # define i_SRL(buf, rs, rt, sh) i_dsrl(buf, rs, rt, sh) |
454 | # define i_MFC0(buf, rt, rd) i_dmfc0(buf, rt, rd) | 476 | # define i_MFC0(buf, rt, rd...) i_dmfc0(buf, rt, rd) |
455 | # define i_MTC0(buf, rt, rd) i_dmtc0(buf, rt, rd) | 477 | # define i_MTC0(buf, rt, rd...) i_dmtc0(buf, rt, rd) |
456 | # define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val) | 478 | # define i_ADDIU(buf, rs, rt, val) i_daddiu(buf, rs, rt, val) |
457 | # define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd) | 479 | # define i_ADDU(buf, rs, rt, rd) i_daddu(buf, rs, rt, rd) |
458 | # define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd) | 480 | # define i_SUBU(buf, rs, rt, rd) i_dsubu(buf, rs, rt, rd) |
@@ -464,8 +486,8 @@ L_LA(_r3000_write_probe_fail) | |||
464 | # define i_SLL(buf, rs, rt, sh) i_sll(buf, rs, rt, sh) | 486 | # define i_SLL(buf, rs, rt, sh) i_sll(buf, rs, rt, sh) |
465 | # define i_SRA(buf, rs, rt, sh) i_sra(buf, rs, rt, sh) | 487 | # define i_SRA(buf, rs, rt, sh) i_sra(buf, rs, rt, sh) |
466 | # define i_SRL(buf, rs, rt, sh) i_srl(buf, rs, rt, sh) | 488 | # define i_SRL(buf, rs, rt, sh) i_srl(buf, rs, rt, sh) |
467 | # define i_MFC0(buf, rt, rd) i_mfc0(buf, rt, rd) | 489 | # define i_MFC0(buf, rt, rd...) i_mfc0(buf, rt, rd) |
468 | # define i_MTC0(buf, rt, rd) i_mtc0(buf, rt, rd) | 490 | # define i_MTC0(buf, rt, rd...) i_mtc0(buf, rt, rd) |
469 | # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val) | 491 | # define i_ADDIU(buf, rs, rt, val) i_addiu(buf, rs, rt, val) |
470 | # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd) | 492 | # define i_ADDU(buf, rs, rt, rd) i_addu(buf, rs, rt, rd) |
471 | # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd) | 493 | # define i_SUBU(buf, rs, rt, rd) i_subu(buf, rs, rt, rd) |
@@ -670,14 +692,15 @@ static void __init il_bgezl(u32 **p, struct reloc **r, unsigned int reg, | |||
670 | #define K1 27 | 692 | #define K1 27 |
671 | 693 | ||
672 | /* Some CP0 registers */ | 694 | /* Some CP0 registers */ |
673 | #define C0_INDEX 0 | 695 | #define C0_INDEX 0, 0 |
674 | #define C0_ENTRYLO0 2 | 696 | #define C0_ENTRYLO0 2, 0 |
675 | #define C0_ENTRYLO1 3 | 697 | #define C0_TCBIND 2, 2 |
676 | #define C0_CONTEXT 4 | 698 | #define C0_ENTRYLO1 3, 0 |
677 | #define C0_BADVADDR 8 | 699 | #define C0_CONTEXT 4, 0 |
678 | #define C0_ENTRYHI 10 | 700 | #define C0_BADVADDR 8, 0 |
679 | #define C0_EPC 14 | 701 | #define C0_ENTRYHI 10, 0 |
680 | #define C0_XCONTEXT 20 | 702 | #define C0_EPC 14, 0 |
703 | #define C0_XCONTEXT 20, 0 | ||
681 | 704 | ||
682 | #ifdef CONFIG_64BIT | 705 | #ifdef CONFIG_64BIT |
683 | # define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_XCONTEXT) | 706 | # define GET_CONTEXT(buf, reg) i_MFC0(buf, reg, C0_XCONTEXT) |
@@ -742,7 +765,7 @@ static void __init build_r3000_tlb_refill_handler(void) | |||
742 | } | 765 | } |
743 | #endif | 766 | #endif |
744 | 767 | ||
745 | memcpy((void *)CAC_BASE, tlb_handler, 0x80); | 768 | memcpy((void *)ebase, tlb_handler, 0x80); |
746 | } | 769 | } |
747 | 770 | ||
748 | /* | 771 | /* |
@@ -951,12 +974,20 @@ build_get_pmde64(u32 **p, struct label **l, struct reloc **r, | |||
951 | /* No i_nop needed here, since the next insn doesn't touch TMP. */ | 974 | /* No i_nop needed here, since the next insn doesn't touch TMP. */ |
952 | 975 | ||
953 | #ifdef CONFIG_SMP | 976 | #ifdef CONFIG_SMP |
977 | # ifdef CONFIG_MIPS_MT_SMTC | ||
978 | /* | ||
979 | * SMTC uses TCBind value as "CPU" index | ||
980 | */ | ||
981 | i_mfc0(p, ptr, C0_TCBIND); | ||
982 | i_dsrl(p, ptr, ptr, 19); | ||
983 | # else | ||
954 | /* | 984 | /* |
955 | * 64 bit SMP running in XKPHYS has smp_processor_id() << 3 | 985 | * 64 bit SMP running in XKPHYS has smp_processor_id() << 3 |
956 | * stored in CONTEXT. | 986 | * stored in CONTEXT. |
957 | */ | 987 | */ |
958 | i_dmfc0(p, ptr, C0_CONTEXT); | 988 | i_dmfc0(p, ptr, C0_CONTEXT); |
959 | i_dsrl(p, ptr, ptr, 23); | 989 | i_dsrl(p, ptr, ptr, 23); |
990 | #endif | ||
960 | i_LA_mostly(p, tmp, pgdc); | 991 | i_LA_mostly(p, tmp, pgdc); |
961 | i_daddu(p, ptr, ptr, tmp); | 992 | i_daddu(p, ptr, ptr, tmp); |
962 | i_dmfc0(p, tmp, C0_BADVADDR); | 993 | i_dmfc0(p, tmp, C0_BADVADDR); |
@@ -1014,9 +1045,21 @@ build_get_pgde32(u32 **p, unsigned int tmp, unsigned int ptr) | |||
1014 | 1045 | ||
1015 | /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */ | 1046 | /* 32 bit SMP has smp_processor_id() stored in CONTEXT. */ |
1016 | #ifdef CONFIG_SMP | 1047 | #ifdef CONFIG_SMP |
1048 | #ifdef CONFIG_MIPS_MT_SMTC | ||
1049 | /* | ||
1050 | * SMTC uses TCBind value as "CPU" index | ||
1051 | */ | ||
1052 | i_mfc0(p, ptr, C0_TCBIND); | ||
1053 | i_LA_mostly(p, tmp, pgdc); | ||
1054 | i_srl(p, ptr, ptr, 19); | ||
1055 | #else | ||
1056 | /* | ||
1057 | * smp_processor_id() << 3 is stored in CONTEXT. | ||
1058 | */ | ||
1017 | i_mfc0(p, ptr, C0_CONTEXT); | 1059 | i_mfc0(p, ptr, C0_CONTEXT); |
1018 | i_LA_mostly(p, tmp, pgdc); | 1060 | i_LA_mostly(p, tmp, pgdc); |
1019 | i_srl(p, ptr, ptr, 23); | 1061 | i_srl(p, ptr, ptr, 23); |
1062 | #endif | ||
1020 | i_addu(p, ptr, tmp, ptr); | 1063 | i_addu(p, ptr, tmp, ptr); |
1021 | #else | 1064 | #else |
1022 | i_LA_mostly(p, ptr, pgdc); | 1065 | i_LA_mostly(p, ptr, pgdc); |
@@ -1247,7 +1290,7 @@ static void __init build_r4000_tlb_refill_handler(void) | |||
1247 | } | 1290 | } |
1248 | #endif | 1291 | #endif |
1249 | 1292 | ||
1250 | memcpy((void *)CAC_BASE, final_handler, 0x100); | 1293 | memcpy((void *)ebase, final_handler, 0x100); |
1251 | } | 1294 | } |
1252 | 1295 | ||
1253 | /* | 1296 | /* |
diff --git a/arch/mips/momentum/jaguar_atx/Makefile b/arch/mips/momentum/jaguar_atx/Makefile index 20bbd3ea44a8..67372f3f9654 100644 --- a/arch/mips/momentum/jaguar_atx/Makefile +++ b/arch/mips/momentum/jaguar_atx/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += int-handler.o irq.o prom.o reset.o setup.o | 9 | obj-y += irq.o prom.o reset.o setup.o |
10 | 10 | ||
11 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o | 11 | obj-$(CONFIG_SERIAL_8250_CONSOLE) += ja-console.o |
12 | obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o | 12 | obj-$(CONFIG_REMOTE_DEBUG) += dbg_io.o |
diff --git a/arch/mips/momentum/jaguar_atx/int-handler.S b/arch/mips/momentum/jaguar_atx/int-handler.S deleted file mode 100644 index 55bc789733f2..000000000000 --- a/arch/mips/momentum/jaguar_atx/int-handler.S +++ /dev/null | |||
@@ -1,128 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2002 Momentum Computer Inc. | ||
3 | * Author: Matthew Dharm <mdharm@momenco.com> | ||
4 | * | ||
5 | * Based on work: | ||
6 | * Copyright 2001 MontaVista Software Inc. | ||
7 | * Author: jsun@mvista.com or jsun@junsun.net | ||
8 | * | ||
9 | * First-level interrupt dispatcher for Jaguar-ATX board. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify it | ||
12 | * under the terms of the GNU General Public License as published by the | ||
13 | * Free Software Foundation; either version 2 of the License, or (at your | ||
14 | * option) any later version. | ||
15 | */ | ||
16 | #include <asm/asm.h> | ||
17 | #include <asm/mipsregs.h> | ||
18 | #include <asm/addrspace.h> | ||
19 | #include <asm/regdef.h> | ||
20 | #include <asm/stackframe.h> | ||
21 | |||
22 | /* | ||
23 | * First level interrupt dispatcher for Ocelot-CS board | ||
24 | */ | ||
25 | .align 5 | ||
26 | NESTED(jaguar_handle_int, PT_SIZE, sp) | ||
27 | SAVE_ALL | ||
28 | CLI | ||
29 | .set at | ||
30 | mfc0 t0, CP0_CAUSE | ||
31 | mfc0 t2, CP0_STATUS | ||
32 | |||
33 | and t0, t2 | ||
34 | |||
35 | andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ | ||
36 | bnez t1, ll_sw0_irq | ||
37 | andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ | ||
38 | bnez t1, ll_sw1_irq | ||
39 | andi t1, t0, STATUSF_IP2 /* int0 hardware line */ | ||
40 | bnez t1, ll_pcixa_irq | ||
41 | andi t1, t0, STATUSF_IP3 /* int1 hardware line */ | ||
42 | bnez t1, ll_pcixb_irq | ||
43 | andi t1, t0, STATUSF_IP4 /* int2 hardware line */ | ||
44 | bnez t1, ll_pcia_irq | ||
45 | andi t1, t0, STATUSF_IP5 /* int3 hardware line */ | ||
46 | bnez t1, ll_pcib_irq | ||
47 | andi t1, t0, STATUSF_IP6 /* int4 hardware line */ | ||
48 | bnez t1, ll_uart_irq | ||
49 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
50 | bnez t1, ll_cputimer_irq | ||
51 | |||
52 | nop | ||
53 | nop | ||
54 | |||
55 | /* now look at extended interrupts */ | ||
56 | mfc0 t0, CP0_CAUSE | ||
57 | cfc0 t1, CP0_S1_INTCONTROL | ||
58 | |||
59 | /* shift the mask 8 bits left to line up the bits */ | ||
60 | sll t2, t1, 8 | ||
61 | |||
62 | and t0, t2 | ||
63 | srl t0, t0, 16 | ||
64 | |||
65 | andi t1, t0, STATUSF_IP8 /* int6 hardware line */ | ||
66 | bnez t1, ll_mv64340_decode_irq | ||
67 | |||
68 | nop | ||
69 | nop | ||
70 | |||
71 | .set reorder | ||
72 | |||
73 | /* wrong alarm or masked ... */ | ||
74 | j spurious_interrupt | ||
75 | nop | ||
76 | END(jaguar_handle_int) | ||
77 | |||
78 | .align 5 | ||
79 | ll_sw0_irq: | ||
80 | li a0, 0 | ||
81 | move a1, sp | ||
82 | jal do_IRQ | ||
83 | j ret_from_irq | ||
84 | ll_sw1_irq: | ||
85 | li a0, 1 | ||
86 | move a1, sp | ||
87 | jal do_IRQ | ||
88 | j ret_from_irq | ||
89 | ll_pcixa_irq: | ||
90 | li a0, 2 | ||
91 | move a1, sp | ||
92 | jal do_IRQ | ||
93 | j ret_from_irq | ||
94 | |||
95 | ll_pcixb_irq: | ||
96 | li a0, 3 | ||
97 | move a1, sp | ||
98 | jal do_IRQ | ||
99 | j ret_from_irq | ||
100 | |||
101 | ll_pcia_irq: | ||
102 | li a0, 4 | ||
103 | move a1, sp | ||
104 | jal do_IRQ | ||
105 | j ret_from_irq | ||
106 | |||
107 | ll_pcib_irq: | ||
108 | li a0, 5 | ||
109 | move a1, sp | ||
110 | jal do_IRQ | ||
111 | j ret_from_irq | ||
112 | |||
113 | ll_uart_irq: | ||
114 | li a0, 6 | ||
115 | move a1, sp | ||
116 | jal do_IRQ | ||
117 | j ret_from_irq | ||
118 | |||
119 | ll_cputimer_irq: | ||
120 | li a0, 7 | ||
121 | move a1, sp | ||
122 | jal ll_timer_interrupt | ||
123 | j ret_from_irq | ||
124 | |||
125 | ll_mv64340_decode_irq: | ||
126 | move a0, sp | ||
127 | jal ll_mv64340_irq | ||
128 | j ret_from_irq | ||
diff --git a/arch/mips/momentum/jaguar_atx/irq.c b/arch/mips/momentum/jaguar_atx/irq.c index 15588f91ace2..ec4032b38f19 100644 --- a/arch/mips/momentum/jaguar_atx/irq.c +++ b/arch/mips/momentum/jaguar_atx/irq.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * Copyright 2001 MontaVista Software Inc. | 10 | * Copyright 2001 MontaVista Software Inc. |
11 | * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | 11 | * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net |
12 | * | 12 | * |
13 | * Copyright (C) 2000, 2001 Ralf Baechle (ralf@gnu.org) | 13 | * Copyright (C) 2000, 01, 06 Ralf Baechle (ralf@linux-mips.org) |
14 | * | 14 | * |
15 | * This program is free software; you can redistribute it and/or modify it | 15 | * This program is free software; you can redistribute it and/or modify it |
16 | * under the terms of the GNU General Public License as published by the | 16 | * under the terms of the GNU General Public License as published by the |
@@ -38,8 +38,37 @@ | |||
38 | #include <linux/types.h> | 38 | #include <linux/types.h> |
39 | #include <asm/irq_cpu.h> | 39 | #include <asm/irq_cpu.h> |
40 | #include <asm/mipsregs.h> | 40 | #include <asm/mipsregs.h> |
41 | #include <asm/time.h> | ||
41 | 42 | ||
42 | extern asmlinkage void jaguar_handle_int(void); | 43 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
44 | { | ||
45 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
46 | |||
47 | if (pending & STATUSF_IP0) | ||
48 | do_IRQ(0, regs); | ||
49 | else if (pending & STATUSF_IP1) | ||
50 | do_IRQ(1, regs); | ||
51 | else if (pending & STATUSF_IP2) | ||
52 | do_IRQ(2, regs); | ||
53 | else if (pending & STATUSF_IP3) | ||
54 | do_IRQ(3, regs); | ||
55 | else if (pending & STATUSF_IP4) | ||
56 | do_IRQ(4, regs); | ||
57 | else if (pending & STATUSF_IP5) | ||
58 | do_IRQ(5, regs); | ||
59 | else if (pending & STATUSF_IP6) | ||
60 | do_IRQ(6, regs); | ||
61 | else if (pending & STATUSF_IP7) | ||
62 | ll_timer_interrupt(7, regs); | ||
63 | else { | ||
64 | /* | ||
65 | * Now look at the extended interrupts | ||
66 | */ | ||
67 | pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; | ||
68 | if (pending & STATUSF_IP8) | ||
69 | ll_mv64340_irq(regs); | ||
70 | } | ||
71 | } | ||
43 | 72 | ||
44 | static struct irqaction cascade_mv64340 = { | 73 | static struct irqaction cascade_mv64340 = { |
45 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL | 74 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL |
@@ -53,8 +82,6 @@ void __init arch_init_irq(void) | |||
53 | */ | 82 | */ |
54 | clear_c0_status(ST0_IM); | 83 | clear_c0_status(ST0_IM); |
55 | 84 | ||
56 | /* Sets the first-level interrupt dispatcher. */ | ||
57 | set_except_vector(0, jaguar_handle_int); | ||
58 | mips_cpu_irq_init(0); | 85 | mips_cpu_irq_init(0); |
59 | rm7k_cpu_irq_init(8); | 86 | rm7k_cpu_irq_init(8); |
60 | 87 | ||
diff --git a/arch/mips/momentum/jaguar_atx/setup.c b/arch/mips/momentum/jaguar_atx/setup.c index 91d9637143d7..1379c76845dc 100644 --- a/arch/mips/momentum/jaguar_atx/setup.c +++ b/arch/mips/momentum/jaguar_atx/setup.c | |||
@@ -381,24 +381,24 @@ void __init plat_setup(void) | |||
381 | * shut down ethernet ports, just to be sure our memory doesn't get | 381 | * shut down ethernet ports, just to be sure our memory doesn't get |
382 | * corrupted by random ethernet traffic. | 382 | * corrupted by random ethernet traffic. |
383 | */ | 383 | */ |
384 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); | 384 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); |
385 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); | 385 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); |
386 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8); | 386 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(2), 0xff << 8); |
387 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); | 387 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); |
388 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); | 388 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); |
389 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8); | 389 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(2), 0xff << 8); |
390 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); | 390 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); |
391 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); | 391 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); |
392 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff); | 392 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(2)) & 0xff); |
393 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); | 393 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); |
394 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); | 394 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); |
395 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff); | 395 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(2)) & 0xff); |
396 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), | 396 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0), |
397 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); | 397 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); |
398 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), | 398 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1), |
399 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); | 399 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); |
400 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2), | 400 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(2), |
401 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1); | 401 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(2)) & ~1); |
402 | 402 | ||
403 | /* Turn off the Bit-Error LED */ | 403 | /* Turn off the Bit-Error LED */ |
404 | JAGUAR_FPGA_WRITE(0x80, CLR); | 404 | JAGUAR_FPGA_WRITE(0x80, CLR); |
diff --git a/arch/mips/momentum/ocelot_3/Makefile b/arch/mips/momentum/ocelot_3/Makefile index aab8fd89f830..8bcea64dd27b 100644 --- a/arch/mips/momentum/ocelot_3/Makefile +++ b/arch/mips/momentum/ocelot_3/Makefile | |||
@@ -5,4 +5,4 @@ | |||
5 | # removes any old dependencies. DON'T put your own dependencies here | 5 | # removes any old dependencies. DON'T put your own dependencies here |
6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
7 | # | 7 | # |
8 | obj-y += int-handler.o irq.o prom.o reset.o setup.o | 8 | obj-y += irq.o prom.o reset.o setup.o |
diff --git a/arch/mips/momentum/ocelot_3/int-handler.S b/arch/mips/momentum/ocelot_3/int-handler.S deleted file mode 100644 index 4522f09ed769..000000000000 --- a/arch/mips/momentum/ocelot_3/int-handler.S +++ /dev/null | |||
@@ -1,137 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2002 Momentum Computer Inc. | ||
3 | * Author: Matthew Dharm <mdharm@momenco.com> | ||
4 | * | ||
5 | * Copyright 2001 MontaVista Software Inc. | ||
6 | * Author: jsun@mvista.com or jsun@junsun.net | ||
7 | * | ||
8 | * Copyright 2004 PMC-Sierra | ||
9 | * Author: Manish Lachwani (lachwani@pmc-sierra.com) | ||
10 | * | ||
11 | * Copyright (C) 2004 MontaVista Software Inc. | ||
12 | * Author: Manish Lachwani, mlachwani@mvista.com | ||
13 | * | ||
14 | * First-level interrupt dispatcher for Ocelot-3 board. | ||
15 | * | ||
16 | * This program is free software; you can redistribute it and/or modify it | ||
17 | * under the terms of the GNU General Public License as published by the | ||
18 | * Free Software Foundation; either version 2 of the License, or (at your | ||
19 | * option) any later version. | ||
20 | */ | ||
21 | #include <asm/asm.h> | ||
22 | #include <asm/mipsregs.h> | ||
23 | #include <asm/addrspace.h> | ||
24 | #include <asm/regdef.h> | ||
25 | #include <asm/stackframe.h> | ||
26 | |||
27 | /* | ||
28 | * First level interrupt dispatcher for Ocelot-3 board | ||
29 | */ | ||
30 | .align 5 | ||
31 | NESTED(ocelot3_handle_int, PT_SIZE, sp) | ||
32 | SAVE_ALL | ||
33 | CLI | ||
34 | .set at | ||
35 | |||
36 | mfc0 t0, CP0_CAUSE | ||
37 | mfc0 t2, CP0_STATUS | ||
38 | |||
39 | and t0, t2 | ||
40 | |||
41 | andi t1, t0, STATUSF_IP0 /* sw0 software interrupt (IRQ0) */ | ||
42 | bnez t1, ll_sw0_irq | ||
43 | |||
44 | andi t1, t0, STATUSF_IP1 /* sw1 software interrupt (IRQ1) */ | ||
45 | bnez t1, ll_sw1_irq | ||
46 | |||
47 | andi t1, t0, STATUSF_IP2 /* int0 hardware line (IRQ2) */ | ||
48 | bnez t1, ll_pci0slot1_irq | ||
49 | |||
50 | andi t1, t0, STATUSF_IP3 /* int1 hardware line (IRQ3) */ | ||
51 | bnez t1, ll_pci0slot2_irq | ||
52 | |||
53 | andi t1, t0, STATUSF_IP4 /* int2 hardware line (IRQ4) */ | ||
54 | bnez t1, ll_pci1slot1_irq | ||
55 | |||
56 | andi t1, t0, STATUSF_IP5 /* int3 hardware line (IRQ5) */ | ||
57 | bnez t1, ll_pci1slot2_irq | ||
58 | |||
59 | andi t1, t0, STATUSF_IP6 /* int4 hardware line (IRQ6) */ | ||
60 | bnez t1, ll_uart_irq | ||
61 | |||
62 | andi t1, t0, STATUSF_IP7 /* cpu timer (IRQ7) */ | ||
63 | bnez t1, ll_cputimer_irq | ||
64 | |||
65 | /* now look at extended interrupts */ | ||
66 | mfc0 t0, CP0_CAUSE | ||
67 | cfc0 t1, CP0_S1_INTCONTROL | ||
68 | |||
69 | /* shift the mask 8 bits left to line up the bits */ | ||
70 | sll t2, t1, 8 | ||
71 | |||
72 | and t0, t2 | ||
73 | srl t0, t0, 16 | ||
74 | |||
75 | andi t1, t0, STATUSF_IP8 /* int6 hardware line (IRQ9) */ | ||
76 | bnez t1, ll_mv64340_decode_irq | ||
77 | |||
78 | .set reorder | ||
79 | |||
80 | /* wrong alarm or masked ... */ | ||
81 | j spurious_interrupt | ||
82 | nop | ||
83 | END(ocelot3_handle_int) | ||
84 | |||
85 | .align 5 | ||
86 | ll_sw0_irq: | ||
87 | li a0, 0 /* IRQ 1 */ | ||
88 | move a1, sp | ||
89 | jal do_IRQ | ||
90 | j ret_from_irq | ||
91 | ll_sw1_irq: | ||
92 | li a0, 1 /* IRQ 2 */ | ||
93 | move a1, sp | ||
94 | jal do_IRQ | ||
95 | j ret_from_irq | ||
96 | |||
97 | ll_pci0slot1_irq: | ||
98 | li a0, 2 /* IRQ 3 */ | ||
99 | move a1, sp | ||
100 | jal do_IRQ | ||
101 | j ret_from_irq | ||
102 | |||
103 | ll_pci0slot2_irq: | ||
104 | li a0, 3 /* IRQ 4 */ | ||
105 | move a1, sp | ||
106 | jal do_IRQ | ||
107 | j ret_from_irq | ||
108 | |||
109 | ll_pci1slot1_irq: | ||
110 | li a0, 4 /* IRQ 5 */ | ||
111 | move a1, sp | ||
112 | jal do_IRQ | ||
113 | j ret_from_irq | ||
114 | |||
115 | ll_pci1slot2_irq: | ||
116 | li a0, 5 /* IRQ 6 */ | ||
117 | move a1, sp | ||
118 | jal do_IRQ | ||
119 | j ret_from_irq | ||
120 | |||
121 | ll_uart_irq: | ||
122 | li a0, 6 /* IRQ 7 */ | ||
123 | move a1, sp | ||
124 | jal do_IRQ | ||
125 | j ret_from_irq | ||
126 | |||
127 | ll_cputimer_irq: | ||
128 | li a0, 7 /* IRQ 8 */ | ||
129 | move a1, sp | ||
130 | jal do_IRQ | ||
131 | j ret_from_irq | ||
132 | |||
133 | ll_mv64340_decode_irq: | ||
134 | move a0, sp | ||
135 | jal ll_mv64340_irq | ||
136 | j ret_from_irq | ||
137 | |||
diff --git a/arch/mips/momentum/ocelot_3/irq.c b/arch/mips/momentum/ocelot_3/irq.c index 42464dbd4ad2..87c63c340ae3 100644 --- a/arch/mips/momentum/ocelot_3/irq.c +++ b/arch/mips/momentum/ocelot_3/irq.c | |||
@@ -53,8 +53,6 @@ | |||
53 | #include <asm/mipsregs.h> | 53 | #include <asm/mipsregs.h> |
54 | #include <asm/system.h> | 54 | #include <asm/system.h> |
55 | 55 | ||
56 | extern asmlinkage void ocelot3_handle_int(void); | ||
57 | |||
58 | static struct irqaction cascade_mv64340 = { | 56 | static struct irqaction cascade_mv64340 = { |
59 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL | 57 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "MV64340-Cascade", NULL, NULL |
60 | }; | 58 | }; |
@@ -67,9 +65,6 @@ void __init arch_init_irq(void) | |||
67 | */ | 65 | */ |
68 | clear_c0_status(ST0_IM | ST0_BEV); | 66 | clear_c0_status(ST0_IM | ST0_BEV); |
69 | 67 | ||
70 | /* Sets the first-level interrupt dispatcher. */ | ||
71 | set_except_vector(0, ocelot3_handle_int); | ||
72 | mips_cpu_irq_init(0); | ||
73 | rm7k_cpu_irq_init(8); | 68 | rm7k_cpu_irq_init(8); |
74 | 69 | ||
75 | /* set up the cascading interrupts */ | 70 | /* set up the cascading interrupts */ |
@@ -79,3 +74,36 @@ void __init arch_init_irq(void) | |||
79 | set_c0_status(ST0_IM); /* IE in the status register */ | 74 | set_c0_status(ST0_IM); /* IE in the status register */ |
80 | 75 | ||
81 | } | 76 | } |
77 | |||
78 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
79 | { | ||
80 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
81 | |||
82 | if (pending & STATUSF_IP0) | ||
83 | do_IRQ(0, regs); | ||
84 | else if (pending & STATUSF_IP1) | ||
85 | do_IRQ(1, regs); | ||
86 | else if (pending & STATUSF_IP2) | ||
87 | do_IRQ(2, regs); | ||
88 | else if (pending & STATUSF_IP3) | ||
89 | do_IRQ(3, regs); | ||
90 | else if (pending & STATUSF_IP4) | ||
91 | do_IRQ(4, regs); | ||
92 | else if (pending & STATUSF_IP5) | ||
93 | do_IRQ(5, regs); | ||
94 | else if (pending & STATUSF_IP6) | ||
95 | do_IRQ(6, regs); | ||
96 | else if (pending & STATUSF_IP7) | ||
97 | do_IRQ(7, regs); | ||
98 | else { | ||
99 | /* | ||
100 | * Now look at the extended interrupts | ||
101 | */ | ||
102 | pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; | ||
103 | |||
104 | if (pending & STATUSF_IP8) | ||
105 | ll_mv64340_irq(regs); | ||
106 | else | ||
107 | spurious_interrupt(regs); | ||
108 | } | ||
109 | } | ||
diff --git a/arch/mips/momentum/ocelot_3/setup.c b/arch/mips/momentum/ocelot_3/setup.c index 370e75d0e75c..c69195234309 100644 --- a/arch/mips/momentum/ocelot_3/setup.c +++ b/arch/mips/momentum/ocelot_3/setup.c | |||
@@ -329,22 +329,22 @@ void __init plat_setup(void) | |||
329 | /* shut down ethernet ports, just to be sure our memory doesn't get | 329 | /* shut down ethernet ports, just to be sure our memory doesn't get |
330 | * corrupted by random ethernet traffic. | 330 | * corrupted by random ethernet traffic. |
331 | */ | 331 | */ |
332 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); | 332 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0), 0xff << 8); |
333 | MV_WRITE(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); | 333 | MV_WRITE(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1), 0xff << 8); |
334 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); | 334 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0), 0xff << 8); |
335 | MV_WRITE(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); | 335 | MV_WRITE(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1), 0xff << 8); |
336 | do {} | 336 | do {} |
337 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); | 337 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(0)) & 0xff); |
338 | do {} | 338 | do {} |
339 | while (MV_READ(MV64340_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); | 339 | while (MV_READ(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(1)) & 0xff); |
340 | do {} | 340 | do {} |
341 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); | 341 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(0)) & 0xff); |
342 | do {} | 342 | do {} |
343 | while (MV_READ(MV64340_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); | 343 | while (MV_READ(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(1)) & 0xff); |
344 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0), | 344 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0), |
345 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); | 345 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(0)) & ~1); |
346 | MV_WRITE(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1), | 346 | MV_WRITE(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1), |
347 | MV_READ(MV64340_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); | 347 | MV_READ(MV643XX_ETH_PORT_SERIAL_CONTROL_REG(1)) & ~1); |
348 | 348 | ||
349 | /* Turn off the Bit-Error LED */ | 349 | /* Turn off the Bit-Error LED */ |
350 | OCELOT_FPGA_WRITE(0x80, CLR); | 350 | OCELOT_FPGA_WRITE(0x80, CLR); |
diff --git a/arch/mips/momentum/ocelot_c/Makefile b/arch/mips/momentum/ocelot_c/Makefile index 91240777f978..94802b4db472 100644 --- a/arch/mips/momentum/ocelot_c/Makefile +++ b/arch/mips/momentum/ocelot_c/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for Momentum Computer's Ocelot-C and -CS boards. | 2 | # Makefile for Momentum Computer's Ocelot-C and -CS boards. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += cpci-irq.o int-handler.o irq.o prom.o reset.o \ | 5 | obj-y += cpci-irq.o irq.o prom.o reset.o \ |
6 | setup.o uart-irq.o | 6 | setup.o uart-irq.o |
7 | 7 | ||
8 | obj-$(CONFIG_KGDB) += dbg_io.o | 8 | obj-$(CONFIG_KGDB) += dbg_io.o |
diff --git a/arch/mips/momentum/ocelot_c/int-handler.S b/arch/mips/momentum/ocelot_c/int-handler.S deleted file mode 100644 index 52349d9bf1be..000000000000 --- a/arch/mips/momentum/ocelot_c/int-handler.S +++ /dev/null | |||
@@ -1,102 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2002 Momentum Computer Inc. | ||
3 | * Author: Matthew Dharm <mdharm@momenco.com> | ||
4 | * | ||
5 | * Copyright 2001 MontaVista Software Inc. | ||
6 | * Author: jsun@mvista.com or jsun@junsun.net | ||
7 | * | ||
8 | * First-level interrupt dispatcher for Ocelot-CS board. | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | */ | ||
15 | #include <asm/asm.h> | ||
16 | #include <asm/mipsregs.h> | ||
17 | #include <asm/addrspace.h> | ||
18 | #include <asm/regdef.h> | ||
19 | #include <asm/stackframe.h> | ||
20 | #include "ocelot_c_fpga.h" | ||
21 | |||
22 | /* | ||
23 | * First level interrupt dispatcher for Ocelot-CS board | ||
24 | */ | ||
25 | .align 5 | ||
26 | NESTED(ocelot_handle_int, PT_SIZE, sp) | ||
27 | SAVE_ALL | ||
28 | CLI | ||
29 | .set at | ||
30 | mfc0 t0, CP0_CAUSE | ||
31 | mfc0 t2, CP0_STATUS | ||
32 | |||
33 | and t0, t2 | ||
34 | |||
35 | andi t1, t0, STATUSF_IP0 /* sw0 software interrupt */ | ||
36 | bnez t1, ll_sw0_irq | ||
37 | andi t1, t0, STATUSF_IP1 /* sw1 software interrupt */ | ||
38 | bnez t1, ll_sw1_irq | ||
39 | andi t1, t0, STATUSF_IP2 /* int0 hardware line */ | ||
40 | bnez t1, ll_scsi_irq | ||
41 | andi t1, t0, STATUSF_IP3 /* int1 hardware line */ | ||
42 | bnez t1, ll_uart_decode_irq | ||
43 | andi t1, t0, STATUSF_IP4 /* int2 hardware line */ | ||
44 | bnez t1, ll_pmc_irq | ||
45 | andi t1, t0, STATUSF_IP5 /* int3 hardware line */ | ||
46 | bnez t1, ll_cpci_decode_irq | ||
47 | andi t1, t0, STATUSF_IP6 /* int4 hardware line */ | ||
48 | bnez t1, ll_mv64340_decode_irq | ||
49 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
50 | bnez t1, ll_cputimer_irq | ||
51 | |||
52 | .set reorder | ||
53 | |||
54 | /* wrong alarm or masked ... */ | ||
55 | j spurious_interrupt | ||
56 | nop | ||
57 | END(ocelot_handle_int) | ||
58 | |||
59 | .align 5 | ||
60 | ll_sw0_irq: | ||
61 | li a0, 0 | ||
62 | move a1, sp | ||
63 | jal do_IRQ | ||
64 | j ret_from_irq | ||
65 | ll_sw1_irq: | ||
66 | li a0, 1 | ||
67 | move a1, sp | ||
68 | jal do_IRQ | ||
69 | j ret_from_irq | ||
70 | ll_scsi_irq: | ||
71 | li a0, 2 | ||
72 | move a1, sp | ||
73 | jal do_IRQ | ||
74 | j ret_from_irq | ||
75 | |||
76 | ll_uart_decode_irq: | ||
77 | move a0, sp | ||
78 | jal ll_uart_irq | ||
79 | j ret_from_irq | ||
80 | |||
81 | ll_pmc_irq: | ||
82 | li a0, 4 | ||
83 | move a1, sp | ||
84 | jal do_IRQ | ||
85 | j ret_from_irq | ||
86 | |||
87 | ll_cpci_decode_irq: | ||
88 | move a0, sp | ||
89 | jal ll_cpci_irq | ||
90 | j ret_from_irq | ||
91 | |||
92 | ll_mv64340_decode_irq: | ||
93 | move a0, sp | ||
94 | jal ll_mv64340_irq | ||
95 | j ret_from_irq | ||
96 | |||
97 | ll_cputimer_irq: | ||
98 | li a0, 7 | ||
99 | move a1, sp | ||
100 | jal do_IRQ | ||
101 | j ret_from_irq | ||
102 | |||
diff --git a/arch/mips/momentum/ocelot_c/irq.c b/arch/mips/momentum/ocelot_c/irq.c index a5764bc20e36..86f61ce59e53 100644 --- a/arch/mips/momentum/ocelot_c/irq.c +++ b/arch/mips/momentum/ocelot_c/irq.c | |||
@@ -48,7 +48,6 @@ | |||
48 | #include <asm/mipsregs.h> | 48 | #include <asm/mipsregs.h> |
49 | #include <asm/system.h> | 49 | #include <asm/system.h> |
50 | 50 | ||
51 | extern asmlinkage void ocelot_handle_int(void); | ||
52 | extern void uart_irq_init(void); | 51 | extern void uart_irq_init(void); |
53 | extern void cpci_irq_init(void); | 52 | extern void cpci_irq_init(void); |
54 | 53 | ||
@@ -60,6 +59,33 @@ static struct irqaction cascade_mv64340 = { | |||
60 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL | 59 | no_action, SA_INTERRUPT, CPU_MASK_NONE, "cascade via MV64340", NULL, NULL |
61 | }; | 60 | }; |
62 | 61 | ||
62 | extern void ll_uart_irq(struct pt_regs *regs); | ||
63 | extern void ll_cpci_irq(struct pt_regs *regs); | ||
64 | |||
65 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
66 | { | ||
67 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
68 | |||
69 | if (pending & STATUSF_IP0) | ||
70 | do_IRQ(0, regs); | ||
71 | else if (pending & STATUSF_IP1) | ||
72 | do_IRQ(1, regs); | ||
73 | else if (pending & STATUSF_IP2) | ||
74 | do_IRQ(2, regs); | ||
75 | else if (pending & STATUSF_IP3) | ||
76 | ll_uart_irq(regs); | ||
77 | else if (pending & STATUSF_IP4) | ||
78 | do_IRQ(4, regs); | ||
79 | else if (pending & STATUSF_IP5) | ||
80 | ll_cpci_irq(regs); | ||
81 | else if (pending & STATUSF_IP6) | ||
82 | ll_mv64340_irq(regs); | ||
83 | else if (pending & STATUSF_IP7) | ||
84 | do_IRQ(7, regs); | ||
85 | else | ||
86 | spurious_interrupt(regs); | ||
87 | } | ||
88 | |||
63 | void __init arch_init_irq(void) | 89 | void __init arch_init_irq(void) |
64 | { | 90 | { |
65 | /* | 91 | /* |
@@ -68,8 +94,6 @@ void __init arch_init_irq(void) | |||
68 | */ | 94 | */ |
69 | clear_c0_status(ST0_IM); | 95 | clear_c0_status(ST0_IM); |
70 | 96 | ||
71 | /* Sets the first-level interrupt dispatcher. */ | ||
72 | set_except_vector(0, ocelot_handle_int); | ||
73 | mips_cpu_irq_init(0); | 97 | mips_cpu_irq_init(0); |
74 | 98 | ||
75 | /* set up the cascading interrupts */ | 99 | /* set up the cascading interrupts */ |
diff --git a/arch/mips/momentum/ocelot_g/Makefile b/arch/mips/momentum/ocelot_g/Makefile index e5f1cb086973..adb5665d40a9 100644 --- a/arch/mips/momentum/ocelot_g/Makefile +++ b/arch/mips/momentum/ocelot_g/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for Momentum Computer's Ocelot-G board. | 2 | # Makefile for Momentum Computer's Ocelot-G board. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += int-handler.o irq.o gt-irq.o prom.o reset.o setup.o | 5 | obj-y += irq.o gt-irq.o prom.o reset.o setup.o |
6 | obj-$(CONFIG_KGDB) += dbg_io.o | 6 | obj-$(CONFIG_KGDB) += dbg_io.o |
7 | 7 | ||
8 | EXTRA_AFLAGS := $(CFLAGS) | 8 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/momentum/ocelot_g/int-handler.S b/arch/mips/momentum/ocelot_g/int-handler.S deleted file mode 100644 index 772e8f713176..000000000000 --- a/arch/mips/momentum/ocelot_g/int-handler.S +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2001 MontaVista Software Inc. | ||
3 | * Author: jsun@mvista.com or jsun@junsun.net | ||
4 | * | ||
5 | * First-level interrupt dispatcher for ocelot board. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | #include <asm/asm.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/addrspace.h> | ||
15 | #include <asm/regdef.h> | ||
16 | #include <asm/stackframe.h> | ||
17 | |||
18 | /* | ||
19 | * first level interrupt dispatcher for ocelot board - | ||
20 | * We check for the timer first, then check PCI ints A and D. | ||
21 | * Then check for serial IRQ and fall through. | ||
22 | */ | ||
23 | .align 5 | ||
24 | NESTED(ocelot_handle_int, PT_SIZE, sp) | ||
25 | SAVE_ALL | ||
26 | CLI | ||
27 | .set at | ||
28 | mfc0 t0, CP0_CAUSE | ||
29 | mfc0 t2, CP0_STATUS | ||
30 | |||
31 | and t0, t2 | ||
32 | |||
33 | andi t1, t0, STATUSF_IP2 /* int0 hardware line */ | ||
34 | bnez t1, ll_pri_enet_irq | ||
35 | andi t1, t0, STATUSF_IP3 /* int1 hardware line */ | ||
36 | bnez t1, ll_sec_enet_irq | ||
37 | andi t1, t0, STATUSF_IP4 /* int2 hardware line */ | ||
38 | bnez t1, ll_uart_irq | ||
39 | andi t1, t0, STATUSF_IP5 /* int3 hardware line */ | ||
40 | bnez t1, ll_cpci_irq | ||
41 | andi t1, t0, STATUSF_IP6 /* int4 hardware line */ | ||
42 | bnez t1, ll_galileo_p0_irq | ||
43 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
44 | bnez t1, ll_cputimer_irq | ||
45 | |||
46 | /* now look at the extended interrupts */ | ||
47 | mfc0 t0, CP0_CAUSE | ||
48 | cfc0 t1, CP0_S1_INTCONTROL | ||
49 | |||
50 | /* shift the mask 8 bits left to line up the bits */ | ||
51 | sll t2, t1, 8 | ||
52 | |||
53 | and t0, t2 | ||
54 | srl t0, t0, 16 | ||
55 | |||
56 | andi t1, t0, STATUSF_IP8 /* int6 hardware line */ | ||
57 | bnez t1, ll_galileo_p1_irq | ||
58 | andi t1, t0, STATUSF_IP9 /* int7 hardware line */ | ||
59 | bnez t1, ll_pmc_irq | ||
60 | andi t1, t0, STATUSF_IP10 /* int8 hardware line */ | ||
61 | bnez t1, ll_cpci_abcd_irq | ||
62 | andi t1, t0, STATUSF_IP11 /* int9 hardware line */ | ||
63 | bnez t1, ll_testpoint_irq | ||
64 | |||
65 | .set reorder | ||
66 | |||
67 | /* wrong alarm or masked ... */ | ||
68 | j spurious_interrupt | ||
69 | nop | ||
70 | END(ocelot_handle_int) | ||
71 | |||
72 | .align 5 | ||
73 | ll_pri_enet_irq: | ||
74 | li a0, 2 | ||
75 | move a1, sp | ||
76 | jal do_IRQ | ||
77 | j ret_from_irq | ||
78 | |||
79 | ll_sec_enet_irq: | ||
80 | li a0, 3 | ||
81 | move a1, sp | ||
82 | jal do_IRQ | ||
83 | j ret_from_irq | ||
84 | |||
85 | ll_uart_irq: | ||
86 | li a0, 4 | ||
87 | move a1, sp | ||
88 | jal do_IRQ | ||
89 | j ret_from_irq | ||
90 | |||
91 | ll_cpci_irq: | ||
92 | li a0, 5 | ||
93 | move a1, sp | ||
94 | jal do_IRQ | ||
95 | j ret_from_irq | ||
96 | |||
97 | ll_galileo_p0_irq: | ||
98 | li a0, 6 | ||
99 | move a1, sp | ||
100 | jal do_IRQ | ||
101 | j ret_from_irq | ||
102 | |||
103 | ll_cputimer_irq: | ||
104 | li a0, 7 | ||
105 | move a1, sp | ||
106 | jal do_IRQ | ||
107 | j ret_from_irq | ||
108 | |||
109 | ll_galileo_p1_irq: | ||
110 | li a0, 8 | ||
111 | move a1, sp | ||
112 | jal do_IRQ | ||
113 | j ret_from_irq | ||
114 | |||
115 | ll_pmc_irq: | ||
116 | li a0, 9 | ||
117 | move a1, sp | ||
118 | jal do_IRQ | ||
119 | j ret_from_irq | ||
120 | |||
121 | ll_cpci_abcd_irq: | ||
122 | li a0, 10 | ||
123 | move a1, sp | ||
124 | jal do_IRQ | ||
125 | j ret_from_irq | ||
126 | |||
127 | ll_testpoint_irq: | ||
128 | li a0, 11 | ||
129 | move a1, sp | ||
130 | jal do_IRQ | ||
131 | j ret_from_irq | ||
diff --git a/arch/mips/momentum/ocelot_g/irq.c b/arch/mips/momentum/ocelot_g/irq.c index 5eb85b164205..7a4a419804f1 100644 --- a/arch/mips/momentum/ocelot_g/irq.c +++ b/arch/mips/momentum/ocelot_g/irq.c | |||
@@ -48,7 +48,41 @@ | |||
48 | #include <asm/mipsregs.h> | 48 | #include <asm/mipsregs.h> |
49 | #include <asm/system.h> | 49 | #include <asm/system.h> |
50 | 50 | ||
51 | extern asmlinkage void ocelot_handle_int(void); | 51 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
52 | { | ||
53 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
54 | |||
55 | if (pending & STATUSF_IP2) | ||
56 | do_IRQ(2, regs); | ||
57 | else if (pending & STATUSF_IP3) | ||
58 | do_IRQ(3, regs); | ||
59 | else if (pending & STATUSF_IP4) | ||
60 | do_IRQ(4, regs); | ||
61 | else if (pending & STATUSF_IP5) | ||
62 | do_IRQ(5, regs); | ||
63 | else if (pending & STATUSF_IP6) | ||
64 | do_IRQ(6, regs); | ||
65 | else if (pending & STATUSF_IP7) | ||
66 | do_IRQ(7, regs); | ||
67 | else { | ||
68 | /* | ||
69 | * Now look at the extended interrupts | ||
70 | */ | ||
71 | pending = (read_c0_cause() & (read_c0_intcontrol() << 8)) >> 16; | ||
72 | |||
73 | if (pending & STATUSF_IP8) | ||
74 | do_IRQ(8, regs); | ||
75 | else if (pending & STATUSF_IP9) | ||
76 | do_IRQ(9, regs); | ||
77 | else if (pending & STATUSF_IP10) | ||
78 | do_IRQ(10, regs); | ||
79 | else if (pending & STATUSF_IP11) | ||
80 | do_IRQ(11, regs); | ||
81 | else | ||
82 | spurious_interrupt(regs); | ||
83 | } | ||
84 | } | ||
85 | |||
52 | extern void gt64240_irq_init(void); | 86 | extern void gt64240_irq_init(void); |
53 | 87 | ||
54 | void __init arch_init_irq(void) | 88 | void __init arch_init_irq(void) |
@@ -60,8 +94,6 @@ void __init arch_init_irq(void) | |||
60 | clear_c0_status(ST0_IM); | 94 | clear_c0_status(ST0_IM); |
61 | local_irq_disable(); | 95 | local_irq_disable(); |
62 | 96 | ||
63 | /* Sets the first-level interrupt dispatcher. */ | ||
64 | set_except_vector(0, ocelot_handle_int); | ||
65 | mips_cpu_irq_init(0); | 97 | mips_cpu_irq_init(0); |
66 | rm7k_cpu_irq_init(8); | 98 | rm7k_cpu_irq_init(8); |
67 | 99 | ||
diff --git a/arch/mips/philips/pnx8550/common/Makefile b/arch/mips/philips/pnx8550/common/Makefile index 6e38f3bc443c..b7c638166e9f 100644 --- a/arch/mips/philips/pnx8550/common/Makefile +++ b/arch/mips/philips/pnx8550/common/Makefile | |||
@@ -22,6 +22,6 @@ | |||
22 | # under Linux. | 22 | # under Linux. |
23 | # | 23 | # |
24 | 24 | ||
25 | obj-y := setup.o prom.o mipsIRQ.o int.o reset.o time.o proc.o platform.o | 25 | obj-y := setup.o prom.o int.o reset.o time.o proc.o platform.o |
26 | obj-$(CONFIG_PCI) += pci.o | 26 | obj-$(CONFIG_PCI) += pci.o |
27 | obj-$(CONFIG_KGDB) += gdb_hook.o | 27 | obj-$(CONFIG_KGDB) += gdb_hook.o |
diff --git a/arch/mips/philips/pnx8550/common/int.c b/arch/mips/philips/pnx8550/common/int.c index c500e2d41f2c..39ee6314f627 100644 --- a/arch/mips/philips/pnx8550/common/int.c +++ b/arch/mips/philips/pnx8550/common/int.c | |||
@@ -38,8 +38,6 @@ | |||
38 | #include <int.h> | 38 | #include <int.h> |
39 | #include <uart.h> | 39 | #include <uart.h> |
40 | 40 | ||
41 | extern asmlinkage void cp0_irqdispatch(void); | ||
42 | |||
43 | static DEFINE_SPINLOCK(irq_lock); | 41 | static DEFINE_SPINLOCK(irq_lock); |
44 | 42 | ||
45 | /* default prio for interrupts */ | 43 | /* default prio for interrupts */ |
@@ -55,7 +53,7 @@ static char gic_prio[PNX8550_INT_GIC_TOTINT] = { | |||
55 | 1 // 70 | 53 | 1 // 70 |
56 | }; | 54 | }; |
57 | 55 | ||
58 | void hw0_irqdispatch(int irq, struct pt_regs *regs) | 56 | static void hw0_irqdispatch(int irq, struct pt_regs *regs) |
59 | { | 57 | { |
60 | /* find out which interrupt */ | 58 | /* find out which interrupt */ |
61 | irq = PNX8550_GIC_VECTOR_0 >> 3; | 59 | irq = PNX8550_GIC_VECTOR_0 >> 3; |
@@ -68,7 +66,7 @@ void hw0_irqdispatch(int irq, struct pt_regs *regs) | |||
68 | } | 66 | } |
69 | 67 | ||
70 | 68 | ||
71 | void timer_irqdispatch(int irq, struct pt_regs *regs) | 69 | static void timer_irqdispatch(int irq, struct pt_regs *regs) |
72 | { | 70 | { |
73 | irq = (0x01c0 & read_c0_config7()) >> 6; | 71 | irq = (0x01c0 & read_c0_config7()) >> 6; |
74 | 72 | ||
@@ -88,6 +86,20 @@ void timer_irqdispatch(int irq, struct pt_regs *regs) | |||
88 | } | 86 | } |
89 | } | 87 | } |
90 | 88 | ||
89 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
90 | { | ||
91 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
92 | |||
93 | if (pending & STATUSF_IP2) | ||
94 | do_IRQ(2, regs); | ||
95 | else if (pending & STATUSF_IP7) { | ||
96 | if (read_c0_config7() & 0x01c0) | ||
97 | timer_irqdispatch(7, regs); | ||
98 | } | ||
99 | |||
100 | spurious_interrupt(regs); | ||
101 | } | ||
102 | |||
91 | static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) | 103 | static inline void modify_cp0_intmask(unsigned clr_mask, unsigned set_mask) |
92 | { | 104 | { |
93 | unsigned long status = read_c0_status(); | 105 | unsigned long status = read_c0_status(); |
@@ -223,9 +235,6 @@ void __init arch_init_irq(void) | |||
223 | int i; | 235 | int i; |
224 | int configPR; | 236 | int configPR; |
225 | 237 | ||
226 | /* init of cp0 interrupts */ | ||
227 | set_except_vector(0, cp0_irqdispatch); | ||
228 | |||
229 | for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { | 238 | for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { |
230 | irq_desc[i].handler = &level_irq_type; | 239 | irq_desc[i].handler = &level_irq_type; |
231 | pnx8550_ack(i); /* mask the irq just in case */ | 240 | pnx8550_ack(i); /* mask the irq just in case */ |
diff --git a/arch/mips/philips/pnx8550/common/mipsIRQ.S b/arch/mips/philips/pnx8550/common/mipsIRQ.S deleted file mode 100644 index 338bffda3fab..000000000000 --- a/arch/mips/philips/pnx8550/common/mipsIRQ.S +++ /dev/null | |||
@@ -1,76 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2002 Philips, Inc. All rights. | ||
3 | * Copyright (c) 2002 Red Hat, Inc. All rights. | ||
4 | * | ||
5 | * This software may be freely redistributed under the terms of the | ||
6 | * GNU General Public License. | ||
7 | * | ||
8 | * You should have received a copy of the GNU General Public License | ||
9 | * along with this program; if not, write to the Free Software | ||
10 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
11 | * | ||
12 | * Based upon arch/mips/galileo-boards/ev64240/int-handler.S | ||
13 | * | ||
14 | */ | ||
15 | #include <asm/asm.h> | ||
16 | #include <asm/mipsregs.h> | ||
17 | #include <asm/addrspace.h> | ||
18 | #include <asm/regdef.h> | ||
19 | #include <asm/stackframe.h> | ||
20 | |||
21 | /* | ||
22 | * cp0_irqdispatch | ||
23 | * | ||
24 | * Code to handle in-core interrupt exception. | ||
25 | */ | ||
26 | |||
27 | .align 5 | ||
28 | .set reorder | ||
29 | .set noat | ||
30 | NESTED(cp0_irqdispatch, PT_SIZE, sp) | ||
31 | SAVE_ALL | ||
32 | CLI | ||
33 | .set at | ||
34 | mfc0 t0,CP0_CAUSE | ||
35 | mfc0 t2,CP0_STATUS | ||
36 | |||
37 | and t0,t2 | ||
38 | |||
39 | andi t1,t0,STATUSF_IP2 /* int0 hardware line */ | ||
40 | bnez t1,ll_hw0_irq | ||
41 | nop | ||
42 | |||
43 | andi t1,t0,STATUSF_IP7 /* int5 hardware line */ | ||
44 | bnez t1,ll_timer_irq | ||
45 | nop | ||
46 | |||
47 | /* wrong alarm or masked ... */ | ||
48 | |||
49 | j spurious_interrupt | ||
50 | nop | ||
51 | END(cp0_irqdispatch) | ||
52 | |||
53 | .align 5 | ||
54 | .set reorder | ||
55 | ll_hw0_irq: | ||
56 | li a0,2 | ||
57 | move a1,sp | ||
58 | jal hw0_irqdispatch | ||
59 | nop | ||
60 | j ret_from_irq | ||
61 | nop | ||
62 | |||
63 | .align 5 | ||
64 | .set reorder | ||
65 | ll_timer_irq: | ||
66 | mfc0 t3,CP0_CONFIG,7 | ||
67 | andi t4,t3,0x01c0 | ||
68 | beqz t4,ll_timer_out | ||
69 | nop | ||
70 | li a0,7 | ||
71 | move a1,sp | ||
72 | jal timer_irqdispatch | ||
73 | nop | ||
74 | |||
75 | ll_timer_out: j ret_from_irq | ||
76 | nop | ||
diff --git a/arch/mips/philips/pnx8550/common/platform.c b/arch/mips/philips/pnx8550/common/platform.c index a592260fd673..5436b4b97455 100644 --- a/arch/mips/philips/pnx8550/common/platform.c +++ b/arch/mips/philips/pnx8550/common/platform.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/resource.h> | 18 | #include <linux/resource.h> |
19 | #include <linux/serial.h> | 19 | #include <linux/serial.h> |
20 | #include <linux/serial_ip3106.h> | 20 | #include <linux/serial_ip3106.h> |
21 | #include <linux/platform_device.h> | ||
21 | 22 | ||
22 | #include <int.h> | 23 | #include <int.h> |
23 | #include <usb.h> | 24 | #include <usb.h> |
diff --git a/arch/mips/pmc-sierra/yosemite/Makefile b/arch/mips/pmc-sierra/yosemite/Makefile index ae96a71a3089..e931e0d44229 100644 --- a/arch/mips/pmc-sierra/yosemite/Makefile +++ b/arch/mips/pmc-sierra/yosemite/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the PMC-Sierra Titan | 2 | # Makefile for the PMC-Sierra Titan |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += irq-handler.o irq.o i2c-yosemite.o prom.o py-console.o setup.o | 5 | obj-y += irq.o i2c-yosemite.o prom.o py-console.o setup.o |
6 | 6 | ||
7 | obj-$(CONFIG_KGDB) += dbg_io.o | 7 | obj-$(CONFIG_KGDB) += dbg_io.o |
8 | obj-$(CONFIG_SMP) += smp.o | 8 | obj-$(CONFIG_SMP) += smp.o |
diff --git a/arch/mips/pmc-sierra/yosemite/irq-handler.S b/arch/mips/pmc-sierra/yosemite/irq-handler.S deleted file mode 100644 index 33b9c40d4f5c..000000000000 --- a/arch/mips/pmc-sierra/yosemite/irq-handler.S +++ /dev/null | |||
@@ -1,93 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright 2003, 04 PMC-Sierra Inc. | ||
3 | * Author: Manish Lachwani (lachwani@pmc-sierra.com | ||
4 | * Copyright 2004 Ralf Baechle (ralf@linux-mips.org) | ||
5 | * | ||
6 | * First-level interrupt router for the PMC-Sierra Titan board | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | * | ||
13 | * Titan supports Hypertransport or PCI but not both. Hence, one interrupt | ||
14 | * line is shared between the PCI slot A and Hypertransport. This is the | ||
15 | * Processor INTB #0. | ||
16 | */ | ||
17 | |||
18 | #include <linux/config.h> | ||
19 | #include <asm/asm.h> | ||
20 | #include <asm/mipsregs.h> | ||
21 | #include <asm/addrspace.h> | ||
22 | #include <asm/regdef.h> | ||
23 | #include <asm/stackframe.h> | ||
24 | |||
25 | .align 5 | ||
26 | NESTED(titan_handle_int, PT_SIZE, sp) | ||
27 | SAVE_ALL | ||
28 | CLI | ||
29 | .set at | ||
30 | .set noreorder | ||
31 | la ra, ret_from_irq | ||
32 | mfc0 t0, CP0_CAUSE | ||
33 | mfc0 t2, CP0_STATUS | ||
34 | |||
35 | and t0, t2 | ||
36 | |||
37 | andi t2, t0, STATUSF_IP7 /* INTB5 hardware line */ | ||
38 | bnez t2, ll_timer_irq /* Timer */ | ||
39 | andi t1, t0, STATUSF_IP2 /* INTB0 hardware line */ | ||
40 | bnez t1, ll_pcia_irq /* 64-bit PCI */ | ||
41 | andi t2, t0, STATUSF_IP3 /* INTB1 hardware line */ | ||
42 | bnez t2, ll_pcib_irq /* second 64-bit PCI slot */ | ||
43 | andi t1, t0, STATUSF_IP4 /* INTB2 hardware line */ | ||
44 | bnez t1, ll_duart_irq /* UART */ | ||
45 | andi t2, t0, STATUSF_IP5 /* SMP inter-core interrupts */ | ||
46 | bnez t2, ll_smp_irq | ||
47 | andi t1, t0, STATUSF_IP6 | ||
48 | bnez t1, ll_ht_irq /* Hypertransport */ | ||
49 | |||
50 | move a0, sp | ||
51 | j do_extended_irq | ||
52 | END(titan_handle_int) | ||
53 | |||
54 | .set reorder | ||
55 | .align 5 | ||
56 | |||
57 | ll_pcia_irq: | ||
58 | li a0, 2 | ||
59 | move a1, sp | ||
60 | #ifdef CONFIG_HYPERTRANSPORT | ||
61 | j ll_ht_smp_irq_handler | ||
62 | #else | ||
63 | j do_IRQ | ||
64 | #endif | ||
65 | |||
66 | ll_pcib_irq: | ||
67 | li a0, 3 | ||
68 | move a1, sp | ||
69 | j do_IRQ | ||
70 | |||
71 | ll_duart_irq: | ||
72 | li a0, 4 | ||
73 | move a1, sp | ||
74 | j do_IRQ | ||
75 | |||
76 | ll_smp_irq: | ||
77 | li a0, 5 | ||
78 | move a1, sp | ||
79 | #ifdef CONFIG_SMP | ||
80 | j titan_mailbox_irq | ||
81 | #else | ||
82 | j do_IRQ | ||
83 | #endif | ||
84 | |||
85 | ll_ht_irq: | ||
86 | li a0, 6 | ||
87 | move a1, sp | ||
88 | j ll_ht_smp_irq_handler | ||
89 | |||
90 | ll_timer_irq: | ||
91 | li a0, 7 | ||
92 | move a1, sp | ||
93 | j do_IRQ | ||
diff --git a/arch/mips/pmc-sierra/yosemite/irq.c b/arch/mips/pmc-sierra/yosemite/irq.c index f4e2897d9bf7..a1f524fc4c10 100644 --- a/arch/mips/pmc-sierra/yosemite/irq.c +++ b/arch/mips/pmc-sierra/yosemite/irq.c | |||
@@ -2,6 +2,8 @@ | |||
2 | * Copyright (C) 2003 PMC-Sierra Inc. | 2 | * Copyright (C) 2003 PMC-Sierra Inc. |
3 | * Author: Manish Lachwani (lachwani@pmc-sierra.com) | 3 | * Author: Manish Lachwani (lachwani@pmc-sierra.com) |
4 | * | 4 | * |
5 | * Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org) | ||
6 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | 7 | * This program is free software; you can redistribute it and/or modify it |
6 | * under the terms of the GNU General Public License as published by the | 8 | * under the terms of the GNU General Public License as published by the |
7 | * Free Software Foundation; either version 2 of the License, or (at your | 9 | * Free Software Foundation; either version 2 of the License, or (at your |
@@ -55,7 +57,6 @@ | |||
55 | #define HYPERTRANSPORT_INTC 0x7a /* INTC# */ | 57 | #define HYPERTRANSPORT_INTC 0x7a /* INTC# */ |
56 | #define HYPERTRANSPORT_INTD 0x7b /* INTD# */ | 58 | #define HYPERTRANSPORT_INTD 0x7b /* INTD# */ |
57 | 59 | ||
58 | extern asmlinkage void titan_handle_int(void); | ||
59 | extern void jaguar_mailbox_irq(struct pt_regs *); | 60 | extern void jaguar_mailbox_irq(struct pt_regs *); |
60 | 61 | ||
61 | /* | 62 | /* |
@@ -125,6 +126,35 @@ asmlinkage void do_extended_irq(struct pt_regs *regs) | |||
125 | 126 | ||
126 | } | 127 | } |
127 | 128 | ||
129 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
130 | { | ||
131 | unsigned int cause = read_c0_cause(); | ||
132 | unsigned int status = read_c0_status(); | ||
133 | unsigned int pending = cause & status; | ||
134 | |||
135 | if (pending & STATUSF_IP7) { | ||
136 | do_IRQ(7, regs); | ||
137 | } else if (pending & STATUSF_IP2) { | ||
138 | #ifdef CONFIG_HYPERTRANSPORT | ||
139 | ll_ht_smp_irq_handler(2, regs); | ||
140 | #else | ||
141 | do_IRQ(2, regs); | ||
142 | #endif | ||
143 | } else if (pending & STATUSF_IP3) { | ||
144 | do_IRQ(3, regs); | ||
145 | } else if (pending & STATUSF_IP4) { | ||
146 | do_IRQ(4, regs); | ||
147 | } else if (pending & STATUSF_IP5) { | ||
148 | #ifdef CONFIG_SMP | ||
149 | titan_mailbox_irq(regs); | ||
150 | #else | ||
151 | do_IRQ(5, regs); | ||
152 | #endif | ||
153 | } else if (pending & STATUSF_IP6) { | ||
154 | do_IRQ(4, regs); | ||
155 | } | ||
156 | } | ||
157 | |||
128 | #ifdef CONFIG_KGDB | 158 | #ifdef CONFIG_KGDB |
129 | extern void init_second_port(void); | 159 | extern void init_second_port(void); |
130 | #endif | 160 | #endif |
@@ -136,7 +166,6 @@ void __init arch_init_irq(void) | |||
136 | { | 166 | { |
137 | clear_c0_status(ST0_IM); | 167 | clear_c0_status(ST0_IM); |
138 | 168 | ||
139 | set_except_vector(0, titan_handle_int); | ||
140 | mips_cpu_irq_init(0); | 169 | mips_cpu_irq_init(0); |
141 | rm7k_cpu_irq_init(8); | 170 | rm7k_cpu_irq_init(8); |
142 | rm9k_cpu_irq_init(12); | 171 | rm9k_cpu_irq_init(12); |
diff --git a/arch/mips/qemu/Makefile b/arch/mips/qemu/Makefile index 6a8e8bcef552..730f459f3e99 100644 --- a/arch/mips/qemu/Makefile +++ b/arch/mips/qemu/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for Qemu specific kernel interface routines under Linux. | 2 | # Makefile for Qemu specific kernel interface routines under Linux. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y = q-firmware.o q-int.o q-irq.o q-mem.o q-setup.o | 5 | obj-y = q-firmware.o q-irq.o q-mem.o q-setup.o |
6 | 6 | ||
7 | obj-$(CONFIG_SMP) += q-smp.o | 7 | obj-$(CONFIG_SMP) += q-smp.o |
diff --git a/arch/mips/qemu/q-int.S b/arch/mips/qemu/q-int.S deleted file mode 100644 index 6e3dfe5eb14b..000000000000 --- a/arch/mips/qemu/q-int.S +++ /dev/null | |||
@@ -1,17 +0,0 @@ | |||
1 | /* | ||
2 | * Qemu interrupt handler code. | ||
3 | * | ||
4 | * Copyright (C) 2005 by Ralf Baechle | ||
5 | */ | ||
6 | #include <asm/asm.h> | ||
7 | #include <asm/regdef.h> | ||
8 | #include <asm/stackframe.h> | ||
9 | |||
10 | .align 5 | ||
11 | NESTED(qemu_handle_int, PT_SIZE, sp) | ||
12 | SAVE_ALL | ||
13 | CLI | ||
14 | move a0, sp | ||
15 | PTR_LA ra, ret_from_irq | ||
16 | j do_qemu_int | ||
17 | END(qemu_handle_int) | ||
diff --git a/arch/mips/qemu/q-irq.c b/arch/mips/qemu/q-irq.c index 2c4e0704ff10..3352374c4c7d 100644 --- a/arch/mips/qemu/q-irq.c +++ b/arch/mips/qemu/q-irq.c | |||
@@ -9,7 +9,7 @@ | |||
9 | 9 | ||
10 | extern asmlinkage void qemu_handle_int(void); | 10 | extern asmlinkage void qemu_handle_int(void); |
11 | 11 | ||
12 | asmlinkage void do_qemu_int(struct pt_regs *regs) | 12 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
13 | { | 13 | { |
14 | unsigned int pending = read_c0_status() & read_c0_cause(); | 14 | unsigned int pending = read_c0_status() & read_c0_cause(); |
15 | 15 | ||
@@ -29,7 +29,6 @@ asmlinkage void do_qemu_int(struct pt_regs *regs) | |||
29 | 29 | ||
30 | void __init arch_init_irq(void) | 30 | void __init arch_init_irq(void) |
31 | { | 31 | { |
32 | set_except_vector(0, qemu_handle_int); | ||
33 | mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */ | 32 | mips_hpt_frequency = QEMU_C0_COUNTER_CLOCK; /* 100MHz */ |
34 | 33 | ||
35 | init_i8259_irqs(); | 34 | init_i8259_irqs(); |
diff --git a/arch/mips/sgi-ip22/Makefile b/arch/mips/sgi-ip22/Makefile index eb0820fe50bd..6aa4c0cd169c 100644 --- a/arch/mips/sgi-ip22/Makefile +++ b/arch/mips/sgi-ip22/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-irq.o ip22-berr.o \ | 6 | obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ |
7 | ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o | 7 | ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o |
8 | 8 | ||
9 | obj-$(CONFIG_EISA) += ip22-eisa.o | 9 | obj-$(CONFIG_EISA) += ip22-eisa.o |
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c index d16fb43b1a93..fc6a7e2b189c 100644 --- a/arch/mips/sgi-ip22/ip22-int.c +++ b/arch/mips/sgi-ip22/ip22-int.c | |||
@@ -37,7 +37,6 @@ static char lc1msk_to_irqnr[256]; | |||
37 | static char lc2msk_to_irqnr[256]; | 37 | static char lc2msk_to_irqnr[256]; |
38 | static char lc3msk_to_irqnr[256]; | 38 | static char lc3msk_to_irqnr[256]; |
39 | 39 | ||
40 | extern asmlinkage void indyIRQ(void); | ||
41 | extern int ip22_eisa_init(void); | 40 | extern int ip22_eisa_init(void); |
42 | 41 | ||
43 | static void enable_local0_irq(unsigned int irq) | 42 | static void enable_local0_irq(unsigned int irq) |
@@ -224,7 +223,7 @@ static struct hw_interrupt_type ip22_local3_irq_type = { | |||
224 | .end = end_local3_irq, | 223 | .end = end_local3_irq, |
225 | }; | 224 | }; |
226 | 225 | ||
227 | void indy_local0_irqdispatch(struct pt_regs *regs) | 226 | static void indy_local0_irqdispatch(struct pt_regs *regs) |
228 | { | 227 | { |
229 | u8 mask = sgint->istat0 & sgint->imask0; | 228 | u8 mask = sgint->istat0 & sgint->imask0; |
230 | u8 mask2; | 229 | u8 mask2; |
@@ -242,7 +241,7 @@ void indy_local0_irqdispatch(struct pt_regs *regs) | |||
242 | return; | 241 | return; |
243 | } | 242 | } |
244 | 243 | ||
245 | void indy_local1_irqdispatch(struct pt_regs *regs) | 244 | static void indy_local1_irqdispatch(struct pt_regs *regs) |
246 | { | 245 | { |
247 | u8 mask = sgint->istat1 & sgint->imask1; | 246 | u8 mask = sgint->istat1 & sgint->imask1; |
248 | u8 mask2; | 247 | u8 mask2; |
@@ -262,7 +261,7 @@ void indy_local1_irqdispatch(struct pt_regs *regs) | |||
262 | 261 | ||
263 | extern void ip22_be_interrupt(int irq, struct pt_regs *regs); | 262 | extern void ip22_be_interrupt(int irq, struct pt_regs *regs); |
264 | 263 | ||
265 | void indy_buserror_irq(struct pt_regs *regs) | 264 | static void indy_buserror_irq(struct pt_regs *regs) |
266 | { | 265 | { |
267 | int irq = SGI_BUSERR_IRQ; | 266 | int irq = SGI_BUSERR_IRQ; |
268 | 267 | ||
@@ -307,6 +306,56 @@ static struct irqaction map1_cascade = { | |||
307 | #define SGI_INTERRUPTS SGINT_LOCAL3 | 306 | #define SGI_INTERRUPTS SGINT_LOCAL3 |
308 | #endif | 307 | #endif |
309 | 308 | ||
309 | extern void indy_r4k_timer_interrupt(struct pt_regs *regs); | ||
310 | extern void indy_8254timer_irq(struct pt_regs *regs); | ||
311 | |||
312 | /* | ||
313 | * IRQs on the INDY look basically (barring software IRQs which we don't use | ||
314 | * at all) like: | ||
315 | * | ||
316 | * MIPS IRQ Source | ||
317 | * -------- ------ | ||
318 | * 0 Software (ignored) | ||
319 | * 1 Software (ignored) | ||
320 | * 2 Local IRQ level zero | ||
321 | * 3 Local IRQ level one | ||
322 | * 4 8254 Timer zero | ||
323 | * 5 8254 Timer one | ||
324 | * 6 Bus Error | ||
325 | * 7 R4k timer (what we use) | ||
326 | * | ||
327 | * We handle the IRQ according to _our_ priority which is: | ||
328 | * | ||
329 | * Highest ---- R4k Timer | ||
330 | * Local IRQ zero | ||
331 | * Local IRQ one | ||
332 | * Bus Error | ||
333 | * 8254 Timer zero | ||
334 | * Lowest ---- 8254 Timer one | ||
335 | * | ||
336 | * then we just return, if multiple IRQs are pending then we will just take | ||
337 | * another exception, big deal. | ||
338 | */ | ||
339 | |||
340 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
341 | { | ||
342 | unsigned int pending = read_c0_cause(); | ||
343 | |||
344 | /* | ||
345 | * First we check for r4k counter/timer IRQ. | ||
346 | */ | ||
347 | if (pending & CAUSEF_IP7) | ||
348 | indy_r4k_timer_interrupt(regs); | ||
349 | else if (pending & CAUSEF_IP2) | ||
350 | indy_local0_irqdispatch(regs); | ||
351 | else if (pending & CAUSEF_IP3) | ||
352 | indy_local1_irqdispatch(regs); | ||
353 | else if (pending & CAUSEF_IP6) | ||
354 | indy_buserror_irq(regs); | ||
355 | else if (pending & (CAUSEF_IP4 | CAUSEF_IP5)) | ||
356 | indy_8254timer_irq(regs); | ||
357 | } | ||
358 | |||
310 | extern void mips_cpu_irq_init(unsigned int irq_base); | 359 | extern void mips_cpu_irq_init(unsigned int irq_base); |
311 | 360 | ||
312 | void __init arch_init_irq(void) | 361 | void __init arch_init_irq(void) |
@@ -369,8 +418,6 @@ void __init arch_init_irq(void) | |||
369 | sgint->cmeimask0 = 0; | 418 | sgint->cmeimask0 = 0; |
370 | sgint->cmeimask1 = 0; | 419 | sgint->cmeimask1 = 0; |
371 | 420 | ||
372 | set_except_vector(0, indyIRQ); | ||
373 | |||
374 | /* init CPU irqs */ | 421 | /* init CPU irqs */ |
375 | mips_cpu_irq_init(SGINT_CPU); | 422 | mips_cpu_irq_init(SGINT_CPU); |
376 | 423 | ||
diff --git a/arch/mips/sgi-ip22/ip22-irq.S b/arch/mips/sgi-ip22/ip22-irq.S deleted file mode 100644 index 6ccbd9e1d967..000000000000 --- a/arch/mips/sgi-ip22/ip22-irq.S +++ /dev/null | |||
@@ -1,118 +0,0 @@ | |||
1 | /* | ||
2 | * ip22-irq.S: Interrupt exception dispatch code for FullHouse and | ||
3 | * Guiness. | ||
4 | * | ||
5 | * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com) | ||
6 | */ | ||
7 | |||
8 | #include <asm/asm.h> | ||
9 | #include <asm/mipsregs.h> | ||
10 | #include <asm/regdef.h> | ||
11 | #include <asm/stackframe.h> | ||
12 | |||
13 | /* A lot of complication here is taken away because: | ||
14 | * | ||
15 | * 1) We handle one interrupt and return, sitting in a loop and moving across | ||
16 | * all the pending IRQ bits in the cause register is _NOT_ the answer, the | ||
17 | * common case is one pending IRQ so optimize in that direction. | ||
18 | * | ||
19 | * 2) We need not check against bits in the status register IRQ mask, that | ||
20 | * would make this routine slow as hell. | ||
21 | * | ||
22 | * 3) Linux only thinks in terms of all IRQs on or all IRQs off, nothing in | ||
23 | * between like BSD spl() brain-damage. | ||
24 | * | ||
25 | * Furthermore, the IRQs on the INDY look basically (barring software IRQs | ||
26 | * which we don't use at all) like: | ||
27 | * | ||
28 | * MIPS IRQ Source | ||
29 | * -------- ------ | ||
30 | * 0 Software (ignored) | ||
31 | * 1 Software (ignored) | ||
32 | * 2 Local IRQ level zero | ||
33 | * 3 Local IRQ level one | ||
34 | * 4 8254 Timer zero | ||
35 | * 5 8254 Timer one | ||
36 | * 6 Bus Error | ||
37 | * 7 R4k timer (what we use) | ||
38 | * | ||
39 | * We handle the IRQ according to _our_ priority which is: | ||
40 | * | ||
41 | * Highest ---- R4k Timer | ||
42 | * Local IRQ zero | ||
43 | * Local IRQ one | ||
44 | * Bus Error | ||
45 | * 8254 Timer zero | ||
46 | * Lowest ---- 8254 Timer one | ||
47 | * | ||
48 | * then we just return, if multiple IRQs are pending then we will just take | ||
49 | * another exception, big deal. | ||
50 | */ | ||
51 | |||
52 | .text | ||
53 | .set noreorder | ||
54 | .set noat | ||
55 | .align 5 | ||
56 | NESTED(indyIRQ, PT_SIZE, sp) | ||
57 | SAVE_ALL | ||
58 | CLI | ||
59 | .set at | ||
60 | mfc0 s0, CP0_CAUSE # get irq mask | ||
61 | |||
62 | /* First we check for r4k counter/timer IRQ. */ | ||
63 | andi a0, s0, CAUSEF_IP7 | ||
64 | beq a0, zero, 1f | ||
65 | andi a0, s0, CAUSEF_IP2 # delay slot, check local level zero | ||
66 | |||
67 | /* Wheee, a timer interrupt. */ | ||
68 | jal indy_r4k_timer_interrupt | ||
69 | move a0, sp # delay slot | ||
70 | j ret_from_irq | ||
71 | nop # delay slot | ||
72 | |||
73 | 1: | ||
74 | beq a0, zero, 1f | ||
75 | andi a0, s0, CAUSEF_IP3 # delay slot, check local level one | ||
76 | |||
77 | /* Wheee, local level zero interrupt. */ | ||
78 | jal indy_local0_irqdispatch | ||
79 | move a0, sp # delay slot | ||
80 | |||
81 | j ret_from_irq | ||
82 | nop # delay slot | ||
83 | |||
84 | 1: | ||
85 | beq a0, zero, 1f | ||
86 | andi a0, s0, CAUSEF_IP6 # delay slot, check bus error | ||
87 | |||
88 | /* Wheee, local level one interrupt. */ | ||
89 | jal indy_local1_irqdispatch | ||
90 | move a0, sp # delay slot | ||
91 | j ret_from_irq | ||
92 | nop # delay slot | ||
93 | |||
94 | 1: | ||
95 | beq a0, zero, 1f | ||
96 | andi a0, s0, (CAUSEF_IP4 | CAUSEF_IP5) # delay slot | ||
97 | |||
98 | /* Wheee, an asynchronous bus error... */ | ||
99 | jal indy_buserror_irq | ||
100 | move a0, sp # delay slot | ||
101 | j ret_from_irq | ||
102 | nop # delay slot | ||
103 | |||
104 | 1: | ||
105 | /* Here by mistake? It is possible, that by the time we take | ||
106 | * the exception the IRQ pin goes low, so just leave if this | ||
107 | * is the case. | ||
108 | */ | ||
109 | beq a0, zero, 1f | ||
110 | nop # delay slot | ||
111 | |||
112 | /* Must be one of the 8254 timers... */ | ||
113 | jal indy_8254timer_irq | ||
114 | move a0, sp # delay slot | ||
115 | 1: | ||
116 | j ret_from_irq | ||
117 | nop # delay slot | ||
118 | END(indyIRQ) | ||
diff --git a/arch/mips/sgi-ip27/Makefile b/arch/mips/sgi-ip27/Makefile index 4ba340780c35..686ba14e2882 100644 --- a/arch/mips/sgi-ip27/Makefile +++ b/arch/mips/sgi-ip27/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for the IP27 specific kernel interface routines under Linux. | 2 | # Makefile for the IP27 specific kernel interface routines under Linux. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o ip27-irq-glue.o \ | 5 | obj-y := ip27-berr.o ip27-console.o ip27-irq.o ip27-init.o \ |
6 | ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \ | 6 | ip27-klconfig.o ip27-klnuma.o ip27-memory.o ip27-nmi.o ip27-reset.o \ |
7 | ip27-timer.o ip27-hubio.o ip27-xtalk.o | 7 | ip27-timer.o ip27-hubio.o ip27-xtalk.o |
8 | 8 | ||
diff --git a/arch/mips/sgi-ip27/TODO b/arch/mips/sgi-ip27/TODO index 32106131b0d0..19f1512c8f2e 100644 --- a/arch/mips/sgi-ip27/TODO +++ b/arch/mips/sgi-ip27/TODO | |||
@@ -9,10 +9,6 @@ ip27-init.c:find_lbaord_real. DONE | |||
9 | in irix? | 9 | in irix? |
10 | 6. Investigate why things do not work without the setup_test() call | 10 | 6. Investigate why things do not work without the setup_test() call |
11 | being invoked on all nodes in ip27-memory.c. | 11 | being invoked on all nodes in ip27-memory.c. |
12 | 7. Too many CLIs in the locore handlers : | ||
13 | For the low level handlers set up by set_except_vector(), | ||
14 | __tlb_refill_debug_tramp, __xtlb_refill_debug_tramp and cacheerror, | ||
15 | investigate whether the code should do CLI, STI or KMODE. | ||
16 | 8. Too many do_page_faults invoked - investigate. | 12 | 8. Too many do_page_faults invoked - investigate. |
17 | 9. start_thread must turn off UX64 ... and define tlb_refill_debug. | 13 | 9. start_thread must turn off UX64 ... and define tlb_refill_debug. |
18 | 10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable | 14 | 10. Need a bad pmd table, bad pte table. __bad_pmd_table/__bad_pagetable |
diff --git a/arch/mips/sgi-ip27/ip27-irq-glue.S b/arch/mips/sgi-ip27/ip27-irq-glue.S deleted file mode 100644 index c304df715e0a..000000000000 --- a/arch/mips/sgi-ip27/ip27-irq-glue.S +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 1999 Ralf Baechle | ||
7 | * Copyright (C) 1999 Silicon Graphics, Inc. | ||
8 | */ | ||
9 | #include <asm/asm.h> | ||
10 | #include <asm/mipsregs.h> | ||
11 | #include <asm/regdef.h> | ||
12 | #include <asm/stackframe.h> | ||
13 | |||
14 | .text | ||
15 | .align 5 | ||
16 | NESTED(ip27_irq, PT_SIZE, sp) | ||
17 | SAVE_ALL | ||
18 | CLI | ||
19 | |||
20 | mfc0 s0, CP0_CAUSE | ||
21 | mfc0 t0, CP0_STATUS | ||
22 | and s0, t0 | ||
23 | move a0, sp | ||
24 | PTR_LA ra, ret_from_irq | ||
25 | |||
26 | /* First check for RT interrupt. */ | ||
27 | andi t0, s0, CAUSEF_IP4 | ||
28 | bnez t0, ip4 | ||
29 | andi t0, s0, CAUSEF_IP2 | ||
30 | bnez t0, ip2 | ||
31 | andi t0, s0, CAUSEF_IP3 | ||
32 | bnez t0, ip3 | ||
33 | andi t0, s0, CAUSEF_IP5 | ||
34 | bnez t0, ip5 | ||
35 | andi t0, s0, CAUSEF_IP6 | ||
36 | bnez t0, ip6 | ||
37 | j ra | ||
38 | |||
39 | ip2: j ip27_do_irq_mask0 # PI_INT_PEND_0 or CC_PEND_{A|B} | ||
40 | ip3: j ip27_do_irq_mask1 # PI_INT_PEND_1 | ||
41 | ip4: j ip27_rt_timer_interrupt | ||
42 | ip5: j ip27_prof_timer | ||
43 | ip6: j ip27_hub_error | ||
44 | |||
45 | END(ip27_irq) | ||
diff --git a/arch/mips/sgi-ip27/ip27-irq.c b/arch/mips/sgi-ip27/ip27-irq.c index 2854ac4c9be1..2e643d2f51cb 100644 --- a/arch/mips/sgi-ip27/ip27-irq.c +++ b/arch/mips/sgi-ip27/ip27-irq.c | |||
@@ -130,7 +130,7 @@ static int ms1bit(unsigned long x) | |||
130 | * Kanoj 05.13.00 | 130 | * Kanoj 05.13.00 |
131 | */ | 131 | */ |
132 | 132 | ||
133 | void ip27_do_irq_mask0(struct pt_regs *regs) | 133 | static void ip27_do_irq_mask0(struct pt_regs *regs) |
134 | { | 134 | { |
135 | int irq, swlevel; | 135 | int irq, swlevel; |
136 | hubreg_t pend0, mask0; | 136 | hubreg_t pend0, mask0; |
@@ -171,7 +171,7 @@ void ip27_do_irq_mask0(struct pt_regs *regs) | |||
171 | LOCAL_HUB_L(PI_INT_PEND0); | 171 | LOCAL_HUB_L(PI_INT_PEND0); |
172 | } | 172 | } |
173 | 173 | ||
174 | void ip27_do_irq_mask1(struct pt_regs *regs) | 174 | static void ip27_do_irq_mask1(struct pt_regs *regs) |
175 | { | 175 | { |
176 | int irq, swlevel; | 176 | int irq, swlevel; |
177 | hubreg_t pend1, mask1; | 177 | hubreg_t pend1, mask1; |
@@ -196,12 +196,12 @@ void ip27_do_irq_mask1(struct pt_regs *regs) | |||
196 | LOCAL_HUB_L(PI_INT_PEND1); | 196 | LOCAL_HUB_L(PI_INT_PEND1); |
197 | } | 197 | } |
198 | 198 | ||
199 | void ip27_prof_timer(struct pt_regs *regs) | 199 | static void ip27_prof_timer(struct pt_regs *regs) |
200 | { | 200 | { |
201 | panic("CPU %d got a profiling interrupt", smp_processor_id()); | 201 | panic("CPU %d got a profiling interrupt", smp_processor_id()); |
202 | } | 202 | } |
203 | 203 | ||
204 | void ip27_hub_error(struct pt_regs *regs) | 204 | static void ip27_hub_error(struct pt_regs *regs) |
205 | { | 205 | { |
206 | panic("CPU %d got a hub error interrupt", smp_processor_id()); | 206 | panic("CPU %d got a hub error interrupt", smp_processor_id()); |
207 | } | 207 | } |
@@ -421,9 +421,26 @@ int __devinit request_bridge_irq(struct bridge_controller *bc) | |||
421 | return irq; | 421 | return irq; |
422 | } | 422 | } |
423 | 423 | ||
424 | extern void ip27_rt_timer_interrupt(struct pt_regs *regs); | ||
425 | |||
426 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
427 | { | ||
428 | unsigned long pending = read_c0_cause() & read_c0_status(); | ||
429 | |||
430 | if (pending & CAUSEF_IP4) | ||
431 | ip27_rt_timer_interrupt(regs); | ||
432 | else if (pending & CAUSEF_IP2) /* PI_INT_PEND_0 or CC_PEND_{A|B} */ | ||
433 | ip27_do_irq_mask0(regs); | ||
434 | else if (pending & CAUSEF_IP3) /* PI_INT_PEND_1 */ | ||
435 | ip27_do_irq_mask1(regs); | ||
436 | else if (pending & CAUSEF_IP5) | ||
437 | ip27_prof_timer(regs); | ||
438 | else if (pending & CAUSEF_IP6) | ||
439 | ip27_hub_error(regs); | ||
440 | } | ||
441 | |||
424 | void __init arch_init_irq(void) | 442 | void __init arch_init_irq(void) |
425 | { | 443 | { |
426 | set_except_vector(0, ip27_irq); | ||
427 | } | 444 | } |
428 | 445 | ||
429 | void install_ipi(void) | 446 | void install_ipi(void) |
diff --git a/arch/mips/sgi-ip32/Makefile b/arch/mips/sgi-ip32/Makefile index 470898f4afe1..530bf848c3d0 100644 --- a/arch/mips/sgi-ip32/Makefile +++ b/arch/mips/sgi-ip32/Makefile | |||
@@ -3,7 +3,7 @@ | |||
3 | # under Linux. | 3 | # under Linux. |
4 | # | 4 | # |
5 | 5 | ||
6 | obj-y += ip32-berr.o ip32-irq.o ip32-irq-glue.o ip32-setup.o ip32-reset.o \ | 6 | obj-y += ip32-berr.o ip32-irq.o ip32-setup.o ip32-reset.o \ |
7 | crime.o ip32-memory.o | 7 | crime.o ip32-memory.o |
8 | 8 | ||
9 | EXTRA_AFLAGS := $(CFLAGS) | 9 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/sgi-ip32/ip32-irq-glue.S b/arch/mips/sgi-ip32/ip32-irq-glue.S deleted file mode 100644 index 200924e1c4f5..000000000000 --- a/arch/mips/sgi-ip32/ip32-irq-glue.S +++ /dev/null | |||
@@ -1,86 +0,0 @@ | |||
1 | /* | ||
2 | * Low level interrupt handler for the SGI O2 aka IP32 aka Moosehead | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2000 Harald Koerfgen | ||
9 | * Copyright (C) 2001 Keith M Wesolowski | ||
10 | */ | ||
11 | #include <asm/asm.h> | ||
12 | #include <asm/regdef.h> | ||
13 | #include <asm/mipsregs.h> | ||
14 | #include <asm/stackframe.h> | ||
15 | #include <asm/addrspace.h> | ||
16 | |||
17 | .text | ||
18 | .set noreorder | ||
19 | .set noat | ||
20 | .align 5 | ||
21 | NESTED(ip32_handle_int, PT_SIZE, ra) | ||
22 | .set noat | ||
23 | SAVE_ALL | ||
24 | CLI # TEST: interrupts should be off | ||
25 | .set at | ||
26 | .set noreorder | ||
27 | |||
28 | mfc0 s0,CP0_CAUSE | ||
29 | |||
30 | andi t1, s0, IE_IRQ0 | ||
31 | bnez t1, handle_irq0 | ||
32 | andi t1, s0, IE_IRQ1 | ||
33 | bnez t1, handle_irq1 | ||
34 | andi t1, s0, IE_IRQ2 | ||
35 | bnez t1, handle_irq2 | ||
36 | andi t1, s0, IE_IRQ3 | ||
37 | bnez t1, handle_irq3 | ||
38 | andi t1, s0, IE_IRQ4 | ||
39 | bnez t1, handle_irq4 | ||
40 | andi t1, s0, IE_IRQ5 | ||
41 | bnez t1, handle_irq5 | ||
42 | nop | ||
43 | |||
44 | /* Either someone has triggered the "software interrupts" | ||
45 | * or we lost an interrupt somehow. Ignore it. | ||
46 | */ | ||
47 | j ret_from_irq | ||
48 | nop | ||
49 | |||
50 | handle_irq0: | ||
51 | jal ip32_irq0 | ||
52 | move a0, sp | ||
53 | j ret_from_irq | ||
54 | nop | ||
55 | |||
56 | handle_irq1: | ||
57 | jal ip32_irq1 | ||
58 | move a0, sp | ||
59 | j ret_from_irq | ||
60 | nop | ||
61 | |||
62 | handle_irq2: | ||
63 | jal ip32_irq2 | ||
64 | move a0, sp | ||
65 | j ret_from_irq | ||
66 | nop | ||
67 | |||
68 | handle_irq3: | ||
69 | jal ip32_irq3 | ||
70 | move a0, sp | ||
71 | j ret_from_irq | ||
72 | nop | ||
73 | |||
74 | handle_irq4: | ||
75 | jal ip32_irq4 | ||
76 | move a0, sp | ||
77 | j ret_from_irq | ||
78 | nop | ||
79 | |||
80 | handle_irq5: | ||
81 | jal ip32_irq5 | ||
82 | move a0, sp | ||
83 | j ret_from_irq | ||
84 | nop | ||
85 | |||
86 | END(ip32_handle_int) | ||
diff --git a/arch/mips/sgi-ip32/ip32-irq.c b/arch/mips/sgi-ip32/ip32-irq.c index 2eb22d692ed9..22a6df94b4a1 100644 --- a/arch/mips/sgi-ip32/ip32-irq.c +++ b/arch/mips/sgi-ip32/ip32-irq.c | |||
@@ -130,8 +130,6 @@ struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, | |||
130 | struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, | 130 | struct irqaction cpuerr_irq = { crime_cpuerr_intr, SA_INTERRUPT, |
131 | CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; | 131 | CPU_MASK_NONE, "CRIME CPU error", NULL, NULL }; |
132 | 132 | ||
133 | extern void ip32_handle_int(void); | ||
134 | |||
135 | /* | 133 | /* |
136 | * For interrupts wired from a single device to the CPU. Only the clock | 134 | * For interrupts wired from a single device to the CPU. Only the clock |
137 | * uses this it seems, which is IRQ 0 and IP7. | 135 | * uses this it seems, which is IRQ 0 and IP7. |
@@ -503,7 +501,7 @@ static void ip32_unknown_interrupt(struct pt_regs *regs) | |||
503 | 501 | ||
504 | /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ | 502 | /* CRIME 1.1 appears to deliver all interrupts to this one pin. */ |
505 | /* change this to loop over all edge-triggered irqs, exception masked out ones */ | 503 | /* change this to loop over all edge-triggered irqs, exception masked out ones */ |
506 | void ip32_irq0(struct pt_regs *regs) | 504 | static void ip32_irq0(struct pt_regs *regs) |
507 | { | 505 | { |
508 | uint64_t crime_int; | 506 | uint64_t crime_int; |
509 | int irq = 0; | 507 | int irq = 0; |
@@ -520,31 +518,49 @@ void ip32_irq0(struct pt_regs *regs) | |||
520 | do_IRQ(irq, regs); | 518 | do_IRQ(irq, regs); |
521 | } | 519 | } |
522 | 520 | ||
523 | void ip32_irq1(struct pt_regs *regs) | 521 | static void ip32_irq1(struct pt_regs *regs) |
524 | { | 522 | { |
525 | ip32_unknown_interrupt(regs); | 523 | ip32_unknown_interrupt(regs); |
526 | } | 524 | } |
527 | 525 | ||
528 | void ip32_irq2(struct pt_regs *regs) | 526 | static void ip32_irq2(struct pt_regs *regs) |
529 | { | 527 | { |
530 | ip32_unknown_interrupt(regs); | 528 | ip32_unknown_interrupt(regs); |
531 | } | 529 | } |
532 | 530 | ||
533 | void ip32_irq3(struct pt_regs *regs) | 531 | static void ip32_irq3(struct pt_regs *regs) |
534 | { | 532 | { |
535 | ip32_unknown_interrupt(regs); | 533 | ip32_unknown_interrupt(regs); |
536 | } | 534 | } |
537 | 535 | ||
538 | void ip32_irq4(struct pt_regs *regs) | 536 | static void ip32_irq4(struct pt_regs *regs) |
539 | { | 537 | { |
540 | ip32_unknown_interrupt(regs); | 538 | ip32_unknown_interrupt(regs); |
541 | } | 539 | } |
542 | 540 | ||
543 | void ip32_irq5(struct pt_regs *regs) | 541 | static void ip32_irq5(struct pt_regs *regs) |
544 | { | 542 | { |
545 | ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs); | 543 | ll_timer_interrupt(IP32_R4K_TIMER_IRQ, regs); |
546 | } | 544 | } |
547 | 545 | ||
546 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
547 | { | ||
548 | unsigned int pending = read_c0_cause(); | ||
549 | |||
550 | if (likely(pending & IE_IRQ0)) | ||
551 | ip32_irq0(regs); | ||
552 | else if (unlikely(pending & IE_IRQ1)) | ||
553 | ip32_irq1(regs); | ||
554 | else if (unlikely(pending & IE_IRQ2)) | ||
555 | ip32_irq2(regs); | ||
556 | else if (unlikely(pending & IE_IRQ3)) | ||
557 | ip32_irq3(regs); | ||
558 | else if (unlikely(pending & IE_IRQ4)) | ||
559 | ip32_irq4(regs); | ||
560 | else if (likely(pending & IE_IRQ5)) | ||
561 | ip32_irq5(regs); | ||
562 | } | ||
563 | |||
548 | void __init arch_init_irq(void) | 564 | void __init arch_init_irq(void) |
549 | { | 565 | { |
550 | unsigned int irq; | 566 | unsigned int irq; |
@@ -556,7 +572,6 @@ void __init arch_init_irq(void) | |||
556 | crime->soft_int = 0; | 572 | crime->soft_int = 0; |
557 | mace->perif.ctrl.istat = 0; | 573 | mace->perif.ctrl.istat = 0; |
558 | mace->perif.ctrl.imask = 0; | 574 | mace->perif.ctrl.imask = 0; |
559 | set_except_vector(0, ip32_handle_int); | ||
560 | 575 | ||
561 | for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { | 576 | for (irq = 0; irq <= IP32_IRQ_MAX; irq++) { |
562 | hw_irq_controller *controller; | 577 | hw_irq_controller *controller; |
diff --git a/arch/mips/sibyte/bcm1480/Makefile b/arch/mips/sibyte/bcm1480/Makefile index 538d5a51ae94..7b36ff3873b7 100644 --- a/arch/mips/sibyte/bcm1480/Makefile +++ b/arch/mips/sibyte/bcm1480/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y := setup.o irq.o irq_handler.o time.o | 1 | obj-y := setup.o irq.o time.o |
2 | 2 | ||
3 | obj-$(CONFIG_SMP) += smp.o | 3 | obj-$(CONFIG_SMP) += smp.o |
4 | 4 | ||
diff --git a/arch/mips/sibyte/bcm1480/irq.c b/arch/mips/sibyte/bcm1480/irq.c index 9cf7d713b13c..e61760b14d99 100644 --- a/arch/mips/sibyte/bcm1480/irq.c +++ b/arch/mips/sibyte/bcm1480/irq.c | |||
@@ -187,9 +187,6 @@ static void bcm1480_set_affinity(unsigned int irq, cpumask_t mask) | |||
187 | #endif | 187 | #endif |
188 | 188 | ||
189 | 189 | ||
190 | /* Defined in arch/mips/sibyte/bcm1480/irq_handler.S */ | ||
191 | extern void bcm1480_irq_handler(void); | ||
192 | |||
193 | /*****************************************************************************/ | 190 | /*****************************************************************************/ |
194 | 191 | ||
195 | static unsigned int startup_bcm1480_irq(unsigned int irq) | 192 | static unsigned int startup_bcm1480_irq(unsigned int irq) |
@@ -422,7 +419,6 @@ void __init arch_init_irq(void) | |||
422 | #endif | 419 | #endif |
423 | /* Enable necessary IPs, disable the rest */ | 420 | /* Enable necessary IPs, disable the rest */ |
424 | change_c0_status(ST0_IM, imask); | 421 | change_c0_status(ST0_IM, imask); |
425 | set_except_vector(0, bcm1480_irq_handler); | ||
426 | 422 | ||
427 | #ifdef CONFIG_KGDB | 423 | #ifdef CONFIG_KGDB |
428 | if (kgdb_flag) { | 424 | if (kgdb_flag) { |
@@ -473,3 +469,76 @@ void bcm1480_kgdb_interrupt(struct pt_regs *regs) | |||
473 | } | 469 | } |
474 | 470 | ||
475 | #endif /* CONFIG_KGDB */ | 471 | #endif /* CONFIG_KGDB */ |
472 | |||
473 | static inline int dclz(unsigned long long x) | ||
474 | { | ||
475 | int lz; | ||
476 | |||
477 | __asm__ ( | ||
478 | " .set push \n" | ||
479 | " .set mips64 \n" | ||
480 | " dclz %0, %1 \n" | ||
481 | " .set pop \n" | ||
482 | : "=r" (lz) | ||
483 | : "r" (x)); | ||
484 | |||
485 | return lz; | ||
486 | } | ||
487 | |||
488 | extern void bcm1480_timer_interrupt(struct pt_regs *regs); | ||
489 | extern void bcm1480_mailbox_interrupt(struct pt_regs *regs); | ||
490 | extern void bcm1480_kgdb_interrupt(struct pt_regs *regs); | ||
491 | |||
492 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
493 | { | ||
494 | unsigned int pending; | ||
495 | |||
496 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
497 | /* Set compare to count to silence count/compare timer interrupts */ | ||
498 | write_c0_compare(read_c0_count()); | ||
499 | #endif | ||
500 | |||
501 | pending = read_c0_cause(); | ||
502 | |||
503 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
504 | if (pending & CAUSEF_IP7) /* Cpu performance counter interrupt */ | ||
505 | sbprof_cpu_intr(exception_epc(regs)); | ||
506 | #endif | ||
507 | |||
508 | if (pending & CAUSEF_IP4) | ||
509 | bcm1480_timer_interrupt(regs); | ||
510 | |||
511 | #ifdef CONFIG_SMP | ||
512 | if (pending & CAUSEF_IP3) | ||
513 | bcm1480_mailbox_interrupt(regs); | ||
514 | #endif | ||
515 | |||
516 | #ifdef CONFIG_KGDB | ||
517 | if (pending & CAUSEF_IP6) | ||
518 | bcm1480_kgdb_interrupt(regs); /* KGDB (uart 1) */ | ||
519 | #endif | ||
520 | |||
521 | if (pending & CAUSEF_IP2) { | ||
522 | unsigned long long mask_h, mask_l; | ||
523 | unsigned long base; | ||
524 | |||
525 | /* | ||
526 | * Default...we've hit an IP[2] interrupt, which means we've | ||
527 | * got to check the 1480 interrupt registers to figure out what | ||
528 | * to do. Need to detect which CPU we're on, now that | ||
529 | * smp_affinity is supported. | ||
530 | */ | ||
531 | base = A_BCM1480_IMR_MAPPER(smp_processor_id()); | ||
532 | mask_h = __raw_readq( | ||
533 | IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H)); | ||
534 | mask_l = __raw_readq( | ||
535 | IOADDR(base + R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L)); | ||
536 | |||
537 | if (!mask_h) { | ||
538 | if (mask_h ^ 1) | ||
539 | do_IRQ(63 - dclz(mask_h), regs); | ||
540 | else | ||
541 | do_IRQ(127 - dclz(mask_l), regs); | ||
542 | } | ||
543 | } | ||
544 | } | ||
diff --git a/arch/mips/sibyte/bcm1480/irq_handler.S b/arch/mips/sibyte/bcm1480/irq_handler.S deleted file mode 100644 index 408db88d050f..000000000000 --- a/arch/mips/sibyte/bcm1480/irq_handler.S +++ /dev/null | |||
@@ -1,165 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000,2001,2002,2003,2004 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * bcm1480_irq_handler() is the routine that is actually called when an | ||
21 | * interrupt occurs. It is installed as the exception vector handler in | ||
22 | * init_IRQ() in arch/mips/sibyte/bcm1480/irq.c | ||
23 | * | ||
24 | * In the handle we figure out which interrupts need handling, and use that | ||
25 | * to call the dispatcher, which will take care of actually calling | ||
26 | * registered handlers | ||
27 | * | ||
28 | * Note that we take care of all raised interrupts in one go at the handler. | ||
29 | * This is more BSDish than the Indy code, and also, IMHO, more sane. | ||
30 | */ | ||
31 | #include <linux/config.h> | ||
32 | |||
33 | #include <asm/addrspace.h> | ||
34 | #include <asm/asm.h> | ||
35 | #include <asm/mipsregs.h> | ||
36 | #include <asm/regdef.h> | ||
37 | #include <asm/stackframe.h> | ||
38 | #include <asm/sibyte/sb1250_defs.h> | ||
39 | #include <asm/sibyte/bcm1480_regs.h> | ||
40 | #include <asm/sibyte/bcm1480_int.h> | ||
41 | |||
42 | /* | ||
43 | * What a pain. We have to be really careful saving the upper 32 bits of any | ||
44 | * register across function calls if we don't want them trashed--since were | ||
45 | * running in -o32, the calling routing never saves the full 64 bits of a | ||
46 | * register across a function call. Being the interrupt handler, we're | ||
47 | * guaranteed that interrupts are disabled during this code so we don't have | ||
48 | * to worry about random interrupts blasting the high 32 bits. | ||
49 | */ | ||
50 | |||
51 | .text | ||
52 | .set push | ||
53 | .set noreorder | ||
54 | .set noat | ||
55 | .set mips64 | ||
56 | #.set mips4 | ||
57 | .align 5 | ||
58 | NESTED(bcm1480_irq_handler, PT_SIZE, sp) | ||
59 | SAVE_ALL | ||
60 | CLI | ||
61 | |||
62 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
63 | /* Set compare to count to silence count/compare timer interrupts */ | ||
64 | mfc0 t1, CP0_COUNT | ||
65 | mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */ | ||
66 | #endif | ||
67 | /* Read cause */ | ||
68 | mfc0 s0, CP0_CAUSE | ||
69 | |||
70 | #ifdef CONFIG_SIBYTE_BCM1480_PROF | ||
71 | /* Cpu performance counter interrupt is routed to IP[7] */ | ||
72 | andi t1, s0, CAUSEF_IP7 | ||
73 | beqz t1, 0f | ||
74 | srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */ | ||
75 | and t1, t1, 0x4 /* mask to get just BD bit */ | ||
76 | #ifdef CONFIG_MIPS64 | ||
77 | dmfc0 a0, CP0_EPC | ||
78 | daddu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ | ||
79 | #else | ||
80 | mfc0 a0, CP0_EPC | ||
81 | addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ | ||
82 | #endif | ||
83 | jal sbprof_cpu_intr | ||
84 | nop | ||
85 | j ret_from_irq | ||
86 | nop | ||
87 | 0: | ||
88 | #endif | ||
89 | |||
90 | /* Timer interrupt is routed to IP[4] */ | ||
91 | andi t1, s0, CAUSEF_IP4 | ||
92 | beqz t1, 1f | ||
93 | nop | ||
94 | jal bcm1480_timer_interrupt | ||
95 | move a0, sp /* Pass the registers along */ | ||
96 | j ret_from_irq | ||
97 | nop /* delay slot */ | ||
98 | 1: | ||
99 | |||
100 | #ifdef CONFIG_SMP | ||
101 | /* Mailbox interrupt is routed to IP[3] */ | ||
102 | andi t1, s0, CAUSEF_IP3 | ||
103 | beqz t1, 2f | ||
104 | nop | ||
105 | jal bcm1480_mailbox_interrupt | ||
106 | move a0, sp | ||
107 | j ret_from_irq | ||
108 | nop /* delay slot */ | ||
109 | 2: | ||
110 | #endif | ||
111 | |||
112 | #ifdef CONFIG_KGDB | ||
113 | /* KGDB (uart 1) interrupt is routed to IP[6] */ | ||
114 | andi t1, s0, CAUSEF_IP6 | ||
115 | beqz t1, 3f | ||
116 | nop /* delay slot */ | ||
117 | jal bcm1480_kgdb_interrupt | ||
118 | move a0, sp | ||
119 | j ret_from_irq | ||
120 | nop /* delay slot */ | ||
121 | 3: | ||
122 | #endif | ||
123 | |||
124 | and t1, s0, CAUSEF_IP2 | ||
125 | beqz t1, 9f | ||
126 | nop | ||
127 | |||
128 | /* | ||
129 | * Default...we've hit an IP[2] interrupt, which means we've got | ||
130 | * to check the 1480 interrupt registers to figure out what to do | ||
131 | * Need to detect which CPU we're on, now that smp_affinity is | ||
132 | * supported. | ||
133 | */ | ||
134 | PTR_LA v0, CKSEG1 + A_BCM1480_IMR_CPU0_BASE | ||
135 | #ifdef CONFIG_SMP | ||
136 | lw t1, TI_CPU($28) | ||
137 | sll t1, t1, BCM1480_IMR_REGISTER_SPACING_SHIFT | ||
138 | addu v0, v0, t1 | ||
139 | #endif | ||
140 | |||
141 | /* Read IP[2] status (get both high and low halves of status) */ | ||
142 | ld s0, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_H(v0) | ||
143 | ld s1, R_BCM1480_IMR_INTERRUPT_STATUS_BASE_L(v0) | ||
144 | |||
145 | move s2, zero /* intr number */ | ||
146 | li s3, 64 | ||
147 | |||
148 | beqz s0, 9f /* No interrupts. Return. */ | ||
149 | move a1, sp | ||
150 | |||
151 | xori s4, s0, 1 /* if s0 (_H) == 1, it's a low intr, so... */ | ||
152 | movz s2, s3, s4 /* start the intr number at 64, and */ | ||
153 | movz s0, s1, s4 /* look at the low status value. */ | ||
154 | |||
155 | dclz s1, s0 /* Find the next interrupt. */ | ||
156 | dsubu a0, zero, s1 | ||
157 | daddiu a0, a0, 63 | ||
158 | jal do_IRQ | ||
159 | daddu a0, a0, s2 | ||
160 | |||
161 | 9: j ret_from_irq | ||
162 | nop | ||
163 | |||
164 | .set pop | ||
165 | END(bcm1480_irq_handler) | ||
diff --git a/arch/mips/sibyte/sb1250/Makefile b/arch/mips/sibyte/sb1250/Makefile index a8af84697588..a2fdbd62f8ac 100644 --- a/arch/mips/sibyte/sb1250/Makefile +++ b/arch/mips/sibyte/sb1250/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y := setup.o irq.o irq_handler.o time.o | 1 | obj-y := setup.o irq.o time.o |
2 | 2 | ||
3 | obj-$(CONFIG_SMP) += smp.o | 3 | obj-$(CONFIG_SMP) += smp.o |
4 | obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o | 4 | obj-$(CONFIG_SIBYTE_TBPROF) += bcm1250_tbprof.o |
diff --git a/arch/mips/sibyte/sb1250/irq.c b/arch/mips/sibyte/sb1250/irq.c index 589537bfcc3d..0f6e54db4888 100644 --- a/arch/mips/sibyte/sb1250/irq.c +++ b/arch/mips/sibyte/sb1250/irq.c | |||
@@ -163,10 +163,6 @@ static void sb1250_set_affinity(unsigned int irq, cpumask_t mask) | |||
163 | } | 163 | } |
164 | #endif | 164 | #endif |
165 | 165 | ||
166 | |||
167 | /* Defined in arch/mips/sibyte/sb1250/irq_handler.S */ | ||
168 | extern void sb1250_irq_handler(void); | ||
169 | |||
170 | /*****************************************************************************/ | 166 | /*****************************************************************************/ |
171 | 167 | ||
172 | static unsigned int startup_sb1250_irq(unsigned int irq) | 168 | static unsigned int startup_sb1250_irq(unsigned int irq) |
@@ -379,7 +375,6 @@ void __init arch_init_irq(void) | |||
379 | #endif | 375 | #endif |
380 | /* Enable necessary IPs, disable the rest */ | 376 | /* Enable necessary IPs, disable the rest */ |
381 | change_c0_status(ST0_IM, imask); | 377 | change_c0_status(ST0_IM, imask); |
382 | set_except_vector(0, sb1250_irq_handler); | ||
383 | 378 | ||
384 | #ifdef CONFIG_KGDB | 379 | #ifdef CONFIG_KGDB |
385 | if (kgdb_flag) { | 380 | if (kgdb_flag) { |
@@ -409,7 +404,7 @@ void __init arch_init_irq(void) | |||
409 | #define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) | 404 | #define duart_out(reg, val) csr_out32(val, IOADDR(A_DUART_CHANREG(kgdb_port,reg))) |
410 | #define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) | 405 | #define duart_in(reg) csr_in32(IOADDR(A_DUART_CHANREG(kgdb_port,reg))) |
411 | 406 | ||
412 | void sb1250_kgdb_interrupt(struct pt_regs *regs) | 407 | static void sb1250_kgdb_interrupt(struct pt_regs *regs) |
413 | { | 408 | { |
414 | /* | 409 | /* |
415 | * Clear break-change status (allow some time for the remote | 410 | * Clear break-change status (allow some time for the remote |
@@ -424,3 +419,74 @@ void sb1250_kgdb_interrupt(struct pt_regs *regs) | |||
424 | } | 419 | } |
425 | 420 | ||
426 | #endif /* CONFIG_KGDB */ | 421 | #endif /* CONFIG_KGDB */ |
422 | |||
423 | static inline int dclz(unsigned long long x) | ||
424 | { | ||
425 | int lz; | ||
426 | |||
427 | __asm__ ( | ||
428 | " .set push \n" | ||
429 | " .set mips64 \n" | ||
430 | " dclz %0, %1 \n" | ||
431 | " .set pop \n" | ||
432 | : "=r" (lz) | ||
433 | : "r" (x)); | ||
434 | |||
435 | return lz; | ||
436 | } | ||
437 | |||
438 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
439 | { | ||
440 | unsigned int pending; | ||
441 | |||
442 | #ifdef CONFIG_SIBYTE_SB1250_PROF | ||
443 | /* Set compare to count to silence count/compare timer interrupts */ | ||
444 | write_c0_count(read_c0_count()); | ||
445 | #endif | ||
446 | |||
447 | /* | ||
448 | * What a pain. We have to be really careful saving the upper 32 bits | ||
449 | * of any * register across function calls if we don't want them | ||
450 | * trashed--since were running in -o32, the calling routing never saves | ||
451 | * the full 64 bits of a register across a function call. Being the | ||
452 | * interrupt handler, we're guaranteed that interrupts are disabled | ||
453 | * during this code so we don't have to worry about random interrupts | ||
454 | * blasting the high 32 bits. | ||
455 | */ | ||
456 | |||
457 | pending = read_c0_cause(); | ||
458 | |||
459 | #ifdef CONFIG_SIBYTE_SB1250_PROF | ||
460 | if (pending & CAUSEF_IP7) { /* Cpu performance counter interrupt */ | ||
461 | sbprof_cpu_intr(exception_epc(regs)); | ||
462 | } | ||
463 | #endif | ||
464 | |||
465 | if (pending & CAUSEF_IP4) | ||
466 | sb1250_timer_interrupt(regs); | ||
467 | |||
468 | #ifdef CONFIG_SMP | ||
469 | if (pending & CAUSEF_IP3) | ||
470 | sb1250_mailbox_interrupt(regs); | ||
471 | #endif | ||
472 | |||
473 | #ifdef CONFIG_KGDB | ||
474 | if (pending & CAUSEF_IP6) /* KGDB (uart 1) */ | ||
475 | sb1250_kgdb_interrupt(regs); | ||
476 | #endif | ||
477 | |||
478 | if (pending & CAUSEF_IP2) { | ||
479 | unsigned long long mask; | ||
480 | |||
481 | /* | ||
482 | * Default...we've hit an IP[2] interrupt, which means we've | ||
483 | * got to check the 1250 interrupt registers to figure out what | ||
484 | * to do. Need to detect which CPU we're on, now that | ||
485 | ~ smp_affinity is supported. | ||
486 | */ | ||
487 | mask = __raw_readq(IOADDR(A_IMR_REGISTER(smp_processor_id(), | ||
488 | R_IMR_INTERRUPT_STATUS_BASE))); | ||
489 | if (mask) | ||
490 | do_IRQ(63 - dclz(mask), regs); | ||
491 | } | ||
492 | } | ||
diff --git a/arch/mips/sibyte/sb1250/irq_handler.S b/arch/mips/sibyte/sb1250/irq_handler.S deleted file mode 100644 index 60edc8fb302b..000000000000 --- a/arch/mips/sibyte/sb1250/irq_handler.S +++ /dev/null | |||
@@ -1,147 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License | ||
6 | * as published by the Free Software Foundation; either version 2 | ||
7 | * of the License, or (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * sb1250_handle_int() is the routine that is actually called when an interrupt | ||
21 | * occurs. It is installed as the exception vector handler in arch_init_irq() | ||
22 | * in arch/mips/sibyte/sb1250/irq.c | ||
23 | * | ||
24 | * In the handle we figure out which interrupts need handling, and use that to | ||
25 | * call the dispatcher, which will take care of actually calling registered | ||
26 | * handlers | ||
27 | * | ||
28 | * Note that we take care of all raised interrupts in one go at the handler. | ||
29 | * This is more BSDish than the Indy code, and also, IMHO, more sane. | ||
30 | */ | ||
31 | #include <linux/config.h> | ||
32 | |||
33 | #include <asm/addrspace.h> | ||
34 | #include <asm/asm.h> | ||
35 | #include <asm/mipsregs.h> | ||
36 | #include <asm/regdef.h> | ||
37 | #include <asm/stackframe.h> | ||
38 | #include <asm/sibyte/sb1250_defs.h> | ||
39 | #include <asm/sibyte/sb1250_regs.h> | ||
40 | #include <asm/sibyte/sb1250_int.h> | ||
41 | |||
42 | /* | ||
43 | * What a pain. We have to be really careful saving the upper 32 bits of any | ||
44 | * register across function calls if we don't want them trashed--since were | ||
45 | * running in -o32, the calling routing never saves the full 64 bits of a | ||
46 | * register across a function call. Being the interrupt handler, we're | ||
47 | * guaranteed that interrupts are disabled during this code so we don't have | ||
48 | * to worry about random interrupts blasting the high 32 bits. | ||
49 | */ | ||
50 | |||
51 | .text | ||
52 | .set push | ||
53 | .set noreorder | ||
54 | .set noat | ||
55 | .set mips64 | ||
56 | .align 5 | ||
57 | NESTED(sb1250_irq_handler, PT_SIZE, sp) | ||
58 | SAVE_ALL | ||
59 | CLI | ||
60 | |||
61 | #ifdef CONFIG_SIBYTE_SB1250_PROF | ||
62 | /* Set compare to count to silence count/compare timer interrupts */ | ||
63 | mfc0 t1, CP0_COUNT | ||
64 | mtc0 t1, CP0_COMPARE /* pause to clear IP[7] bit of cause ? */ | ||
65 | #endif | ||
66 | /* Read cause */ | ||
67 | mfc0 s0, CP0_CAUSE | ||
68 | |||
69 | #ifdef CONFIG_SIBYTE_SB1250_PROF | ||
70 | /* Cpu performance counter interrupt is routed to IP[7] */ | ||
71 | andi t1, s0, CAUSEF_IP7 | ||
72 | beqz t1, 0f | ||
73 | srl t1, s0, (CAUSEB_BD-2) /* Shift BD bit to bit 2 */ | ||
74 | and t1, t1, 0x4 /* mask to get just BD bit */ | ||
75 | mfc0 a0, CP0_EPC | ||
76 | jal sbprof_cpu_intr | ||
77 | addu a0, a0, t1 /* a0 = EPC + (BD ? 4 : 0) */ | ||
78 | j ret_from_irq | ||
79 | nop | ||
80 | 0: | ||
81 | #endif | ||
82 | |||
83 | /* Timer interrupt is routed to IP[4] */ | ||
84 | andi t1, s0, CAUSEF_IP4 | ||
85 | beqz t1, 1f | ||
86 | nop | ||
87 | jal sb1250_timer_interrupt | ||
88 | move a0, sp /* Pass the registers along */ | ||
89 | j ret_from_irq | ||
90 | nop # delay slot | ||
91 | 1: | ||
92 | |||
93 | #ifdef CONFIG_SMP | ||
94 | /* Mailbox interrupt is routed to IP[3] */ | ||
95 | andi t1, s0, CAUSEF_IP3 | ||
96 | beqz t1, 2f | ||
97 | nop | ||
98 | jal sb1250_mailbox_interrupt | ||
99 | move a0, sp | ||
100 | j ret_from_irq | ||
101 | nop # delay slot | ||
102 | 2: | ||
103 | #endif | ||
104 | |||
105 | #ifdef CONFIG_KGDB | ||
106 | /* KGDB (uart 1) interrupt is routed to IP[6] */ | ||
107 | andi t1, s0, CAUSEF_IP6 | ||
108 | beqz t1, 1f | ||
109 | nop # delay slot | ||
110 | jal sb1250_kgdb_interrupt | ||
111 | move a0, sp | ||
112 | j ret_from_irq | ||
113 | nop # delay slot | ||
114 | 1: | ||
115 | #endif | ||
116 | |||
117 | and t1, s0, CAUSEF_IP2 | ||
118 | beqz t1, 4f | ||
119 | nop | ||
120 | |||
121 | /* | ||
122 | * Default...we've hit an IP[2] interrupt, which means we've got to | ||
123 | * check the 1250 interrupt registers to figure out what to do | ||
124 | * Need to detect which CPU we're on, now that smp_affinity is supported. | ||
125 | */ | ||
126 | PTR_LA v0, CKSEG1 + A_IMR_CPU0_BASE | ||
127 | #ifdef CONFIG_SMP | ||
128 | lw t1, TI_CPU($28) | ||
129 | sll t1, IMR_REGISTER_SPACING_SHIFT | ||
130 | addu v0, t1 | ||
131 | #endif | ||
132 | ld s0, R_IMR_INTERRUPT_STATUS_BASE(v0) /* read IP[2] status */ | ||
133 | |||
134 | beqz s0, 4f /* No interrupts. Return */ | ||
135 | move a1, sp | ||
136 | |||
137 | 3: dclz s1, s0 /* Find the next interrupt */ | ||
138 | dsubu a0, zero, s1 | ||
139 | daddiu a0, a0, 63 | ||
140 | jal do_IRQ | ||
141 | nop | ||
142 | |||
143 | 4: j ret_from_irq | ||
144 | nop | ||
145 | |||
146 | .set pop | ||
147 | END(sb1250_irq_handler) | ||
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile index 1e5676e4be86..9c7eaa5fb210 100644 --- a/arch/mips/sni/Makefile +++ b/arch/mips/sni/Makefile | |||
@@ -2,6 +2,6 @@ | |||
2 | # Makefile for the SNI specific part of the kernel | 2 | # Makefile for the SNI specific part of the kernel |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += int-handler.o irq.o pcimt_scache.o reset.o setup.o | 5 | obj-y += irq.o pcimt_scache.o reset.o setup.o |
6 | 6 | ||
7 | EXTRA_AFLAGS := $(CFLAGS) | 7 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/sni/int-handler.S b/arch/mips/sni/int-handler.S deleted file mode 100644 index 2cdc09f55f18..000000000000 --- a/arch/mips/sni/int-handler.S +++ /dev/null | |||
@@ -1,106 +0,0 @@ | |||
1 | /* | ||
2 | * SNI RM200 PCI specific interrupt handler code. | ||
3 | * | ||
4 | * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle | ||
5 | */ | ||
6 | #include <asm/asm.h> | ||
7 | #include <asm/mipsregs.h> | ||
8 | #include <asm/regdef.h> | ||
9 | #include <asm/sni.h> | ||
10 | #include <asm/stackframe.h> | ||
11 | |||
12 | /* | ||
13 | * The PCI ASIC has the nasty property that it may delay writes if it is busy. | ||
14 | * As a consequence from writes that have not graduated when we exit from the | ||
15 | * interrupt handler we might catch a spurious interrupt. To avoid this we | ||
16 | * force the PCI ASIC to graduate all writes by executing a read from the | ||
17 | * PCI bus. | ||
18 | */ | ||
19 | .set noreorder | ||
20 | .set noat | ||
21 | .align 5 | ||
22 | NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp) | ||
23 | SAVE_ALL | ||
24 | CLI | ||
25 | .set at | ||
26 | |||
27 | /* Blinken light ... */ | ||
28 | lb t0, led_cache | ||
29 | addiu t0, 1 | ||
30 | sb t0, led_cache | ||
31 | sb t0, PCIMT_CSLED # write only register | ||
32 | .data | ||
33 | led_cache: .byte 0 | ||
34 | .text | ||
35 | |||
36 | mfc0 t0, CP0_STATUS | ||
37 | mfc0 t1, CP0_CAUSE | ||
38 | and t0, t1 | ||
39 | |||
40 | andi t1, t0, 0x0800 # hardware interrupt 1 | ||
41 | bnez t1, _hwint1 | ||
42 | andi t1, t0, 0x4000 # hardware interrupt 4 | ||
43 | bnez t1, _hwint4 | ||
44 | andi t1, t0, 0x2000 # hardware interrupt 3 | ||
45 | bnez t1, _hwint3 | ||
46 | andi t1, t0, 0x1000 # hardware interrupt 2 | ||
47 | bnez t1, _hwint2 | ||
48 | andi t1, t0, 0x8000 # hardware interrupt 5 | ||
49 | bnez t1, _hwint5 | ||
50 | andi t1, t0, 0x0400 # hardware interrupt 0 | ||
51 | bnez t1, _hwint0 | ||
52 | nop | ||
53 | |||
54 | j restore_all # spurious interrupt | ||
55 | nop | ||
56 | |||
57 | ############################################################################## | ||
58 | |||
59 | /* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug | ||
60 | button interrupts. */ | ||
61 | _hwint0: jal pciasic_hwint0 | ||
62 | move a0, sp | ||
63 | j ret_from_irq | ||
64 | nop | ||
65 | |||
66 | /* | ||
67 | * hwint 1 deals with EISA and SCSI interrupts | ||
68 | */ | ||
69 | _hwint1: jal pciasic_hwint1 | ||
70 | move a0, sp | ||
71 | j ret_from_irq | ||
72 | nop | ||
73 | |||
74 | |||
75 | /* | ||
76 | * This interrupt was used for the com1 console on the first prototypes; | ||
77 | * it's unsed otherwise | ||
78 | */ | ||
79 | _hwint2: jal pciasic_hwint2 | ||
80 | move a0, sp | ||
81 | j ret_from_irq | ||
82 | nop | ||
83 | |||
84 | /* | ||
85 | * hwint 3 are the PCI interrupts A - D | ||
86 | */ | ||
87 | _hwint3: jal pciasic_hwint3 | ||
88 | move a0, sp | ||
89 | j ret_from_irq | ||
90 | nop | ||
91 | |||
92 | /* | ||
93 | * hwint 4 is used for only the onboard PCnet 32. | ||
94 | */ | ||
95 | _hwint4: jal pciasic_hwint4 | ||
96 | move a0, sp | ||
97 | j ret_from_irq | ||
98 | nop | ||
99 | |||
100 | /* hwint5 is the r4k count / compare interrupt */ | ||
101 | _hwint5: jal pciasic_hwint5 | ||
102 | move a0, sp | ||
103 | j ret_from_irq | ||
104 | nop | ||
105 | |||
106 | END(sni_rm200_pci_handle_int) | ||
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c index 952038aa4b90..7365b4853ddb 100644 --- a/arch/mips/sni/irq.c +++ b/arch/mips/sni/irq.c | |||
@@ -19,8 +19,6 @@ | |||
19 | 19 | ||
20 | DEFINE_SPINLOCK(pciasic_lock); | 20 | DEFINE_SPINLOCK(pciasic_lock); |
21 | 21 | ||
22 | extern asmlinkage void sni_rm200_pci_handle_int(void); | ||
23 | |||
24 | static void enable_pciasic_irq(unsigned int irq) | 22 | static void enable_pciasic_irq(unsigned int irq) |
25 | { | 23 | { |
26 | unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); | 24 | unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); |
@@ -71,20 +69,20 @@ static struct hw_interrupt_type pciasic_irq_type = { | |||
71 | * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug | 69 | * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug |
72 | * button interrupts. Later ... | 70 | * button interrupts. Later ... |
73 | */ | 71 | */ |
74 | void pciasic_hwint0(struct pt_regs *regs) | 72 | static void pciasic_hwint0(struct pt_regs *regs) |
75 | { | 73 | { |
76 | panic("Received int0 but no handler yet ..."); | 74 | panic("Received int0 but no handler yet ..."); |
77 | } | 75 | } |
78 | 76 | ||
79 | /* This interrupt was used for the com1 console on the first prototypes. */ | 77 | /* This interrupt was used for the com1 console on the first prototypes. */ |
80 | void pciasic_hwint2(struct pt_regs *regs) | 78 | static void pciasic_hwint2(struct pt_regs *regs) |
81 | { | 79 | { |
82 | /* I think this shouldn't happen on production machines. */ | 80 | /* I think this shouldn't happen on production machines. */ |
83 | panic("hwint2 and no handler yet"); | 81 | panic("hwint2 and no handler yet"); |
84 | } | 82 | } |
85 | 83 | ||
86 | /* hwint5 is the r4k count / compare interrupt */ | 84 | /* hwint5 is the r4k count / compare interrupt */ |
87 | void pciasic_hwint5(struct pt_regs *regs) | 85 | static void pciasic_hwint5(struct pt_regs *regs) |
88 | { | 86 | { |
89 | panic("hwint5 and no handler yet"); | 87 | panic("hwint5 and no handler yet"); |
90 | } | 88 | } |
@@ -105,7 +103,7 @@ static unsigned int ls1bit8(unsigned int x) | |||
105 | * | 103 | * |
106 | * The EISA_INT bit in CSITPEND is high active, all others are low active. | 104 | * The EISA_INT bit in CSITPEND is high active, all others are low active. |
107 | */ | 105 | */ |
108 | void pciasic_hwint1(struct pt_regs *regs) | 106 | static void pciasic_hwint1(struct pt_regs *regs) |
109 | { | 107 | { |
110 | u8 pend = *(volatile char *)PCIMT_CSITPEND; | 108 | u8 pend = *(volatile char *)PCIMT_CSITPEND; |
111 | unsigned long flags; | 109 | unsigned long flags; |
@@ -135,7 +133,7 @@ void pciasic_hwint1(struct pt_regs *regs) | |||
135 | /* | 133 | /* |
136 | * hwint 3 should deal with the PCI A - D interrupts, | 134 | * hwint 3 should deal with the PCI A - D interrupts, |
137 | */ | 135 | */ |
138 | void pciasic_hwint3(struct pt_regs *regs) | 136 | static void pciasic_hwint3(struct pt_regs *regs) |
139 | { | 137 | { |
140 | u8 pend = *(volatile char *)PCIMT_CSITPEND; | 138 | u8 pend = *(volatile char *)PCIMT_CSITPEND; |
141 | int irq; | 139 | int irq; |
@@ -150,13 +148,34 @@ void pciasic_hwint3(struct pt_regs *regs) | |||
150 | /* | 148 | /* |
151 | * hwint 4 is used for only the onboard PCnet 32. | 149 | * hwint 4 is used for only the onboard PCnet 32. |
152 | */ | 150 | */ |
153 | void pciasic_hwint4(struct pt_regs *regs) | 151 | static void pciasic_hwint4(struct pt_regs *regs) |
154 | { | 152 | { |
155 | clear_c0_status(IE_IRQ4); | 153 | clear_c0_status(IE_IRQ4); |
156 | do_IRQ(PCIMT_IRQ_ETHERNET, regs); | 154 | do_IRQ(PCIMT_IRQ_ETHERNET, regs); |
157 | set_c0_status(IE_IRQ4); | 155 | set_c0_status(IE_IRQ4); |
158 | } | 156 | } |
159 | 157 | ||
158 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
159 | { | ||
160 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
161 | static unsigned char led_cache; | ||
162 | |||
163 | *(volatile unsigned char *) PCIMT_CSLED = ++led_cache; | ||
164 | |||
165 | if (pending & 0x0800) | ||
166 | pciasic_hwint1(regs); | ||
167 | else if (pending & 0x4000) | ||
168 | pciasic_hwint4(regs); | ||
169 | else if (pending & 0x2000) | ||
170 | pciasic_hwint3(regs); | ||
171 | else if (pending & 0x1000) | ||
172 | pciasic_hwint2(regs); | ||
173 | else if (pending & 0x8000) | ||
174 | pciasic_hwint5(regs); | ||
175 | else if (pending & 0x0400) | ||
176 | pciasic_hwint0(regs); | ||
177 | } | ||
178 | |||
160 | void __init init_pciasic(void) | 179 | void __init init_pciasic(void) |
161 | { | 180 | { |
162 | unsigned long flags; | 181 | unsigned long flags; |
@@ -176,8 +195,6 @@ void __init arch_init_irq(void) | |||
176 | { | 195 | { |
177 | int i; | 196 | int i; |
178 | 197 | ||
179 | set_except_vector(0, sni_rm200_pci_handle_int); | ||
180 | |||
181 | init_i8259_irqs(); /* Integrated i8259 */ | 198 | init_i8259_irqs(); /* Integrated i8259 */ |
182 | init_pciasic(); | 199 | init_pciasic(); |
183 | 200 | ||
diff --git a/arch/mips/tx4927/common/Makefile b/arch/mips/tx4927/common/Makefile index 8fa126b296e1..9cb9535ebacb 100644 --- a/arch/mips/tx4927/common/Makefile +++ b/arch/mips/tx4927/common/Makefile | |||
@@ -6,7 +6,7 @@ | |||
6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o tx4927_irq_handler.o | 9 | obj-y += tx4927_prom.o tx4927_setup.o tx4927_irq.o |
10 | 10 | ||
11 | obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o | 11 | obj-$(CONFIG_TOSHIBA_FPCIB0) += smsc_fdc37m81x.o |
12 | obj-$(CONFIG_KGDB) += tx4927_dbgio.o | 12 | obj-$(CONFIG_KGDB) += tx4927_dbgio.o |
diff --git a/arch/mips/tx4927/common/tx4927_irq.c b/arch/mips/tx4927/common/tx4927_irq.c index 5ab2e2b76018..8ca68015cf40 100644 --- a/arch/mips/tx4927/common/tx4927_irq.c +++ b/arch/mips/tx4927/common/tx4927_irq.c | |||
@@ -525,8 +525,6 @@ static void tx4927_irq_pic_end(unsigned int irq) | |||
525 | */ | 525 | */ |
526 | void __init tx4927_irq_init(void) | 526 | void __init tx4927_irq_init(void) |
527 | { | 527 | { |
528 | extern asmlinkage void tx4927_irq_handler(void); | ||
529 | |||
530 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); | 528 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "-\n"); |
531 | 529 | ||
532 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); | 530 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_cp0_init()\n"); |
@@ -535,16 +533,12 @@ void __init tx4927_irq_init(void) | |||
535 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); | 533 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "=Calling tx4927_irq_pic_init()\n"); |
536 | tx4927_irq_pic_init(); | 534 | tx4927_irq_pic_init(); |
537 | 535 | ||
538 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, | ||
539 | "=Calling set_except_vector(tx4927_irq_handler)\n"); | ||
540 | set_except_vector(0, tx4927_irq_handler); | ||
541 | |||
542 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); | 536 | TX4927_IRQ_DPRINTK(TX4927_IRQ_INIT, "+\n"); |
543 | 537 | ||
544 | return; | 538 | return; |
545 | } | 539 | } |
546 | 540 | ||
547 | int tx4927_irq_nested(void) | 541 | static int tx4927_irq_nested(void) |
548 | { | 542 | { |
549 | int sw_irq = 0; | 543 | int sw_irq = 0; |
550 | u32 level2; | 544 | u32 level2; |
@@ -582,3 +576,25 @@ int tx4927_irq_nested(void) | |||
582 | 576 | ||
583 | return (sw_irq); | 577 | return (sw_irq); |
584 | } | 578 | } |
579 | |||
580 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
581 | { | ||
582 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
583 | |||
584 | if (pending & STATUSF_IP7) /* cpu timer */ | ||
585 | do_IRQ(TX4927_IRQ_CPU_TIMER, regs); | ||
586 | else if (pending & STATUSF_IP2) { /* tx4927 pic */ | ||
587 | unsigned int irq = tx4927_irq_nested(); | ||
588 | |||
589 | if (unlikely(irq == 0)) { | ||
590 | spurious_interrupt(regs); | ||
591 | return; | ||
592 | } | ||
593 | do_IRQ(irq, regs); | ||
594 | } else if (pending & STATUSF_IP0) /* user line 0 */ | ||
595 | do_IRQ(TX4927_IRQ_USER0, regs); | ||
596 | else if (pending & STATUSF_IP1) /* user line 1 */ | ||
597 | do_IRQ(TX4927_IRQ_USER1, regs); | ||
598 | else | ||
599 | spurious_interrupt(regs); | ||
600 | } | ||
diff --git a/arch/mips/tx4927/common/tx4927_irq_handler.S b/arch/mips/tx4927/common/tx4927_irq_handler.S deleted file mode 100644 index dd3ceda9d712..000000000000 --- a/arch/mips/tx4927/common/tx4927_irq_handler.S +++ /dev/null | |||
@@ -1,103 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/mips/tx4927/common/tx4927_irq_handler.S | ||
3 | * | ||
4 | * Primary interrupt handler for tx4927 based systems | ||
5 | * | ||
6 | * Author: MontaVista Software, Inc. | ||
7 | * Author: jsun@mvista.com or jsun@junsun.net | ||
8 | * source@mvista.com | ||
9 | * | ||
10 | * Copyright 2001-2002 MontaVista Software Inc. | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify it | ||
13 | * under the terms of the GNU General Public License as published by the | ||
14 | * Free Software Foundation; either version 2 of the License, or (at your | ||
15 | * option) any later version. | ||
16 | * | ||
17 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
18 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
19 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
22 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | ||
23 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
24 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | ||
25 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
26 | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
27 | * | ||
28 | * You should have received a copy of the GNU General Public License along | ||
29 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
30 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
31 | */ | ||
32 | #include <asm/asm.h> | ||
33 | #include <asm/mipsregs.h> | ||
34 | #include <asm/addrspace.h> | ||
35 | #include <asm/regdef.h> | ||
36 | #include <asm/stackframe.h> | ||
37 | #include <asm/tx4927/tx4927.h> | ||
38 | |||
39 | .align 5 | ||
40 | NESTED(tx4927_irq_handler, PT_SIZE, sp) | ||
41 | SAVE_ALL | ||
42 | CLI | ||
43 | .set at | ||
44 | |||
45 | mfc0 t0, CP0_CAUSE | ||
46 | mfc0 t1, CP0_STATUS | ||
47 | and t0, t1 | ||
48 | |||
49 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
50 | bnez t1, ll_ip7 | ||
51 | |||
52 | /* IP6..IP3 multiplexed -- do not use */ | ||
53 | |||
54 | andi t1, t0, STATUSF_IP2 /* tx4927 pic */ | ||
55 | bnez t1, ll_ip2 | ||
56 | |||
57 | andi t1, t0, STATUSF_IP0 /* user line 0 */ | ||
58 | bnez t1, ll_ip0 | ||
59 | |||
60 | andi t1, t0, STATUSF_IP1 /* user line 1 */ | ||
61 | bnez t1, ll_ip1 | ||
62 | |||
63 | .set reorder | ||
64 | |||
65 | /* wrong alarm or masked ... */ | ||
66 | j spurious_interrupt | ||
67 | nop | ||
68 | END(tx4927_irq_handler) | ||
69 | |||
70 | .align 5 | ||
71 | |||
72 | |||
73 | ll_ip7: | ||
74 | li a0, TX4927_IRQ_CPU_TIMER | ||
75 | move a1, sp | ||
76 | jal do_IRQ | ||
77 | j ret_from_irq | ||
78 | |||
79 | ll_ip2: | ||
80 | jal tx4927_irq_nested | ||
81 | nop | ||
82 | beqz v0, goto_spurious_interrupt | ||
83 | nop | ||
84 | move a0, v0 | ||
85 | move a1, sp | ||
86 | jal do_IRQ | ||
87 | j ret_from_irq | ||
88 | |||
89 | goto_spurious_interrupt: | ||
90 | j spurious_interrupt | ||
91 | nop | ||
92 | |||
93 | ll_ip1: | ||
94 | li a0, TX4927_IRQ_USER1 | ||
95 | move a1, sp | ||
96 | jal do_IRQ | ||
97 | j ret_from_irq | ||
98 | |||
99 | ll_ip0: | ||
100 | li a0, TX4927_IRQ_USER0 | ||
101 | move a1, sp | ||
102 | jal do_IRQ | ||
103 | j ret_from_irq | ||
diff --git a/arch/mips/tx4938/common/Makefile b/arch/mips/tx4938/common/Makefile index 74c95c5bcdbf..2033ae77f632 100644 --- a/arch/mips/tx4938/common/Makefile +++ b/arch/mips/tx4938/common/Makefile | |||
@@ -6,6 +6,6 @@ | |||
6 | # unless it's something special (ie not a .c file). | 6 | # unless it's something special (ie not a .c file). |
7 | # | 7 | # |
8 | 8 | ||
9 | obj-y += prom.o setup.o irq.o irq_handler.o rtc_rx5c348.o | 9 | obj-y += prom.o setup.o irq.o rtc_rx5c348.o |
10 | obj-$(CONFIG_KGDB) += dbgio.o | 10 | obj-$(CONFIG_KGDB) += dbgio.o |
11 | 11 | ||
diff --git a/arch/mips/tx4938/common/irq.c b/arch/mips/tx4938/common/irq.c index 4f90d7faf634..873805178d8e 100644 --- a/arch/mips/tx4938/common/irq.c +++ b/arch/mips/tx4938/common/irq.c | |||
@@ -392,11 +392,8 @@ tx4938_irq_pic_end(unsigned int irq) | |||
392 | void __init | 392 | void __init |
393 | tx4938_irq_init(void) | 393 | tx4938_irq_init(void) |
394 | { | 394 | { |
395 | extern asmlinkage void tx4938_irq_handler(void); | ||
396 | |||
397 | tx4938_irq_cp0_init(); | 395 | tx4938_irq_cp0_init(); |
398 | tx4938_irq_pic_init(); | 396 | tx4938_irq_pic_init(); |
399 | set_except_vector(0, tx4938_irq_handler); | ||
400 | 397 | ||
401 | return; | 398 | return; |
402 | } | 399 | } |
@@ -422,3 +419,21 @@ tx4938_irq_nested(void) | |||
422 | wbflush(); | 419 | wbflush(); |
423 | return (sw_irq); | 420 | return (sw_irq); |
424 | } | 421 | } |
422 | |||
423 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) | ||
424 | { | ||
425 | unsigned int pending = read_c0_cause() & read_c0_status(); | ||
426 | |||
427 | if (pending & STATUSF_IP7) | ||
428 | do_IRQ(TX4938_IRQ_CPU_TIMER, regs); | ||
429 | else if (pending & STATUSF_IP2) { | ||
430 | int irq = tx4938_irq_nested(); | ||
431 | if (irq) | ||
432 | do_IRQ(irq, regs); | ||
433 | else | ||
434 | spurious_interrupt(regs); | ||
435 | } else if (pending & STATUSF_IP1) | ||
436 | do_IRQ(TX4938_IRQ_USER1, regs); | ||
437 | else if (pending & STATUSF_IP0) | ||
438 | do_IRQ(TX4938_IRQ_USER0, regs); | ||
439 | } | ||
diff --git a/arch/mips/tx4938/common/irq_handler.S b/arch/mips/tx4938/common/irq_handler.S deleted file mode 100644 index 1b2f72bac42d..000000000000 --- a/arch/mips/tx4938/common/irq_handler.S +++ /dev/null | |||
@@ -1,84 +0,0 @@ | |||
1 | /* | ||
2 | * linux/arch/mips/tx4938/common/handler.S | ||
3 | * | ||
4 | * Primary interrupt handler for tx4938 based systems | ||
5 | * Copyright (C) 2000-2001 Toshiba Corporation | ||
6 | * | ||
7 | * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the | ||
8 | * terms of the GNU General Public License version 2. This program is | ||
9 | * licensed "as is" without any warranty of any kind, whether express | ||
10 | * or implied. | ||
11 | * | ||
12 | * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) | ||
13 | */ | ||
14 | #include <asm/asm.h> | ||
15 | #include <asm/mipsregs.h> | ||
16 | #include <asm/addrspace.h> | ||
17 | #include <asm/regdef.h> | ||
18 | #include <asm/stackframe.h> | ||
19 | #include <asm/tx4938/rbtx4938.h> | ||
20 | |||
21 | |||
22 | .align 5 | ||
23 | NESTED(tx4938_irq_handler, PT_SIZE, sp) | ||
24 | SAVE_ALL | ||
25 | CLI | ||
26 | .set at | ||
27 | |||
28 | mfc0 t0, CP0_CAUSE | ||
29 | mfc0 t1, CP0_STATUS | ||
30 | and t0, t1 | ||
31 | |||
32 | andi t1, t0, STATUSF_IP7 /* cpu timer */ | ||
33 | bnez t1, ll_ip7 | ||
34 | |||
35 | /* IP6..IP3 multiplexed -- do not use */ | ||
36 | |||
37 | andi t1, t0, STATUSF_IP2 /* tx4938 pic */ | ||
38 | bnez t1, ll_ip2 | ||
39 | |||
40 | andi t1, t0, STATUSF_IP1 /* user line 1 */ | ||
41 | bnez t1, ll_ip1 | ||
42 | |||
43 | andi t1, t0, STATUSF_IP0 /* user line 0 */ | ||
44 | bnez t1, ll_ip0 | ||
45 | |||
46 | .set reorder | ||
47 | |||
48 | nop | ||
49 | END(tx4938_irq_handler) | ||
50 | |||
51 | .align 5 | ||
52 | |||
53 | |||
54 | ll_ip7: | ||
55 | li a0, TX4938_IRQ_CPU_TIMER | ||
56 | move a1, sp | ||
57 | jal do_IRQ | ||
58 | j ret_from_irq | ||
59 | |||
60 | |||
61 | ll_ip2: | ||
62 | jal tx4938_irq_nested | ||
63 | nop | ||
64 | beqz v0, goto_spurious_interrupt | ||
65 | nop | ||
66 | move a0, v0 | ||
67 | move a1, sp | ||
68 | jal do_IRQ | ||
69 | j ret_from_irq | ||
70 | |||
71 | goto_spurious_interrupt: | ||
72 | j ret_from_irq | ||
73 | |||
74 | ll_ip1: | ||
75 | li a0, TX4938_IRQ_USER1 | ||
76 | move a1, sp | ||
77 | jal do_IRQ | ||
78 | j ret_from_irq | ||
79 | |||
80 | ll_ip0: | ||
81 | li a0, TX4938_IRQ_USER0 | ||
82 | move a1, sp | ||
83 | jal do_IRQ | ||
84 | j ret_from_irq | ||
diff --git a/arch/mips/vr41xx/Kconfig b/arch/mips/vr41xx/Kconfig index a7add16c9aa4..055a2cdfc841 100644 --- a/arch/mips/vr41xx/Kconfig +++ b/arch/mips/vr41xx/Kconfig | |||
@@ -4,6 +4,8 @@ config CASIO_E55 | |||
4 | select DMA_NONCOHERENT | 4 | select DMA_NONCOHERENT |
5 | select IRQ_CPU | 5 | select IRQ_CPU |
6 | select ISA | 6 | select ISA |
7 | select SYS_HAS_CPU_VR41XX | ||
8 | select SYS_SUPPORTS_32BIT_KERNEL | ||
7 | select SYS_SUPPORTS_LITTLE_ENDIAN | 9 | select SYS_SUPPORTS_LITTLE_ENDIAN |
8 | 10 | ||
9 | config IBM_WORKPAD | 11 | config IBM_WORKPAD |
@@ -12,6 +14,8 @@ config IBM_WORKPAD | |||
12 | select DMA_NONCOHERENT | 14 | select DMA_NONCOHERENT |
13 | select IRQ_CPU | 15 | select IRQ_CPU |
14 | select ISA | 16 | select ISA |
17 | select SYS_HAS_CPU_VR41XX | ||
18 | select SYS_SUPPORTS_32BIT_KERNEL | ||
15 | select SYS_SUPPORTS_LITTLE_ENDIAN | 19 | select SYS_SUPPORTS_LITTLE_ENDIAN |
16 | 20 | ||
17 | config NEC_CMBVR4133 | 21 | config NEC_CMBVR4133 |
@@ -21,6 +25,9 @@ config NEC_CMBVR4133 | |||
21 | select DMA_NONCOHERENT | 25 | select DMA_NONCOHERENT |
22 | select IRQ_CPU | 26 | select IRQ_CPU |
23 | select HW_HAS_PCI | 27 | select HW_HAS_PCI |
28 | select SYS_HAS_CPU_VR41XX | ||
29 | select SYS_SUPPORTS_32BIT_KERNEL | ||
30 | select SYS_SUPPORTS_LITTLE_ENDIAN | ||
24 | 31 | ||
25 | config ROCKHOPPER | 32 | config ROCKHOPPER |
26 | bool "Support for Rockhopper baseboard" | 33 | bool "Support for Rockhopper baseboard" |
@@ -34,6 +41,8 @@ config TANBAC_TB022X | |||
34 | select DMA_NONCOHERENT | 41 | select DMA_NONCOHERENT |
35 | select HW_HAS_PCI | 42 | select HW_HAS_PCI |
36 | select IRQ_CPU | 43 | select IRQ_CPU |
44 | select SYS_HAS_CPU_VR41XX | ||
45 | select SYS_SUPPORTS_32BIT_KERNEL | ||
37 | select SYS_SUPPORTS_LITTLE_ENDIAN | 46 | select SYS_SUPPORTS_LITTLE_ENDIAN |
38 | help | 47 | help |
39 | The TANBAC VR4131 multichip module(TB0225) and | 48 | The TANBAC VR4131 multichip module(TB0225) and |
@@ -65,6 +74,8 @@ config VICTOR_MPC30X | |||
65 | select DMA_NONCOHERENT | 74 | select DMA_NONCOHERENT |
66 | select HW_HAS_PCI | 75 | select HW_HAS_PCI |
67 | select IRQ_CPU | 76 | select IRQ_CPU |
77 | select SYS_HAS_CPU_VR41XX | ||
78 | select SYS_SUPPORTS_32BIT_KERNEL | ||
68 | select SYS_SUPPORTS_LITTLE_ENDIAN | 79 | select SYS_SUPPORTS_LITTLE_ENDIAN |
69 | 80 | ||
70 | config ZAO_CAPCELLA | 81 | config ZAO_CAPCELLA |
@@ -73,6 +84,8 @@ config ZAO_CAPCELLA | |||
73 | select DMA_NONCOHERENT | 84 | select DMA_NONCOHERENT |
74 | select HW_HAS_PCI | 85 | select HW_HAS_PCI |
75 | select IRQ_CPU | 86 | select IRQ_CPU |
87 | select SYS_HAS_CPU_VR41XX | ||
88 | select SYS_SUPPORTS_32BIT_KERNEL | ||
76 | select SYS_SUPPORTS_LITTLE_ENDIAN | 89 | select SYS_SUPPORTS_LITTLE_ENDIAN |
77 | 90 | ||
78 | config PCI_VR41XX | 91 | config PCI_VR41XX |
diff --git a/arch/mips/vr41xx/common/Makefile b/arch/mips/vr41xx/common/Makefile index 9096302a7ecc..aa373974c80f 100644 --- a/arch/mips/vr41xx/common/Makefile +++ b/arch/mips/vr41xx/common/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | # Makefile for common code of the NEC VR4100 series. | 2 | # Makefile for common code of the NEC VR4100 series. |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-y += bcu.o cmu.o icu.o init.o int-handler.o irq.o pmu.o type.o | 5 | obj-y += bcu.o cmu.o icu.o init.o irq.o pmu.o type.o |
6 | obj-$(CONFIG_VRC4173) += vrc4173.o | 6 | obj-$(CONFIG_VRC4173) += vrc4173.o |
7 | 7 | ||
8 | EXTRA_AFLAGS := $(CFLAGS) | 8 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/vr41xx/common/int-handler.S b/arch/mips/vr41xx/common/int-handler.S deleted file mode 100644 index 2b6043f16d09..000000000000 --- a/arch/mips/vr41xx/common/int-handler.S +++ /dev/null | |||
@@ -1,114 +0,0 @@ | |||
1 | /* | ||
2 | * FILE NAME | ||
3 | * arch/mips/vr41xx/common/int-handler.S | ||
4 | * | ||
5 | * BRIEF MODULE DESCRIPTION | ||
6 | * Interrupt dispatcher for the NEC VR4100 series. | ||
7 | * | ||
8 | * Author: Yoichi Yuasa | ||
9 | * yyuasa@mvista.com or source@mvista.com | ||
10 | * | ||
11 | * Copyright 2001 MontaVista Software Inc. | ||
12 | * | ||
13 | * This program is free software; you can redistribute it and/or modify it | ||
14 | * under the terms of the GNU General Public License as published by the | ||
15 | * Free Software Foundation; either version 2 of the License, or (at your | ||
16 | * option) any later version. | ||
17 | * | ||
18 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
19 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
20 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | ||
21 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
22 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | ||
23 | * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | ||
24 | * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
25 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR | ||
26 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE | ||
27 | * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
28 | * | ||
29 | * You should have received a copy of the GNU General Public License along | ||
30 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
31 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
32 | */ | ||
33 | /* | ||
34 | * Changes: | ||
35 | * MontaVista Software Inc. <yyuasa@mvista.com> or <source@mvista.com> | ||
36 | * - New creation, NEC VR4100 series are supported. | ||
37 | * | ||
38 | * Yoichi Yuasa <yoichi_yuasa@tripeaks.co.jp> | ||
39 | * - Coped with INTASSIGN of NEC VR4133. | ||
40 | */ | ||
41 | #include <asm/asm.h> | ||
42 | #include <asm/regdef.h> | ||
43 | #include <asm/mipsregs.h> | ||
44 | #include <asm/stackframe.h> | ||
45 | |||
46 | .text | ||
47 | .set noreorder | ||
48 | |||
49 | .align 5 | ||
50 | NESTED(vr41xx_handle_interrupt, PT_SIZE, ra) | ||
51 | .set noat | ||
52 | SAVE_ALL | ||
53 | CLI | ||
54 | .set at | ||
55 | .set noreorder | ||
56 | |||
57 | /* | ||
58 | * Get the pending interrupts | ||
59 | */ | ||
60 | mfc0 t0, CP0_CAUSE | ||
61 | mfc0 t1, CP0_STATUS | ||
62 | andi t0, 0xff00 | ||
63 | and t0, t0, t1 | ||
64 | |||
65 | andi t1, t0, CAUSEF_IP7 # MIPS timer interrupt | ||
66 | bnez t1, handle_irq | ||
67 | li a0, 7 | ||
68 | |||
69 | andi t1, t0, 0x7800 # check for Int1-4 | ||
70 | beqz t1, 1f | ||
71 | |||
72 | andi t1, t0, CAUSEF_IP3 # check for Int1 | ||
73 | bnez t1, handle_int | ||
74 | li a0, 3 | ||
75 | |||
76 | andi t1, t0, CAUSEF_IP4 # check for Int2 | ||
77 | bnez t1, handle_int | ||
78 | li a0, 4 | ||
79 | |||
80 | andi t1, t0, CAUSEF_IP5 # check for Int3 | ||
81 | bnez t1, handle_int | ||
82 | li a0, 5 | ||
83 | |||
84 | andi t1, t0, CAUSEF_IP6 # check for Int4 | ||
85 | bnez t1, handle_int | ||
86 | li a0, 6 | ||
87 | |||
88 | 1: | ||
89 | andi t1, t0, CAUSEF_IP2 # check for Int0 | ||
90 | bnez t1, handle_int | ||
91 | li a0, 2 | ||
92 | |||
93 | andi t1, t0, CAUSEF_IP0 # check for IP0 | ||
94 | bnez t1, handle_irq | ||
95 | li a0, 0 | ||
96 | |||
97 | andi t1, t0, CAUSEF_IP1 # check for IP1 | ||
98 | bnez t1, handle_irq | ||
99 | li a0, 1 | ||
100 | |||
101 | j spurious_interrupt | ||
102 | nop | ||
103 | |||
104 | handle_int: | ||
105 | jal irq_dispatch | ||
106 | move a1, sp | ||
107 | j ret_from_irq | ||
108 | nop | ||
109 | |||
110 | handle_irq: | ||
111 | jal do_IRQ | ||
112 | move a1, sp | ||
113 | j ret_from_irq | ||
114 | END(vr41xx_handle_interrupt) | ||
diff --git a/arch/mips/vr41xx/common/irq.c b/arch/mips/vr41xx/common/irq.c index 61aa264275ff..86796bb63c3c 100644 --- a/arch/mips/vr41xx/common/irq.c +++ b/arch/mips/vr41xx/common/irq.c | |||
@@ -59,7 +59,7 @@ int cascade_irq(unsigned int irq, int (*get_irq)(unsigned int, struct pt_regs *) | |||
59 | 59 | ||
60 | EXPORT_SYMBOL_GPL(cascade_irq); | 60 | EXPORT_SYMBOL_GPL(cascade_irq); |
61 | 61 | ||
62 | asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs) | 62 | static void irq_dispatch(unsigned int irq, struct pt_regs *regs) |
63 | { | 63 | { |
64 | irq_cascade_t *cascade; | 64 | irq_cascade_t *cascade; |
65 | irq_desc_t *desc; | 65 | irq_desc_t *desc; |
@@ -84,11 +84,32 @@ asmlinkage void irq_dispatch(unsigned int irq, struct pt_regs *regs) | |||
84 | do_IRQ(irq, regs); | 84 | do_IRQ(irq, regs); |
85 | } | 85 | } |
86 | 86 | ||
87 | extern asmlinkage void vr41xx_handle_interrupt(void); | 87 | asmlinkage void plat_irq_dispatch(struct pt_regs *regs) |
88 | { | ||
89 | unsigned int pending = read_c0_cause() & read_c0_status() & ST0_IM; | ||
90 | |||
91 | if (pending & CAUSEF_IP7) | ||
92 | do_IRQ(7, regs); | ||
93 | else if (pending & 0x7800) { | ||
94 | if (pending & CAUSEF_IP3) | ||
95 | irq_dispatch(3, regs); | ||
96 | else if (pending & CAUSEF_IP4) | ||
97 | irq_dispatch(4, regs); | ||
98 | else if (pending & CAUSEF_IP5) | ||
99 | irq_dispatch(5, regs); | ||
100 | else if (pending & CAUSEF_IP6) | ||
101 | irq_dispatch(6, regs); | ||
102 | } else if (pending & CAUSEF_IP2) | ||
103 | irq_dispatch(2, regs); | ||
104 | else if (pending & CAUSEF_IP0) | ||
105 | do_IRQ(0, regs); | ||
106 | else if (pending & CAUSEF_IP1) | ||
107 | do_IRQ(1, regs); | ||
108 | else | ||
109 | spurious_interrupt(regs); | ||
110 | } | ||
88 | 111 | ||
89 | void __init arch_init_irq(void) | 112 | void __init arch_init_irq(void) |
90 | { | 113 | { |
91 | mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); | 114 | mips_cpu_irq_init(MIPS_CPU_IRQ_BASE); |
92 | |||
93 | set_except_vector(0, vr41xx_handle_interrupt); | ||
94 | } | 115 | } |
diff --git a/arch/parisc/Kconfig b/arch/parisc/Kconfig index 19f911c5dd58..910fb3afc0b5 100644 --- a/arch/parisc/Kconfig +++ b/arch/parisc/Kconfig | |||
@@ -138,6 +138,37 @@ config 64BIT | |||
138 | enable this option otherwise. The 64bit kernel is significantly bigger | 138 | enable this option otherwise. The 64bit kernel is significantly bigger |
139 | and slower than the 32bit one. | 139 | and slower than the 32bit one. |
140 | 140 | ||
141 | choice | ||
142 | prompt "Kernel page size" | ||
143 | default PARISC_PAGE_SIZE_4KB if !64BIT | ||
144 | default PARISC_PAGE_SIZE_4KB if 64BIT | ||
145 | # default PARISC_PAGE_SIZE_16KB if 64BIT | ||
146 | |||
147 | config PARISC_PAGE_SIZE_4KB | ||
148 | bool "4KB" | ||
149 | help | ||
150 | This lets you select the page size of the kernel. For best | ||
151 | performance, a page size of 16KB is recommended. For best | ||
152 | compatibility with 32bit applications, a page size of 4KB should be | ||
153 | selected (the vast majority of 32bit binaries work perfectly fine | ||
154 | with a larger page size). | ||
155 | |||
156 | 4KB For best 32bit compatibility | ||
157 | 16KB For best performance | ||
158 | 64KB For best performance, might give more overhead. | ||
159 | |||
160 | If you don't know what to do, choose 4KB. | ||
161 | |||
162 | config PARISC_PAGE_SIZE_16KB | ||
163 | bool "16KB (EXPERIMENTAL)" | ||
164 | depends on PA8X00 && EXPERIMENTAL | ||
165 | |||
166 | config PARISC_PAGE_SIZE_64KB | ||
167 | bool "64KB (EXPERIMENTAL)" | ||
168 | depends on PA8X00 && EXPERIMENTAL | ||
169 | |||
170 | endchoice | ||
171 | |||
141 | config SMP | 172 | config SMP |
142 | bool "Symmetric multi-processing support" | 173 | bool "Symmetric multi-processing support" |
143 | ---help--- | 174 | ---help--- |
diff --git a/arch/parisc/defconfig b/arch/parisc/defconfig index 59f7bc38e72e..b38b58eb9dc2 100644 --- a/arch/parisc/defconfig +++ b/arch/parisc/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-pa6 | 3 | # Linux kernel version: 2.6.16-pa10 |
4 | # Sun Mar 26 19:50:07 2006 | 4 | # Sun Apr 2 15:26:38 2006 |
5 | # | 5 | # |
6 | CONFIG_PARISC=y | 6 | CONFIG_PARISC=y |
7 | CONFIG_MMU=y | 7 | CONFIG_MMU=y |
@@ -25,7 +25,7 @@ CONFIG_LOCALVERSION="" | |||
25 | # CONFIG_LOCALVERSION_AUTO is not set | 25 | # CONFIG_LOCALVERSION_AUTO is not set |
26 | CONFIG_SWAP=y | 26 | CONFIG_SWAP=y |
27 | CONFIG_SYSVIPC=y | 27 | CONFIG_SYSVIPC=y |
28 | # CONFIG_POSIX_MQUEUE is not set | 28 | CONFIG_POSIX_MQUEUE=y |
29 | # CONFIG_BSD_PROCESS_ACCT is not set | 29 | # CONFIG_BSD_PROCESS_ACCT is not set |
30 | CONFIG_SYSCTL=y | 30 | CONFIG_SYSCTL=y |
31 | # CONFIG_AUDIT is not set | 31 | # CONFIG_AUDIT is not set |
@@ -35,7 +35,7 @@ CONFIG_INITRAMFS_SOURCE="" | |||
35 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 35 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
36 | # CONFIG_EMBEDDED is not set | 36 | # CONFIG_EMBEDDED is not set |
37 | CONFIG_KALLSYMS=y | 37 | CONFIG_KALLSYMS=y |
38 | # CONFIG_KALLSYMS_ALL is not set | 38 | CONFIG_KALLSYMS_ALL=y |
39 | # CONFIG_KALLSYMS_EXTRA_PASS is not set | 39 | # CONFIG_KALLSYMS_EXTRA_PASS is not set |
40 | CONFIG_HOTPLUG=y | 40 | CONFIG_HOTPLUG=y |
41 | CONFIG_PRINTK=y | 41 | CONFIG_PRINTK=y |
@@ -57,7 +57,13 @@ CONFIG_BASE_SMALL=0 | |||
57 | # | 57 | # |
58 | # Loadable module support | 58 | # Loadable module support |
59 | # | 59 | # |
60 | # CONFIG_MODULES is not set | 60 | CONFIG_MODULES=y |
61 | CONFIG_MODULE_UNLOAD=y | ||
62 | CONFIG_MODULE_FORCE_UNLOAD=y | ||
63 | CONFIG_OBSOLETE_MODPARM=y | ||
64 | # CONFIG_MODVERSIONS is not set | ||
65 | # CONFIG_MODULE_SRCVERSION_ALL is not set | ||
66 | CONFIG_KMOD=y | ||
61 | 67 | ||
62 | # | 68 | # |
63 | # Block layer | 69 | # Block layer |
@@ -79,16 +85,19 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" | |||
79 | # | 85 | # |
80 | # Processor type and features | 86 | # Processor type and features |
81 | # | 87 | # |
82 | CONFIG_PA7000=y | 88 | # CONFIG_PA7000 is not set |
83 | # CONFIG_PA7100LC is not set | 89 | CONFIG_PA7100LC=y |
84 | # CONFIG_PA7200 is not set | 90 | # CONFIG_PA7200 is not set |
85 | # CONFIG_PA7300LC is not set | 91 | # CONFIG_PA7300LC is not set |
86 | # CONFIG_PA8X00 is not set | 92 | # CONFIG_PA8X00 is not set |
87 | CONFIG_PA11=y | 93 | CONFIG_PA11=y |
94 | CONFIG_PARISC_PAGE_SIZE_4KB=y | ||
95 | # CONFIG_PARISC_PAGE_SIZE_16KB is not set | ||
96 | # CONFIG_PARISC_PAGE_SIZE_64KB is not set | ||
88 | # CONFIG_SMP is not set | 97 | # CONFIG_SMP is not set |
89 | CONFIG_ARCH_FLATMEM_ENABLE=y | 98 | CONFIG_ARCH_FLATMEM_ENABLE=y |
90 | CONFIG_PREEMPT_NONE=y | 99 | # CONFIG_PREEMPT_NONE is not set |
91 | # CONFIG_PREEMPT_VOLUNTARY is not set | 100 | CONFIG_PREEMPT_VOLUNTARY=y |
92 | # CONFIG_PREEMPT is not set | 101 | # CONFIG_PREEMPT is not set |
93 | # CONFIG_HZ_100 is not set | 102 | # CONFIG_HZ_100 is not set |
94 | CONFIG_HZ_250=y | 103 | CONFIG_HZ_250=y |
@@ -108,7 +117,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096 | |||
108 | # Bus options (PCI, PCMCIA, EISA, GSC, ISA) | 117 | # Bus options (PCI, PCMCIA, EISA, GSC, ISA) |
109 | # | 118 | # |
110 | CONFIG_GSC=y | 119 | CONFIG_GSC=y |
111 | CONFIG_HPPB=y | 120 | # CONFIG_HPPB is not set |
112 | CONFIG_IOMMU_CCIO=y | 121 | CONFIG_IOMMU_CCIO=y |
113 | CONFIG_GSC_LASI=y | 122 | CONFIG_GSC_LASI=y |
114 | CONFIG_GSC_WAX=y | 123 | CONFIG_GSC_WAX=y |
@@ -126,7 +135,25 @@ CONFIG_IOMMU_SBA=y | |||
126 | # | 135 | # |
127 | # PCCARD (PCMCIA/CardBus) support | 136 | # PCCARD (PCMCIA/CardBus) support |
128 | # | 137 | # |
129 | # CONFIG_PCCARD is not set | 138 | CONFIG_PCCARD=y |
139 | # CONFIG_PCMCIA_DEBUG is not set | ||
140 | CONFIG_PCMCIA=y | ||
141 | CONFIG_PCMCIA_LOAD_CIS=y | ||
142 | CONFIG_PCMCIA_IOCTL=y | ||
143 | CONFIG_CARDBUS=y | ||
144 | |||
145 | # | ||
146 | # PC-card bridges | ||
147 | # | ||
148 | CONFIG_YENTA=y | ||
149 | CONFIG_YENTA_O2=y | ||
150 | CONFIG_YENTA_RICOH=y | ||
151 | CONFIG_YENTA_TI=y | ||
152 | CONFIG_YENTA_ENE_TUNE=y | ||
153 | CONFIG_YENTA_TOSHIBA=y | ||
154 | CONFIG_PD6729=y | ||
155 | CONFIG_I82092=y | ||
156 | CONFIG_PCCARD_NONSTATIC=y | ||
130 | 157 | ||
131 | # | 158 | # |
132 | # PCI Hotplug Support | 159 | # PCI Hotplug Support |
@@ -145,7 +172,7 @@ CONFIG_PDC_STABLE=y | |||
145 | # Executable file formats | 172 | # Executable file formats |
146 | # | 173 | # |
147 | CONFIG_BINFMT_ELF=y | 174 | CONFIG_BINFMT_ELF=y |
148 | # CONFIG_BINFMT_MISC is not set | 175 | CONFIG_BINFMT_MISC=m |
149 | 176 | ||
150 | # | 177 | # |
151 | # Networking | 178 | # Networking |
@@ -159,13 +186,15 @@ CONFIG_NET=y | |||
159 | CONFIG_PACKET=y | 186 | CONFIG_PACKET=y |
160 | CONFIG_PACKET_MMAP=y | 187 | CONFIG_PACKET_MMAP=y |
161 | CONFIG_UNIX=y | 188 | CONFIG_UNIX=y |
162 | # CONFIG_NET_KEY is not set | 189 | CONFIG_XFRM=y |
190 | CONFIG_XFRM_USER=m | ||
191 | CONFIG_NET_KEY=m | ||
163 | CONFIG_INET=y | 192 | CONFIG_INET=y |
164 | CONFIG_IP_MULTICAST=y | 193 | CONFIG_IP_MULTICAST=y |
165 | # CONFIG_IP_ADVANCED_ROUTER is not set | 194 | # CONFIG_IP_ADVANCED_ROUTER is not set |
166 | CONFIG_IP_FIB_HASH=y | 195 | CONFIG_IP_FIB_HASH=y |
167 | CONFIG_IP_PNP=y | 196 | CONFIG_IP_PNP=y |
168 | # CONFIG_IP_PNP_DHCP is not set | 197 | CONFIG_IP_PNP_DHCP=y |
169 | CONFIG_IP_PNP_BOOTP=y | 198 | CONFIG_IP_PNP_BOOTP=y |
170 | # CONFIG_IP_PNP_RARP is not set | 199 | # CONFIG_IP_PNP_RARP is not set |
171 | # CONFIG_NET_IPIP is not set | 200 | # CONFIG_NET_IPIP is not set |
@@ -173,19 +202,20 @@ CONFIG_IP_PNP_BOOTP=y | |||
173 | # CONFIG_IP_MROUTE is not set | 202 | # CONFIG_IP_MROUTE is not set |
174 | # CONFIG_ARPD is not set | 203 | # CONFIG_ARPD is not set |
175 | # CONFIG_SYN_COOKIES is not set | 204 | # CONFIG_SYN_COOKIES is not set |
176 | # CONFIG_INET_AH is not set | 205 | CONFIG_INET_AH=m |
177 | # CONFIG_INET_ESP is not set | 206 | CONFIG_INET_ESP=m |
178 | # CONFIG_INET_IPCOMP is not set | 207 | # CONFIG_INET_IPCOMP is not set |
179 | # CONFIG_INET_TUNNEL is not set | 208 | CONFIG_INET_TUNNEL=m |
180 | # CONFIG_INET_DIAG is not set | 209 | CONFIG_INET_DIAG=m |
210 | CONFIG_INET_TCP_DIAG=m | ||
181 | # CONFIG_TCP_CONG_ADVANCED is not set | 211 | # CONFIG_TCP_CONG_ADVANCED is not set |
182 | CONFIG_TCP_CONG_BIC=y | 212 | CONFIG_TCP_CONG_BIC=y |
183 | CONFIG_IPV6=y | 213 | CONFIG_IPV6=y |
184 | # CONFIG_IPV6_PRIVACY is not set | 214 | # CONFIG_IPV6_PRIVACY is not set |
185 | # CONFIG_INET6_AH is not set | 215 | CONFIG_INET6_AH=y |
186 | # CONFIG_INET6_ESP is not set | 216 | CONFIG_INET6_ESP=y |
187 | # CONFIG_INET6_IPCOMP is not set | 217 | CONFIG_INET6_IPCOMP=y |
188 | # CONFIG_INET6_TUNNEL is not set | 218 | CONFIG_INET6_TUNNEL=y |
189 | # CONFIG_IPV6_TUNNEL is not set | 219 | # CONFIG_IPV6_TUNNEL is not set |
190 | # CONFIG_NETFILTER is not set | 220 | # CONFIG_NETFILTER is not set |
191 | 221 | ||
@@ -207,7 +237,8 @@ CONFIG_IPV6=y | |||
207 | # CONFIG_BRIDGE is not set | 237 | # CONFIG_BRIDGE is not set |
208 | # CONFIG_VLAN_8021Q is not set | 238 | # CONFIG_VLAN_8021Q is not set |
209 | # CONFIG_DECNET is not set | 239 | # CONFIG_DECNET is not set |
210 | # CONFIG_LLC2 is not set | 240 | CONFIG_LLC=m |
241 | CONFIG_LLC2=m | ||
211 | # CONFIG_IPX is not set | 242 | # CONFIG_IPX is not set |
212 | # CONFIG_ATALK is not set | 243 | # CONFIG_ATALK is not set |
213 | # CONFIG_X25 is not set | 244 | # CONFIG_X25 is not set |
@@ -237,9 +268,9 @@ CONFIG_IPV6=y | |||
237 | # | 268 | # |
238 | # Generic Driver Options | 269 | # Generic Driver Options |
239 | # | 270 | # |
240 | CONFIG_STANDALONE=y | 271 | # CONFIG_STANDALONE is not set |
241 | CONFIG_PREVENT_FIRMWARE_BUILD=y | 272 | # CONFIG_PREVENT_FIRMWARE_BUILD is not set |
242 | # CONFIG_FW_LOADER is not set | 273 | CONFIG_FW_LOADER=y |
243 | # CONFIG_DEBUG_DRIVER is not set | 274 | # CONFIG_DEBUG_DRIVER is not set |
244 | 275 | ||
245 | # | 276 | # |
@@ -256,13 +287,14 @@ CONFIG_PREVENT_FIRMWARE_BUILD=y | |||
256 | # Parallel port support | 287 | # Parallel port support |
257 | # | 288 | # |
258 | CONFIG_PARPORT=y | 289 | CONFIG_PARPORT=y |
259 | CONFIG_PARPORT_PC=y | 290 | CONFIG_PARPORT_PC=m |
260 | # CONFIG_PARPORT_SERIAL is not set | 291 | # CONFIG_PARPORT_SERIAL is not set |
261 | # CONFIG_PARPORT_PC_FIFO is not set | 292 | # CONFIG_PARPORT_PC_FIFO is not set |
262 | # CONFIG_PARPORT_PC_SUPERIO is not set | 293 | # CONFIG_PARPORT_PC_SUPERIO is not set |
294 | CONFIG_PARPORT_PC_PCMCIA=m | ||
263 | CONFIG_PARPORT_NOT_PC=y | 295 | CONFIG_PARPORT_NOT_PC=y |
264 | CONFIG_PARPORT_GSC=y | 296 | CONFIG_PARPORT_GSC=y |
265 | # CONFIG_PARPORT_1284 is not set | 297 | CONFIG_PARPORT_1284=y |
266 | 298 | ||
267 | # | 299 | # |
268 | # Plug and Play support | 300 | # Plug and Play support |
@@ -284,7 +316,7 @@ CONFIG_BLK_DEV_CRYPTOLOOP=y | |||
284 | # CONFIG_BLK_DEV_UB is not set | 316 | # CONFIG_BLK_DEV_UB is not set |
285 | CONFIG_BLK_DEV_RAM=y | 317 | CONFIG_BLK_DEV_RAM=y |
286 | CONFIG_BLK_DEV_RAM_COUNT=16 | 318 | CONFIG_BLK_DEV_RAM_COUNT=16 |
287 | CONFIG_BLK_DEV_RAM_SIZE=4096 | 319 | CONFIG_BLK_DEV_RAM_SIZE=6144 |
288 | CONFIG_BLK_DEV_INITRD=y | 320 | CONFIG_BLK_DEV_INITRD=y |
289 | # CONFIG_CDROM_PKTCDVD is not set | 321 | # CONFIG_CDROM_PKTCDVD is not set |
290 | # CONFIG_ATA_OVER_ETH is not set | 322 | # CONFIG_ATA_OVER_ETH is not set |
@@ -292,7 +324,60 @@ CONFIG_BLK_DEV_INITRD=y | |||
292 | # | 324 | # |
293 | # ATA/ATAPI/MFM/RLL support | 325 | # ATA/ATAPI/MFM/RLL support |
294 | # | 326 | # |
295 | # CONFIG_IDE is not set | 327 | CONFIG_IDE=y |
328 | CONFIG_BLK_DEV_IDE=y | ||
329 | |||
330 | # | ||
331 | # Please see Documentation/ide.txt for help/info on IDE drives | ||
332 | # | ||
333 | # CONFIG_BLK_DEV_IDE_SATA is not set | ||
334 | CONFIG_BLK_DEV_IDEDISK=y | ||
335 | CONFIG_IDEDISK_MULTI_MODE=y | ||
336 | CONFIG_BLK_DEV_IDECS=y | ||
337 | CONFIG_BLK_DEV_IDECD=y | ||
338 | # CONFIG_BLK_DEV_IDETAPE is not set | ||
339 | # CONFIG_BLK_DEV_IDEFLOPPY is not set | ||
340 | CONFIG_BLK_DEV_IDESCSI=y | ||
341 | # CONFIG_IDE_TASK_IOCTL is not set | ||
342 | |||
343 | # | ||
344 | # IDE chipset support/bugfixes | ||
345 | # | ||
346 | CONFIG_IDE_GENERIC=y | ||
347 | CONFIG_BLK_DEV_IDEPCI=y | ||
348 | CONFIG_IDEPCI_SHARE_IRQ=y | ||
349 | # CONFIG_BLK_DEV_OFFBOARD is not set | ||
350 | CONFIG_BLK_DEV_GENERIC=y | ||
351 | # CONFIG_BLK_DEV_OPTI621 is not set | ||
352 | CONFIG_BLK_DEV_IDEDMA_PCI=y | ||
353 | # CONFIG_BLK_DEV_IDEDMA_FORCED is not set | ||
354 | # CONFIG_IDEDMA_PCI_AUTO is not set | ||
355 | # CONFIG_BLK_DEV_AEC62XX is not set | ||
356 | # CONFIG_BLK_DEV_ALI15X3 is not set | ||
357 | # CONFIG_BLK_DEV_AMD74XX is not set | ||
358 | # CONFIG_BLK_DEV_CMD64X is not set | ||
359 | # CONFIG_BLK_DEV_TRIFLEX is not set | ||
360 | # CONFIG_BLK_DEV_CY82C693 is not set | ||
361 | # CONFIG_BLK_DEV_CS5520 is not set | ||
362 | # CONFIG_BLK_DEV_CS5530 is not set | ||
363 | # CONFIG_BLK_DEV_HPT34X is not set | ||
364 | # CONFIG_BLK_DEV_HPT366 is not set | ||
365 | # CONFIG_BLK_DEV_SC1200 is not set | ||
366 | # CONFIG_BLK_DEV_PIIX is not set | ||
367 | # CONFIG_BLK_DEV_IT821X is not set | ||
368 | CONFIG_BLK_DEV_NS87415=y | ||
369 | # CONFIG_BLK_DEV_PDC202XX_OLD is not set | ||
370 | # CONFIG_BLK_DEV_PDC202XX_NEW is not set | ||
371 | # CONFIG_BLK_DEV_SVWKS is not set | ||
372 | # CONFIG_BLK_DEV_SIIMAGE is not set | ||
373 | # CONFIG_BLK_DEV_SLC90E66 is not set | ||
374 | # CONFIG_BLK_DEV_TRM290 is not set | ||
375 | # CONFIG_BLK_DEV_VIA82CXXX is not set | ||
376 | # CONFIG_IDE_ARM is not set | ||
377 | CONFIG_BLK_DEV_IDEDMA=y | ||
378 | # CONFIG_IDEDMA_IVB is not set | ||
379 | # CONFIG_IDEDMA_AUTO is not set | ||
380 | # CONFIG_BLK_DEV_HD is not set | ||
296 | 381 | ||
297 | # | 382 | # |
298 | # SCSI device support | 383 | # SCSI device support |
@@ -375,6 +460,15 @@ CONFIG_SCSI_NCR53C8XX_SYNC=20 | |||
375 | # CONFIG_SCSI_DEBUG is not set | 460 | # CONFIG_SCSI_DEBUG is not set |
376 | 461 | ||
377 | # | 462 | # |
463 | # PCMCIA SCSI adapter support | ||
464 | # | ||
465 | # CONFIG_PCMCIA_AHA152X is not set | ||
466 | # CONFIG_PCMCIA_FDOMAIN is not set | ||
467 | # CONFIG_PCMCIA_NINJA_SCSI is not set | ||
468 | # CONFIG_PCMCIA_QLOGIC is not set | ||
469 | # CONFIG_PCMCIA_SYM53C500 is not set | ||
470 | |||
471 | # | ||
378 | # Multi-device support (RAID and LVM) | 472 | # Multi-device support (RAID and LVM) |
379 | # | 473 | # |
380 | CONFIG_MD=y | 474 | CONFIG_MD=y |
@@ -382,12 +476,17 @@ CONFIG_BLK_DEV_MD=y | |||
382 | CONFIG_MD_LINEAR=y | 476 | CONFIG_MD_LINEAR=y |
383 | CONFIG_MD_RAID0=y | 477 | CONFIG_MD_RAID0=y |
384 | CONFIG_MD_RAID1=y | 478 | CONFIG_MD_RAID1=y |
385 | # CONFIG_MD_RAID10 is not set | 479 | CONFIG_MD_RAID10=y |
386 | CONFIG_MD_RAID5=y | 480 | CONFIG_MD_RAID5=y |
387 | # CONFIG_MD_RAID6 is not set | 481 | CONFIG_MD_RAID6=y |
388 | # CONFIG_MD_MULTIPATH is not set | 482 | # CONFIG_MD_MULTIPATH is not set |
389 | # CONFIG_MD_FAULTY is not set | 483 | # CONFIG_MD_FAULTY is not set |
390 | # CONFIG_BLK_DEV_DM is not set | 484 | CONFIG_BLK_DEV_DM=y |
485 | # CONFIG_DM_CRYPT is not set | ||
486 | # CONFIG_DM_SNAPSHOT is not set | ||
487 | # CONFIG_DM_MIRROR is not set | ||
488 | # CONFIG_DM_ZERO is not set | ||
489 | # CONFIG_DM_MULTIPATH is not set | ||
391 | 490 | ||
392 | # | 491 | # |
393 | # Fusion MPT device support | 492 | # Fusion MPT device support |
@@ -411,10 +510,10 @@ CONFIG_MD_RAID5=y | |||
411 | # Network device support | 510 | # Network device support |
412 | # | 511 | # |
413 | CONFIG_NETDEVICES=y | 512 | CONFIG_NETDEVICES=y |
414 | # CONFIG_DUMMY is not set | 513 | CONFIG_DUMMY=m |
415 | # CONFIG_BONDING is not set | 514 | CONFIG_BONDING=m |
416 | # CONFIG_EQUALIZER is not set | 515 | # CONFIG_EQUALIZER is not set |
417 | # CONFIG_TUN is not set | 516 | CONFIG_TUN=m |
418 | 517 | ||
419 | # | 518 | # |
420 | # ARCnet devices | 519 | # ARCnet devices |
@@ -430,7 +529,7 @@ CONFIG_NETDEVICES=y | |||
430 | # Ethernet (10 or 100Mbit) | 529 | # Ethernet (10 or 100Mbit) |
431 | # | 530 | # |
432 | CONFIG_NET_ETHERNET=y | 531 | CONFIG_NET_ETHERNET=y |
433 | # CONFIG_MII is not set | 532 | CONFIG_MII=m |
434 | CONFIG_LASI_82596=y | 533 | CONFIG_LASI_82596=y |
435 | # CONFIG_HAPPYMEAL is not set | 534 | # CONFIG_HAPPYMEAL is not set |
436 | # CONFIG_SUNGEM is not set | 535 | # CONFIG_SUNGEM is not set |
@@ -451,6 +550,8 @@ CONFIG_TULIP=y | |||
451 | # CONFIG_WINBOND_840 is not set | 550 | # CONFIG_WINBOND_840 is not set |
452 | # CONFIG_DM9102 is not set | 551 | # CONFIG_DM9102 is not set |
453 | # CONFIG_ULI526X is not set | 552 | # CONFIG_ULI526X is not set |
553 | # CONFIG_PCMCIA_XIRCOM is not set | ||
554 | # CONFIG_PCMCIA_XIRTULIP is not set | ||
454 | # CONFIG_DEPCA is not set | 555 | # CONFIG_DEPCA is not set |
455 | # CONFIG_HP100 is not set | 556 | # CONFIG_HP100 is not set |
456 | CONFIG_NET_PCI=y | 557 | CONFIG_NET_PCI=y |
@@ -518,14 +619,33 @@ CONFIG_NET_RADIO=y | |||
518 | # Obsolete Wireless cards support (pre-802.11) | 619 | # Obsolete Wireless cards support (pre-802.11) |
519 | # | 620 | # |
520 | # CONFIG_STRIP is not set | 621 | # CONFIG_STRIP is not set |
622 | # CONFIG_PCMCIA_WAVELAN is not set | ||
623 | # CONFIG_PCMCIA_NETWAVE is not set | ||
624 | |||
625 | # | ||
626 | # Wireless 802.11 Frequency Hopping cards support | ||
627 | # | ||
628 | # CONFIG_PCMCIA_RAYCS is not set | ||
521 | 629 | ||
522 | # | 630 | # |
523 | # Wireless 802.11b ISA/PCI cards support | 631 | # Wireless 802.11b ISA/PCI cards support |
524 | # | 632 | # |
525 | # CONFIG_HERMES is not set | 633 | CONFIG_HERMES=y |
634 | # CONFIG_PLX_HERMES is not set | ||
635 | # CONFIG_TMD_HERMES is not set | ||
636 | # CONFIG_NORTEL_HERMES is not set | ||
637 | # CONFIG_PCI_HERMES is not set | ||
526 | # CONFIG_ATMEL is not set | 638 | # CONFIG_ATMEL is not set |
527 | 639 | ||
528 | # | 640 | # |
641 | # Wireless 802.11b Pcmcia/Cardbus cards support | ||
642 | # | ||
643 | CONFIG_PCMCIA_HERMES=y | ||
644 | CONFIG_PCMCIA_SPECTRUM=y | ||
645 | # CONFIG_AIRO_CS is not set | ||
646 | # CONFIG_PCMCIA_WL3501 is not set | ||
647 | |||
648 | # | ||
529 | # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support | 649 | # Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support |
530 | # | 650 | # |
531 | # CONFIG_PRISM54 is not set | 651 | # CONFIG_PRISM54 is not set |
@@ -533,13 +653,34 @@ CONFIG_NET_RADIO=y | |||
533 | CONFIG_NET_WIRELESS=y | 653 | CONFIG_NET_WIRELESS=y |
534 | 654 | ||
535 | # | 655 | # |
656 | # PCMCIA network device support | ||
657 | # | ||
658 | CONFIG_NET_PCMCIA=y | ||
659 | # CONFIG_PCMCIA_3C589 is not set | ||
660 | # CONFIG_PCMCIA_3C574 is not set | ||
661 | # CONFIG_PCMCIA_FMVJ18X is not set | ||
662 | # CONFIG_PCMCIA_PCNET is not set | ||
663 | # CONFIG_PCMCIA_NMCLAN is not set | ||
664 | # CONFIG_PCMCIA_SMC91C92 is not set | ||
665 | # CONFIG_PCMCIA_XIRC2PS is not set | ||
666 | # CONFIG_PCMCIA_AXNET is not set | ||
667 | |||
668 | # | ||
536 | # Wan interfaces | 669 | # Wan interfaces |
537 | # | 670 | # |
538 | # CONFIG_WAN is not set | 671 | # CONFIG_WAN is not set |
539 | # CONFIG_FDDI is not set | 672 | # CONFIG_FDDI is not set |
540 | # CONFIG_HIPPI is not set | 673 | # CONFIG_HIPPI is not set |
541 | # CONFIG_PLIP is not set | 674 | # CONFIG_PLIP is not set |
542 | # CONFIG_PPP is not set | 675 | CONFIG_PPP=m |
676 | # CONFIG_PPP_MULTILINK is not set | ||
677 | # CONFIG_PPP_FILTER is not set | ||
678 | CONFIG_PPP_ASYNC=m | ||
679 | CONFIG_PPP_SYNC_TTY=m | ||
680 | CONFIG_PPP_DEFLATE=m | ||
681 | CONFIG_PPP_BSDCOMP=m | ||
682 | # CONFIG_PPP_MPPE is not set | ||
683 | CONFIG_PPPOE=m | ||
543 | # CONFIG_SLIP is not set | 684 | # CONFIG_SLIP is not set |
544 | # CONFIG_NET_FC is not set | 685 | # CONFIG_NET_FC is not set |
545 | # CONFIG_SHAPER is not set | 686 | # CONFIG_SHAPER is not set |
@@ -571,14 +712,16 @@ CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 | |||
571 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 | 712 | CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 |
572 | # CONFIG_INPUT_JOYDEV is not set | 713 | # CONFIG_INPUT_JOYDEV is not set |
573 | # CONFIG_INPUT_TSDEV is not set | 714 | # CONFIG_INPUT_TSDEV is not set |
574 | CONFIG_INPUT_EVDEV=y | 715 | # CONFIG_INPUT_EVDEV is not set |
575 | # CONFIG_INPUT_EVBUG is not set | 716 | # CONFIG_INPUT_EVBUG is not set |
576 | 717 | ||
577 | # | 718 | # |
578 | # Input Device Drivers | 719 | # Input Device Drivers |
579 | # | 720 | # |
580 | CONFIG_INPUT_KEYBOARD=y | 721 | CONFIG_INPUT_KEYBOARD=y |
581 | # CONFIG_KEYBOARD_ATKBD is not set | 722 | CONFIG_KEYBOARD_ATKBD=y |
723 | CONFIG_KEYBOARD_ATKBD_HP_KEYCODES=y | ||
724 | # CONFIG_KEYBOARD_ATKBD_RDI_KEYCODES is not set | ||
582 | # CONFIG_KEYBOARD_SUNKBD is not set | 725 | # CONFIG_KEYBOARD_SUNKBD is not set |
583 | # CONFIG_KEYBOARD_LKKBD is not set | 726 | # CONFIG_KEYBOARD_LKKBD is not set |
584 | # CONFIG_KEYBOARD_XTKBD is not set | 727 | # CONFIG_KEYBOARD_XTKBD is not set |
@@ -586,52 +729,25 @@ CONFIG_INPUT_KEYBOARD=y | |||
586 | # CONFIG_KEYBOARD_HIL_OLD is not set | 729 | # CONFIG_KEYBOARD_HIL_OLD is not set |
587 | CONFIG_KEYBOARD_HIL=y | 730 | CONFIG_KEYBOARD_HIL=y |
588 | CONFIG_INPUT_MOUSE=y | 731 | CONFIG_INPUT_MOUSE=y |
589 | # CONFIG_MOUSE_PS2 is not set | 732 | CONFIG_MOUSE_PS2=y |
590 | # CONFIG_MOUSE_SERIAL is not set | 733 | CONFIG_MOUSE_SERIAL=y |
591 | # CONFIG_MOUSE_VSXXXAA is not set | 734 | # CONFIG_MOUSE_VSXXXAA is not set |
592 | CONFIG_MOUSE_HIL=y | 735 | CONFIG_MOUSE_HIL=y |
593 | CONFIG_INPUT_JOYSTICK=y | 736 | # CONFIG_INPUT_JOYSTICK is not set |
594 | # CONFIG_JOYSTICK_ANALOG is not set | 737 | # CONFIG_INPUT_TOUCHSCREEN is not set |
595 | # CONFIG_JOYSTICK_A3D is not set | 738 | # CONFIG_INPUT_MISC is not set |
596 | # CONFIG_JOYSTICK_ADI is not set | ||
597 | # CONFIG_JOYSTICK_COBRA is not set | ||
598 | # CONFIG_JOYSTICK_GF2K is not set | ||
599 | # CONFIG_JOYSTICK_GRIP is not set | ||
600 | # CONFIG_JOYSTICK_GRIP_MP is not set | ||
601 | # CONFIG_JOYSTICK_GUILLEMOT is not set | ||
602 | # CONFIG_JOYSTICK_INTERACT is not set | ||
603 | # CONFIG_JOYSTICK_SIDEWINDER is not set | ||
604 | # CONFIG_JOYSTICK_TMDC is not set | ||
605 | # CONFIG_JOYSTICK_IFORCE is not set | ||
606 | # CONFIG_JOYSTICK_WARRIOR is not set | ||
607 | # CONFIG_JOYSTICK_MAGELLAN is not set | ||
608 | # CONFIG_JOYSTICK_SPACEORB is not set | ||
609 | # CONFIG_JOYSTICK_SPACEBALL is not set | ||
610 | # CONFIG_JOYSTICK_STINGER is not set | ||
611 | # CONFIG_JOYSTICK_TWIDJOY is not set | ||
612 | # CONFIG_JOYSTICK_DB9 is not set | ||
613 | # CONFIG_JOYSTICK_GAMECON is not set | ||
614 | # CONFIG_JOYSTICK_TURBOGRAFX is not set | ||
615 | # CONFIG_JOYSTICK_JOYDUMP is not set | ||
616 | CONFIG_INPUT_TOUCHSCREEN=y | ||
617 | # CONFIG_TOUCHSCREEN_GUNZE is not set | ||
618 | # CONFIG_TOUCHSCREEN_ELO is not set | ||
619 | # CONFIG_TOUCHSCREEN_MTOUCH is not set | ||
620 | # CONFIG_TOUCHSCREEN_MK712 is not set | ||
621 | CONFIG_INPUT_MISC=y | ||
622 | # CONFIG_INPUT_UINPUT is not set | ||
623 | CONFIG_HP_SDC_RTC=y | ||
624 | 739 | ||
625 | # | 740 | # |
626 | # Hardware I/O ports | 741 | # Hardware I/O ports |
627 | # | 742 | # |
628 | CONFIG_SERIO=y | 743 | CONFIG_SERIO=y |
629 | # CONFIG_SERIO_SERPORT is not set | 744 | CONFIG_SERIO_SERPORT=y |
630 | # CONFIG_SERIO_PARKBD is not set | 745 | # CONFIG_SERIO_PARKBD is not set |
631 | CONFIG_SERIO_GSCPS2=y | 746 | CONFIG_SERIO_GSCPS2=y |
632 | CONFIG_HP_SDC=y | 747 | CONFIG_HP_SDC=y |
633 | CONFIG_HIL_MLC=y | 748 | CONFIG_HIL_MLC=y |
634 | # CONFIG_SERIO_PCIPS2 is not set | 749 | # CONFIG_SERIO_PCIPS2 is not set |
750 | CONFIG_SERIO_LIBPS2=y | ||
635 | # CONFIG_SERIO_RAW is not set | 751 | # CONFIG_SERIO_RAW is not set |
636 | # CONFIG_GAMEPORT is not set | 752 | # CONFIG_GAMEPORT is not set |
637 | 753 | ||
@@ -648,7 +764,8 @@ CONFIG_HW_CONSOLE=y | |||
648 | # | 764 | # |
649 | CONFIG_SERIAL_8250=y | 765 | CONFIG_SERIAL_8250=y |
650 | CONFIG_SERIAL_8250_CONSOLE=y | 766 | CONFIG_SERIAL_8250_CONSOLE=y |
651 | CONFIG_SERIAL_8250_NR_UARTS=13 | 767 | CONFIG_SERIAL_8250_CS=y |
768 | CONFIG_SERIAL_8250_NR_UARTS=17 | ||
652 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | 769 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 |
653 | CONFIG_SERIAL_8250_EXTENDED=y | 770 | CONFIG_SERIAL_8250_EXTENDED=y |
654 | CONFIG_SERIAL_8250_MANY_PORTS=y | 771 | CONFIG_SERIAL_8250_MANY_PORTS=y |
@@ -666,10 +783,10 @@ CONFIG_SERIAL_CORE_CONSOLE=y | |||
666 | # CONFIG_SERIAL_JSM is not set | 783 | # CONFIG_SERIAL_JSM is not set |
667 | CONFIG_UNIX98_PTYS=y | 784 | CONFIG_UNIX98_PTYS=y |
668 | CONFIG_LEGACY_PTYS=y | 785 | CONFIG_LEGACY_PTYS=y |
669 | CONFIG_LEGACY_PTY_COUNT=256 | 786 | CONFIG_LEGACY_PTY_COUNT=64 |
670 | CONFIG_PRINTER=y | 787 | CONFIG_PRINTER=m |
671 | # CONFIG_LP_CONSOLE is not set | 788 | # CONFIG_LP_CONSOLE is not set |
672 | # CONFIG_PPDEV is not set | 789 | CONFIG_PPDEV=m |
673 | # CONFIG_TIPAR is not set | 790 | # CONFIG_TIPAR is not set |
674 | 791 | ||
675 | # | 792 | # |
@@ -682,7 +799,7 @@ CONFIG_PRINTER=y | |||
682 | # | 799 | # |
683 | # CONFIG_WATCHDOG is not set | 800 | # CONFIG_WATCHDOG is not set |
684 | CONFIG_GEN_RTC=y | 801 | CONFIG_GEN_RTC=y |
685 | # CONFIG_GEN_RTC_X is not set | 802 | CONFIG_GEN_RTC_X=y |
686 | # CONFIG_DTLK is not set | 803 | # CONFIG_DTLK is not set |
687 | # CONFIG_R3964 is not set | 804 | # CONFIG_R3964 is not set |
688 | # CONFIG_APPLICOM is not set | 805 | # CONFIG_APPLICOM is not set |
@@ -691,6 +808,13 @@ CONFIG_GEN_RTC=y | |||
691 | # Ftape, the floppy tape device driver | 808 | # Ftape, the floppy tape device driver |
692 | # | 809 | # |
693 | # CONFIG_DRM is not set | 810 | # CONFIG_DRM is not set |
811 | |||
812 | # | ||
813 | # PCMCIA character devices | ||
814 | # | ||
815 | # CONFIG_SYNCLINK_CS is not set | ||
816 | # CONFIG_CARDMAN_4000 is not set | ||
817 | # CONFIG_CARDMAN_4040 is not set | ||
694 | # CONFIG_RAW_DRIVER is not set | 818 | # CONFIG_RAW_DRIVER is not set |
695 | 819 | ||
696 | # | 820 | # |
@@ -718,10 +842,8 @@ CONFIG_GEN_RTC=y | |||
718 | # | 842 | # |
719 | # Hardware Monitoring support | 843 | # Hardware Monitoring support |
720 | # | 844 | # |
721 | CONFIG_HWMON=y | 845 | # CONFIG_HWMON is not set |
722 | # CONFIG_HWMON_VID is not set | 846 | # CONFIG_HWMON_VID is not set |
723 | # CONFIG_SENSORS_F71805F is not set | ||
724 | # CONFIG_HWMON_DEBUG_CHIP is not set | ||
725 | 847 | ||
726 | # | 848 | # |
727 | # Misc devices | 849 | # Misc devices |
@@ -749,8 +871,8 @@ CONFIG_FB_CFB_FILLRECT=y | |||
749 | CONFIG_FB_CFB_COPYAREA=y | 871 | CONFIG_FB_CFB_COPYAREA=y |
750 | CONFIG_FB_CFB_IMAGEBLIT=y | 872 | CONFIG_FB_CFB_IMAGEBLIT=y |
751 | # CONFIG_FB_MACMODES is not set | 873 | # CONFIG_FB_MACMODES is not set |
752 | # CONFIG_FB_MODE_HELPERS is not set | 874 | CONFIG_FB_MODE_HELPERS=y |
753 | # CONFIG_FB_TILEBLITTING is not set | 875 | CONFIG_FB_TILEBLITTING=y |
754 | # CONFIG_FB_CIRRUS is not set | 876 | # CONFIG_FB_CIRRUS is not set |
755 | # CONFIG_FB_PM2 is not set | 877 | # CONFIG_FB_PM2 is not set |
756 | # CONFIG_FB_CYBER2000 is not set | 878 | # CONFIG_FB_CYBER2000 is not set |
@@ -778,8 +900,8 @@ CONFIG_FB_STI=y | |||
778 | # Console display driver support | 900 | # Console display driver support |
779 | # | 901 | # |
780 | CONFIG_DUMMY_CONSOLE=y | 902 | CONFIG_DUMMY_CONSOLE=y |
781 | CONFIG_DUMMY_CONSOLE_COLUMNS=160 | 903 | CONFIG_DUMMY_CONSOLE_COLUMNS=128 |
782 | CONFIG_DUMMY_CONSOLE_ROWS=64 | 904 | CONFIG_DUMMY_CONSOLE_ROWS=48 |
783 | CONFIG_FRAMEBUFFER_CONSOLE=y | 905 | CONFIG_FRAMEBUFFER_CONSOLE=y |
784 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set | 906 | # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set |
785 | CONFIG_STI_CONSOLE=y | 907 | CONFIG_STI_CONSOLE=y |
@@ -816,13 +938,14 @@ CONFIG_SOUND=y | |||
816 | CONFIG_SND=y | 938 | CONFIG_SND=y |
817 | CONFIG_SND_TIMER=y | 939 | CONFIG_SND_TIMER=y |
818 | CONFIG_SND_PCM=y | 940 | CONFIG_SND_PCM=y |
941 | CONFIG_SND_HWDEP=y | ||
819 | CONFIG_SND_SEQUENCER=y | 942 | CONFIG_SND_SEQUENCER=y |
820 | # CONFIG_SND_SEQ_DUMMY is not set | 943 | # CONFIG_SND_SEQ_DUMMY is not set |
821 | CONFIG_SND_OSSEMUL=y | 944 | CONFIG_SND_OSSEMUL=y |
822 | CONFIG_SND_MIXER_OSS=y | 945 | CONFIG_SND_MIXER_OSS=y |
823 | CONFIG_SND_PCM_OSS=y | 946 | CONFIG_SND_PCM_OSS=y |
824 | CONFIG_SND_SEQUENCER_OSS=y | 947 | CONFIG_SND_SEQUENCER_OSS=y |
825 | # CONFIG_SND_DYNAMIC_MINORS is not set | 948 | CONFIG_SND_DYNAMIC_MINORS=y |
826 | CONFIG_SND_SUPPORT_OLD_API=y | 949 | CONFIG_SND_SUPPORT_OLD_API=y |
827 | # CONFIG_SND_VERBOSE_PRINTK is not set | 950 | # CONFIG_SND_VERBOSE_PRINTK is not set |
828 | # CONFIG_SND_DEBUG is not set | 951 | # CONFIG_SND_DEBUG is not set |
@@ -830,6 +953,7 @@ CONFIG_SND_SUPPORT_OLD_API=y | |||
830 | # | 953 | # |
831 | # Generic devices | 954 | # Generic devices |
832 | # | 955 | # |
956 | CONFIG_SND_OPL3_LIB=y | ||
833 | CONFIG_SND_AC97_CODEC=y | 957 | CONFIG_SND_AC97_CODEC=y |
834 | CONFIG_SND_AC97_BUS=y | 958 | CONFIG_SND_AC97_BUS=y |
835 | # CONFIG_SND_DUMMY is not set | 959 | # CONFIG_SND_DUMMY is not set |
@@ -842,7 +966,7 @@ CONFIG_SND_AC97_BUS=y | |||
842 | # PCI devices | 966 | # PCI devices |
843 | # | 967 | # |
844 | CONFIG_SND_AD1889=y | 968 | CONFIG_SND_AD1889=y |
845 | # CONFIG_SND_AD1889_OPL3 is not set | 969 | CONFIG_SND_AD1889_OPL3=y |
846 | # CONFIG_SND_ALI5451 is not set | 970 | # CONFIG_SND_ALI5451 is not set |
847 | # CONFIG_SND_ATIIXP is not set | 971 | # CONFIG_SND_ATIIXP is not set |
848 | # CONFIG_SND_ATIIXP_MODEM is not set | 972 | # CONFIG_SND_ATIIXP_MODEM is not set |
@@ -890,6 +1014,10 @@ CONFIG_SND_AD1889=y | |||
890 | # CONFIG_SND_USB_AUDIO is not set | 1014 | # CONFIG_SND_USB_AUDIO is not set |
891 | 1015 | ||
892 | # | 1016 | # |
1017 | # PCMCIA devices | ||
1018 | # | ||
1019 | |||
1020 | # | ||
893 | # GSC devices | 1021 | # GSC devices |
894 | # | 1022 | # |
895 | CONFIG_SND_HARMONY=y | 1023 | CONFIG_SND_HARMONY=y |
@@ -905,12 +1033,12 @@ CONFIG_SND_HARMONY=y | |||
905 | CONFIG_USB_ARCH_HAS_HCD=y | 1033 | CONFIG_USB_ARCH_HAS_HCD=y |
906 | CONFIG_USB_ARCH_HAS_OHCI=y | 1034 | CONFIG_USB_ARCH_HAS_OHCI=y |
907 | CONFIG_USB=y | 1035 | CONFIG_USB=y |
908 | CONFIG_USB_DEBUG=y | 1036 | # CONFIG_USB_DEBUG is not set |
909 | 1037 | ||
910 | # | 1038 | # |
911 | # Miscellaneous USB options | 1039 | # Miscellaneous USB options |
912 | # | 1040 | # |
913 | # CONFIG_USB_DEVICEFS is not set | 1041 | CONFIG_USB_DEVICEFS=y |
914 | # CONFIG_USB_BANDWIDTH is not set | 1042 | # CONFIG_USB_BANDWIDTH is not set |
915 | # CONFIG_USB_DYNAMIC_MINORS is not set | 1043 | # CONFIG_USB_DYNAMIC_MINORS is not set |
916 | # CONFIG_USB_OTG is not set | 1044 | # CONFIG_USB_OTG is not set |
@@ -918,14 +1046,12 @@ CONFIG_USB_DEBUG=y | |||
918 | # | 1046 | # |
919 | # USB Host Controller Drivers | 1047 | # USB Host Controller Drivers |
920 | # | 1048 | # |
921 | CONFIG_USB_EHCI_HCD=y | 1049 | # CONFIG_USB_EHCI_HCD is not set |
922 | # CONFIG_USB_EHCI_SPLIT_ISO is not set | ||
923 | # CONFIG_USB_EHCI_ROOT_HUB_TT is not set | ||
924 | # CONFIG_USB_ISP116X_HCD is not set | 1050 | # CONFIG_USB_ISP116X_HCD is not set |
925 | CONFIG_USB_OHCI_HCD=y | 1051 | CONFIG_USB_OHCI_HCD=y |
926 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set | 1052 | # CONFIG_USB_OHCI_BIG_ENDIAN is not set |
927 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y | 1053 | CONFIG_USB_OHCI_LITTLE_ENDIAN=y |
928 | # CONFIG_USB_UHCI_HCD is not set | 1054 | CONFIG_USB_UHCI_HCD=y |
929 | # CONFIG_USB_SL811_HCD is not set | 1055 | # CONFIG_USB_SL811_HCD is not set |
930 | 1056 | ||
931 | # | 1057 | # |
@@ -948,13 +1074,11 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y | |||
948 | # | 1074 | # |
949 | # USB Input Devices | 1075 | # USB Input Devices |
950 | # | 1076 | # |
951 | # CONFIG_USB_HID is not set | 1077 | CONFIG_USB_HID=y |
952 | 1078 | CONFIG_USB_HIDINPUT=y | |
953 | # | 1079 | # CONFIG_USB_HIDINPUT_POWERBOOK is not set |
954 | # USB HID Boot Protocol drivers | 1080 | # CONFIG_HID_FF is not set |
955 | # | 1081 | # CONFIG_USB_HIDDEV is not set |
956 | # CONFIG_USB_KBD is not set | ||
957 | # CONFIG_USB_MOUSE is not set | ||
958 | # CONFIG_USB_AIPTEK is not set | 1082 | # CONFIG_USB_AIPTEK is not set |
959 | # CONFIG_USB_WACOM is not set | 1083 | # CONFIG_USB_WACOM is not set |
960 | # CONFIG_USB_ACECAD is not set | 1084 | # CONFIG_USB_ACECAD is not set |
@@ -1020,8 +1144,8 @@ CONFIG_USB_MON=y | |||
1020 | # CONFIG_USB_PHIDGETKIT is not set | 1144 | # CONFIG_USB_PHIDGETKIT is not set |
1021 | # CONFIG_USB_PHIDGETSERVO is not set | 1145 | # CONFIG_USB_PHIDGETSERVO is not set |
1022 | # CONFIG_USB_IDMOUSE is not set | 1146 | # CONFIG_USB_IDMOUSE is not set |
1023 | # CONFIG_USB_SISUSBVGA is not set | ||
1024 | # CONFIG_USB_LD is not set | 1147 | # CONFIG_USB_LD is not set |
1148 | # CONFIG_USB_TEST is not set | ||
1025 | 1149 | ||
1026 | # | 1150 | # |
1027 | # USB DSL modem support | 1151 | # USB DSL modem support |
@@ -1058,7 +1182,7 @@ CONFIG_JBD=y | |||
1058 | # CONFIG_JBD_DEBUG is not set | 1182 | # CONFIG_JBD_DEBUG is not set |
1059 | # CONFIG_REISERFS_FS is not set | 1183 | # CONFIG_REISERFS_FS is not set |
1060 | # CONFIG_JFS_FS is not set | 1184 | # CONFIG_JFS_FS is not set |
1061 | # CONFIG_FS_POSIX_ACL is not set | 1185 | CONFIG_FS_POSIX_ACL=y |
1062 | # CONFIG_XFS_FS is not set | 1186 | # CONFIG_XFS_FS is not set |
1063 | # CONFIG_OCFS2_FS is not set | 1187 | # CONFIG_OCFS2_FS is not set |
1064 | # CONFIG_MINIX_FS is not set | 1188 | # CONFIG_MINIX_FS is not set |
@@ -1066,7 +1190,7 @@ CONFIG_JBD=y | |||
1066 | CONFIG_INOTIFY=y | 1190 | CONFIG_INOTIFY=y |
1067 | # CONFIG_QUOTA is not set | 1191 | # CONFIG_QUOTA is not set |
1068 | CONFIG_DNOTIFY=y | 1192 | CONFIG_DNOTIFY=y |
1069 | # CONFIG_AUTOFS_FS is not set | 1193 | CONFIG_AUTOFS_FS=y |
1070 | # CONFIG_AUTOFS4_FS is not set | 1194 | # CONFIG_AUTOFS4_FS is not set |
1071 | # CONFIG_FUSE_FS is not set | 1195 | # CONFIG_FUSE_FS is not set |
1072 | 1196 | ||
@@ -1081,8 +1205,11 @@ CONFIG_JOLIET=y | |||
1081 | # | 1205 | # |
1082 | # DOS/FAT/NT Filesystems | 1206 | # DOS/FAT/NT Filesystems |
1083 | # | 1207 | # |
1208 | CONFIG_FAT_FS=y | ||
1084 | # CONFIG_MSDOS_FS is not set | 1209 | # CONFIG_MSDOS_FS is not set |
1085 | # CONFIG_VFAT_FS is not set | 1210 | CONFIG_VFAT_FS=y |
1211 | CONFIG_FAT_DEFAULT_CODEPAGE=437 | ||
1212 | CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" | ||
1086 | # CONFIG_NTFS_FS is not set | 1213 | # CONFIG_NTFS_FS is not set |
1087 | 1214 | ||
1088 | # | 1215 | # |
@@ -1125,7 +1252,7 @@ CONFIG_NFS_V3=y | |||
1125 | CONFIG_NFSD=y | 1252 | CONFIG_NFSD=y |
1126 | CONFIG_NFSD_V3=y | 1253 | CONFIG_NFSD_V3=y |
1127 | # CONFIG_NFSD_V3_ACL is not set | 1254 | # CONFIG_NFSD_V3_ACL is not set |
1128 | # CONFIG_NFSD_V4 is not set | 1255 | CONFIG_NFSD_V4=y |
1129 | CONFIG_NFSD_TCP=y | 1256 | CONFIG_NFSD_TCP=y |
1130 | CONFIG_ROOT_NFS=y | 1257 | CONFIG_ROOT_NFS=y |
1131 | CONFIG_LOCKD=y | 1258 | CONFIG_LOCKD=y |
@@ -1133,10 +1260,16 @@ CONFIG_LOCKD_V4=y | |||
1133 | CONFIG_EXPORTFS=y | 1260 | CONFIG_EXPORTFS=y |
1134 | CONFIG_NFS_COMMON=y | 1261 | CONFIG_NFS_COMMON=y |
1135 | CONFIG_SUNRPC=y | 1262 | CONFIG_SUNRPC=y |
1136 | # CONFIG_RPCSEC_GSS_KRB5 is not set | 1263 | CONFIG_SUNRPC_GSS=y |
1137 | # CONFIG_RPCSEC_GSS_SPKM3 is not set | 1264 | CONFIG_RPCSEC_GSS_KRB5=y |
1138 | # CONFIG_SMB_FS is not set | 1265 | CONFIG_RPCSEC_GSS_SPKM3=m |
1139 | # CONFIG_CIFS is not set | 1266 | CONFIG_SMB_FS=m |
1267 | CONFIG_SMB_NLS_DEFAULT=y | ||
1268 | CONFIG_SMB_NLS_REMOTE="cp437" | ||
1269 | CONFIG_CIFS=m | ||
1270 | # CONFIG_CIFS_STATS is not set | ||
1271 | # CONFIG_CIFS_XATTR is not set | ||
1272 | # CONFIG_CIFS_EXPERIMENTAL is not set | ||
1140 | # CONFIG_NCP_FS is not set | 1273 | # CONFIG_NCP_FS is not set |
1141 | # CONFIG_CODA_FS is not set | 1274 | # CONFIG_CODA_FS is not set |
1142 | # CONFIG_AFS_FS is not set | 1275 | # CONFIG_AFS_FS is not set |
@@ -1153,50 +1286,50 @@ CONFIG_MSDOS_PARTITION=y | |||
1153 | # | 1286 | # |
1154 | CONFIG_NLS=y | 1287 | CONFIG_NLS=y |
1155 | CONFIG_NLS_DEFAULT="iso8859-1" | 1288 | CONFIG_NLS_DEFAULT="iso8859-1" |
1156 | # CONFIG_NLS_CODEPAGE_437 is not set | 1289 | CONFIG_NLS_CODEPAGE_437=y |
1157 | # CONFIG_NLS_CODEPAGE_737 is not set | 1290 | CONFIG_NLS_CODEPAGE_737=m |
1158 | # CONFIG_NLS_CODEPAGE_775 is not set | 1291 | CONFIG_NLS_CODEPAGE_775=m |
1159 | # CONFIG_NLS_CODEPAGE_850 is not set | 1292 | CONFIG_NLS_CODEPAGE_850=m |
1160 | # CONFIG_NLS_CODEPAGE_852 is not set | 1293 | CONFIG_NLS_CODEPAGE_852=m |
1161 | # CONFIG_NLS_CODEPAGE_855 is not set | 1294 | CONFIG_NLS_CODEPAGE_855=m |
1162 | # CONFIG_NLS_CODEPAGE_857 is not set | 1295 | CONFIG_NLS_CODEPAGE_857=m |
1163 | # CONFIG_NLS_CODEPAGE_860 is not set | 1296 | CONFIG_NLS_CODEPAGE_860=m |
1164 | # CONFIG_NLS_CODEPAGE_861 is not set | 1297 | CONFIG_NLS_CODEPAGE_861=m |
1165 | # CONFIG_NLS_CODEPAGE_862 is not set | 1298 | CONFIG_NLS_CODEPAGE_862=m |
1166 | # CONFIG_NLS_CODEPAGE_863 is not set | 1299 | CONFIG_NLS_CODEPAGE_863=m |
1167 | # CONFIG_NLS_CODEPAGE_864 is not set | 1300 | CONFIG_NLS_CODEPAGE_864=m |
1168 | # CONFIG_NLS_CODEPAGE_865 is not set | 1301 | CONFIG_NLS_CODEPAGE_865=m |
1169 | # CONFIG_NLS_CODEPAGE_866 is not set | 1302 | CONFIG_NLS_CODEPAGE_866=m |
1170 | # CONFIG_NLS_CODEPAGE_869 is not set | 1303 | CONFIG_NLS_CODEPAGE_869=m |
1171 | # CONFIG_NLS_CODEPAGE_936 is not set | 1304 | CONFIG_NLS_CODEPAGE_936=m |
1172 | # CONFIG_NLS_CODEPAGE_950 is not set | 1305 | CONFIG_NLS_CODEPAGE_950=m |
1173 | # CONFIG_NLS_CODEPAGE_932 is not set | 1306 | CONFIG_NLS_CODEPAGE_932=m |
1174 | # CONFIG_NLS_CODEPAGE_949 is not set | 1307 | CONFIG_NLS_CODEPAGE_949=m |
1175 | # CONFIG_NLS_CODEPAGE_874 is not set | 1308 | CONFIG_NLS_CODEPAGE_874=m |
1176 | # CONFIG_NLS_ISO8859_8 is not set | 1309 | CONFIG_NLS_ISO8859_8=m |
1177 | # CONFIG_NLS_CODEPAGE_1250 is not set | 1310 | CONFIG_NLS_CODEPAGE_1250=y |
1178 | # CONFIG_NLS_CODEPAGE_1251 is not set | 1311 | CONFIG_NLS_CODEPAGE_1251=m |
1179 | # CONFIG_NLS_ASCII is not set | 1312 | CONFIG_NLS_ASCII=m |
1180 | # CONFIG_NLS_ISO8859_1 is not set | 1313 | CONFIG_NLS_ISO8859_1=y |
1181 | # CONFIG_NLS_ISO8859_2 is not set | 1314 | CONFIG_NLS_ISO8859_2=m |
1182 | # CONFIG_NLS_ISO8859_3 is not set | 1315 | CONFIG_NLS_ISO8859_3=m |
1183 | # CONFIG_NLS_ISO8859_4 is not set | 1316 | CONFIG_NLS_ISO8859_4=m |
1184 | # CONFIG_NLS_ISO8859_5 is not set | 1317 | CONFIG_NLS_ISO8859_5=m |
1185 | # CONFIG_NLS_ISO8859_6 is not set | 1318 | CONFIG_NLS_ISO8859_6=m |
1186 | # CONFIG_NLS_ISO8859_7 is not set | 1319 | CONFIG_NLS_ISO8859_7=m |
1187 | # CONFIG_NLS_ISO8859_9 is not set | 1320 | CONFIG_NLS_ISO8859_9=m |
1188 | # CONFIG_NLS_ISO8859_13 is not set | 1321 | CONFIG_NLS_ISO8859_13=m |
1189 | # CONFIG_NLS_ISO8859_14 is not set | 1322 | CONFIG_NLS_ISO8859_14=m |
1190 | # CONFIG_NLS_ISO8859_15 is not set | 1323 | CONFIG_NLS_ISO8859_15=m |
1191 | # CONFIG_NLS_KOI8_R is not set | 1324 | CONFIG_NLS_KOI8_R=m |
1192 | # CONFIG_NLS_KOI8_U is not set | 1325 | CONFIG_NLS_KOI8_U=m |
1193 | # CONFIG_NLS_UTF8 is not set | 1326 | CONFIG_NLS_UTF8=y |
1194 | 1327 | ||
1195 | # | 1328 | # |
1196 | # Profiling support | 1329 | # Profiling support |
1197 | # | 1330 | # |
1198 | CONFIG_PROFILING=y | 1331 | CONFIG_PROFILING=y |
1199 | CONFIG_OPROFILE=y | 1332 | CONFIG_OPROFILE=m |
1200 | 1333 | ||
1201 | # | 1334 | # |
1202 | # Kernel hacking | 1335 | # Kernel hacking |
@@ -1204,7 +1337,7 @@ CONFIG_OPROFILE=y | |||
1204 | # CONFIG_PRINTK_TIME is not set | 1337 | # CONFIG_PRINTK_TIME is not set |
1205 | CONFIG_MAGIC_SYSRQ=y | 1338 | CONFIG_MAGIC_SYSRQ=y |
1206 | CONFIG_DEBUG_KERNEL=y | 1339 | CONFIG_DEBUG_KERNEL=y |
1207 | CONFIG_LOG_BUF_SHIFT=15 | 1340 | CONFIG_LOG_BUF_SHIFT=16 |
1208 | CONFIG_DETECT_SOFTLOCKUP=y | 1341 | CONFIG_DETECT_SOFTLOCKUP=y |
1209 | # CONFIG_SCHEDSTATS is not set | 1342 | # CONFIG_SCHEDSTATS is not set |
1210 | # CONFIG_DEBUG_SLAB is not set | 1343 | # CONFIG_DEBUG_SLAB is not set |
@@ -1217,42 +1350,43 @@ CONFIG_DEBUG_MUTEXES=y | |||
1217 | # CONFIG_DEBUG_VM is not set | 1350 | # CONFIG_DEBUG_VM is not set |
1218 | CONFIG_FORCED_INLINING=y | 1351 | CONFIG_FORCED_INLINING=y |
1219 | # CONFIG_RCU_TORTURE_TEST is not set | 1352 | # CONFIG_RCU_TORTURE_TEST is not set |
1220 | CONFIG_DEBUG_RODATA=y | 1353 | # CONFIG_DEBUG_RODATA is not set |
1221 | 1354 | ||
1222 | # | 1355 | # |
1223 | # Security options | 1356 | # Security options |
1224 | # | 1357 | # |
1225 | # CONFIG_KEYS is not set | 1358 | CONFIG_KEYS=y |
1359 | CONFIG_KEYS_DEBUG_PROC_KEYS=y | ||
1226 | # CONFIG_SECURITY is not set | 1360 | # CONFIG_SECURITY is not set |
1227 | 1361 | ||
1228 | # | 1362 | # |
1229 | # Cryptographic options | 1363 | # Cryptographic options |
1230 | # | 1364 | # |
1231 | CONFIG_CRYPTO=y | 1365 | CONFIG_CRYPTO=y |
1232 | # CONFIG_CRYPTO_HMAC is not set | 1366 | CONFIG_CRYPTO_HMAC=y |
1233 | # CONFIG_CRYPTO_NULL is not set | 1367 | CONFIG_CRYPTO_NULL=m |
1234 | # CONFIG_CRYPTO_MD4 is not set | 1368 | CONFIG_CRYPTO_MD4=m |
1235 | # CONFIG_CRYPTO_MD5 is not set | 1369 | CONFIG_CRYPTO_MD5=y |
1236 | # CONFIG_CRYPTO_SHA1 is not set | 1370 | CONFIG_CRYPTO_SHA1=y |
1237 | # CONFIG_CRYPTO_SHA256 is not set | 1371 | CONFIG_CRYPTO_SHA256=m |
1238 | # CONFIG_CRYPTO_SHA512 is not set | 1372 | CONFIG_CRYPTO_SHA512=m |
1239 | # CONFIG_CRYPTO_WP512 is not set | 1373 | CONFIG_CRYPTO_WP512=m |
1240 | # CONFIG_CRYPTO_TGR192 is not set | 1374 | CONFIG_CRYPTO_TGR192=m |
1241 | # CONFIG_CRYPTO_DES is not set | 1375 | CONFIG_CRYPTO_DES=y |
1242 | # CONFIG_CRYPTO_BLOWFISH is not set | 1376 | CONFIG_CRYPTO_BLOWFISH=m |
1243 | # CONFIG_CRYPTO_TWOFISH is not set | 1377 | CONFIG_CRYPTO_TWOFISH=m |
1244 | # CONFIG_CRYPTO_SERPENT is not set | 1378 | CONFIG_CRYPTO_SERPENT=m |
1245 | # CONFIG_CRYPTO_AES is not set | 1379 | CONFIG_CRYPTO_AES=m |
1246 | # CONFIG_CRYPTO_CAST5 is not set | 1380 | CONFIG_CRYPTO_CAST5=m |
1247 | # CONFIG_CRYPTO_CAST6 is not set | 1381 | CONFIG_CRYPTO_CAST6=m |
1248 | # CONFIG_CRYPTO_TEA is not set | 1382 | CONFIG_CRYPTO_TEA=m |
1249 | # CONFIG_CRYPTO_ARC4 is not set | 1383 | CONFIG_CRYPTO_ARC4=m |
1250 | # CONFIG_CRYPTO_KHAZAD is not set | 1384 | CONFIG_CRYPTO_KHAZAD=m |
1251 | # CONFIG_CRYPTO_ANUBIS is not set | 1385 | CONFIG_CRYPTO_ANUBIS=m |
1252 | # CONFIG_CRYPTO_DEFLATE is not set | 1386 | CONFIG_CRYPTO_DEFLATE=y |
1253 | # CONFIG_CRYPTO_MICHAEL_MIC is not set | 1387 | CONFIG_CRYPTO_MICHAEL_MIC=m |
1254 | # CONFIG_CRYPTO_CRC32C is not set | 1388 | CONFIG_CRYPTO_CRC32C=m |
1255 | # CONFIG_CRYPTO_TEST is not set | 1389 | CONFIG_CRYPTO_TEST=m |
1256 | 1390 | ||
1257 | # | 1391 | # |
1258 | # Hardware crypto devices | 1392 | # Hardware crypto devices |
@@ -1261,7 +1395,9 @@ CONFIG_CRYPTO=y | |||
1261 | # | 1395 | # |
1262 | # Library routines | 1396 | # Library routines |
1263 | # | 1397 | # |
1264 | # CONFIG_CRC_CCITT is not set | 1398 | CONFIG_CRC_CCITT=m |
1265 | # CONFIG_CRC16 is not set | 1399 | # CONFIG_CRC16 is not set |
1266 | CONFIG_CRC32=y | 1400 | CONFIG_CRC32=y |
1267 | # CONFIG_LIBCRC32C is not set | 1401 | CONFIG_LIBCRC32C=m |
1402 | CONFIG_ZLIB_INFLATE=y | ||
1403 | CONFIG_ZLIB_DEFLATE=y | ||
diff --git a/arch/parisc/kernel/asm-offsets.c b/arch/parisc/kernel/asm-offsets.c index e23c4e1e3a25..c11a5bc7c067 100644 --- a/arch/parisc/kernel/asm-offsets.c +++ b/arch/parisc/kernel/asm-offsets.c | |||
@@ -288,8 +288,11 @@ int main(void) | |||
288 | DEFINE(ASM_PGD_ENTRY_SIZE, PGD_ENTRY_SIZE); | 288 | DEFINE(ASM_PGD_ENTRY_SIZE, PGD_ENTRY_SIZE); |
289 | DEFINE(ASM_PMD_ENTRY_SIZE, PMD_ENTRY_SIZE); | 289 | DEFINE(ASM_PMD_ENTRY_SIZE, PMD_ENTRY_SIZE); |
290 | DEFINE(ASM_PTE_ENTRY_SIZE, PTE_ENTRY_SIZE); | 290 | DEFINE(ASM_PTE_ENTRY_SIZE, PTE_ENTRY_SIZE); |
291 | DEFINE(ASM_PFN_PTE_SHIFT, PFN_PTE_SHIFT); | ||
291 | DEFINE(ASM_PT_INITIAL, PT_INITIAL); | 292 | DEFINE(ASM_PT_INITIAL, PT_INITIAL); |
292 | DEFINE(ASM_PAGE_SIZE, PAGE_SIZE); | 293 | DEFINE(ASM_PAGE_SIZE, PAGE_SIZE); |
294 | DEFINE(ASM_PAGE_SIZE_DIV64, PAGE_SIZE/64); | ||
295 | DEFINE(ASM_PAGE_SIZE_DIV128, PAGE_SIZE/128); | ||
293 | BLANK(); | 296 | BLANK(); |
294 | DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip)); | 297 | DEFINE(EXCDATA_IP, offsetof(struct exception_data, fault_ip)); |
295 | DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space)); | 298 | DEFINE(EXCDATA_SPACE, offsetof(struct exception_data, fault_space)); |
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c index 360b7391cb8c..c057ad7605ba 100644 --- a/arch/parisc/kernel/cache.c +++ b/arch/parisc/kernel/cache.c | |||
@@ -4,7 +4,7 @@ | |||
4 | * License. See the file "COPYING" in the main directory of this archive | 4 | * License. See the file "COPYING" in the main directory of this archive |
5 | * for more details. | 5 | * for more details. |
6 | * | 6 | * |
7 | * Copyright (C) 1999 Helge Deller (07-13-1999) | 7 | * Copyright (C) 1999-2006 Helge Deller <deller@gmx.de> (07-13-1999) |
8 | * Copyright (C) 1999 SuSE GmbH Nuernberg | 8 | * Copyright (C) 1999 SuSE GmbH Nuernberg |
9 | * Copyright (C) 2000 Philipp Rumpf (prumpf@tux.org) | 9 | * Copyright (C) 2000 Philipp Rumpf (prumpf@tux.org) |
10 | * | 10 | * |
@@ -358,5 +358,5 @@ void parisc_setup_cache_timing(void) | |||
358 | if (!parisc_cache_flush_threshold) | 358 | if (!parisc_cache_flush_threshold) |
359 | parisc_cache_flush_threshold = FLUSH_THRESHOLD; | 359 | parisc_cache_flush_threshold = FLUSH_THRESHOLD; |
360 | 360 | ||
361 | printk("Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus()); | 361 | printk(KERN_INFO "Setting cache flush threshold to %x (%d CPUs online)\n", parisc_cache_flush_threshold, num_online_cpus()); |
362 | } | 362 | } |
diff --git a/arch/parisc/kernel/entry.S b/arch/parisc/kernel/entry.S index 7c95d7663c29..d9e53cf0372b 100644 --- a/arch/parisc/kernel/entry.S +++ b/arch/parisc/kernel/entry.S | |||
@@ -502,18 +502,20 @@ | |||
502 | * all ILP32 processes and all the kernel for machines with | 502 | * all ILP32 processes and all the kernel for machines with |
503 | * under 4GB of memory) */ | 503 | * under 4GB of memory) */ |
504 | .macro L3_ptep pgd,pte,index,va,fault | 504 | .macro L3_ptep pgd,pte,index,va,fault |
505 | #if PT_NLEVELS == 3 /* we might have a 2-Level scheme, e.g. with 16kb page size */ | ||
505 | extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index | 506 | extrd,u \va,63-ASM_PGDIR_SHIFT,ASM_BITS_PER_PGD,\index |
506 | copy %r0,\pte | 507 | copy %r0,\pte |
507 | extrd,u,*= \va,31,32,%r0 | 508 | extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 |
508 | ldw,s \index(\pgd),\pgd | 509 | ldw,s \index(\pgd),\pgd |
509 | extrd,u,*= \va,31,32,%r0 | 510 | extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 |
510 | bb,>=,n \pgd,_PxD_PRESENT_BIT,\fault | 511 | bb,>=,n \pgd,_PxD_PRESENT_BIT,\fault |
511 | extrd,u,*= \va,31,32,%r0 | 512 | extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 |
512 | shld \pgd,PxD_VALUE_SHIFT,\index | 513 | shld \pgd,PxD_VALUE_SHIFT,\index |
513 | extrd,u,*= \va,31,32,%r0 | 514 | extrd,u,*= \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 |
514 | copy \index,\pgd | 515 | copy \index,\pgd |
515 | extrd,u,*<> \va,31,32,%r0 | 516 | extrd,u,*<> \va,63-ASM_PGDIR_SHIFT,64-ASM_PGDIR_SHIFT,%r0 |
516 | ldo ASM_PGD_PMD_OFFSET(\pgd),\pgd | 517 | ldo ASM_PGD_PMD_OFFSET(\pgd),\pgd |
518 | #endif | ||
517 | L2_ptep \pgd,\pte,\index,\va,\fault | 519 | L2_ptep \pgd,\pte,\index,\va,\fault |
518 | .endm | 520 | .endm |
519 | 521 | ||
@@ -563,10 +565,18 @@ | |||
563 | extrd,u,*= \pte,_PAGE_GATEWAY_BIT+32,1,%r0 | 565 | extrd,u,*= \pte,_PAGE_GATEWAY_BIT+32,1,%r0 |
564 | depd %r0,11,2,\prot /* If Gateway, Set PL2 to 0 */ | 566 | depd %r0,11,2,\prot /* If Gateway, Set PL2 to 0 */ |
565 | 567 | ||
566 | /* Get rid of prot bits and convert to page addr for iitlbt and idtlbt */ | 568 | /* Enforce uncacheable pages. |
569 | * This should ONLY be use for MMIO on PA 2.0 machines. | ||
570 | * Memory/DMA is cache coherent on all PA2.0 machines we support | ||
571 | * (that means T-class is NOT supported) and the memory controllers | ||
572 | * on most of those machines only handles cache transactions. | ||
573 | */ | ||
574 | extrd,u,*= \pte,_PAGE_NO_CACHE_BIT+32,1,%r0 | ||
575 | depi 1,12,1,\prot | ||
567 | 576 | ||
568 | depd %r0,63,PAGE_SHIFT,\pte | 577 | /* Drop prot bits and convert to page addr for iitlbt and idtlbt */ |
569 | extrd,s \pte,(63-PAGE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte | 578 | extrd,u \pte,(63-ASM_PFN_PTE_SHIFT)+(63-58),64-PAGE_SHIFT,\pte |
579 | depdi _PAGE_SIZE_ENCODING_DEFAULT,63,63-58,\pte | ||
570 | .endm | 580 | .endm |
571 | 581 | ||
572 | /* Identical macro to make_insert_tlb above, except it | 582 | /* Identical macro to make_insert_tlb above, except it |
@@ -584,9 +594,8 @@ | |||
584 | 594 | ||
585 | /* Get rid of prot bits and convert to page addr for iitlba */ | 595 | /* Get rid of prot bits and convert to page addr for iitlba */ |
586 | 596 | ||
587 | depi 0,31,PAGE_SHIFT,\pte | 597 | depi _PAGE_SIZE_ENCODING_DEFAULT,31,ASM_PFN_PTE_SHIFT,\pte |
588 | extru \pte,24,25,\pte | 598 | extru \pte,24,25,\pte |
589 | |||
590 | .endm | 599 | .endm |
591 | 600 | ||
592 | /* This is for ILP32 PA2.0 only. The TLB insertion needs | 601 | /* This is for ILP32 PA2.0 only. The TLB insertion needs |
@@ -1201,10 +1210,9 @@ intr_save: | |||
1201 | */ | 1210 | */ |
1202 | 1211 | ||
1203 | /* adjust isr/ior. */ | 1212 | /* adjust isr/ior. */ |
1204 | 1213 | extrd,u %r16,63,SPACEID_SHIFT,%r1 /* get high bits from isr for ior */ | |
1205 | extrd,u %r16,63,7,%r1 /* get high bits from isr for ior */ | 1214 | depd %r1,31,SPACEID_SHIFT,%r17 /* deposit them into ior */ |
1206 | depd %r1,31,7,%r17 /* deposit them into ior */ | 1215 | depdi 0,63,SPACEID_SHIFT,%r16 /* clear them from isr */ |
1207 | depdi 0,63,7,%r16 /* clear them from isr */ | ||
1208 | #endif | 1216 | #endif |
1209 | STREG %r16, PT_ISR(%r29) | 1217 | STREG %r16, PT_ISR(%r29) |
1210 | STREG %r17, PT_IOR(%r29) | 1218 | STREG %r17, PT_IOR(%r29) |
diff --git a/arch/parisc/kernel/head.S b/arch/parisc/kernel/head.S index 0b47afc20690..3e79e62f7b0b 100644 --- a/arch/parisc/kernel/head.S +++ b/arch/parisc/kernel/head.S | |||
@@ -76,16 +76,16 @@ $bss_loop: | |||
76 | mtctl %r4,%cr24 /* Initialize kernel root pointer */ | 76 | mtctl %r4,%cr24 /* Initialize kernel root pointer */ |
77 | mtctl %r4,%cr25 /* Initialize user root pointer */ | 77 | mtctl %r4,%cr25 /* Initialize user root pointer */ |
78 | 78 | ||
79 | #ifdef CONFIG_64BIT | 79 | #if PT_NLEVELS == 3 |
80 | /* Set pmd in pgd */ | 80 | /* Set pmd in pgd */ |
81 | load32 PA(pmd0),%r5 | 81 | load32 PA(pmd0),%r5 |
82 | shrd %r5,PxD_VALUE_SHIFT,%r3 | 82 | shrd %r5,PxD_VALUE_SHIFT,%r3 |
83 | ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3 | 83 | ldo (PxD_FLAG_PRESENT+PxD_FLAG_VALID)(%r3),%r3 |
84 | stw %r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4) | 84 | stw %r3,ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4) |
85 | ldo ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r4 | 85 | ldo ASM_PMD_ENTRY*ASM_PMD_ENTRY_SIZE(%r5),%r4 |
86 | #else | 86 | #else |
87 | /* 2-level page table, so pmd == pgd */ | 87 | /* 2-level page table, so pmd == pgd */ |
88 | ldo ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4 | 88 | ldo ASM_PGD_ENTRY*ASM_PGD_ENTRY_SIZE(%r4),%r4 |
89 | #endif | 89 | #endif |
90 | 90 | ||
91 | /* Fill in pmd with enough pte directories */ | 91 | /* Fill in pmd with enough pte directories */ |
@@ -99,7 +99,7 @@ $bss_loop: | |||
99 | stw %r3,0(%r4) | 99 | stw %r3,0(%r4) |
100 | ldo (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3 | 100 | ldo (ASM_PAGE_SIZE >> PxD_VALUE_SHIFT)(%r3),%r3 |
101 | addib,> -1,%r1,1b | 101 | addib,> -1,%r1,1b |
102 | #ifdef CONFIG_64BIT | 102 | #if PT_NLEVELS == 3 |
103 | ldo ASM_PMD_ENTRY_SIZE(%r4),%r4 | 103 | ldo ASM_PMD_ENTRY_SIZE(%r4),%r4 |
104 | #else | 104 | #else |
105 | ldo ASM_PGD_ENTRY_SIZE(%r4),%r4 | 105 | ldo ASM_PGD_ENTRY_SIZE(%r4),%r4 |
@@ -107,13 +107,14 @@ $bss_loop: | |||
107 | 107 | ||
108 | 108 | ||
109 | /* Now initialize the PTEs themselves */ | 109 | /* Now initialize the PTEs themselves */ |
110 | ldo _PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */ | 110 | ldo 0+_PAGE_KERNEL(%r0),%r3 /* Hardwired 0 phys addr start */ |
111 | ldi (1<<(KERNEL_INITIAL_ORDER-PAGE_SHIFT)),%r11 /* PFN count */ | ||
111 | load32 PA(pg0),%r1 | 112 | load32 PA(pg0),%r1 |
112 | 113 | ||
113 | $pgt_fill_loop: | 114 | $pgt_fill_loop: |
114 | STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1) | 115 | STREGM %r3,ASM_PTE_ENTRY_SIZE(%r1) |
115 | ldo ASM_PAGE_SIZE(%r3),%r3 | 116 | ldo (1<<PFN_PTE_SHIFT)(%r3),%r3 /* add one PFN */ |
116 | bb,>= %r3,31-KERNEL_INITIAL_ORDER,$pgt_fill_loop | 117 | addib,> -1,%r11,$pgt_fill_loop |
117 | nop | 118 | nop |
118 | 119 | ||
119 | /* Load the return address...er...crash 'n burn */ | 120 | /* Load the return address...er...crash 'n burn */ |
diff --git a/arch/parisc/kernel/init_task.c b/arch/parisc/kernel/init_task.c index 7e898fd64415..8384bf9cecd2 100644 --- a/arch/parisc/kernel/init_task.c +++ b/arch/parisc/kernel/init_task.c | |||
@@ -53,17 +53,17 @@ union thread_union init_thread_union | |||
53 | __attribute__((aligned(128))) __attribute__((__section__(".data.init_task"))) = | 53 | __attribute__((aligned(128))) __attribute__((__section__(".data.init_task"))) = |
54 | { INIT_THREAD_INFO(init_task) }; | 54 | { INIT_THREAD_INFO(init_task) }; |
55 | 55 | ||
56 | #ifdef __LP64__ | 56 | #if PT_NLEVELS == 3 |
57 | /* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout | 57 | /* NOTE: This layout exactly conforms to the hybrid L2/L3 page table layout |
58 | * with the first pmd adjacent to the pgd and below it. gcc doesn't actually | 58 | * with the first pmd adjacent to the pgd and below it. gcc doesn't actually |
59 | * guarantee that global objects will be laid out in memory in the same order | 59 | * guarantee that global objects will be laid out in memory in the same order |
60 | * as the order of declaration, so put these in different sections and use | 60 | * as the order of declaration, so put these in different sections and use |
61 | * the linker script to order them. */ | 61 | * the linker script to order them. */ |
62 | pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((aligned(PAGE_SIZE))) __attribute__ ((__section__ (".data.vm0.pmd"))) = { {0}, }; | 62 | pmd_t pmd0[PTRS_PER_PMD] __attribute__ ((__section__ (".data.vm0.pmd"), aligned(PAGE_SIZE))); |
63 | |||
64 | #endif | 63 | #endif |
65 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((aligned(PAGE_SIZE))) __attribute__ ((__section__ (".data.vm0.pgd"))) = { {0}, }; | 64 | |
66 | pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((aligned(PAGE_SIZE))) __attribute__ ((__section__ (".data.vm0.pte"))) = { {0}, }; | 65 | pgd_t swapper_pg_dir[PTRS_PER_PGD] __attribute__ ((__section__ (".data.vm0.pgd"), aligned(PAGE_SIZE))); |
66 | pte_t pg0[PT_INITIAL * PTRS_PER_PTE] __attribute__ ((__section__ (".data.vm0.pte"), aligned(PAGE_SIZE))); | ||
67 | 67 | ||
68 | /* | 68 | /* |
69 | * Initial task structure. | 69 | * Initial task structure. |
diff --git a/arch/parisc/kernel/pacache.S b/arch/parisc/kernel/pacache.S index 7a4f07e8d3c3..f600556414d1 100644 --- a/arch/parisc/kernel/pacache.S +++ b/arch/parisc/kernel/pacache.S | |||
@@ -65,7 +65,7 @@ flush_tlb_all_local: | |||
65 | */ | 65 | */ |
66 | 66 | ||
67 | /* pcxt_ssm_bug - relied upon translation! PA 2.0 Arch. F-4 and F-5 */ | 67 | /* pcxt_ssm_bug - relied upon translation! PA 2.0 Arch. F-4 and F-5 */ |
68 | rsm PSW_SM_I, %r19 /* save I-bit state */ | 68 | rsm PSW_SM_I, %r19 /* save I-bit state */ |
69 | load32 PA(1f), %r1 | 69 | load32 PA(1f), %r1 |
70 | nop | 70 | nop |
71 | nop | 71 | nop |
@@ -84,8 +84,7 @@ flush_tlb_all_local: | |||
84 | rfi | 84 | rfi |
85 | nop | 85 | nop |
86 | 86 | ||
87 | 1: ldil L%PA(cache_info), %r1 | 87 | 1: load32 PA(cache_info), %r1 |
88 | ldo R%PA(cache_info)(%r1), %r1 | ||
89 | 88 | ||
90 | /* Flush Instruction Tlb */ | 89 | /* Flush Instruction Tlb */ |
91 | 90 | ||
@@ -212,8 +211,7 @@ flush_instruction_cache_local: | |||
212 | .entry | 211 | .entry |
213 | 212 | ||
214 | mtsp %r0, %sr1 | 213 | mtsp %r0, %sr1 |
215 | ldil L%cache_info, %r1 | 214 | load32 cache_info, %r1 |
216 | ldo R%cache_info(%r1), %r1 | ||
217 | 215 | ||
218 | /* Flush Instruction Cache */ | 216 | /* Flush Instruction Cache */ |
219 | 217 | ||
@@ -254,8 +252,7 @@ flush_data_cache_local: | |||
254 | .entry | 252 | .entry |
255 | 253 | ||
256 | mtsp %r0, %sr1 | 254 | mtsp %r0, %sr1 |
257 | ldil L%cache_info, %r1 | 255 | load32 cache_info, %r1 |
258 | ldo R%cache_info(%r1), %r1 | ||
259 | 256 | ||
260 | /* Flush Data Cache */ | 257 | /* Flush Data Cache */ |
261 | 258 | ||
@@ -303,7 +300,8 @@ copy_user_page_asm: | |||
303 | */ | 300 | */ |
304 | 301 | ||
305 | ldd 0(%r25), %r19 | 302 | ldd 0(%r25), %r19 |
306 | ldi 32, %r1 /* PAGE_SIZE/128 == 32 */ | 303 | ldi ASM_PAGE_SIZE_DIV128, %r1 |
304 | |||
307 | ldw 64(%r25), %r0 /* prefetch 1 cacheline ahead */ | 305 | ldw 64(%r25), %r0 /* prefetch 1 cacheline ahead */ |
308 | ldw 128(%r25), %r0 /* prefetch 2 */ | 306 | ldw 128(%r25), %r0 /* prefetch 2 */ |
309 | 307 | ||
@@ -368,7 +366,7 @@ copy_user_page_asm: | |||
368 | * use ldd/std on a 32 bit kernel. | 366 | * use ldd/std on a 32 bit kernel. |
369 | */ | 367 | */ |
370 | ldw 0(%r25), %r19 | 368 | ldw 0(%r25), %r19 |
371 | ldi 64, %r1 /* PAGE_SIZE/64 == 64 */ | 369 | ldi ASM_PAGE_SIZE_DIV64, %r1 |
372 | 370 | ||
373 | 1: | 371 | 1: |
374 | ldw 4(%r25), %r20 | 372 | ldw 4(%r25), %r20 |
@@ -461,6 +459,7 @@ copy_user_page_asm: | |||
461 | sub %r25, %r1, %r23 /* move physical addr into non shadowed reg */ | 459 | sub %r25, %r1, %r23 /* move physical addr into non shadowed reg */ |
462 | 460 | ||
463 | ldil L%(TMPALIAS_MAP_START), %r28 | 461 | ldil L%(TMPALIAS_MAP_START), %r28 |
462 | /* FIXME for different page sizes != 4k */ | ||
464 | #ifdef CONFIG_64BIT | 463 | #ifdef CONFIG_64BIT |
465 | extrd,u %r26,56,32, %r26 /* convert phys addr to tlb insert format */ | 464 | extrd,u %r26,56,32, %r26 /* convert phys addr to tlb insert format */ |
466 | extrd,u %r23,56,32, %r23 /* convert phys addr to tlb insert format */ | 465 | extrd,u %r23,56,32, %r23 /* convert phys addr to tlb insert format */ |
@@ -551,6 +550,7 @@ __clear_user_page_asm: | |||
551 | #ifdef CONFIG_64BIT | 550 | #ifdef CONFIG_64BIT |
552 | #if (TMPALIAS_MAP_START >= 0x80000000) | 551 | #if (TMPALIAS_MAP_START >= 0x80000000) |
553 | depdi 0, 31,32, %r28 /* clear any sign extension */ | 552 | depdi 0, 31,32, %r28 /* clear any sign extension */ |
553 | /* FIXME: page size dependend */ | ||
554 | #endif | 554 | #endif |
555 | extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ | 555 | extrd,u %r26, 56,32, %r26 /* convert phys addr to tlb insert format */ |
556 | depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ | 556 | depd %r25, 63,22, %r28 /* Form aliased virtual address 'to' */ |
@@ -566,10 +566,10 @@ __clear_user_page_asm: | |||
566 | pdtlb 0(%r28) | 566 | pdtlb 0(%r28) |
567 | 567 | ||
568 | #ifdef CONFIG_64BIT | 568 | #ifdef CONFIG_64BIT |
569 | ldi 32, %r1 /* PAGE_SIZE/128 == 32 */ | 569 | ldi ASM_PAGE_SIZE_DIV128, %r1 |
570 | 570 | ||
571 | /* PREFETCH (Write) has not (yet) been proven to help here */ | 571 | /* PREFETCH (Write) has not (yet) been proven to help here */ |
572 | /* #define PREFETCHW_OP ldd 256(%0), %r0 */ | 572 | /* #define PREFETCHW_OP ldd 256(%0), %r0 */ |
573 | 573 | ||
574 | 1: std %r0, 0(%r28) | 574 | 1: std %r0, 0(%r28) |
575 | std %r0, 8(%r28) | 575 | std %r0, 8(%r28) |
@@ -591,8 +591,7 @@ __clear_user_page_asm: | |||
591 | ldo 128(%r28), %r28 | 591 | ldo 128(%r28), %r28 |
592 | 592 | ||
593 | #else /* ! CONFIG_64BIT */ | 593 | #else /* ! CONFIG_64BIT */ |
594 | 594 | ldi ASM_PAGE_SIZE_DIV64, %r1 | |
595 | ldi 64, %r1 /* PAGE_SIZE/64 == 64 */ | ||
596 | 595 | ||
597 | 1: | 596 | 1: |
598 | stw %r0, 0(%r28) | 597 | stw %r0, 0(%r28) |
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index d15a1d53e101..8b5df98e2b31 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c | |||
@@ -231,6 +231,14 @@ asmlinkage long parisc_fadvise64_64(int fd, | |||
231 | (loff_t)high_len << 32 | low_len, advice); | 231 | (loff_t)high_len << 32 | low_len, advice); |
232 | } | 232 | } |
233 | 233 | ||
234 | asmlinkage long parisc_sync_file_range(int fd, | ||
235 | u32 hi_off, u32 lo_off, u32 hi_nbytes, u32 lo_nbytes, | ||
236 | unsigned int flags) | ||
237 | { | ||
238 | return sys_sync_file_range(fd, (loff_t)hi_off << 32 | lo_off, | ||
239 | (loff_t)hi_nbytes << 32 | lo_nbytes, flags); | ||
240 | } | ||
241 | |||
234 | asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag) | 242 | asmlinkage unsigned long sys_alloc_hugepages(int key, unsigned long addr, unsigned long len, int prot, int flag) |
235 | { | 243 | { |
236 | return -ENOMEM; | 244 | return -ENOMEM; |
diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S index af88afef41bd..479d9a017cd1 100644 --- a/arch/parisc/kernel/syscall.S +++ b/arch/parisc/kernel/syscall.S | |||
@@ -55,7 +55,7 @@ | |||
55 | * pointers. | 55 | * pointers. |
56 | */ | 56 | */ |
57 | 57 | ||
58 | .align 4096 | 58 | .align ASM_PAGE_SIZE |
59 | linux_gateway_page: | 59 | linux_gateway_page: |
60 | 60 | ||
61 | /* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */ | 61 | /* ADDRESS 0x00 to 0xb0 = 176 bytes / 4 bytes per insn = 44 insns */ |
@@ -632,7 +632,7 @@ cas_action: | |||
632 | end_compare_and_swap: | 632 | end_compare_and_swap: |
633 | 633 | ||
634 | /* Make sure nothing else is placed on this page */ | 634 | /* Make sure nothing else is placed on this page */ |
635 | .align 4096 | 635 | .align ASM_PAGE_SIZE |
636 | .export end_linux_gateway_page | 636 | .export end_linux_gateway_page |
637 | end_linux_gateway_page: | 637 | end_linux_gateway_page: |
638 | 638 | ||
@@ -652,7 +652,7 @@ end_linux_gateway_page: | |||
652 | 652 | ||
653 | .section .rodata,"a" | 653 | .section .rodata,"a" |
654 | 654 | ||
655 | .align 4096 | 655 | .align ASM_PAGE_SIZE |
656 | /* Light-weight-syscall table */ | 656 | /* Light-weight-syscall table */ |
657 | /* Start of lws table. */ | 657 | /* Start of lws table. */ |
658 | .export lws_table | 658 | .export lws_table |
@@ -662,14 +662,14 @@ lws_table: | |||
662 | LWS_ENTRY(compare_and_swap64) /* 1 - ELF64 Atomic compare and swap */ | 662 | LWS_ENTRY(compare_and_swap64) /* 1 - ELF64 Atomic compare and swap */ |
663 | /* End of lws table */ | 663 | /* End of lws table */ |
664 | 664 | ||
665 | .align 4096 | 665 | .align ASM_PAGE_SIZE |
666 | .export sys_call_table | 666 | .export sys_call_table |
667 | .Lsys_call_table: | 667 | .Lsys_call_table: |
668 | sys_call_table: | 668 | sys_call_table: |
669 | #include "syscall_table.S" | 669 | #include "syscall_table.S" |
670 | 670 | ||
671 | #ifdef CONFIG_64BIT | 671 | #ifdef CONFIG_64BIT |
672 | .align 4096 | 672 | .align ASM_PAGE_SIZE |
673 | .export sys_call_table64 | 673 | .export sys_call_table64 |
674 | .Lsys_call_table64: | 674 | .Lsys_call_table64: |
675 | sys_call_table64: | 675 | sys_call_table64: |
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S index bbeeb614cfab..e27b432f90a8 100644 --- a/arch/parisc/kernel/syscall_table.S +++ b/arch/parisc/kernel/syscall_table.S | |||
@@ -13,7 +13,7 @@ | |||
13 | * Copyright (C) 2001 Helge Deller <deller at parisc-linux.org> | 13 | * Copyright (C) 2001 Helge Deller <deller at parisc-linux.org> |
14 | * Copyright (C) 2000-2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org> | 14 | * Copyright (C) 2000-2001 Thomas Bogendoerfer <tsbogend at parisc-linux.org> |
15 | * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org> | 15 | * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org> |
16 | * | 16 | * Copyright (C) 2005-2006 Kyle McMartin <kyle at parisc-linux.org> |
17 | * | 17 | * |
18 | * This program is free software; you can redistribute it and/or modify | 18 | * This program is free software; you can redistribute it and/or modify |
19 | * it under the terms of the GNU General Public License as published by | 19 | * it under the terms of the GNU General Public License as published by |
@@ -393,5 +393,11 @@ | |||
393 | ENTRY_SAME(readlinkat) /* 285 */ | 393 | ENTRY_SAME(readlinkat) /* 285 */ |
394 | ENTRY_SAME(fchmodat) | 394 | ENTRY_SAME(fchmodat) |
395 | ENTRY_SAME(faccessat) | 395 | ENTRY_SAME(faccessat) |
396 | ENTRY_SAME(unshare) | ||
397 | ENTRY_COMP(set_robust_list) | ||
398 | ENTRY_COMP(get_robust_list) /* 290 */ | ||
399 | ENTRY_SAME(splice) | ||
400 | ENTRY_OURS(sync_file_range) | ||
401 | ENTRY_SAME(tee) | ||
396 | /* Nothing yet */ | 402 | /* Nothing yet */ |
397 | 403 | ||
diff --git a/arch/parisc/kernel/vmlinux.lds.S b/arch/parisc/kernel/vmlinux.lds.S index 6d6436a6b624..94dcc03a28ed 100644 --- a/arch/parisc/kernel/vmlinux.lds.S +++ b/arch/parisc/kernel/vmlinux.lds.S | |||
@@ -6,6 +6,7 @@ | |||
6 | * Copyright (C) 2000 Michael Ang <mang with subcarrier.org> | 6 | * Copyright (C) 2000 Michael Ang <mang with subcarrier.org> |
7 | * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org> | 7 | * Copyright (C) 2002 Randolph Chung <tausq with parisc-linux.org> |
8 | * Copyright (C) 2003 James Bottomley <jejb with parisc-linux.org> | 8 | * Copyright (C) 2003 James Bottomley <jejb with parisc-linux.org> |
9 | * Copyright (C) 2006 Helge Deller <deller@gmx.de> | ||
9 | * | 10 | * |
10 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
@@ -27,6 +28,7 @@ | |||
27 | /* needed for the processor specific cache alignment size */ | 28 | /* needed for the processor specific cache alignment size */ |
28 | #include <asm/cache.h> | 29 | #include <asm/cache.h> |
29 | #include <asm/page.h> | 30 | #include <asm/page.h> |
31 | #include <asm/asm-offsets.h> | ||
30 | 32 | ||
31 | /* ld script to make hppa Linux kernel */ | 33 | /* ld script to make hppa Linux kernel */ |
32 | #ifndef CONFIG_64BIT | 34 | #ifndef CONFIG_64BIT |
@@ -68,7 +70,7 @@ SECTIONS | |||
68 | RODATA | 70 | RODATA |
69 | 71 | ||
70 | /* writeable */ | 72 | /* writeable */ |
71 | . = ALIGN(4096); /* Make sure this is page aligned so | 73 | . = ALIGN(ASM_PAGE_SIZE); /* Make sure this is page aligned so |
72 | that we can properly leave these | 74 | that we can properly leave these |
73 | as writable */ | 75 | as writable */ |
74 | data_start = .; | 76 | data_start = .; |
@@ -81,23 +83,17 @@ SECTIONS | |||
81 | __start___unwind = .; /* unwind info */ | 83 | __start___unwind = .; /* unwind info */ |
82 | .PARISC.unwind : { *(.PARISC.unwind) } | 84 | .PARISC.unwind : { *(.PARISC.unwind) } |
83 | __stop___unwind = .; | 85 | __stop___unwind = .; |
84 | 86 | ||
87 | /* rarely changed data like cpu maps */ | ||
88 | . = ALIGN(16); | ||
89 | .data.read_mostly : { *(.data.read_mostly) } | ||
90 | |||
91 | . = ALIGN(L1_CACHE_BYTES); | ||
85 | .data : { /* Data */ | 92 | .data : { /* Data */ |
86 | *(.data) | 93 | *(.data) |
87 | *(.data.vm0.pmd) | ||
88 | *(.data.vm0.pgd) | ||
89 | *(.data.vm0.pte) | ||
90 | CONSTRUCTORS | 94 | CONSTRUCTORS |
91 | } | 95 | } |
92 | 96 | ||
93 | . = ALIGN(4096); | ||
94 | /* nosave data is really only used for software suspend...it's here | ||
95 | * just in case we ever implement it */ | ||
96 | __nosave_begin = .; | ||
97 | .data_nosave : { *(.data.nosave) } | ||
98 | . = ALIGN(4096); | ||
99 | __nosave_end = .; | ||
100 | |||
101 | . = ALIGN(L1_CACHE_BYTES); | 97 | . = ALIGN(L1_CACHE_BYTES); |
102 | .data.cacheline_aligned : { *(.data.cacheline_aligned) } | 98 | .data.cacheline_aligned : { *(.data.cacheline_aligned) } |
103 | 99 | ||
@@ -105,12 +101,29 @@ SECTIONS | |||
105 | . = ALIGN(16); | 101 | . = ALIGN(16); |
106 | .data.lock_aligned : { *(.data.lock_aligned) } | 102 | .data.lock_aligned : { *(.data.lock_aligned) } |
107 | 103 | ||
108 | /* rarely changed data like cpu maps */ | 104 | . = ALIGN(ASM_PAGE_SIZE); |
109 | . = ALIGN(16); | 105 | /* nosave data is really only used for software suspend...it's here |
110 | .data.read_mostly : { *(.data.read_mostly) } | 106 | * just in case we ever implement it */ |
107 | __nosave_begin = .; | ||
108 | .data_nosave : { *(.data.nosave) } | ||
109 | . = ALIGN(ASM_PAGE_SIZE); | ||
110 | __nosave_end = .; | ||
111 | 111 | ||
112 | _edata = .; /* End of data section */ | 112 | _edata = .; /* End of data section */ |
113 | 113 | ||
114 | __bss_start = .; /* BSS */ | ||
115 | /* page table entries need to be PAGE_SIZE aligned */ | ||
116 | . = ALIGN(ASM_PAGE_SIZE); | ||
117 | .data.vmpages : { | ||
118 | *(.data.vm0.pmd) | ||
119 | *(.data.vm0.pgd) | ||
120 | *(.data.vm0.pte) | ||
121 | } | ||
122 | .bss : { *(.bss) *(COMMON) } | ||
123 | __bss_stop = .; | ||
124 | |||
125 | |||
126 | /* assembler code expects init_task to be 16k aligned */ | ||
114 | . = ALIGN(16384); /* init_task */ | 127 | . = ALIGN(16384); /* init_task */ |
115 | .data.init_task : { *(.data.init_task) } | 128 | .data.init_task : { *(.data.init_task) } |
116 | 129 | ||
@@ -126,6 +139,7 @@ SECTIONS | |||
126 | .dlt : { *(.dlt) } | 139 | .dlt : { *(.dlt) } |
127 | #endif | 140 | #endif |
128 | 141 | ||
142 | /* reserve space for interrupt stack by aligning __init* to 16k */ | ||
129 | . = ALIGN(16384); | 143 | . = ALIGN(16384); |
130 | __init_begin = .; | 144 | __init_begin = .; |
131 | .init.text : { | 145 | .init.text : { |
@@ -166,7 +180,7 @@ SECTIONS | |||
166 | from .altinstructions and .eh_frame */ | 180 | from .altinstructions and .eh_frame */ |
167 | .exit.text : { *(.exit.text) } | 181 | .exit.text : { *(.exit.text) } |
168 | .exit.data : { *(.exit.data) } | 182 | .exit.data : { *(.exit.data) } |
169 | . = ALIGN(4096); | 183 | . = ALIGN(ASM_PAGE_SIZE); |
170 | __initramfs_start = .; | 184 | __initramfs_start = .; |
171 | .init.ramfs : { *(.init.ramfs) } | 185 | .init.ramfs : { *(.init.ramfs) } |
172 | __initramfs_end = .; | 186 | __initramfs_end = .; |
@@ -174,14 +188,10 @@ SECTIONS | |||
174 | __per_cpu_start = .; | 188 | __per_cpu_start = .; |
175 | .data.percpu : { *(.data.percpu) } | 189 | .data.percpu : { *(.data.percpu) } |
176 | __per_cpu_end = .; | 190 | __per_cpu_end = .; |
177 | . = ALIGN(4096); | 191 | . = ALIGN(ASM_PAGE_SIZE); |
178 | __init_end = .; | 192 | __init_end = .; |
179 | /* freed after init ends here */ | 193 | /* freed after init ends here */ |
180 | 194 | ||
181 | __bss_start = .; /* BSS */ | ||
182 | .bss : { *(.bss) *(COMMON) } | ||
183 | __bss_stop = .; | ||
184 | |||
185 | _end = . ; | 195 | _end = . ; |
186 | 196 | ||
187 | /* Sections to be discarded */ | 197 | /* Sections to be discarded */ |
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c index 0ad945d4c0a4..64785e46f93b 100644 --- a/arch/parisc/mm/fault.c +++ b/arch/parisc/mm/fault.c | |||
@@ -186,7 +186,7 @@ good_area: | |||
186 | break; | 186 | break; |
187 | case VM_FAULT_SIGBUS: | 187 | case VM_FAULT_SIGBUS: |
188 | /* | 188 | /* |
189 | * We hit a hared mapping outside of the file, or some | 189 | * We hit a shared mapping outside of the file, or some |
190 | * other thing happened to us that made us unable to | 190 | * other thing happened to us that made us unable to |
191 | * handle the page fault gracefully. | 191 | * handle the page fault gracefully. |
192 | */ | 192 | */ |
diff --git a/arch/parisc/mm/init.c b/arch/parisc/mm/init.c index 3796be67cd53..631712562656 100644 --- a/arch/parisc/mm/init.c +++ b/arch/parisc/mm/init.c | |||
@@ -6,6 +6,7 @@ | |||
6 | * changed by Philipp Rumpf | 6 | * changed by Philipp Rumpf |
7 | * Copyright 1999 Philipp Rumpf (prumpf@tux.org) | 7 | * Copyright 1999 Philipp Rumpf (prumpf@tux.org) |
8 | * Copyright 2004 Randolph Chung (tausq@debian.org) | 8 | * Copyright 2004 Randolph Chung (tausq@debian.org) |
9 | * Copyright 2006 Helge Deller (deller@gmx.de) | ||
9 | * | 10 | * |
10 | */ | 11 | */ |
11 | 12 | ||
@@ -371,8 +372,8 @@ static void __init setup_bootmem(void) | |||
371 | 372 | ||
372 | void free_initmem(void) | 373 | void free_initmem(void) |
373 | { | 374 | { |
374 | unsigned long addr; | 375 | unsigned long addr, init_begin, init_end; |
375 | 376 | ||
376 | printk(KERN_INFO "Freeing unused kernel memory: "); | 377 | printk(KERN_INFO "Freeing unused kernel memory: "); |
377 | 378 | ||
378 | #ifdef CONFIG_DEBUG_KERNEL | 379 | #ifdef CONFIG_DEBUG_KERNEL |
@@ -395,8 +396,11 @@ void free_initmem(void) | |||
395 | local_irq_enable(); | 396 | local_irq_enable(); |
396 | #endif | 397 | #endif |
397 | 398 | ||
398 | addr = (unsigned long)(&__init_begin); | 399 | /* align __init_begin and __init_end to page size, |
399 | for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { | 400 | ignoring linker script where we might have tried to save RAM */ |
401 | init_begin = PAGE_ALIGN((unsigned long)(&__init_begin)); | ||
402 | init_end = PAGE_ALIGN((unsigned long)(&__init_end)); | ||
403 | for (addr = init_begin; addr < init_end; addr += PAGE_SIZE) { | ||
400 | ClearPageReserved(virt_to_page(addr)); | 404 | ClearPageReserved(virt_to_page(addr)); |
401 | init_page_count(virt_to_page(addr)); | 405 | init_page_count(virt_to_page(addr)); |
402 | free_page(addr); | 406 | free_page(addr); |
@@ -407,7 +411,7 @@ void free_initmem(void) | |||
407 | /* set up a new led state on systems shipped LED State panel */ | 411 | /* set up a new led state on systems shipped LED State panel */ |
408 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); | 412 | pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BCOMPLETE); |
409 | 413 | ||
410 | printk("%luk freed\n", (unsigned long)(&__init_end - &__init_begin) >> 10); | 414 | printk("%luk freed\n", (init_end - init_begin) >> 10); |
411 | } | 415 | } |
412 | 416 | ||
413 | 417 | ||
@@ -639,11 +643,13 @@ static void __init map_pages(unsigned long start_vaddr, unsigned long start_padd | |||
639 | * Map the fault vector writable so we can | 643 | * Map the fault vector writable so we can |
640 | * write the HPMC checksum. | 644 | * write the HPMC checksum. |
641 | */ | 645 | */ |
646 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) | ||
642 | if (address >= ro_start && address < ro_end | 647 | if (address >= ro_start && address < ro_end |
643 | && address != fv_addr | 648 | && address != fv_addr |
644 | && address != gw_addr) | 649 | && address != gw_addr) |
645 | pte = __mk_pte(address, PAGE_KERNEL_RO); | 650 | pte = __mk_pte(address, PAGE_KERNEL_RO); |
646 | else | 651 | else |
652 | #endif | ||
647 | pte = __mk_pte(address, pgprot); | 653 | pte = __mk_pte(address, pgprot); |
648 | 654 | ||
649 | if (address >= end_paddr) | 655 | if (address >= end_paddr) |
@@ -874,8 +880,7 @@ unsigned long alloc_sid(void) | |||
874 | flush_tlb_all(); /* flush_tlb_all() calls recycle_sids() */ | 880 | flush_tlb_all(); /* flush_tlb_all() calls recycle_sids() */ |
875 | spin_lock(&sid_lock); | 881 | spin_lock(&sid_lock); |
876 | } | 882 | } |
877 | if (free_space_ids == 0) | 883 | BUG_ON(free_space_ids == 0); |
878 | BUG(); | ||
879 | } | 884 | } |
880 | 885 | ||
881 | free_space_ids--; | 886 | free_space_ids--; |
@@ -899,8 +904,7 @@ void free_sid(unsigned long spaceid) | |||
899 | 904 | ||
900 | spin_lock(&sid_lock); | 905 | spin_lock(&sid_lock); |
901 | 906 | ||
902 | if (*dirty_space_offset & (1L << index)) | 907 | BUG_ON(*dirty_space_offset & (1L << index)); /* attempt to free space id twice */ |
903 | BUG(); /* attempt to free space id twice */ | ||
904 | 908 | ||
905 | *dirty_space_offset |= (1L << index); | 909 | *dirty_space_offset |= (1L << index); |
906 | dirty_space_ids++; | 910 | dirty_space_ids++; |
@@ -975,7 +979,7 @@ static void recycle_sids(void) | |||
975 | 979 | ||
976 | static unsigned long recycle_ndirty; | 980 | static unsigned long recycle_ndirty; |
977 | static unsigned long recycle_dirty_array[SID_ARRAY_SIZE]; | 981 | static unsigned long recycle_dirty_array[SID_ARRAY_SIZE]; |
978 | static unsigned int recycle_inuse = 0; | 982 | static unsigned int recycle_inuse; |
979 | 983 | ||
980 | void flush_tlb_all(void) | 984 | void flush_tlb_all(void) |
981 | { | 985 | { |
@@ -984,9 +988,7 @@ void flush_tlb_all(void) | |||
984 | do_recycle = 0; | 988 | do_recycle = 0; |
985 | spin_lock(&sid_lock); | 989 | spin_lock(&sid_lock); |
986 | if (dirty_space_ids > RECYCLE_THRESHOLD) { | 990 | if (dirty_space_ids > RECYCLE_THRESHOLD) { |
987 | if (recycle_inuse) { | 991 | BUG_ON(recycle_inuse); /* FIXME: Use a semaphore/wait queue here */ |
988 | BUG(); /* FIXME: Use a semaphore/wait queue here */ | ||
989 | } | ||
990 | get_dirty_sids(&recycle_ndirty,recycle_dirty_array); | 992 | get_dirty_sids(&recycle_ndirty,recycle_dirty_array); |
991 | recycle_inuse++; | 993 | recycle_inuse++; |
992 | do_recycle++; | 994 | do_recycle++; |
diff --git a/arch/parisc/mm/ioremap.c b/arch/parisc/mm/ioremap.c index 0db12818d7bc..27384567a1d0 100644 --- a/arch/parisc/mm/ioremap.c +++ b/arch/parisc/mm/ioremap.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * arch/parisc/mm/ioremap.c | 2 | * arch/parisc/mm/ioremap.c |
3 | * | 3 | * |
4 | * (C) Copyright 1995 1996 Linus Torvalds | 4 | * (C) Copyright 1995 1996 Linus Torvalds |
5 | * (C) Copyright 2001 Helge Deller <deller@gmx.de> | 5 | * (C) Copyright 2001-2006 Helge Deller <deller@gmx.de> |
6 | * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> | 6 | * (C) Copyright 2005 Kyle McMartin <kyle@parisc-linux.org> |
7 | */ | 7 | */ |
8 | 8 | ||
@@ -138,6 +138,7 @@ void __iomem * __ioremap(unsigned long phys_addr, unsigned long size, unsigned l | |||
138 | if ((phys_addr >= 0x00080000 && end < 0x000fffff) || | 138 | if ((phys_addr >= 0x00080000 && end < 0x000fffff) || |
139 | (phys_addr >= 0x00500000 && end < 0x03bfffff)) { | 139 | (phys_addr >= 0x00500000 && end < 0x03bfffff)) { |
140 | phys_addr |= F_EXTEND(0xfc000000); | 140 | phys_addr |= F_EXTEND(0xfc000000); |
141 | flags |= _PAGE_NO_CACHE; | ||
141 | } | 142 | } |
142 | #endif | 143 | #endif |
143 | 144 | ||
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 167e70e95556..6729c98b66f9 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -366,6 +366,7 @@ config PPC_PMAC64 | |||
366 | select U3_DART | 366 | select U3_DART |
367 | select MPIC_BROKEN_U3 | 367 | select MPIC_BROKEN_U3 |
368 | select GENERIC_TBSYNC | 368 | select GENERIC_TBSYNC |
369 | select PPC_970_NAP | ||
369 | default y | 370 | default y |
370 | 371 | ||
371 | config PPC_PREP | 372 | config PPC_PREP |
@@ -383,6 +384,7 @@ config PPC_MAPLE | |||
383 | select MPIC_BROKEN_U3 | 384 | select MPIC_BROKEN_U3 |
384 | select GENERIC_TBSYNC | 385 | select GENERIC_TBSYNC |
385 | select PPC_UDBG_16550 | 386 | select PPC_UDBG_16550 |
387 | select PPC_970_NAP | ||
386 | default n | 388 | default n |
387 | help | 389 | help |
388 | This option enables support for the Maple 970FX Evaluation Board. | 390 | This option enables support for the Maple 970FX Evaluation Board. |
@@ -457,6 +459,10 @@ config PPC_MPC106 | |||
457 | bool | 459 | bool |
458 | default n | 460 | default n |
459 | 461 | ||
462 | config PPC_970_NAP | ||
463 | bool | ||
464 | default n | ||
465 | |||
460 | source "drivers/cpufreq/Kconfig" | 466 | source "drivers/cpufreq/Kconfig" |
461 | 467 | ||
462 | config CPU_FREQ_PMAC | 468 | config CPU_FREQ_PMAC |
diff --git a/arch/powerpc/Makefile b/arch/powerpc/Makefile index 6ec84d37a337..ed5b26aa8be3 100644 --- a/arch/powerpc/Makefile +++ b/arch/powerpc/Makefile | |||
@@ -104,6 +104,10 @@ ifndef CONFIG_FSL_BOOKE | |||
104 | CFLAGS += -mstring | 104 | CFLAGS += -mstring |
105 | endif | 105 | endif |
106 | 106 | ||
107 | ifeq ($(CONFIG_6xx),y) | ||
108 | CFLAGS += -mcpu=powerpc | ||
109 | endif | ||
110 | |||
107 | cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge | 111 | cpu-as-$(CONFIG_PPC64BRIDGE) += -Wa,-mppc64bridge |
108 | cpu-as-$(CONFIG_4xx) += -Wa,-m405 | 112 | cpu-as-$(CONFIG_4xx) += -Wa,-m405 |
109 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec | 113 | cpu-as-$(CONFIG_6xx) += -Wa,-maltivec |
diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 2c3fd2007676..a45627547d03 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-rc2 | 3 | # Linux kernel version: 2.6.17-rc1 |
4 | # Fri Feb 10 17:33:08 2006 | 4 | # Wed Apr 19 13:24:37 2006 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -9,6 +9,7 @@ CONFIG_PPC_MERGE=y | |||
9 | CONFIG_MMU=y | 9 | CONFIG_MMU=y |
10 | CONFIG_GENERIC_HARDIRQS=y | 10 | CONFIG_GENERIC_HARDIRQS=y |
11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
12 | CONFIG_GENERIC_HWEIGHT=y | ||
12 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 13 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
13 | CONFIG_PPC=y | 14 | CONFIG_PPC=y |
14 | CONFIG_EARLY_PRINTK=y | 15 | CONFIG_EARLY_PRINTK=y |
@@ -29,6 +30,7 @@ CONFIG_POWER4=y | |||
29 | CONFIG_PPC_FPU=y | 30 | CONFIG_PPC_FPU=y |
30 | CONFIG_ALTIVEC=y | 31 | CONFIG_ALTIVEC=y |
31 | CONFIG_PPC_STD_MMU=y | 32 | CONFIG_PPC_STD_MMU=y |
33 | CONFIG_VIRT_CPU_ACCOUNTING=y | ||
32 | CONFIG_SMP=y | 34 | CONFIG_SMP=y |
33 | CONFIG_NR_CPUS=4 | 35 | CONFIG_NR_CPUS=4 |
34 | 36 | ||
@@ -53,6 +55,7 @@ CONFIG_SYSCTL=y | |||
53 | CONFIG_IKCONFIG=y | 55 | CONFIG_IKCONFIG=y |
54 | CONFIG_IKCONFIG_PROC=y | 56 | CONFIG_IKCONFIG_PROC=y |
55 | # CONFIG_CPUSETS is not set | 57 | # CONFIG_CPUSETS is not set |
58 | # CONFIG_RELAY is not set | ||
56 | CONFIG_INITRAMFS_SOURCE="" | 59 | CONFIG_INITRAMFS_SOURCE="" |
57 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 60 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
58 | # CONFIG_EMBEDDED is not set | 61 | # CONFIG_EMBEDDED is not set |
@@ -67,10 +70,6 @@ CONFIG_BASE_FULL=y | |||
67 | CONFIG_FUTEX=y | 70 | CONFIG_FUTEX=y |
68 | CONFIG_EPOLL=y | 71 | CONFIG_EPOLL=y |
69 | CONFIG_SHMEM=y | 72 | CONFIG_SHMEM=y |
70 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
71 | CONFIG_CC_ALIGN_LABELS=0 | ||
72 | CONFIG_CC_ALIGN_LOOPS=0 | ||
73 | CONFIG_CC_ALIGN_JUMPS=0 | ||
74 | CONFIG_SLAB=y | 73 | CONFIG_SLAB=y |
75 | # CONFIG_TINY_SHMEM is not set | 74 | # CONFIG_TINY_SHMEM is not set |
76 | CONFIG_BASE_SMALL=0 | 75 | CONFIG_BASE_SMALL=0 |
@@ -82,7 +81,6 @@ CONFIG_BASE_SMALL=0 | |||
82 | CONFIG_MODULES=y | 81 | CONFIG_MODULES=y |
83 | CONFIG_MODULE_UNLOAD=y | 82 | CONFIG_MODULE_UNLOAD=y |
84 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 83 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
85 | CONFIG_OBSOLETE_MODPARM=y | ||
86 | CONFIG_MODVERSIONS=y | 84 | CONFIG_MODVERSIONS=y |
87 | CONFIG_MODULE_SRCVERSION_ALL=y | 85 | CONFIG_MODULE_SRCVERSION_ALL=y |
88 | CONFIG_KMOD=y | 86 | CONFIG_KMOD=y |
@@ -91,6 +89,7 @@ CONFIG_STOP_MACHINE=y | |||
91 | # | 89 | # |
92 | # Block layer | 90 | # Block layer |
93 | # | 91 | # |
92 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
94 | 93 | ||
95 | # | 94 | # |
96 | # IO Schedulers | 95 | # IO Schedulers |
@@ -185,7 +184,6 @@ CONFIG_GENERIC_ISA_DMA=y | |||
185 | # CONFIG_PPC_INDIRECT_PCI is not set | 184 | # CONFIG_PPC_INDIRECT_PCI is not set |
186 | CONFIG_PCI=y | 185 | CONFIG_PCI=y |
187 | CONFIG_PCI_DOMAINS=y | 186 | CONFIG_PCI_DOMAINS=y |
188 | CONFIG_PCI_LEGACY_PROC=y | ||
189 | # CONFIG_PCI_DEBUG is not set | 187 | # CONFIG_PCI_DEBUG is not set |
190 | 188 | ||
191 | # | 189 | # |
@@ -227,6 +225,7 @@ CONFIG_SYN_COOKIES=y | |||
227 | CONFIG_INET_AH=m | 225 | CONFIG_INET_AH=m |
228 | CONFIG_INET_ESP=m | 226 | CONFIG_INET_ESP=m |
229 | CONFIG_INET_IPCOMP=m | 227 | CONFIG_INET_IPCOMP=m |
228 | CONFIG_INET_XFRM_TUNNEL=m | ||
230 | CONFIG_INET_TUNNEL=y | 229 | CONFIG_INET_TUNNEL=y |
231 | CONFIG_INET_DIAG=y | 230 | CONFIG_INET_DIAG=y |
232 | CONFIG_INET_TCP_DIAG=y | 231 | CONFIG_INET_TCP_DIAG=y |
@@ -238,6 +237,8 @@ CONFIG_TCP_CONG_BIC=y | |||
238 | # | 237 | # |
239 | # CONFIG_IP_VS is not set | 238 | # CONFIG_IP_VS is not set |
240 | # CONFIG_IPV6 is not set | 239 | # CONFIG_IPV6 is not set |
240 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
241 | # CONFIG_INET6_TUNNEL is not set | ||
241 | CONFIG_NETFILTER=y | 242 | CONFIG_NETFILTER=y |
242 | # CONFIG_NETFILTER_DEBUG is not set | 243 | # CONFIG_NETFILTER_DEBUG is not set |
243 | 244 | ||
@@ -261,6 +262,7 @@ CONFIG_IP_NF_IRC=m | |||
261 | CONFIG_IP_NF_TFTP=m | 262 | CONFIG_IP_NF_TFTP=m |
262 | CONFIG_IP_NF_AMANDA=m | 263 | CONFIG_IP_NF_AMANDA=m |
263 | # CONFIG_IP_NF_PPTP is not set | 264 | # CONFIG_IP_NF_PPTP is not set |
265 | # CONFIG_IP_NF_H323 is not set | ||
264 | CONFIG_IP_NF_QUEUE=m | 266 | CONFIG_IP_NF_QUEUE=m |
265 | 267 | ||
266 | # | 268 | # |
@@ -513,6 +515,7 @@ CONFIG_MD_RAID0=y | |||
513 | CONFIG_MD_RAID1=y | 515 | CONFIG_MD_RAID1=y |
514 | CONFIG_MD_RAID10=m | 516 | CONFIG_MD_RAID10=m |
515 | CONFIG_MD_RAID5=y | 517 | CONFIG_MD_RAID5=y |
518 | # CONFIG_MD_RAID5_RESHAPE is not set | ||
516 | CONFIG_MD_RAID6=m | 519 | CONFIG_MD_RAID6=m |
517 | CONFIG_MD_MULTIPATH=m | 520 | CONFIG_MD_MULTIPATH=m |
518 | CONFIG_MD_FAULTY=m | 521 | CONFIG_MD_FAULTY=m |
@@ -761,7 +764,6 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
761 | # Watchdog Cards | 764 | # Watchdog Cards |
762 | # | 765 | # |
763 | # CONFIG_WATCHDOG is not set | 766 | # CONFIG_WATCHDOG is not set |
764 | # CONFIG_RTC is not set | ||
765 | CONFIG_GEN_RTC=y | 767 | CONFIG_GEN_RTC=y |
766 | # CONFIG_GEN_RTC_X is not set | 768 | # CONFIG_GEN_RTC_X is not set |
767 | # CONFIG_DTLK is not set | 769 | # CONFIG_DTLK is not set |
@@ -772,6 +774,7 @@ CONFIG_GEN_RTC=y | |||
772 | # Ftape, the floppy tape device driver | 774 | # Ftape, the floppy tape device driver |
773 | # | 775 | # |
774 | CONFIG_AGP=m | 776 | CONFIG_AGP=m |
777 | # CONFIG_AGP_VIA is not set | ||
775 | CONFIG_AGP_UNINORTH=m | 778 | CONFIG_AGP_UNINORTH=m |
776 | # CONFIG_DRM is not set | 779 | # CONFIG_DRM is not set |
777 | CONFIG_RAW_DRIVER=y | 780 | CONFIG_RAW_DRIVER=y |
@@ -813,7 +816,6 @@ CONFIG_I2C_POWERMAC=y | |||
813 | # CONFIG_I2C_PARPORT_LIGHT is not set | 816 | # CONFIG_I2C_PARPORT_LIGHT is not set |
814 | # CONFIG_I2C_PROSAVAGE is not set | 817 | # CONFIG_I2C_PROSAVAGE is not set |
815 | # CONFIG_I2C_SAVAGE4 is not set | 818 | # CONFIG_I2C_SAVAGE4 is not set |
816 | # CONFIG_SCx200_ACB is not set | ||
817 | # CONFIG_I2C_SIS5595 is not set | 819 | # CONFIG_I2C_SIS5595 is not set |
818 | # CONFIG_I2C_SIS630 is not set | 820 | # CONFIG_I2C_SIS630 is not set |
819 | # CONFIG_I2C_SIS96X is not set | 821 | # CONFIG_I2C_SIS96X is not set |
@@ -832,9 +834,7 @@ CONFIG_I2C_POWERMAC=y | |||
832 | # CONFIG_SENSORS_PCF8574 is not set | 834 | # CONFIG_SENSORS_PCF8574 is not set |
833 | # CONFIG_SENSORS_PCA9539 is not set | 835 | # CONFIG_SENSORS_PCA9539 is not set |
834 | # CONFIG_SENSORS_PCF8591 is not set | 836 | # CONFIG_SENSORS_PCF8591 is not set |
835 | # CONFIG_SENSORS_RTC8564 is not set | ||
836 | # CONFIG_SENSORS_MAX6875 is not set | 837 | # CONFIG_SENSORS_MAX6875 is not set |
837 | # CONFIG_RTC_X1205_I2C is not set | ||
838 | # CONFIG_I2C_DEBUG_CORE is not set | 838 | # CONFIG_I2C_DEBUG_CORE is not set |
839 | # CONFIG_I2C_DEBUG_ALGO is not set | 839 | # CONFIG_I2C_DEBUG_ALGO is not set |
840 | # CONFIG_I2C_DEBUG_BUS is not set | 840 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -862,10 +862,6 @@ CONFIG_I2C_POWERMAC=y | |||
862 | # | 862 | # |
863 | 863 | ||
864 | # | 864 | # |
865 | # Multimedia Capabilities Port drivers | ||
866 | # | ||
867 | |||
868 | # | ||
869 | # Multimedia devices | 865 | # Multimedia devices |
870 | # | 866 | # |
871 | # CONFIG_VIDEO_DEV is not set | 867 | # CONFIG_VIDEO_DEV is not set |
@@ -874,6 +870,7 @@ CONFIG_I2C_POWERMAC=y | |||
874 | # Digital Video Broadcasting Devices | 870 | # Digital Video Broadcasting Devices |
875 | # | 871 | # |
876 | # CONFIG_DVB is not set | 872 | # CONFIG_DVB is not set |
873 | # CONFIG_USB_DABUSB is not set | ||
877 | 874 | ||
878 | # | 875 | # |
879 | # Graphics support | 876 | # Graphics support |
@@ -883,6 +880,7 @@ CONFIG_FB_CFB_FILLRECT=y | |||
883 | CONFIG_FB_CFB_COPYAREA=y | 880 | CONFIG_FB_CFB_COPYAREA=y |
884 | CONFIG_FB_CFB_IMAGEBLIT=y | 881 | CONFIG_FB_CFB_IMAGEBLIT=y |
885 | CONFIG_FB_MACMODES=y | 882 | CONFIG_FB_MACMODES=y |
883 | CONFIG_FB_FIRMWARE_EDID=y | ||
886 | CONFIG_FB_MODE_HELPERS=y | 884 | CONFIG_FB_MODE_HELPERS=y |
887 | CONFIG_FB_TILEBLITTING=y | 885 | CONFIG_FB_TILEBLITTING=y |
888 | # CONFIG_FB_CIRRUS is not set | 886 | # CONFIG_FB_CIRRUS is not set |
@@ -901,7 +899,6 @@ CONFIG_FB_NVIDIA=y | |||
901 | CONFIG_FB_NVIDIA_I2C=y | 899 | CONFIG_FB_NVIDIA_I2C=y |
902 | # CONFIG_FB_RIVA is not set | 900 | # CONFIG_FB_RIVA is not set |
903 | # CONFIG_FB_MATROX is not set | 901 | # CONFIG_FB_MATROX is not set |
904 | # CONFIG_FB_RADEON_OLD is not set | ||
905 | CONFIG_FB_RADEON=y | 902 | CONFIG_FB_RADEON=y |
906 | CONFIG_FB_RADEON_I2C=y | 903 | CONFIG_FB_RADEON_I2C=y |
907 | # CONFIG_FB_RADEON_DEBUG is not set | 904 | # CONFIG_FB_RADEON_DEBUG is not set |
@@ -958,9 +955,11 @@ CONFIG_SND_SEQUENCER=m | |||
958 | CONFIG_SND_OSSEMUL=y | 955 | CONFIG_SND_OSSEMUL=y |
959 | CONFIG_SND_MIXER_OSS=m | 956 | CONFIG_SND_MIXER_OSS=m |
960 | CONFIG_SND_PCM_OSS=m | 957 | CONFIG_SND_PCM_OSS=m |
958 | CONFIG_SND_PCM_OSS_PLUGINS=y | ||
961 | CONFIG_SND_SEQUENCER_OSS=y | 959 | CONFIG_SND_SEQUENCER_OSS=y |
962 | # CONFIG_SND_DYNAMIC_MINORS is not set | 960 | # CONFIG_SND_DYNAMIC_MINORS is not set |
963 | CONFIG_SND_SUPPORT_OLD_API=y | 961 | CONFIG_SND_SUPPORT_OLD_API=y |
962 | CONFIG_SND_VERBOSE_PROCFS=y | ||
964 | # CONFIG_SND_VERBOSE_PRINTK is not set | 963 | # CONFIG_SND_VERBOSE_PRINTK is not set |
965 | # CONFIG_SND_DEBUG is not set | 964 | # CONFIG_SND_DEBUG is not set |
966 | 965 | ||
@@ -977,6 +976,7 @@ CONFIG_SND_SUPPORT_OLD_API=y | |||
977 | # PCI devices | 976 | # PCI devices |
978 | # | 977 | # |
979 | # CONFIG_SND_AD1889 is not set | 978 | # CONFIG_SND_AD1889 is not set |
979 | # CONFIG_SND_ALS300 is not set | ||
980 | # CONFIG_SND_ALS4000 is not set | 980 | # CONFIG_SND_ALS4000 is not set |
981 | # CONFIG_SND_ALI5451 is not set | 981 | # CONFIG_SND_ALI5451 is not set |
982 | # CONFIG_SND_ATIIXP is not set | 982 | # CONFIG_SND_ATIIXP is not set |
@@ -1009,6 +1009,7 @@ CONFIG_SND_SUPPORT_OLD_API=y | |||
1009 | # CONFIG_SND_MIXART is not set | 1009 | # CONFIG_SND_MIXART is not set |
1010 | # CONFIG_SND_NM256 is not set | 1010 | # CONFIG_SND_NM256 is not set |
1011 | # CONFIG_SND_PCXHR is not set | 1011 | # CONFIG_SND_PCXHR is not set |
1012 | # CONFIG_SND_RIPTIDE is not set | ||
1012 | # CONFIG_SND_RME32 is not set | 1013 | # CONFIG_SND_RME32 is not set |
1013 | # CONFIG_SND_RME96 is not set | 1014 | # CONFIG_SND_RME96 is not set |
1014 | # CONFIG_SND_RME9652 is not set | 1015 | # CONFIG_SND_RME9652 is not set |
@@ -1041,6 +1042,7 @@ CONFIG_SND_USB_AUDIO=m | |||
1041 | # | 1042 | # |
1042 | CONFIG_USB_ARCH_HAS_HCD=y | 1043 | CONFIG_USB_ARCH_HAS_HCD=y |
1043 | CONFIG_USB_ARCH_HAS_OHCI=y | 1044 | CONFIG_USB_ARCH_HAS_OHCI=y |
1045 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
1044 | CONFIG_USB=y | 1046 | CONFIG_USB=y |
1045 | # CONFIG_USB_DEBUG is not set | 1047 | # CONFIG_USB_DEBUG is not set |
1046 | 1048 | ||
@@ -1068,7 +1070,6 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y | |||
1068 | # | 1070 | # |
1069 | # USB Device Class drivers | 1071 | # USB Device Class drivers |
1070 | # | 1072 | # |
1071 | # CONFIG_OBSOLETE_OSS_USB_DRIVER is not set | ||
1072 | CONFIG_USB_ACM=m | 1073 | CONFIG_USB_ACM=m |
1073 | CONFIG_USB_PRINTER=y | 1074 | CONFIG_USB_PRINTER=y |
1074 | 1075 | ||
@@ -1126,15 +1127,6 @@ CONFIG_USB_HIDDEV=y | |||
1126 | # CONFIG_USB_MICROTEK is not set | 1127 | # CONFIG_USB_MICROTEK is not set |
1127 | 1128 | ||
1128 | # | 1129 | # |
1129 | # USB Multimedia devices | ||
1130 | # | ||
1131 | # CONFIG_USB_DABUSB is not set | ||
1132 | |||
1133 | # | ||
1134 | # Video4Linux support is needed for USB Multimedia device support | ||
1135 | # | ||
1136 | |||
1137 | # | ||
1138 | # USB Network Adapters | 1130 | # USB Network Adapters |
1139 | # | 1131 | # |
1140 | CONFIG_USB_CATC=m | 1132 | CONFIG_USB_CATC=m |
@@ -1194,6 +1186,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y | |||
1194 | CONFIG_USB_SERIAL_KLSI=m | 1186 | CONFIG_USB_SERIAL_KLSI=m |
1195 | CONFIG_USB_SERIAL_KOBIL_SCT=m | 1187 | CONFIG_USB_SERIAL_KOBIL_SCT=m |
1196 | CONFIG_USB_SERIAL_MCT_U232=m | 1188 | CONFIG_USB_SERIAL_MCT_U232=m |
1189 | # CONFIG_USB_SERIAL_NAVMAN is not set | ||
1197 | CONFIG_USB_SERIAL_PL2303=m | 1190 | CONFIG_USB_SERIAL_PL2303=m |
1198 | # CONFIG_USB_SERIAL_HP4X is not set | 1191 | # CONFIG_USB_SERIAL_HP4X is not set |
1199 | CONFIG_USB_SERIAL_SAFE=m | 1192 | CONFIG_USB_SERIAL_SAFE=m |
@@ -1237,17 +1230,23 @@ CONFIG_USB_EZUSB=y | |||
1237 | # CONFIG_MMC is not set | 1230 | # CONFIG_MMC is not set |
1238 | 1231 | ||
1239 | # | 1232 | # |
1233 | # LED devices | ||
1234 | # | ||
1235 | # CONFIG_NEW_LEDS is not set | ||
1236 | |||
1237 | # | ||
1240 | # InfiniBand support | 1238 | # InfiniBand support |
1241 | # | 1239 | # |
1242 | # CONFIG_INFINIBAND is not set | 1240 | # CONFIG_INFINIBAND is not set |
1243 | 1241 | ||
1244 | # | 1242 | # |
1245 | # SN Devices | 1243 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) |
1246 | # | 1244 | # |
1247 | 1245 | ||
1248 | # | 1246 | # |
1249 | # EDAC - error detection and reporting (RAS) | 1247 | # Real Time Clock |
1250 | # | 1248 | # |
1249 | # CONFIG_RTC_CLASS is not set | ||
1251 | 1250 | ||
1252 | # | 1251 | # |
1253 | # File systems | 1252 | # File systems |
@@ -1319,7 +1318,6 @@ CONFIG_TMPFS=y | |||
1319 | CONFIG_HUGETLBFS=y | 1318 | CONFIG_HUGETLBFS=y |
1320 | CONFIG_HUGETLB_PAGE=y | 1319 | CONFIG_HUGETLB_PAGE=y |
1321 | CONFIG_RAMFS=y | 1320 | CONFIG_RAMFS=y |
1322 | # CONFIG_RELAYFS_FS is not set | ||
1323 | # CONFIG_CONFIGFS_FS is not set | 1321 | # CONFIG_CONFIGFS_FS is not set |
1324 | 1322 | ||
1325 | # | 1323 | # |
diff --git a/arch/powerpc/configs/iseries_defconfig b/arch/powerpc/configs/iseries_defconfig index 1816a46742f6..a95e455a1944 100644 --- a/arch/powerpc/configs/iseries_defconfig +++ b/arch/powerpc/configs/iseries_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-rc6 | 3 | # Linux kernel version: 2.6.17-rc1 |
4 | # Wed Mar 15 16:19:52 2006 | 4 | # Wed Apr 19 11:46:44 2006 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -9,6 +9,7 @@ CONFIG_PPC_MERGE=y | |||
9 | CONFIG_MMU=y | 9 | CONFIG_MMU=y |
10 | CONFIG_GENERIC_HARDIRQS=y | 10 | CONFIG_GENERIC_HARDIRQS=y |
11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
12 | CONFIG_GENERIC_HWEIGHT=y | ||
12 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 13 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
13 | CONFIG_PPC=y | 14 | CONFIG_PPC=y |
14 | CONFIG_EARLY_PRINTK=y | 15 | CONFIG_EARLY_PRINTK=y |
@@ -30,6 +31,7 @@ CONFIG_POWER4=y | |||
30 | CONFIG_PPC_FPU=y | 31 | CONFIG_PPC_FPU=y |
31 | # CONFIG_ALTIVEC is not set | 32 | # CONFIG_ALTIVEC is not set |
32 | CONFIG_PPC_STD_MMU=y | 33 | CONFIG_PPC_STD_MMU=y |
34 | CONFIG_VIRT_CPU_ACCOUNTING=y | ||
33 | CONFIG_SMP=y | 35 | CONFIG_SMP=y |
34 | CONFIG_NR_CPUS=32 | 36 | CONFIG_NR_CPUS=32 |
35 | 37 | ||
@@ -55,6 +57,7 @@ CONFIG_AUDITSYSCALL=y | |||
55 | CONFIG_IKCONFIG=y | 57 | CONFIG_IKCONFIG=y |
56 | CONFIG_IKCONFIG_PROC=y | 58 | CONFIG_IKCONFIG_PROC=y |
57 | # CONFIG_CPUSETS is not set | 59 | # CONFIG_CPUSETS is not set |
60 | # CONFIG_RELAY is not set | ||
58 | CONFIG_INITRAMFS_SOURCE="" | 61 | CONFIG_INITRAMFS_SOURCE="" |
59 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 62 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
60 | # CONFIG_EMBEDDED is not set | 63 | # CONFIG_EMBEDDED is not set |
@@ -69,10 +72,6 @@ CONFIG_BASE_FULL=y | |||
69 | CONFIG_FUTEX=y | 72 | CONFIG_FUTEX=y |
70 | CONFIG_EPOLL=y | 73 | CONFIG_EPOLL=y |
71 | CONFIG_SHMEM=y | 74 | CONFIG_SHMEM=y |
72 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
73 | CONFIG_CC_ALIGN_LABELS=0 | ||
74 | CONFIG_CC_ALIGN_LOOPS=0 | ||
75 | CONFIG_CC_ALIGN_JUMPS=0 | ||
76 | CONFIG_SLAB=y | 75 | CONFIG_SLAB=y |
77 | # CONFIG_TINY_SHMEM is not set | 76 | # CONFIG_TINY_SHMEM is not set |
78 | CONFIG_BASE_SMALL=0 | 77 | CONFIG_BASE_SMALL=0 |
@@ -84,7 +83,6 @@ CONFIG_BASE_SMALL=0 | |||
84 | CONFIG_MODULES=y | 83 | CONFIG_MODULES=y |
85 | CONFIG_MODULE_UNLOAD=y | 84 | CONFIG_MODULE_UNLOAD=y |
86 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 85 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
87 | CONFIG_OBSOLETE_MODPARM=y | ||
88 | CONFIG_MODVERSIONS=y | 86 | CONFIG_MODVERSIONS=y |
89 | CONFIG_MODULE_SRCVERSION_ALL=y | 87 | CONFIG_MODULE_SRCVERSION_ALL=y |
90 | CONFIG_KMOD=y | 88 | CONFIG_KMOD=y |
@@ -93,6 +91,7 @@ CONFIG_STOP_MACHINE=y | |||
93 | # | 91 | # |
94 | # Block layer | 92 | # Block layer |
95 | # | 93 | # |
94 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
96 | 95 | ||
97 | # | 96 | # |
98 | # IO Schedulers | 97 | # IO Schedulers |
@@ -165,7 +164,6 @@ CONFIG_GENERIC_ISA_DMA=y | |||
165 | # CONFIG_PPC_INDIRECT_PCI is not set | 164 | # CONFIG_PPC_INDIRECT_PCI is not set |
166 | CONFIG_PCI=y | 165 | CONFIG_PCI=y |
167 | CONFIG_PCI_DOMAINS=y | 166 | CONFIG_PCI_DOMAINS=y |
168 | CONFIG_PCI_LEGACY_PROC=y | ||
169 | # CONFIG_PCI_DEBUG is not set | 167 | # CONFIG_PCI_DEBUG is not set |
170 | 168 | ||
171 | # | 169 | # |
@@ -207,6 +205,7 @@ CONFIG_SYN_COOKIES=y | |||
207 | CONFIG_INET_AH=m | 205 | CONFIG_INET_AH=m |
208 | CONFIG_INET_ESP=m | 206 | CONFIG_INET_ESP=m |
209 | CONFIG_INET_IPCOMP=m | 207 | CONFIG_INET_IPCOMP=m |
208 | CONFIG_INET_XFRM_TUNNEL=m | ||
210 | CONFIG_INET_TUNNEL=y | 209 | CONFIG_INET_TUNNEL=y |
211 | CONFIG_INET_DIAG=y | 210 | CONFIG_INET_DIAG=y |
212 | CONFIG_INET_TCP_DIAG=y | 211 | CONFIG_INET_TCP_DIAG=y |
@@ -218,6 +217,8 @@ CONFIG_TCP_CONG_BIC=y | |||
218 | # | 217 | # |
219 | # CONFIG_IP_VS is not set | 218 | # CONFIG_IP_VS is not set |
220 | # CONFIG_IPV6 is not set | 219 | # CONFIG_IPV6 is not set |
220 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
221 | # CONFIG_INET6_TUNNEL is not set | ||
221 | CONFIG_NETFILTER=y | 222 | CONFIG_NETFILTER=y |
222 | # CONFIG_NETFILTER_DEBUG is not set | 223 | # CONFIG_NETFILTER_DEBUG is not set |
223 | 224 | ||
@@ -236,11 +237,14 @@ CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m | |||
236 | CONFIG_NETFILTER_XT_MATCH_CONNMARK=m | 237 | CONFIG_NETFILTER_XT_MATCH_CONNMARK=m |
237 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m | 238 | CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m |
238 | # CONFIG_NETFILTER_XT_MATCH_DCCP is not set | 239 | # CONFIG_NETFILTER_XT_MATCH_DCCP is not set |
240 | # CONFIG_NETFILTER_XT_MATCH_ESP is not set | ||
239 | CONFIG_NETFILTER_XT_MATCH_HELPER=m | 241 | CONFIG_NETFILTER_XT_MATCH_HELPER=m |
240 | CONFIG_NETFILTER_XT_MATCH_LENGTH=m | 242 | CONFIG_NETFILTER_XT_MATCH_LENGTH=m |
241 | CONFIG_NETFILTER_XT_MATCH_LIMIT=m | 243 | CONFIG_NETFILTER_XT_MATCH_LIMIT=m |
242 | CONFIG_NETFILTER_XT_MATCH_MAC=m | 244 | CONFIG_NETFILTER_XT_MATCH_MAC=m |
243 | CONFIG_NETFILTER_XT_MATCH_MARK=m | 245 | CONFIG_NETFILTER_XT_MATCH_MARK=m |
246 | # CONFIG_NETFILTER_XT_MATCH_POLICY is not set | ||
247 | # CONFIG_NETFILTER_XT_MATCH_MULTIPORT is not set | ||
244 | CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m | 248 | CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m |
245 | CONFIG_NETFILTER_XT_MATCH_REALM=m | 249 | CONFIG_NETFILTER_XT_MATCH_REALM=m |
246 | CONFIG_NETFILTER_XT_MATCH_SCTP=m | 250 | CONFIG_NETFILTER_XT_MATCH_SCTP=m |
@@ -262,20 +266,19 @@ CONFIG_IP_NF_IRC=m | |||
262 | CONFIG_IP_NF_TFTP=m | 266 | CONFIG_IP_NF_TFTP=m |
263 | CONFIG_IP_NF_AMANDA=m | 267 | CONFIG_IP_NF_AMANDA=m |
264 | # CONFIG_IP_NF_PPTP is not set | 268 | # CONFIG_IP_NF_PPTP is not set |
269 | # CONFIG_IP_NF_H323 is not set | ||
265 | CONFIG_IP_NF_QUEUE=m | 270 | CONFIG_IP_NF_QUEUE=m |
266 | CONFIG_IP_NF_IPTABLES=m | 271 | CONFIG_IP_NF_IPTABLES=m |
267 | CONFIG_IP_NF_MATCH_IPRANGE=m | 272 | CONFIG_IP_NF_MATCH_IPRANGE=m |
268 | CONFIG_IP_NF_MATCH_MULTIPORT=m | ||
269 | CONFIG_IP_NF_MATCH_TOS=m | 273 | CONFIG_IP_NF_MATCH_TOS=m |
270 | CONFIG_IP_NF_MATCH_RECENT=m | 274 | CONFIG_IP_NF_MATCH_RECENT=m |
271 | CONFIG_IP_NF_MATCH_ECN=m | 275 | CONFIG_IP_NF_MATCH_ECN=m |
272 | CONFIG_IP_NF_MATCH_DSCP=m | 276 | CONFIG_IP_NF_MATCH_DSCP=m |
273 | CONFIG_IP_NF_MATCH_AH_ESP=m | 277 | # CONFIG_IP_NF_MATCH_AH is not set |
274 | CONFIG_IP_NF_MATCH_TTL=m | 278 | CONFIG_IP_NF_MATCH_TTL=m |
275 | CONFIG_IP_NF_MATCH_OWNER=m | 279 | CONFIG_IP_NF_MATCH_OWNER=m |
276 | CONFIG_IP_NF_MATCH_ADDRTYPE=m | 280 | CONFIG_IP_NF_MATCH_ADDRTYPE=m |
277 | CONFIG_IP_NF_MATCH_HASHLIMIT=m | 281 | CONFIG_IP_NF_MATCH_HASHLIMIT=m |
278 | CONFIG_IP_NF_MATCH_POLICY=m | ||
279 | CONFIG_IP_NF_FILTER=m | 282 | CONFIG_IP_NF_FILTER=m |
280 | CONFIG_IP_NF_TARGET_REJECT=m | 283 | CONFIG_IP_NF_TARGET_REJECT=m |
281 | CONFIG_IP_NF_TARGET_LOG=m | 284 | CONFIG_IP_NF_TARGET_LOG=m |
@@ -479,6 +482,7 @@ CONFIG_MD_RAID0=y | |||
479 | CONFIG_MD_RAID1=y | 482 | CONFIG_MD_RAID1=y |
480 | CONFIG_MD_RAID10=m | 483 | CONFIG_MD_RAID10=m |
481 | CONFIG_MD_RAID5=y | 484 | CONFIG_MD_RAID5=y |
485 | # CONFIG_MD_RAID5_RESHAPE is not set | ||
482 | CONFIG_MD_RAID6=m | 486 | CONFIG_MD_RAID6=m |
483 | CONFIG_MD_MULTIPATH=m | 487 | CONFIG_MD_MULTIPATH=m |
484 | CONFIG_MD_FAULTY=m | 488 | CONFIG_MD_FAULTY=m |
@@ -702,7 +706,6 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
702 | # Watchdog Cards | 706 | # Watchdog Cards |
703 | # | 707 | # |
704 | # CONFIG_WATCHDOG is not set | 708 | # CONFIG_WATCHDOG is not set |
705 | # CONFIG_RTC is not set | ||
706 | CONFIG_GEN_RTC=y | 709 | CONFIG_GEN_RTC=y |
707 | # CONFIG_GEN_RTC_X is not set | 710 | # CONFIG_GEN_RTC_X is not set |
708 | # CONFIG_DTLK is not set | 711 | # CONFIG_DTLK is not set |
@@ -751,10 +754,6 @@ CONFIG_MAX_RAW_DEVS=256 | |||
751 | # | 754 | # |
752 | 755 | ||
753 | # | 756 | # |
754 | # Multimedia Capabilities Port drivers | ||
755 | # | ||
756 | |||
757 | # | ||
758 | # Multimedia devices | 757 | # Multimedia devices |
759 | # | 758 | # |
760 | # CONFIG_VIDEO_DEV is not set | 759 | # CONFIG_VIDEO_DEV is not set |
@@ -779,6 +778,7 @@ CONFIG_MAX_RAW_DEVS=256 | |||
779 | # | 778 | # |
780 | CONFIG_USB_ARCH_HAS_HCD=y | 779 | CONFIG_USB_ARCH_HAS_HCD=y |
781 | CONFIG_USB_ARCH_HAS_OHCI=y | 780 | CONFIG_USB_ARCH_HAS_OHCI=y |
781 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
782 | # CONFIG_USB is not set | 782 | # CONFIG_USB is not set |
783 | 783 | ||
784 | # | 784 | # |
@@ -796,6 +796,11 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
796 | # CONFIG_MMC is not set | 796 | # CONFIG_MMC is not set |
797 | 797 | ||
798 | # | 798 | # |
799 | # LED devices | ||
800 | # | ||
801 | # CONFIG_NEW_LEDS is not set | ||
802 | |||
803 | # | ||
799 | # InfiniBand support | 804 | # InfiniBand support |
800 | # | 805 | # |
801 | # CONFIG_INFINIBAND is not set | 806 | # CONFIG_INFINIBAND is not set |
@@ -805,6 +810,11 @@ CONFIG_USB_ARCH_HAS_OHCI=y | |||
805 | # | 810 | # |
806 | 811 | ||
807 | # | 812 | # |
813 | # Real Time Clock | ||
814 | # | ||
815 | # CONFIG_RTC_CLASS is not set | ||
816 | |||
817 | # | ||
808 | # File systems | 818 | # File systems |
809 | # | 819 | # |
810 | CONFIG_EXT2_FS=y | 820 | CONFIG_EXT2_FS=y |
@@ -878,7 +888,6 @@ CONFIG_TMPFS=y | |||
878 | # CONFIG_HUGETLBFS is not set | 888 | # CONFIG_HUGETLBFS is not set |
879 | # CONFIG_HUGETLB_PAGE is not set | 889 | # CONFIG_HUGETLB_PAGE is not set |
880 | CONFIG_RAMFS=y | 890 | CONFIG_RAMFS=y |
881 | # CONFIG_RELAYFS_FS is not set | ||
882 | # CONFIG_CONFIGFS_FS is not set | 891 | # CONFIG_CONFIGFS_FS is not set |
883 | 892 | ||
884 | # | 893 | # |
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index daaf038a1faa..58e68ce09b0f 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.16-rc2 | 3 | # Linux kernel version: 2.6.17-rc1 |
4 | # Fri Feb 10 17:33:32 2006 | 4 | # Wed Apr 19 11:48:00 2006 |
5 | # | 5 | # |
6 | CONFIG_PPC64=y | 6 | CONFIG_PPC64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -9,6 +9,7 @@ CONFIG_PPC_MERGE=y | |||
9 | CONFIG_MMU=y | 9 | CONFIG_MMU=y |
10 | CONFIG_GENERIC_HARDIRQS=y | 10 | CONFIG_GENERIC_HARDIRQS=y |
11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y | 11 | CONFIG_RWSEM_XCHGADD_ALGORITHM=y |
12 | CONFIG_GENERIC_HWEIGHT=y | ||
12 | CONFIG_GENERIC_CALIBRATE_DELAY=y | 13 | CONFIG_GENERIC_CALIBRATE_DELAY=y |
13 | CONFIG_PPC=y | 14 | CONFIG_PPC=y |
14 | CONFIG_EARLY_PRINTK=y | 15 | CONFIG_EARLY_PRINTK=y |
@@ -30,6 +31,7 @@ CONFIG_POWER4=y | |||
30 | CONFIG_PPC_FPU=y | 31 | CONFIG_PPC_FPU=y |
31 | CONFIG_ALTIVEC=y | 32 | CONFIG_ALTIVEC=y |
32 | CONFIG_PPC_STD_MMU=y | 33 | CONFIG_PPC_STD_MMU=y |
34 | CONFIG_VIRT_CPU_ACCOUNTING=y | ||
33 | CONFIG_SMP=y | 35 | CONFIG_SMP=y |
34 | CONFIG_NR_CPUS=128 | 36 | CONFIG_NR_CPUS=128 |
35 | 37 | ||
@@ -55,6 +57,7 @@ CONFIG_AUDITSYSCALL=y | |||
55 | CONFIG_IKCONFIG=y | 57 | CONFIG_IKCONFIG=y |
56 | CONFIG_IKCONFIG_PROC=y | 58 | CONFIG_IKCONFIG_PROC=y |
57 | CONFIG_CPUSETS=y | 59 | CONFIG_CPUSETS=y |
60 | # CONFIG_RELAY is not set | ||
58 | CONFIG_INITRAMFS_SOURCE="" | 61 | CONFIG_INITRAMFS_SOURCE="" |
59 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y | 62 | CONFIG_CC_OPTIMIZE_FOR_SIZE=y |
60 | # CONFIG_EMBEDDED is not set | 63 | # CONFIG_EMBEDDED is not set |
@@ -69,10 +72,6 @@ CONFIG_BASE_FULL=y | |||
69 | CONFIG_FUTEX=y | 72 | CONFIG_FUTEX=y |
70 | CONFIG_EPOLL=y | 73 | CONFIG_EPOLL=y |
71 | CONFIG_SHMEM=y | 74 | CONFIG_SHMEM=y |
72 | CONFIG_CC_ALIGN_FUNCTIONS=0 | ||
73 | CONFIG_CC_ALIGN_LABELS=0 | ||
74 | CONFIG_CC_ALIGN_LOOPS=0 | ||
75 | CONFIG_CC_ALIGN_JUMPS=0 | ||
76 | CONFIG_SLAB=y | 75 | CONFIG_SLAB=y |
77 | # CONFIG_TINY_SHMEM is not set | 76 | # CONFIG_TINY_SHMEM is not set |
78 | CONFIG_BASE_SMALL=0 | 77 | CONFIG_BASE_SMALL=0 |
@@ -84,7 +83,6 @@ CONFIG_BASE_SMALL=0 | |||
84 | CONFIG_MODULES=y | 83 | CONFIG_MODULES=y |
85 | CONFIG_MODULE_UNLOAD=y | 84 | CONFIG_MODULE_UNLOAD=y |
86 | # CONFIG_MODULE_FORCE_UNLOAD is not set | 85 | # CONFIG_MODULE_FORCE_UNLOAD is not set |
87 | CONFIG_OBSOLETE_MODPARM=y | ||
88 | CONFIG_MODVERSIONS=y | 86 | CONFIG_MODVERSIONS=y |
89 | CONFIG_MODULE_SRCVERSION_ALL=y | 87 | CONFIG_MODULE_SRCVERSION_ALL=y |
90 | CONFIG_KMOD=y | 88 | CONFIG_KMOD=y |
@@ -93,6 +91,7 @@ CONFIG_STOP_MACHINE=y | |||
93 | # | 91 | # |
94 | # Block layer | 92 | # Block layer |
95 | # | 93 | # |
94 | # CONFIG_BLK_DEV_IO_TRACE is not set | ||
96 | 95 | ||
97 | # | 96 | # |
98 | # IO Schedulers | 97 | # IO Schedulers |
@@ -188,7 +187,6 @@ CONFIG_PPC_I8259=y | |||
188 | # CONFIG_PPC_INDIRECT_PCI is not set | 187 | # CONFIG_PPC_INDIRECT_PCI is not set |
189 | CONFIG_PCI=y | 188 | CONFIG_PCI=y |
190 | CONFIG_PCI_DOMAINS=y | 189 | CONFIG_PCI_DOMAINS=y |
191 | CONFIG_PCI_LEGACY_PROC=y | ||
192 | # CONFIG_PCI_DEBUG is not set | 190 | # CONFIG_PCI_DEBUG is not set |
193 | 191 | ||
194 | # | 192 | # |
@@ -235,6 +233,7 @@ CONFIG_SYN_COOKIES=y | |||
235 | CONFIG_INET_AH=m | 233 | CONFIG_INET_AH=m |
236 | CONFIG_INET_ESP=m | 234 | CONFIG_INET_ESP=m |
237 | CONFIG_INET_IPCOMP=m | 235 | CONFIG_INET_IPCOMP=m |
236 | CONFIG_INET_XFRM_TUNNEL=m | ||
238 | CONFIG_INET_TUNNEL=y | 237 | CONFIG_INET_TUNNEL=y |
239 | CONFIG_INET_DIAG=y | 238 | CONFIG_INET_DIAG=y |
240 | CONFIG_INET_TCP_DIAG=y | 239 | CONFIG_INET_TCP_DIAG=y |
@@ -246,6 +245,8 @@ CONFIG_TCP_CONG_BIC=y | |||
246 | # | 245 | # |
247 | # CONFIG_IP_VS is not set | 246 | # CONFIG_IP_VS is not set |
248 | # CONFIG_IPV6 is not set | 247 | # CONFIG_IPV6 is not set |
248 | # CONFIG_INET6_XFRM_TUNNEL is not set | ||
249 | # CONFIG_INET6_TUNNEL is not set | ||
249 | CONFIG_NETFILTER=y | 250 | CONFIG_NETFILTER=y |
250 | # CONFIG_NETFILTER_DEBUG is not set | 251 | # CONFIG_NETFILTER_DEBUG is not set |
251 | 252 | ||
@@ -272,6 +273,7 @@ CONFIG_IP_NF_IRC=m | |||
272 | CONFIG_IP_NF_TFTP=m | 273 | CONFIG_IP_NF_TFTP=m |
273 | CONFIG_IP_NF_AMANDA=m | 274 | CONFIG_IP_NF_AMANDA=m |
274 | # CONFIG_IP_NF_PPTP is not set | 275 | # CONFIG_IP_NF_PPTP is not set |
276 | # CONFIG_IP_NF_H323 is not set | ||
275 | CONFIG_IP_NF_QUEUE=m | 277 | CONFIG_IP_NF_QUEUE=m |
276 | 278 | ||
277 | # | 279 | # |
@@ -519,6 +521,7 @@ CONFIG_MD_RAID0=y | |||
519 | CONFIG_MD_RAID1=y | 521 | CONFIG_MD_RAID1=y |
520 | CONFIG_MD_RAID10=m | 522 | CONFIG_MD_RAID10=m |
521 | CONFIG_MD_RAID5=y | 523 | CONFIG_MD_RAID5=y |
524 | # CONFIG_MD_RAID5_RESHAPE is not set | ||
522 | CONFIG_MD_RAID6=m | 525 | CONFIG_MD_RAID6=m |
523 | CONFIG_MD_MULTIPATH=m | 526 | CONFIG_MD_MULTIPATH=m |
524 | CONFIG_MD_FAULTY=m | 527 | CONFIG_MD_FAULTY=m |
@@ -750,6 +753,7 @@ CONFIG_HW_CONSOLE=y | |||
750 | # | 753 | # |
751 | CONFIG_SERIAL_8250=y | 754 | CONFIG_SERIAL_8250=y |
752 | CONFIG_SERIAL_8250_CONSOLE=y | 755 | CONFIG_SERIAL_8250_CONSOLE=y |
756 | CONFIG_SERIAL_8250_PCI=y | ||
753 | CONFIG_SERIAL_8250_NR_UARTS=4 | 757 | CONFIG_SERIAL_8250_NR_UARTS=4 |
754 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 | 758 | CONFIG_SERIAL_8250_RUNTIME_UARTS=4 |
755 | # CONFIG_SERIAL_8250_EXTENDED is not set | 759 | # CONFIG_SERIAL_8250_EXTENDED is not set |
@@ -767,7 +771,9 @@ CONFIG_LEGACY_PTY_COUNT=256 | |||
767 | # CONFIG_PRINTER is not set | 771 | # CONFIG_PRINTER is not set |
768 | # CONFIG_PPDEV is not set | 772 | # CONFIG_PPDEV is not set |
769 | # CONFIG_TIPAR is not set | 773 | # CONFIG_TIPAR is not set |
774 | CONFIG_HVC_DRIVER=y | ||
770 | CONFIG_HVC_CONSOLE=y | 775 | CONFIG_HVC_CONSOLE=y |
776 | # CONFIG_HVC_RTAS is not set | ||
771 | CONFIG_HVCS=m | 777 | CONFIG_HVCS=m |
772 | 778 | ||
773 | # | 779 | # |
@@ -779,7 +785,6 @@ CONFIG_HVCS=m | |||
779 | # Watchdog Cards | 785 | # Watchdog Cards |
780 | # | 786 | # |
781 | # CONFIG_WATCHDOG is not set | 787 | # CONFIG_WATCHDOG is not set |
782 | # CONFIG_RTC is not set | ||
783 | CONFIG_GEN_RTC=y | 788 | CONFIG_GEN_RTC=y |
784 | # CONFIG_GEN_RTC_X is not set | 789 | # CONFIG_GEN_RTC_X is not set |
785 | # CONFIG_DTLK is not set | 790 | # CONFIG_DTLK is not set |
@@ -830,7 +835,6 @@ CONFIG_I2C_ALGOBIT=y | |||
830 | # CONFIG_I2C_PARPORT_LIGHT is not set | 835 | # CONFIG_I2C_PARPORT_LIGHT is not set |
831 | # CONFIG_I2C_PROSAVAGE is not set | 836 | # CONFIG_I2C_PROSAVAGE is not set |
832 | # CONFIG_I2C_SAVAGE4 is not set | 837 | # CONFIG_I2C_SAVAGE4 is not set |
833 | # CONFIG_SCx200_ACB is not set | ||
834 | # CONFIG_I2C_SIS5595 is not set | 838 | # CONFIG_I2C_SIS5595 is not set |
835 | # CONFIG_I2C_SIS630 is not set | 839 | # CONFIG_I2C_SIS630 is not set |
836 | # CONFIG_I2C_SIS96X is not set | 840 | # CONFIG_I2C_SIS96X is not set |
@@ -849,9 +853,7 @@ CONFIG_I2C_ALGOBIT=y | |||
849 | # CONFIG_SENSORS_PCF8574 is not set | 853 | # CONFIG_SENSORS_PCF8574 is not set |
850 | # CONFIG_SENSORS_PCA9539 is not set | 854 | # CONFIG_SENSORS_PCA9539 is not set |
851 | # CONFIG_SENSORS_PCF8591 is not set | 855 | # CONFIG_SENSORS_PCF8591 is not set |
852 | # CONFIG_SENSORS_RTC8564 is not set | ||
853 | # CONFIG_SENSORS_MAX6875 is not set | 856 | # CONFIG_SENSORS_MAX6875 is not set |
854 | # CONFIG_RTC_X1205_I2C is not set | ||
855 | # CONFIG_I2C_DEBUG_CORE is not set | 857 | # CONFIG_I2C_DEBUG_CORE is not set |
856 | # CONFIG_I2C_DEBUG_ALGO is not set | 858 | # CONFIG_I2C_DEBUG_ALGO is not set |
857 | # CONFIG_I2C_DEBUG_BUS is not set | 859 | # CONFIG_I2C_DEBUG_BUS is not set |
@@ -879,10 +881,6 @@ CONFIG_I2C_ALGOBIT=y | |||
879 | # | 881 | # |
880 | 882 | ||
881 | # | 883 | # |
882 | # Multimedia Capabilities Port drivers | ||
883 | # | ||
884 | |||
885 | # | ||
886 | # Multimedia devices | 884 | # Multimedia devices |
887 | # | 885 | # |
888 | # CONFIG_VIDEO_DEV is not set | 886 | # CONFIG_VIDEO_DEV is not set |
@@ -891,6 +889,7 @@ CONFIG_I2C_ALGOBIT=y | |||
891 | # Digital Video Broadcasting Devices | 889 | # Digital Video Broadcasting Devices |
892 | # | 890 | # |
893 | # CONFIG_DVB is not set | 891 | # CONFIG_DVB is not set |
892 | # CONFIG_USB_DABUSB is not set | ||
894 | 893 | ||
895 | # | 894 | # |
896 | # Graphics support | 895 | # Graphics support |
@@ -900,6 +899,7 @@ CONFIG_FB_CFB_FILLRECT=y | |||
900 | CONFIG_FB_CFB_COPYAREA=y | 899 | CONFIG_FB_CFB_COPYAREA=y |
901 | CONFIG_FB_CFB_IMAGEBLIT=y | 900 | CONFIG_FB_CFB_IMAGEBLIT=y |
902 | CONFIG_FB_MACMODES=y | 901 | CONFIG_FB_MACMODES=y |
902 | CONFIG_FB_FIRMWARE_EDID=y | ||
903 | CONFIG_FB_MODE_HELPERS=y | 903 | CONFIG_FB_MODE_HELPERS=y |
904 | CONFIG_FB_TILEBLITTING=y | 904 | CONFIG_FB_TILEBLITTING=y |
905 | # CONFIG_FB_CIRRUS is not set | 905 | # CONFIG_FB_CIRRUS is not set |
@@ -919,7 +919,6 @@ CONFIG_FB_MATROX_MYSTIQUE=y | |||
919 | CONFIG_FB_MATROX_G=y | 919 | CONFIG_FB_MATROX_G=y |
920 | # CONFIG_FB_MATROX_I2C is not set | 920 | # CONFIG_FB_MATROX_I2C is not set |
921 | CONFIG_FB_MATROX_MULTIHEAD=y | 921 | CONFIG_FB_MATROX_MULTIHEAD=y |
922 | # CONFIG_FB_RADEON_OLD is not set | ||
923 | CONFIG_FB_RADEON=y | 922 | CONFIG_FB_RADEON=y |
924 | CONFIG_FB_RADEON_I2C=y | 923 | CONFIG_FB_RADEON_I2C=y |
925 | # CONFIG_FB_RADEON_DEBUG is not set | 924 | # CONFIG_FB_RADEON_DEBUG is not set |
@@ -968,6 +967,7 @@ CONFIG_LCD_DEVICE=y | |||
968 | # | 967 | # |
969 | CONFIG_USB_ARCH_HAS_HCD=y | 968 | CONFIG_USB_ARCH_HAS_HCD=y |
970 | CONFIG_USB_ARCH_HAS_OHCI=y | 969 | CONFIG_USB_ARCH_HAS_OHCI=y |
970 | CONFIG_USB_ARCH_HAS_EHCI=y | ||
971 | CONFIG_USB=y | 971 | CONFIG_USB=y |
972 | # CONFIG_USB_DEBUG is not set | 972 | # CONFIG_USB_DEBUG is not set |
973 | 973 | ||
@@ -1048,15 +1048,6 @@ CONFIG_USB_HIDDEV=y | |||
1048 | # CONFIG_USB_MICROTEK is not set | 1048 | # CONFIG_USB_MICROTEK is not set |
1049 | 1049 | ||
1050 | # | 1050 | # |
1051 | # USB Multimedia devices | ||
1052 | # | ||
1053 | # CONFIG_USB_DABUSB is not set | ||
1054 | |||
1055 | # | ||
1056 | # Video4Linux support is needed for USB Multimedia device support | ||
1057 | # | ||
1058 | |||
1059 | # | ||
1060 | # USB Network Adapters | 1051 | # USB Network Adapters |
1061 | # | 1052 | # |
1062 | # CONFIG_USB_CATC is not set | 1053 | # CONFIG_USB_CATC is not set |
@@ -1109,6 +1100,11 @@ CONFIG_USB_MON=y | |||
1109 | # CONFIG_MMC is not set | 1100 | # CONFIG_MMC is not set |
1110 | 1101 | ||
1111 | # | 1102 | # |
1103 | # LED devices | ||
1104 | # | ||
1105 | # CONFIG_NEW_LEDS is not set | ||
1106 | |||
1107 | # | ||
1112 | # InfiniBand support | 1108 | # InfiniBand support |
1113 | # | 1109 | # |
1114 | CONFIG_INFINIBAND=m | 1110 | CONFIG_INFINIBAND=m |
@@ -1121,12 +1117,13 @@ CONFIG_INFINIBAND_IPOIB=m | |||
1121 | # CONFIG_INFINIBAND_SRP is not set | 1117 | # CONFIG_INFINIBAND_SRP is not set |
1122 | 1118 | ||
1123 | # | 1119 | # |
1124 | # SN Devices | 1120 | # EDAC - error detection and reporting (RAS) (EXPERIMENTAL) |
1125 | # | 1121 | # |
1126 | 1122 | ||
1127 | # | 1123 | # |
1128 | # EDAC - error detection and reporting (RAS) | 1124 | # Real Time Clock |
1129 | # | 1125 | # |
1126 | # CONFIG_RTC_CLASS is not set | ||
1130 | 1127 | ||
1131 | # | 1128 | # |
1132 | # File systems | 1129 | # File systems |
@@ -1202,7 +1199,6 @@ CONFIG_TMPFS=y | |||
1202 | CONFIG_HUGETLBFS=y | 1199 | CONFIG_HUGETLBFS=y |
1203 | CONFIG_HUGETLB_PAGE=y | 1200 | CONFIG_HUGETLB_PAGE=y |
1204 | CONFIG_RAMFS=y | 1201 | CONFIG_RAMFS=y |
1205 | # CONFIG_RELAYFS_FS is not set | ||
1206 | # CONFIG_CONFIGFS_FS is not set | 1202 | # CONFIG_CONFIGFS_FS is not set |
1207 | 1203 | ||
1208 | # | 1204 | # |
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 0cc0995b81b0..803858e86160 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile | |||
@@ -20,7 +20,7 @@ obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ | |||
20 | firmware.o sysfs.o | 20 | firmware.o sysfs.o |
21 | obj-$(CONFIG_PPC64) += vdso64/ | 21 | obj-$(CONFIG_PPC64) += vdso64/ |
22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o | 22 | obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o |
23 | obj-$(CONFIG_POWER4) += idle_power4.o | 23 | obj-$(CONFIG_PPC_970_NAP) += idle_power4.o |
24 | obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o | 24 | obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o |
25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o | 25 | procfs-$(CONFIG_PPC64) := proc_ppc64.o |
26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) | 26 | obj-$(CONFIG_PROC_FS) += $(procfs-y) |
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 54b48f330051..8f85c5e8a55a 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c | |||
@@ -91,6 +91,7 @@ int main(void) | |||
91 | #endif /* CONFIG_PPC64 */ | 91 | #endif /* CONFIG_PPC64 */ |
92 | 92 | ||
93 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); | 93 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); |
94 | DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, local_flags)); | ||
94 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); | 95 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); |
95 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); | 96 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); |
96 | #ifdef CONFIG_PPC32 | 97 | #ifdef CONFIG_PPC32 |
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index b3a979467225..8866fd26c6b9 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S | |||
@@ -128,37 +128,36 @@ transfer_to_handler: | |||
128 | stw r12,4(r11) | 128 | stw r12,4(r11) |
129 | #endif | 129 | #endif |
130 | b 3f | 130 | b 3f |
131 | |||
131 | 2: /* if from kernel, check interrupted DOZE/NAP mode and | 132 | 2: /* if from kernel, check interrupted DOZE/NAP mode and |
132 | * check for stack overflow | 133 | * check for stack overflow |
133 | */ | 134 | */ |
135 | lwz r9,THREAD_INFO-THREAD(r12) | ||
136 | cmplw r1,r9 /* if r1 <= current->thread_info */ | ||
137 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
138 | 5: | ||
134 | #ifdef CONFIG_6xx | 139 | #ifdef CONFIG_6xx |
135 | mfspr r11,SPRN_HID0 | 140 | tophys(r9,r9) /* check local flags */ |
136 | mtcr r11 | 141 | lwz r12,TI_LOCAL_FLAGS(r9) |
137 | BEGIN_FTR_SECTION | 142 | mtcrf 0x01,r12 |
138 | bt- 8,4f /* Check DOZE */ | 143 | bt- 31-TLF_NAPPING,4f |
139 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
140 | BEGIN_FTR_SECTION | ||
141 | bt- 9,4f /* Check NAP */ | ||
142 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
143 | #endif /* CONFIG_6xx */ | 144 | #endif /* CONFIG_6xx */ |
144 | .globl transfer_to_handler_cont | 145 | .globl transfer_to_handler_cont |
145 | transfer_to_handler_cont: | 146 | transfer_to_handler_cont: |
146 | lwz r11,THREAD_INFO-THREAD(r12) | ||
147 | cmplw r1,r11 /* if r1 <= current->thread_info */ | ||
148 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
149 | 3: | 147 | 3: |
150 | mflr r9 | 148 | mflr r9 |
151 | lwz r11,0(r9) /* virtual address of handler */ | 149 | lwz r11,0(r9) /* virtual address of handler */ |
152 | lwz r9,4(r9) /* where to go when done */ | 150 | lwz r9,4(r9) /* where to go when done */ |
153 | FIX_SRR1(r10,r12) | ||
154 | mtspr SPRN_SRR0,r11 | 151 | mtspr SPRN_SRR0,r11 |
155 | mtspr SPRN_SRR1,r10 | 152 | mtspr SPRN_SRR1,r10 |
156 | mtlr r9 | 153 | mtlr r9 |
157 | SYNC | 154 | SYNC |
158 | RFI /* jump to handler, enable MMU */ | 155 | RFI /* jump to handler, enable MMU */ |
159 | 156 | ||
160 | #ifdef CONFIG_6xx | 157 | #ifdef CONFIG_6xx |
161 | 4: b power_save_6xx_restore | 158 | 4: rlwinm r12,r12,0,~_TLF_NAPPING |
159 | stw r12,TI_LOCAL_FLAGS(r9) | ||
160 | b power_save_6xx_restore | ||
162 | #endif | 161 | #endif |
163 | 162 | ||
164 | /* | 163 | /* |
@@ -167,10 +166,10 @@ transfer_to_handler_cont: | |||
167 | */ | 166 | */ |
168 | stack_ovf: | 167 | stack_ovf: |
169 | /* sometimes we use a statically-allocated stack, which is OK. */ | 168 | /* sometimes we use a statically-allocated stack, which is OK. */ |
170 | lis r11,_end@h | 169 | lis r12,_end@h |
171 | ori r11,r11,_end@l | 170 | ori r12,r12,_end@l |
172 | cmplw r1,r11 | 171 | cmplw r1,r12 |
173 | ble 3b /* r1 <= &_end is OK */ | 172 | ble 5b /* r1 <= &_end is OK */ |
174 | SAVE_NVGPRS(r11) | 173 | SAVE_NVGPRS(r11) |
175 | addi r3,r1,STACK_FRAME_OVERHEAD | 174 | addi r3,r1,STACK_FRAME_OVERHEAD |
176 | lis r1,init_thread_union@ha | 175 | lis r1,init_thread_union@ha |
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index a5ae04a57c78..b7d140430a41 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S | |||
@@ -376,11 +376,28 @@ label##_common: \ | |||
376 | bl hdlr; \ | 376 | bl hdlr; \ |
377 | b .ret_from_except | 377 | b .ret_from_except |
378 | 378 | ||
379 | /* | ||
380 | * Like STD_EXCEPTION_COMMON, but for exceptions that can occur | ||
381 | * in the idle task and therefore need the special idle handling. | ||
382 | */ | ||
383 | #define STD_EXCEPTION_COMMON_IDLE(trap, label, hdlr) \ | ||
384 | .align 7; \ | ||
385 | .globl label##_common; \ | ||
386 | label##_common: \ | ||
387 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ | ||
388 | FINISH_NAP; \ | ||
389 | DISABLE_INTS; \ | ||
390 | bl .save_nvgprs; \ | ||
391 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | ||
392 | bl hdlr; \ | ||
393 | b .ret_from_except | ||
394 | |||
379 | #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ | 395 | #define STD_EXCEPTION_COMMON_LITE(trap, label, hdlr) \ |
380 | .align 7; \ | 396 | .align 7; \ |
381 | .globl label##_common; \ | 397 | .globl label##_common; \ |
382 | label##_common: \ | 398 | label##_common: \ |
383 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ | 399 | EXCEPTION_PROLOG_COMMON(trap, PACA_EXGEN); \ |
400 | FINISH_NAP; \ | ||
384 | DISABLE_INTS; \ | 401 | DISABLE_INTS; \ |
385 | bl .ppc64_runlatch_on; \ | 402 | bl .ppc64_runlatch_on; \ |
386 | addi r3,r1,STACK_FRAME_OVERHEAD; \ | 403 | addi r3,r1,STACK_FRAME_OVERHEAD; \ |
@@ -388,6 +405,25 @@ label##_common: \ | |||
388 | b .ret_from_except_lite | 405 | b .ret_from_except_lite |
389 | 406 | ||
390 | /* | 407 | /* |
408 | * When the idle code in power4_idle puts the CPU into NAP mode, | ||
409 | * it has to do so in a loop, and relies on the external interrupt | ||
410 | * and decrementer interrupt entry code to get it out of the loop. | ||
411 | * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags | ||
412 | * to signal that it is in the loop and needs help to get out. | ||
413 | */ | ||
414 | #ifdef CONFIG_PPC_970_NAP | ||
415 | #define FINISH_NAP \ | ||
416 | BEGIN_FTR_SECTION \ | ||
417 | clrrdi r11,r1,THREAD_SHIFT; \ | ||
418 | ld r9,TI_LOCAL_FLAGS(r11); \ | ||
419 | andi. r10,r9,_TLF_NAPPING; \ | ||
420 | bnel power4_fixup_nap; \ | ||
421 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
422 | #else | ||
423 | #define FINISH_NAP | ||
424 | #endif | ||
425 | |||
426 | /* | ||
391 | * Start of pSeries system interrupt routines | 427 | * Start of pSeries system interrupt routines |
392 | */ | 428 | */ |
393 | . = 0x100 | 429 | . = 0x100 |
@@ -772,6 +808,7 @@ hardware_interrupt_iSeries_masked: | |||
772 | .globl machine_check_common | 808 | .globl machine_check_common |
773 | machine_check_common: | 809 | machine_check_common: |
774 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) | 810 | EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) |
811 | FINISH_NAP | ||
775 | DISABLE_INTS | 812 | DISABLE_INTS |
776 | bl .save_nvgprs | 813 | bl .save_nvgprs |
777 | addi r3,r1,STACK_FRAME_OVERHEAD | 814 | addi r3,r1,STACK_FRAME_OVERHEAD |
@@ -783,7 +820,7 @@ machine_check_common: | |||
783 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) | 820 | STD_EXCEPTION_COMMON(0xb00, trap_0b, .unknown_exception) |
784 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) | 821 | STD_EXCEPTION_COMMON(0xd00, single_step, .single_step_exception) |
785 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) | 822 | STD_EXCEPTION_COMMON(0xe00, trap_0e, .unknown_exception) |
786 | STD_EXCEPTION_COMMON(0xf00, performance_monitor, .performance_monitor_exception) | 823 | STD_EXCEPTION_COMMON_IDLE(0xf00, performance_monitor, .performance_monitor_exception) |
787 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) | 824 | STD_EXCEPTION_COMMON(0x1300, instruction_breakpoint, .instruction_breakpoint_exception) |
788 | #ifdef CONFIG_ALTIVEC | 825 | #ifdef CONFIG_ALTIVEC |
789 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) | 826 | STD_EXCEPTION_COMMON(0x1700, altivec_assist, .altivec_assist_exception) |
@@ -1034,6 +1071,7 @@ unrecov_slb: | |||
1034 | .globl hardware_interrupt_entry | 1071 | .globl hardware_interrupt_entry |
1035 | hardware_interrupt_common: | 1072 | hardware_interrupt_common: |
1036 | EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) | 1073 | EXCEPTION_PROLOG_COMMON(0x500, PACA_EXGEN) |
1074 | FINISH_NAP | ||
1037 | hardware_interrupt_entry: | 1075 | hardware_interrupt_entry: |
1038 | DISABLE_INTS | 1076 | DISABLE_INTS |
1039 | bl .ppc64_runlatch_on | 1077 | bl .ppc64_runlatch_on |
@@ -1041,6 +1079,15 @@ hardware_interrupt_entry: | |||
1041 | bl .do_IRQ | 1079 | bl .do_IRQ |
1042 | b .ret_from_except_lite | 1080 | b .ret_from_except_lite |
1043 | 1081 | ||
1082 | #ifdef CONFIG_PPC_970_NAP | ||
1083 | power4_fixup_nap: | ||
1084 | andc r9,r9,r10 | ||
1085 | std r9,TI_LOCAL_FLAGS(r11) | ||
1086 | ld r10,_LINK(r1) /* make idle task do the */ | ||
1087 | std r10,_NIP(r1) /* equivalent of a blr */ | ||
1088 | blr | ||
1089 | #endif | ||
1090 | |||
1044 | .align 7 | 1091 | .align 7 |
1045 | .globl alignment_common | 1092 | .globl alignment_common |
1046 | alignment_common: | 1093 | alignment_common: |
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c index e9f321d74d85..d491052c8e0c 100644 --- a/arch/powerpc/kernel/idle.c +++ b/arch/powerpc/kernel/idle.c | |||
@@ -50,9 +50,9 @@ void cpu_idle(void) | |||
50 | 50 | ||
51 | set_thread_flag(TIF_POLLING_NRFLAG); | 51 | set_thread_flag(TIF_POLLING_NRFLAG); |
52 | while (1) { | 52 | while (1) { |
53 | ppc64_runlatch_off(); | ||
54 | |||
55 | while (!need_resched() && !cpu_should_die()) { | 53 | while (!need_resched() && !cpu_should_die()) { |
54 | ppc64_runlatch_off(); | ||
55 | |||
56 | if (ppc_md.power_save) { | 56 | if (ppc_md.power_save) { |
57 | clear_thread_flag(TIF_POLLING_NRFLAG); | 57 | clear_thread_flag(TIF_POLLING_NRFLAG); |
58 | /* | 58 | /* |
diff --git a/arch/powerpc/kernel/idle_6xx.S b/arch/powerpc/kernel/idle_6xx.S index 12a4efbaa08f..b45fa0e37212 100644 --- a/arch/powerpc/kernel/idle_6xx.S +++ b/arch/powerpc/kernel/idle_6xx.S | |||
@@ -22,8 +22,6 @@ | |||
22 | #include <asm/ppc_asm.h> | 22 | #include <asm/ppc_asm.h> |
23 | #include <asm/asm-offsets.h> | 23 | #include <asm/asm-offsets.h> |
24 | 24 | ||
25 | #undef DEBUG | ||
26 | |||
27 | .text | 25 | .text |
28 | 26 | ||
29 | /* | 27 | /* |
@@ -109,12 +107,6 @@ BEGIN_FTR_SECTION | |||
109 | dcbf 0,r4 | 107 | dcbf 0,r4 |
110 | dcbf 0,r4 | 108 | dcbf 0,r4 |
111 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) | 109 | END_FTR_SECTION_IFSET(CPU_FTR_NAP_DISABLE_L2_PR) |
112 | #ifdef DEBUG | ||
113 | lis r6,nap_enter_count@ha | ||
114 | lwz r4,nap_enter_count@l(r6) | ||
115 | addi r4,r4,1 | ||
116 | stw r4,nap_enter_count@l(r6) | ||
117 | #endif | ||
118 | 2: | 110 | 2: |
119 | BEGIN_FTR_SECTION | 111 | BEGIN_FTR_SECTION |
120 | /* Go to low speed mode on some 750FX */ | 112 | /* Go to low speed mode on some 750FX */ |
@@ -144,48 +136,42 @@ BEGIN_FTR_SECTION | |||
144 | DSSALL | 136 | DSSALL |
145 | sync | 137 | sync |
146 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 138 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
139 | rlwinm r9,r1,0,0,31-THREAD_SHIFT /* current thread_info */ | ||
140 | lwz r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ | ||
141 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ | ||
142 | stw r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ | ||
147 | mfmsr r7 | 143 | mfmsr r7 |
148 | ori r7,r7,MSR_EE | 144 | ori r7,r7,MSR_EE |
149 | oris r7,r7,MSR_POW@h | 145 | oris r7,r7,MSR_POW@h |
150 | sync | 146 | 1: sync |
151 | isync | ||
152 | mtmsr r7 | 147 | mtmsr r7 |
153 | isync | 148 | isync |
154 | sync | 149 | b 1b |
155 | blr | 150 | |
156 | |||
157 | /* | 151 | /* |
158 | * Return from NAP/DOZE mode, restore some CPU specific registers, | 152 | * Return from NAP/DOZE mode, restore some CPU specific registers, |
159 | * we are called with DR/IR still off and r2 containing physical | 153 | * we are called with DR/IR still off and r2 containing physical |
160 | * address of current. | 154 | * address of current. R11 points to the exception frame (physical |
155 | * address). We have to preserve r10. | ||
161 | */ | 156 | */ |
162 | _GLOBAL(power_save_6xx_restore) | 157 | _GLOBAL(power_save_6xx_restore) |
163 | mfspr r11,SPRN_HID0 | 158 | lwz r9,_LINK(r11) /* interrupted in ppc6xx_idle: */ |
164 | rlwinm. r11,r11,0,10,8 /* Clear NAP & copy NAP bit !state to cr1 EQ */ | 159 | stw r9,_NIP(r11) /* make it do a blr */ |
165 | cror 4*cr1+eq,4*cr0+eq,4*cr0+eq | ||
166 | BEGIN_FTR_SECTION | ||
167 | rlwinm r11,r11,0,9,7 /* Clear DOZE */ | ||
168 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
169 | mtspr SPRN_HID0, r11 | ||
170 | 160 | ||
171 | #ifdef DEBUG | 161 | #ifdef CONFIG_SMP |
172 | beq cr1,1f | 162 | mfspr r12,SPRN_SPRG3 |
173 | lis r11,(nap_return_count-KERNELBASE)@ha | 163 | lwz r11,TI_CPU(r12) /* get cpu number * 4 */ |
174 | lwz r9,nap_return_count@l(r11) | ||
175 | addi r9,r9,1 | ||
176 | stw r9,nap_return_count@l(r11) | ||
177 | 1: | ||
178 | #endif | ||
179 | |||
180 | rlwinm r9,r1,0,0,18 | ||
181 | tophys(r9,r9) | ||
182 | lwz r11,TI_CPU(r9) | ||
183 | slwi r11,r11,2 | 164 | slwi r11,r11,2 |
165 | #else | ||
166 | li r11,0 | ||
167 | #endif | ||
184 | /* Todo make sure all these are in the same page | 168 | /* Todo make sure all these are in the same page |
185 | * and load r22 (@ha part + CPU offset) only once | 169 | * and load r11 (@ha part + CPU offset) only once |
186 | */ | 170 | */ |
187 | BEGIN_FTR_SECTION | 171 | BEGIN_FTR_SECTION |
188 | beq cr1,1f | 172 | mfspr r9,SPRN_HID0 |
173 | andis. r9,r9,HID0_NAP@h | ||
174 | beq 1f | ||
189 | addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha | 175 | addis r9,r11,(nap_save_msscr0-KERNELBASE)@ha |
190 | lwz r9,nap_save_msscr0@l(r9) | 176 | lwz r9,nap_save_msscr0@l(r9) |
191 | mtspr SPRN_MSSCR0, r9 | 177 | mtspr SPRN_MSSCR0, r9 |
@@ -210,10 +196,3 @@ _GLOBAL(nap_save_hid1) | |||
210 | 196 | ||
211 | _GLOBAL(powersave_lowspeed) | 197 | _GLOBAL(powersave_lowspeed) |
212 | .long 0 | 198 | .long 0 |
213 | |||
214 | #ifdef DEBUG | ||
215 | _GLOBAL(nap_enter_count) | ||
216 | .space 4 | ||
217 | _GLOBAL(nap_return_count) | ||
218 | .space 4 | ||
219 | #endif | ||
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S index 6dad1c02496e..d85c7c938eed 100644 --- a/arch/powerpc/kernel/idle_power4.S +++ b/arch/powerpc/kernel/idle_power4.S | |||
@@ -35,12 +35,16 @@ BEGIN_FTR_SECTION | |||
35 | DSSALL | 35 | DSSALL |
36 | sync | 36 | sync |
37 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) | 37 | END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) |
38 | clrrdi r9,r1,THREAD_SHIFT /* current thread_info */ | ||
39 | ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ | ||
40 | ori r8,r8,_TLF_NAPPING /* so when we take an exception */ | ||
41 | std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ | ||
38 | mfmsr r7 | 42 | mfmsr r7 |
39 | ori r7,r7,MSR_EE | 43 | ori r7,r7,MSR_EE |
40 | oris r7,r7,MSR_POW@h | 44 | oris r7,r7,MSR_POW@h |
41 | sync | 45 | 1: sync |
42 | isync | 46 | isync |
43 | mtmsrd r7 | 47 | mtmsrd r7 |
44 | isync | 48 | isync |
45 | sync | 49 | b 1b |
46 | blr | 50 | |
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index d9a7fdef59b9..4eba60a32890 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c | |||
@@ -61,6 +61,7 @@ __setup("iommu=", setup_iommu); | |||
61 | static unsigned long iommu_range_alloc(struct iommu_table *tbl, | 61 | static unsigned long iommu_range_alloc(struct iommu_table *tbl, |
62 | unsigned long npages, | 62 | unsigned long npages, |
63 | unsigned long *handle, | 63 | unsigned long *handle, |
64 | unsigned long mask, | ||
64 | unsigned int align_order) | 65 | unsigned int align_order) |
65 | { | 66 | { |
66 | unsigned long n, end, i, start; | 67 | unsigned long n, end, i, start; |
@@ -97,9 +98,21 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl, | |||
97 | */ | 98 | */ |
98 | if (start >= limit) | 99 | if (start >= limit) |
99 | start = largealloc ? tbl->it_largehint : tbl->it_hint; | 100 | start = largealloc ? tbl->it_largehint : tbl->it_hint; |
100 | 101 | ||
101 | again: | 102 | again: |
102 | 103 | ||
104 | if (limit + tbl->it_offset > mask) { | ||
105 | limit = mask - tbl->it_offset + 1; | ||
106 | /* If we're constrained on address range, first try | ||
107 | * at the masked hint to avoid O(n) search complexity, | ||
108 | * but on second pass, start at 0. | ||
109 | */ | ||
110 | if ((start & mask) >= limit || pass > 0) | ||
111 | start = 0; | ||
112 | else | ||
113 | start &= mask; | ||
114 | } | ||
115 | |||
103 | n = find_next_zero_bit(tbl->it_map, limit, start); | 116 | n = find_next_zero_bit(tbl->it_map, limit, start); |
104 | 117 | ||
105 | /* Align allocation */ | 118 | /* Align allocation */ |
@@ -150,14 +163,14 @@ static unsigned long iommu_range_alloc(struct iommu_table *tbl, | |||
150 | 163 | ||
151 | static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page, | 164 | static dma_addr_t iommu_alloc(struct iommu_table *tbl, void *page, |
152 | unsigned int npages, enum dma_data_direction direction, | 165 | unsigned int npages, enum dma_data_direction direction, |
153 | unsigned int align_order) | 166 | unsigned long mask, unsigned int align_order) |
154 | { | 167 | { |
155 | unsigned long entry, flags; | 168 | unsigned long entry, flags; |
156 | dma_addr_t ret = DMA_ERROR_CODE; | 169 | dma_addr_t ret = DMA_ERROR_CODE; |
157 | 170 | ||
158 | spin_lock_irqsave(&(tbl->it_lock), flags); | 171 | spin_lock_irqsave(&(tbl->it_lock), flags); |
159 | 172 | ||
160 | entry = iommu_range_alloc(tbl, npages, NULL, align_order); | 173 | entry = iommu_range_alloc(tbl, npages, NULL, mask, align_order); |
161 | 174 | ||
162 | if (unlikely(entry == DMA_ERROR_CODE)) { | 175 | if (unlikely(entry == DMA_ERROR_CODE)) { |
163 | spin_unlock_irqrestore(&(tbl->it_lock), flags); | 176 | spin_unlock_irqrestore(&(tbl->it_lock), flags); |
@@ -236,7 +249,7 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr, | |||
236 | 249 | ||
237 | int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | 250 | int iommu_map_sg(struct device *dev, struct iommu_table *tbl, |
238 | struct scatterlist *sglist, int nelems, | 251 | struct scatterlist *sglist, int nelems, |
239 | enum dma_data_direction direction) | 252 | unsigned long mask, enum dma_data_direction direction) |
240 | { | 253 | { |
241 | dma_addr_t dma_next = 0, dma_addr; | 254 | dma_addr_t dma_next = 0, dma_addr; |
242 | unsigned long flags; | 255 | unsigned long flags; |
@@ -274,7 +287,7 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | |||
274 | vaddr = (unsigned long)page_address(s->page) + s->offset; | 287 | vaddr = (unsigned long)page_address(s->page) + s->offset; |
275 | npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK); | 288 | npages = PAGE_ALIGN(vaddr + slen) - (vaddr & PAGE_MASK); |
276 | npages >>= PAGE_SHIFT; | 289 | npages >>= PAGE_SHIFT; |
277 | entry = iommu_range_alloc(tbl, npages, &handle, 0); | 290 | entry = iommu_range_alloc(tbl, npages, &handle, mask >> PAGE_SHIFT, 0); |
278 | 291 | ||
279 | DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); | 292 | DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); |
280 | 293 | ||
@@ -479,7 +492,8 @@ void iommu_free_table(struct device_node *dn) | |||
479 | * byte within the page as vaddr. | 492 | * byte within the page as vaddr. |
480 | */ | 493 | */ |
481 | dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, | 494 | dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, |
482 | size_t size, enum dma_data_direction direction) | 495 | size_t size, unsigned long mask, |
496 | enum dma_data_direction direction) | ||
483 | { | 497 | { |
484 | dma_addr_t dma_handle = DMA_ERROR_CODE; | 498 | dma_addr_t dma_handle = DMA_ERROR_CODE; |
485 | unsigned long uaddr; | 499 | unsigned long uaddr; |
@@ -492,7 +506,8 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, | |||
492 | npages >>= PAGE_SHIFT; | 506 | npages >>= PAGE_SHIFT; |
493 | 507 | ||
494 | if (tbl) { | 508 | if (tbl) { |
495 | dma_handle = iommu_alloc(tbl, vaddr, npages, direction, 0); | 509 | dma_handle = iommu_alloc(tbl, vaddr, npages, direction, |
510 | mask >> PAGE_SHIFT, 0); | ||
496 | if (dma_handle == DMA_ERROR_CODE) { | 511 | if (dma_handle == DMA_ERROR_CODE) { |
497 | if (printk_ratelimit()) { | 512 | if (printk_ratelimit()) { |
498 | printk(KERN_INFO "iommu_alloc failed, " | 513 | printk(KERN_INFO "iommu_alloc failed, " |
@@ -521,7 +536,7 @@ void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, | |||
521 | * to the dma address (mapping) of the first page. | 536 | * to the dma address (mapping) of the first page. |
522 | */ | 537 | */ |
523 | void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, | 538 | void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, |
524 | dma_addr_t *dma_handle, gfp_t flag) | 539 | dma_addr_t *dma_handle, unsigned long mask, gfp_t flag) |
525 | { | 540 | { |
526 | void *ret = NULL; | 541 | void *ret = NULL; |
527 | dma_addr_t mapping; | 542 | dma_addr_t mapping; |
@@ -551,7 +566,8 @@ void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, | |||
551 | memset(ret, 0, size); | 566 | memset(ret, 0, size); |
552 | 567 | ||
553 | /* Set up tces to cover the allocated range */ | 568 | /* Set up tces to cover the allocated range */ |
554 | mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, order); | 569 | mapping = iommu_alloc(tbl, ret, npages, DMA_BIDIRECTIONAL, |
570 | mask >> PAGE_SHIFT, order); | ||
555 | if (mapping == DMA_ERROR_CODE) { | 571 | if (mapping == DMA_ERROR_CODE) { |
556 | free_pages((unsigned long)ret, order); | 572 | free_pages((unsigned long)ret, order); |
557 | ret = NULL; | 573 | ret = NULL; |
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index bb5c9501234c..57d560c68897 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c | |||
@@ -272,18 +272,26 @@ unsigned int virt_irq_to_real_map[NR_IRQS]; | |||
272 | * Don't use virtual irqs 0, 1, 2 for devices. | 272 | * Don't use virtual irqs 0, 1, 2 for devices. |
273 | * The pcnet32 driver considers interrupt numbers < 2 to be invalid, | 273 | * The pcnet32 driver considers interrupt numbers < 2 to be invalid, |
274 | * and 2 is the XICS IPI interrupt. | 274 | * and 2 is the XICS IPI interrupt. |
275 | * We limit virtual irqs to 17 less than NR_IRQS so that when we | 275 | * We limit virtual irqs to __irq_offet_value less than virt_irq_max so |
276 | * offset them by 16 (to reserve the first 16 for ISA interrupts) | 276 | * that when we offset them we don't end up with an interrupt |
277 | * we don't end up with an interrupt number >= NR_IRQS. | 277 | * number >= virt_irq_max. |
278 | */ | 278 | */ |
279 | #define MIN_VIRT_IRQ 3 | 279 | #define MIN_VIRT_IRQ 3 |
280 | #define MAX_VIRT_IRQ (NR_IRQS - NUM_ISA_INTERRUPTS - 1) | 280 | |
281 | #define NR_VIRT_IRQS (MAX_VIRT_IRQ - MIN_VIRT_IRQ + 1) | 281 | unsigned int virt_irq_max; |
282 | static unsigned int max_virt_irq; | ||
283 | static unsigned int nr_virt_irqs; | ||
282 | 284 | ||
283 | void | 285 | void |
284 | virt_irq_init(void) | 286 | virt_irq_init(void) |
285 | { | 287 | { |
286 | int i; | 288 | int i; |
289 | |||
290 | if ((virt_irq_max == 0) || (virt_irq_max > (NR_IRQS - 1))) | ||
291 | virt_irq_max = NR_IRQS - 1; | ||
292 | max_virt_irq = virt_irq_max - __irq_offset_value; | ||
293 | nr_virt_irqs = max_virt_irq - MIN_VIRT_IRQ + 1; | ||
294 | |||
287 | for (i = 0; i < NR_IRQS; i++) | 295 | for (i = 0; i < NR_IRQS; i++) |
288 | virt_irq_to_real_map[i] = UNDEFINED_IRQ; | 296 | virt_irq_to_real_map[i] = UNDEFINED_IRQ; |
289 | } | 297 | } |
@@ -308,17 +316,17 @@ int virt_irq_create_mapping(unsigned int real_irq) | |||
308 | return real_irq; | 316 | return real_irq; |
309 | } | 317 | } |
310 | 318 | ||
311 | /* map to a number between MIN_VIRT_IRQ and MAX_VIRT_IRQ */ | 319 | /* map to a number between MIN_VIRT_IRQ and max_virt_irq */ |
312 | virq = real_irq; | 320 | virq = real_irq; |
313 | if (virq > MAX_VIRT_IRQ) | 321 | if (virq > max_virt_irq) |
314 | virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; | 322 | virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; |
315 | 323 | ||
316 | /* search for this number or a free slot */ | 324 | /* search for this number or a free slot */ |
317 | first_virq = virq; | 325 | first_virq = virq; |
318 | while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { | 326 | while (virt_irq_to_real_map[virq] != UNDEFINED_IRQ) { |
319 | if (virt_irq_to_real_map[virq] == real_irq) | 327 | if (virt_irq_to_real_map[virq] == real_irq) |
320 | return virq; | 328 | return virq; |
321 | if (++virq > MAX_VIRT_IRQ) | 329 | if (++virq > max_virt_irq) |
322 | virq = MIN_VIRT_IRQ; | 330 | virq = MIN_VIRT_IRQ; |
323 | if (virq == first_virq) | 331 | if (virq == first_virq) |
324 | goto nospace; /* oops, no free slots */ | 332 | goto nospace; /* oops, no free slots */ |
@@ -330,8 +338,8 @@ int virt_irq_create_mapping(unsigned int real_irq) | |||
330 | nospace: | 338 | nospace: |
331 | if (!warned) { | 339 | if (!warned) { |
332 | printk(KERN_CRIT "Interrupt table is full\n"); | 340 | printk(KERN_CRIT "Interrupt table is full\n"); |
333 | printk(KERN_CRIT "Increase NR_IRQS (currently %d) " | 341 | printk(KERN_CRIT "Increase virt_irq_max (currently %d) " |
334 | "in your kernel sources and rebuild.\n", NR_IRQS); | 342 | "in your kernel sources and rebuild.\n", virt_irq_max); |
335 | warned = 1; | 343 | warned = 1; |
336 | } | 344 | } |
337 | return NO_IRQ; | 345 | return NO_IRQ; |
@@ -349,8 +357,8 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
349 | 357 | ||
350 | virq = real_irq; | 358 | virq = real_irq; |
351 | 359 | ||
352 | if (virq > MAX_VIRT_IRQ) | 360 | if (virq > max_virt_irq) |
353 | virq = (virq % NR_VIRT_IRQS) + MIN_VIRT_IRQ; | 361 | virq = (virq % nr_virt_irqs) + MIN_VIRT_IRQ; |
354 | 362 | ||
355 | first_virq = virq; | 363 | first_virq = virq; |
356 | 364 | ||
@@ -360,7 +368,7 @@ unsigned int real_irq_to_virt_slowpath(unsigned int real_irq) | |||
360 | 368 | ||
361 | virq++; | 369 | virq++; |
362 | 370 | ||
363 | if (virq >= MAX_VIRT_IRQ) | 371 | if (virq >= max_virt_irq) |
364 | virq = 0; | 372 | virq = 0; |
365 | 373 | ||
366 | } while (first_virq != virq); | 374 | } while (first_virq != virq); |
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index ad7a90212204..856ef1a832b9 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c | |||
@@ -88,7 +88,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) | |||
88 | mutex_unlock(&kprobe_mutex); | 88 | mutex_unlock(&kprobe_mutex); |
89 | } | 89 | } |
90 | 90 | ||
91 | static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | 91 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) |
92 | { | 92 | { |
93 | kprobe_opcode_t insn = *p->ainsn.insn; | 93 | kprobe_opcode_t insn = *p->ainsn.insn; |
94 | 94 | ||
@@ -101,21 +101,21 @@ static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs) | |||
101 | regs->nip = (unsigned long)p->ainsn.insn; | 101 | regs->nip = (unsigned long)p->ainsn.insn; |
102 | } | 102 | } |
103 | 103 | ||
104 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 104 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
105 | { | 105 | { |
106 | kcb->prev_kprobe.kp = kprobe_running(); | 106 | kcb->prev_kprobe.kp = kprobe_running(); |
107 | kcb->prev_kprobe.status = kcb->kprobe_status; | 107 | kcb->prev_kprobe.status = kcb->kprobe_status; |
108 | kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr; | 108 | kcb->prev_kprobe.saved_msr = kcb->kprobe_saved_msr; |
109 | } | 109 | } |
110 | 110 | ||
111 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 111 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
112 | { | 112 | { |
113 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 113 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
114 | kcb->kprobe_status = kcb->prev_kprobe.status; | 114 | kcb->kprobe_status = kcb->prev_kprobe.status; |
115 | kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr; | 115 | kcb->kprobe_saved_msr = kcb->prev_kprobe.saved_msr; |
116 | } | 116 | } |
117 | 117 | ||
118 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | 118 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
119 | struct kprobe_ctlblk *kcb) | 119 | struct kprobe_ctlblk *kcb) |
120 | { | 120 | { |
121 | __get_cpu_var(current_kprobe) = p; | 121 | __get_cpu_var(current_kprobe) = p; |
@@ -141,7 +141,7 @@ void __kprobes arch_prepare_kretprobe(struct kretprobe *rp, | |||
141 | } | 141 | } |
142 | } | 142 | } |
143 | 143 | ||
144 | static inline int kprobe_handler(struct pt_regs *regs) | 144 | static int __kprobes kprobe_handler(struct pt_regs *regs) |
145 | { | 145 | { |
146 | struct kprobe *p; | 146 | struct kprobe *p; |
147 | int ret = 0; | 147 | int ret = 0; |
@@ -334,7 +334,7 @@ static void __kprobes resume_execution(struct kprobe *p, struct pt_regs *regs) | |||
334 | regs->nip = (unsigned long)p->addr + 4; | 334 | regs->nip = (unsigned long)p->addr + 4; |
335 | } | 335 | } |
336 | 336 | ||
337 | static inline int post_kprobe_handler(struct pt_regs *regs) | 337 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
338 | { | 338 | { |
339 | struct kprobe *cur = kprobe_running(); | 339 | struct kprobe *cur = kprobe_running(); |
340 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 340 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -370,7 +370,7 @@ out: | |||
370 | return 1; | 370 | return 1; |
371 | } | 371 | } |
372 | 372 | ||
373 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 373 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
374 | { | 374 | { |
375 | struct kprobe *cur = kprobe_running(); | 375 | struct kprobe *cur = kprobe_running(); |
376 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 376 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c index c336f3e31cff..c1d95e14bbed 100644 --- a/arch/powerpc/kernel/pci_iommu.c +++ b/arch/powerpc/kernel/pci_iommu.c | |||
@@ -59,6 +59,25 @@ static inline struct iommu_table *devnode_table(struct device *dev) | |||
59 | } | 59 | } |
60 | 60 | ||
61 | 61 | ||
62 | static inline unsigned long device_to_mask(struct device *hwdev) | ||
63 | { | ||
64 | struct pci_dev *pdev; | ||
65 | |||
66 | if (!hwdev) { | ||
67 | pdev = ppc64_isabridge_dev; | ||
68 | if (!pdev) /* This is the best guess we can do */ | ||
69 | return 0xfffffffful; | ||
70 | } else | ||
71 | pdev = to_pci_dev(hwdev); | ||
72 | |||
73 | if (pdev->dma_mask) | ||
74 | return pdev->dma_mask; | ||
75 | |||
76 | /* Assume devices without mask can take 32 bit addresses */ | ||
77 | return 0xfffffffful; | ||
78 | } | ||
79 | |||
80 | |||
62 | /* Allocates a contiguous real buffer and creates mappings over it. | 81 | /* Allocates a contiguous real buffer and creates mappings over it. |
63 | * Returns the virtual address of the buffer and sets dma_handle | 82 | * Returns the virtual address of the buffer and sets dma_handle |
64 | * to the dma address (mapping) of the first page. | 83 | * to the dma address (mapping) of the first page. |
@@ -67,7 +86,7 @@ static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size, | |||
67 | dma_addr_t *dma_handle, gfp_t flag) | 86 | dma_addr_t *dma_handle, gfp_t flag) |
68 | { | 87 | { |
69 | return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle, | 88 | return iommu_alloc_coherent(devnode_table(hwdev), size, dma_handle, |
70 | flag); | 89 | device_to_mask(hwdev), flag); |
71 | } | 90 | } |
72 | 91 | ||
73 | static void pci_iommu_free_coherent(struct device *hwdev, size_t size, | 92 | static void pci_iommu_free_coherent(struct device *hwdev, size_t size, |
@@ -85,7 +104,8 @@ static void pci_iommu_free_coherent(struct device *hwdev, size_t size, | |||
85 | static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr, | 104 | static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr, |
86 | size_t size, enum dma_data_direction direction) | 105 | size_t size, enum dma_data_direction direction) |
87 | { | 106 | { |
88 | return iommu_map_single(devnode_table(hwdev), vaddr, size, direction); | 107 | return iommu_map_single(devnode_table(hwdev), vaddr, size, |
108 | device_to_mask(hwdev), direction); | ||
89 | } | 109 | } |
90 | 110 | ||
91 | 111 | ||
@@ -100,7 +120,7 @@ static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist, | |||
100 | int nelems, enum dma_data_direction direction) | 120 | int nelems, enum dma_data_direction direction) |
101 | { | 121 | { |
102 | return iommu_map_sg(pdev, devnode_table(pdev), sglist, | 122 | return iommu_map_sg(pdev, devnode_table(pdev), sglist, |
103 | nelems, direction); | 123 | nelems, device_to_mask(pdev), direction); |
104 | } | 124 | } |
105 | 125 | ||
106 | static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist, | 126 | static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist, |
@@ -112,7 +132,19 @@ static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist, | |||
112 | /* We support DMA to/from any memory page via the iommu */ | 132 | /* We support DMA to/from any memory page via the iommu */ |
113 | static int pci_iommu_dma_supported(struct device *dev, u64 mask) | 133 | static int pci_iommu_dma_supported(struct device *dev, u64 mask) |
114 | { | 134 | { |
115 | return 1; | 135 | struct iommu_table *tbl = devnode_table(dev); |
136 | |||
137 | if (!tbl || tbl->it_offset > mask) { | ||
138 | printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n"); | ||
139 | if (tbl) | ||
140 | printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n", | ||
141 | mask, tbl->it_offset); | ||
142 | else | ||
143 | printk(KERN_INFO "mask: 0x%08lx, table unavailable\n", | ||
144 | mask); | ||
145 | return 0; | ||
146 | } else | ||
147 | return 1; | ||
116 | } | 148 | } |
117 | 149 | ||
118 | void pci_iommu_init(void) | 150 | void pci_iommu_init(void) |
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index dfa5398ab3c8..4b052ae5dc34 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c | |||
@@ -81,6 +81,7 @@ EXPORT_SYMBOL(strcat); | |||
81 | EXPORT_SYMBOL(strlen); | 81 | EXPORT_SYMBOL(strlen); |
82 | EXPORT_SYMBOL(strcmp); | 82 | EXPORT_SYMBOL(strcmp); |
83 | EXPORT_SYMBOL(strcasecmp); | 83 | EXPORT_SYMBOL(strcasecmp); |
84 | EXPORT_SYMBOL(strncasecmp); | ||
84 | 85 | ||
85 | EXPORT_SYMBOL(csum_partial); | 86 | EXPORT_SYMBOL(csum_partial); |
86 | EXPORT_SYMBOL(csum_partial_copy_generic); | 87 | EXPORT_SYMBOL(csum_partial_copy_generic); |
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c index 4336390bcf34..1cb69e8fb0b1 100644 --- a/arch/powerpc/kernel/prom.c +++ b/arch/powerpc/kernel/prom.c | |||
@@ -62,7 +62,7 @@ static int __initdata dt_root_addr_cells; | |||
62 | static int __initdata dt_root_size_cells; | 62 | static int __initdata dt_root_size_cells; |
63 | 63 | ||
64 | #ifdef CONFIG_PPC64 | 64 | #ifdef CONFIG_PPC64 |
65 | static int __initdata iommu_is_off; | 65 | int __initdata iommu_is_off; |
66 | int __initdata iommu_force_on; | 66 | int __initdata iommu_force_on; |
67 | unsigned long tce_alloc_start, tce_alloc_end; | 67 | unsigned long tce_alloc_start, tce_alloc_end; |
68 | #endif | 68 | #endif |
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index d66c5e77fcff..7e4d54821a07 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c | |||
@@ -1528,12 +1528,11 @@ static int __init prom_find_machine_type(void) | |||
1528 | * non-IBM designs ! | 1528 | * non-IBM designs ! |
1529 | * - it has /rtas | 1529 | * - it has /rtas |
1530 | */ | 1530 | */ |
1531 | len = prom_getprop(_prom->root, "model", | 1531 | len = prom_getprop(_prom->root, "device_type", |
1532 | compat, sizeof(compat)-1); | 1532 | compat, sizeof(compat)-1); |
1533 | if (len <= 0) | 1533 | if (len <= 0) |
1534 | return PLATFORM_GENERIC; | 1534 | return PLATFORM_GENERIC; |
1535 | compat[len] = 0; | 1535 | if (strncmp(compat, RELOC("chrp"), 4)) |
1536 | if (strcmp(compat, "chrp")) | ||
1537 | return PLATFORM_GENERIC; | 1536 | return PLATFORM_GENERIC; |
1538 | 1537 | ||
1539 | /* Default to pSeries. We need to know if we are running LPAR */ | 1538 | /* Default to pSeries. We need to know if we are running LPAR */ |
diff --git a/arch/powerpc/kernel/rtas-proc.c b/arch/powerpc/kernel/rtas-proc.c index 456286cf1d14..9c9ad1fa9cce 100644 --- a/arch/powerpc/kernel/rtas-proc.c +++ b/arch/powerpc/kernel/rtas-proc.c | |||
@@ -258,11 +258,11 @@ static int __init proc_rtas_init(void) | |||
258 | struct proc_dir_entry *entry; | 258 | struct proc_dir_entry *entry; |
259 | 259 | ||
260 | if (!machine_is(pseries)) | 260 | if (!machine_is(pseries)) |
261 | return 1; | 261 | return -ENODEV; |
262 | 262 | ||
263 | rtas_node = of_find_node_by_name(NULL, "rtas"); | 263 | rtas_node = of_find_node_by_name(NULL, "rtas"); |
264 | if (rtas_node == NULL) | 264 | if (rtas_node == NULL) |
265 | return 1; | 265 | return -ENODEV; |
266 | 266 | ||
267 | entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); | 267 | entry = create_proc_entry("ppc64/rtas/progress", S_IRUGO|S_IWUSR, NULL); |
268 | if (entry) | 268 | if (entry) |
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 73560ef6f802..ed737cacf92d 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c | |||
@@ -279,7 +279,7 @@ static void unregister_cpu_online(unsigned int cpu) | |||
279 | } | 279 | } |
280 | #endif /* CONFIG_HOTPLUG_CPU */ | 280 | #endif /* CONFIG_HOTPLUG_CPU */ |
281 | 281 | ||
282 | static int __devinit sysfs_cpu_notify(struct notifier_block *self, | 282 | static int sysfs_cpu_notify(struct notifier_block *self, |
283 | unsigned long action, void *hcpu) | 283 | unsigned long action, void *hcpu) |
284 | { | 284 | { |
285 | unsigned int cpu = (unsigned int)(long)hcpu; | 285 | unsigned int cpu = (unsigned int)(long)hcpu; |
@@ -297,7 +297,7 @@ static int __devinit sysfs_cpu_notify(struct notifier_block *self, | |||
297 | return NOTIFY_OK; | 297 | return NOTIFY_OK; |
298 | } | 298 | } |
299 | 299 | ||
300 | static struct notifier_block __devinitdata sysfs_cpu_nb = { | 300 | static struct notifier_block sysfs_cpu_nb = { |
301 | .notifier_call = sysfs_cpu_notify, | 301 | .notifier_call = sysfs_cpu_notify, |
302 | }; | 302 | }; |
303 | 303 | ||
diff --git a/arch/powerpc/kernel/systbl.S b/arch/powerpc/kernel/systbl.S index a14c96403840..0b98eea73c5e 100644 --- a/arch/powerpc/kernel/systbl.S +++ b/arch/powerpc/kernel/systbl.S | |||
@@ -324,3 +324,9 @@ COMPAT_SYS(ppoll) | |||
324 | SYSCALL(unshare) | 324 | SYSCALL(unshare) |
325 | SYSCALL(splice) | 325 | SYSCALL(splice) |
326 | SYSCALL(tee) | 326 | SYSCALL(tee) |
327 | SYSCALL(vmsplice) | ||
328 | |||
329 | /* | ||
330 | * please add new calls to arch/powerpc/platforms/cell/spu_callbacks.c | ||
331 | * as well when appropriate. | ||
332 | */ | ||
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 13c655ba2841..971020cf3f7d 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c | |||
@@ -202,7 +202,7 @@ static dma_addr_t vio_map_single(struct device *dev, void *vaddr, | |||
202 | size_t size, enum dma_data_direction direction) | 202 | size_t size, enum dma_data_direction direction) |
203 | { | 203 | { |
204 | return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size, | 204 | return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size, |
205 | direction); | 205 | ~0ul, direction); |
206 | } | 206 | } |
207 | 207 | ||
208 | static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle, | 208 | static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle, |
@@ -216,7 +216,7 @@ static int vio_map_sg(struct device *dev, struct scatterlist *sglist, | |||
216 | int nelems, enum dma_data_direction direction) | 216 | int nelems, enum dma_data_direction direction) |
217 | { | 217 | { |
218 | return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist, | 218 | return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist, |
219 | nelems, direction); | 219 | nelems, ~0ul, direction); |
220 | } | 220 | } |
221 | 221 | ||
222 | static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist, | 222 | static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist, |
@@ -229,7 +229,7 @@ static void *vio_alloc_coherent(struct device *dev, size_t size, | |||
229 | dma_addr_t *dma_handle, gfp_t flag) | 229 | dma_addr_t *dma_handle, gfp_t flag) |
230 | { | 230 | { |
231 | return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size, | 231 | return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size, |
232 | dma_handle, flag); | 232 | dma_handle, ~0ul, flag); |
233 | } | 233 | } |
234 | 234 | ||
235 | static void vio_free_coherent(struct device *dev, size_t size, | 235 | static void vio_free_coherent(struct device *dev, size_t size, |
diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c index 6594bec73882..b283380a2a18 100644 --- a/arch/powerpc/platforms/cell/spu_callbacks.c +++ b/arch/powerpc/platforms/cell/spu_callbacks.c | |||
@@ -317,17 +317,17 @@ void *spu_syscall_table[] = { | |||
317 | [__NR_ppoll] sys_ni_syscall, /* sys_ppoll */ | 317 | [__NR_ppoll] sys_ni_syscall, /* sys_ppoll */ |
318 | [__NR_unshare] sys_unshare, | 318 | [__NR_unshare] sys_unshare, |
319 | [__NR_splice] sys_splice, | 319 | [__NR_splice] sys_splice, |
320 | [__NR_tee] sys_tee, | ||
321 | [__NR_vmsplice] sys_vmsplice, | ||
320 | }; | 322 | }; |
321 | 323 | ||
322 | long spu_sys_callback(struct spu_syscall_block *s) | 324 | long spu_sys_callback(struct spu_syscall_block *s) |
323 | { | 325 | { |
324 | long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6); | 326 | long (*syscall)(u64 a1, u64 a2, u64 a3, u64 a4, u64 a5, u64 a6); |
325 | 327 | ||
326 | BUILD_BUG_ON(ARRAY_SIZE(spu_syscall_table) != __NR_syscalls); | ||
327 | |||
328 | syscall = spu_syscall_table[s->nr_ret]; | 328 | syscall = spu_syscall_table[s->nr_ret]; |
329 | 329 | ||
330 | if (s->nr_ret >= __NR_syscalls) { | 330 | if (s->nr_ret >= ARRAY_SIZE(spu_syscall_table)) { |
331 | pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret); | 331 | pr_debug("%s: invalid syscall #%ld", __FUNCTION__, s->nr_ret); |
332 | return -ENOSYS; | 332 | return -ENOSYS; |
333 | } | 333 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 97898d5d34e5..1726bfe38ee0 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c | |||
@@ -1297,7 +1297,7 @@ static inline void setup_decr(struct spu_state *csa, struct spu *spu) | |||
1297 | cycles_t resume_time = get_cycles(); | 1297 | cycles_t resume_time = get_cycles(); |
1298 | cycles_t delta_time = resume_time - csa->suspend_time; | 1298 | cycles_t delta_time = resume_time - csa->suspend_time; |
1299 | 1299 | ||
1300 | csa->lscsa->decr.slot[0] = delta_time; | 1300 | csa->lscsa->decr.slot[0] -= delta_time; |
1301 | } | 1301 | } |
1302 | } | 1302 | } |
1303 | 1303 | ||
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h index 63f0aee4c158..996c28744e96 100644 --- a/arch/powerpc/platforms/chrp/chrp.h +++ b/arch/powerpc/platforms/chrp/chrp.h | |||
@@ -9,3 +9,4 @@ extern long chrp_time_init(void); | |||
9 | 9 | ||
10 | extern void chrp_find_bridges(void); | 10 | extern void chrp_find_bridges(void); |
11 | extern void chrp_event_scan(unsigned long); | 11 | extern void chrp_event_scan(unsigned long); |
12 | extern void chrp_pcibios_fixup(void); | ||
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c index 8ef279ad36ad..ac224876ce59 100644 --- a/arch/powerpc/platforms/chrp/pci.c +++ b/arch/powerpc/platforms/chrp/pci.c | |||
@@ -23,6 +23,8 @@ | |||
23 | #include <asm/grackle.h> | 23 | #include <asm/grackle.h> |
24 | #include <asm/rtas.h> | 24 | #include <asm/rtas.h> |
25 | 25 | ||
26 | #include "chrp.h" | ||
27 | |||
26 | /* LongTrail */ | 28 | /* LongTrail */ |
27 | void __iomem *gg2_pci_config_base; | 29 | void __iomem *gg2_pci_config_base; |
28 | 30 | ||
@@ -314,6 +316,6 @@ chrp_find_bridges(void) | |||
314 | } | 316 | } |
315 | 317 | ||
316 | /* Do not fixup interrupts from OF tree on pegasos */ | 318 | /* Do not fixup interrupts from OF tree on pegasos */ |
317 | if (is_pegasos == 0) | 319 | if (is_pegasos) |
318 | ppc_md.pcibios_fixup = chrp_pcibios_fixup; | 320 | ppc_md.pcibios_fixup = NULL; |
319 | } | 321 | } |
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c index 23a201718704..18d89f38796b 100644 --- a/arch/powerpc/platforms/chrp/setup.c +++ b/arch/powerpc/platforms/chrp/setup.c | |||
@@ -440,8 +440,6 @@ void __init chrp_init_IRQ(void) | |||
440 | 440 | ||
441 | if (_chrp_type == _CHRP_Pegasos) | 441 | if (_chrp_type == _CHRP_Pegasos) |
442 | ppc_md.get_irq = i8259_irq; | 442 | ppc_md.get_irq = i8259_irq; |
443 | else | ||
444 | ppc_md.get_irq = mpic_get_irq; | ||
445 | 443 | ||
446 | #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) | 444 | #if defined(CONFIG_VT) && defined(CONFIG_INPUT_ADBHID) && defined(XMON) |
447 | /* see if there is a keyboard in the device tree | 445 | /* see if there is a keyboard in the device tree |
@@ -528,26 +526,24 @@ static int __init chrp_probe(void) | |||
528 | /* Assume we have an 8259... */ | 526 | /* Assume we have an 8259... */ |
529 | __irq_offset_value = NUM_ISA_INTERRUPTS; | 527 | __irq_offset_value = NUM_ISA_INTERRUPTS; |
530 | 528 | ||
531 | ppc_md.setup_arch = chrp_setup_arch; | 529 | return 1; |
532 | ppc_md.show_cpuinfo = chrp_show_cpuinfo; | ||
533 | |||
534 | ppc_md.init_IRQ = chrp_init_IRQ; | ||
535 | ppc_md.init = chrp_init2; | ||
536 | |||
537 | ppc_md.phys_mem_access_prot = pci_phys_mem_access_prot; | ||
538 | |||
539 | ppc_md.restart = rtas_restart; | ||
540 | ppc_md.power_off = rtas_power_off; | ||
541 | ppc_md.halt = rtas_halt; | ||
542 | |||
543 | ppc_md.time_init = chrp_time_init; | ||
544 | ppc_md.calibrate_decr = generic_calibrate_decr; | ||
545 | |||
546 | /* this may get overridden with rtas routines later... */ | ||
547 | ppc_md.set_rtc_time = chrp_set_rtc_time; | ||
548 | ppc_md.get_rtc_time = chrp_get_rtc_time; | ||
549 | |||
550 | #ifdef CONFIG_SMP | ||
551 | smp_ops = &chrp_smp_ops; | ||
552 | #endif /* CONFIG_SMP */ | ||
553 | } | 530 | } |
531 | |||
532 | define_machine(chrp) { | ||
533 | .name = "CHRP", | ||
534 | .probe = chrp_probe, | ||
535 | .setup_arch = chrp_setup_arch, | ||
536 | .init = chrp_init2, | ||
537 | .show_cpuinfo = chrp_show_cpuinfo, | ||
538 | .init_IRQ = chrp_init_IRQ, | ||
539 | .get_irq = mpic_get_irq, | ||
540 | .pcibios_fixup = chrp_pcibios_fixup, | ||
541 | .restart = rtas_restart, | ||
542 | .power_off = rtas_power_off, | ||
543 | .halt = rtas_halt, | ||
544 | .time_init = chrp_time_init, | ||
545 | .set_rtc_time = chrp_set_rtc_time, | ||
546 | .get_rtc_time = chrp_get_rtc_time, | ||
547 | .calibrate_decr = generic_calibrate_decr, | ||
548 | .phys_mem_access_prot = pci_phys_mem_access_prot, | ||
549 | }; | ||
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index 6ce8a404ba6b..a6fd9bedb074 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
@@ -54,6 +54,7 @@ | |||
54 | #include <asm/iseries/hv_lp_event.h> | 54 | #include <asm/iseries/hv_lp_event.h> |
55 | #include <asm/iseries/lpar_map.h> | 55 | #include <asm/iseries/lpar_map.h> |
56 | #include <asm/udbg.h> | 56 | #include <asm/udbg.h> |
57 | #include <asm/irq.h> | ||
57 | 58 | ||
58 | #include "naca.h" | 59 | #include "naca.h" |
59 | #include "setup.h" | 60 | #include "setup.h" |
@@ -684,6 +685,12 @@ static int __init iseries_probe(void) | |||
684 | powerpc_firmware_features |= FW_FEATURE_ISERIES; | 685 | powerpc_firmware_features |= FW_FEATURE_ISERIES; |
685 | powerpc_firmware_features |= FW_FEATURE_LPAR; | 686 | powerpc_firmware_features |= FW_FEATURE_LPAR; |
686 | 687 | ||
688 | /* | ||
689 | * The Hypervisor only allows us up to 256 interrupt | ||
690 | * sources (the irq number is passed in a u8). | ||
691 | */ | ||
692 | virt_irq_max = 255; | ||
693 | |||
687 | return 1; | 694 | return 1; |
688 | } | 695 | } |
689 | 696 | ||
diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c index e14f9ac55cf4..df2343e1956b 100644 --- a/arch/powerpc/platforms/powermac/low_i2c.c +++ b/arch/powerpc/platforms/powermac/low_i2c.c | |||
@@ -231,6 +231,14 @@ static u8 kw_i2c_wait_interrupt(struct pmac_i2c_host_kw *host) | |||
231 | return isr; | 231 | return isr; |
232 | } | 232 | } |
233 | 233 | ||
234 | static void kw_i2c_do_stop(struct pmac_i2c_host_kw *host, int result) | ||
235 | { | ||
236 | kw_write_reg(reg_control, KW_I2C_CTL_STOP); | ||
237 | host->state = state_stop; | ||
238 | host->result = result; | ||
239 | } | ||
240 | |||
241 | |||
234 | static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr) | 242 | static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr) |
235 | { | 243 | { |
236 | u8 ack; | 244 | u8 ack; |
@@ -246,42 +254,36 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr) | |||
246 | } | 254 | } |
247 | 255 | ||
248 | if (isr == 0) { | 256 | if (isr == 0) { |
257 | printk(KERN_WARNING "low_i2c: Timeout in i2c transfer" | ||
258 | " on keywest !\n"); | ||
249 | if (host->state != state_stop) { | 259 | if (host->state != state_stop) { |
250 | DBG_LOW("KW: Timeout !\n"); | 260 | kw_i2c_do_stop(host, -EIO); |
251 | host->result = -EIO; | 261 | return; |
252 | goto stop; | ||
253 | } | ||
254 | if (host->state == state_stop) { | ||
255 | ack = kw_read_reg(reg_status); | ||
256 | if (ack & KW_I2C_STAT_BUSY) | ||
257 | kw_write_reg(reg_status, 0); | ||
258 | host->state = state_idle; | ||
259 | kw_write_reg(reg_ier, 0x00); | ||
260 | if (!host->polled) | ||
261 | complete(&host->complete); | ||
262 | } | 262 | } |
263 | ack = kw_read_reg(reg_status); | ||
264 | if (ack & KW_I2C_STAT_BUSY) | ||
265 | kw_write_reg(reg_status, 0); | ||
266 | host->state = state_idle; | ||
267 | kw_write_reg(reg_ier, 0x00); | ||
268 | if (!host->polled) | ||
269 | complete(&host->complete); | ||
263 | return; | 270 | return; |
264 | } | 271 | } |
265 | 272 | ||
266 | if (isr & KW_I2C_IRQ_ADDR) { | 273 | if (isr & KW_I2C_IRQ_ADDR) { |
267 | ack = kw_read_reg(reg_status); | 274 | ack = kw_read_reg(reg_status); |
268 | if (host->state != state_addr) { | 275 | if (host->state != state_addr) { |
269 | kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); | ||
270 | WRONG_STATE("KW_I2C_IRQ_ADDR"); | 276 | WRONG_STATE("KW_I2C_IRQ_ADDR"); |
271 | host->result = -EIO; | 277 | kw_i2c_do_stop(host, -EIO); |
272 | goto stop; | ||
273 | } | 278 | } |
274 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { | 279 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
275 | host->result = -ENODEV; | 280 | host->result = -ENXIO; |
276 | DBG_LOW("KW: NAK on address\n"); | ||
277 | host->state = state_stop; | 281 | host->state = state_stop; |
278 | return; | 282 | DBG_LOW("KW: NAK on address\n"); |
279 | } else { | 283 | } else { |
280 | if (host->len == 0) { | 284 | if (host->len == 0) |
281 | kw_write_reg(reg_isr, KW_I2C_IRQ_ADDR); | 285 | kw_i2c_do_stop(host, 0); |
282 | goto stop; | 286 | else if (host->rw) { |
283 | } | ||
284 | if (host->rw) { | ||
285 | host->state = state_read; | 287 | host->state = state_read; |
286 | if (host->len > 1) | 288 | if (host->len > 1) |
287 | kw_write_reg(reg_control, | 289 | kw_write_reg(reg_control, |
@@ -308,25 +310,19 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr) | |||
308 | ack = kw_read_reg(reg_status); | 310 | ack = kw_read_reg(reg_status); |
309 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { | 311 | if ((ack & KW_I2C_STAT_LAST_AAK) == 0) { |
310 | DBG_LOW("KW: nack on data write\n"); | 312 | DBG_LOW("KW: nack on data write\n"); |
311 | host->result = -EIO; | 313 | host->result = -EFBIG; |
312 | goto stop; | 314 | host->state = state_stop; |
313 | } else if (host->len) { | 315 | } else if (host->len) { |
314 | kw_write_reg(reg_data, *(host->data++)); | 316 | kw_write_reg(reg_data, *(host->data++)); |
315 | host->len--; | 317 | host->len--; |
316 | } else { | 318 | } else |
317 | kw_write_reg(reg_control, KW_I2C_CTL_STOP); | 319 | kw_i2c_do_stop(host, 0); |
318 | host->state = state_stop; | ||
319 | host->result = 0; | ||
320 | } | ||
321 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); | ||
322 | } else { | 320 | } else { |
323 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); | ||
324 | WRONG_STATE("KW_I2C_IRQ_DATA"); | 321 | WRONG_STATE("KW_I2C_IRQ_DATA"); |
325 | if (host->state != state_stop) { | 322 | if (host->state != state_stop) |
326 | host->result = -EIO; | 323 | kw_i2c_do_stop(host, -EIO); |
327 | goto stop; | ||
328 | } | ||
329 | } | 324 | } |
325 | kw_write_reg(reg_isr, KW_I2C_IRQ_DATA); | ||
330 | } | 326 | } |
331 | 327 | ||
332 | if (isr & KW_I2C_IRQ_STOP) { | 328 | if (isr & KW_I2C_IRQ_STOP) { |
@@ -340,14 +336,10 @@ static void kw_i2c_handle_interrupt(struct pmac_i2c_host_kw *host, u8 isr) | |||
340 | complete(&host->complete); | 336 | complete(&host->complete); |
341 | } | 337 | } |
342 | 338 | ||
339 | /* Below should only happen in manual mode which we don't use ... */ | ||
343 | if (isr & KW_I2C_IRQ_START) | 340 | if (isr & KW_I2C_IRQ_START) |
344 | kw_write_reg(reg_isr, KW_I2C_IRQ_START); | 341 | kw_write_reg(reg_isr, KW_I2C_IRQ_START); |
345 | 342 | ||
346 | return; | ||
347 | stop: | ||
348 | kw_write_reg(reg_control, KW_I2C_CTL_STOP); | ||
349 | host->state = state_stop; | ||
350 | return; | ||
351 | } | 343 | } |
352 | 344 | ||
353 | /* Interrupt handler */ | 345 | /* Interrupt handler */ |
@@ -544,11 +536,11 @@ static struct pmac_i2c_host_kw *__init kw_i2c_host_init(struct device_node *np) | |||
544 | return NULL; | 536 | return NULL; |
545 | } | 537 | } |
546 | 538 | ||
547 | /* Make sure IRA is disabled */ | 539 | /* Make sure IRQ is disabled */ |
548 | kw_write_reg(reg_ier, 0); | 540 | kw_write_reg(reg_ier, 0); |
549 | 541 | ||
550 | /* Request chip interrupt */ | 542 | /* Request chip interrupt */ |
551 | if (request_irq(host->irq, kw_i2c_irq, SA_SHIRQ, "keywest i2c", host)) | 543 | if (request_irq(host->irq, kw_i2c_irq, 0, "keywest i2c", host)) |
552 | host->irq = NO_IRQ; | 544 | host->irq = NO_IRQ; |
553 | 545 | ||
554 | printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n", | 546 | printk(KERN_INFO "KeyWest i2c @0x%08x irq %d %s\n", |
diff --git a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c index 780fb27a0099..32eaddfa5470 100644 --- a/arch/powerpc/platforms/pseries/eeh.c +++ b/arch/powerpc/platforms/pseries/eeh.c | |||
@@ -957,8 +957,10 @@ static void eeh_remove_device(struct pci_dev *dev) | |||
957 | pci_addr_cache_remove_device(dev); | 957 | pci_addr_cache_remove_device(dev); |
958 | 958 | ||
959 | dn = pci_device_to_OF_node(dev); | 959 | dn = pci_device_to_OF_node(dev); |
960 | PCI_DN(dn)->pcidev = NULL; | 960 | if (PCI_DN(dn)->pcidev) { |
961 | pci_dev_put (dev); | 961 | PCI_DN(dn)->pcidev = NULL; |
962 | pci_dev_put (dev); | ||
963 | } | ||
962 | } | 964 | } |
963 | 965 | ||
964 | void eeh_remove_bus_device(struct pci_dev *dev) | 966 | void eeh_remove_bus_device(struct pci_dev *dev) |
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index fcc4d561a236..e0000ce769e5 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c | |||
@@ -488,7 +488,7 @@ static int __init rtas_init(void) | |||
488 | /* No RTAS */ | 488 | /* No RTAS */ |
489 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { | 489 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { |
490 | printk(KERN_INFO "rtasd: no event-scan on system\n"); | 490 | printk(KERN_INFO "rtasd: no event-scan on system\n"); |
491 | return 1; | 491 | return -ENODEV; |
492 | } | 492 | } |
493 | 493 | ||
494 | entry = create_proc_entry("ppc64/rtas/error_log", S_IRUSR, NULL); | 494 | entry = create_proc_entry("ppc64/rtas/error_log", S_IRUSR, NULL); |
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 61d317428610..38087bd6e3cf 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c | |||
@@ -49,6 +49,7 @@ | |||
49 | 49 | ||
50 | #include "dart.h" | 50 | #include "dart.h" |
51 | 51 | ||
52 | extern int iommu_is_off; | ||
52 | extern int iommu_force_on; | 53 | extern int iommu_force_on; |
53 | 54 | ||
54 | /* Physical base address and size of the DART table */ | 55 | /* Physical base address and size of the DART table */ |
@@ -329,10 +330,17 @@ void iommu_init_early_dart(void) | |||
329 | 330 | ||
330 | void __init alloc_dart_table(void) | 331 | void __init alloc_dart_table(void) |
331 | { | 332 | { |
332 | /* Only reserve DART space if machine has more than 2GB of RAM | 333 | /* Only reserve DART space if machine has more than 1GB of RAM |
333 | * or if requested with iommu=on on cmdline. | 334 | * or if requested with iommu=on on cmdline. |
335 | * | ||
336 | * 1GB of RAM is picked as limit because some default devices | ||
337 | * (i.e. Airport Extreme) have 30 bit address range limits. | ||
334 | */ | 338 | */ |
335 | if (lmb_end_of_DRAM() <= 0x80000000ull && !iommu_force_on) | 339 | |
340 | if (iommu_is_off) | ||
341 | return; | ||
342 | |||
343 | if (!iommu_force_on && lmb_end_of_DRAM() <= 0x40000000ull) | ||
336 | return; | 344 | return; |
337 | 345 | ||
338 | /* 512 pages (2MB) is max DART tablesize. */ | 346 | /* 512 pages (2MB) is max DART tablesize. */ |
diff --git a/arch/ppc/kernel/asm-offsets.c b/arch/ppc/kernel/asm-offsets.c index 77e4dc780f8c..cc7c4aea9397 100644 --- a/arch/ppc/kernel/asm-offsets.c +++ b/arch/ppc/kernel/asm-offsets.c | |||
@@ -134,6 +134,7 @@ main(void) | |||
134 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); | 134 | DEFINE(TI_TASK, offsetof(struct thread_info, task)); |
135 | DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); | 135 | DEFINE(TI_EXECDOMAIN, offsetof(struct thread_info, exec_domain)); |
136 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); | 136 | DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); |
137 | DEFINE(TI_LOCAL_FLAGS, offsetof(struct thread_info, flags)); | ||
137 | DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); | 138 | DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); |
138 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); | 139 | DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); |
139 | 140 | ||
diff --git a/arch/ppc/kernel/entry.S b/arch/ppc/kernel/entry.S index 5891ecbdc703..1adc9145516f 100644 --- a/arch/ppc/kernel/entry.S +++ b/arch/ppc/kernel/entry.S | |||
@@ -128,29 +128,26 @@ transfer_to_handler: | |||
128 | stw r12,4(r11) | 128 | stw r12,4(r11) |
129 | #endif | 129 | #endif |
130 | b 3f | 130 | b 3f |
131 | |||
131 | 2: /* if from kernel, check interrupted DOZE/NAP mode and | 132 | 2: /* if from kernel, check interrupted DOZE/NAP mode and |
132 | * check for stack overflow | 133 | * check for stack overflow |
133 | */ | 134 | */ |
135 | lwz r9,THREAD_INFO-THREAD(r12) | ||
136 | cmplw r1,r9 /* if r1 <= current->thread_info */ | ||
137 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
138 | 5: | ||
134 | #ifdef CONFIG_6xx | 139 | #ifdef CONFIG_6xx |
135 | mfspr r11,SPRN_HID0 | 140 | tophys(r9,r9) /* check local flags */ |
136 | mtcr r11 | 141 | lwz r12,TI_LOCAL_FLAGS(r9) |
137 | BEGIN_FTR_SECTION | 142 | mtcrf 0x01,r12 |
138 | bt- 8,4f /* Check DOZE */ | 143 | bt- 31-TLF_NAPPING,4f |
139 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_DOZE) | ||
140 | BEGIN_FTR_SECTION | ||
141 | bt- 9,4f /* Check NAP */ | ||
142 | END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) | ||
143 | #endif /* CONFIG_6xx */ | 144 | #endif /* CONFIG_6xx */ |
144 | .globl transfer_to_handler_cont | 145 | .globl transfer_to_handler_cont |
145 | transfer_to_handler_cont: | 146 | transfer_to_handler_cont: |
146 | lwz r11,THREAD_INFO-THREAD(r12) | ||
147 | cmplw r1,r11 /* if r1 <= current->thread_info */ | ||
148 | ble- stack_ovf /* then the kernel stack overflowed */ | ||
149 | 3: | 147 | 3: |
150 | mflr r9 | 148 | mflr r9 |
151 | lwz r11,0(r9) /* virtual address of handler */ | 149 | lwz r11,0(r9) /* virtual address of handler */ |
152 | lwz r9,4(r9) /* where to go when done */ | 150 | lwz r9,4(r9) /* where to go when done */ |
153 | FIX_SRR1(r10,r12) | ||
154 | mtspr SPRN_SRR0,r11 | 151 | mtspr SPRN_SRR0,r11 |
155 | mtspr SPRN_SRR1,r10 | 152 | mtspr SPRN_SRR1,r10 |
156 | mtlr r9 | 153 | mtlr r9 |
@@ -158,7 +155,9 @@ transfer_to_handler_cont: | |||
158 | RFI /* jump to handler, enable MMU */ | 155 | RFI /* jump to handler, enable MMU */ |
159 | 156 | ||
160 | #ifdef CONFIG_6xx | 157 | #ifdef CONFIG_6xx |
161 | 4: b power_save_6xx_restore | 158 | 4: rlwinm r12,r12,0,~_TLF_NAPPING |
159 | stw r12,TI_LOCAL_FLAGS(r9) | ||
160 | b power_save_6xx_restore | ||
162 | #endif | 161 | #endif |
163 | 162 | ||
164 | /* | 163 | /* |
@@ -167,10 +166,10 @@ transfer_to_handler_cont: | |||
167 | */ | 166 | */ |
168 | stack_ovf: | 167 | stack_ovf: |
169 | /* sometimes we use a statically-allocated stack, which is OK. */ | 168 | /* sometimes we use a statically-allocated stack, which is OK. */ |
170 | lis r11,_end@h | 169 | lis r12,_end@h |
171 | ori r11,r11,_end@l | 170 | ori r12,r12,_end@l |
172 | cmplw r1,r11 | 171 | cmplw r1,r12 |
173 | ble 3b /* r1 <= &_end is OK */ | 172 | ble 5b /* r1 <= &_end is OK */ |
174 | SAVE_NVGPRS(r11) | 173 | SAVE_NVGPRS(r11) |
175 | addi r3,r1,STACK_FRAME_OVERHEAD | 174 | addi r3,r1,STACK_FRAME_OVERHEAD |
176 | lis r1,init_thread_union@ha | 175 | lis r1,init_thread_union@ha |
diff --git a/arch/ppc/kernel/ppc_ksyms.c b/arch/ppc/kernel/ppc_ksyms.c index 865ba74991a9..b250b1b539b6 100644 --- a/arch/ppc/kernel/ppc_ksyms.c +++ b/arch/ppc/kernel/ppc_ksyms.c | |||
@@ -94,6 +94,7 @@ EXPORT_SYMBOL(strcat); | |||
94 | EXPORT_SYMBOL(strlen); | 94 | EXPORT_SYMBOL(strlen); |
95 | EXPORT_SYMBOL(strcmp); | 95 | EXPORT_SYMBOL(strcmp); |
96 | EXPORT_SYMBOL(strcasecmp); | 96 | EXPORT_SYMBOL(strcasecmp); |
97 | EXPORT_SYMBOL(strncasecmp); | ||
97 | EXPORT_SYMBOL(__div64_32); | 98 | EXPORT_SYMBOL(__div64_32); |
98 | 99 | ||
99 | EXPORT_SYMBOL(csum_partial); | 100 | EXPORT_SYMBOL(csum_partial); |
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c index 60c724e11584..7662c4e6e7d6 100644 --- a/arch/ppc/syslib/ppc_sys.c +++ b/arch/ppc/syslib/ppc_sys.c | |||
@@ -156,12 +156,13 @@ void platform_notify_map(const struct platform_notify_dev_map *map, | |||
156 | while (map->bus_id != NULL) { | 156 | while (map->bus_id != NULL) { |
157 | idx = -1; | 157 | idx = -1; |
158 | s = strrchr(dev->bus_id, '.'); | 158 | s = strrchr(dev->bus_id, '.'); |
159 | if (s != NULL) | 159 | if (s != NULL) { |
160 | idx = (int)simple_strtol(s + 1, NULL, 10); | 160 | idx = (int)simple_strtol(s + 1, NULL, 10); |
161 | else | 161 | len = s - dev->bus_id; |
162 | } else { | ||
162 | s = dev->bus_id; | 163 | s = dev->bus_id; |
163 | 164 | len = strlen(dev->bus_id); | |
164 | len = s - dev->bus_id; | 165 | } |
165 | 166 | ||
166 | if (!strncmp(dev->bus_id, map->bus_id, len)) { | 167 | if (!strncmp(dev->bus_id, map->bus_id, len)) { |
167 | pdev = container_of(dev, struct platform_device, dev); | 168 | pdev = container_of(dev, struct platform_device, dev); |
diff --git a/arch/s390/appldata/appldata_base.c b/arch/s390/appldata/appldata_base.c index 54d35c130907..9a22434a580c 100644 --- a/arch/s390/appldata/appldata_base.c +++ b/arch/s390/appldata/appldata_base.c | |||
@@ -652,7 +652,7 @@ appldata_cpu_notify(struct notifier_block *self, | |||
652 | return NOTIFY_OK; | 652 | return NOTIFY_OK; |
653 | } | 653 | } |
654 | 654 | ||
655 | static struct notifier_block __devinitdata appldata_nb = { | 655 | static struct notifier_block appldata_nb = { |
656 | .notifier_call = appldata_cpu_notify, | 656 | .notifier_call = appldata_cpu_notify, |
657 | }; | 657 | }; |
658 | 658 | ||
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 648047a0bce3..43a66f5407f4 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig | |||
@@ -187,7 +187,7 @@ config HUGETLB_PAGE_SIZE_512K | |||
187 | bool "512K" | 187 | bool "512K" |
188 | 188 | ||
189 | config HUGETLB_PAGE_SIZE_64K | 189 | config HUGETLB_PAGE_SIZE_64K |
190 | depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB && !SPARC64_PAGE_SIZE_64K | 190 | depends on !SPARC64_PAGE_SIZE_4MB && !SPARC64_PAGE_SIZE_512KB && !SPARC64_PAGE_SIZE_64KB |
191 | bool "64K" | 191 | bool "64K" |
192 | 192 | ||
193 | endchoice | 193 | endchoice |
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c index ffc7309e9f22..2e1c824c1cc9 100644 --- a/arch/sparc64/kernel/kprobes.c +++ b/arch/sparc64/kernel/kprobes.c | |||
@@ -63,7 +63,7 @@ void __kprobes arch_disarm_kprobe(struct kprobe *p) | |||
63 | flushi(p->addr); | 63 | flushi(p->addr); |
64 | } | 64 | } |
65 | 65 | ||
66 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 66 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
67 | { | 67 | { |
68 | kcb->prev_kprobe.kp = kprobe_running(); | 68 | kcb->prev_kprobe.kp = kprobe_running(); |
69 | kcb->prev_kprobe.status = kcb->kprobe_status; | 69 | kcb->prev_kprobe.status = kcb->kprobe_status; |
@@ -71,7 +71,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
71 | kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil; | 71 | kcb->prev_kprobe.orig_tstate_pil = kcb->kprobe_orig_tstate_pil; |
72 | } | 72 | } |
73 | 73 | ||
74 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 74 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
75 | { | 75 | { |
76 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 76 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
77 | kcb->kprobe_status = kcb->prev_kprobe.status; | 77 | kcb->kprobe_status = kcb->prev_kprobe.status; |
@@ -79,7 +79,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
79 | kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil; | 79 | kcb->kprobe_orig_tstate_pil = kcb->prev_kprobe.orig_tstate_pil; |
80 | } | 80 | } |
81 | 81 | ||
82 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | 82 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
83 | struct kprobe_ctlblk *kcb) | 83 | struct kprobe_ctlblk *kcb) |
84 | { | 84 | { |
85 | __get_cpu_var(current_kprobe) = p; | 85 | __get_cpu_var(current_kprobe) = p; |
@@ -87,7 +87,7 @@ static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | |||
87 | kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL); | 87 | kcb->kprobe_orig_tstate_pil = (regs->tstate & TSTATE_PIL); |
88 | } | 88 | } |
89 | 89 | ||
90 | static inline void prepare_singlestep(struct kprobe *p, struct pt_regs *regs, | 90 | static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs, |
91 | struct kprobe_ctlblk *kcb) | 91 | struct kprobe_ctlblk *kcb) |
92 | { | 92 | { |
93 | regs->tstate |= TSTATE_PIL; | 93 | regs->tstate |= TSTATE_PIL; |
@@ -273,7 +273,7 @@ static void __kprobes resume_execution(struct kprobe *p, | |||
273 | kcb->kprobe_orig_tstate_pil); | 273 | kcb->kprobe_orig_tstate_pil); |
274 | } | 274 | } |
275 | 275 | ||
276 | static inline int post_kprobe_handler(struct pt_regs *regs) | 276 | static int __kprobes post_kprobe_handler(struct pt_regs *regs) |
277 | { | 277 | { |
278 | struct kprobe *cur = kprobe_running(); | 278 | struct kprobe *cur = kprobe_running(); |
279 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 279 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
@@ -300,7 +300,7 @@ out: | |||
300 | return 1; | 300 | return 1; |
301 | } | 301 | } |
302 | 302 | ||
303 | static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) | 303 | static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) |
304 | { | 304 | { |
305 | struct kprobe *cur = kprobe_running(); | 305 | struct kprobe *cur = kprobe_running(); |
306 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); | 306 | struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); |
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index 0ec4052db9c5..6ab852bfcd3a 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c | |||
@@ -100,7 +100,7 @@ struct cow_header_v3_broken { | |||
100 | __u32 alignment; | 100 | __u32 alignment; |
101 | __u32 cow_format; | 101 | __u32 cow_format; |
102 | char backing_file[PATH_LEN_V3]; | 102 | char backing_file[PATH_LEN_V3]; |
103 | }; | 103 | } __attribute__((packed)); |
104 | 104 | ||
105 | /* COW format definitions - for now, we have only the usual COW bitmap */ | 105 | /* COW format definitions - for now, we have only the usual COW bitmap */ |
106 | #define COW_BITMAP 0 | 106 | #define COW_BITMAP 0 |
diff --git a/arch/um/include/longjmp.h b/arch/um/include/longjmp.h index 018b3819ab0b..8e7053013f7b 100644 --- a/arch/um/include/longjmp.h +++ b/arch/um/include/longjmp.h | |||
@@ -4,11 +4,11 @@ | |||
4 | #include <setjmp.h> | 4 | #include <setjmp.h> |
5 | #include "os.h" | 5 | #include "os.h" |
6 | 6 | ||
7 | #define UML_SIGLONGJMP(buf, val) do { \ | 7 | #define UML_LONGJMP(buf, val) do { \ |
8 | longjmp(*buf, val); \ | 8 | longjmp(*buf, val); \ |
9 | } while(0) | 9 | } while(0) |
10 | 10 | ||
11 | #define UML_SIGSETJMP(buf, enable) ({ \ | 11 | #define UML_SETJMP(buf, enable) ({ \ |
12 | int n; \ | 12 | int n; \ |
13 | enable = get_signals(); \ | 13 | enable = get_signals(); \ |
14 | n = setjmp(*buf); \ | 14 | n = setjmp(*buf); \ |
diff --git a/arch/um/include/sysdep-i386/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h index 82f96c574144..2c13de321f2f 100644 --- a/arch/um/include/sysdep-i386/kernel-offsets.h +++ b/arch/um/include/sysdep-i386/kernel-offsets.h | |||
@@ -1,6 +1,7 @@ | |||
1 | #include <linux/stddef.h> | 1 | #include <linux/stddef.h> |
2 | #include <linux/sched.h> | 2 | #include <linux/sched.h> |
3 | #include <linux/elf.h> | 3 | #include <linux/elf.h> |
4 | #include <asm/mman.h> | ||
4 | 5 | ||
5 | #define DEFINE(sym, val) \ | 6 | #define DEFINE(sym, val) \ |
6 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | 7 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) |
@@ -16,6 +17,7 @@ | |||
16 | void foo(void) | 17 | void foo(void) |
17 | { | 18 | { |
18 | OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); | 19 | OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs); |
20 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | ||
19 | #ifdef CONFIG_MODE_TT | 21 | #ifdef CONFIG_MODE_TT |
20 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | 22 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); |
21 | #endif | 23 | #endif |
diff --git a/arch/um/include/sysdep-x86_64/kernel-offsets.h b/arch/um/include/sysdep-x86_64/kernel-offsets.h index 5ce93abd0b54..939cc475757a 100644 --- a/arch/um/include/sysdep-x86_64/kernel-offsets.h +++ b/arch/um/include/sysdep-x86_64/kernel-offsets.h | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/time.h> | 4 | #include <linux/time.h> |
5 | #include <linux/elf.h> | 5 | #include <linux/elf.h> |
6 | #include <asm/page.h> | 6 | #include <asm/page.h> |
7 | #include <asm/mman.h> | ||
7 | 8 | ||
8 | #define DEFINE(sym, val) \ | 9 | #define DEFINE(sym, val) \ |
9 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) | 10 | asm volatile("\n->" #sym " %0 " #val : : "i" (val)) |
@@ -18,6 +19,7 @@ | |||
18 | 19 | ||
19 | void foo(void) | 20 | void foo(void) |
20 | { | 21 | { |
22 | DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); | ||
21 | #ifdef CONFIG_MODE_TT | 23 | #ifdef CONFIG_MODE_TT |
22 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); | 24 | OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid); |
23 | #endif | 25 | #endif |
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c index 71bb90a7606d..c6432e729241 100644 --- a/arch/um/os-Linux/mem.c +++ b/arch/um/os-Linux/mem.c | |||
@@ -8,6 +8,7 @@ | |||
8 | #include <fcntl.h> | 8 | #include <fcntl.h> |
9 | #include <sys/types.h> | 9 | #include <sys/types.h> |
10 | #include <sys/mman.h> | 10 | #include <sys/mman.h> |
11 | #include <sys/statfs.h> | ||
11 | #include "kern_util.h" | 12 | #include "kern_util.h" |
12 | #include "user.h" | 13 | #include "user.h" |
13 | #include "user_util.h" | 14 | #include "user_util.h" |
@@ -19,6 +20,7 @@ | |||
19 | 20 | ||
20 | #include <sys/param.h> | 21 | #include <sys/param.h> |
21 | 22 | ||
23 | static char *default_tmpdir = "/tmp"; | ||
22 | static char *tempdir = NULL; | 24 | static char *tempdir = NULL; |
23 | 25 | ||
24 | static void __init find_tempdir(void) | 26 | static void __init find_tempdir(void) |
@@ -34,7 +36,7 @@ static void __init find_tempdir(void) | |||
34 | break; | 36 | break; |
35 | } | 37 | } |
36 | if((dir == NULL) || (*dir == '\0')) | 38 | if((dir == NULL) || (*dir == '\0')) |
37 | dir = "/tmp"; | 39 | dir = default_tmpdir; |
38 | 40 | ||
39 | tempdir = malloc(strlen(dir) + 2); | 41 | tempdir = malloc(strlen(dir) + 2); |
40 | if(tempdir == NULL){ | 42 | if(tempdir == NULL){ |
@@ -46,6 +48,96 @@ static void __init find_tempdir(void) | |||
46 | strcat(tempdir, "/"); | 48 | strcat(tempdir, "/"); |
47 | } | 49 | } |
48 | 50 | ||
51 | /* This will return 1, with the first character in buf being the | ||
52 | * character following the next instance of c in the file. This will | ||
53 | * read the file as needed. If there's an error, -errno is returned; | ||
54 | * if the end of the file is reached, 0 is returned. | ||
55 | */ | ||
56 | static int next(int fd, char *buf, int size, char c) | ||
57 | { | ||
58 | int n; | ||
59 | char *ptr; | ||
60 | |||
61 | while((ptr = strchr(buf, c)) == NULL){ | ||
62 | n = read(fd, buf, size - 1); | ||
63 | if(n == 0) | ||
64 | return 0; | ||
65 | else if(n < 0) | ||
66 | return -errno; | ||
67 | |||
68 | buf[n] = '\0'; | ||
69 | } | ||
70 | |||
71 | ptr++; | ||
72 | memmove(buf, ptr, strlen(ptr) + 1); | ||
73 | return 1; | ||
74 | } | ||
75 | |||
76 | static int checked_tmpdir = 0; | ||
77 | |||
78 | /* Look for a tmpfs mounted at /dev/shm. I couldn't find a cleaner | ||
79 | * way to do this than to parse /proc/mounts. statfs will return the | ||
80 | * same filesystem magic number and fs id for both /dev and /dev/shm | ||
81 | * when they are both tmpfs, so you can't tell if they are different | ||
82 | * filesystems. Also, there seems to be no other way of finding the | ||
83 | * mount point of a filesystem from within it. | ||
84 | * | ||
85 | * If a /dev/shm tmpfs entry is found, then we switch to using it. | ||
86 | * Otherwise, we stay with the default /tmp. | ||
87 | */ | ||
88 | static void which_tmpdir(void) | ||
89 | { | ||
90 | int fd, found; | ||
91 | char buf[128] = { '\0' }; | ||
92 | |||
93 | if(checked_tmpdir) | ||
94 | return; | ||
95 | |||
96 | checked_tmpdir = 1; | ||
97 | |||
98 | printf("Checking for tmpfs mount on /dev/shm..."); | ||
99 | |||
100 | fd = open("/proc/mounts", O_RDONLY); | ||
101 | if(fd < 0){ | ||
102 | printf("failed to open /proc/mounts, errno = %d\n", errno); | ||
103 | return; | ||
104 | } | ||
105 | |||
106 | while(1){ | ||
107 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); | ||
108 | if(found != 1) | ||
109 | break; | ||
110 | |||
111 | if(!strncmp(buf, "/dev/shm", strlen("/dev/shm"))) | ||
112 | goto found; | ||
113 | |||
114 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), '\n'); | ||
115 | if(found != 1) | ||
116 | break; | ||
117 | } | ||
118 | |||
119 | err: | ||
120 | if(found == 0) | ||
121 | printf("nothing mounted on /dev/shm\n"); | ||
122 | else if(found < 0) | ||
123 | printf("read returned errno %d\n", -found); | ||
124 | |||
125 | return; | ||
126 | |||
127 | found: | ||
128 | found = next(fd, buf, sizeof(buf) / sizeof(buf[0]), ' '); | ||
129 | if(found != 1) | ||
130 | goto err; | ||
131 | |||
132 | if(strncmp(buf, "tmpfs", strlen("tmpfs"))){ | ||
133 | printf("not tmpfs\n"); | ||
134 | return; | ||
135 | } | ||
136 | |||
137 | printf("OK\n"); | ||
138 | default_tmpdir = "/dev/shm"; | ||
139 | } | ||
140 | |||
49 | /* | 141 | /* |
50 | * This proc still used in tt-mode | 142 | * This proc still used in tt-mode |
51 | * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). | 143 | * (file: kernel/tt/ptproxy/proxy.c, proc: start_debugger). |
@@ -56,6 +148,7 @@ int make_tempfile(const char *template, char **out_tempname, int do_unlink) | |||
56 | char *tempname; | 148 | char *tempname; |
57 | int fd; | 149 | int fd; |
58 | 150 | ||
151 | which_tmpdir(); | ||
59 | tempname = malloc(MAXPATHLEN); | 152 | tempname = malloc(MAXPATHLEN); |
60 | 153 | ||
61 | find_tempdir(); | 154 | find_tempdir(); |
@@ -137,3 +230,26 @@ int create_mem_file(unsigned long long len) | |||
137 | } | 230 | } |
138 | return(fd); | 231 | return(fd); |
139 | } | 232 | } |
233 | |||
234 | |||
235 | void check_tmpexec(void) | ||
236 | { | ||
237 | void *addr; | ||
238 | int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); | ||
239 | |||
240 | addr = mmap(NULL, UM_KERN_PAGE_SIZE, | ||
241 | PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); | ||
242 | printf("Checking PROT_EXEC mmap in %s...",tempdir); | ||
243 | fflush(stdout); | ||
244 | if(addr == MAP_FAILED){ | ||
245 | err = errno; | ||
246 | perror("failed"); | ||
247 | if(err == EPERM) | ||
248 | printf("%s must be not mounted noexec\n",tempdir); | ||
249 | exit(1); | ||
250 | } | ||
251 | printf("OK\n"); | ||
252 | munmap(addr, UM_KERN_PAGE_SIZE); | ||
253 | |||
254 | close(fd); | ||
255 | } | ||
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c index 8176b0b52047..3505f44f8a25 100644 --- a/arch/um/os-Linux/process.c +++ b/arch/um/os-Linux/process.c | |||
@@ -190,7 +190,7 @@ int os_unmap_memory(void *addr, int len) | |||
190 | } | 190 | } |
191 | 191 | ||
192 | #ifndef MADV_REMOVE | 192 | #ifndef MADV_REMOVE |
193 | #define MADV_REMOVE 0x5 /* remove these pages & resources */ | 193 | #define MADV_REMOVE KERNEL_MADV_REMOVE |
194 | #endif | 194 | #endif |
195 | 195 | ||
196 | int os_drop_memory(void *addr, int length) | 196 | int os_drop_memory(void *addr, int length) |
@@ -216,7 +216,7 @@ int can_drop_memory(void) | |||
216 | } | 216 | } |
217 | 217 | ||
218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, | 218 | addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, |
219 | MAP_PRIVATE, fd, 0); | 219 | MAP_SHARED, fd, 0); |
220 | if(addr == MAP_FAILED){ | 220 | if(addr == MAP_FAILED){ |
221 | printk("Mapping test memory file failed, err = %d\n", -errno); | 221 | printk("Mapping test memory file failed, err = %d\n", -errno); |
222 | return 0; | 222 | return 0; |
@@ -266,11 +266,11 @@ void init_new_thread_signals(int altstack) | |||
266 | 266 | ||
267 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) | 267 | int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) |
268 | { | 268 | { |
269 | sigjmp_buf buf; | 269 | jmp_buf buf; |
270 | int n, enable; | 270 | int n, enable; |
271 | 271 | ||
272 | *jmp_ptr = &buf; | 272 | *jmp_ptr = &buf; |
273 | n = UML_SIGSETJMP(&buf, enable); | 273 | n = UML_SETJMP(&buf, enable); |
274 | if(n != 0) | 274 | if(n != 0) |
275 | return(n); | 275 | return(n); |
276 | (*fn)(arg); | 276 | (*fn)(arg); |
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index 045ae0037456..0776bc18ca85 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c | |||
@@ -434,7 +434,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
434 | void (*handler)(int)) | 434 | void (*handler)(int)) |
435 | { | 435 | { |
436 | unsigned long flags; | 436 | unsigned long flags; |
437 | sigjmp_buf switch_buf, fork_buf; | 437 | jmp_buf switch_buf, fork_buf; |
438 | int enable; | 438 | int enable; |
439 | 439 | ||
440 | *switch_buf_ptr = &switch_buf; | 440 | *switch_buf_ptr = &switch_buf; |
@@ -450,7 +450,7 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
450 | */ | 450 | */ |
451 | flags = get_signals(); | 451 | flags = get_signals(); |
452 | block_signals(); | 452 | block_signals(); |
453 | if(UML_SIGSETJMP(&fork_buf, enable) == 0) | 453 | if(UML_SETJMP(&fork_buf, enable) == 0) |
454 | new_thread_proc(stack, handler); | 454 | new_thread_proc(stack, handler); |
455 | 455 | ||
456 | remove_sigstack(); | 456 | remove_sigstack(); |
@@ -466,35 +466,35 @@ void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, | |||
466 | 466 | ||
467 | void thread_wait(void *sw, void *fb) | 467 | void thread_wait(void *sw, void *fb) |
468 | { | 468 | { |
469 | sigjmp_buf buf, **switch_buf = sw, *fork_buf; | 469 | jmp_buf buf, **switch_buf = sw, *fork_buf; |
470 | int enable; | 470 | int enable; |
471 | 471 | ||
472 | *switch_buf = &buf; | 472 | *switch_buf = &buf; |
473 | fork_buf = fb; | 473 | fork_buf = fb; |
474 | if(UML_SIGSETJMP(&buf, enable) == 0) | 474 | if(UML_SETJMP(&buf, enable) == 0) |
475 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); | 475 | siglongjmp(*fork_buf, INIT_JMP_REMOVE_SIGSTACK); |
476 | } | 476 | } |
477 | 477 | ||
478 | void switch_threads(void *me, void *next) | 478 | void switch_threads(void *me, void *next) |
479 | { | 479 | { |
480 | sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; | 480 | jmp_buf my_buf, **me_ptr = me, *next_buf = next; |
481 | int enable; | 481 | int enable; |
482 | 482 | ||
483 | *me_ptr = &my_buf; | 483 | *me_ptr = &my_buf; |
484 | if(UML_SIGSETJMP(&my_buf, enable) == 0) | 484 | if(UML_SETJMP(&my_buf, enable) == 0) |
485 | UML_SIGLONGJMP(next_buf, 1); | 485 | UML_LONGJMP(next_buf, 1); |
486 | } | 486 | } |
487 | 487 | ||
488 | static sigjmp_buf initial_jmpbuf; | 488 | static jmp_buf initial_jmpbuf; |
489 | 489 | ||
490 | /* XXX Make these percpu */ | 490 | /* XXX Make these percpu */ |
491 | static void (*cb_proc)(void *arg); | 491 | static void (*cb_proc)(void *arg); |
492 | static void *cb_arg; | 492 | static void *cb_arg; |
493 | static sigjmp_buf *cb_back; | 493 | static jmp_buf *cb_back; |
494 | 494 | ||
495 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | 495 | int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) |
496 | { | 496 | { |
497 | sigjmp_buf **switch_buf = switch_buf_ptr; | 497 | jmp_buf **switch_buf = switch_buf_ptr; |
498 | int n, enable; | 498 | int n, enable; |
499 | 499 | ||
500 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, | 500 | set_handler(SIGWINCH, (__sighandler_t) sig_handler, |
@@ -502,7 +502,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
502 | SIGVTALRM, -1); | 502 | SIGVTALRM, -1); |
503 | 503 | ||
504 | *fork_buf_ptr = &initial_jmpbuf; | 504 | *fork_buf_ptr = &initial_jmpbuf; |
505 | n = UML_SIGSETJMP(&initial_jmpbuf, enable); | 505 | n = UML_SETJMP(&initial_jmpbuf, enable); |
506 | switch(n){ | 506 | switch(n){ |
507 | case INIT_JMP_NEW_THREAD: | 507 | case INIT_JMP_NEW_THREAD: |
508 | new_thread_proc((void *) stack, new_thread_handler); | 508 | new_thread_proc((void *) stack, new_thread_handler); |
@@ -512,7 +512,7 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
512 | break; | 512 | break; |
513 | case INIT_JMP_CALLBACK: | 513 | case INIT_JMP_CALLBACK: |
514 | (*cb_proc)(cb_arg); | 514 | (*cb_proc)(cb_arg); |
515 | UML_SIGLONGJMP(cb_back, 1); | 515 | UML_LONGJMP(cb_back, 1); |
516 | break; | 516 | break; |
517 | case INIT_JMP_HALT: | 517 | case INIT_JMP_HALT: |
518 | kmalloc_ok = 0; | 518 | kmalloc_ok = 0; |
@@ -523,12 +523,12 @@ int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) | |||
523 | default: | 523 | default: |
524 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); | 524 | panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); |
525 | } | 525 | } |
526 | UML_SIGLONGJMP(*switch_buf, 1); | 526 | UML_LONGJMP(*switch_buf, 1); |
527 | } | 527 | } |
528 | 528 | ||
529 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) | 529 | void initial_thread_cb_skas(void (*proc)(void *), void *arg) |
530 | { | 530 | { |
531 | sigjmp_buf here; | 531 | jmp_buf here; |
532 | int enable; | 532 | int enable; |
533 | 533 | ||
534 | cb_proc = proc; | 534 | cb_proc = proc; |
@@ -536,8 +536,8 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
536 | cb_back = &here; | 536 | cb_back = &here; |
537 | 537 | ||
538 | block_signals(); | 538 | block_signals(); |
539 | if(UML_SIGSETJMP(&here, enable) == 0) | 539 | if(UML_SETJMP(&here, enable) == 0) |
540 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); | 540 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); |
541 | unblock_signals(); | 541 | unblock_signals(); |
542 | 542 | ||
543 | cb_proc = NULL; | 543 | cb_proc = NULL; |
@@ -548,13 +548,13 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg) | |||
548 | void halt_skas(void) | 548 | void halt_skas(void) |
549 | { | 549 | { |
550 | block_signals(); | 550 | block_signals(); |
551 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_HALT); | 551 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_HALT); |
552 | } | 552 | } |
553 | 553 | ||
554 | void reboot_skas(void) | 554 | void reboot_skas(void) |
555 | { | 555 | { |
556 | block_signals(); | 556 | block_signals(); |
557 | UML_SIGLONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); | 557 | UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); |
558 | } | 558 | } |
559 | 559 | ||
560 | void switch_mm_skas(struct mm_id *mm_idp) | 560 | void switch_mm_skas(struct mm_id *mm_idp) |
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c index 387e26af301a..503148504009 100644 --- a/arch/um/os-Linux/start_up.c +++ b/arch/um/os-Linux/start_up.c | |||
@@ -296,29 +296,7 @@ static void __init check_ptrace(void) | |||
296 | check_sysemu(); | 296 | check_sysemu(); |
297 | } | 297 | } |
298 | 298 | ||
299 | extern int create_tmp_file(unsigned long long len); | 299 | extern void check_tmpexec(void); |
300 | |||
301 | static void check_tmpexec(void) | ||
302 | { | ||
303 | void *addr; | ||
304 | int err, fd = create_tmp_file(UM_KERN_PAGE_SIZE); | ||
305 | |||
306 | addr = mmap(NULL, UM_KERN_PAGE_SIZE, | ||
307 | PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE, fd, 0); | ||
308 | printf("Checking PROT_EXEC mmap in /tmp..."); | ||
309 | fflush(stdout); | ||
310 | if(addr == MAP_FAILED){ | ||
311 | err = errno; | ||
312 | perror("failed"); | ||
313 | if(err == EPERM) | ||
314 | printf("/tmp must be not mounted noexec\n"); | ||
315 | exit(1); | ||
316 | } | ||
317 | printf("OK\n"); | ||
318 | munmap(addr, UM_KERN_PAGE_SIZE); | ||
319 | |||
320 | close(fd); | ||
321 | } | ||
322 | 300 | ||
323 | void os_early_checks(void) | 301 | void os_early_checks(void) |
324 | { | 302 | { |
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c index a9f6b26f9828..90b29ae9af46 100644 --- a/arch/um/os-Linux/trap.c +++ b/arch/um/os-Linux/trap.c | |||
@@ -35,7 +35,7 @@ void os_fill_handlinfo(struct kern_handlers h) | |||
35 | 35 | ||
36 | void do_longjmp(void *b, int val) | 36 | void do_longjmp(void *b, int val) |
37 | { | 37 | { |
38 | sigjmp_buf *buf = b; | 38 | jmp_buf *buf = b; |
39 | 39 | ||
40 | UML_SIGLONGJMP(buf, val); | 40 | UML_LONGJMP(buf, val); |
41 | } | 41 | } |
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c index 166fb66995df..e523719330b2 100644 --- a/arch/um/os-Linux/uaccess.c +++ b/arch/um/os-Linux/uaccess.c | |||
@@ -16,9 +16,9 @@ unsigned long __do_user_copy(void *to, const void *from, int n, | |||
16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; | 16 | unsigned long *faddrp = (unsigned long *) fault_addr, ret; |
17 | int enable; | 17 | int enable; |
18 | 18 | ||
19 | sigjmp_buf jbuf; | 19 | jmp_buf jbuf; |
20 | *fault_catcher = &jbuf; | 20 | *fault_catcher = &jbuf; |
21 | if(UML_SIGSETJMP(&jbuf, enable) == 0){ | 21 | if(UML_SETJMP(&jbuf, enable) == 0){ |
22 | (*op)(to, from, n); | 22 | (*op)(to, from, n); |
23 | ret = 0; | 23 | ret = 0; |
24 | *faulted_out = 0; | 24 | *faulted_out = 0; |
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c index e32065e2fdc8..c47a2a7ce70e 100644 --- a/arch/um/os-Linux/util.c +++ b/arch/um/os-Linux/util.c | |||
@@ -104,7 +104,7 @@ void setup_hostinfo(void) | |||
104 | int setjmp_wrapper(void (*proc)(void *, void *), ...) | 104 | int setjmp_wrapper(void (*proc)(void *, void *), ...) |
105 | { | 105 | { |
106 | va_list args; | 106 | va_list args; |
107 | sigjmp_buf buf; | 107 | jmp_buf buf; |
108 | int n; | 108 | int n; |
109 | 109 | ||
110 | n = sigsetjmp(buf, 1); | 110 | n = sigsetjmp(buf, 1); |
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c index 618fd8594643..0709fc6670c2 100644 --- a/arch/um/sys-i386/signal.c +++ b/arch/um/sys-i386/signal.c | |||
@@ -57,7 +57,7 @@ static int copy_sc_from_user_skas(struct pt_regs *regs, | |||
57 | return(0); | 57 | return(0); |
58 | } | 58 | } |
59 | 59 | ||
60 | int copy_sc_to_user_skas(struct sigcontext *to, struct _fpstate __user *to_fp, | 60 | int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp, |
61 | struct pt_regs *regs, unsigned long sp) | 61 | struct pt_regs *regs, unsigned long sp) |
62 | { | 62 | { |
63 | struct sigcontext sc; | 63 | struct sigcontext sc; |
@@ -132,7 +132,7 @@ int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, | |||
132 | return(err); | 132 | return(err); |
133 | } | 133 | } |
134 | 134 | ||
135 | int copy_sc_to_user_tt(struct sigcontext *to, struct _fpstate __user *fp, | 135 | int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, |
136 | struct sigcontext *from, int fpsize, unsigned long sp) | 136 | struct sigcontext *from, int fpsize, unsigned long sp) |
137 | { | 137 | { |
138 | struct _fpstate __user *to_fp; | 138 | struct _fpstate __user *to_fp; |
@@ -167,7 +167,7 @@ static int copy_sc_from_user(struct pt_regs *to, void __user *from) | |||
167 | return(ret); | 167 | return(ret); |
168 | } | 168 | } |
169 | 169 | ||
170 | static int copy_sc_to_user(struct sigcontext *to, struct _fpstate __user *fp, | 170 | static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp, |
171 | struct pt_regs *from, unsigned long sp) | 171 | struct pt_regs *from, unsigned long sp) |
172 | { | 172 | { |
173 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), | 173 | return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), |
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c index a37f672ec964..2355dc19c46c 100644 --- a/arch/um/sys-i386/stub_segv.c +++ b/arch/um/sys-i386/stub_segv.c | |||
@@ -27,6 +27,6 @@ stub_segv_handler(int sig) | |||
27 | * the stack in its original form when we do the sigreturn here, by | 27 | * the stack in its original form when we do the sigreturn here, by |
28 | * hand. | 28 | * hand. |
29 | */ | 29 | */ |
30 | __asm__("mov %0,%%esp ; movl %1, %%eax ; " | 30 | __asm__ __volatile__("mov %0,%%esp ; movl %1, %%eax ; " |
31 | "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); | 31 | "int $0x80" : : "a" (sc), "g" (__NR_sigreturn)); |
32 | } | 32 | } |
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c index a27099533198..1c967026c957 100644 --- a/arch/um/sys-x86_64/stub_segv.c +++ b/arch/um/sys-x86_64/stub_segv.c | |||
@@ -33,7 +33,7 @@ stub_segv_handler(int sig) | |||
33 | struct ucontext *uc; | 33 | struct ucontext *uc; |
34 | int pid; | 34 | int pid; |
35 | 35 | ||
36 | __asm__("movq %%rdx, %0" : "=g" (uc) :); | 36 | __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); |
37 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), | 37 | GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), |
38 | &uc->uc_mcontext); | 38 | &uc->uc_mcontext); |
39 | 39 | ||
@@ -44,8 +44,8 @@ stub_segv_handler(int sig) | |||
44 | * the signal frame. So, we use the ucontext pointer, which we know | 44 | * the signal frame. So, we use the ucontext pointer, which we know |
45 | * already, to get the signal frame pointer, and add 8 to that. | 45 | * already, to get the signal frame pointer, and add 8 to that. |
46 | */ | 46 | */ |
47 | __asm__("movq %0, %%rsp; movq %1, %%rax ; syscall": : | 47 | __asm__ __volatile__("movq %0, %%rsp; movq %1, %%rax ; syscall": : |
48 | "g" ((unsigned long) container_of(uc, struct rt_sigframe, | 48 | "g" ((unsigned long) |
49 | uc) + 8), | 49 | container_of(uc, struct rt_sigframe, uc) + 8), |
50 | "g" (__NR_rt_sigreturn)); | 50 | "g" (__NR_rt_sigreturn)); |
51 | } | 51 | } |
diff --git a/arch/x86_64/defconfig b/arch/x86_64/defconfig index 3c45ec22b3fe..69db0c0721d1 100644 --- a/arch/x86_64/defconfig +++ b/arch/x86_64/defconfig | |||
@@ -1,7 +1,7 @@ | |||
1 | # | 1 | # |
2 | # Automatically generated make config: don't edit | 2 | # Automatically generated make config: don't edit |
3 | # Linux kernel version: 2.6.17-rc1 | 3 | # Linux kernel version: 2.6.17-rc1-git11 |
4 | # Mon Apr 3 16:11:14 2006 | 4 | # Sun Apr 16 07:22:36 2006 |
5 | # | 5 | # |
6 | CONFIG_X86_64=y | 6 | CONFIG_X86_64=y |
7 | CONFIG_64BIT=y | 7 | CONFIG_64BIT=y |
@@ -57,6 +57,7 @@ CONFIG_FUTEX=y | |||
57 | CONFIG_EPOLL=y | 57 | CONFIG_EPOLL=y |
58 | CONFIG_SHMEM=y | 58 | CONFIG_SHMEM=y |
59 | CONFIG_SLAB=y | 59 | CONFIG_SLAB=y |
60 | CONFIG_DOUBLEFAULT=y | ||
60 | # CONFIG_TINY_SHMEM is not set | 61 | # CONFIG_TINY_SHMEM is not set |
61 | CONFIG_BASE_SMALL=0 | 62 | CONFIG_BASE_SMALL=0 |
62 | # CONFIG_SLOB is not set | 63 | # CONFIG_SLOB is not set |
@@ -121,6 +122,7 @@ CONFIG_PREEMPT_VOLUNTARY=y | |||
121 | CONFIG_PREEMPT_BKL=y | 122 | CONFIG_PREEMPT_BKL=y |
122 | CONFIG_NUMA=y | 123 | CONFIG_NUMA=y |
123 | CONFIG_K8_NUMA=y | 124 | CONFIG_K8_NUMA=y |
125 | CONFIG_NODES_SHIFT=6 | ||
124 | CONFIG_X86_64_ACPI_NUMA=y | 126 | CONFIG_X86_64_ACPI_NUMA=y |
125 | CONFIG_NUMA_EMU=y | 127 | CONFIG_NUMA_EMU=y |
126 | CONFIG_ARCH_DISCONTIGMEM_ENABLE=y | 128 | CONFIG_ARCH_DISCONTIGMEM_ENABLE=y |
@@ -544,7 +546,6 @@ CONFIG_SCSI_SATA_INTEL_COMBINED=y | |||
544 | # CONFIG_SCSI_INIA100 is not set | 546 | # CONFIG_SCSI_INIA100 is not set |
545 | # CONFIG_SCSI_SYM53C8XX_2 is not set | 547 | # CONFIG_SCSI_SYM53C8XX_2 is not set |
546 | # CONFIG_SCSI_IPR is not set | 548 | # CONFIG_SCSI_IPR is not set |
547 | # CONFIG_SCSI_QLOGIC_FC is not set | ||
548 | # CONFIG_SCSI_QLOGIC_1280 is not set | 549 | # CONFIG_SCSI_QLOGIC_1280 is not set |
549 | # CONFIG_SCSI_QLA_FC is not set | 550 | # CONFIG_SCSI_QLA_FC is not set |
550 | # CONFIG_SCSI_LPFC is not set | 551 | # CONFIG_SCSI_LPFC is not set |
@@ -1045,9 +1046,7 @@ CONFIG_USB_HIDINPUT=y | |||
1045 | # CONFIG_USB_ACECAD is not set | 1046 | # CONFIG_USB_ACECAD is not set |
1046 | # CONFIG_USB_KBTAB is not set | 1047 | # CONFIG_USB_KBTAB is not set |
1047 | # CONFIG_USB_POWERMATE is not set | 1048 | # CONFIG_USB_POWERMATE is not set |
1048 | # CONFIG_USB_MTOUCH is not set | 1049 | # CONFIG_USB_TOUCHSCREEN is not set |
1049 | # CONFIG_USB_ITMTOUCH is not set | ||
1050 | # CONFIG_USB_EGALAX is not set | ||
1051 | # CONFIG_USB_YEALINK is not set | 1050 | # CONFIG_USB_YEALINK is not set |
1052 | # CONFIG_USB_XPAD is not set | 1051 | # CONFIG_USB_XPAD is not set |
1053 | # CONFIG_USB_ATI_REMOTE is not set | 1052 | # CONFIG_USB_ATI_REMOTE is not set |
@@ -1118,6 +1117,14 @@ CONFIG_USB_MON=y | |||
1118 | # CONFIG_NEW_LEDS is not set | 1117 | # CONFIG_NEW_LEDS is not set |
1119 | 1118 | ||
1120 | # | 1119 | # |
1120 | # LED drivers | ||
1121 | # | ||
1122 | |||
1123 | # | ||
1124 | # LED Triggers | ||
1125 | # | ||
1126 | |||
1127 | # | ||
1121 | # InfiniBand support | 1128 | # InfiniBand support |
1122 | # | 1129 | # |
1123 | # CONFIG_INFINIBAND is not set | 1130 | # CONFIG_INFINIBAND is not set |
diff --git a/arch/x86_64/ia32/Makefile b/arch/x86_64/ia32/Makefile index 929e6b0771f8..e9263b4975e0 100644 --- a/arch/x86_64/ia32/Makefile +++ b/arch/x86_64/ia32/Makefile | |||
@@ -27,5 +27,5 @@ $(obj)/vsyscall-sysenter.so $(obj)/vsyscall-syscall.so: \ | |||
27 | $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE | 27 | $(obj)/vsyscall-%.so: $(src)/vsyscall.lds $(obj)/vsyscall-%.o FORCE |
28 | $(call if_changed,syscall) | 28 | $(call if_changed,syscall) |
29 | 29 | ||
30 | AFLAGS_vsyscall-sysenter.o = -m32 | 30 | AFLAGS_vsyscall-sysenter.o = -m32 -Wa,-32 |
31 | AFLAGS_vsyscall-syscall.o = -m32 | 31 | AFLAGS_vsyscall-syscall.o = -m32 -Wa,-32 |
diff --git a/arch/x86_64/ia32/ia32entry.S b/arch/x86_64/ia32/ia32entry.S index 5a9802676689..57fc37e0fb9c 100644 --- a/arch/x86_64/ia32/ia32entry.S +++ b/arch/x86_64/ia32/ia32entry.S | |||
@@ -694,4 +694,5 @@ ia32_sys_call_table: | |||
694 | .quad compat_sys_get_robust_list | 694 | .quad compat_sys_get_robust_list |
695 | .quad sys_splice | 695 | .quad sys_splice |
696 | .quad sys_sync_file_range | 696 | .quad sys_sync_file_range |
697 | .quad sys_tee | ||
697 | ia32_syscall_end: | 698 | ia32_syscall_end: |
diff --git a/arch/x86_64/kernel/kprobes.c b/arch/x86_64/kernel/kprobes.c index accbff3fec49..1eaa5dae6174 100644 --- a/arch/x86_64/kernel/kprobes.c +++ b/arch/x86_64/kernel/kprobes.c | |||
@@ -53,7 +53,7 @@ DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); | |||
53 | /* | 53 | /* |
54 | * returns non-zero if opcode modifies the interrupt flag. | 54 | * returns non-zero if opcode modifies the interrupt flag. |
55 | */ | 55 | */ |
56 | static inline int is_IF_modifier(kprobe_opcode_t *insn) | 56 | static __always_inline int is_IF_modifier(kprobe_opcode_t *insn) |
57 | { | 57 | { |
58 | switch (*insn) { | 58 | switch (*insn) { |
59 | case 0xfa: /* cli */ | 59 | case 0xfa: /* cli */ |
@@ -84,7 +84,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p) | |||
84 | * If it does, return the address of the 32-bit displacement word. | 84 | * If it does, return the address of the 32-bit displacement word. |
85 | * If not, return null. | 85 | * If not, return null. |
86 | */ | 86 | */ |
87 | static inline s32 *is_riprel(u8 *insn) | 87 | static s32 __kprobes *is_riprel(u8 *insn) |
88 | { | 88 | { |
89 | #define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \ | 89 | #define W(row,b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,ba,bb,bc,bd,be,bf) \ |
90 | (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ | 90 | (((b0##UL << 0x0)|(b1##UL << 0x1)|(b2##UL << 0x2)|(b3##UL << 0x3) | \ |
@@ -229,7 +229,7 @@ void __kprobes arch_remove_kprobe(struct kprobe *p) | |||
229 | mutex_unlock(&kprobe_mutex); | 229 | mutex_unlock(&kprobe_mutex); |
230 | } | 230 | } |
231 | 231 | ||
232 | static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | 232 | static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) |
233 | { | 233 | { |
234 | kcb->prev_kprobe.kp = kprobe_running(); | 234 | kcb->prev_kprobe.kp = kprobe_running(); |
235 | kcb->prev_kprobe.status = kcb->kprobe_status; | 235 | kcb->prev_kprobe.status = kcb->kprobe_status; |
@@ -237,7 +237,7 @@ static inline void save_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
237 | kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags; | 237 | kcb->prev_kprobe.saved_rflags = kcb->kprobe_saved_rflags; |
238 | } | 238 | } |
239 | 239 | ||
240 | static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | 240 | static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) |
241 | { | 241 | { |
242 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; | 242 | __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; |
243 | kcb->kprobe_status = kcb->prev_kprobe.status; | 243 | kcb->kprobe_status = kcb->prev_kprobe.status; |
@@ -245,7 +245,7 @@ static inline void restore_previous_kprobe(struct kprobe_ctlblk *kcb) | |||
245 | kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags; | 245 | kcb->kprobe_saved_rflags = kcb->prev_kprobe.saved_rflags; |
246 | } | 246 | } |
247 | 247 | ||
248 | static inline void set_current_kprobe(struct kprobe *p, struct pt_regs *regs, | 248 | static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, |
249 | struct kprobe_ctlblk *kcb) | 249 | struct kprobe_ctlblk *kcb) |
250 | { | 250 | { |
251 | __get_cpu_var(current_kprobe) = p; | 251 | __get_cpu_var(current_kprobe) = p; |
diff --git a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c index 6f0790e8b6d3..c69fc43cee7b 100644 --- a/arch/x86_64/kernel/mce.c +++ b/arch/x86_64/kernel/mce.c | |||
@@ -629,7 +629,7 @@ static __cpuinit void mce_remove_device(unsigned int cpu) | |||
629 | #endif | 629 | #endif |
630 | 630 | ||
631 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ | 631 | /* Get notified when a cpu comes on/off. Be hotplug friendly. */ |
632 | static __cpuinit int | 632 | static int |
633 | mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 633 | mce_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
634 | { | 634 | { |
635 | unsigned int cpu = (unsigned long)hcpu; | 635 | unsigned int cpu = (unsigned long)hcpu; |
diff --git a/arch/x86_64/kernel/mce_amd.c b/arch/x86_64/kernel/mce_amd.c index d3ad7d81266d..d13b241ad094 100644 --- a/arch/x86_64/kernel/mce_amd.c +++ b/arch/x86_64/kernel/mce_amd.c | |||
@@ -482,7 +482,7 @@ static void threshold_remove_device(unsigned int cpu) | |||
482 | #endif | 482 | #endif |
483 | 483 | ||
484 | /* get notified when a cpu comes on/off */ | 484 | /* get notified when a cpu comes on/off */ |
485 | static __cpuinit int threshold_cpu_callback(struct notifier_block *nfb, | 485 | static int threshold_cpu_callback(struct notifier_block *nfb, |
486 | unsigned long action, void *hcpu) | 486 | unsigned long action, void *hcpu) |
487 | { | 487 | { |
488 | /* cpu was unsigned int to begin with */ | 488 | /* cpu was unsigned int to begin with */ |
diff --git a/arch/x86_64/kernel/pci-gart.c b/arch/x86_64/kernel/pci-gart.c index a6c01e121266..9d3d76c85ae7 100644 --- a/arch/x86_64/kernel/pci-gart.c +++ b/arch/x86_64/kernel/pci-gart.c | |||
@@ -112,10 +112,6 @@ static unsigned long alloc_iommu(int size) | |||
112 | static void free_iommu(unsigned long offset, int size) | 112 | static void free_iommu(unsigned long offset, int size) |
113 | { | 113 | { |
114 | unsigned long flags; | 114 | unsigned long flags; |
115 | if (size == 1) { | ||
116 | clear_bit(offset, iommu_gart_bitmap); | ||
117 | return; | ||
118 | } | ||
119 | spin_lock_irqsave(&iommu_bitmap_lock, flags); | 115 | spin_lock_irqsave(&iommu_bitmap_lock, flags); |
120 | __clear_bit_string(iommu_gart_bitmap, offset, size); | 116 | __clear_bit_string(iommu_gart_bitmap, offset, size); |
121 | spin_unlock_irqrestore(&iommu_bitmap_lock, flags); | 117 | spin_unlock_irqrestore(&iommu_bitmap_lock, flags); |
diff --git a/arch/x86_64/kernel/process.c b/arch/x86_64/kernel/process.c index 1c44b53cb15b..fb903e65e079 100644 --- a/arch/x86_64/kernel/process.c +++ b/arch/x86_64/kernel/process.c | |||
@@ -575,8 +575,10 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p) | |||
575 | prev->userrsp = read_pda(oldrsp); | 575 | prev->userrsp = read_pda(oldrsp); |
576 | write_pda(oldrsp, next->userrsp); | 576 | write_pda(oldrsp, next->userrsp); |
577 | write_pda(pcurrent, next_p); | 577 | write_pda(pcurrent, next_p); |
578 | |||
578 | /* This must be here to ensure both math_state_restore() and | 579 | /* This must be here to ensure both math_state_restore() and |
579 | kernel_fpu_begin() work consistently. */ | 580 | kernel_fpu_begin() work consistently. |
581 | And the AMD workaround requires it to be after DS reload. */ | ||
580 | unlazy_fpu(prev_p); | 582 | unlazy_fpu(prev_p); |
581 | write_pda(kernelstack, | 583 | write_pda(kernelstack, |
582 | task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); | 584 | task_stack_page(next_p) + THREAD_SIZE - PDA_STACKOFFSET); |
diff --git a/arch/x86_64/kernel/setup.c b/arch/x86_64/kernel/setup.c index c50b06765a80..759070c82751 100644 --- a/arch/x86_64/kernel/setup.c +++ b/arch/x86_64/kernel/setup.c | |||
@@ -930,6 +930,10 @@ static int __init init_amd(struct cpuinfo_x86 *c) | |||
930 | if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) | 930 | if (c->x86 == 15 && ((level >= 0x0f48 && level < 0x0f50) || level >= 0x0f58)) |
931 | set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); | 931 | set_bit(X86_FEATURE_REP_GOOD, &c->x86_capability); |
932 | 932 | ||
933 | /* Enable workaround for FXSAVE leak */ | ||
934 | if (c->x86 >= 6) | ||
935 | set_bit(X86_FEATURE_FXSAVE_LEAK, &c->x86_capability); | ||
936 | |||
933 | r = get_model_name(c); | 937 | r = get_model_name(c); |
934 | if (!r) { | 938 | if (!r) { |
935 | switch (c->x86) { | 939 | switch (c->x86) { |
diff --git a/arch/x86_64/kernel/traps.c b/arch/x86_64/kernel/traps.c index 6bda322d3caf..2700b1375c1f 100644 --- a/arch/x86_64/kernel/traps.c +++ b/arch/x86_64/kernel/traps.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include <linux/moduleparam.h> | 30 | #include <linux/moduleparam.h> |
31 | #include <linux/nmi.h> | 31 | #include <linux/nmi.h> |
32 | #include <linux/kprobes.h> | 32 | #include <linux/kprobes.h> |
33 | #include <linux/kexec.h> | ||
33 | 34 | ||
34 | #include <asm/system.h> | 35 | #include <asm/system.h> |
35 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
@@ -433,6 +434,8 @@ void __kprobes __die(const char * str, struct pt_regs * regs, long err) | |||
433 | printk(KERN_ALERT "RIP "); | 434 | printk(KERN_ALERT "RIP "); |
434 | printk_address(regs->rip); | 435 | printk_address(regs->rip); |
435 | printk(" RSP <%016lx>\n", regs->rsp); | 436 | printk(" RSP <%016lx>\n", regs->rsp); |
437 | if (kexec_should_crash(current)) | ||
438 | crash_kexec(regs); | ||
436 | } | 439 | } |
437 | 440 | ||
438 | void die(const char * str, struct pt_regs * regs, long err) | 441 | void die(const char * str, struct pt_regs * regs, long err) |
@@ -455,6 +458,8 @@ void __kprobes die_nmi(char *str, struct pt_regs *regs) | |||
455 | */ | 458 | */ |
456 | printk(str, safe_smp_processor_id()); | 459 | printk(str, safe_smp_processor_id()); |
457 | show_registers(regs); | 460 | show_registers(regs); |
461 | if (kexec_should_crash(current)) | ||
462 | crash_kexec(regs); | ||
458 | if (panic_on_timeout || panic_on_oops) | 463 | if (panic_on_timeout || panic_on_oops) |
459 | panic("nmi watchdog"); | 464 | panic("nmi watchdog"); |
460 | printk("console shuts up ...\n"); | 465 | printk("console shuts up ...\n"); |
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index cc02573a3271..b2fac14baac0 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -188,11 +188,13 @@ void __init setup_node_zones(int nodeid) | |||
188 | memory. */ | 188 | memory. */ |
189 | memmapsize = sizeof(struct page) * (end_pfn-start_pfn); | 189 | memmapsize = sizeof(struct page) * (end_pfn-start_pfn); |
190 | limit = end_pfn << PAGE_SHIFT; | 190 | limit = end_pfn << PAGE_SHIFT; |
191 | #ifdef CONFIG_FLAT_NODE_MEM_MAP | ||
191 | NODE_DATA(nodeid)->node_mem_map = | 192 | NODE_DATA(nodeid)->node_mem_map = |
192 | __alloc_bootmem_core(NODE_DATA(nodeid)->bdata, | 193 | __alloc_bootmem_core(NODE_DATA(nodeid)->bdata, |
193 | memmapsize, SMP_CACHE_BYTES, | 194 | memmapsize, SMP_CACHE_BYTES, |
194 | round_down(limit - memmapsize, PAGE_SIZE), | 195 | round_down(limit - memmapsize, PAGE_SIZE), |
195 | limit); | 196 | limit); |
197 | #endif | ||
196 | 198 | ||
197 | size_zones(zones, holes, start_pfn, end_pfn); | 199 | size_zones(zones, holes, start_pfn, end_pfn); |
198 | free_area_init_node(nodeid, NODE_DATA(nodeid), zones, | 200 | free_area_init_node(nodeid, NODE_DATA(nodeid), zones, |
diff --git a/block/as-iosched.c b/block/as-iosched.c index 296708ceceb2..e25a5d79ab27 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c | |||
@@ -1844,9 +1844,10 @@ static void __exit as_exit(void) | |||
1844 | DECLARE_COMPLETION(all_gone); | 1844 | DECLARE_COMPLETION(all_gone); |
1845 | elv_unregister(&iosched_as); | 1845 | elv_unregister(&iosched_as); |
1846 | ioc_gone = &all_gone; | 1846 | ioc_gone = &all_gone; |
1847 | barrier(); | 1847 | /* ioc_gone's update must be visible before reading ioc_count */ |
1848 | smp_wmb(); | ||
1848 | if (atomic_read(&ioc_count)) | 1849 | if (atomic_read(&ioc_count)) |
1849 | complete(ioc_gone); | 1850 | wait_for_completion(ioc_gone); |
1850 | synchronize_rcu(); | 1851 | synchronize_rcu(); |
1851 | kmem_cache_destroy(arq_pool); | 1852 | kmem_cache_destroy(arq_pool); |
1852 | } | 1853 | } |
diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 67d446de0227..2540dfaa3e38 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c | |||
@@ -1472,19 +1472,37 @@ out: | |||
1472 | return cfqq; | 1472 | return cfqq; |
1473 | } | 1473 | } |
1474 | 1474 | ||
1475 | static void | ||
1476 | cfq_drop_dead_cic(struct io_context *ioc, struct cfq_io_context *cic) | ||
1477 | { | ||
1478 | read_lock(&cfq_exit_lock); | ||
1479 | rb_erase(&cic->rb_node, &ioc->cic_root); | ||
1480 | read_unlock(&cfq_exit_lock); | ||
1481 | kmem_cache_free(cfq_ioc_pool, cic); | ||
1482 | atomic_dec(&ioc_count); | ||
1483 | } | ||
1484 | |||
1475 | static struct cfq_io_context * | 1485 | static struct cfq_io_context * |
1476 | cfq_cic_rb_lookup(struct cfq_data *cfqd, struct io_context *ioc) | 1486 | cfq_cic_rb_lookup(struct cfq_data *cfqd, struct io_context *ioc) |
1477 | { | 1487 | { |
1478 | struct rb_node *n = ioc->cic_root.rb_node; | 1488 | struct rb_node *n; |
1479 | struct cfq_io_context *cic; | 1489 | struct cfq_io_context *cic; |
1480 | void *key = cfqd; | 1490 | void *k, *key = cfqd; |
1481 | 1491 | ||
1492 | restart: | ||
1493 | n = ioc->cic_root.rb_node; | ||
1482 | while (n) { | 1494 | while (n) { |
1483 | cic = rb_entry(n, struct cfq_io_context, rb_node); | 1495 | cic = rb_entry(n, struct cfq_io_context, rb_node); |
1496 | /* ->key must be copied to avoid race with cfq_exit_queue() */ | ||
1497 | k = cic->key; | ||
1498 | if (unlikely(!k)) { | ||
1499 | cfq_drop_dead_cic(ioc, cic); | ||
1500 | goto restart; | ||
1501 | } | ||
1484 | 1502 | ||
1485 | if (key < cic->key) | 1503 | if (key < k) |
1486 | n = n->rb_left; | 1504 | n = n->rb_left; |
1487 | else if (key > cic->key) | 1505 | else if (key > k) |
1488 | n = n->rb_right; | 1506 | n = n->rb_right; |
1489 | else | 1507 | else |
1490 | return cic; | 1508 | return cic; |
@@ -1497,29 +1515,37 @@ static inline void | |||
1497 | cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, | 1515 | cfq_cic_link(struct cfq_data *cfqd, struct io_context *ioc, |
1498 | struct cfq_io_context *cic) | 1516 | struct cfq_io_context *cic) |
1499 | { | 1517 | { |
1500 | struct rb_node **p = &ioc->cic_root.rb_node; | 1518 | struct rb_node **p; |
1501 | struct rb_node *parent = NULL; | 1519 | struct rb_node *parent; |
1502 | struct cfq_io_context *__cic; | 1520 | struct cfq_io_context *__cic; |
1503 | 1521 | void *k; | |
1504 | read_lock(&cfq_exit_lock); | ||
1505 | 1522 | ||
1506 | cic->ioc = ioc; | 1523 | cic->ioc = ioc; |
1507 | cic->key = cfqd; | 1524 | cic->key = cfqd; |
1508 | 1525 | ||
1509 | ioc->set_ioprio = cfq_ioc_set_ioprio; | 1526 | ioc->set_ioprio = cfq_ioc_set_ioprio; |
1510 | 1527 | restart: | |
1528 | parent = NULL; | ||
1529 | p = &ioc->cic_root.rb_node; | ||
1511 | while (*p) { | 1530 | while (*p) { |
1512 | parent = *p; | 1531 | parent = *p; |
1513 | __cic = rb_entry(parent, struct cfq_io_context, rb_node); | 1532 | __cic = rb_entry(parent, struct cfq_io_context, rb_node); |
1533 | /* ->key must be copied to avoid race with cfq_exit_queue() */ | ||
1534 | k = __cic->key; | ||
1535 | if (unlikely(!k)) { | ||
1536 | cfq_drop_dead_cic(ioc, cic); | ||
1537 | goto restart; | ||
1538 | } | ||
1514 | 1539 | ||
1515 | if (cic->key < __cic->key) | 1540 | if (cic->key < k) |
1516 | p = &(*p)->rb_left; | 1541 | p = &(*p)->rb_left; |
1517 | else if (cic->key > __cic->key) | 1542 | else if (cic->key > k) |
1518 | p = &(*p)->rb_right; | 1543 | p = &(*p)->rb_right; |
1519 | else | 1544 | else |
1520 | BUG(); | 1545 | BUG(); |
1521 | } | 1546 | } |
1522 | 1547 | ||
1548 | read_lock(&cfq_exit_lock); | ||
1523 | rb_link_node(&cic->rb_node, parent, p); | 1549 | rb_link_node(&cic->rb_node, parent, p); |
1524 | rb_insert_color(&cic->rb_node, &ioc->cic_root); | 1550 | rb_insert_color(&cic->rb_node, &ioc->cic_root); |
1525 | list_add(&cic->queue_list, &cfqd->cic_list); | 1551 | list_add(&cic->queue_list, &cfqd->cic_list); |
@@ -2439,9 +2465,10 @@ static void __exit cfq_exit(void) | |||
2439 | DECLARE_COMPLETION(all_gone); | 2465 | DECLARE_COMPLETION(all_gone); |
2440 | elv_unregister(&iosched_cfq); | 2466 | elv_unregister(&iosched_cfq); |
2441 | ioc_gone = &all_gone; | 2467 | ioc_gone = &all_gone; |
2442 | barrier(); | 2468 | /* ioc_gone's update must be visible before reading ioc_count */ |
2469 | smp_wmb(); | ||
2443 | if (atomic_read(&ioc_count)) | 2470 | if (atomic_read(&ioc_count)) |
2444 | complete(ioc_gone); | 2471 | wait_for_completion(ioc_gone); |
2445 | synchronize_rcu(); | 2472 | synchronize_rcu(); |
2446 | cfq_slab_kill(); | 2473 | cfq_slab_kill(); |
2447 | } | 2474 | } |
diff --git a/block/elevator.c b/block/elevator.c index 0d6be03d929e..29825792cbd5 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -895,10 +895,8 @@ ssize_t elv_iosched_show(request_queue_t *q, char *name) | |||
895 | EXPORT_SYMBOL(elv_dispatch_sort); | 895 | EXPORT_SYMBOL(elv_dispatch_sort); |
896 | EXPORT_SYMBOL(elv_add_request); | 896 | EXPORT_SYMBOL(elv_add_request); |
897 | EXPORT_SYMBOL(__elv_add_request); | 897 | EXPORT_SYMBOL(__elv_add_request); |
898 | EXPORT_SYMBOL(elv_requeue_request); | ||
899 | EXPORT_SYMBOL(elv_next_request); | 898 | EXPORT_SYMBOL(elv_next_request); |
900 | EXPORT_SYMBOL(elv_dequeue_request); | 899 | EXPORT_SYMBOL(elv_dequeue_request); |
901 | EXPORT_SYMBOL(elv_queue_empty); | 900 | EXPORT_SYMBOL(elv_queue_empty); |
902 | EXPORT_SYMBOL(elv_completed_request); | ||
903 | EXPORT_SYMBOL(elevator_exit); | 901 | EXPORT_SYMBOL(elevator_exit); |
904 | EXPORT_SYMBOL(elevator_init); | 902 | EXPORT_SYMBOL(elevator_init); |
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index e112d1a5dab6..e5041a02e21f 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
@@ -1554,7 +1554,7 @@ void blk_plug_device(request_queue_t *q) | |||
1554 | * don't plug a stopped queue, it must be paired with blk_start_queue() | 1554 | * don't plug a stopped queue, it must be paired with blk_start_queue() |
1555 | * which will restart the queueing | 1555 | * which will restart the queueing |
1556 | */ | 1556 | */ |
1557 | if (test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags)) | 1557 | if (blk_queue_stopped(q)) |
1558 | return; | 1558 | return; |
1559 | 1559 | ||
1560 | if (!test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) { | 1560 | if (!test_and_set_bit(QUEUE_FLAG_PLUGGED, &q->queue_flags)) { |
@@ -1587,7 +1587,7 @@ EXPORT_SYMBOL(blk_remove_plug); | |||
1587 | */ | 1587 | */ |
1588 | void __generic_unplug_device(request_queue_t *q) | 1588 | void __generic_unplug_device(request_queue_t *q) |
1589 | { | 1589 | { |
1590 | if (unlikely(test_bit(QUEUE_FLAG_STOPPED, &q->queue_flags))) | 1590 | if (unlikely(blk_queue_stopped(q))) |
1591 | return; | 1591 | return; |
1592 | 1592 | ||
1593 | if (!blk_remove_plug(q)) | 1593 | if (!blk_remove_plug(q)) |
@@ -3385,7 +3385,7 @@ static int blk_cpu_notify(struct notifier_block *self, unsigned long action, | |||
3385 | } | 3385 | } |
3386 | 3386 | ||
3387 | 3387 | ||
3388 | static struct notifier_block __devinitdata blk_cpu_notifier = { | 3388 | static struct notifier_block blk_cpu_notifier = { |
3389 | .notifier_call = blk_cpu_notify, | 3389 | .notifier_call = blk_cpu_notify, |
3390 | }; | 3390 | }; |
3391 | 3391 | ||
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 915810f6237e..8c52421cbc54 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -107,7 +107,7 @@ static int __cpuinit topology_remove_dev(struct sys_device * sys_dev) | |||
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | 109 | ||
110 | static int __cpuinit topology_cpu_callback(struct notifier_block *nfb, | 110 | static int topology_cpu_callback(struct notifier_block *nfb, |
111 | unsigned long action, void *hcpu) | 111 | unsigned long action, void *hcpu) |
112 | { | 112 | { |
113 | unsigned int cpu = (unsigned long)hcpu; | 113 | unsigned int cpu = (unsigned long)hcpu; |
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c index 5d72f50de1ac..46d66037b917 100644 --- a/drivers/char/cs5535_gpio.c +++ b/drivers/char/cs5535_gpio.c | |||
@@ -241,9 +241,10 @@ static int __init cs5535_gpio_init(void) | |||
241 | static void __exit cs5535_gpio_cleanup(void) | 241 | static void __exit cs5535_gpio_cleanup(void) |
242 | { | 242 | { |
243 | dev_t dev_id = MKDEV(major, 0); | 243 | dev_t dev_id = MKDEV(major, 0); |
244 | |||
245 | cdev_del(&cs5535_gpio_cdev); | ||
244 | unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT); | 246 | unregister_chrdev_region(dev_id, CS5535_GPIO_COUNT); |
245 | if (gpio_base != 0) | 247 | release_region(gpio_base, CS5535_GPIO_SIZE); |
246 | release_region(gpio_base, CS5535_GPIO_SIZE); | ||
247 | } | 248 | } |
248 | 249 | ||
249 | module_init(cs5535_gpio_init); | 250 | module_init(cs5535_gpio_init); |
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h index edc72a6348a7..cb76e5ca9a23 100644 --- a/drivers/char/drm/drmP.h +++ b/drivers/char/drm/drmP.h | |||
@@ -815,8 +815,6 @@ extern int drm_mem_info(char *buf, char **start, off_t offset, | |||
815 | extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); | 815 | extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area); |
816 | extern void *drm_ioremap(unsigned long offset, unsigned long size, | 816 | extern void *drm_ioremap(unsigned long offset, unsigned long size, |
817 | drm_device_t * dev); | 817 | drm_device_t * dev); |
818 | extern void *drm_ioremap_nocache(unsigned long offset, unsigned long size, | ||
819 | drm_device_t * dev); | ||
820 | extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev); | 818 | extern void drm_ioremapfree(void *pt, unsigned long size, drm_device_t * dev); |
821 | 819 | ||
822 | extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type); | 820 | extern DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type); |
@@ -891,7 +889,6 @@ extern int drm_lock_free(drm_device_t * dev, | |||
891 | /* Buffer management support (drm_bufs.h) */ | 889 | /* Buffer management support (drm_bufs.h) */ |
892 | extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); | 890 | extern int drm_addbufs_agp(drm_device_t * dev, drm_buf_desc_t * request); |
893 | extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request); | 891 | extern int drm_addbufs_pci(drm_device_t * dev, drm_buf_desc_t * request); |
894 | extern int drm_addbufs_fb(drm_device_t *dev, drm_buf_desc_t *request); | ||
895 | extern int drm_addmap(drm_device_t * dev, unsigned int offset, | 892 | extern int drm_addmap(drm_device_t * dev, unsigned int offset, |
896 | unsigned int size, drm_map_type_t type, | 893 | unsigned int size, drm_map_type_t type, |
897 | drm_map_flags_t flags, drm_local_map_t ** map_ptr); | 894 | drm_map_flags_t flags, drm_local_map_t ** map_ptr); |
@@ -1022,11 +1019,13 @@ static __inline__ void drm_core_ioremap(struct drm_map *map, | |||
1022 | map->handle = drm_ioremap(map->offset, map->size, dev); | 1019 | map->handle = drm_ioremap(map->offset, map->size, dev); |
1023 | } | 1020 | } |
1024 | 1021 | ||
1022 | #if 0 | ||
1025 | static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, | 1023 | static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, |
1026 | struct drm_device *dev) | 1024 | struct drm_device *dev) |
1027 | { | 1025 | { |
1028 | map->handle = drm_ioremap_nocache(map->offset, map->size, dev); | 1026 | map->handle = drm_ioremap_nocache(map->offset, map->size, dev); |
1029 | } | 1027 | } |
1028 | #endif /* 0 */ | ||
1030 | 1029 | ||
1031 | static __inline__ void drm_core_ioremapfree(struct drm_map *map, | 1030 | static __inline__ void drm_core_ioremapfree(struct drm_map *map, |
1032 | struct drm_device *dev) | 1031 | struct drm_device *dev) |
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c index fabc930c67a2..40bfd9b01e39 100644 --- a/drivers/char/drm/drm_agpsupport.c +++ b/drivers/char/drm/drm_agpsupport.c | |||
@@ -503,8 +503,6 @@ int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start) | |||
503 | return agp_bind_memory(handle, start); | 503 | return agp_bind_memory(handle, start); |
504 | } | 504 | } |
505 | 505 | ||
506 | EXPORT_SYMBOL(drm_agp_bind_memory); | ||
507 | |||
508 | /** Calls agp_unbind_memory() */ | 506 | /** Calls agp_unbind_memory() */ |
509 | int drm_agp_unbind_memory(DRM_AGP_MEM * handle) | 507 | int drm_agp_unbind_memory(DRM_AGP_MEM * handle) |
510 | { | 508 | { |
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c index 8a9cf12e6183..006b06d29727 100644 --- a/drivers/char/drm/drm_bufs.c +++ b/drivers/char/drm/drm_bufs.c | |||
@@ -386,7 +386,6 @@ int drm_rmmap_locked(drm_device_t *dev, drm_local_map_t *map) | |||
386 | 386 | ||
387 | return 0; | 387 | return 0; |
388 | } | 388 | } |
389 | EXPORT_SYMBOL(drm_rmmap_locked); | ||
390 | 389 | ||
391 | int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) | 390 | int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) |
392 | { | 391 | { |
@@ -398,7 +397,6 @@ int drm_rmmap(drm_device_t *dev, drm_local_map_t *map) | |||
398 | 397 | ||
399 | return ret; | 398 | return ret; |
400 | } | 399 | } |
401 | EXPORT_SYMBOL(drm_rmmap); | ||
402 | 400 | ||
403 | /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on | 401 | /* The rmmap ioctl appears to be unnecessary. All mappings are torn down on |
404 | * the last close of the device, and this is necessary for cleanup when things | 402 | * the last close of the device, and this is necessary for cleanup when things |
@@ -1053,7 +1051,7 @@ static int drm_addbufs_sg(drm_device_t * dev, drm_buf_desc_t * request) | |||
1053 | return 0; | 1051 | return 0; |
1054 | } | 1052 | } |
1055 | 1053 | ||
1056 | int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | 1054 | static int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) |
1057 | { | 1055 | { |
1058 | drm_device_dma_t *dma = dev->dma; | 1056 | drm_device_dma_t *dma = dev->dma; |
1059 | drm_buf_entry_t *entry; | 1057 | drm_buf_entry_t *entry; |
@@ -1212,7 +1210,6 @@ int drm_addbufs_fb(drm_device_t * dev, drm_buf_desc_t * request) | |||
1212 | atomic_dec(&dev->buf_alloc); | 1210 | atomic_dec(&dev->buf_alloc); |
1213 | return 0; | 1211 | return 0; |
1214 | } | 1212 | } |
1215 | EXPORT_SYMBOL(drm_addbufs_fb); | ||
1216 | 1213 | ||
1217 | 1214 | ||
1218 | /** | 1215 | /** |
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c index dc6bbe8a18dc..3c0b882a8e72 100644 --- a/drivers/char/drm/drm_drv.c +++ b/drivers/char/drm/drm_drv.c | |||
@@ -75,8 +75,8 @@ static drm_ioctl_desc_t drm_ioctls[] = { | |||
75 | [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | 75 | [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX)] = {drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
76 | [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH}, | 76 | [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX)] = {drm_getsareactx, DRM_AUTH}, |
77 | 77 | ||
78 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | 78 | [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = {drm_addctx, DRM_AUTH|DRM_ROOT_ONLY}, |
79 | [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | 79 | [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = {drm_rmctx, DRM_AUTH|DRM_ROOT_ONLY}, |
80 | [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | 80 | [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = {drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
81 | [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH}, | 81 | [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = {drm_getctx, DRM_AUTH}, |
82 | [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, | 82 | [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = {drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY}, |
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c index dddf8de66143..7e3318e1d1c6 100644 --- a/drivers/char/drm/drm_memory.c +++ b/drivers/char/drm/drm_memory.c | |||
@@ -80,6 +80,71 @@ void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area) | |||
80 | } | 80 | } |
81 | 81 | ||
82 | #if __OS_HAS_AGP | 82 | #if __OS_HAS_AGP |
83 | /* | ||
84 | * Find the drm_map that covers the range [offset, offset+size). | ||
85 | */ | ||
86 | static drm_map_t *drm_lookup_map(unsigned long offset, | ||
87 | unsigned long size, drm_device_t * dev) | ||
88 | { | ||
89 | struct list_head *list; | ||
90 | drm_map_list_t *r_list; | ||
91 | drm_map_t *map; | ||
92 | |||
93 | list_for_each(list, &dev->maplist->head) { | ||
94 | r_list = (drm_map_list_t *) list; | ||
95 | map = r_list->map; | ||
96 | if (!map) | ||
97 | continue; | ||
98 | if (map->offset <= offset | ||
99 | && (offset + size) <= (map->offset + map->size)) | ||
100 | return map; | ||
101 | } | ||
102 | return NULL; | ||
103 | } | ||
104 | |||
105 | static void *agp_remap(unsigned long offset, unsigned long size, | ||
106 | drm_device_t * dev) | ||
107 | { | ||
108 | unsigned long *phys_addr_map, i, num_pages = | ||
109 | PAGE_ALIGN(size) / PAGE_SIZE; | ||
110 | struct drm_agp_mem *agpmem; | ||
111 | struct page **page_map; | ||
112 | void *addr; | ||
113 | |||
114 | size = PAGE_ALIGN(size); | ||
115 | |||
116 | #ifdef __alpha__ | ||
117 | offset -= dev->hose->mem_space->start; | ||
118 | #endif | ||
119 | |||
120 | for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) | ||
121 | if (agpmem->bound <= offset | ||
122 | && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= | ||
123 | (offset + size)) | ||
124 | break; | ||
125 | if (!agpmem) | ||
126 | return NULL; | ||
127 | |||
128 | /* | ||
129 | * OK, we're mapping AGP space on a chipset/platform on which memory accesses by | ||
130 | * the CPU do not get remapped by the GART. We fix this by using the kernel's | ||
131 | * page-table instead (that's probably faster anyhow...). | ||
132 | */ | ||
133 | /* note: use vmalloc() because num_pages could be large... */ | ||
134 | page_map = vmalloc(num_pages * sizeof(struct page *)); | ||
135 | if (!page_map) | ||
136 | return NULL; | ||
137 | |||
138 | phys_addr_map = | ||
139 | agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE; | ||
140 | for (i = 0; i < num_pages; ++i) | ||
141 | page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT); | ||
142 | addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP); | ||
143 | vfree(page_map); | ||
144 | |||
145 | return addr; | ||
146 | } | ||
147 | |||
83 | /** Wrapper around agp_allocate_memory() */ | 148 | /** Wrapper around agp_allocate_memory() */ |
84 | DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) | 149 | DRM_AGP_MEM *drm_alloc_agp(drm_device_t * dev, int pages, u32 type) |
85 | { | 150 | { |
@@ -103,5 +168,74 @@ int drm_unbind_agp(DRM_AGP_MEM * handle) | |||
103 | { | 168 | { |
104 | return drm_agp_unbind_memory(handle); | 169 | return drm_agp_unbind_memory(handle); |
105 | } | 170 | } |
171 | |||
172 | #else /* __OS_HAS_AGP */ | ||
173 | |||
174 | static inline drm_map_t *drm_lookup_map(unsigned long offset, | ||
175 | unsigned long size, drm_device_t * dev) | ||
176 | { | ||
177 | return NULL; | ||
178 | } | ||
179 | |||
180 | static inline void *agp_remap(unsigned long offset, unsigned long size, | ||
181 | drm_device_t * dev) | ||
182 | { | ||
183 | return NULL; | ||
184 | } | ||
185 | |||
106 | #endif /* agp */ | 186 | #endif /* agp */ |
187 | |||
188 | void *drm_ioremap(unsigned long offset, unsigned long size, | ||
189 | drm_device_t * dev) | ||
190 | { | ||
191 | if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { | ||
192 | drm_map_t *map = drm_lookup_map(offset, size, dev); | ||
193 | |||
194 | if (map && map->type == _DRM_AGP) | ||
195 | return agp_remap(offset, size, dev); | ||
196 | } | ||
197 | return ioremap(offset, size); | ||
198 | } | ||
199 | EXPORT_SYMBOL(drm_ioremap); | ||
200 | |||
201 | #if 0 | ||
202 | void *drm_ioremap_nocache(unsigned long offset, | ||
203 | unsigned long size, drm_device_t * dev) | ||
204 | { | ||
205 | if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { | ||
206 | drm_map_t *map = drm_lookup_map(offset, size, dev); | ||
207 | |||
208 | if (map && map->type == _DRM_AGP) | ||
209 | return agp_remap(offset, size, dev); | ||
210 | } | ||
211 | return ioremap_nocache(offset, size); | ||
212 | } | ||
213 | #endif /* 0 */ | ||
214 | |||
215 | void drm_ioremapfree(void *pt, unsigned long size, | ||
216 | drm_device_t * dev) | ||
217 | { | ||
218 | /* | ||
219 | * This is a bit ugly. It would be much cleaner if the DRM API would use separate | ||
220 | * routines for handling mappings in the AGP space. Hopefully this can be done in | ||
221 | * a future revision of the interface... | ||
222 | */ | ||
223 | if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture | ||
224 | && ((unsigned long)pt >= VMALLOC_START | ||
225 | && (unsigned long)pt < VMALLOC_END)) { | ||
226 | unsigned long offset; | ||
227 | drm_map_t *map; | ||
228 | |||
229 | offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK); | ||
230 | map = drm_lookup_map(offset, size, dev); | ||
231 | if (map && map->type == _DRM_AGP) { | ||
232 | vunmap(pt); | ||
233 | return; | ||
234 | } | ||
235 | } | ||
236 | |||
237 | iounmap(pt); | ||
238 | } | ||
239 | EXPORT_SYMBOL(drm_ioremapfree); | ||
240 | |||
107 | #endif /* debug_memory */ | 241 | #endif /* debug_memory */ |
diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h index 3732a61c3762..714d9aedcff5 100644 --- a/drivers/char/drm/drm_memory.h +++ b/drivers/char/drm/drm_memory.h | |||
@@ -57,71 +57,6 @@ | |||
57 | # endif | 57 | # endif |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | /* | ||
61 | * Find the drm_map that covers the range [offset, offset+size). | ||
62 | */ | ||
63 | static inline drm_map_t *drm_lookup_map(unsigned long offset, | ||
64 | unsigned long size, drm_device_t * dev) | ||
65 | { | ||
66 | struct list_head *list; | ||
67 | drm_map_list_t *r_list; | ||
68 | drm_map_t *map; | ||
69 | |||
70 | list_for_each(list, &dev->maplist->head) { | ||
71 | r_list = (drm_map_list_t *) list; | ||
72 | map = r_list->map; | ||
73 | if (!map) | ||
74 | continue; | ||
75 | if (map->offset <= offset | ||
76 | && (offset + size) <= (map->offset + map->size)) | ||
77 | return map; | ||
78 | } | ||
79 | return NULL; | ||
80 | } | ||
81 | |||
82 | static inline void *agp_remap(unsigned long offset, unsigned long size, | ||
83 | drm_device_t * dev) | ||
84 | { | ||
85 | unsigned long *phys_addr_map, i, num_pages = | ||
86 | PAGE_ALIGN(size) / PAGE_SIZE; | ||
87 | struct drm_agp_mem *agpmem; | ||
88 | struct page **page_map; | ||
89 | void *addr; | ||
90 | |||
91 | size = PAGE_ALIGN(size); | ||
92 | |||
93 | #ifdef __alpha__ | ||
94 | offset -= dev->hose->mem_space->start; | ||
95 | #endif | ||
96 | |||
97 | for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) | ||
98 | if (agpmem->bound <= offset | ||
99 | && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= | ||
100 | (offset + size)) | ||
101 | break; | ||
102 | if (!agpmem) | ||
103 | return NULL; | ||
104 | |||
105 | /* | ||
106 | * OK, we're mapping AGP space on a chipset/platform on which memory accesses by | ||
107 | * the CPU do not get remapped by the GART. We fix this by using the kernel's | ||
108 | * page-table instead (that's probably faster anyhow...). | ||
109 | */ | ||
110 | /* note: use vmalloc() because num_pages could be large... */ | ||
111 | page_map = vmalloc(num_pages * sizeof(struct page *)); | ||
112 | if (!page_map) | ||
113 | return NULL; | ||
114 | |||
115 | phys_addr_map = | ||
116 | agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE; | ||
117 | for (i = 0; i < num_pages; ++i) | ||
118 | page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT); | ||
119 | addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP); | ||
120 | vfree(page_map); | ||
121 | |||
122 | return addr; | ||
123 | } | ||
124 | |||
125 | static inline unsigned long drm_follow_page(void *vaddr) | 60 | static inline unsigned long drm_follow_page(void *vaddr) |
126 | { | 61 | { |
127 | pgd_t *pgd = pgd_offset_k((unsigned long)vaddr); | 62 | pgd_t *pgd = pgd_offset_k((unsigned long)vaddr); |
@@ -133,18 +68,6 @@ static inline unsigned long drm_follow_page(void *vaddr) | |||
133 | 68 | ||
134 | #else /* __OS_HAS_AGP */ | 69 | #else /* __OS_HAS_AGP */ |
135 | 70 | ||
136 | static inline drm_map_t *drm_lookup_map(unsigned long offset, | ||
137 | unsigned long size, drm_device_t * dev) | ||
138 | { | ||
139 | return NULL; | ||
140 | } | ||
141 | |||
142 | static inline void *agp_remap(unsigned long offset, unsigned long size, | ||
143 | drm_device_t * dev) | ||
144 | { | ||
145 | return NULL; | ||
146 | } | ||
147 | |||
148 | static inline unsigned long drm_follow_page(void *vaddr) | 71 | static inline unsigned long drm_follow_page(void *vaddr) |
149 | { | 72 | { |
150 | return 0; | 73 | return 0; |
@@ -152,51 +75,8 @@ static inline unsigned long drm_follow_page(void *vaddr) | |||
152 | 75 | ||
153 | #endif | 76 | #endif |
154 | 77 | ||
155 | static inline void *drm_ioremap(unsigned long offset, unsigned long size, | 78 | void *drm_ioremap(unsigned long offset, unsigned long size, |
156 | drm_device_t * dev) | 79 | drm_device_t * dev); |
157 | { | ||
158 | if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { | ||
159 | drm_map_t *map = drm_lookup_map(offset, size, dev); | ||
160 | |||
161 | if (map && map->type == _DRM_AGP) | ||
162 | return agp_remap(offset, size, dev); | ||
163 | } | ||
164 | return ioremap(offset, size); | ||
165 | } | ||
166 | |||
167 | static inline void *drm_ioremap_nocache(unsigned long offset, | ||
168 | unsigned long size, drm_device_t * dev) | ||
169 | { | ||
170 | if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) { | ||
171 | drm_map_t *map = drm_lookup_map(offset, size, dev); | ||
172 | |||
173 | if (map && map->type == _DRM_AGP) | ||
174 | return agp_remap(offset, size, dev); | ||
175 | } | ||
176 | return ioremap_nocache(offset, size); | ||
177 | } | ||
178 | |||
179 | static inline void drm_ioremapfree(void *pt, unsigned long size, | ||
180 | drm_device_t * dev) | ||
181 | { | ||
182 | /* | ||
183 | * This is a bit ugly. It would be much cleaner if the DRM API would use separate | ||
184 | * routines for handling mappings in the AGP space. Hopefully this can be done in | ||
185 | * a future revision of the interface... | ||
186 | */ | ||
187 | if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture | ||
188 | && ((unsigned long)pt >= VMALLOC_START | ||
189 | && (unsigned long)pt < VMALLOC_END)) { | ||
190 | unsigned long offset; | ||
191 | drm_map_t *map; | ||
192 | |||
193 | offset = drm_follow_page(pt) | ((unsigned long)pt & ~PAGE_MASK); | ||
194 | map = drm_lookup_map(offset, size, dev); | ||
195 | if (map && map->type == _DRM_AGP) { | ||
196 | vunmap(pt); | ||
197 | return; | ||
198 | } | ||
199 | } | ||
200 | 80 | ||
201 | iounmap(pt); | 81 | void drm_ioremapfree(void *pt, unsigned long size, |
202 | } | 82 | drm_device_t * dev); |
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h index 7868341817da..6543b9a14c42 100644 --- a/drivers/char/drm/drm_memory_debug.h +++ b/drivers/char/drm/drm_memory_debug.h | |||
@@ -229,6 +229,7 @@ void *drm_ioremap (unsigned long offset, unsigned long size, | |||
229 | return pt; | 229 | return pt; |
230 | } | 230 | } |
231 | 231 | ||
232 | #if 0 | ||
232 | void *drm_ioremap_nocache (unsigned long offset, unsigned long size, | 233 | void *drm_ioremap_nocache (unsigned long offset, unsigned long size, |
233 | drm_device_t * dev) { | 234 | drm_device_t * dev) { |
234 | void *pt; | 235 | void *pt; |
@@ -251,6 +252,7 @@ void *drm_ioremap_nocache (unsigned long offset, unsigned long size, | |||
251 | spin_unlock(&drm_mem_lock); | 252 | spin_unlock(&drm_mem_lock); |
252 | return pt; | 253 | return pt; |
253 | } | 254 | } |
255 | #endif /* 0 */ | ||
254 | 256 | ||
255 | void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { | 257 | void drm_ioremapfree (void *pt, unsigned long size, drm_device_t * dev) { |
256 | int alloc_count; | 258 | int alloc_count; |
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c index b28ca9cea8a2..86a0f1c22091 100644 --- a/drivers/char/drm/drm_pci.c +++ b/drivers/char/drm/drm_pci.c | |||
@@ -37,6 +37,7 @@ | |||
37 | */ | 37 | */ |
38 | 38 | ||
39 | #include <linux/pci.h> | 39 | #include <linux/pci.h> |
40 | #include <linux/dma-mapping.h> | ||
40 | #include "drmP.h" | 41 | #include "drmP.h" |
41 | 42 | ||
42 | /**********************************************************************/ | 43 | /**********************************************************************/ |
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c index 68073e14fdec..9a842a36bb27 100644 --- a/drivers/char/drm/drm_stub.c +++ b/drivers/char/drm/drm_stub.c | |||
@@ -229,8 +229,6 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
229 | return ret; | 229 | return ret; |
230 | } | 230 | } |
231 | 231 | ||
232 | EXPORT_SYMBOL(drm_get_dev); | ||
233 | |||
234 | /** | 232 | /** |
235 | * Put a device minor number. | 233 | * Put a device minor number. |
236 | * | 234 | * |
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c index b108c7f913b2..26bdf2ca59d7 100644 --- a/drivers/char/drm/r300_cmdbuf.c +++ b/drivers/char/drm/r300_cmdbuf.c | |||
@@ -723,7 +723,7 @@ static int r300_scratch(drm_radeon_private_t *dev_priv, | |||
723 | 723 | ||
724 | dev_priv->scratch_ages[header.scratch.reg]++; | 724 | dev_priv->scratch_ages[header.scratch.reg]++; |
725 | 725 | ||
726 | ref_age_base = *(u32 **)cmdbuf->buf; | 726 | ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf); |
727 | 727 | ||
728 | cmdbuf->buf += sizeof(u64); | 728 | cmdbuf->buf += sizeof(u64); |
729 | cmdbuf->bufsz -= sizeof(u64); | 729 | cmdbuf->bufsz -= sizeof(u64); |
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c index 6152415644e9..c33d068cde19 100644 --- a/drivers/char/drm/via_irq.c +++ b/drivers/char/drm/via_irq.c | |||
@@ -196,9 +196,9 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, | |||
196 | { | 196 | { |
197 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 197 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
198 | unsigned int cur_irq_sequence; | 198 | unsigned int cur_irq_sequence; |
199 | drm_via_irq_t *cur_irq = dev_priv->via_irqs; | 199 | drm_via_irq_t *cur_irq; |
200 | int ret = 0; | 200 | int ret = 0; |
201 | maskarray_t *masks = dev_priv->irq_masks; | 201 | maskarray_t *masks; |
202 | int real_irq; | 202 | int real_irq; |
203 | 203 | ||
204 | DRM_DEBUG("%s\n", __FUNCTION__); | 204 | DRM_DEBUG("%s\n", __FUNCTION__); |
@@ -221,8 +221,9 @@ via_driver_irq_wait(drm_device_t * dev, unsigned int irq, int force_sequence, | |||
221 | __FUNCTION__, irq); | 221 | __FUNCTION__, irq); |
222 | return DRM_ERR(EINVAL); | 222 | return DRM_ERR(EINVAL); |
223 | } | 223 | } |
224 | 224 | ||
225 | cur_irq += real_irq; | 225 | masks = dev_priv->irq_masks; |
226 | cur_irq = dev_priv->via_irqs + real_irq; | ||
226 | 227 | ||
227 | if (masks[real_irq][2] && !force_sequence) { | 228 | if (masks[real_irq][2] && !force_sequence) { |
228 | DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, | 229 | DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ, |
@@ -247,11 +248,12 @@ void via_driver_irq_preinstall(drm_device_t * dev) | |||
247 | { | 248 | { |
248 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; | 249 | drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private; |
249 | u32 status; | 250 | u32 status; |
250 | drm_via_irq_t *cur_irq = dev_priv->via_irqs; | 251 | drm_via_irq_t *cur_irq; |
251 | int i; | 252 | int i; |
252 | 253 | ||
253 | DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv); | 254 | DRM_DEBUG("driver_irq_preinstall: dev_priv: %p\n", dev_priv); |
254 | if (dev_priv) { | 255 | if (dev_priv) { |
256 | cur_irq = dev_priv->via_irqs; | ||
255 | 257 | ||
256 | dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE; | 258 | dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE; |
257 | dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; | 259 | dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING; |
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c index 58dcdee1cd71..0030cd8e2e95 100644 --- a/drivers/char/ipmi/ipmi_bt_sm.c +++ b/drivers/char/ipmi/ipmi_bt_sm.c | |||
@@ -165,7 +165,7 @@ static int bt_start_transaction(struct si_sm_data *bt, | |||
165 | { | 165 | { |
166 | unsigned int i; | 166 | unsigned int i; |
167 | 167 | ||
168 | if ((size < 2) || (size > IPMI_MAX_MSG_LENGTH)) | 168 | if ((size < 2) || (size > (IPMI_MAX_MSG_LENGTH - 2))) |
169 | return -1; | 169 | return -1; |
170 | 170 | ||
171 | if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED)) | 171 | if ((bt->state != BT_STATE_IDLE) && (bt->state != BT_STATE_HOSED)) |
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index a86c0f29953e..b36eef0e9d19 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c | |||
@@ -2198,11 +2198,11 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info) | |||
2198 | } | 2198 | } |
2199 | } | 2199 | } |
2200 | 2200 | ||
2201 | static struct ipmi_default_vals | 2201 | static __devinitdata struct ipmi_default_vals |
2202 | { | 2202 | { |
2203 | int type; | 2203 | int type; |
2204 | int port; | 2204 | int port; |
2205 | } __devinit ipmi_defaults[] = | 2205 | } ipmi_defaults[] = |
2206 | { | 2206 | { |
2207 | { .type = SI_KCS, .port = 0xca2 }, | 2207 | { .type = SI_KCS, .port = 0xca2 }, |
2208 | { .type = SI_SMIC, .port = 0xca9 }, | 2208 | { .type = SI_SMIC, .port = 0xca9 }, |
diff --git a/drivers/char/mem.c b/drivers/char/mem.c index 66719f9d294c..1fa9fa157c12 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/crash_dump.h> | 27 | #include <linux/crash_dump.h> |
28 | #include <linux/backing-dev.h> | 28 | #include <linux/backing-dev.h> |
29 | #include <linux/bootmem.h> | 29 | #include <linux/bootmem.h> |
30 | #include <linux/pipe_fs_i.h> | ||
30 | 31 | ||
31 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
32 | #include <asm/io.h> | 33 | #include <asm/io.h> |
@@ -578,6 +579,18 @@ static ssize_t write_null(struct file * file, const char __user * buf, | |||
578 | return count; | 579 | return count; |
579 | } | 580 | } |
580 | 581 | ||
582 | static int pipe_to_null(struct pipe_inode_info *info, struct pipe_buffer *buf, | ||
583 | struct splice_desc *sd) | ||
584 | { | ||
585 | return sd->len; | ||
586 | } | ||
587 | |||
588 | static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out, | ||
589 | loff_t *ppos, size_t len, unsigned int flags) | ||
590 | { | ||
591 | return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); | ||
592 | } | ||
593 | |||
581 | #ifdef CONFIG_MMU | 594 | #ifdef CONFIG_MMU |
582 | /* | 595 | /* |
583 | * For fun, we are using the MMU for this. | 596 | * For fun, we are using the MMU for this. |
@@ -785,6 +798,7 @@ static struct file_operations null_fops = { | |||
785 | .llseek = null_lseek, | 798 | .llseek = null_lseek, |
786 | .read = read_null, | 799 | .read = read_null, |
787 | .write = write_null, | 800 | .write = write_null, |
801 | .splice_write = splice_write_null, | ||
788 | }; | 802 | }; |
789 | 803 | ||
790 | #if defined(CONFIG_ISA) || !defined(__mc68000__) | 804 | #if defined(CONFIG_ISA) || !defined(__mc68000__) |
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c index b543821d8cb4..56c8243cdb73 100644 --- a/drivers/char/snsc.c +++ b/drivers/char/snsc.c | |||
@@ -390,7 +390,8 @@ scdrv_init(void) | |||
390 | format_module_id(devnamep, geo_module(geoid), | 390 | format_module_id(devnamep, geo_module(geoid), |
391 | MODULE_FORMAT_BRIEF); | 391 | MODULE_FORMAT_BRIEF); |
392 | devnamep = devname + strlen(devname); | 392 | devnamep = devname + strlen(devname); |
393 | sprintf(devnamep, "#%d", geo_slab(geoid)); | 393 | sprintf(devnamep, "^%d#%d", geo_slot(geoid), |
394 | geo_slab(geoid)); | ||
394 | 395 | ||
395 | /* allocate sysctl device data */ | 396 | /* allocate sysctl device data */ |
396 | scd = kzalloc(sizeof (struct sysctl_data_s), | 397 | scd = kzalloc(sizeof (struct sysctl_data_s), |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index f8dd8527c6aa..a90f5d97df35 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -1341,6 +1341,9 @@ static int __devinit sonypi_probe(struct platform_device *dev) | |||
1341 | else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 1341 | else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
1342 | PCI_DEVICE_ID_INTEL_ICH6_1, NULL))) | 1342 | PCI_DEVICE_ID_INTEL_ICH6_1, NULL))) |
1343 | sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; | 1343 | sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; |
1344 | else if ((pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
1345 | PCI_DEVICE_ID_INTEL_ICH7_1, NULL))) | ||
1346 | sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE3; | ||
1344 | else | 1347 | else |
1345 | sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2; | 1348 | sonypi_device.model = SONYPI_DEVICE_MODEL_TYPE2; |
1346 | 1349 | ||
diff --git a/drivers/char/tpm/Kconfig b/drivers/char/tpm/Kconfig index a6873bf89ffa..1efde3b27619 100644 --- a/drivers/char/tpm/Kconfig +++ b/drivers/char/tpm/Kconfig | |||
@@ -20,9 +20,18 @@ config TCG_TPM | |||
20 | Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI | 20 | Note: For more TPM drivers enable CONFIG_PNP, CONFIG_ACPI |
21 | and CONFIG_PNPACPI. | 21 | and CONFIG_PNPACPI. |
22 | 22 | ||
23 | config TCG_TIS | ||
24 | tristate "TPM Interface Specification 1.2 Interface" | ||
25 | depends on TCG_TPM | ||
26 | ---help--- | ||
27 | If you have a TPM security chip that is compliant with the | ||
28 | TCG TIS 1.2 TPM specification say Yes and it will be accessible | ||
29 | from within Linux. To compile this driver as a module, choose | ||
30 | M here; the module will be called tpm_tis. | ||
31 | |||
23 | config TCG_NSC | 32 | config TCG_NSC |
24 | tristate "National Semiconductor TPM Interface" | 33 | tristate "National Semiconductor TPM Interface" |
25 | depends on TCG_TPM | 34 | depends on TCG_TPM && PNPACPI |
26 | ---help--- | 35 | ---help--- |
27 | If you have a TPM security chip from National Semicondutor | 36 | If you have a TPM security chip from National Semicondutor |
28 | say Yes and it will be accessible from within Linux. To | 37 | say Yes and it will be accessible from within Linux. To |
diff --git a/drivers/char/tpm/Makefile b/drivers/char/tpm/Makefile index ba4582d160fd..ea3a1e02a824 100644 --- a/drivers/char/tpm/Makefile +++ b/drivers/char/tpm/Makefile | |||
@@ -5,6 +5,7 @@ obj-$(CONFIG_TCG_TPM) += tpm.o | |||
5 | ifdef CONFIG_ACPI | 5 | ifdef CONFIG_ACPI |
6 | obj-$(CONFIG_TCG_TPM) += tpm_bios.o | 6 | obj-$(CONFIG_TCG_TPM) += tpm_bios.o |
7 | endif | 7 | endif |
8 | obj-$(CONFIG_TCG_TIS) += tpm_tis.o | ||
8 | obj-$(CONFIG_TCG_NSC) += tpm_nsc.o | 9 | obj-$(CONFIG_TCG_NSC) += tpm_nsc.o |
9 | obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o | 10 | obj-$(CONFIG_TCG_ATMEL) += tpm_atmel.o |
10 | obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o | 11 | obj-$(CONFIG_TCG_INFINEON) += tpm_infineon.o |
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 5a3870477ef1..6889e7db3aff 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c | |||
@@ -32,12 +32,291 @@ enum tpm_const { | |||
32 | TPM_MINOR = 224, /* officially assigned */ | 32 | TPM_MINOR = 224, /* officially assigned */ |
33 | TPM_BUFSIZE = 2048, | 33 | TPM_BUFSIZE = 2048, |
34 | TPM_NUM_DEVICES = 256, | 34 | TPM_NUM_DEVICES = 256, |
35 | TPM_NUM_MASK_ENTRIES = TPM_NUM_DEVICES / (8 * sizeof(int)) | ||
36 | }; | 35 | }; |
37 | 36 | ||
37 | enum tpm_duration { | ||
38 | TPM_SHORT = 0, | ||
39 | TPM_MEDIUM = 1, | ||
40 | TPM_LONG = 2, | ||
41 | TPM_UNDEFINED, | ||
42 | }; | ||
43 | |||
44 | #define TPM_MAX_ORDINAL 243 | ||
45 | #define TPM_MAX_PROTECTED_ORDINAL 12 | ||
46 | #define TPM_PROTECTED_ORDINAL_MASK 0xFF | ||
47 | |||
38 | static LIST_HEAD(tpm_chip_list); | 48 | static LIST_HEAD(tpm_chip_list); |
39 | static DEFINE_SPINLOCK(driver_lock); | 49 | static DEFINE_SPINLOCK(driver_lock); |
40 | static int dev_mask[TPM_NUM_MASK_ENTRIES]; | 50 | static DECLARE_BITMAP(dev_mask, TPM_NUM_DEVICES); |
51 | |||
52 | /* | ||
53 | * Array with one entry per ordinal defining the maximum amount | ||
54 | * of time the chip could take to return the result. The ordinal | ||
55 | * designation of short, medium or long is defined in a table in | ||
56 | * TCG Specification TPM Main Part 2 TPM Structures Section 17. The | ||
57 | * values of the SHORT, MEDIUM, and LONG durations are retrieved | ||
58 | * from the chip during initialization with a call to tpm_get_timeouts. | ||
59 | */ | ||
60 | static const u8 tpm_protected_ordinal_duration[TPM_MAX_PROTECTED_ORDINAL] = { | ||
61 | TPM_UNDEFINED, /* 0 */ | ||
62 | TPM_UNDEFINED, | ||
63 | TPM_UNDEFINED, | ||
64 | TPM_UNDEFINED, | ||
65 | TPM_UNDEFINED, | ||
66 | TPM_UNDEFINED, /* 5 */ | ||
67 | TPM_UNDEFINED, | ||
68 | TPM_UNDEFINED, | ||
69 | TPM_UNDEFINED, | ||
70 | TPM_UNDEFINED, | ||
71 | TPM_SHORT, /* 10 */ | ||
72 | TPM_SHORT, | ||
73 | }; | ||
74 | |||
75 | static const u8 tpm_ordinal_duration[TPM_MAX_ORDINAL] = { | ||
76 | TPM_UNDEFINED, /* 0 */ | ||
77 | TPM_UNDEFINED, | ||
78 | TPM_UNDEFINED, | ||
79 | TPM_UNDEFINED, | ||
80 | TPM_UNDEFINED, | ||
81 | TPM_UNDEFINED, /* 5 */ | ||
82 | TPM_UNDEFINED, | ||
83 | TPM_UNDEFINED, | ||
84 | TPM_UNDEFINED, | ||
85 | TPM_UNDEFINED, | ||
86 | TPM_SHORT, /* 10 */ | ||
87 | TPM_SHORT, | ||
88 | TPM_MEDIUM, | ||
89 | TPM_LONG, | ||
90 | TPM_LONG, | ||
91 | TPM_MEDIUM, /* 15 */ | ||
92 | TPM_SHORT, | ||
93 | TPM_SHORT, | ||
94 | TPM_MEDIUM, | ||
95 | TPM_LONG, | ||
96 | TPM_SHORT, /* 20 */ | ||
97 | TPM_SHORT, | ||
98 | TPM_MEDIUM, | ||
99 | TPM_MEDIUM, | ||
100 | TPM_MEDIUM, | ||
101 | TPM_SHORT, /* 25 */ | ||
102 | TPM_SHORT, | ||
103 | TPM_MEDIUM, | ||
104 | TPM_SHORT, | ||
105 | TPM_SHORT, | ||
106 | TPM_MEDIUM, /* 30 */ | ||
107 | TPM_LONG, | ||
108 | TPM_MEDIUM, | ||
109 | TPM_SHORT, | ||
110 | TPM_SHORT, | ||
111 | TPM_SHORT, /* 35 */ | ||
112 | TPM_MEDIUM, | ||
113 | TPM_MEDIUM, | ||
114 | TPM_UNDEFINED, | ||
115 | TPM_UNDEFINED, | ||
116 | TPM_MEDIUM, /* 40 */ | ||
117 | TPM_LONG, | ||
118 | TPM_MEDIUM, | ||
119 | TPM_SHORT, | ||
120 | TPM_SHORT, | ||
121 | TPM_SHORT, /* 45 */ | ||
122 | TPM_SHORT, | ||
123 | TPM_SHORT, | ||
124 | TPM_SHORT, | ||
125 | TPM_LONG, | ||
126 | TPM_MEDIUM, /* 50 */ | ||
127 | TPM_MEDIUM, | ||
128 | TPM_UNDEFINED, | ||
129 | TPM_UNDEFINED, | ||
130 | TPM_UNDEFINED, | ||
131 | TPM_UNDEFINED, /* 55 */ | ||
132 | TPM_UNDEFINED, | ||
133 | TPM_UNDEFINED, | ||
134 | TPM_UNDEFINED, | ||
135 | TPM_UNDEFINED, | ||
136 | TPM_MEDIUM, /* 60 */ | ||
137 | TPM_MEDIUM, | ||
138 | TPM_MEDIUM, | ||
139 | TPM_SHORT, | ||
140 | TPM_SHORT, | ||
141 | TPM_MEDIUM, /* 65 */ | ||
142 | TPM_UNDEFINED, | ||
143 | TPM_UNDEFINED, | ||
144 | TPM_UNDEFINED, | ||
145 | TPM_UNDEFINED, | ||
146 | TPM_SHORT, /* 70 */ | ||
147 | TPM_SHORT, | ||
148 | TPM_UNDEFINED, | ||
149 | TPM_UNDEFINED, | ||
150 | TPM_UNDEFINED, | ||
151 | TPM_UNDEFINED, /* 75 */ | ||
152 | TPM_UNDEFINED, | ||
153 | TPM_UNDEFINED, | ||
154 | TPM_UNDEFINED, | ||
155 | TPM_UNDEFINED, | ||
156 | TPM_LONG, /* 80 */ | ||
157 | TPM_UNDEFINED, | ||
158 | TPM_MEDIUM, | ||
159 | TPM_LONG, | ||
160 | TPM_SHORT, | ||
161 | TPM_UNDEFINED, /* 85 */ | ||
162 | TPM_UNDEFINED, | ||
163 | TPM_UNDEFINED, | ||
164 | TPM_UNDEFINED, | ||
165 | TPM_UNDEFINED, | ||
166 | TPM_SHORT, /* 90 */ | ||
167 | TPM_SHORT, | ||
168 | TPM_SHORT, | ||
169 | TPM_SHORT, | ||
170 | TPM_SHORT, | ||
171 | TPM_UNDEFINED, /* 95 */ | ||
172 | TPM_UNDEFINED, | ||
173 | TPM_UNDEFINED, | ||
174 | TPM_UNDEFINED, | ||
175 | TPM_UNDEFINED, | ||
176 | TPM_MEDIUM, /* 100 */ | ||
177 | TPM_SHORT, | ||
178 | TPM_SHORT, | ||
179 | TPM_UNDEFINED, | ||
180 | TPM_UNDEFINED, | ||
181 | TPM_UNDEFINED, /* 105 */ | ||
182 | TPM_UNDEFINED, | ||
183 | TPM_UNDEFINED, | ||
184 | TPM_UNDEFINED, | ||
185 | TPM_UNDEFINED, | ||
186 | TPM_SHORT, /* 110 */ | ||
187 | TPM_SHORT, | ||
188 | TPM_SHORT, | ||
189 | TPM_SHORT, | ||
190 | TPM_SHORT, | ||
191 | TPM_SHORT, /* 115 */ | ||
192 | TPM_SHORT, | ||
193 | TPM_SHORT, | ||
194 | TPM_UNDEFINED, | ||
195 | TPM_UNDEFINED, | ||
196 | TPM_LONG, /* 120 */ | ||
197 | TPM_LONG, | ||
198 | TPM_MEDIUM, | ||
199 | TPM_UNDEFINED, | ||
200 | TPM_SHORT, | ||
201 | TPM_SHORT, /* 125 */ | ||
202 | TPM_SHORT, | ||
203 | TPM_LONG, | ||
204 | TPM_SHORT, | ||
205 | TPM_SHORT, | ||
206 | TPM_SHORT, /* 130 */ | ||
207 | TPM_MEDIUM, | ||
208 | TPM_UNDEFINED, | ||
209 | TPM_SHORT, | ||
210 | TPM_MEDIUM, | ||
211 | TPM_UNDEFINED, /* 135 */ | ||
212 | TPM_UNDEFINED, | ||
213 | TPM_UNDEFINED, | ||
214 | TPM_UNDEFINED, | ||
215 | TPM_UNDEFINED, | ||
216 | TPM_SHORT, /* 140 */ | ||
217 | TPM_SHORT, | ||
218 | TPM_UNDEFINED, | ||
219 | TPM_UNDEFINED, | ||
220 | TPM_UNDEFINED, | ||
221 | TPM_UNDEFINED, /* 145 */ | ||
222 | TPM_UNDEFINED, | ||
223 | TPM_UNDEFINED, | ||
224 | TPM_UNDEFINED, | ||
225 | TPM_UNDEFINED, | ||
226 | TPM_SHORT, /* 150 */ | ||
227 | TPM_MEDIUM, | ||
228 | TPM_MEDIUM, | ||
229 | TPM_SHORT, | ||
230 | TPM_SHORT, | ||
231 | TPM_UNDEFINED, /* 155 */ | ||
232 | TPM_UNDEFINED, | ||
233 | TPM_UNDEFINED, | ||
234 | TPM_UNDEFINED, | ||
235 | TPM_UNDEFINED, | ||
236 | TPM_SHORT, /* 160 */ | ||
237 | TPM_SHORT, | ||
238 | TPM_SHORT, | ||
239 | TPM_SHORT, | ||
240 | TPM_UNDEFINED, | ||
241 | TPM_UNDEFINED, /* 165 */ | ||
242 | TPM_UNDEFINED, | ||
243 | TPM_UNDEFINED, | ||
244 | TPM_UNDEFINED, | ||
245 | TPM_UNDEFINED, | ||
246 | TPM_LONG, /* 170 */ | ||
247 | TPM_UNDEFINED, | ||
248 | TPM_UNDEFINED, | ||
249 | TPM_UNDEFINED, | ||
250 | TPM_UNDEFINED, | ||
251 | TPM_UNDEFINED, /* 175 */ | ||
252 | TPM_UNDEFINED, | ||
253 | TPM_UNDEFINED, | ||
254 | TPM_UNDEFINED, | ||
255 | TPM_UNDEFINED, | ||
256 | TPM_MEDIUM, /* 180 */ | ||
257 | TPM_SHORT, | ||
258 | TPM_MEDIUM, | ||
259 | TPM_MEDIUM, | ||
260 | TPM_MEDIUM, | ||
261 | TPM_MEDIUM, /* 185 */ | ||
262 | TPM_SHORT, | ||
263 | TPM_UNDEFINED, | ||
264 | TPM_UNDEFINED, | ||
265 | TPM_UNDEFINED, | ||
266 | TPM_UNDEFINED, /* 190 */ | ||
267 | TPM_UNDEFINED, | ||
268 | TPM_UNDEFINED, | ||
269 | TPM_UNDEFINED, | ||
270 | TPM_UNDEFINED, | ||
271 | TPM_UNDEFINED, /* 195 */ | ||
272 | TPM_UNDEFINED, | ||
273 | TPM_UNDEFINED, | ||
274 | TPM_UNDEFINED, | ||
275 | TPM_UNDEFINED, | ||
276 | TPM_SHORT, /* 200 */ | ||
277 | TPM_UNDEFINED, | ||
278 | TPM_UNDEFINED, | ||
279 | TPM_UNDEFINED, | ||
280 | TPM_SHORT, | ||
281 | TPM_SHORT, /* 205 */ | ||
282 | TPM_SHORT, | ||
283 | TPM_SHORT, | ||
284 | TPM_SHORT, | ||
285 | TPM_SHORT, | ||
286 | TPM_MEDIUM, /* 210 */ | ||
287 | TPM_UNDEFINED, | ||
288 | TPM_MEDIUM, | ||
289 | TPM_MEDIUM, | ||
290 | TPM_MEDIUM, | ||
291 | TPM_UNDEFINED, /* 215 */ | ||
292 | TPM_MEDIUM, | ||
293 | TPM_UNDEFINED, | ||
294 | TPM_UNDEFINED, | ||
295 | TPM_SHORT, | ||
296 | TPM_SHORT, /* 220 */ | ||
297 | TPM_SHORT, | ||
298 | TPM_SHORT, | ||
299 | TPM_SHORT, | ||
300 | TPM_SHORT, | ||
301 | TPM_UNDEFINED, /* 225 */ | ||
302 | TPM_UNDEFINED, | ||
303 | TPM_UNDEFINED, | ||
304 | TPM_UNDEFINED, | ||
305 | TPM_UNDEFINED, | ||
306 | TPM_SHORT, /* 230 */ | ||
307 | TPM_LONG, | ||
308 | TPM_MEDIUM, | ||
309 | TPM_UNDEFINED, | ||
310 | TPM_UNDEFINED, | ||
311 | TPM_UNDEFINED, /* 235 */ | ||
312 | TPM_UNDEFINED, | ||
313 | TPM_UNDEFINED, | ||
314 | TPM_UNDEFINED, | ||
315 | TPM_UNDEFINED, | ||
316 | TPM_SHORT, /* 240 */ | ||
317 | TPM_UNDEFINED, | ||
318 | TPM_MEDIUM, | ||
319 | }; | ||
41 | 320 | ||
42 | static void user_reader_timeout(unsigned long ptr) | 321 | static void user_reader_timeout(unsigned long ptr) |
43 | { | 322 | { |
@@ -46,7 +325,7 @@ static void user_reader_timeout(unsigned long ptr) | |||
46 | schedule_work(&chip->work); | 325 | schedule_work(&chip->work); |
47 | } | 326 | } |
48 | 327 | ||
49 | static void timeout_work(void * ptr) | 328 | static void timeout_work(void *ptr) |
50 | { | 329 | { |
51 | struct tpm_chip *chip = ptr; | 330 | struct tpm_chip *chip = ptr; |
52 | 331 | ||
@@ -57,17 +336,43 @@ static void timeout_work(void * ptr) | |||
57 | } | 336 | } |
58 | 337 | ||
59 | /* | 338 | /* |
339 | * Returns max number of jiffies to wait | ||
340 | */ | ||
341 | unsigned long tpm_calc_ordinal_duration(struct tpm_chip *chip, | ||
342 | u32 ordinal) | ||
343 | { | ||
344 | int duration_idx = TPM_UNDEFINED; | ||
345 | int duration = 0; | ||
346 | |||
347 | if (ordinal < TPM_MAX_ORDINAL) | ||
348 | duration_idx = tpm_ordinal_duration[ordinal]; | ||
349 | else if ((ordinal & TPM_PROTECTED_ORDINAL_MASK) < | ||
350 | TPM_MAX_PROTECTED_ORDINAL) | ||
351 | duration_idx = | ||
352 | tpm_protected_ordinal_duration[ordinal & | ||
353 | TPM_PROTECTED_ORDINAL_MASK]; | ||
354 | |||
355 | if (duration_idx != TPM_UNDEFINED) | ||
356 | duration = chip->vendor.duration[duration_idx]; | ||
357 | if (duration <= 0) | ||
358 | return 2 * 60 * HZ; | ||
359 | else | ||
360 | return duration; | ||
361 | } | ||
362 | EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); | ||
363 | |||
364 | /* | ||
60 | * Internal kernel interface to transmit TPM commands | 365 | * Internal kernel interface to transmit TPM commands |
61 | */ | 366 | */ |
62 | static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | 367 | static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, |
63 | size_t bufsiz) | 368 | size_t bufsiz) |
64 | { | 369 | { |
65 | ssize_t rc; | 370 | ssize_t rc; |
66 | u32 count; | 371 | u32 count, ordinal; |
67 | unsigned long stop; | 372 | unsigned long stop; |
68 | 373 | ||
69 | count = be32_to_cpu(*((__be32 *) (buf + 2))); | 374 | count = be32_to_cpu(*((__be32 *) (buf + 2))); |
70 | 375 | ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); | |
71 | if (count == 0) | 376 | if (count == 0) |
72 | return -ENODATA; | 377 | return -ENODATA; |
73 | if (count > bufsiz) { | 378 | if (count > bufsiz) { |
@@ -78,21 +383,23 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
78 | 383 | ||
79 | down(&chip->tpm_mutex); | 384 | down(&chip->tpm_mutex); |
80 | 385 | ||
81 | if ((rc = chip->vendor->send(chip, (u8 *) buf, count)) < 0) { | 386 | if ((rc = chip->vendor.send(chip, (u8 *) buf, count)) < 0) { |
82 | dev_err(chip->dev, | 387 | dev_err(chip->dev, |
83 | "tpm_transmit: tpm_send: error %zd\n", rc); | 388 | "tpm_transmit: tpm_send: error %zd\n", rc); |
84 | goto out; | 389 | goto out; |
85 | } | 390 | } |
86 | 391 | ||
87 | stop = jiffies + 2 * 60 * HZ; | 392 | if (chip->vendor.irq) |
393 | goto out_recv; | ||
394 | |||
395 | stop = jiffies + tpm_calc_ordinal_duration(chip, ordinal); | ||
88 | do { | 396 | do { |
89 | u8 status = chip->vendor->status(chip); | 397 | u8 status = chip->vendor.status(chip); |
90 | if ((status & chip->vendor->req_complete_mask) == | 398 | if ((status & chip->vendor.req_complete_mask) == |
91 | chip->vendor->req_complete_val) { | 399 | chip->vendor.req_complete_val) |
92 | goto out_recv; | 400 | goto out_recv; |
93 | } | ||
94 | 401 | ||
95 | if ((status == chip->vendor->req_canceled)) { | 402 | if ((status == chip->vendor.req_canceled)) { |
96 | dev_err(chip->dev, "Operation Canceled\n"); | 403 | dev_err(chip->dev, "Operation Canceled\n"); |
97 | rc = -ECANCELED; | 404 | rc = -ECANCELED; |
98 | goto out; | 405 | goto out; |
@@ -102,14 +409,13 @@ static ssize_t tpm_transmit(struct tpm_chip *chip, const char *buf, | |||
102 | rmb(); | 409 | rmb(); |
103 | } while (time_before(jiffies, stop)); | 410 | } while (time_before(jiffies, stop)); |
104 | 411 | ||
105 | 412 | chip->vendor.cancel(chip); | |
106 | chip->vendor->cancel(chip); | ||
107 | dev_err(chip->dev, "Operation Timed out\n"); | 413 | dev_err(chip->dev, "Operation Timed out\n"); |
108 | rc = -ETIME; | 414 | rc = -ETIME; |
109 | goto out; | 415 | goto out; |
110 | 416 | ||
111 | out_recv: | 417 | out_recv: |
112 | rc = chip->vendor->recv(chip, (u8 *) buf, bufsiz); | 418 | rc = chip->vendor.recv(chip, (u8 *) buf, bufsiz); |
113 | if (rc < 0) | 419 | if (rc < 0) |
114 | dev_err(chip->dev, | 420 | dev_err(chip->dev, |
115 | "tpm_transmit: tpm_recv: error %zd\n", rc); | 421 | "tpm_transmit: tpm_recv: error %zd\n", rc); |
@@ -119,17 +425,247 @@ out: | |||
119 | } | 425 | } |
120 | 426 | ||
121 | #define TPM_DIGEST_SIZE 20 | 427 | #define TPM_DIGEST_SIZE 20 |
122 | #define CAP_PCR_RESULT_SIZE 18 | 428 | #define TPM_ERROR_SIZE 10 |
123 | static const u8 cap_pcr[] = { | 429 | #define TPM_RET_CODE_IDX 6 |
430 | #define TPM_GET_CAP_RET_SIZE_IDX 10 | ||
431 | #define TPM_GET_CAP_RET_UINT32_1_IDX 14 | ||
432 | #define TPM_GET_CAP_RET_UINT32_2_IDX 18 | ||
433 | #define TPM_GET_CAP_RET_UINT32_3_IDX 22 | ||
434 | #define TPM_GET_CAP_RET_UINT32_4_IDX 26 | ||
435 | #define TPM_GET_CAP_PERM_DISABLE_IDX 16 | ||
436 | #define TPM_GET_CAP_PERM_INACTIVE_IDX 18 | ||
437 | #define TPM_GET_CAP_RET_BOOL_1_IDX 14 | ||
438 | #define TPM_GET_CAP_TEMP_INACTIVE_IDX 16 | ||
439 | |||
440 | #define TPM_CAP_IDX 13 | ||
441 | #define TPM_CAP_SUBCAP_IDX 21 | ||
442 | |||
443 | enum tpm_capabilities { | ||
444 | TPM_CAP_FLAG = 4, | ||
445 | TPM_CAP_PROP = 5, | ||
446 | }; | ||
447 | |||
448 | enum tpm_sub_capabilities { | ||
449 | TPM_CAP_PROP_PCR = 0x1, | ||
450 | TPM_CAP_PROP_MANUFACTURER = 0x3, | ||
451 | TPM_CAP_FLAG_PERM = 0x8, | ||
452 | TPM_CAP_FLAG_VOL = 0x9, | ||
453 | TPM_CAP_PROP_OWNER = 0x11, | ||
454 | TPM_CAP_PROP_TIS_TIMEOUT = 0x15, | ||
455 | TPM_CAP_PROP_TIS_DURATION = 0x20, | ||
456 | }; | ||
457 | |||
458 | /* | ||
459 | * This is a semi generic GetCapability command for use | ||
460 | * with the capability type TPM_CAP_PROP or TPM_CAP_FLAG | ||
461 | * and their associated sub_capabilities. | ||
462 | */ | ||
463 | |||
464 | static const u8 tpm_cap[] = { | ||
124 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | 465 | 0, 193, /* TPM_TAG_RQU_COMMAND */ |
125 | 0, 0, 0, 22, /* length */ | 466 | 0, 0, 0, 22, /* length */ |
126 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ | 467 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ |
127 | 0, 0, 0, 5, | 468 | 0, 0, 0, 0, /* TPM_CAP_<TYPE> */ |
128 | 0, 0, 0, 4, | 469 | 0, 0, 0, 4, /* TPM_CAP_SUB_<TYPE> size */ |
129 | 0, 0, 1, 1 | 470 | 0, 0, 1, 0 /* TPM_CAP_SUB_<TYPE> */ |
130 | }; | 471 | }; |
131 | 472 | ||
132 | #define READ_PCR_RESULT_SIZE 30 | 473 | static ssize_t transmit_cmd(struct tpm_chip *chip, u8 *data, int len, |
474 | char *desc) | ||
475 | { | ||
476 | int err; | ||
477 | |||
478 | len = tpm_transmit(chip, data, len); | ||
479 | if (len < 0) | ||
480 | return len; | ||
481 | if (len == TPM_ERROR_SIZE) { | ||
482 | err = be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX))); | ||
483 | dev_dbg(chip->dev, "A TPM error (%d) occurred %s\n", err, desc); | ||
484 | return err; | ||
485 | } | ||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | void tpm_gen_interrupt(struct tpm_chip *chip) | ||
490 | { | ||
491 | u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)]; | ||
492 | ssize_t rc; | ||
493 | |||
494 | memcpy(data, tpm_cap, sizeof(tpm_cap)); | ||
495 | data[TPM_CAP_IDX] = TPM_CAP_PROP; | ||
496 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT; | ||
497 | |||
498 | rc = transmit_cmd(chip, data, sizeof(data), | ||
499 | "attempting to determine the timeouts"); | ||
500 | } | ||
501 | EXPORT_SYMBOL_GPL(tpm_gen_interrupt); | ||
502 | |||
503 | void tpm_get_timeouts(struct tpm_chip *chip) | ||
504 | { | ||
505 | u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 30)]; | ||
506 | ssize_t rc; | ||
507 | u32 timeout; | ||
508 | |||
509 | memcpy(data, tpm_cap, sizeof(tpm_cap)); | ||
510 | data[TPM_CAP_IDX] = TPM_CAP_PROP; | ||
511 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_TIMEOUT; | ||
512 | |||
513 | rc = transmit_cmd(chip, data, sizeof(data), | ||
514 | "attempting to determine the timeouts"); | ||
515 | if (rc) | ||
516 | goto duration; | ||
517 | |||
518 | if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX))) | ||
519 | != 4 * sizeof(u32)) | ||
520 | goto duration; | ||
521 | |||
522 | /* Don't overwrite default if value is 0 */ | ||
523 | timeout = | ||
524 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX))); | ||
525 | if (timeout) | ||
526 | chip->vendor.timeout_a = msecs_to_jiffies(timeout); | ||
527 | timeout = | ||
528 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_2_IDX))); | ||
529 | if (timeout) | ||
530 | chip->vendor.timeout_b = msecs_to_jiffies(timeout); | ||
531 | timeout = | ||
532 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_3_IDX))); | ||
533 | if (timeout) | ||
534 | chip->vendor.timeout_c = msecs_to_jiffies(timeout); | ||
535 | timeout = | ||
536 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_4_IDX))); | ||
537 | if (timeout) | ||
538 | chip->vendor.timeout_d = msecs_to_jiffies(timeout); | ||
539 | |||
540 | duration: | ||
541 | memcpy(data, tpm_cap, sizeof(tpm_cap)); | ||
542 | data[TPM_CAP_IDX] = TPM_CAP_PROP; | ||
543 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_TIS_DURATION; | ||
544 | |||
545 | rc = transmit_cmd(chip, data, sizeof(data), | ||
546 | "attempting to determine the durations"); | ||
547 | if (rc) | ||
548 | return; | ||
549 | |||
550 | if (be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_SIZE_IDX))) | ||
551 | != 3 * sizeof(u32)) | ||
552 | return; | ||
553 | |||
554 | chip->vendor.duration[TPM_SHORT] = | ||
555 | msecs_to_jiffies(be32_to_cpu | ||
556 | (*((__be32 *) (data + | ||
557 | TPM_GET_CAP_RET_UINT32_1_IDX)))); | ||
558 | chip->vendor.duration[TPM_MEDIUM] = | ||
559 | msecs_to_jiffies(be32_to_cpu | ||
560 | (*((__be32 *) (data + | ||
561 | TPM_GET_CAP_RET_UINT32_2_IDX)))); | ||
562 | chip->vendor.duration[TPM_LONG] = | ||
563 | msecs_to_jiffies(be32_to_cpu | ||
564 | (*((__be32 *) (data + | ||
565 | TPM_GET_CAP_RET_UINT32_3_IDX)))); | ||
566 | } | ||
567 | EXPORT_SYMBOL_GPL(tpm_get_timeouts); | ||
568 | |||
569 | void tpm_continue_selftest(struct tpm_chip *chip) | ||
570 | { | ||
571 | u8 data[] = { | ||
572 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | ||
573 | 0, 0, 0, 10, /* length */ | ||
574 | 0, 0, 0, 83, /* TPM_ORD_GetCapability */ | ||
575 | }; | ||
576 | |||
577 | tpm_transmit(chip, data, sizeof(data)); | ||
578 | } | ||
579 | EXPORT_SYMBOL_GPL(tpm_continue_selftest); | ||
580 | |||
581 | ssize_t tpm_show_enabled(struct device * dev, struct device_attribute * attr, | ||
582 | char *buf) | ||
583 | { | ||
584 | u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)]; | ||
585 | ssize_t rc; | ||
586 | |||
587 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
588 | if (chip == NULL) | ||
589 | return -ENODEV; | ||
590 | |||
591 | memcpy(data, tpm_cap, sizeof(tpm_cap)); | ||
592 | data[TPM_CAP_IDX] = TPM_CAP_FLAG; | ||
593 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM; | ||
594 | |||
595 | rc = transmit_cmd(chip, data, sizeof(data), | ||
596 | "attemtping to determine the permanent state"); | ||
597 | if (rc) | ||
598 | return 0; | ||
599 | return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_DISABLE_IDX]); | ||
600 | } | ||
601 | EXPORT_SYMBOL_GPL(tpm_show_enabled); | ||
602 | |||
603 | ssize_t tpm_show_active(struct device * dev, struct device_attribute * attr, | ||
604 | char *buf) | ||
605 | { | ||
606 | u8 data[max_t(int, ARRAY_SIZE(tpm_cap), 35)]; | ||
607 | ssize_t rc; | ||
608 | |||
609 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
610 | if (chip == NULL) | ||
611 | return -ENODEV; | ||
612 | |||
613 | memcpy(data, tpm_cap, sizeof(tpm_cap)); | ||
614 | data[TPM_CAP_IDX] = TPM_CAP_FLAG; | ||
615 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_PERM; | ||
616 | |||
617 | rc = transmit_cmd(chip, data, sizeof(data), | ||
618 | "attemtping to determine the permanent state"); | ||
619 | if (rc) | ||
620 | return 0; | ||
621 | return sprintf(buf, "%d\n", !data[TPM_GET_CAP_PERM_INACTIVE_IDX]); | ||
622 | } | ||
623 | EXPORT_SYMBOL_GPL(tpm_show_active); | ||
624 | |||
625 | ssize_t tpm_show_owned(struct device * dev, struct device_attribute * attr, | ||
626 | char *buf) | ||
627 | { | ||
628 | u8 data[sizeof(tpm_cap)]; | ||
629 | ssize_t rc; | ||
630 | |||
631 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
632 | if (chip == NULL) | ||
633 | return -ENODEV; | ||
634 | |||
635 | memcpy(data, tpm_cap, sizeof(tpm_cap)); | ||
636 | data[TPM_CAP_IDX] = TPM_CAP_PROP; | ||
637 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_OWNER; | ||
638 | |||
639 | rc = transmit_cmd(chip, data, sizeof(data), | ||
640 | "attempting to determine the owner state"); | ||
641 | if (rc) | ||
642 | return 0; | ||
643 | return sprintf(buf, "%d\n", data[TPM_GET_CAP_RET_BOOL_1_IDX]); | ||
644 | } | ||
645 | EXPORT_SYMBOL_GPL(tpm_show_owned); | ||
646 | |||
647 | ssize_t tpm_show_temp_deactivated(struct device * dev, | ||
648 | struct device_attribute * attr, char *buf) | ||
649 | { | ||
650 | u8 data[sizeof(tpm_cap)]; | ||
651 | ssize_t rc; | ||
652 | |||
653 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
654 | if (chip == NULL) | ||
655 | return -ENODEV; | ||
656 | |||
657 | memcpy(data, tpm_cap, sizeof(tpm_cap)); | ||
658 | data[TPM_CAP_IDX] = TPM_CAP_FLAG; | ||
659 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_FLAG_VOL; | ||
660 | |||
661 | rc = transmit_cmd(chip, data, sizeof(data), | ||
662 | "attempting to determine the temporary state"); | ||
663 | if (rc) | ||
664 | return 0; | ||
665 | return sprintf(buf, "%d\n", data[TPM_GET_CAP_TEMP_INACTIVE_IDX]); | ||
666 | } | ||
667 | EXPORT_SYMBOL_GPL(tpm_show_temp_deactivated); | ||
668 | |||
133 | static const u8 pcrread[] = { | 669 | static const u8 pcrread[] = { |
134 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | 670 | 0, 193, /* TPM_TAG_RQU_COMMAND */ |
135 | 0, 0, 0, 14, /* length */ | 671 | 0, 0, 0, 14, /* length */ |
@@ -140,8 +676,8 @@ static const u8 pcrread[] = { | |||
140 | ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | 676 | ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, |
141 | char *buf) | 677 | char *buf) |
142 | { | 678 | { |
143 | u8 data[READ_PCR_RESULT_SIZE]; | 679 | u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(pcrread)), 30)]; |
144 | ssize_t len; | 680 | ssize_t rc; |
145 | int i, j, num_pcrs; | 681 | int i, j, num_pcrs; |
146 | __be32 index; | 682 | __be32 index; |
147 | char *str = buf; | 683 | char *str = buf; |
@@ -150,29 +686,24 @@ ssize_t tpm_show_pcrs(struct device *dev, struct device_attribute *attr, | |||
150 | if (chip == NULL) | 686 | if (chip == NULL) |
151 | return -ENODEV; | 687 | return -ENODEV; |
152 | 688 | ||
153 | memcpy(data, cap_pcr, sizeof(cap_pcr)); | 689 | memcpy(data, tpm_cap, sizeof(tpm_cap)); |
154 | if ((len = tpm_transmit(chip, data, sizeof(data))) | 690 | data[TPM_CAP_IDX] = TPM_CAP_PROP; |
155 | < CAP_PCR_RESULT_SIZE) { | 691 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_PCR; |
156 | dev_dbg(chip->dev, "A TPM error (%d) occurred " | 692 | |
157 | "attempting to determine the number of PCRS\n", | 693 | rc = transmit_cmd(chip, data, sizeof(data), |
158 | be32_to_cpu(*((__be32 *) (data + 6)))); | 694 | "attempting to determine the number of PCRS"); |
695 | if (rc) | ||
159 | return 0; | 696 | return 0; |
160 | } | ||
161 | 697 | ||
162 | num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); | 698 | num_pcrs = be32_to_cpu(*((__be32 *) (data + 14))); |
163 | |||
164 | for (i = 0; i < num_pcrs; i++) { | 699 | for (i = 0; i < num_pcrs; i++) { |
165 | memcpy(data, pcrread, sizeof(pcrread)); | 700 | memcpy(data, pcrread, sizeof(pcrread)); |
166 | index = cpu_to_be32(i); | 701 | index = cpu_to_be32(i); |
167 | memcpy(data + 10, &index, 4); | 702 | memcpy(data + 10, &index, 4); |
168 | if ((len = tpm_transmit(chip, data, sizeof(data))) | 703 | rc = transmit_cmd(chip, data, sizeof(data), |
169 | < READ_PCR_RESULT_SIZE){ | 704 | "attempting to read a PCR"); |
170 | dev_dbg(chip->dev, "A TPM error (%d) occurred" | 705 | if (rc) |
171 | " attempting to read PCR %d of %d\n", | ||
172 | be32_to_cpu(*((__be32 *) (data + 6))), | ||
173 | i, num_pcrs); | ||
174 | goto out; | 706 | goto out; |
175 | } | ||
176 | str += sprintf(str, "PCR-%02d: ", i); | 707 | str += sprintf(str, "PCR-%02d: ", i); |
177 | for (j = 0; j < TPM_DIGEST_SIZE; j++) | 708 | for (j = 0; j < TPM_DIGEST_SIZE; j++) |
178 | str += sprintf(str, "%02X ", *(data + 10 + j)); | 709 | str += sprintf(str, "%02X ", *(data + 10 + j)); |
@@ -194,7 +725,7 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
194 | char *buf) | 725 | char *buf) |
195 | { | 726 | { |
196 | u8 *data; | 727 | u8 *data; |
197 | ssize_t len; | 728 | ssize_t err; |
198 | int i, rc; | 729 | int i, rc; |
199 | char *str = buf; | 730 | char *str = buf; |
200 | 731 | ||
@@ -208,14 +739,10 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
208 | 739 | ||
209 | memcpy(data, readpubek, sizeof(readpubek)); | 740 | memcpy(data, readpubek, sizeof(readpubek)); |
210 | 741 | ||
211 | if ((len = tpm_transmit(chip, data, READ_PUBEK_RESULT_SIZE)) < | 742 | err = transmit_cmd(chip, data, READ_PUBEK_RESULT_SIZE, |
212 | READ_PUBEK_RESULT_SIZE) { | 743 | "attempting to read the PUBEK"); |
213 | dev_dbg(chip->dev, "A TPM error (%d) occurred " | 744 | if (err) |
214 | "attempting to read the PUBEK\n", | ||
215 | be32_to_cpu(*((__be32 *) (data + 6)))); | ||
216 | rc = 0; | ||
217 | goto out; | 745 | goto out; |
218 | } | ||
219 | 746 | ||
220 | /* | 747 | /* |
221 | ignore header 10 bytes | 748 | ignore header 10 bytes |
@@ -245,67 +772,110 @@ ssize_t tpm_show_pubek(struct device *dev, struct device_attribute *attr, | |||
245 | if ((i + 1) % 16 == 0) | 772 | if ((i + 1) % 16 == 0) |
246 | str += sprintf(str, "\n"); | 773 | str += sprintf(str, "\n"); |
247 | } | 774 | } |
248 | rc = str - buf; | ||
249 | out: | 775 | out: |
776 | rc = str - buf; | ||
250 | kfree(data); | 777 | kfree(data); |
251 | return rc; | 778 | return rc; |
252 | } | 779 | } |
253 | EXPORT_SYMBOL_GPL(tpm_show_pubek); | 780 | EXPORT_SYMBOL_GPL(tpm_show_pubek); |
254 | 781 | ||
255 | #define CAP_VER_RESULT_SIZE 18 | 782 | #define CAP_VERSION_1_1 6 |
783 | #define CAP_VERSION_1_2 0x1A | ||
784 | #define CAP_VERSION_IDX 13 | ||
256 | static const u8 cap_version[] = { | 785 | static const u8 cap_version[] = { |
257 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | 786 | 0, 193, /* TPM_TAG_RQU_COMMAND */ |
258 | 0, 0, 0, 18, /* length */ | 787 | 0, 0, 0, 18, /* length */ |
259 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ | 788 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ |
260 | 0, 0, 0, 6, | 789 | 0, 0, 0, 0, |
261 | 0, 0, 0, 0 | 790 | 0, 0, 0, 0 |
262 | }; | 791 | }; |
263 | 792 | ||
264 | #define CAP_MANUFACTURER_RESULT_SIZE 18 | ||
265 | static const u8 cap_manufacturer[] = { | ||
266 | 0, 193, /* TPM_TAG_RQU_COMMAND */ | ||
267 | 0, 0, 0, 22, /* length */ | ||
268 | 0, 0, 0, 101, /* TPM_ORD_GetCapability */ | ||
269 | 0, 0, 0, 5, | ||
270 | 0, 0, 0, 4, | ||
271 | 0, 0, 1, 3 | ||
272 | }; | ||
273 | |||
274 | ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, | 793 | ssize_t tpm_show_caps(struct device *dev, struct device_attribute *attr, |
275 | char *buf) | 794 | char *buf) |
276 | { | 795 | { |
277 | u8 data[sizeof(cap_manufacturer)]; | 796 | u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)]; |
278 | ssize_t len; | 797 | ssize_t rc; |
279 | char *str = buf; | 798 | char *str = buf; |
280 | 799 | ||
281 | struct tpm_chip *chip = dev_get_drvdata(dev); | 800 | struct tpm_chip *chip = dev_get_drvdata(dev); |
282 | if (chip == NULL) | 801 | if (chip == NULL) |
283 | return -ENODEV; | 802 | return -ENODEV; |
284 | 803 | ||
285 | memcpy(data, cap_manufacturer, sizeof(cap_manufacturer)); | 804 | memcpy(data, tpm_cap, sizeof(tpm_cap)); |
805 | data[TPM_CAP_IDX] = TPM_CAP_PROP; | ||
806 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER; | ||
286 | 807 | ||
287 | if ((len = tpm_transmit(chip, data, sizeof(data))) < | 808 | rc = transmit_cmd(chip, data, sizeof(data), |
288 | CAP_MANUFACTURER_RESULT_SIZE) | 809 | "attempting to determine the manufacturer"); |
289 | return len; | 810 | if (rc) |
811 | return 0; | ||
290 | 812 | ||
291 | str += sprintf(str, "Manufacturer: 0x%x\n", | 813 | str += sprintf(str, "Manufacturer: 0x%x\n", |
292 | be32_to_cpu(*((__be32 *) (data + 14)))); | 814 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)))); |
293 | 815 | ||
294 | memcpy(data, cap_version, sizeof(cap_version)); | 816 | memcpy(data, cap_version, sizeof(cap_version)); |
817 | data[CAP_VERSION_IDX] = CAP_VERSION_1_1; | ||
818 | rc = transmit_cmd(chip, data, sizeof(data), | ||
819 | "attempting to determine the 1.1 version"); | ||
820 | if (rc) | ||
821 | goto out; | ||
295 | 822 | ||
296 | if ((len = tpm_transmit(chip, data, sizeof(data))) < | 823 | str += sprintf(str, |
297 | CAP_VER_RESULT_SIZE) | 824 | "TCG version: %d.%d\nFirmware version: %d.%d\n", |
298 | return len; | 825 | (int) data[14], (int) data[15], (int) data[16], |
299 | 826 | (int) data[17]); | |
300 | str += | ||
301 | sprintf(str, "TCG version: %d.%d\nFirmware version: %d.%d\n", | ||
302 | (int) data[14], (int) data[15], (int) data[16], | ||
303 | (int) data[17]); | ||
304 | 827 | ||
828 | out: | ||
305 | return str - buf; | 829 | return str - buf; |
306 | } | 830 | } |
307 | EXPORT_SYMBOL_GPL(tpm_show_caps); | 831 | EXPORT_SYMBOL_GPL(tpm_show_caps); |
308 | 832 | ||
833 | ssize_t tpm_show_caps_1_2(struct device * dev, | ||
834 | struct device_attribute * attr, char *buf) | ||
835 | { | ||
836 | u8 data[max_t(int, max(ARRAY_SIZE(tpm_cap), ARRAY_SIZE(cap_version)), 30)]; | ||
837 | ssize_t len; | ||
838 | char *str = buf; | ||
839 | |||
840 | struct tpm_chip *chip = dev_get_drvdata(dev); | ||
841 | if (chip == NULL) | ||
842 | return -ENODEV; | ||
843 | |||
844 | memcpy(data, tpm_cap, sizeof(tpm_cap)); | ||
845 | data[TPM_CAP_IDX] = TPM_CAP_PROP; | ||
846 | data[TPM_CAP_SUBCAP_IDX] = TPM_CAP_PROP_MANUFACTURER; | ||
847 | |||
848 | if ((len = tpm_transmit(chip, data, sizeof(data))) <= | ||
849 | TPM_ERROR_SIZE) { | ||
850 | dev_dbg(chip->dev, "A TPM error (%d) occurred " | ||
851 | "attempting to determine the manufacturer\n", | ||
852 | be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)))); | ||
853 | return 0; | ||
854 | } | ||
855 | |||
856 | str += sprintf(str, "Manufacturer: 0x%x\n", | ||
857 | be32_to_cpu(*((__be32 *) (data + TPM_GET_CAP_RET_UINT32_1_IDX)))); | ||
858 | |||
859 | memcpy(data, cap_version, sizeof(cap_version)); | ||
860 | data[CAP_VERSION_IDX] = CAP_VERSION_1_2; | ||
861 | |||
862 | if ((len = tpm_transmit(chip, data, sizeof(data))) <= | ||
863 | TPM_ERROR_SIZE) { | ||
864 | dev_err(chip->dev, "A TPM error (%d) occurred " | ||
865 | "attempting to determine the 1.2 version\n", | ||
866 | be32_to_cpu(*((__be32 *) (data + TPM_RET_CODE_IDX)))); | ||
867 | goto out; | ||
868 | } | ||
869 | str += sprintf(str, | ||
870 | "TCG version: %d.%d\nFirmware version: %d.%d\n", | ||
871 | (int) data[16], (int) data[17], (int) data[18], | ||
872 | (int) data[19]); | ||
873 | |||
874 | out: | ||
875 | return str - buf; | ||
876 | } | ||
877 | EXPORT_SYMBOL_GPL(tpm_show_caps_1_2); | ||
878 | |||
309 | ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, | 879 | ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, |
310 | const char *buf, size_t count) | 880 | const char *buf, size_t count) |
311 | { | 881 | { |
@@ -313,7 +883,7 @@ ssize_t tpm_store_cancel(struct device *dev, struct device_attribute *attr, | |||
313 | if (chip == NULL) | 883 | if (chip == NULL) |
314 | return 0; | 884 | return 0; |
315 | 885 | ||
316 | chip->vendor->cancel(chip); | 886 | chip->vendor.cancel(chip); |
317 | return count; | 887 | return count; |
318 | } | 888 | } |
319 | EXPORT_SYMBOL_GPL(tpm_store_cancel); | 889 | EXPORT_SYMBOL_GPL(tpm_store_cancel); |
@@ -329,7 +899,7 @@ int tpm_open(struct inode *inode, struct file *file) | |||
329 | spin_lock(&driver_lock); | 899 | spin_lock(&driver_lock); |
330 | 900 | ||
331 | list_for_each_entry(pos, &tpm_chip_list, list) { | 901 | list_for_each_entry(pos, &tpm_chip_list, list) { |
332 | if (pos->vendor->miscdev.minor == minor) { | 902 | if (pos->vendor.miscdev.minor == minor) { |
333 | chip = pos; | 903 | chip = pos; |
334 | break; | 904 | break; |
335 | } | 905 | } |
@@ -387,7 +957,7 @@ int tpm_release(struct inode *inode, struct file *file) | |||
387 | EXPORT_SYMBOL_GPL(tpm_release); | 957 | EXPORT_SYMBOL_GPL(tpm_release); |
388 | 958 | ||
389 | ssize_t tpm_write(struct file *file, const char __user *buf, | 959 | ssize_t tpm_write(struct file *file, const char __user *buf, |
390 | size_t size, loff_t * off) | 960 | size_t size, loff_t *off) |
391 | { | 961 | { |
392 | struct tpm_chip *chip = file->private_data; | 962 | struct tpm_chip *chip = file->private_data; |
393 | int in_size = size, out_size; | 963 | int in_size = size, out_size; |
@@ -419,11 +989,10 @@ ssize_t tpm_write(struct file *file, const char __user *buf, | |||
419 | 989 | ||
420 | return in_size; | 990 | return in_size; |
421 | } | 991 | } |
422 | |||
423 | EXPORT_SYMBOL_GPL(tpm_write); | 992 | EXPORT_SYMBOL_GPL(tpm_write); |
424 | 993 | ||
425 | ssize_t tpm_read(struct file * file, char __user *buf, | 994 | ssize_t tpm_read(struct file *file, char __user *buf, |
426 | size_t size, loff_t * off) | 995 | size_t size, loff_t *off) |
427 | { | 996 | { |
428 | struct tpm_chip *chip = file->private_data; | 997 | struct tpm_chip *chip = file->private_data; |
429 | int ret_size; | 998 | int ret_size; |
@@ -462,14 +1031,13 @@ void tpm_remove_hardware(struct device *dev) | |||
462 | spin_unlock(&driver_lock); | 1031 | spin_unlock(&driver_lock); |
463 | 1032 | ||
464 | dev_set_drvdata(dev, NULL); | 1033 | dev_set_drvdata(dev, NULL); |
465 | misc_deregister(&chip->vendor->miscdev); | 1034 | misc_deregister(&chip->vendor.miscdev); |
466 | kfree(chip->vendor->miscdev.name); | 1035 | kfree(chip->vendor.miscdev.name); |
467 | 1036 | ||
468 | sysfs_remove_group(&dev->kobj, chip->vendor->attr_group); | 1037 | sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); |
469 | tpm_bios_log_teardown(chip->bios_dir); | 1038 | tpm_bios_log_teardown(chip->bios_dir); |
470 | 1039 | ||
471 | dev_mask[chip->dev_num / TPM_NUM_MASK_ENTRIES ] &= | 1040 | clear_bit(chip->dev_num, dev_mask); |
472 | ~(1 << (chip->dev_num % TPM_NUM_MASK_ENTRIES)); | ||
473 | 1041 | ||
474 | kfree(chip); | 1042 | kfree(chip); |
475 | 1043 | ||
@@ -520,18 +1088,18 @@ EXPORT_SYMBOL_GPL(tpm_pm_resume); | |||
520 | * upon errant exit from this function specific probe function should call | 1088 | * upon errant exit from this function specific probe function should call |
521 | * pci_disable_device | 1089 | * pci_disable_device |
522 | */ | 1090 | */ |
523 | int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry) | 1091 | struct tpm_chip *tpm_register_hardware(struct device *dev, const struct tpm_vendor_specific |
1092 | *entry) | ||
524 | { | 1093 | { |
525 | #define DEVNAME_SIZE 7 | 1094 | #define DEVNAME_SIZE 7 |
526 | 1095 | ||
527 | char *devname; | 1096 | char *devname; |
528 | struct tpm_chip *chip; | 1097 | struct tpm_chip *chip; |
529 | int i, j; | ||
530 | 1098 | ||
531 | /* Driver specific per-device data */ | 1099 | /* Driver specific per-device data */ |
532 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | 1100 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); |
533 | if (chip == NULL) | 1101 | if (chip == NULL) |
534 | return -ENOMEM; | 1102 | return NULL; |
535 | 1103 | ||
536 | init_MUTEX(&chip->buffer_mutex); | 1104 | init_MUTEX(&chip->buffer_mutex); |
537 | init_MUTEX(&chip->tpm_mutex); | 1105 | init_MUTEX(&chip->tpm_mutex); |
@@ -543,45 +1111,37 @@ int tpm_register_hardware(struct device *dev, struct tpm_vendor_specific *entry) | |||
543 | chip->user_read_timer.function = user_reader_timeout; | 1111 | chip->user_read_timer.function = user_reader_timeout; |
544 | chip->user_read_timer.data = (unsigned long) chip; | 1112 | chip->user_read_timer.data = (unsigned long) chip; |
545 | 1113 | ||
546 | chip->vendor = entry; | 1114 | memcpy(&chip->vendor, entry, sizeof(struct tpm_vendor_specific)); |
547 | |||
548 | chip->dev_num = -1; | ||
549 | 1115 | ||
550 | for (i = 0; i < TPM_NUM_MASK_ENTRIES; i++) | 1116 | chip->dev_num = find_first_zero_bit(dev_mask, TPM_NUM_DEVICES); |
551 | for (j = 0; j < 8 * sizeof(int); j++) | ||
552 | if ((dev_mask[i] & (1 << j)) == 0) { | ||
553 | chip->dev_num = | ||
554 | i * TPM_NUM_MASK_ENTRIES + j; | ||
555 | dev_mask[i] |= 1 << j; | ||
556 | goto dev_num_search_complete; | ||
557 | } | ||
558 | 1117 | ||
559 | dev_num_search_complete: | 1118 | if (chip->dev_num >= TPM_NUM_DEVICES) { |
560 | if (chip->dev_num < 0) { | ||
561 | dev_err(dev, "No available tpm device numbers\n"); | 1119 | dev_err(dev, "No available tpm device numbers\n"); |
562 | kfree(chip); | 1120 | kfree(chip); |
563 | return -ENODEV; | 1121 | return NULL; |
564 | } else if (chip->dev_num == 0) | 1122 | } else if (chip->dev_num == 0) |
565 | chip->vendor->miscdev.minor = TPM_MINOR; | 1123 | chip->vendor.miscdev.minor = TPM_MINOR; |
566 | else | 1124 | else |
567 | chip->vendor->miscdev.minor = MISC_DYNAMIC_MINOR; | 1125 | chip->vendor.miscdev.minor = MISC_DYNAMIC_MINOR; |
1126 | |||
1127 | set_bit(chip->dev_num, dev_mask); | ||
568 | 1128 | ||
569 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); | 1129 | devname = kmalloc(DEVNAME_SIZE, GFP_KERNEL); |
570 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); | 1130 | scnprintf(devname, DEVNAME_SIZE, "%s%d", "tpm", chip->dev_num); |
571 | chip->vendor->miscdev.name = devname; | 1131 | chip->vendor.miscdev.name = devname; |
572 | 1132 | ||
573 | chip->vendor->miscdev.dev = dev; | 1133 | chip->vendor.miscdev.dev = dev; |
574 | chip->dev = get_device(dev); | 1134 | chip->dev = get_device(dev); |
575 | 1135 | ||
576 | if (misc_register(&chip->vendor->miscdev)) { | 1136 | if (misc_register(&chip->vendor.miscdev)) { |
577 | dev_err(chip->dev, | 1137 | dev_err(chip->dev, |
578 | "unable to misc_register %s, minor %d\n", | 1138 | "unable to misc_register %s, minor %d\n", |
579 | chip->vendor->miscdev.name, | 1139 | chip->vendor.miscdev.name, |
580 | chip->vendor->miscdev.minor); | 1140 | chip->vendor.miscdev.minor); |
581 | put_device(dev); | 1141 | put_device(dev); |
1142 | clear_bit(chip->dev_num, dev_mask); | ||
582 | kfree(chip); | 1143 | kfree(chip); |
583 | dev_mask[i] &= !(1 << j); | 1144 | return NULL; |
584 | return -ENODEV; | ||
585 | } | 1145 | } |
586 | 1146 | ||
587 | spin_lock(&driver_lock); | 1147 | spin_lock(&driver_lock); |
@@ -592,11 +1152,11 @@ dev_num_search_complete: | |||
592 | 1152 | ||
593 | spin_unlock(&driver_lock); | 1153 | spin_unlock(&driver_lock); |
594 | 1154 | ||
595 | sysfs_create_group(&dev->kobj, chip->vendor->attr_group); | 1155 | sysfs_create_group(&dev->kobj, chip->vendor.attr_group); |
596 | 1156 | ||
597 | chip->bios_dir = tpm_bios_log_setup(devname); | 1157 | chip->bios_dir = tpm_bios_log_setup(devname); |
598 | 1158 | ||
599 | return 0; | 1159 | return chip; |
600 | } | 1160 | } |
601 | EXPORT_SYMBOL_GPL(tpm_register_hardware); | 1161 | EXPORT_SYMBOL_GPL(tpm_register_hardware); |
602 | 1162 | ||
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index dec0224b4478..54a4c804e25f 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h | |||
@@ -42,18 +42,30 @@ extern ssize_t tpm_show_pcrs(struct device *, struct device_attribute *attr, | |||
42 | char *); | 42 | char *); |
43 | extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, | 43 | extern ssize_t tpm_show_caps(struct device *, struct device_attribute *attr, |
44 | char *); | 44 | char *); |
45 | extern ssize_t tpm_show_caps_1_2(struct device *, struct device_attribute *attr, | ||
46 | char *); | ||
45 | extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, | 47 | extern ssize_t tpm_store_cancel(struct device *, struct device_attribute *attr, |
46 | const char *, size_t); | 48 | const char *, size_t); |
49 | extern ssize_t tpm_show_enabled(struct device *, struct device_attribute *attr, | ||
50 | char *); | ||
51 | extern ssize_t tpm_show_active(struct device *, struct device_attribute *attr, | ||
52 | char *); | ||
53 | extern ssize_t tpm_show_owned(struct device *, struct device_attribute *attr, | ||
54 | char *); | ||
55 | extern ssize_t tpm_show_temp_deactivated(struct device *, | ||
56 | struct device_attribute *attr, char *); | ||
47 | 57 | ||
48 | struct tpm_chip; | 58 | struct tpm_chip; |
49 | 59 | ||
50 | struct tpm_vendor_specific { | 60 | struct tpm_vendor_specific { |
51 | u8 req_complete_mask; | 61 | const u8 req_complete_mask; |
52 | u8 req_complete_val; | 62 | const u8 req_complete_val; |
53 | u8 req_canceled; | 63 | const u8 req_canceled; |
54 | void __iomem *iobase; /* ioremapped address */ | 64 | void __iomem *iobase; /* ioremapped address */ |
55 | unsigned long base; /* TPM base address */ | 65 | unsigned long base; /* TPM base address */ |
56 | 66 | ||
67 | int irq; | ||
68 | |||
57 | int region_size; | 69 | int region_size; |
58 | int have_region; | 70 | int have_region; |
59 | 71 | ||
@@ -63,6 +75,13 @@ struct tpm_vendor_specific { | |||
63 | u8 (*status) (struct tpm_chip *); | 75 | u8 (*status) (struct tpm_chip *); |
64 | struct miscdevice miscdev; | 76 | struct miscdevice miscdev; |
65 | struct attribute_group *attr_group; | 77 | struct attribute_group *attr_group; |
78 | struct list_head list; | ||
79 | int locality; | ||
80 | unsigned long timeout_a, timeout_b, timeout_c, timeout_d; /* jiffies */ | ||
81 | unsigned long duration[3]; /* jiffies */ | ||
82 | |||
83 | wait_queue_head_t read_queue; | ||
84 | wait_queue_head_t int_queue; | ||
66 | }; | 85 | }; |
67 | 86 | ||
68 | struct tpm_chip { | 87 | struct tpm_chip { |
@@ -81,13 +100,15 @@ struct tpm_chip { | |||
81 | struct work_struct work; | 100 | struct work_struct work; |
82 | struct semaphore tpm_mutex; /* tpm is processing */ | 101 | struct semaphore tpm_mutex; /* tpm is processing */ |
83 | 102 | ||
84 | struct tpm_vendor_specific *vendor; | 103 | struct tpm_vendor_specific vendor; |
85 | 104 | ||
86 | struct dentry **bios_dir; | 105 | struct dentry **bios_dir; |
87 | 106 | ||
88 | struct list_head list; | 107 | struct list_head list; |
89 | }; | 108 | }; |
90 | 109 | ||
110 | #define to_tpm_chip(n) container_of(n, struct tpm_chip, vendor) | ||
111 | |||
91 | static inline int tpm_read_index(int base, int index) | 112 | static inline int tpm_read_index(int base, int index) |
92 | { | 113 | { |
93 | outb(index, base); | 114 | outb(index, base); |
@@ -100,8 +121,12 @@ static inline void tpm_write_index(int base, int index, int value) | |||
100 | outb(value & 0xFF, base+1); | 121 | outb(value & 0xFF, base+1); |
101 | } | 122 | } |
102 | 123 | ||
103 | extern int tpm_register_hardware(struct device *, | 124 | extern void tpm_get_timeouts(struct tpm_chip *); |
104 | struct tpm_vendor_specific *); | 125 | extern void tpm_gen_interrupt(struct tpm_chip *); |
126 | extern void tpm_continue_selftest(struct tpm_chip *); | ||
127 | extern unsigned long tpm_calc_ordinal_duration(struct tpm_chip *, u32); | ||
128 | extern struct tpm_chip* tpm_register_hardware(struct device *, | ||
129 | const struct tpm_vendor_specific *); | ||
105 | extern int tpm_open(struct inode *, struct file *); | 130 | extern int tpm_open(struct inode *, struct file *); |
106 | extern int tpm_release(struct inode *, struct file *); | 131 | extern int tpm_release(struct inode *, struct file *); |
107 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, | 132 | extern ssize_t tpm_write(struct file *, const char __user *, size_t, |
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c index ff3654964fe3..58a258cec153 100644 --- a/drivers/char/tpm/tpm_atmel.c +++ b/drivers/char/tpm/tpm_atmel.c | |||
@@ -47,12 +47,12 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
47 | return -EIO; | 47 | return -EIO; |
48 | 48 | ||
49 | for (i = 0; i < 6; i++) { | 49 | for (i = 0; i < 6; i++) { |
50 | status = ioread8(chip->vendor->iobase + 1); | 50 | status = ioread8(chip->vendor.iobase + 1); |
51 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 51 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
52 | dev_err(chip->dev, "error reading header\n"); | 52 | dev_err(chip->dev, "error reading header\n"); |
53 | return -EIO; | 53 | return -EIO; |
54 | } | 54 | } |
55 | *buf++ = ioread8(chip->vendor->iobase); | 55 | *buf++ = ioread8(chip->vendor.iobase); |
56 | } | 56 | } |
57 | 57 | ||
58 | /* size of the data received */ | 58 | /* size of the data received */ |
@@ -63,7 +63,7 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
63 | dev_err(chip->dev, | 63 | dev_err(chip->dev, |
64 | "Recv size(%d) less than available space\n", size); | 64 | "Recv size(%d) less than available space\n", size); |
65 | for (; i < size; i++) { /* clear the waiting data anyway */ | 65 | for (; i < size; i++) { /* clear the waiting data anyway */ |
66 | status = ioread8(chip->vendor->iobase + 1); | 66 | status = ioread8(chip->vendor.iobase + 1); |
67 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 67 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
68 | dev_err(chip->dev, "error reading data\n"); | 68 | dev_err(chip->dev, "error reading data\n"); |
69 | return -EIO; | 69 | return -EIO; |
@@ -74,16 +74,16 @@ static int tpm_atml_recv(struct tpm_chip *chip, u8 *buf, size_t count) | |||
74 | 74 | ||
75 | /* read all the data available */ | 75 | /* read all the data available */ |
76 | for (; i < size; i++) { | 76 | for (; i < size; i++) { |
77 | status = ioread8(chip->vendor->iobase + 1); | 77 | status = ioread8(chip->vendor.iobase + 1); |
78 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { | 78 | if ((status & ATML_STATUS_DATA_AVAIL) == 0) { |
79 | dev_err(chip->dev, "error reading data\n"); | 79 | dev_err(chip->dev, "error reading data\n"); |
80 | return -EIO; | 80 | return -EIO; |
81 | } | 81 | } |
82 | *buf++ = ioread8(chip->vendor->iobase); | 82 | *buf++ = ioread8(chip->vendor.iobase); |
83 | } | 83 | } |
84 | 84 | ||
85 | /* make sure data available is gone */ | 85 | /* make sure data available is gone */ |
86 | status = ioread8(chip->vendor->iobase + 1); | 86 | status = ioread8(chip->vendor.iobase + 1); |
87 | 87 | ||
88 | if (status & ATML_STATUS_DATA_AVAIL) { | 88 | if (status & ATML_STATUS_DATA_AVAIL) { |
89 | dev_err(chip->dev, "data available is stuck\n"); | 89 | dev_err(chip->dev, "data available is stuck\n"); |
@@ -100,7 +100,7 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count) | |||
100 | dev_dbg(chip->dev, "tpm_atml_send:\n"); | 100 | dev_dbg(chip->dev, "tpm_atml_send:\n"); |
101 | for (i = 0; i < count; i++) { | 101 | for (i = 0; i < count; i++) { |
102 | dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]); | 102 | dev_dbg(chip->dev, "%d 0x%x(%d)\n", i, buf[i], buf[i]); |
103 | iowrite8(buf[i], chip->vendor->iobase); | 103 | iowrite8(buf[i], chip->vendor.iobase); |
104 | } | 104 | } |
105 | 105 | ||
106 | return count; | 106 | return count; |
@@ -108,12 +108,12 @@ static int tpm_atml_send(struct tpm_chip *chip, u8 *buf, size_t count) | |||
108 | 108 | ||
109 | static void tpm_atml_cancel(struct tpm_chip *chip) | 109 | static void tpm_atml_cancel(struct tpm_chip *chip) |
110 | { | 110 | { |
111 | iowrite8(ATML_STATUS_ABORT, chip->vendor->iobase + 1); | 111 | iowrite8(ATML_STATUS_ABORT, chip->vendor.iobase + 1); |
112 | } | 112 | } |
113 | 113 | ||
114 | static u8 tpm_atml_status(struct tpm_chip *chip) | 114 | static u8 tpm_atml_status(struct tpm_chip *chip) |
115 | { | 115 | { |
116 | return ioread8(chip->vendor->iobase + 1); | 116 | return ioread8(chip->vendor.iobase + 1); |
117 | } | 117 | } |
118 | 118 | ||
119 | static struct file_operations atmel_ops = { | 119 | static struct file_operations atmel_ops = { |
@@ -140,7 +140,7 @@ static struct attribute* atmel_attrs[] = { | |||
140 | 140 | ||
141 | static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs }; | 141 | static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs }; |
142 | 142 | ||
143 | static struct tpm_vendor_specific tpm_atmel = { | 143 | static const struct tpm_vendor_specific tpm_atmel = { |
144 | .recv = tpm_atml_recv, | 144 | .recv = tpm_atml_recv, |
145 | .send = tpm_atml_send, | 145 | .send = tpm_atml_send, |
146 | .cancel = tpm_atml_cancel, | 146 | .cancel = tpm_atml_cancel, |
@@ -159,10 +159,10 @@ static void atml_plat_remove(void) | |||
159 | struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); | 159 | struct tpm_chip *chip = dev_get_drvdata(&pdev->dev); |
160 | 160 | ||
161 | if (chip) { | 161 | if (chip) { |
162 | if (chip->vendor->have_region) | 162 | if (chip->vendor.have_region) |
163 | atmel_release_region(chip->vendor->base, | 163 | atmel_release_region(chip->vendor.base, |
164 | chip->vendor->region_size); | 164 | chip->vendor.region_size); |
165 | atmel_put_base_addr(chip->vendor); | 165 | atmel_put_base_addr(chip->vendor.iobase); |
166 | tpm_remove_hardware(chip->dev); | 166 | tpm_remove_hardware(chip->dev); |
167 | platform_device_unregister(pdev); | 167 | platform_device_unregister(pdev); |
168 | } | 168 | } |
@@ -179,18 +179,22 @@ static struct device_driver atml_drv = { | |||
179 | static int __init init_atmel(void) | 179 | static int __init init_atmel(void) |
180 | { | 180 | { |
181 | int rc = 0; | 181 | int rc = 0; |
182 | void __iomem *iobase = NULL; | ||
183 | int have_region, region_size; | ||
184 | unsigned long base; | ||
185 | struct tpm_chip *chip; | ||
182 | 186 | ||
183 | driver_register(&atml_drv); | 187 | driver_register(&atml_drv); |
184 | 188 | ||
185 | if ((tpm_atmel.iobase = atmel_get_base_addr(&tpm_atmel)) == NULL) { | 189 | if ((iobase = atmel_get_base_addr(&base, ®ion_size)) == NULL) { |
186 | rc = -ENODEV; | 190 | rc = -ENODEV; |
187 | goto err_unreg_drv; | 191 | goto err_unreg_drv; |
188 | } | 192 | } |
189 | 193 | ||
190 | tpm_atmel.have_region = | 194 | have_region = |
191 | (atmel_request_region | 195 | (atmel_request_region |
192 | (tpm_atmel.base, tpm_atmel.region_size, | 196 | (tpm_atmel.base, region_size, "tpm_atmel0") == NULL) ? 0 : 1; |
193 | "tpm_atmel0") == NULL) ? 0 : 1; | 197 | |
194 | 198 | ||
195 | if (IS_ERR | 199 | if (IS_ERR |
196 | (pdev = | 200 | (pdev = |
@@ -199,17 +203,25 @@ static int __init init_atmel(void) | |||
199 | goto err_rel_reg; | 203 | goto err_rel_reg; |
200 | } | 204 | } |
201 | 205 | ||
202 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_atmel)) < 0) | 206 | if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_atmel))) { |
207 | rc = -ENODEV; | ||
203 | goto err_unreg_dev; | 208 | goto err_unreg_dev; |
209 | } | ||
210 | |||
211 | chip->vendor.iobase = iobase; | ||
212 | chip->vendor.base = base; | ||
213 | chip->vendor.have_region = have_region; | ||
214 | chip->vendor.region_size = region_size; | ||
215 | |||
204 | return 0; | 216 | return 0; |
205 | 217 | ||
206 | err_unreg_dev: | 218 | err_unreg_dev: |
207 | platform_device_unregister(pdev); | 219 | platform_device_unregister(pdev); |
208 | err_rel_reg: | 220 | err_rel_reg: |
209 | atmel_put_base_addr(&tpm_atmel); | 221 | atmel_put_base_addr(iobase); |
210 | if (tpm_atmel.have_region) | 222 | if (have_region) |
211 | atmel_release_region(tpm_atmel.base, | 223 | atmel_release_region(base, |
212 | tpm_atmel.region_size); | 224 | region_size); |
213 | err_unreg_drv: | 225 | err_unreg_drv: |
214 | driver_unregister(&atml_drv); | 226 | driver_unregister(&atml_drv); |
215 | return rc; | 227 | return rc; |
diff --git a/drivers/char/tpm/tpm_atmel.h b/drivers/char/tpm/tpm_atmel.h index d3478aaadd77..2e68eeb8a2cd 100644 --- a/drivers/char/tpm/tpm_atmel.h +++ b/drivers/char/tpm/tpm_atmel.h | |||
@@ -28,13 +28,12 @@ | |||
28 | #define atmel_request_region request_mem_region | 28 | #define atmel_request_region request_mem_region |
29 | #define atmel_release_region release_mem_region | 29 | #define atmel_release_region release_mem_region |
30 | 30 | ||
31 | static inline void atmel_put_base_addr(struct tpm_vendor_specific | 31 | static inline void atmel_put_base_addr(void __iomem *iobase) |
32 | *vendor) | ||
33 | { | 32 | { |
34 | iounmap(vendor->iobase); | 33 | iounmap(iobase); |
35 | } | 34 | } |
36 | 35 | ||
37 | static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor) | 36 | static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size) |
38 | { | 37 | { |
39 | struct device_node *dn; | 38 | struct device_node *dn; |
40 | unsigned long address, size; | 39 | unsigned long address, size; |
@@ -71,9 +70,9 @@ static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific *vendor) | |||
71 | else | 70 | else |
72 | size = reg[naddrc]; | 71 | size = reg[naddrc]; |
73 | 72 | ||
74 | vendor->base = address; | 73 | *base = address; |
75 | vendor->region_size = size; | 74 | *region_size = size; |
76 | return ioremap(vendor->base, vendor->region_size); | 75 | return ioremap(*base, *region_size); |
77 | } | 76 | } |
78 | #else | 77 | #else |
79 | #define atmel_getb(chip, offset) inb(chip->vendor->base + offset) | 78 | #define atmel_getb(chip, offset) inb(chip->vendor->base + offset) |
@@ -106,14 +105,12 @@ static int atmel_verify_tpm11(void) | |||
106 | return 0; | 105 | return 0; |
107 | } | 106 | } |
108 | 107 | ||
109 | static inline void atmel_put_base_addr(struct tpm_vendor_specific | 108 | static inline void atmel_put_base_addr(void __iomem *iobase) |
110 | *vendor) | ||
111 | { | 109 | { |
112 | } | 110 | } |
113 | 111 | ||
114 | /* Determine where to talk to device */ | 112 | /* Determine where to talk to device */ |
115 | static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific | 113 | static void __iomem * atmel_get_base_addr(unsigned long *base, int *region_size) |
116 | *vendor) | ||
117 | { | 114 | { |
118 | int lo, hi; | 115 | int lo, hi; |
119 | 116 | ||
@@ -123,9 +120,9 @@ static void __iomem * atmel_get_base_addr(struct tpm_vendor_specific | |||
123 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); | 120 | lo = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_LO); |
124 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); | 121 | hi = tpm_read_index(TPM_ADDR, TPM_ATMEL_BASE_ADDR_HI); |
125 | 122 | ||
126 | vendor->base = (hi << 8) | lo; | 123 | *base = (hi << 8) | lo; |
127 | vendor->region_size = 2; | 124 | *region_size = 2; |
128 | 125 | ||
129 | return ioport_map(vendor->base, vendor->region_size); | 126 | return ioport_map(*base, *region_size); |
130 | } | 127 | } |
131 | #endif | 128 | #endif |
diff --git a/drivers/char/tpm/tpm_bios.c b/drivers/char/tpm/tpm_bios.c index 537aa45d8c67..e45f0d3d12de 100644 --- a/drivers/char/tpm/tpm_bios.c +++ b/drivers/char/tpm/tpm_bios.c | |||
@@ -29,6 +29,11 @@ | |||
29 | #define MAX_TEXT_EVENT 1000 /* Max event string length */ | 29 | #define MAX_TEXT_EVENT 1000 /* Max event string length */ |
30 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ | 30 | #define ACPI_TCPA_SIG "TCPA" /* 0x41504354 /'TCPA' */ |
31 | 31 | ||
32 | enum bios_platform_class { | ||
33 | BIOS_CLIENT = 0x00, | ||
34 | BIOS_SERVER = 0x01, | ||
35 | }; | ||
36 | |||
32 | struct tpm_bios_log { | 37 | struct tpm_bios_log { |
33 | void *bios_event_log; | 38 | void *bios_event_log; |
34 | void *bios_event_log_end; | 39 | void *bios_event_log_end; |
@@ -36,9 +41,18 @@ struct tpm_bios_log { | |||
36 | 41 | ||
37 | struct acpi_tcpa { | 42 | struct acpi_tcpa { |
38 | struct acpi_table_header hdr; | 43 | struct acpi_table_header hdr; |
39 | u16 reserved; | 44 | u16 platform_class; |
40 | u32 log_max_len __attribute__ ((packed)); | 45 | union { |
41 | u32 log_start_addr __attribute__ ((packed)); | 46 | struct client_hdr { |
47 | u32 log_max_len __attribute__ ((packed)); | ||
48 | u64 log_start_addr __attribute__ ((packed)); | ||
49 | } client; | ||
50 | struct server_hdr { | ||
51 | u16 reserved; | ||
52 | u64 log_max_len __attribute__ ((packed)); | ||
53 | u64 log_start_addr __attribute__ ((packed)); | ||
54 | } server; | ||
55 | }; | ||
42 | }; | 56 | }; |
43 | 57 | ||
44 | struct tcpa_event { | 58 | struct tcpa_event { |
@@ -120,6 +134,7 @@ static const char* tcpa_pc_event_id_strings[] = { | |||
120 | "S-CRTM Version", | 134 | "S-CRTM Version", |
121 | "S-CRTM Contents", | 135 | "S-CRTM Contents", |
122 | "S-CRTM POST Contents", | 136 | "S-CRTM POST Contents", |
137 | "POST Contents", | ||
123 | }; | 138 | }; |
124 | 139 | ||
125 | /* returns pointer to start of pos. entry of tcg log */ | 140 | /* returns pointer to start of pos. entry of tcg log */ |
@@ -306,6 +321,7 @@ static int tpm_binary_bios_measurements_show(struct seq_file *m, void *v) | |||
306 | /* 5th: delimiter */ | 321 | /* 5th: delimiter */ |
307 | seq_putc(m, '\0'); | 322 | seq_putc(m, '\0'); |
308 | 323 | ||
324 | kfree(eventname); | ||
309 | return 0; | 325 | return 0; |
310 | } | 326 | } |
311 | 327 | ||
@@ -353,6 +369,7 @@ static int tpm_ascii_bios_measurements_show(struct seq_file *m, void *v) | |||
353 | /* 4th: eventname <= max + \'0' delimiter */ | 369 | /* 4th: eventname <= max + \'0' delimiter */ |
354 | seq_printf(m, " %s\n", eventname); | 370 | seq_printf(m, " %s\n", eventname); |
355 | 371 | ||
372 | kfree(eventname); | ||
356 | return 0; | 373 | return 0; |
357 | } | 374 | } |
358 | 375 | ||
@@ -376,6 +393,7 @@ static int read_log(struct tpm_bios_log *log) | |||
376 | struct acpi_tcpa *buff; | 393 | struct acpi_tcpa *buff; |
377 | acpi_status status; | 394 | acpi_status status; |
378 | struct acpi_table_header *virt; | 395 | struct acpi_table_header *virt; |
396 | u64 len, start; | ||
379 | 397 | ||
380 | if (log->bios_event_log != NULL) { | 398 | if (log->bios_event_log != NULL) { |
381 | printk(KERN_ERR | 399 | printk(KERN_ERR |
@@ -396,27 +414,37 @@ static int read_log(struct tpm_bios_log *log) | |||
396 | return -EIO; | 414 | return -EIO; |
397 | } | 415 | } |
398 | 416 | ||
399 | if (buff->log_max_len == 0) { | 417 | switch(buff->platform_class) { |
418 | case BIOS_SERVER: | ||
419 | len = buff->server.log_max_len; | ||
420 | start = buff->server.log_start_addr; | ||
421 | break; | ||
422 | case BIOS_CLIENT: | ||
423 | default: | ||
424 | len = buff->client.log_max_len; | ||
425 | start = buff->client.log_start_addr; | ||
426 | break; | ||
427 | } | ||
428 | if (!len) { | ||
400 | printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); | 429 | printk(KERN_ERR "%s: ERROR - TCPA log area empty\n", __func__); |
401 | return -EIO; | 430 | return -EIO; |
402 | } | 431 | } |
403 | 432 | ||
404 | /* malloc EventLog space */ | 433 | /* malloc EventLog space */ |
405 | log->bios_event_log = kmalloc(buff->log_max_len, GFP_KERNEL); | 434 | log->bios_event_log = kmalloc(len, GFP_KERNEL); |
406 | if (!log->bios_event_log) { | 435 | if (!log->bios_event_log) { |
407 | printk | 436 | printk("%s: ERROR - Not enough Memory for BIOS measurements\n", |
408 | ("%s: ERROR - Not enough Memory for BIOS measurements\n", | 437 | __func__); |
409 | __func__); | ||
410 | return -ENOMEM; | 438 | return -ENOMEM; |
411 | } | 439 | } |
412 | 440 | ||
413 | log->bios_event_log_end = log->bios_event_log + buff->log_max_len; | 441 | log->bios_event_log_end = log->bios_event_log + len; |
414 | 442 | ||
415 | acpi_os_map_memory(buff->log_start_addr, buff->log_max_len, (void *) &virt); | 443 | acpi_os_map_memory(start, len, (void *) &virt); |
416 | 444 | ||
417 | memcpy(log->bios_event_log, virt, buff->log_max_len); | 445 | memcpy(log->bios_event_log, virt, len); |
418 | 446 | ||
419 | acpi_os_unmap_memory(virt, buff->log_max_len); | 447 | acpi_os_unmap_memory(virt, len); |
420 | return 0; | 448 | return 0; |
421 | } | 449 | } |
422 | 450 | ||
diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 24095f6ee6da..adfff21beb21 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c | |||
@@ -15,6 +15,7 @@ | |||
15 | * License. | 15 | * License. |
16 | */ | 16 | */ |
17 | 17 | ||
18 | #include <linux/init.h> | ||
18 | #include <linux/pnp.h> | 19 | #include <linux/pnp.h> |
19 | #include "tpm.h" | 20 | #include "tpm.h" |
20 | 21 | ||
@@ -104,7 +105,7 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) | |||
104 | 105 | ||
105 | if (clear_wrfifo) { | 106 | if (clear_wrfifo) { |
106 | for (i = 0; i < 4096; i++) { | 107 | for (i = 0; i < 4096; i++) { |
107 | status = inb(chip->vendor->base + WRFIFO); | 108 | status = inb(chip->vendor.base + WRFIFO); |
108 | if (status == 0xff) { | 109 | if (status == 0xff) { |
109 | if (check == 5) | 110 | if (check == 5) |
110 | break; | 111 | break; |
@@ -124,8 +125,8 @@ static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo) | |||
124 | */ | 125 | */ |
125 | i = 0; | 126 | i = 0; |
126 | do { | 127 | do { |
127 | status = inb(chip->vendor->base + RDFIFO); | 128 | status = inb(chip->vendor.base + RDFIFO); |
128 | status = inb(chip->vendor->base + STAT); | 129 | status = inb(chip->vendor.base + STAT); |
129 | i++; | 130 | i++; |
130 | if (i == TPM_MAX_TRIES) | 131 | if (i == TPM_MAX_TRIES) |
131 | return -EIO; | 132 | return -EIO; |
@@ -138,7 +139,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
138 | int status; | 139 | int status; |
139 | int i; | 140 | int i; |
140 | for (i = 0; i < TPM_MAX_TRIES; i++) { | 141 | for (i = 0; i < TPM_MAX_TRIES; i++) { |
141 | status = inb(chip->vendor->base + STAT); | 142 | status = inb(chip->vendor.base + STAT); |
142 | /* check the status-register if wait_for_bit is set */ | 143 | /* check the status-register if wait_for_bit is set */ |
143 | if (status & 1 << wait_for_bit) | 144 | if (status & 1 << wait_for_bit) |
144 | break; | 145 | break; |
@@ -157,7 +158,7 @@ static int wait(struct tpm_chip *chip, int wait_for_bit) | |||
157 | static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) | 158 | static void wait_and_send(struct tpm_chip *chip, u8 sendbyte) |
158 | { | 159 | { |
159 | wait(chip, STAT_XFE); | 160 | wait(chip, STAT_XFE); |
160 | outb(sendbyte, chip->vendor->base + WRFIFO); | 161 | outb(sendbyte, chip->vendor.base + WRFIFO); |
161 | } | 162 | } |
162 | 163 | ||
163 | /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more | 164 | /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more |
@@ -204,7 +205,7 @@ recv_begin: | |||
204 | ret = wait(chip, STAT_RDA); | 205 | ret = wait(chip, STAT_RDA); |
205 | if (ret) | 206 | if (ret) |
206 | return -EIO; | 207 | return -EIO; |
207 | buf[i] = inb(chip->vendor->base + RDFIFO); | 208 | buf[i] = inb(chip->vendor.base + RDFIFO); |
208 | } | 209 | } |
209 | 210 | ||
210 | if (buf[0] != TPM_VL_VER) { | 211 | if (buf[0] != TPM_VL_VER) { |
@@ -219,7 +220,7 @@ recv_begin: | |||
219 | 220 | ||
220 | for (i = 0; i < size; i++) { | 221 | for (i = 0; i < size; i++) { |
221 | wait(chip, STAT_RDA); | 222 | wait(chip, STAT_RDA); |
222 | buf[i] = inb(chip->vendor->base + RDFIFO); | 223 | buf[i] = inb(chip->vendor.base + RDFIFO); |
223 | } | 224 | } |
224 | 225 | ||
225 | if ((size == 0x6D00) && (buf[1] == 0x80)) { | 226 | if ((size == 0x6D00) && (buf[1] == 0x80)) { |
@@ -268,7 +269,7 @@ static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
268 | u8 count_high, count_low, count_4, count_3, count_2, count_1; | 269 | u8 count_high, count_low, count_4, count_3, count_2, count_1; |
269 | 270 | ||
270 | /* Disabling Reset, LP and IRQC */ | 271 | /* Disabling Reset, LP and IRQC */ |
271 | outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD); | 272 | outb(RESET_LP_IRQC_DISABLE, chip->vendor.base + CMD); |
272 | 273 | ||
273 | ret = empty_fifo(chip, 1); | 274 | ret = empty_fifo(chip, 1); |
274 | if (ret) { | 275 | if (ret) { |
@@ -319,7 +320,7 @@ static void tpm_inf_cancel(struct tpm_chip *chip) | |||
319 | 320 | ||
320 | static u8 tpm_inf_status(struct tpm_chip *chip) | 321 | static u8 tpm_inf_status(struct tpm_chip *chip) |
321 | { | 322 | { |
322 | return inb(chip->vendor->base + STAT); | 323 | return inb(chip->vendor.base + STAT); |
323 | } | 324 | } |
324 | 325 | ||
325 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | 326 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); |
@@ -346,7 +347,7 @@ static struct file_operations inf_ops = { | |||
346 | .release = tpm_release, | 347 | .release = tpm_release, |
347 | }; | 348 | }; |
348 | 349 | ||
349 | static struct tpm_vendor_specific tpm_inf = { | 350 | static const struct tpm_vendor_specific tpm_inf = { |
350 | .recv = tpm_inf_recv, | 351 | .recv = tpm_inf_recv, |
351 | .send = tpm_inf_send, | 352 | .send = tpm_inf_send, |
352 | .cancel = tpm_inf_cancel, | 353 | .cancel = tpm_inf_cancel, |
@@ -375,6 +376,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
375 | int version[2]; | 376 | int version[2]; |
376 | int productid[2]; | 377 | int productid[2]; |
377 | char chipname[20]; | 378 | char chipname[20]; |
379 | struct tpm_chip *chip; | ||
378 | 380 | ||
379 | /* read IO-ports through PnP */ | 381 | /* read IO-ports through PnP */ |
380 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && | 382 | if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) && |
@@ -395,14 +397,13 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
395 | goto err_last; | 397 | goto err_last; |
396 | } | 398 | } |
397 | /* publish my base address and request region */ | 399 | /* publish my base address and request region */ |
398 | tpm_inf.base = TPM_INF_BASE; | ||
399 | if (request_region | 400 | if (request_region |
400 | (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { | 401 | (TPM_INF_BASE, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) { |
401 | rc = -EINVAL; | 402 | rc = -EINVAL; |
402 | goto err_last; | 403 | goto err_last; |
403 | } | 404 | } |
404 | if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN, | 405 | if (request_region |
405 | "tpm_infineon0") == NULL) { | 406 | (TPM_INF_ADDR, TPM_INF_ADDR_LEN, "tpm_infineon0") == NULL) { |
406 | rc = -EINVAL; | 407 | rc = -EINVAL; |
407 | goto err_last; | 408 | goto err_last; |
408 | } | 409 | } |
@@ -442,9 +443,9 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
442 | 443 | ||
443 | /* configure TPM with IO-ports */ | 444 | /* configure TPM with IO-ports */ |
444 | outb(IOLIMH, TPM_INF_ADDR); | 445 | outb(IOLIMH, TPM_INF_ADDR); |
445 | outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA); | 446 | outb(((TPM_INF_BASE >> 8) & 0xff), TPM_INF_DATA); |
446 | outb(IOLIML, TPM_INF_ADDR); | 447 | outb(IOLIML, TPM_INF_ADDR); |
447 | outb((tpm_inf.base & 0xff), TPM_INF_DATA); | 448 | outb((TPM_INF_BASE & 0xff), TPM_INF_DATA); |
448 | 449 | ||
449 | /* control if IO-ports are set correctly */ | 450 | /* control if IO-ports are set correctly */ |
450 | outb(IOLIMH, TPM_INF_ADDR); | 451 | outb(IOLIMH, TPM_INF_ADDR); |
@@ -452,10 +453,10 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
452 | outb(IOLIML, TPM_INF_ADDR); | 453 | outb(IOLIML, TPM_INF_ADDR); |
453 | iol = inb(TPM_INF_DATA); | 454 | iol = inb(TPM_INF_DATA); |
454 | 455 | ||
455 | if ((ioh << 8 | iol) != tpm_inf.base) { | 456 | if ((ioh << 8 | iol) != TPM_INF_BASE) { |
456 | dev_err(&dev->dev, | 457 | dev_err(&dev->dev, |
457 | "Could not set IO-ports to 0x%lx\n", | 458 | "Could not set IO-ports to 0x%x\n", |
458 | tpm_inf.base); | 459 | TPM_INF_BASE); |
459 | rc = -EIO; | 460 | rc = -EIO; |
460 | goto err_release_region; | 461 | goto err_release_region; |
461 | } | 462 | } |
@@ -466,15 +467,15 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
466 | outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); | 467 | outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR); |
467 | 468 | ||
468 | /* disable RESET, LP and IRQC */ | 469 | /* disable RESET, LP and IRQC */ |
469 | outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD); | 470 | outb(RESET_LP_IRQC_DISABLE, TPM_INF_BASE + CMD); |
470 | 471 | ||
471 | /* Finally, we're done, print some infos */ | 472 | /* Finally, we're done, print some infos */ |
472 | dev_info(&dev->dev, "TPM found: " | 473 | dev_info(&dev->dev, "TPM found: " |
473 | "config base 0x%x, " | 474 | "config base 0x%x, " |
474 | "io base 0x%x, " | 475 | "io base 0x%x, " |
475 | "chip version %02x%02x, " | 476 | "chip version 0x%02x%02x, " |
476 | "vendor id %x%x (Infineon), " | 477 | "vendor id 0x%x%x (Infineon), " |
477 | "product id %02x%02x" | 478 | "product id 0x%02x%02x" |
478 | "%s\n", | 479 | "%s\n", |
479 | TPM_INF_ADDR, | 480 | TPM_INF_ADDR, |
480 | TPM_INF_BASE, | 481 | TPM_INF_BASE, |
@@ -482,11 +483,10 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
482 | vendorid[0], vendorid[1], | 483 | vendorid[0], vendorid[1], |
483 | productid[0], productid[1], chipname); | 484 | productid[0], productid[1], chipname); |
484 | 485 | ||
485 | rc = tpm_register_hardware(&dev->dev, &tpm_inf); | 486 | if (!(chip = tpm_register_hardware(&dev->dev, &tpm_inf))) { |
486 | if (rc < 0) { | ||
487 | rc = -ENODEV; | ||
488 | goto err_release_region; | 487 | goto err_release_region; |
489 | } | 488 | } |
489 | chip->vendor.base = TPM_INF_BASE; | ||
490 | return 0; | 490 | return 0; |
491 | } else { | 491 | } else { |
492 | rc = -ENODEV; | 492 | rc = -ENODEV; |
@@ -494,7 +494,7 @@ static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, | |||
494 | } | 494 | } |
495 | 495 | ||
496 | err_release_region: | 496 | err_release_region: |
497 | release_region(tpm_inf.base, TPM_INF_PORT_LEN); | 497 | release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); |
498 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | 498 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); |
499 | 499 | ||
500 | err_last: | 500 | err_last: |
@@ -506,7 +506,8 @@ static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) | |||
506 | struct tpm_chip *chip = pnp_get_drvdata(dev); | 506 | struct tpm_chip *chip = pnp_get_drvdata(dev); |
507 | 507 | ||
508 | if (chip) { | 508 | if (chip) { |
509 | release_region(chip->vendor->base, TPM_INF_PORT_LEN); | 509 | release_region(TPM_INF_BASE, TPM_INF_PORT_LEN); |
510 | release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN); | ||
510 | tpm_remove_hardware(chip->dev); | 511 | tpm_remove_hardware(chip->dev); |
511 | } | 512 | } |
512 | } | 513 | } |
@@ -520,7 +521,7 @@ static struct pnp_driver tpm_inf_pnp = { | |||
520 | }, | 521 | }, |
521 | .id_table = tpm_pnp_tbl, | 522 | .id_table = tpm_pnp_tbl, |
522 | .probe = tpm_inf_pnp_probe, | 523 | .probe = tpm_inf_pnp_probe, |
523 | .remove = tpm_inf_pnp_remove, | 524 | .remove = __devexit_p(tpm_inf_pnp_remove), |
524 | }; | 525 | }; |
525 | 526 | ||
526 | static int __init init_inf(void) | 527 | static int __init init_inf(void) |
@@ -538,5 +539,5 @@ module_exit(cleanup_inf); | |||
538 | 539 | ||
539 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); | 540 | MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>"); |
540 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); | 541 | MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2"); |
541 | MODULE_VERSION("1.7"); | 542 | MODULE_VERSION("1.8"); |
542 | MODULE_LICENSE("GPL"); | 543 | MODULE_LICENSE("GPL"); |
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c index 680a8e331887..4c8bc06c7d95 100644 --- a/drivers/char/tpm/tpm_nsc.c +++ b/drivers/char/tpm/tpm_nsc.c | |||
@@ -71,7 +71,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) | |||
71 | unsigned long stop; | 71 | unsigned long stop; |
72 | 72 | ||
73 | /* status immediately available check */ | 73 | /* status immediately available check */ |
74 | *data = inb(chip->vendor->base + NSC_STATUS); | 74 | *data = inb(chip->vendor.base + NSC_STATUS); |
75 | if ((*data & mask) == val) | 75 | if ((*data & mask) == val) |
76 | return 0; | 76 | return 0; |
77 | 77 | ||
@@ -79,7 +79,7 @@ static int wait_for_stat(struct tpm_chip *chip, u8 mask, u8 val, u8 * data) | |||
79 | stop = jiffies + 10 * HZ; | 79 | stop = jiffies + 10 * HZ; |
80 | do { | 80 | do { |
81 | msleep(TPM_TIMEOUT); | 81 | msleep(TPM_TIMEOUT); |
82 | *data = inb(chip->vendor->base + 1); | 82 | *data = inb(chip->vendor.base + 1); |
83 | if ((*data & mask) == val) | 83 | if ((*data & mask) == val) |
84 | return 0; | 84 | return 0; |
85 | } | 85 | } |
@@ -94,9 +94,9 @@ static int nsc_wait_for_ready(struct tpm_chip *chip) | |||
94 | unsigned long stop; | 94 | unsigned long stop; |
95 | 95 | ||
96 | /* status immediately available check */ | 96 | /* status immediately available check */ |
97 | status = inb(chip->vendor->base + NSC_STATUS); | 97 | status = inb(chip->vendor.base + NSC_STATUS); |
98 | if (status & NSC_STATUS_OBF) | 98 | if (status & NSC_STATUS_OBF) |
99 | status = inb(chip->vendor->base + NSC_DATA); | 99 | status = inb(chip->vendor.base + NSC_DATA); |
100 | if (status & NSC_STATUS_RDY) | 100 | if (status & NSC_STATUS_RDY) |
101 | return 0; | 101 | return 0; |
102 | 102 | ||
@@ -104,9 +104,9 @@ static int nsc_wait_for_ready(struct tpm_chip *chip) | |||
104 | stop = jiffies + 100; | 104 | stop = jiffies + 100; |
105 | do { | 105 | do { |
106 | msleep(TPM_TIMEOUT); | 106 | msleep(TPM_TIMEOUT); |
107 | status = inb(chip->vendor->base + NSC_STATUS); | 107 | status = inb(chip->vendor.base + NSC_STATUS); |
108 | if (status & NSC_STATUS_OBF) | 108 | if (status & NSC_STATUS_OBF) |
109 | status = inb(chip->vendor->base + NSC_DATA); | 109 | status = inb(chip->vendor.base + NSC_DATA); |
110 | if (status & NSC_STATUS_RDY) | 110 | if (status & NSC_STATUS_RDY) |
111 | return 0; | 111 | return 0; |
112 | } | 112 | } |
@@ -132,7 +132,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
132 | return -EIO; | 132 | return -EIO; |
133 | } | 133 | } |
134 | if ((data = | 134 | if ((data = |
135 | inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_NORMAL) { | 135 | inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_NORMAL) { |
136 | dev_err(chip->dev, "not in normal mode (0x%x)\n", | 136 | dev_err(chip->dev, "not in normal mode (0x%x)\n", |
137 | data); | 137 | data); |
138 | return -EIO; | 138 | return -EIO; |
@@ -148,7 +148,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
148 | } | 148 | } |
149 | if (data & NSC_STATUS_F0) | 149 | if (data & NSC_STATUS_F0) |
150 | break; | 150 | break; |
151 | *p = inb(chip->vendor->base + NSC_DATA); | 151 | *p = inb(chip->vendor.base + NSC_DATA); |
152 | } | 152 | } |
153 | 153 | ||
154 | if ((data & NSC_STATUS_F0) == 0 && | 154 | if ((data & NSC_STATUS_F0) == 0 && |
@@ -156,7 +156,7 @@ static int tpm_nsc_recv(struct tpm_chip *chip, u8 * buf, size_t count) | |||
156 | dev_err(chip->dev, "F0 not set\n"); | 156 | dev_err(chip->dev, "F0 not set\n"); |
157 | return -EIO; | 157 | return -EIO; |
158 | } | 158 | } |
159 | if ((data = inb(chip->vendor->base + NSC_DATA)) != NSC_COMMAND_EOC) { | 159 | if ((data = inb(chip->vendor.base + NSC_DATA)) != NSC_COMMAND_EOC) { |
160 | dev_err(chip->dev, | 160 | dev_err(chip->dev, |
161 | "expected end of command(0x%x)\n", data); | 161 | "expected end of command(0x%x)\n", data); |
162 | return -EIO; | 162 | return -EIO; |
@@ -182,7 +182,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
182 | * fix it. Not sure why this is needed, we followed the flow | 182 | * fix it. Not sure why this is needed, we followed the flow |
183 | * chart in the manual to the letter. | 183 | * chart in the manual to the letter. |
184 | */ | 184 | */ |
185 | outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); | 185 | outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND); |
186 | 186 | ||
187 | if (nsc_wait_for_ready(chip) != 0) | 187 | if (nsc_wait_for_ready(chip) != 0) |
188 | return -EIO; | 188 | return -EIO; |
@@ -192,7 +192,7 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
192 | return -EIO; | 192 | return -EIO; |
193 | } | 193 | } |
194 | 194 | ||
195 | outb(NSC_COMMAND_NORMAL, chip->vendor->base + NSC_COMMAND); | 195 | outb(NSC_COMMAND_NORMAL, chip->vendor.base + NSC_COMMAND); |
196 | if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { | 196 | if (wait_for_stat(chip, NSC_STATUS_IBR, NSC_STATUS_IBR, &data) < 0) { |
197 | dev_err(chip->dev, "IBR timeout\n"); | 197 | dev_err(chip->dev, "IBR timeout\n"); |
198 | return -EIO; | 198 | return -EIO; |
@@ -204,26 +204,26 @@ static int tpm_nsc_send(struct tpm_chip *chip, u8 * buf, size_t count) | |||
204 | "IBF timeout (while writing data)\n"); | 204 | "IBF timeout (while writing data)\n"); |
205 | return -EIO; | 205 | return -EIO; |
206 | } | 206 | } |
207 | outb(buf[i], chip->vendor->base + NSC_DATA); | 207 | outb(buf[i], chip->vendor.base + NSC_DATA); |
208 | } | 208 | } |
209 | 209 | ||
210 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { | 210 | if (wait_for_stat(chip, NSC_STATUS_IBF, 0, &data) < 0) { |
211 | dev_err(chip->dev, "IBF timeout\n"); | 211 | dev_err(chip->dev, "IBF timeout\n"); |
212 | return -EIO; | 212 | return -EIO; |
213 | } | 213 | } |
214 | outb(NSC_COMMAND_EOC, chip->vendor->base + NSC_COMMAND); | 214 | outb(NSC_COMMAND_EOC, chip->vendor.base + NSC_COMMAND); |
215 | 215 | ||
216 | return count; | 216 | return count; |
217 | } | 217 | } |
218 | 218 | ||
219 | static void tpm_nsc_cancel(struct tpm_chip *chip) | 219 | static void tpm_nsc_cancel(struct tpm_chip *chip) |
220 | { | 220 | { |
221 | outb(NSC_COMMAND_CANCEL, chip->vendor->base + NSC_COMMAND); | 221 | outb(NSC_COMMAND_CANCEL, chip->vendor.base + NSC_COMMAND); |
222 | } | 222 | } |
223 | 223 | ||
224 | static u8 tpm_nsc_status(struct tpm_chip *chip) | 224 | static u8 tpm_nsc_status(struct tpm_chip *chip) |
225 | { | 225 | { |
226 | return inb(chip->vendor->base + NSC_STATUS); | 226 | return inb(chip->vendor.base + NSC_STATUS); |
227 | } | 227 | } |
228 | 228 | ||
229 | static struct file_operations nsc_ops = { | 229 | static struct file_operations nsc_ops = { |
@@ -250,7 +250,7 @@ static struct attribute * nsc_attrs[] = { | |||
250 | 250 | ||
251 | static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; | 251 | static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs }; |
252 | 252 | ||
253 | static struct tpm_vendor_specific tpm_nsc = { | 253 | static const struct tpm_vendor_specific tpm_nsc = { |
254 | .recv = tpm_nsc_recv, | 254 | .recv = tpm_nsc_recv, |
255 | .send = tpm_nsc_send, | 255 | .send = tpm_nsc_send, |
256 | .cancel = tpm_nsc_cancel, | 256 | .cancel = tpm_nsc_cancel, |
@@ -268,7 +268,7 @@ static void __devexit tpm_nsc_remove(struct device *dev) | |||
268 | { | 268 | { |
269 | struct tpm_chip *chip = dev_get_drvdata(dev); | 269 | struct tpm_chip *chip = dev_get_drvdata(dev); |
270 | if ( chip ) { | 270 | if ( chip ) { |
271 | release_region(chip->vendor->base, 2); | 271 | release_region(chip->vendor.base, 2); |
272 | tpm_remove_hardware(chip->dev); | 272 | tpm_remove_hardware(chip->dev); |
273 | } | 273 | } |
274 | } | 274 | } |
@@ -286,7 +286,8 @@ static int __init init_nsc(void) | |||
286 | int rc = 0; | 286 | int rc = 0; |
287 | int lo, hi; | 287 | int lo, hi; |
288 | int nscAddrBase = TPM_ADDR; | 288 | int nscAddrBase = TPM_ADDR; |
289 | 289 | struct tpm_chip *chip; | |
290 | unsigned long base; | ||
290 | 291 | ||
291 | /* verify that it is a National part (SID) */ | 292 | /* verify that it is a National part (SID) */ |
292 | if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { | 293 | if (tpm_read_index(TPM_ADDR, NSC_SID_INDEX) != 0xEF) { |
@@ -300,7 +301,7 @@ static int __init init_nsc(void) | |||
300 | 301 | ||
301 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); | 302 | hi = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_HI); |
302 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); | 303 | lo = tpm_read_index(nscAddrBase, TPM_NSC_BASE0_LO); |
303 | tpm_nsc.base = (hi<<8) | lo; | 304 | base = (hi<<8) | lo; |
304 | 305 | ||
305 | /* enable the DPM module */ | 306 | /* enable the DPM module */ |
306 | tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); | 307 | tpm_write_index(nscAddrBase, NSC_LDC_INDEX, 0x01); |
@@ -320,13 +321,15 @@ static int __init init_nsc(void) | |||
320 | if ((rc = platform_device_register(pdev)) < 0) | 321 | if ((rc = platform_device_register(pdev)) < 0) |
321 | goto err_free_dev; | 322 | goto err_free_dev; |
322 | 323 | ||
323 | if (request_region(tpm_nsc.base, 2, "tpm_nsc0") == NULL ) { | 324 | if (request_region(base, 2, "tpm_nsc0") == NULL ) { |
324 | rc = -EBUSY; | 325 | rc = -EBUSY; |
325 | goto err_unreg_dev; | 326 | goto err_unreg_dev; |
326 | } | 327 | } |
327 | 328 | ||
328 | if ((rc = tpm_register_hardware(&pdev->dev, &tpm_nsc)) < 0) | 329 | if (!(chip = tpm_register_hardware(&pdev->dev, &tpm_nsc))) { |
330 | rc = -ENODEV; | ||
329 | goto err_rel_reg; | 331 | goto err_rel_reg; |
332 | } | ||
330 | 333 | ||
331 | dev_dbg(&pdev->dev, "NSC TPM detected\n"); | 334 | dev_dbg(&pdev->dev, "NSC TPM detected\n"); |
332 | dev_dbg(&pdev->dev, | 335 | dev_dbg(&pdev->dev, |
@@ -361,10 +364,12 @@ static int __init init_nsc(void) | |||
361 | "NSC TPM revision %d\n", | 364 | "NSC TPM revision %d\n", |
362 | tpm_read_index(nscAddrBase, 0x27) & 0x1F); | 365 | tpm_read_index(nscAddrBase, 0x27) & 0x1F); |
363 | 366 | ||
367 | chip->vendor.base = base; | ||
368 | |||
364 | return 0; | 369 | return 0; |
365 | 370 | ||
366 | err_rel_reg: | 371 | err_rel_reg: |
367 | release_region(tpm_nsc.base, 2); | 372 | release_region(base, 2); |
368 | err_unreg_dev: | 373 | err_unreg_dev: |
369 | platform_device_unregister(pdev); | 374 | platform_device_unregister(pdev); |
370 | err_free_dev: | 375 | err_free_dev: |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c new file mode 100644 index 000000000000..b9cae9a238bb --- /dev/null +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -0,0 +1,669 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005, 2006 IBM Corporation | ||
3 | * | ||
4 | * Authors: | ||
5 | * Leendert van Doorn <leendert@watson.ibm.com> | ||
6 | * Kylene Hall <kjhall@us.ibm.com> | ||
7 | * | ||
8 | * Device driver for TCG/TCPA TPM (trusted platform module). | ||
9 | * Specifications at www.trustedcomputinggroup.org | ||
10 | * | ||
11 | * This device driver implements the TPM interface as defined in | ||
12 | * the TCG TPM Interface Spec version 1.2, revision 1.0. | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or | ||
15 | * modify it under the terms of the GNU General Public License as | ||
16 | * published by the Free Software Foundation, version 2 of the | ||
17 | * License. | ||
18 | */ | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/module.h> | ||
21 | #include <linux/moduleparam.h> | ||
22 | #include <linux/pnp.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/wait.h> | ||
25 | #include "tpm.h" | ||
26 | |||
27 | #define TPM_HEADER_SIZE 10 | ||
28 | |||
29 | enum tis_access { | ||
30 | TPM_ACCESS_VALID = 0x80, | ||
31 | TPM_ACCESS_ACTIVE_LOCALITY = 0x20, | ||
32 | TPM_ACCESS_REQUEST_PENDING = 0x04, | ||
33 | TPM_ACCESS_REQUEST_USE = 0x02, | ||
34 | }; | ||
35 | |||
36 | enum tis_status { | ||
37 | TPM_STS_VALID = 0x80, | ||
38 | TPM_STS_COMMAND_READY = 0x40, | ||
39 | TPM_STS_GO = 0x20, | ||
40 | TPM_STS_DATA_AVAIL = 0x10, | ||
41 | TPM_STS_DATA_EXPECT = 0x08, | ||
42 | }; | ||
43 | |||
44 | enum tis_int_flags { | ||
45 | TPM_GLOBAL_INT_ENABLE = 0x80000000, | ||
46 | TPM_INTF_BURST_COUNT_STATIC = 0x100, | ||
47 | TPM_INTF_CMD_READY_INT = 0x080, | ||
48 | TPM_INTF_INT_EDGE_FALLING = 0x040, | ||
49 | TPM_INTF_INT_EDGE_RISING = 0x020, | ||
50 | TPM_INTF_INT_LEVEL_LOW = 0x010, | ||
51 | TPM_INTF_INT_LEVEL_HIGH = 0x008, | ||
52 | TPM_INTF_LOCALITY_CHANGE_INT = 0x004, | ||
53 | TPM_INTF_STS_VALID_INT = 0x002, | ||
54 | TPM_INTF_DATA_AVAIL_INT = 0x001, | ||
55 | }; | ||
56 | |||
57 | enum tis_defaults { | ||
58 | TIS_MEM_BASE = 0xFED4000, | ||
59 | TIS_MEM_LEN = 0x5000, | ||
60 | TIS_SHORT_TIMEOUT = 750, /* ms */ | ||
61 | TIS_LONG_TIMEOUT = 2000, /* 2 sec */ | ||
62 | }; | ||
63 | |||
64 | #define TPM_ACCESS(l) (0x0000 | ((l) << 12)) | ||
65 | #define TPM_INT_ENABLE(l) (0x0008 | ((l) << 12)) | ||
66 | #define TPM_INT_VECTOR(l) (0x000C | ((l) << 12)) | ||
67 | #define TPM_INT_STATUS(l) (0x0010 | ((l) << 12)) | ||
68 | #define TPM_INTF_CAPS(l) (0x0014 | ((l) << 12)) | ||
69 | #define TPM_STS(l) (0x0018 | ((l) << 12)) | ||
70 | #define TPM_DATA_FIFO(l) (0x0024 | ((l) << 12)) | ||
71 | |||
72 | #define TPM_DID_VID(l) (0x0F00 | ((l) << 12)) | ||
73 | #define TPM_RID(l) (0x0F04 | ((l) << 12)) | ||
74 | |||
75 | static LIST_HEAD(tis_chips); | ||
76 | static DEFINE_SPINLOCK(tis_lock); | ||
77 | |||
78 | static int check_locality(struct tpm_chip *chip, int l) | ||
79 | { | ||
80 | if ((ioread8(chip->vendor.iobase + TPM_ACCESS(l)) & | ||
81 | (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) == | ||
82 | (TPM_ACCESS_ACTIVE_LOCALITY | TPM_ACCESS_VALID)) | ||
83 | return chip->vendor.locality = l; | ||
84 | |||
85 | return -1; | ||
86 | } | ||
87 | |||
88 | static void release_locality(struct tpm_chip *chip, int l, int force) | ||
89 | { | ||
90 | if (force || (ioread8(chip->vendor.iobase + TPM_ACCESS(l)) & | ||
91 | (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) == | ||
92 | (TPM_ACCESS_REQUEST_PENDING | TPM_ACCESS_VALID)) | ||
93 | iowrite8(TPM_ACCESS_ACTIVE_LOCALITY, | ||
94 | chip->vendor.iobase + TPM_ACCESS(l)); | ||
95 | } | ||
96 | |||
97 | static int request_locality(struct tpm_chip *chip, int l) | ||
98 | { | ||
99 | unsigned long stop; | ||
100 | long rc; | ||
101 | |||
102 | if (check_locality(chip, l) >= 0) | ||
103 | return l; | ||
104 | |||
105 | iowrite8(TPM_ACCESS_REQUEST_USE, | ||
106 | chip->vendor.iobase + TPM_ACCESS(l)); | ||
107 | |||
108 | if (chip->vendor.irq) { | ||
109 | rc = wait_event_interruptible_timeout(chip->vendor.int_queue, | ||
110 | (check_locality | ||
111 | (chip, l) >= 0), | ||
112 | chip->vendor.timeout_a); | ||
113 | if (rc > 0) | ||
114 | return l; | ||
115 | |||
116 | } else { | ||
117 | /* wait for burstcount */ | ||
118 | stop = jiffies + chip->vendor.timeout_a; | ||
119 | do { | ||
120 | if (check_locality(chip, l) >= 0) | ||
121 | return l; | ||
122 | msleep(TPM_TIMEOUT); | ||
123 | } | ||
124 | while (time_before(jiffies, stop)); | ||
125 | } | ||
126 | return -1; | ||
127 | } | ||
128 | |||
129 | static u8 tpm_tis_status(struct tpm_chip *chip) | ||
130 | { | ||
131 | return ioread8(chip->vendor.iobase + | ||
132 | TPM_STS(chip->vendor.locality)); | ||
133 | } | ||
134 | |||
135 | static void tpm_tis_ready(struct tpm_chip *chip) | ||
136 | { | ||
137 | /* this causes the current command to be aborted */ | ||
138 | iowrite8(TPM_STS_COMMAND_READY, | ||
139 | chip->vendor.iobase + TPM_STS(chip->vendor.locality)); | ||
140 | } | ||
141 | |||
142 | static int get_burstcount(struct tpm_chip *chip) | ||
143 | { | ||
144 | unsigned long stop; | ||
145 | int burstcnt; | ||
146 | |||
147 | /* wait for burstcount */ | ||
148 | /* which timeout value, spec has 2 answers (c & d) */ | ||
149 | stop = jiffies + chip->vendor.timeout_d; | ||
150 | do { | ||
151 | burstcnt = ioread8(chip->vendor.iobase + | ||
152 | TPM_STS(chip->vendor.locality) + 1); | ||
153 | burstcnt += ioread8(chip->vendor.iobase + | ||
154 | TPM_STS(chip->vendor.locality) + | ||
155 | 2) << 8; | ||
156 | if (burstcnt) | ||
157 | return burstcnt; | ||
158 | msleep(TPM_TIMEOUT); | ||
159 | } while (time_before(jiffies, stop)); | ||
160 | return -EBUSY; | ||
161 | } | ||
162 | |||
163 | static int wait_for_stat(struct tpm_chip *chip, u8 mask, unsigned long timeout, | ||
164 | wait_queue_head_t *queue) | ||
165 | { | ||
166 | unsigned long stop; | ||
167 | long rc; | ||
168 | u8 status; | ||
169 | |||
170 | /* check current status */ | ||
171 | status = tpm_tis_status(chip); | ||
172 | if ((status & mask) == mask) | ||
173 | return 0; | ||
174 | |||
175 | if (chip->vendor.irq) { | ||
176 | rc = wait_event_interruptible_timeout(*queue, | ||
177 | ((tpm_tis_status | ||
178 | (chip) & mask) == | ||
179 | mask), timeout); | ||
180 | if (rc > 0) | ||
181 | return 0; | ||
182 | } else { | ||
183 | stop = jiffies + timeout; | ||
184 | do { | ||
185 | msleep(TPM_TIMEOUT); | ||
186 | status = tpm_tis_status(chip); | ||
187 | if ((status & mask) == mask) | ||
188 | return 0; | ||
189 | } while (time_before(jiffies, stop)); | ||
190 | } | ||
191 | return -ETIME; | ||
192 | } | ||
193 | |||
194 | static int recv_data(struct tpm_chip *chip, u8 *buf, size_t count) | ||
195 | { | ||
196 | int size = 0, burstcnt; | ||
197 | while (size < count && | ||
198 | wait_for_stat(chip, | ||
199 | TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
200 | chip->vendor.timeout_c, | ||
201 | &chip->vendor.read_queue) | ||
202 | == 0) { | ||
203 | burstcnt = get_burstcount(chip); | ||
204 | for (; burstcnt > 0 && size < count; burstcnt--) | ||
205 | buf[size++] = ioread8(chip->vendor.iobase + | ||
206 | TPM_DATA_FIFO(chip->vendor. | ||
207 | locality)); | ||
208 | } | ||
209 | return size; | ||
210 | } | ||
211 | |||
212 | static int tpm_tis_recv(struct tpm_chip *chip, u8 *buf, size_t count) | ||
213 | { | ||
214 | int size = 0; | ||
215 | int expected, status; | ||
216 | |||
217 | if (count < TPM_HEADER_SIZE) { | ||
218 | size = -EIO; | ||
219 | goto out; | ||
220 | } | ||
221 | |||
222 | /* read first 10 bytes, including tag, paramsize, and result */ | ||
223 | if ((size = | ||
224 | recv_data(chip, buf, TPM_HEADER_SIZE)) < TPM_HEADER_SIZE) { | ||
225 | dev_err(chip->dev, "Unable to read header\n"); | ||
226 | goto out; | ||
227 | } | ||
228 | |||
229 | expected = be32_to_cpu(*(__be32 *) (buf + 2)); | ||
230 | if (expected > count) { | ||
231 | size = -EIO; | ||
232 | goto out; | ||
233 | } | ||
234 | |||
235 | if ((size += | ||
236 | recv_data(chip, &buf[TPM_HEADER_SIZE], | ||
237 | expected - TPM_HEADER_SIZE)) < expected) { | ||
238 | dev_err(chip->dev, "Unable to read remainder of result\n"); | ||
239 | size = -ETIME; | ||
240 | goto out; | ||
241 | } | ||
242 | |||
243 | wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, | ||
244 | &chip->vendor.int_queue); | ||
245 | status = tpm_tis_status(chip); | ||
246 | if (status & TPM_STS_DATA_AVAIL) { /* retry? */ | ||
247 | dev_err(chip->dev, "Error left over data\n"); | ||
248 | size = -EIO; | ||
249 | goto out; | ||
250 | } | ||
251 | |||
252 | out: | ||
253 | tpm_tis_ready(chip); | ||
254 | release_locality(chip, chip->vendor.locality, 0); | ||
255 | return size; | ||
256 | } | ||
257 | |||
258 | /* | ||
259 | * If interrupts are used (signaled by an irq set in the vendor structure) | ||
260 | * tpm.c can skip polling for the data to be available as the interrupt is | ||
261 | * waited for here | ||
262 | */ | ||
263 | static int tpm_tis_send(struct tpm_chip *chip, u8 *buf, size_t len) | ||
264 | { | ||
265 | int rc, status, burstcnt; | ||
266 | size_t count = 0; | ||
267 | u32 ordinal; | ||
268 | |||
269 | if (request_locality(chip, 0) < 0) | ||
270 | return -EBUSY; | ||
271 | |||
272 | status = tpm_tis_status(chip); | ||
273 | if ((status & TPM_STS_COMMAND_READY) == 0) { | ||
274 | tpm_tis_ready(chip); | ||
275 | if (wait_for_stat | ||
276 | (chip, TPM_STS_COMMAND_READY, chip->vendor.timeout_b, | ||
277 | &chip->vendor.int_queue) < 0) { | ||
278 | rc = -ETIME; | ||
279 | goto out_err; | ||
280 | } | ||
281 | } | ||
282 | |||
283 | while (count < len - 1) { | ||
284 | burstcnt = get_burstcount(chip); | ||
285 | for (; burstcnt > 0 && count < len - 1; burstcnt--) { | ||
286 | iowrite8(buf[count], chip->vendor.iobase + | ||
287 | TPM_DATA_FIFO(chip->vendor.locality)); | ||
288 | count++; | ||
289 | } | ||
290 | |||
291 | wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, | ||
292 | &chip->vendor.int_queue); | ||
293 | status = tpm_tis_status(chip); | ||
294 | if ((status & TPM_STS_DATA_EXPECT) == 0) { | ||
295 | rc = -EIO; | ||
296 | goto out_err; | ||
297 | } | ||
298 | } | ||
299 | |||
300 | /* write last byte */ | ||
301 | iowrite8(buf[count], | ||
302 | chip->vendor.iobase + | ||
303 | TPM_DATA_FIFO(chip->vendor.locality)); | ||
304 | wait_for_stat(chip, TPM_STS_VALID, chip->vendor.timeout_c, | ||
305 | &chip->vendor.int_queue); | ||
306 | status = tpm_tis_status(chip); | ||
307 | if ((status & TPM_STS_DATA_EXPECT) != 0) { | ||
308 | rc = -EIO; | ||
309 | goto out_err; | ||
310 | } | ||
311 | |||
312 | /* go and do it */ | ||
313 | iowrite8(TPM_STS_GO, | ||
314 | chip->vendor.iobase + TPM_STS(chip->vendor.locality)); | ||
315 | |||
316 | if (chip->vendor.irq) { | ||
317 | ordinal = be32_to_cpu(*((__be32 *) (buf + 6))); | ||
318 | if (wait_for_stat | ||
319 | (chip, TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
320 | tpm_calc_ordinal_duration(chip, ordinal), | ||
321 | &chip->vendor.read_queue) < 0) { | ||
322 | rc = -ETIME; | ||
323 | goto out_err; | ||
324 | } | ||
325 | } | ||
326 | return len; | ||
327 | out_err: | ||
328 | tpm_tis_ready(chip); | ||
329 | release_locality(chip, chip->vendor.locality, 0); | ||
330 | return rc; | ||
331 | } | ||
332 | |||
333 | static struct file_operations tis_ops = { | ||
334 | .owner = THIS_MODULE, | ||
335 | .llseek = no_llseek, | ||
336 | .open = tpm_open, | ||
337 | .read = tpm_read, | ||
338 | .write = tpm_write, | ||
339 | .release = tpm_release, | ||
340 | }; | ||
341 | |||
342 | static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL); | ||
343 | static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL); | ||
344 | static DEVICE_ATTR(enabled, S_IRUGO, tpm_show_enabled, NULL); | ||
345 | static DEVICE_ATTR(active, S_IRUGO, tpm_show_active, NULL); | ||
346 | static DEVICE_ATTR(owned, S_IRUGO, tpm_show_owned, NULL); | ||
347 | static DEVICE_ATTR(temp_deactivated, S_IRUGO, tpm_show_temp_deactivated, | ||
348 | NULL); | ||
349 | static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps_1_2, NULL); | ||
350 | static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel); | ||
351 | |||
352 | static struct attribute *tis_attrs[] = { | ||
353 | &dev_attr_pubek.attr, | ||
354 | &dev_attr_pcrs.attr, | ||
355 | &dev_attr_enabled.attr, | ||
356 | &dev_attr_active.attr, | ||
357 | &dev_attr_owned.attr, | ||
358 | &dev_attr_temp_deactivated.attr, | ||
359 | &dev_attr_caps.attr, | ||
360 | &dev_attr_cancel.attr, NULL, | ||
361 | }; | ||
362 | |||
363 | static struct attribute_group tis_attr_grp = { | ||
364 | .attrs = tis_attrs | ||
365 | }; | ||
366 | |||
367 | static struct tpm_vendor_specific tpm_tis = { | ||
368 | .status = tpm_tis_status, | ||
369 | .recv = tpm_tis_recv, | ||
370 | .send = tpm_tis_send, | ||
371 | .cancel = tpm_tis_ready, | ||
372 | .req_complete_mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
373 | .req_complete_val = TPM_STS_DATA_AVAIL | TPM_STS_VALID, | ||
374 | .req_canceled = TPM_STS_COMMAND_READY, | ||
375 | .attr_group = &tis_attr_grp, | ||
376 | .miscdev = { | ||
377 | .fops = &tis_ops,}, | ||
378 | }; | ||
379 | |||
380 | static irqreturn_t tis_int_probe(int irq, void *dev_id, struct pt_regs *regs) | ||
381 | { | ||
382 | struct tpm_chip *chip = (struct tpm_chip *) dev_id; | ||
383 | u32 interrupt; | ||
384 | |||
385 | interrupt = ioread32(chip->vendor.iobase + | ||
386 | TPM_INT_STATUS(chip->vendor.locality)); | ||
387 | |||
388 | if (interrupt == 0) | ||
389 | return IRQ_NONE; | ||
390 | |||
391 | chip->vendor.irq = irq; | ||
392 | |||
393 | /* Clear interrupts handled with TPM_EOI */ | ||
394 | iowrite32(interrupt, | ||
395 | chip->vendor.iobase + | ||
396 | TPM_INT_STATUS(chip->vendor.locality)); | ||
397 | return IRQ_HANDLED; | ||
398 | } | ||
399 | |||
400 | static irqreturn_t tis_int_handler(int irq, void *dev_id, struct pt_regs *regs) | ||
401 | { | ||
402 | struct tpm_chip *chip = (struct tpm_chip *) dev_id; | ||
403 | u32 interrupt; | ||
404 | int i; | ||
405 | |||
406 | interrupt = ioread32(chip->vendor.iobase + | ||
407 | TPM_INT_STATUS(chip->vendor.locality)); | ||
408 | |||
409 | if (interrupt == 0) | ||
410 | return IRQ_NONE; | ||
411 | |||
412 | if (interrupt & TPM_INTF_DATA_AVAIL_INT) | ||
413 | wake_up_interruptible(&chip->vendor.read_queue); | ||
414 | if (interrupt & TPM_INTF_LOCALITY_CHANGE_INT) | ||
415 | for (i = 0; i < 5; i++) | ||
416 | if (check_locality(chip, i) >= 0) | ||
417 | break; | ||
418 | if (interrupt & | ||
419 | (TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_STS_VALID_INT | | ||
420 | TPM_INTF_CMD_READY_INT)) | ||
421 | wake_up_interruptible(&chip->vendor.int_queue); | ||
422 | |||
423 | /* Clear interrupts handled with TPM_EOI */ | ||
424 | iowrite32(interrupt, | ||
425 | chip->vendor.iobase + | ||
426 | TPM_INT_STATUS(chip->vendor.locality)); | ||
427 | return IRQ_HANDLED; | ||
428 | } | ||
429 | |||
430 | static int interrupts = 1; | ||
431 | module_param(interrupts, bool, 0444); | ||
432 | MODULE_PARM_DESC(interrupts, "Enable interrupts"); | ||
433 | |||
434 | static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, | ||
435 | const struct pnp_device_id *pnp_id) | ||
436 | { | ||
437 | u32 vendor, intfcaps, intmask; | ||
438 | int rc, i; | ||
439 | unsigned long start, len; | ||
440 | struct tpm_chip *chip; | ||
441 | |||
442 | start = pnp_mem_start(pnp_dev, 0); | ||
443 | len = pnp_mem_len(pnp_dev, 0); | ||
444 | |||
445 | if (!start) | ||
446 | start = TIS_MEM_BASE; | ||
447 | if (!len) | ||
448 | len = TIS_MEM_LEN; | ||
449 | |||
450 | if (!(chip = tpm_register_hardware(&pnp_dev->dev, &tpm_tis))) | ||
451 | return -ENODEV; | ||
452 | |||
453 | chip->vendor.iobase = ioremap(start, len); | ||
454 | if (!chip->vendor.iobase) { | ||
455 | rc = -EIO; | ||
456 | goto out_err; | ||
457 | } | ||
458 | |||
459 | vendor = ioread32(chip->vendor.iobase + TPM_DID_VID(0)); | ||
460 | if ((vendor & 0xFFFF) == 0xFFFF) { | ||
461 | rc = -ENODEV; | ||
462 | goto out_err; | ||
463 | } | ||
464 | |||
465 | /* Default timeouts */ | ||
466 | chip->vendor.timeout_a = msecs_to_jiffies(TIS_SHORT_TIMEOUT); | ||
467 | chip->vendor.timeout_b = msecs_to_jiffies(TIS_LONG_TIMEOUT); | ||
468 | chip->vendor.timeout_c = msecs_to_jiffies(TIS_SHORT_TIMEOUT); | ||
469 | chip->vendor.timeout_d = msecs_to_jiffies(TIS_SHORT_TIMEOUT); | ||
470 | |||
471 | dev_info(&pnp_dev->dev, | ||
472 | "1.2 TPM (device-id 0x%X, rev-id %d)\n", | ||
473 | vendor >> 16, ioread8(chip->vendor.iobase + TPM_RID(0))); | ||
474 | |||
475 | /* Figure out the capabilities */ | ||
476 | intfcaps = | ||
477 | ioread32(chip->vendor.iobase + | ||
478 | TPM_INTF_CAPS(chip->vendor.locality)); | ||
479 | dev_dbg(&pnp_dev->dev, "TPM interface capabilities (0x%x):\n", | ||
480 | intfcaps); | ||
481 | if (intfcaps & TPM_INTF_BURST_COUNT_STATIC) | ||
482 | dev_dbg(&pnp_dev->dev, "\tBurst Count Static\n"); | ||
483 | if (intfcaps & TPM_INTF_CMD_READY_INT) | ||
484 | dev_dbg(&pnp_dev->dev, "\tCommand Ready Int Support\n"); | ||
485 | if (intfcaps & TPM_INTF_INT_EDGE_FALLING) | ||
486 | dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Falling\n"); | ||
487 | if (intfcaps & TPM_INTF_INT_EDGE_RISING) | ||
488 | dev_dbg(&pnp_dev->dev, "\tInterrupt Edge Rising\n"); | ||
489 | if (intfcaps & TPM_INTF_INT_LEVEL_LOW) | ||
490 | dev_dbg(&pnp_dev->dev, "\tInterrupt Level Low\n"); | ||
491 | if (intfcaps & TPM_INTF_INT_LEVEL_HIGH) | ||
492 | dev_dbg(&pnp_dev->dev, "\tInterrupt Level High\n"); | ||
493 | if (intfcaps & TPM_INTF_LOCALITY_CHANGE_INT) | ||
494 | dev_dbg(&pnp_dev->dev, "\tLocality Change Int Support\n"); | ||
495 | if (intfcaps & TPM_INTF_STS_VALID_INT) | ||
496 | dev_dbg(&pnp_dev->dev, "\tSts Valid Int Support\n"); | ||
497 | if (intfcaps & TPM_INTF_DATA_AVAIL_INT) | ||
498 | dev_dbg(&pnp_dev->dev, "\tData Avail Int Support\n"); | ||
499 | |||
500 | if (request_locality(chip, 0) != 0) { | ||
501 | rc = -ENODEV; | ||
502 | goto out_err; | ||
503 | } | ||
504 | |||
505 | /* INTERRUPT Setup */ | ||
506 | init_waitqueue_head(&chip->vendor.read_queue); | ||
507 | init_waitqueue_head(&chip->vendor.int_queue); | ||
508 | |||
509 | intmask = | ||
510 | ioread32(chip->vendor.iobase + | ||
511 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
512 | |||
513 | intmask |= TPM_INTF_CMD_READY_INT | ||
514 | | TPM_INTF_LOCALITY_CHANGE_INT | TPM_INTF_DATA_AVAIL_INT | ||
515 | | TPM_INTF_STS_VALID_INT; | ||
516 | |||
517 | iowrite32(intmask, | ||
518 | chip->vendor.iobase + | ||
519 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
520 | if (interrupts) { | ||
521 | chip->vendor.irq = | ||
522 | ioread8(chip->vendor.iobase + | ||
523 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
524 | |||
525 | for (i = 3; i < 16 && chip->vendor.irq == 0; i++) { | ||
526 | iowrite8(i, chip->vendor.iobase + | ||
527 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
528 | if (request_irq | ||
529 | (i, tis_int_probe, SA_SHIRQ, | ||
530 | chip->vendor.miscdev.name, chip) != 0) { | ||
531 | dev_info(chip->dev, | ||
532 | "Unable to request irq: %d for probe\n", | ||
533 | i); | ||
534 | continue; | ||
535 | } | ||
536 | |||
537 | /* Clear all existing */ | ||
538 | iowrite32(ioread32 | ||
539 | (chip->vendor.iobase + | ||
540 | TPM_INT_STATUS(chip->vendor.locality)), | ||
541 | chip->vendor.iobase + | ||
542 | TPM_INT_STATUS(chip->vendor.locality)); | ||
543 | |||
544 | /* Turn on */ | ||
545 | iowrite32(intmask | TPM_GLOBAL_INT_ENABLE, | ||
546 | chip->vendor.iobase + | ||
547 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
548 | |||
549 | /* Generate Interrupts */ | ||
550 | tpm_gen_interrupt(chip); | ||
551 | |||
552 | /* Turn off */ | ||
553 | iowrite32(intmask, | ||
554 | chip->vendor.iobase + | ||
555 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
556 | free_irq(i, chip); | ||
557 | } | ||
558 | } | ||
559 | if (chip->vendor.irq) { | ||
560 | iowrite8(chip->vendor.irq, | ||
561 | chip->vendor.iobase + | ||
562 | TPM_INT_VECTOR(chip->vendor.locality)); | ||
563 | if (request_irq | ||
564 | (chip->vendor.irq, tis_int_handler, SA_SHIRQ, | ||
565 | chip->vendor.miscdev.name, chip) != 0) { | ||
566 | dev_info(chip->dev, | ||
567 | "Unable to request irq: %d for use\n", | ||
568 | chip->vendor.irq); | ||
569 | chip->vendor.irq = 0; | ||
570 | } else { | ||
571 | /* Clear all existing */ | ||
572 | iowrite32(ioread32 | ||
573 | (chip->vendor.iobase + | ||
574 | TPM_INT_STATUS(chip->vendor.locality)), | ||
575 | chip->vendor.iobase + | ||
576 | TPM_INT_STATUS(chip->vendor.locality)); | ||
577 | |||
578 | /* Turn on */ | ||
579 | iowrite32(intmask | TPM_GLOBAL_INT_ENABLE, | ||
580 | chip->vendor.iobase + | ||
581 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
582 | } | ||
583 | } | ||
584 | |||
585 | INIT_LIST_HEAD(&chip->vendor.list); | ||
586 | spin_lock(&tis_lock); | ||
587 | list_add(&chip->vendor.list, &tis_chips); | ||
588 | spin_unlock(&tis_lock); | ||
589 | |||
590 | tpm_get_timeouts(chip); | ||
591 | tpm_continue_selftest(chip); | ||
592 | |||
593 | return 0; | ||
594 | out_err: | ||
595 | if (chip->vendor.iobase) | ||
596 | iounmap(chip->vendor.iobase); | ||
597 | tpm_remove_hardware(chip->dev); | ||
598 | return rc; | ||
599 | } | ||
600 | |||
601 | static int tpm_tis_pnp_suspend(struct pnp_dev *dev, pm_message_t msg) | ||
602 | { | ||
603 | return tpm_pm_suspend(&dev->dev, msg); | ||
604 | } | ||
605 | |||
606 | static int tpm_tis_pnp_resume(struct pnp_dev *dev) | ||
607 | { | ||
608 | return tpm_pm_resume(&dev->dev); | ||
609 | } | ||
610 | |||
611 | static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { | ||
612 | {"PNP0C31", 0}, /* TPM */ | ||
613 | {"ATM1200", 0}, /* Atmel */ | ||
614 | {"IFX0102", 0}, /* Infineon */ | ||
615 | {"BCM0101", 0}, /* Broadcom */ | ||
616 | {"NSC1200", 0}, /* National */ | ||
617 | /* Add new here */ | ||
618 | {"", 0}, /* User Specified */ | ||
619 | {"", 0} /* Terminator */ | ||
620 | }; | ||
621 | |||
622 | static struct pnp_driver tis_pnp_driver = { | ||
623 | .name = "tpm_tis", | ||
624 | .id_table = tpm_pnp_tbl, | ||
625 | .probe = tpm_tis_pnp_init, | ||
626 | .suspend = tpm_tis_pnp_suspend, | ||
627 | .resume = tpm_tis_pnp_resume, | ||
628 | }; | ||
629 | |||
630 | #define TIS_HID_USR_IDX sizeof(tpm_pnp_tbl)/sizeof(struct pnp_device_id) -2 | ||
631 | module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, | ||
632 | sizeof(tpm_pnp_tbl[TIS_HID_USR_IDX].id), 0444); | ||
633 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); | ||
634 | |||
635 | static int __init init_tis(void) | ||
636 | { | ||
637 | return pnp_register_driver(&tis_pnp_driver); | ||
638 | } | ||
639 | |||
640 | static void __exit cleanup_tis(void) | ||
641 | { | ||
642 | struct tpm_vendor_specific *i, *j; | ||
643 | struct tpm_chip *chip; | ||
644 | spin_lock(&tis_lock); | ||
645 | list_for_each_entry_safe(i, j, &tis_chips, list) { | ||
646 | chip = to_tpm_chip(i); | ||
647 | iowrite32(~TPM_GLOBAL_INT_ENABLE & | ||
648 | ioread32(chip->vendor.iobase + | ||
649 | TPM_INT_ENABLE(chip->vendor. | ||
650 | locality)), | ||
651 | chip->vendor.iobase + | ||
652 | TPM_INT_ENABLE(chip->vendor.locality)); | ||
653 | release_locality(chip, chip->vendor.locality, 1); | ||
654 | if (chip->vendor.irq) | ||
655 | free_irq(chip->vendor.irq, chip); | ||
656 | iounmap(i->iobase); | ||
657 | list_del(&i->list); | ||
658 | tpm_remove_hardware(chip->dev); | ||
659 | } | ||
660 | spin_unlock(&tis_lock); | ||
661 | pnp_unregister_driver(&tis_pnp_driver); | ||
662 | } | ||
663 | |||
664 | module_init(init_tis); | ||
665 | module_exit(cleanup_tis); | ||
666 | MODULE_AUTHOR("Leendert van Doorn (leendert@watson.ibm.com)"); | ||
667 | MODULE_DESCRIPTION("TPM Driver"); | ||
668 | MODULE_VERSION("2.0"); | ||
669 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c index 841f0bd3eaaf..f07637a8f88f 100644 --- a/drivers/char/tty_io.c +++ b/drivers/char/tty_io.c | |||
@@ -2723,7 +2723,11 @@ static void __do_SAK(void *arg) | |||
2723 | } | 2723 | } |
2724 | task_lock(p); | 2724 | task_lock(p); |
2725 | if (p->files) { | 2725 | if (p->files) { |
2726 | rcu_read_lock(); | 2726 | /* |
2727 | * We don't take a ref to the file, so we must | ||
2728 | * hold ->file_lock instead. | ||
2729 | */ | ||
2730 | spin_lock(&p->files->file_lock); | ||
2727 | fdt = files_fdtable(p->files); | 2731 | fdt = files_fdtable(p->files); |
2728 | for (i=0; i < fdt->max_fds; i++) { | 2732 | for (i=0; i < fdt->max_fds; i++) { |
2729 | filp = fcheck_files(p->files, i); | 2733 | filp = fcheck_files(p->files, i); |
@@ -2738,7 +2742,7 @@ static void __do_SAK(void *arg) | |||
2738 | break; | 2742 | break; |
2739 | } | 2743 | } |
2740 | } | 2744 | } |
2741 | rcu_read_unlock(); | 2745 | spin_unlock(&p->files->file_lock); |
2742 | } | 2746 | } |
2743 | task_unlock(p); | 2747 | task_unlock(p); |
2744 | } while_each_thread(g, p); | 2748 | } while_each_thread(g, p); |
diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 60c9be99c6d9..2cc71b66231e 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig | |||
@@ -99,7 +99,7 @@ config CPU_FREQ_GOV_USERSPACE | |||
99 | Enable this cpufreq governor when you either want to set the | 99 | Enable this cpufreq governor when you either want to set the |
100 | CPU frequency manually or when an userspace program shall | 100 | CPU frequency manually or when an userspace program shall |
101 | be able to set the CPU dynamically, like on LART | 101 | be able to set the CPU dynamically, like on LART |
102 | <http://www.lart.tudelft.nl/> | 102 | <http://www.lartmaker.nl/>. |
103 | 103 | ||
104 | For details, take a look at <file:Documentation/cpu-freq/>. | 104 | For details, take a look at <file:Documentation/cpu-freq/>. |
105 | 105 | ||
diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c index 9b6ae7dc8b8a..29b2fa5534ae 100644 --- a/drivers/cpufreq/cpufreq.c +++ b/drivers/cpufreq/cpufreq.c | |||
@@ -319,7 +319,6 @@ out: | |||
319 | } | 319 | } |
320 | return -EINVAL; | 320 | return -EINVAL; |
321 | } | 321 | } |
322 | EXPORT_SYMBOL_GPL(cpufreq_parse_governor); | ||
323 | 322 | ||
324 | 323 | ||
325 | /* drivers/base/cpu.c */ | 324 | /* drivers/base/cpu.c */ |
@@ -346,6 +345,8 @@ show_one(scaling_min_freq, min); | |||
346 | show_one(scaling_max_freq, max); | 345 | show_one(scaling_max_freq, max); |
347 | show_one(scaling_cur_freq, cur); | 346 | show_one(scaling_cur_freq, cur); |
348 | 347 | ||
348 | static int __cpufreq_set_policy(struct cpufreq_policy *data, struct cpufreq_policy *policy); | ||
349 | |||
349 | /** | 350 | /** |
350 | * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access | 351 | * cpufreq_per_cpu_attr_write() / store_##file_name() - sysfs write access |
351 | */ | 352 | */ |
@@ -364,7 +365,10 @@ static ssize_t store_##file_name \ | |||
364 | if (ret != 1) \ | 365 | if (ret != 1) \ |
365 | return -EINVAL; \ | 366 | return -EINVAL; \ |
366 | \ | 367 | \ |
367 | ret = cpufreq_set_policy(&new_policy); \ | 368 | mutex_lock(&policy->lock); \ |
369 | ret = __cpufreq_set_policy(policy, &new_policy); \ | ||
370 | policy->user_policy.object = policy->object; \ | ||
371 | mutex_unlock(&policy->lock); \ | ||
368 | \ | 372 | \ |
369 | return ret ? ret : count; \ | 373 | return ret ? ret : count; \ |
370 | } | 374 | } |
@@ -420,7 +424,15 @@ static ssize_t store_scaling_governor (struct cpufreq_policy * policy, | |||
420 | if (cpufreq_parse_governor(str_governor, &new_policy.policy, &new_policy.governor)) | 424 | if (cpufreq_parse_governor(str_governor, &new_policy.policy, &new_policy.governor)) |
421 | return -EINVAL; | 425 | return -EINVAL; |
422 | 426 | ||
423 | ret = cpufreq_set_policy(&new_policy); | 427 | /* Do not use cpufreq_set_policy here or the user_policy.max |
428 | will be wrongly overridden */ | ||
429 | mutex_lock(&policy->lock); | ||
430 | ret = __cpufreq_set_policy(policy, &new_policy); | ||
431 | |||
432 | policy->user_policy.policy = policy->policy; | ||
433 | policy->user_policy.governor = policy->governor; | ||
434 | mutex_unlock(&policy->lock); | ||
435 | |||
424 | return ret ? ret : count; | 436 | return ret ? ret : count; |
425 | } | 437 | } |
426 | 438 | ||
@@ -685,7 +697,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
685 | if (!cpu_online(j)) | 697 | if (!cpu_online(j)) |
686 | continue; | 698 | continue; |
687 | 699 | ||
688 | dprintk("CPU already managed, adding link\n"); | 700 | dprintk("CPU %u already managed, adding link\n", j); |
689 | cpufreq_cpu_get(cpu); | 701 | cpufreq_cpu_get(cpu); |
690 | cpu_sys_dev = get_cpu_sysdev(j); | 702 | cpu_sys_dev = get_cpu_sysdev(j); |
691 | sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, | 703 | sysfs_create_link(&cpu_sys_dev->kobj, &policy->kobj, |
@@ -695,9 +707,8 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
695 | policy->governor = NULL; /* to assure that the starting sequence is | 707 | policy->governor = NULL; /* to assure that the starting sequence is |
696 | * run in cpufreq_set_policy */ | 708 | * run in cpufreq_set_policy */ |
697 | mutex_unlock(&policy->lock); | 709 | mutex_unlock(&policy->lock); |
698 | 710 | ||
699 | /* set default policy */ | 711 | /* set default policy */ |
700 | |||
701 | ret = cpufreq_set_policy(&new_policy); | 712 | ret = cpufreq_set_policy(&new_policy); |
702 | if (ret) { | 713 | if (ret) { |
703 | dprintk("setting policy failed\n"); | 714 | dprintk("setting policy failed\n"); |
@@ -707,7 +718,7 @@ static int cpufreq_add_dev (struct sys_device * sys_dev) | |||
707 | module_put(cpufreq_driver->owner); | 718 | module_put(cpufreq_driver->owner); |
708 | dprintk("initialization complete\n"); | 719 | dprintk("initialization complete\n"); |
709 | cpufreq_debug_enable_ratelimit(); | 720 | cpufreq_debug_enable_ratelimit(); |
710 | 721 | ||
711 | return 0; | 722 | return 0; |
712 | 723 | ||
713 | 724 | ||
@@ -1486,7 +1497,7 @@ int cpufreq_update_policy(unsigned int cpu) | |||
1486 | } | 1497 | } |
1487 | EXPORT_SYMBOL(cpufreq_update_policy); | 1498 | EXPORT_SYMBOL(cpufreq_update_policy); |
1488 | 1499 | ||
1489 | static int __cpuinit cpufreq_cpu_callback(struct notifier_block *nfb, | 1500 | static int cpufreq_cpu_callback(struct notifier_block *nfb, |
1490 | unsigned long action, void *hcpu) | 1501 | unsigned long action, void *hcpu) |
1491 | { | 1502 | { |
1492 | unsigned int cpu = (unsigned long)hcpu; | 1503 | unsigned int cpu = (unsigned long)hcpu; |
diff --git a/drivers/cpufreq/cpufreq_conservative.c b/drivers/cpufreq/cpufreq_conservative.c index 037f6bf4543c..e07a35487bde 100644 --- a/drivers/cpufreq/cpufreq_conservative.c +++ b/drivers/cpufreq/cpufreq_conservative.c | |||
@@ -176,8 +176,7 @@ static ssize_t store_up_threshold(struct cpufreq_policy *unused, | |||
176 | ret = sscanf (buf, "%u", &input); | 176 | ret = sscanf (buf, "%u", &input); |
177 | 177 | ||
178 | mutex_lock(&dbs_mutex); | 178 | mutex_lock(&dbs_mutex); |
179 | if (ret != 1 || input > 100 || input < 0 || | 179 | if (ret != 1 || input > 100 || input <= dbs_tuners_ins.down_threshold) { |
180 | input <= dbs_tuners_ins.down_threshold) { | ||
181 | mutex_unlock(&dbs_mutex); | 180 | mutex_unlock(&dbs_mutex); |
182 | return -EINVAL; | 181 | return -EINVAL; |
183 | } | 182 | } |
@@ -196,8 +195,7 @@ static ssize_t store_down_threshold(struct cpufreq_policy *unused, | |||
196 | ret = sscanf (buf, "%u", &input); | 195 | ret = sscanf (buf, "%u", &input); |
197 | 196 | ||
198 | mutex_lock(&dbs_mutex); | 197 | mutex_lock(&dbs_mutex); |
199 | if (ret != 1 || input > 100 || input < 0 || | 198 | if (ret != 1 || input > 100 || input >= dbs_tuners_ins.up_threshold) { |
200 | input >= dbs_tuners_ins.up_threshold) { | ||
201 | mutex_unlock(&dbs_mutex); | 199 | mutex_unlock(&dbs_mutex); |
202 | return -EINVAL; | 200 | return -EINVAL; |
203 | } | 201 | } |
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 8e0f3158215f..dfca74933625 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c | |||
@@ -478,6 +478,11 @@ static s32 i801_access(struct i2c_adapter * adap, u16 addr, | |||
478 | ret = i801_transaction(); | 478 | ret = i801_transaction(); |
479 | } | 479 | } |
480 | 480 | ||
481 | /* Some BIOSes don't like it when PEC is enabled at reboot or resume | ||
482 | time, so we forcibly disable it after every transaction. */ | ||
483 | if (hwpec) | ||
484 | outb_p(0, SMBAUXCTL); | ||
485 | |||
481 | if(block) | 486 | if(block) |
482 | return ret; | 487 | return ret; |
483 | if(ret) | 488 | if(ret) |
diff --git a/drivers/i2c/chips/m41t00.c b/drivers/i2c/chips/m41t00.c index 27fc9ff2961a..99ab4ec34390 100644 --- a/drivers/i2c/chips/m41t00.c +++ b/drivers/i2c/chips/m41t00.c | |||
@@ -131,13 +131,13 @@ m41t00_set(void *arg) | |||
131 | if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) | 131 | if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0) |
132 | || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) | 132 | || (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f) |
133 | < 0) | 133 | < 0) |
134 | || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x7f) | 134 | || (i2c_smbus_write_byte_data(save_client, 2, tm.tm_hour & 0x3f) |
135 | < 0) | 135 | < 0) |
136 | || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x7f) | 136 | || (i2c_smbus_write_byte_data(save_client, 4, tm.tm_mday & 0x3f) |
137 | < 0) | 137 | < 0) |
138 | || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x7f) | 138 | || (i2c_smbus_write_byte_data(save_client, 5, tm.tm_mon & 0x1f) |
139 | < 0) | 139 | < 0) |
140 | || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0x7f) | 140 | || (i2c_smbus_write_byte_data(save_client, 6, tm.tm_year & 0xff) |
141 | < 0)) | 141 | < 0)) |
142 | 142 | ||
143 | dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); | 143 | dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n"); |
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c index cf84350efc55..8b24b4f2a839 100644 --- a/drivers/ide/pci/alim15x3.c +++ b/drivers/ide/pci/alim15x3.c | |||
@@ -731,6 +731,8 @@ static unsigned int __devinit ata66_ali15x3 (ide_hwif_t *hwif) | |||
731 | 731 | ||
732 | if(m5229_revision <= 0x20) | 732 | if(m5229_revision <= 0x20) |
733 | tmpbyte = (tmpbyte & (~0x02)) | 0x01; | 733 | tmpbyte = (tmpbyte & (~0x02)) | 0x01; |
734 | else if (m5229_revision == 0xc7) | ||
735 | tmpbyte |= 0x03; | ||
734 | else | 736 | else |
735 | tmpbyte |= 0x01; | 737 | tmpbyte |= 0x01; |
736 | 738 | ||
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c index df9ee9a78435..900efd1da587 100644 --- a/drivers/ide/pci/atiixp.c +++ b/drivers/ide/pci/atiixp.c | |||
@@ -348,6 +348,7 @@ static struct pci_device_id atiixp_pci_tbl[] = { | |||
348 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 348 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
349 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 349 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
350 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | 350 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, |
351 | { PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, | ||
351 | { 0, }, | 352 | { 0, }, |
352 | }; | 353 | }; |
353 | MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); | 354 | MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl); |
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c index 6f8f8645b02c..7ce5bf783688 100644 --- a/drivers/ide/pci/pdc202xx_old.c +++ b/drivers/ide/pci/pdc202xx_old.c | |||
@@ -798,7 +798,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { | |||
798 | .autodma = AUTODMA, | 798 | .autodma = AUTODMA, |
799 | .bootable = OFF_BOARD, | 799 | .bootable = OFF_BOARD, |
800 | .extra = 48, | 800 | .extra = 48, |
801 | .flags = IDEPCI_FLAG_FORCE_PDC, | ||
802 | },{ /* 2 */ | 801 | },{ /* 2 */ |
803 | .name = "PDC20263", | 802 | .name = "PDC20263", |
804 | .init_setup = init_setup_pdc202ata4, | 803 | .init_setup = init_setup_pdc202ata4, |
@@ -819,7 +818,6 @@ static ide_pci_device_t pdc202xx_chipsets[] __devinitdata = { | |||
819 | .autodma = AUTODMA, | 818 | .autodma = AUTODMA, |
820 | .bootable = OFF_BOARD, | 819 | .bootable = OFF_BOARD, |
821 | .extra = 48, | 820 | .extra = 48, |
822 | .flags = IDEPCI_FLAG_FORCE_PDC, | ||
823 | },{ /* 4 */ | 821 | },{ /* 4 */ |
824 | .name = "PDC20267", | 822 | .name = "PDC20267", |
825 | .init_setup = init_setup_pdc202xx, | 823 | .init_setup = init_setup_pdc202xx, |
diff --git a/drivers/ide/setup-pci.c b/drivers/ide/setup-pci.c index 7ebf992e8c2f..462ed3006c30 100644 --- a/drivers/ide/setup-pci.c +++ b/drivers/ide/setup-pci.c | |||
@@ -580,7 +580,6 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a | |||
580 | int port; | 580 | int port; |
581 | int at_least_one_hwif_enabled = 0; | 581 | int at_least_one_hwif_enabled = 0; |
582 | ide_hwif_t *hwif, *mate = NULL; | 582 | ide_hwif_t *hwif, *mate = NULL; |
583 | static int secondpdc = 0; | ||
584 | u8 tmp; | 583 | u8 tmp; |
585 | 584 | ||
586 | index->all = 0xf0f0; | 585 | index->all = 0xf0f0; |
@@ -592,21 +591,9 @@ void ide_pci_setup_ports(struct pci_dev *dev, ide_pci_device_t *d, int pciirq, a | |||
592 | for (port = 0; port <= 1; ++port) { | 591 | for (port = 0; port <= 1; ++port) { |
593 | ide_pci_enablebit_t *e = &(d->enablebits[port]); | 592 | ide_pci_enablebit_t *e = &(d->enablebits[port]); |
594 | 593 | ||
595 | /* | ||
596 | * If this is a Promise FakeRaid controller, | ||
597 | * the 2nd controller will be marked as | ||
598 | * disabled while it is actually there and enabled | ||
599 | * by the bios for raid purposes. | ||
600 | * Skip the normal "is it enabled" test for those. | ||
601 | */ | ||
602 | if ((d->flags & IDEPCI_FLAG_FORCE_PDC) && | ||
603 | (secondpdc++==1) && (port==1)) | ||
604 | goto controller_ok; | ||
605 | |||
606 | if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || | 594 | if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || |
607 | (tmp & e->mask) != e->val)) | 595 | (tmp & e->mask) != e->val)) |
608 | continue; /* port not enabled */ | 596 | continue; /* port not enabled */ |
609 | controller_ok: | ||
610 | 597 | ||
611 | if (d->channels <= port) | 598 | if (d->channels <= port) |
612 | break; | 599 | break; |
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c index 3a702da83e41..469b6923a2e2 100644 --- a/drivers/infiniband/core/mad.c +++ b/drivers/infiniband/core/mad.c | |||
@@ -228,10 +228,7 @@ struct ib_mad_agent *ib_register_mad_agent(struct ib_device *device, | |||
228 | goto error1; | 228 | goto error1; |
229 | } | 229 | } |
230 | /* Make sure class supplied is consistent with RMPP */ | 230 | /* Make sure class supplied is consistent with RMPP */ |
231 | if (ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) { | 231 | if (!ib_is_mad_class_rmpp(mad_reg_req->mgmt_class)) { |
232 | if (!rmpp_version) | ||
233 | goto error1; | ||
234 | } else { | ||
235 | if (rmpp_version) | 232 | if (rmpp_version) |
236 | goto error1; | 233 | goto error1; |
237 | } | 234 | } |
diff --git a/drivers/infiniband/hw/ipath/ipath_diag.c b/drivers/infiniband/hw/ipath/ipath_diag.c index cd533cf951c2..7d3fb6996b41 100644 --- a/drivers/infiniband/hw/ipath/ipath_diag.c +++ b/drivers/infiniband/hw/ipath/ipath_diag.c | |||
@@ -365,15 +365,3 @@ static ssize_t ipath_diag_write(struct file *fp, const char __user *data, | |||
365 | bail: | 365 | bail: |
366 | return ret; | 366 | return ret; |
367 | } | 367 | } |
368 | |||
369 | void ipath_diag_bringup_link(struct ipath_devdata *dd) | ||
370 | { | ||
371 | if (diag_set_link || (dd->ipath_flags & IPATH_LINKACTIVE)) | ||
372 | return; | ||
373 | |||
374 | diag_set_link = 1; | ||
375 | ipath_cdbg(VERBOSE, "Trying to set to set link active for " | ||
376 | "diag pkt\n"); | ||
377 | ipath_layer_set_linkstate(dd, IPATH_IB_LINKARM); | ||
378 | ipath_layer_set_linkstate(dd, IPATH_IB_LINKACTIVE); | ||
379 | } | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_driver.c b/drivers/infiniband/hw/ipath/ipath_driver.c index 58a94efb0070..e7617c3982ea 100644 --- a/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/drivers/infiniband/hw/ipath/ipath_driver.c | |||
@@ -1729,7 +1729,7 @@ void ipath_free_pddata(struct ipath_devdata *dd, u32 port, int freehdrq) | |||
1729 | } | 1729 | } |
1730 | } | 1730 | } |
1731 | 1731 | ||
1732 | int __init infinipath_init(void) | 1732 | static int __init infinipath_init(void) |
1733 | { | 1733 | { |
1734 | int ret; | 1734 | int ret; |
1735 | 1735 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_intr.c b/drivers/infiniband/hw/ipath/ipath_intr.c index 60f5f4108069..0bcb428041f3 100644 --- a/drivers/infiniband/hw/ipath/ipath_intr.c +++ b/drivers/infiniband/hw/ipath/ipath_intr.c | |||
@@ -172,8 +172,8 @@ static void handle_e_ibstatuschanged(struct ipath_devdata *dd, | |||
172 | "was %s\n", dd->ipath_unit, | 172 | "was %s\n", dd->ipath_unit, |
173 | ib_linkstate(lstate), | 173 | ib_linkstate(lstate), |
174 | ib_linkstate((unsigned) | 174 | ib_linkstate((unsigned) |
175 | dd->ipath_lastibcstat | 175 | dd->ipath_lastibcstat |
176 | & IPATH_IBSTATE_MASK)); | 176 | & IPATH_IBSTATE_MASK)); |
177 | } | 177 | } |
178 | else { | 178 | else { |
179 | lstate = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK; | 179 | lstate = dd->ipath_lastibcstat & IPATH_IBSTATE_MASK; |
diff --git a/drivers/infiniband/hw/ipath/ipath_kernel.h b/drivers/infiniband/hw/ipath/ipath_kernel.h index 159d0aed31a5..0ce5f19c9d62 100644 --- a/drivers/infiniband/hw/ipath/ipath_kernel.h +++ b/drivers/infiniband/hw/ipath/ipath_kernel.h | |||
@@ -528,7 +528,6 @@ extern spinlock_t ipath_devs_lock; | |||
528 | extern struct ipath_devdata *ipath_lookup(int unit); | 528 | extern struct ipath_devdata *ipath_lookup(int unit); |
529 | 529 | ||
530 | extern u16 ipath_layer_rcv_opcode; | 530 | extern u16 ipath_layer_rcv_opcode; |
531 | extern int ipath_verbs_registered; | ||
532 | extern int __ipath_layer_intr(struct ipath_devdata *, u32); | 531 | extern int __ipath_layer_intr(struct ipath_devdata *, u32); |
533 | extern int ipath_layer_intr(struct ipath_devdata *, u32); | 532 | extern int ipath_layer_intr(struct ipath_devdata *, u32); |
534 | extern int __ipath_layer_rcv(struct ipath_devdata *, void *, | 533 | extern int __ipath_layer_rcv(struct ipath_devdata *, void *, |
diff --git a/drivers/infiniband/hw/ipath/ipath_layer.c b/drivers/infiniband/hw/ipath/ipath_layer.c index 2cabf6340572..69ed1100701a 100644 --- a/drivers/infiniband/hw/ipath/ipath_layer.c +++ b/drivers/infiniband/hw/ipath/ipath_layer.c | |||
@@ -52,7 +52,7 @@ static int (*layer_rcv)(void *, void *, struct sk_buff *); | |||
52 | static int (*layer_rcv_lid)(void *, void *); | 52 | static int (*layer_rcv_lid)(void *, void *); |
53 | static int (*verbs_piobufavail)(void *); | 53 | static int (*verbs_piobufavail)(void *); |
54 | static void (*verbs_rcv)(void *, void *, void *, u32); | 54 | static void (*verbs_rcv)(void *, void *, void *, u32); |
55 | int ipath_verbs_registered; | 55 | static int ipath_verbs_registered; |
56 | 56 | ||
57 | static void *(*layer_add_one)(int, struct ipath_devdata *); | 57 | static void *(*layer_add_one)(int, struct ipath_devdata *); |
58 | static void (*layer_remove_one)(void *); | 58 | static void (*layer_remove_one)(void *); |
diff --git a/drivers/infiniband/hw/ipath/ipath_pe800.c b/drivers/infiniband/hw/ipath/ipath_pe800.c index e693a7a82667..e1dc4f757062 100644 --- a/drivers/infiniband/hw/ipath/ipath_pe800.c +++ b/drivers/infiniband/hw/ipath/ipath_pe800.c | |||
@@ -305,8 +305,8 @@ static const struct ipath_cregs ipath_pe_cregs = { | |||
305 | * we'll print them and continue. We reuse the same message buffer as | 305 | * we'll print them and continue. We reuse the same message buffer as |
306 | * ipath_handle_errors() to avoid excessive stack usage. | 306 | * ipath_handle_errors() to avoid excessive stack usage. |
307 | */ | 307 | */ |
308 | void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, | 308 | static void ipath_pe_handle_hwerrors(struct ipath_devdata *dd, char *msg, |
309 | size_t msgl) | 309 | size_t msgl) |
310 | { | 310 | { |
311 | ipath_err_t hwerrs; | 311 | ipath_err_t hwerrs; |
312 | u32 bits, ctrl; | 312 | u32 bits, ctrl; |
@@ -552,7 +552,7 @@ static int ipath_pe_boardname(struct ipath_devdata *dd, char *name, | |||
552 | * freeze mode), and enable hardware errors as errors (along with | 552 | * freeze mode), and enable hardware errors as errors (along with |
553 | * everything else) in errormask | 553 | * everything else) in errormask |
554 | */ | 554 | */ |
555 | void ipath_pe_init_hwerrors(struct ipath_devdata *dd) | 555 | static void ipath_pe_init_hwerrors(struct ipath_devdata *dd) |
556 | { | 556 | { |
557 | ipath_err_t val; | 557 | ipath_err_t val; |
558 | u64 extsval; | 558 | u64 extsval; |
@@ -577,7 +577,7 @@ void ipath_pe_init_hwerrors(struct ipath_devdata *dd) | |||
577 | * ipath_pe_bringup_serdes - bring up the serdes | 577 | * ipath_pe_bringup_serdes - bring up the serdes |
578 | * @dd: the infinipath device | 578 | * @dd: the infinipath device |
579 | */ | 579 | */ |
580 | int ipath_pe_bringup_serdes(struct ipath_devdata *dd) | 580 | static int ipath_pe_bringup_serdes(struct ipath_devdata *dd) |
581 | { | 581 | { |
582 | u64 val, tmp, config1; | 582 | u64 val, tmp, config1; |
583 | int ret = 0, change = 0; | 583 | int ret = 0, change = 0; |
@@ -694,7 +694,7 @@ int ipath_pe_bringup_serdes(struct ipath_devdata *dd) | |||
694 | * @dd: the infinipath device | 694 | * @dd: the infinipath device |
695 | * Called when driver is being unloaded | 695 | * Called when driver is being unloaded |
696 | */ | 696 | */ |
697 | void ipath_pe_quiet_serdes(struct ipath_devdata *dd) | 697 | static void ipath_pe_quiet_serdes(struct ipath_devdata *dd) |
698 | { | 698 | { |
699 | u64 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); | 699 | u64 val = ipath_read_kreg64(dd, dd->ipath_kregs->kr_serdesconfig0); |
700 | 700 | ||
diff --git a/drivers/infiniband/hw/ipath/ipath_qp.c b/drivers/infiniband/hw/ipath/ipath_qp.c index 6058d70d7577..18890716db1e 100644 --- a/drivers/infiniband/hw/ipath/ipath_qp.c +++ b/drivers/infiniband/hw/ipath/ipath_qp.c | |||
@@ -188,8 +188,8 @@ static void free_qpn(struct ipath_qp_table *qpt, u32 qpn) | |||
188 | * Allocate the next available QPN and put the QP into the hash table. | 188 | * Allocate the next available QPN and put the QP into the hash table. |
189 | * The hash table holds a reference to the QP. | 189 | * The hash table holds a reference to the QP. |
190 | */ | 190 | */ |
191 | int ipath_alloc_qpn(struct ipath_qp_table *qpt, struct ipath_qp *qp, | 191 | static int ipath_alloc_qpn(struct ipath_qp_table *qpt, struct ipath_qp *qp, |
192 | enum ib_qp_type type) | 192 | enum ib_qp_type type) |
193 | { | 193 | { |
194 | unsigned long flags; | 194 | unsigned long flags; |
195 | u32 qpn; | 195 | u32 qpn; |
@@ -232,7 +232,7 @@ bail: | |||
232 | * Remove the QP from the table so it can't be found asynchronously by | 232 | * Remove the QP from the table so it can't be found asynchronously by |
233 | * the receive interrupt routine. | 233 | * the receive interrupt routine. |
234 | */ | 234 | */ |
235 | void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp) | 235 | static void ipath_free_qp(struct ipath_qp_table *qpt, struct ipath_qp *qp) |
236 | { | 236 | { |
237 | struct ipath_qp *q, **qpp; | 237 | struct ipath_qp *q, **qpp; |
238 | unsigned long flags; | 238 | unsigned long flags; |
@@ -358,6 +358,65 @@ static void ipath_reset_qp(struct ipath_qp *qp) | |||
358 | } | 358 | } |
359 | 359 | ||
360 | /** | 360 | /** |
361 | * ipath_error_qp - put a QP into an error state | ||
362 | * @qp: the QP to put into an error state | ||
363 | * | ||
364 | * Flushes both send and receive work queues. | ||
365 | * QP r_rq.lock and s_lock should be held. | ||
366 | */ | ||
367 | |||
368 | static void ipath_error_qp(struct ipath_qp *qp) | ||
369 | { | ||
370 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
371 | struct ib_wc wc; | ||
372 | |||
373 | _VERBS_INFO("QP%d/%d in error state\n", | ||
374 | qp->ibqp.qp_num, qp->remote_qpn); | ||
375 | |||
376 | spin_lock(&dev->pending_lock); | ||
377 | /* XXX What if its already removed by the timeout code? */ | ||
378 | if (qp->timerwait.next != LIST_POISON1) | ||
379 | list_del(&qp->timerwait); | ||
380 | if (qp->piowait.next != LIST_POISON1) | ||
381 | list_del(&qp->piowait); | ||
382 | spin_unlock(&dev->pending_lock); | ||
383 | |||
384 | wc.status = IB_WC_WR_FLUSH_ERR; | ||
385 | wc.vendor_err = 0; | ||
386 | wc.byte_len = 0; | ||
387 | wc.imm_data = 0; | ||
388 | wc.qp_num = qp->ibqp.qp_num; | ||
389 | wc.src_qp = 0; | ||
390 | wc.wc_flags = 0; | ||
391 | wc.pkey_index = 0; | ||
392 | wc.slid = 0; | ||
393 | wc.sl = 0; | ||
394 | wc.dlid_path_bits = 0; | ||
395 | wc.port_num = 0; | ||
396 | |||
397 | while (qp->s_last != qp->s_head) { | ||
398 | struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); | ||
399 | |||
400 | wc.wr_id = wqe->wr.wr_id; | ||
401 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
402 | if (++qp->s_last >= qp->s_size) | ||
403 | qp->s_last = 0; | ||
404 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1); | ||
405 | } | ||
406 | qp->s_cur = qp->s_tail = qp->s_head; | ||
407 | qp->s_hdrwords = 0; | ||
408 | qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE; | ||
409 | |||
410 | wc.opcode = IB_WC_RECV; | ||
411 | while (qp->r_rq.tail != qp->r_rq.head) { | ||
412 | wc.wr_id = get_rwqe_ptr(&qp->r_rq, qp->r_rq.tail)->wr_id; | ||
413 | if (++qp->r_rq.tail >= qp->r_rq.size) | ||
414 | qp->r_rq.tail = 0; | ||
415 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); | ||
416 | } | ||
417 | } | ||
418 | |||
419 | /** | ||
361 | * ipath_modify_qp - modify the attributes of a queue pair | 420 | * ipath_modify_qp - modify the attributes of a queue pair |
362 | * @ibqp: the queue pair who's attributes we're modifying | 421 | * @ibqp: the queue pair who's attributes we're modifying |
363 | * @attr: the new attributes | 422 | * @attr: the new attributes |
@@ -821,65 +880,6 @@ void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc) | |||
821 | } | 880 | } |
822 | 881 | ||
823 | /** | 882 | /** |
824 | * ipath_error_qp - put a QP into an error state | ||
825 | * @qp: the QP to put into an error state | ||
826 | * | ||
827 | * Flushes both send and receive work queues. | ||
828 | * QP r_rq.lock and s_lock should be held. | ||
829 | */ | ||
830 | |||
831 | void ipath_error_qp(struct ipath_qp *qp) | ||
832 | { | ||
833 | struct ipath_ibdev *dev = to_idev(qp->ibqp.device); | ||
834 | struct ib_wc wc; | ||
835 | |||
836 | _VERBS_INFO("QP%d/%d in error state\n", | ||
837 | qp->ibqp.qp_num, qp->remote_qpn); | ||
838 | |||
839 | spin_lock(&dev->pending_lock); | ||
840 | /* XXX What if its already removed by the timeout code? */ | ||
841 | if (qp->timerwait.next != LIST_POISON1) | ||
842 | list_del(&qp->timerwait); | ||
843 | if (qp->piowait.next != LIST_POISON1) | ||
844 | list_del(&qp->piowait); | ||
845 | spin_unlock(&dev->pending_lock); | ||
846 | |||
847 | wc.status = IB_WC_WR_FLUSH_ERR; | ||
848 | wc.vendor_err = 0; | ||
849 | wc.byte_len = 0; | ||
850 | wc.imm_data = 0; | ||
851 | wc.qp_num = qp->ibqp.qp_num; | ||
852 | wc.src_qp = 0; | ||
853 | wc.wc_flags = 0; | ||
854 | wc.pkey_index = 0; | ||
855 | wc.slid = 0; | ||
856 | wc.sl = 0; | ||
857 | wc.dlid_path_bits = 0; | ||
858 | wc.port_num = 0; | ||
859 | |||
860 | while (qp->s_last != qp->s_head) { | ||
861 | struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last); | ||
862 | |||
863 | wc.wr_id = wqe->wr.wr_id; | ||
864 | wc.opcode = ib_ipath_wc_opcode[wqe->wr.opcode]; | ||
865 | if (++qp->s_last >= qp->s_size) | ||
866 | qp->s_last = 0; | ||
867 | ipath_cq_enter(to_icq(qp->ibqp.send_cq), &wc, 1); | ||
868 | } | ||
869 | qp->s_cur = qp->s_tail = qp->s_head; | ||
870 | qp->s_hdrwords = 0; | ||
871 | qp->s_ack_state = IB_OPCODE_RC_ACKNOWLEDGE; | ||
872 | |||
873 | wc.opcode = IB_WC_RECV; | ||
874 | while (qp->r_rq.tail != qp->r_rq.head) { | ||
875 | wc.wr_id = get_rwqe_ptr(&qp->r_rq, qp->r_rq.tail)->wr_id; | ||
876 | if (++qp->r_rq.tail >= qp->r_rq.size) | ||
877 | qp->r_rq.tail = 0; | ||
878 | ipath_cq_enter(to_icq(qp->ibqp.recv_cq), &wc, 1); | ||
879 | } | ||
880 | } | ||
881 | |||
882 | /** | ||
883 | * ipath_get_credit - flush the send work queue of a QP | 883 | * ipath_get_credit - flush the send work queue of a QP |
884 | * @qp: the qp who's send work queue to flush | 884 | * @qp: the qp who's send work queue to flush |
885 | * @aeth: the Acknowledge Extended Transport Header | 885 | * @aeth: the Acknowledge Extended Transport Header |
diff --git a/drivers/infiniband/hw/ipath/ipath_ud.c b/drivers/infiniband/hw/ipath/ipath_ud.c index 5ff3de6128b2..01cfb30ee160 100644 --- a/drivers/infiniband/hw/ipath/ipath_ud.c +++ b/drivers/infiniband/hw/ipath/ipath_ud.c | |||
@@ -46,8 +46,8 @@ | |||
46 | * This is called from ipath_post_ud_send() to forward a WQE addressed | 46 | * This is called from ipath_post_ud_send() to forward a WQE addressed |
47 | * to the same HCA. | 47 | * to the same HCA. |
48 | */ | 48 | */ |
49 | void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss, | 49 | static void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss, |
50 | u32 length, struct ib_send_wr *wr, struct ib_wc *wc) | 50 | u32 length, struct ib_send_wr *wr, struct ib_wc *wc) |
51 | { | 51 | { |
52 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); | 52 | struct ipath_ibdev *dev = to_idev(sqp->ibqp.device); |
53 | struct ipath_qp *qp; | 53 | struct ipath_qp *qp; |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c index 9f27fd35cdbb..8d2558a01f35 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.c +++ b/drivers/infiniband/hw/ipath/ipath_verbs.c | |||
@@ -41,7 +41,7 @@ | |||
41 | /* Not static, because we don't want the compiler removing it */ | 41 | /* Not static, because we don't want the compiler removing it */ |
42 | const char ipath_verbs_version[] = "ipath_verbs " IPATH_IDSTR; | 42 | const char ipath_verbs_version[] = "ipath_verbs " IPATH_IDSTR; |
43 | 43 | ||
44 | unsigned int ib_ipath_qp_table_size = 251; | 44 | static unsigned int ib_ipath_qp_table_size = 251; |
45 | module_param_named(qp_table_size, ib_ipath_qp_table_size, uint, S_IRUGO); | 45 | module_param_named(qp_table_size, ib_ipath_qp_table_size, uint, S_IRUGO); |
46 | MODULE_PARM_DESC(qp_table_size, "QP table size"); | 46 | MODULE_PARM_DESC(qp_table_size, "QP table size"); |
47 | 47 | ||
@@ -87,7 +87,7 @@ const enum ib_wc_opcode ib_ipath_wc_opcode[] = { | |||
87 | /* | 87 | /* |
88 | * System image GUID. | 88 | * System image GUID. |
89 | */ | 89 | */ |
90 | __be64 sys_image_guid; | 90 | static __be64 sys_image_guid; |
91 | 91 | ||
92 | /** | 92 | /** |
93 | * ipath_copy_sge - copy data to SGE memory | 93 | * ipath_copy_sge - copy data to SGE memory |
@@ -1110,7 +1110,7 @@ static void ipath_unregister_ib_device(void *arg) | |||
1110 | ib_dealloc_device(ibdev); | 1110 | ib_dealloc_device(ibdev); |
1111 | } | 1111 | } |
1112 | 1112 | ||
1113 | int __init ipath_verbs_init(void) | 1113 | static int __init ipath_verbs_init(void) |
1114 | { | 1114 | { |
1115 | return ipath_verbs_register(ipath_register_ib_device, | 1115 | return ipath_verbs_register(ipath_register_ib_device, |
1116 | ipath_unregister_ib_device, | 1116 | ipath_unregister_ib_device, |
@@ -1118,33 +1118,33 @@ int __init ipath_verbs_init(void) | |||
1118 | ipath_ib_timer); | 1118 | ipath_ib_timer); |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | void __exit ipath_verbs_cleanup(void) | 1121 | static void __exit ipath_verbs_cleanup(void) |
1122 | { | 1122 | { |
1123 | ipath_verbs_unregister(); | 1123 | ipath_verbs_unregister(); |
1124 | } | 1124 | } |
1125 | 1125 | ||
1126 | static ssize_t show_rev(struct class_device *cdev, char *buf) | 1126 | static ssize_t show_rev(struct class_device *cdev, char *buf) |
1127 | { | 1127 | { |
1128 | struct ipath_ibdev *dev = | 1128 | struct ipath_ibdev *dev = |
1129 | container_of(cdev, struct ipath_ibdev, ibdev.class_dev); | 1129 | container_of(cdev, struct ipath_ibdev, ibdev.class_dev); |
1130 | int vendor, boardrev, majrev, minrev; | 1130 | int vendor, boardrev, majrev, minrev; |
1131 | 1131 | ||
1132 | ipath_layer_query_device(dev->dd, &vendor, &boardrev, | 1132 | ipath_layer_query_device(dev->dd, &vendor, &boardrev, |
1133 | &majrev, &minrev); | 1133 | &majrev, &minrev); |
1134 | return sprintf(buf, "%d.%d\n", majrev, minrev); | 1134 | return sprintf(buf, "%d.%d\n", majrev, minrev); |
1135 | } | 1135 | } |
1136 | 1136 | ||
1137 | static ssize_t show_hca(struct class_device *cdev, char *buf) | 1137 | static ssize_t show_hca(struct class_device *cdev, char *buf) |
1138 | { | 1138 | { |
1139 | struct ipath_ibdev *dev = | 1139 | struct ipath_ibdev *dev = |
1140 | container_of(cdev, struct ipath_ibdev, ibdev.class_dev); | 1140 | container_of(cdev, struct ipath_ibdev, ibdev.class_dev); |
1141 | int ret; | 1141 | int ret; |
1142 | 1142 | ||
1143 | ret = ipath_layer_get_boardname(dev->dd, buf, 128); | 1143 | ret = ipath_layer_get_boardname(dev->dd, buf, 128); |
1144 | if (ret < 0) | 1144 | if (ret < 0) |
1145 | goto bail; | 1145 | goto bail; |
1146 | strcat(buf, "\n"); | 1146 | strcat(buf, "\n"); |
1147 | ret = strlen(buf); | 1147 | ret = strlen(buf); |
1148 | 1148 | ||
1149 | bail: | 1149 | bail: |
1150 | return ret; | 1150 | return ret; |
@@ -1152,40 +1152,40 @@ bail: | |||
1152 | 1152 | ||
1153 | static ssize_t show_stats(struct class_device *cdev, char *buf) | 1153 | static ssize_t show_stats(struct class_device *cdev, char *buf) |
1154 | { | 1154 | { |
1155 | struct ipath_ibdev *dev = | 1155 | struct ipath_ibdev *dev = |
1156 | container_of(cdev, struct ipath_ibdev, ibdev.class_dev); | 1156 | container_of(cdev, struct ipath_ibdev, ibdev.class_dev); |
1157 | int i; | 1157 | int i; |
1158 | int len; | 1158 | int len; |
1159 | 1159 | ||
1160 | len = sprintf(buf, | 1160 | len = sprintf(buf, |
1161 | "RC resends %d\n" | 1161 | "RC resends %d\n" |
1162 | "RC QACKs %d\n" | 1162 | "RC QACKs %d\n" |
1163 | "RC ACKs %d\n" | 1163 | "RC ACKs %d\n" |
1164 | "RC SEQ NAKs %d\n" | 1164 | "RC SEQ NAKs %d\n" |
1165 | "RC RDMA seq %d\n" | 1165 | "RC RDMA seq %d\n" |
1166 | "RC RNR NAKs %d\n" | 1166 | "RC RNR NAKs %d\n" |
1167 | "RC OTH NAKs %d\n" | 1167 | "RC OTH NAKs %d\n" |
1168 | "RC timeouts %d\n" | 1168 | "RC timeouts %d\n" |
1169 | "RC RDMA dup %d\n" | 1169 | "RC RDMA dup %d\n" |
1170 | "piobuf wait %d\n" | 1170 | "piobuf wait %d\n" |
1171 | "no piobuf %d\n" | 1171 | "no piobuf %d\n" |
1172 | "PKT drops %d\n" | 1172 | "PKT drops %d\n" |
1173 | "WQE errs %d\n", | 1173 | "WQE errs %d\n", |
1174 | dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks, | 1174 | dev->n_rc_resends, dev->n_rc_qacks, dev->n_rc_acks, |
1175 | dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks, | 1175 | dev->n_seq_naks, dev->n_rdma_seq, dev->n_rnr_naks, |
1176 | dev->n_other_naks, dev->n_timeouts, | 1176 | dev->n_other_naks, dev->n_timeouts, |
1177 | dev->n_rdma_dup_busy, dev->n_piowait, | 1177 | dev->n_rdma_dup_busy, dev->n_piowait, |
1178 | dev->n_no_piobuf, dev->n_pkt_drops, dev->n_wqe_errs); | 1178 | dev->n_no_piobuf, dev->n_pkt_drops, dev->n_wqe_errs); |
1179 | for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) { | 1179 | for (i = 0; i < ARRAY_SIZE(dev->opstats); i++) { |
1180 | const struct ipath_opcode_stats *si = &dev->opstats[i]; | 1180 | const struct ipath_opcode_stats *si = &dev->opstats[i]; |
1181 | 1181 | ||
1182 | if (!si->n_packets && !si->n_bytes) | 1182 | if (!si->n_packets && !si->n_bytes) |
1183 | continue; | 1183 | continue; |
1184 | len += sprintf(buf + len, "%02x %llu/%llu\n", i, | 1184 | len += sprintf(buf + len, "%02x %llu/%llu\n", i, |
1185 | (unsigned long long) si->n_packets, | 1185 | (unsigned long long) si->n_packets, |
1186 | (unsigned long long) si->n_bytes); | 1186 | (unsigned long long) si->n_bytes); |
1187 | } | 1187 | } |
1188 | return len; | 1188 | return len; |
1189 | } | 1189 | } |
1190 | 1190 | ||
1191 | static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); | 1191 | static CLASS_DEVICE_ATTR(hw_rev, S_IRUGO, show_rev, NULL); |
@@ -1194,25 +1194,25 @@ static CLASS_DEVICE_ATTR(board_id, S_IRUGO, show_hca, NULL); | |||
1194 | static CLASS_DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL); | 1194 | static CLASS_DEVICE_ATTR(stats, S_IRUGO, show_stats, NULL); |
1195 | 1195 | ||
1196 | static struct class_device_attribute *ipath_class_attributes[] = { | 1196 | static struct class_device_attribute *ipath_class_attributes[] = { |
1197 | &class_device_attr_hw_rev, | 1197 | &class_device_attr_hw_rev, |
1198 | &class_device_attr_hca_type, | 1198 | &class_device_attr_hca_type, |
1199 | &class_device_attr_board_id, | 1199 | &class_device_attr_board_id, |
1200 | &class_device_attr_stats | 1200 | &class_device_attr_stats |
1201 | }; | 1201 | }; |
1202 | 1202 | ||
1203 | static int ipath_verbs_register_sysfs(struct ib_device *dev) | 1203 | static int ipath_verbs_register_sysfs(struct ib_device *dev) |
1204 | { | 1204 | { |
1205 | int i; | 1205 | int i; |
1206 | int ret; | 1206 | int ret; |
1207 | 1207 | ||
1208 | for (i = 0; i < ARRAY_SIZE(ipath_class_attributes); ++i) | 1208 | for (i = 0; i < ARRAY_SIZE(ipath_class_attributes); ++i) |
1209 | if (class_device_create_file(&dev->class_dev, | 1209 | if (class_device_create_file(&dev->class_dev, |
1210 | ipath_class_attributes[i])) { | 1210 | ipath_class_attributes[i])) { |
1211 | ret = 1; | 1211 | ret = 1; |
1212 | goto bail; | 1212 | goto bail; |
1213 | } | 1213 | } |
1214 | 1214 | ||
1215 | ret = 0; | 1215 | ret = 0; |
1216 | 1216 | ||
1217 | bail: | 1217 | bail: |
1218 | return ret; | 1218 | return ret; |
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.h b/drivers/infiniband/hw/ipath/ipath_verbs.h index b824632b2a8c..fcafbc7c9e71 100644 --- a/drivers/infiniband/hw/ipath/ipath_verbs.h +++ b/drivers/infiniband/hw/ipath/ipath_verbs.h | |||
@@ -577,8 +577,6 @@ int ipath_init_qp_table(struct ipath_ibdev *idev, int size); | |||
577 | 577 | ||
578 | void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc); | 578 | void ipath_sqerror_qp(struct ipath_qp *qp, struct ib_wc *wc); |
579 | 579 | ||
580 | void ipath_error_qp(struct ipath_qp *qp); | ||
581 | |||
582 | void ipath_get_credit(struct ipath_qp *qp, u32 aeth); | 580 | void ipath_get_credit(struct ipath_qp *qp, u32 aeth); |
583 | 581 | ||
584 | void ipath_do_rc_send(unsigned long data); | 582 | void ipath_do_rc_send(unsigned long data); |
@@ -607,9 +605,6 @@ void ipath_rc_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | |||
607 | 605 | ||
608 | void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc); | 606 | void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc); |
609 | 607 | ||
610 | void ipath_ud_loopback(struct ipath_qp *sqp, struct ipath_sge_state *ss, | ||
611 | u32 length, struct ib_send_wr *wr, struct ib_wc *wc); | ||
612 | |||
613 | int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr); | 608 | int ipath_post_ud_send(struct ipath_qp *qp, struct ib_send_wr *wr); |
614 | 609 | ||
615 | void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, | 610 | void ipath_ud_rcv(struct ipath_ibdev *dev, struct ipath_ib_header *hdr, |
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c index f235c7ea42f0..4730863ece9a 100644 --- a/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/drivers/infiniband/hw/mthca/mthca_mad.c | |||
@@ -49,7 +49,7 @@ enum { | |||
49 | MTHCA_VENDOR_CLASS2 = 0xa | 49 | MTHCA_VENDOR_CLASS2 = 0xa |
50 | }; | 50 | }; |
51 | 51 | ||
52 | int mthca_update_rate(struct mthca_dev *dev, u8 port_num) | 52 | static int mthca_update_rate(struct mthca_dev *dev, u8 port_num) |
53 | { | 53 | { |
54 | struct ib_port_attr *tprops = NULL; | 54 | struct ib_port_attr *tprops = NULL; |
55 | int ret; | 55 | int ret; |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index 5f2b3f6e4c47..5bb55742ada6 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -617,6 +617,14 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, | |||
617 | scmnd->sc_data_direction); | 617 | scmnd->sc_data_direction); |
618 | } | 618 | } |
619 | 619 | ||
620 | static void srp_remove_req(struct srp_target_port *target, struct srp_request *req, | ||
621 | int index) | ||
622 | { | ||
623 | list_del(&req->list); | ||
624 | req->next = target->req_head; | ||
625 | target->req_head = index; | ||
626 | } | ||
627 | |||
620 | static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | 628 | static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) |
621 | { | 629 | { |
622 | struct srp_request *req; | 630 | struct srp_request *req; |
@@ -664,9 +672,7 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
664 | scmnd->host_scribble = (void *) -1L; | 672 | scmnd->host_scribble = (void *) -1L; |
665 | scmnd->scsi_done(scmnd); | 673 | scmnd->scsi_done(scmnd); |
666 | 674 | ||
667 | list_del(&req->list); | 675 | srp_remove_req(target, req, rsp->tag & ~SRP_TAG_TSK_MGMT); |
668 | req->next = target->req_head; | ||
669 | target->req_head = rsp->tag & ~SRP_TAG_TSK_MGMT; | ||
670 | } else | 676 | } else |
671 | req->cmd_done = 1; | 677 | req->cmd_done = 1; |
672 | } | 678 | } |
@@ -1188,12 +1194,10 @@ static int srp_send_tsk_mgmt(struct scsi_cmnd *scmnd, u8 func) | |||
1188 | spin_lock_irq(target->scsi_host->host_lock); | 1194 | spin_lock_irq(target->scsi_host->host_lock); |
1189 | 1195 | ||
1190 | if (req->cmd_done) { | 1196 | if (req->cmd_done) { |
1191 | list_del(&req->list); | 1197 | srp_remove_req(target, req, req_index); |
1192 | req->next = target->req_head; | ||
1193 | target->req_head = req_index; | ||
1194 | |||
1195 | scmnd->scsi_done(scmnd); | 1198 | scmnd->scsi_done(scmnd); |
1196 | } else if (!req->tsk_status) { | 1199 | } else if (!req->tsk_status) { |
1200 | srp_remove_req(target, req, req_index); | ||
1197 | scmnd->result = DID_ABORT << 16; | 1201 | scmnd->result = DID_ABORT << 16; |
1198 | ret = SUCCESS; | 1202 | ret = SUCCESS; |
1199 | } | 1203 | } |
diff --git a/drivers/input/keyboard/hil_kbd.c b/drivers/input/keyboard/hil_kbd.c index 1dca3cf42a54..2e4abdc26367 100644 --- a/drivers/input/keyboard/hil_kbd.c +++ b/drivers/input/keyboard/hil_kbd.c | |||
@@ -350,11 +350,11 @@ static int hil_kbd_connect(struct serio *serio, struct serio_driver *drv) | |||
350 | return 0; | 350 | return 0; |
351 | bail2: | 351 | bail2: |
352 | serio_close(serio); | 352 | serio_close(serio); |
353 | serio_set_drvdata(serio, NULL); | ||
353 | bail1: | 354 | bail1: |
354 | input_free_device(kbd->dev); | 355 | input_free_device(kbd->dev); |
355 | bail0: | 356 | bail0: |
356 | kfree(kbd); | 357 | kfree(kbd); |
357 | serio_set_drvdata(serio, NULL); | ||
358 | return -EIO; | 358 | return -EIO; |
359 | } | 359 | } |
360 | 360 | ||
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index f86ed6af3aa2..eb41aba3ddef 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c | |||
@@ -5,8 +5,6 @@ | |||
5 | * Tilman Schmidt <tilman@imap.cc>, | 5 | * Tilman Schmidt <tilman@imap.cc>, |
6 | * Stefan Eilers. | 6 | * Stefan Eilers. |
7 | * | 7 | * |
8 | * Based on usb-gigaset.c. | ||
9 | * | ||
10 | * ===================================================================== | 8 | * ===================================================================== |
11 | * This program is free software; you can redistribute it and/or | 9 | * This program is free software; you can redistribute it and/or |
12 | * modify it under the terms of the GNU General Public License as | 10 | * modify it under the terms of the GNU General Public License as |
@@ -46,19 +44,20 @@ MODULE_PARM_DESC(cidmode, "Call-ID mode"); | |||
46 | #define GIGASET_DEVFSNAME "gig/bas/" | 44 | #define GIGASET_DEVFSNAME "gig/bas/" |
47 | #define GIGASET_DEVNAME "ttyGB" | 45 | #define GIGASET_DEVNAME "ttyGB" |
48 | 46 | ||
49 | #define IF_WRITEBUF 256 //FIXME | 47 | /* length limit according to Siemens 3070usb-protokoll.doc ch. 2.1 */ |
48 | #define IF_WRITEBUF 264 | ||
50 | 49 | ||
51 | /* Values for the Gigaset 307x */ | 50 | /* Values for the Gigaset 307x */ |
52 | #define USB_GIGA_VENDOR_ID 0x0681 | 51 | #define USB_GIGA_VENDOR_ID 0x0681 |
53 | #define USB_GIGA_PRODUCT_ID 0x0001 | 52 | #define USB_3070_PRODUCT_ID 0x0001 |
54 | #define USB_4175_PRODUCT_ID 0x0002 | 53 | #define USB_3075_PRODUCT_ID 0x0002 |
55 | #define USB_SX303_PRODUCT_ID 0x0021 | 54 | #define USB_SX303_PRODUCT_ID 0x0021 |
56 | #define USB_SX353_PRODUCT_ID 0x0022 | 55 | #define USB_SX353_PRODUCT_ID 0x0022 |
57 | 56 | ||
58 | /* table of devices that work with this driver */ | 57 | /* table of devices that work with this driver */ |
59 | static struct usb_device_id gigaset_table [] = { | 58 | static struct usb_device_id gigaset_table [] = { |
60 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_GIGA_PRODUCT_ID) }, | 59 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3070_PRODUCT_ID) }, |
61 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_4175_PRODUCT_ID) }, | 60 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_3075_PRODUCT_ID) }, |
62 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) }, | 61 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX303_PRODUCT_ID) }, |
63 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX353_PRODUCT_ID) }, | 62 | { USB_DEVICE(USB_GIGA_VENDOR_ID, USB_SX353_PRODUCT_ID) }, |
64 | { } /* Terminating entry */ | 63 | { } /* Terminating entry */ |
@@ -77,6 +76,10 @@ static int gigaset_probe(struct usb_interface *interface, | |||
77 | /* Function will be called if the device is unplugged */ | 76 | /* Function will be called if the device is unplugged */ |
78 | static void gigaset_disconnect(struct usb_interface *interface); | 77 | static void gigaset_disconnect(struct usb_interface *interface); |
79 | 78 | ||
79 | static void read_ctrl_callback(struct urb *, struct pt_regs *); | ||
80 | static void stopurbs(struct bas_bc_state *); | ||
81 | static int atwrite_submit(struct cardstate *, unsigned char *, int); | ||
82 | static int start_cbsend(struct cardstate *); | ||
80 | 83 | ||
81 | /*==============================================================================*/ | 84 | /*==============================================================================*/ |
82 | 85 | ||
@@ -111,12 +114,14 @@ struct bas_cardstate { | |||
111 | }; | 114 | }; |
112 | 115 | ||
113 | /* status of direct USB connection to 307x base (bits in basstate) */ | 116 | /* status of direct USB connection to 307x base (bits in basstate) */ |
114 | #define BS_ATOPEN 0x001 | 117 | #define BS_ATOPEN 0x001 /* AT channel open */ |
115 | #define BS_B1OPEN 0x002 | 118 | #define BS_B1OPEN 0x002 /* B channel 1 open */ |
116 | #define BS_B2OPEN 0x004 | 119 | #define BS_B2OPEN 0x004 /* B channel 2 open */ |
117 | #define BS_ATREADY 0x008 | 120 | #define BS_ATREADY 0x008 /* base ready for AT command */ |
118 | #define BS_INIT 0x010 | 121 | #define BS_INIT 0x010 /* base has signalled INIT_OK */ |
119 | #define BS_ATTIMER 0x020 | 122 | #define BS_ATTIMER 0x020 /* waiting for HD_READY_SEND_ATDATA */ |
123 | #define BS_ATRDPEND 0x040 /* urb_cmd_in in use */ | ||
124 | #define BS_ATWRPEND 0x080 /* urb_cmd_out in use */ | ||
120 | 125 | ||
121 | 126 | ||
122 | static struct gigaset_driver *driver = NULL; | 127 | static struct gigaset_driver *driver = NULL; |
@@ -130,6 +135,47 @@ static struct usb_driver gigaset_usb_driver = { | |||
130 | .id_table = gigaset_table, | 135 | .id_table = gigaset_table, |
131 | }; | 136 | }; |
132 | 137 | ||
138 | /* get message text for usb_submit_urb return code | ||
139 | */ | ||
140 | static char *get_usb_rcmsg(int rc) | ||
141 | { | ||
142 | static char unkmsg[28]; | ||
143 | |||
144 | switch (rc) { | ||
145 | case 0: | ||
146 | return "success"; | ||
147 | case -ENOMEM: | ||
148 | return "out of memory"; | ||
149 | case -ENODEV: | ||
150 | return "device not present"; | ||
151 | case -ENOENT: | ||
152 | return "endpoint not present"; | ||
153 | case -ENXIO: | ||
154 | return "URB type not supported"; | ||
155 | case -EINVAL: | ||
156 | return "invalid argument"; | ||
157 | case -EAGAIN: | ||
158 | return "start frame too early or too much scheduled"; | ||
159 | case -EFBIG: | ||
160 | return "too many isochronous frames requested"; | ||
161 | case -EPIPE: | ||
162 | return "endpoint stalled"; | ||
163 | case -EMSGSIZE: | ||
164 | return "invalid packet size"; | ||
165 | case -ENOSPC: | ||
166 | return "would overcommit USB bandwidth"; | ||
167 | case -ESHUTDOWN: | ||
168 | return "device shut down"; | ||
169 | case -EPERM: | ||
170 | return "reject flag set"; | ||
171 | case -EHOSTUNREACH: | ||
172 | return "device suspended"; | ||
173 | default: | ||
174 | snprintf(unkmsg, sizeof(unkmsg), "unknown error %d", rc); | ||
175 | return unkmsg; | ||
176 | } | ||
177 | } | ||
178 | |||
133 | /* get message text for USB status code | 179 | /* get message text for USB status code |
134 | */ | 180 | */ |
135 | static char *get_usb_statmsg(int status) | 181 | static char *get_usb_statmsg(int status) |
@@ -140,43 +186,37 @@ static char *get_usb_statmsg(int status) | |||
140 | case 0: | 186 | case 0: |
141 | return "success"; | 187 | return "success"; |
142 | case -ENOENT: | 188 | case -ENOENT: |
143 | return "canceled"; | 189 | return "unlinked (sync)"; |
144 | case -ECONNRESET: | ||
145 | return "canceled (async)"; | ||
146 | case -EINPROGRESS: | 190 | case -EINPROGRESS: |
147 | return "pending"; | 191 | return "pending"; |
148 | case -EPROTO: | 192 | case -EPROTO: |
149 | return "bit stuffing or unknown USB error"; | 193 | return "bit stuffing error, timeout, or unknown USB error"; |
150 | case -EILSEQ: | 194 | case -EILSEQ: |
151 | return "Illegal byte sequence (CRC mismatch)"; | 195 | return "CRC mismatch, timeout, or unknown USB error"; |
152 | case -EPIPE: | ||
153 | return "babble detect or endpoint stalled"; | ||
154 | case -ENOSR: | ||
155 | return "buffer error"; | ||
156 | case -ETIMEDOUT: | 196 | case -ETIMEDOUT: |
157 | return "timed out"; | 197 | return "timed out"; |
158 | case -ENODEV: | 198 | case -EPIPE: |
159 | return "device not present"; | 199 | return "endpoint stalled"; |
200 | case -ECOMM: | ||
201 | return "IN buffer overrun"; | ||
202 | case -ENOSR: | ||
203 | return "OUT buffer underrun"; | ||
204 | case -EOVERFLOW: | ||
205 | return "too much data"; | ||
160 | case -EREMOTEIO: | 206 | case -EREMOTEIO: |
161 | return "short packet detected"; | 207 | return "short packet detected"; |
208 | case -ENODEV: | ||
209 | return "device removed"; | ||
162 | case -EXDEV: | 210 | case -EXDEV: |
163 | return "partial isochronous transfer"; | 211 | return "partial isochronous transfer"; |
164 | case -EINVAL: | 212 | case -EINVAL: |
165 | return "invalid argument"; | 213 | return "invalid argument"; |
166 | case -ENXIO: | 214 | case -ECONNRESET: |
167 | return "URB already queued"; | 215 | return "unlinked (async)"; |
168 | case -EAGAIN: | ||
169 | return "isochronous start frame too early or too much scheduled"; | ||
170 | case -EFBIG: | ||
171 | return "too many isochronous frames requested"; | ||
172 | case -EMSGSIZE: | ||
173 | return "endpoint message size zero"; | ||
174 | case -ESHUTDOWN: | 216 | case -ESHUTDOWN: |
175 | return "endpoint shutdown"; | 217 | return "device shut down"; |
176 | case -EBUSY: | ||
177 | return "another request pending"; | ||
178 | default: | 218 | default: |
179 | snprintf(unkmsg, sizeof(unkmsg), "unknown error %d", status); | 219 | snprintf(unkmsg, sizeof(unkmsg), "unknown status %d", status); |
180 | return unkmsg; | 220 | return unkmsg; |
181 | } | 221 | } |
182 | } | 222 | } |
@@ -277,18 +317,17 @@ static inline void error_hangup(struct bc_state *bcs) | |||
277 | gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d", | 317 | gig_dbg(DEBUG_ANY, "%s: scheduling HUP for channel %d", |
278 | __func__, bcs->channel); | 318 | __func__, bcs->channel); |
279 | 319 | ||
280 | if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) { | 320 | if (!gigaset_add_event(cs, &bcs->at_state, EV_HUP, NULL, 0, NULL)) |
281 | //FIXME what should we do? | 321 | dev_err(cs->dev, "event queue full\n"); |
282 | return; | ||
283 | } | ||
284 | 322 | ||
285 | gigaset_schedule_event(cs); | 323 | gigaset_schedule_event(cs); |
286 | } | 324 | } |
287 | 325 | ||
288 | /* error_reset | 326 | /* error_reset |
289 | * reset Gigaset device because of an unrecoverable error | 327 | * reset Gigaset device because of an unrecoverable error |
290 | * This function may be called from any context and takes care of scheduling | 328 | * This function may be called from any context, and should take care of |
291 | * the necessary actions for execution outside of interrupt context. | 329 | * scheduling the necessary actions for execution outside of interrupt context. |
330 | * Right now, it just generates a kernel message calling for help. | ||
292 | * argument: | 331 | * argument: |
293 | * controller state structure | 332 | * controller state structure |
294 | */ | 333 | */ |
@@ -364,36 +403,38 @@ static void cmd_in_timeout(unsigned long data) | |||
364 | { | 403 | { |
365 | struct cardstate *cs = (struct cardstate *) data; | 404 | struct cardstate *cs = (struct cardstate *) data; |
366 | struct bas_cardstate *ucs = cs->hw.bas; | 405 | struct bas_cardstate *ucs = cs->hw.bas; |
367 | unsigned long flags; | ||
368 | 406 | ||
369 | spin_lock_irqsave(&cs->lock, flags); | ||
370 | if (unlikely(!cs->connected)) { | ||
371 | gig_dbg(DEBUG_USBREQ, "%s: disconnected", __func__); | ||
372 | spin_unlock_irqrestore(&cs->lock, flags); | ||
373 | return; | ||
374 | } | ||
375 | if (!ucs->rcvbuf_size) { | 407 | if (!ucs->rcvbuf_size) { |
376 | gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); | 408 | gig_dbg(DEBUG_USBREQ, "%s: no receive in progress", __func__); |
377 | spin_unlock_irqrestore(&cs->lock, flags); | ||
378 | return; | 409 | return; |
379 | } | 410 | } |
380 | spin_unlock_irqrestore(&cs->lock, flags); | ||
381 | 411 | ||
382 | dev_err(cs->dev, "timeout reading AT response\n"); | 412 | dev_err(cs->dev, "timeout reading AT response\n"); |
383 | error_reset(cs); //FIXME retry? | 413 | error_reset(cs); //FIXME retry? |
384 | } | 414 | } |
385 | 415 | ||
416 | /* set/clear bits in base connection state, return previous state | ||
417 | */ | ||
418 | inline static int update_basstate(struct bas_cardstate *ucs, | ||
419 | int set, int clear) | ||
420 | { | ||
421 | unsigned long flags; | ||
422 | int state; | ||
386 | 423 | ||
387 | static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs); | 424 | spin_lock_irqsave(&ucs->lock, flags); |
425 | state = atomic_read(&ucs->basstate); | ||
426 | atomic_set(&ucs->basstate, (state & ~clear) | set); | ||
427 | spin_unlock_irqrestore(&ucs->lock, flags); | ||
428 | return state; | ||
429 | } | ||
388 | 430 | ||
389 | /* atread_submit | 431 | /* atread_submit |
390 | * submit an HD_READ_ATMESSAGE command URB | 432 | * submit an HD_READ_ATMESSAGE command URB and optionally start a timeout |
391 | * parameters: | 433 | * parameters: |
392 | * cs controller state structure | 434 | * cs controller state structure |
393 | * timeout timeout in 1/10 sec., 0: none | 435 | * timeout timeout in 1/10 sec., 0: none |
394 | * return value: | 436 | * return value: |
395 | * 0 on success | 437 | * 0 on success |
396 | * -EINVAL if a NULL pointer is encountered somewhere | ||
397 | * -EBUSY if another request is pending | 438 | * -EBUSY if another request is pending |
398 | * any URB submission error code | 439 | * any URB submission error code |
399 | */ | 440 | */ |
@@ -405,7 +446,7 @@ static int atread_submit(struct cardstate *cs, int timeout) | |||
405 | gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", | 446 | gig_dbg(DEBUG_USBREQ, "-------> HD_READ_ATMESSAGE (%d)", |
406 | ucs->rcvbuf_size); | 447 | ucs->rcvbuf_size); |
407 | 448 | ||
408 | if (ucs->urb_cmd_in->status == -EINPROGRESS) { | 449 | if (update_basstate(ucs, BS_ATRDPEND, 0) & BS_ATRDPEND) { |
409 | dev_err(cs->dev, | 450 | dev_err(cs->dev, |
410 | "could not submit HD_READ_ATMESSAGE: URB busy\n"); | 451 | "could not submit HD_READ_ATMESSAGE: URB busy\n"); |
411 | return -EBUSY; | 452 | return -EBUSY; |
@@ -423,6 +464,7 @@ static int atread_submit(struct cardstate *cs, int timeout) | |||
423 | read_ctrl_callback, cs->inbuf); | 464 | read_ctrl_callback, cs->inbuf); |
424 | 465 | ||
425 | if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { | 466 | if ((ret = usb_submit_urb(ucs->urb_cmd_in, SLAB_ATOMIC)) != 0) { |
467 | update_basstate(ucs, 0, BS_ATRDPEND); | ||
426 | dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", | 468 | dev_err(cs->dev, "could not submit HD_READ_ATMESSAGE: %s\n", |
427 | get_usb_statmsg(ret)); | 469 | get_usb_statmsg(ret)); |
428 | return ret; | 470 | return ret; |
@@ -438,26 +480,6 @@ static int atread_submit(struct cardstate *cs, int timeout) | |||
438 | return 0; | 480 | return 0; |
439 | } | 481 | } |
440 | 482 | ||
441 | static void stopurbs(struct bas_bc_state *); | ||
442 | static int start_cbsend(struct cardstate *); | ||
443 | |||
444 | /* set/clear bits in base connection state | ||
445 | */ | ||
446 | inline static void update_basstate(struct bas_cardstate *ucs, | ||
447 | int set, int clear) | ||
448 | { | ||
449 | unsigned long flags; | ||
450 | int state; | ||
451 | |||
452 | spin_lock_irqsave(&ucs->lock, flags); | ||
453 | state = atomic_read(&ucs->basstate); | ||
454 | state &= ~clear; | ||
455 | state |= set; | ||
456 | atomic_set(&ucs->basstate, state); | ||
457 | spin_unlock_irqrestore(&ucs->lock, flags); | ||
458 | } | ||
459 | |||
460 | |||
461 | /* read_int_callback | 483 | /* read_int_callback |
462 | * USB completion handler for interrupt pipe input | 484 | * USB completion handler for interrupt pipe input |
463 | * called by the USB subsystem in interrupt context | 485 | * called by the USB subsystem in interrupt context |
@@ -471,20 +493,25 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
471 | struct bas_cardstate *ucs = cs->hw.bas; | 493 | struct bas_cardstate *ucs = cs->hw.bas; |
472 | struct bc_state *bcs; | 494 | struct bc_state *bcs; |
473 | unsigned long flags; | 495 | unsigned long flags; |
474 | int status; | 496 | int rc; |
475 | unsigned l; | 497 | unsigned l; |
476 | int channel; | 498 | int channel; |
477 | 499 | ||
478 | switch (urb->status) { | 500 | switch (urb->status) { |
479 | case 0: /* success */ | 501 | case 0: /* success */ |
480 | break; | 502 | break; |
481 | case -ENOENT: /* canceled */ | 503 | case -ENOENT: /* cancelled */ |
482 | case -ECONNRESET: /* canceled (async) */ | 504 | case -ECONNRESET: /* cancelled (async) */ |
483 | case -EINPROGRESS: /* pending */ | 505 | case -EINPROGRESS: /* pending */ |
484 | /* ignore silently */ | 506 | /* ignore silently */ |
485 | gig_dbg(DEBUG_USBREQ, "%s: %s", | 507 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
486 | __func__, get_usb_statmsg(urb->status)); | 508 | __func__, get_usb_statmsg(urb->status)); |
487 | return; | 509 | return; |
510 | case -ENODEV: /* device removed */ | ||
511 | case -ESHUTDOWN: /* device shut down */ | ||
512 | //FIXME use this as disconnect indicator? | ||
513 | gig_dbg(DEBUG_USBREQ, "%s: device disconnected", __func__); | ||
514 | return; | ||
488 | default: /* severe trouble */ | 515 | default: /* severe trouble */ |
489 | dev_warn(cs->dev, "interrupt read: %s\n", | 516 | dev_warn(cs->dev, "interrupt read: %s\n", |
490 | get_usb_statmsg(urb->status)); | 517 | get_usb_statmsg(urb->status)); |
@@ -492,6 +519,13 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
492 | goto resubmit; | 519 | goto resubmit; |
493 | } | 520 | } |
494 | 521 | ||
522 | /* drop incomplete packets even if the missing bytes wouldn't matter */ | ||
523 | if (unlikely(urb->actual_length < 3)) { | ||
524 | dev_warn(cs->dev, "incomplete interrupt packet (%d bytes)\n", | ||
525 | urb->actual_length); | ||
526 | goto resubmit; | ||
527 | } | ||
528 | |||
495 | l = (unsigned) ucs->int_in_buf[1] + | 529 | l = (unsigned) ucs->int_in_buf[1] + |
496 | (((unsigned) ucs->int_in_buf[2]) << 8); | 530 | (((unsigned) ucs->int_in_buf[2]) << 8); |
497 | 531 | ||
@@ -558,25 +592,28 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
558 | } | 592 | } |
559 | spin_lock_irqsave(&cs->lock, flags); | 593 | spin_lock_irqsave(&cs->lock, flags); |
560 | if (ucs->rcvbuf_size) { | 594 | if (ucs->rcvbuf_size) { |
561 | spin_unlock_irqrestore(&cs->lock, flags); | 595 | /* throw away previous buffer - we have no queue */ |
562 | dev_err(cs->dev, | 596 | dev_err(cs->dev, |
563 | "receive AT data overrun, %d bytes lost\n", l); | 597 | "receive AT data overrun, %d bytes lost\n", |
564 | error_reset(cs); //FIXME reschedule | 598 | ucs->rcvbuf_size); |
565 | break; | 599 | kfree(ucs->rcvbuf); |
600 | ucs->rcvbuf_size = 0; | ||
566 | } | 601 | } |
567 | if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { | 602 | if ((ucs->rcvbuf = kmalloc(l, GFP_ATOMIC)) == NULL) { |
568 | spin_unlock_irqrestore(&cs->lock, flags); | 603 | spin_unlock_irqrestore(&cs->lock, flags); |
569 | dev_err(cs->dev, "out of memory, %d bytes lost\n", l); | 604 | dev_err(cs->dev, "out of memory receiving AT data\n"); |
570 | error_reset(cs); //FIXME reschedule | 605 | error_reset(cs); |
571 | break; | 606 | break; |
572 | } | 607 | } |
573 | ucs->rcvbuf_size = l; | 608 | ucs->rcvbuf_size = l; |
574 | ucs->retry_cmd_in = 0; | 609 | ucs->retry_cmd_in = 0; |
575 | if ((status = atread_submit(cs, BAS_TIMEOUT)) < 0) { | 610 | if ((rc = atread_submit(cs, BAS_TIMEOUT)) < 0) { |
576 | kfree(ucs->rcvbuf); | 611 | kfree(ucs->rcvbuf); |
577 | ucs->rcvbuf = NULL; | 612 | ucs->rcvbuf = NULL; |
578 | ucs->rcvbuf_size = 0; | 613 | ucs->rcvbuf_size = 0; |
579 | error_reset(cs); //FIXME reschedule | 614 | if (rc != -ENODEV) |
615 | //FIXME corrective action? | ||
616 | error_reset(cs); | ||
580 | } | 617 | } |
581 | spin_unlock_irqrestore(&cs->lock, flags); | 618 | spin_unlock_irqrestore(&cs->lock, flags); |
582 | break; | 619 | break; |
@@ -598,12 +635,10 @@ static void read_int_callback(struct urb *urb, struct pt_regs *regs) | |||
598 | check_pending(ucs); | 635 | check_pending(ucs); |
599 | 636 | ||
600 | resubmit: | 637 | resubmit: |
601 | spin_lock_irqsave(&cs->lock, flags); | 638 | rc = usb_submit_urb(urb, SLAB_ATOMIC); |
602 | status = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | 639 | if (unlikely(rc != 0 && rc != -ENODEV)) { |
603 | spin_unlock_irqrestore(&cs->lock, flags); | ||
604 | if (unlikely(status)) { | ||
605 | dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", | 640 | dev_err(cs->dev, "could not resubmit interrupt URB: %s\n", |
606 | get_usb_statmsg(status)); | 641 | get_usb_rcmsg(rc)); |
607 | error_reset(cs); | 642 | error_reset(cs); |
608 | } | 643 | } |
609 | } | 644 | } |
@@ -622,18 +657,12 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
622 | struct bas_cardstate *ucs = cs->hw.bas; | 657 | struct bas_cardstate *ucs = cs->hw.bas; |
623 | int have_data = 0; | 658 | int have_data = 0; |
624 | unsigned numbytes; | 659 | unsigned numbytes; |
625 | unsigned long flags; | 660 | int rc; |
626 | 661 | ||
627 | spin_lock_irqsave(&cs->lock, flags); | 662 | update_basstate(ucs, 0, BS_ATRDPEND); |
628 | if (unlikely(!cs->connected)) { | ||
629 | warn("%s: disconnected", __func__); | ||
630 | spin_unlock_irqrestore(&cs->lock, flags); | ||
631 | return; | ||
632 | } | ||
633 | 663 | ||
634 | if (!ucs->rcvbuf_size) { | 664 | if (!ucs->rcvbuf_size) { |
635 | dev_warn(cs->dev, "%s: no receive in progress\n", __func__); | 665 | dev_warn(cs->dev, "%s: no receive in progress\n", __func__); |
636 | spin_unlock_irqrestore(&cs->lock, flags); | ||
637 | return; | 666 | return; |
638 | } | 667 | } |
639 | 668 | ||
@@ -666,9 +695,11 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
666 | } | 695 | } |
667 | break; | 696 | break; |
668 | 697 | ||
669 | case -ENOENT: /* canceled */ | 698 | case -ENOENT: /* cancelled */ |
670 | case -ECONNRESET: /* canceled (async) */ | 699 | case -ECONNRESET: /* cancelled (async) */ |
671 | case -EINPROGRESS: /* pending */ | 700 | case -EINPROGRESS: /* pending */ |
701 | case -ENODEV: /* device removed */ | ||
702 | case -ESHUTDOWN: /* device shut down */ | ||
672 | /* no action necessary */ | 703 | /* no action necessary */ |
673 | gig_dbg(DEBUG_USBREQ, "%s: %s", | 704 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
674 | __func__, get_usb_statmsg(urb->status)); | 705 | __func__, get_usb_statmsg(urb->status)); |
@@ -681,11 +712,11 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
681 | if (ucs->retry_cmd_in++ < BAS_RETRY) { | 712 | if (ucs->retry_cmd_in++ < BAS_RETRY) { |
682 | dev_notice(cs->dev, "control read: retry %d\n", | 713 | dev_notice(cs->dev, "control read: retry %d\n", |
683 | ucs->retry_cmd_in); | 714 | ucs->retry_cmd_in); |
684 | if (atread_submit(cs, BAS_TIMEOUT) >= 0) { | 715 | rc = atread_submit(cs, BAS_TIMEOUT); |
685 | /* resubmitted - bypass regular exit block */ | 716 | if (rc >= 0 || rc == -ENODEV) |
686 | spin_unlock_irqrestore(&cs->lock, flags); | 717 | /* resubmitted or disconnected */ |
718 | /* - bypass regular exit block */ | ||
687 | return; | 719 | return; |
688 | } | ||
689 | } else { | 720 | } else { |
690 | dev_err(cs->dev, | 721 | dev_err(cs->dev, |
691 | "control read: giving up after %d tries\n", | 722 | "control read: giving up after %d tries\n", |
@@ -697,7 +728,6 @@ static void read_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
697 | kfree(ucs->rcvbuf); | 728 | kfree(ucs->rcvbuf); |
698 | ucs->rcvbuf = NULL; | 729 | ucs->rcvbuf = NULL; |
699 | ucs->rcvbuf_size = 0; | 730 | ucs->rcvbuf_size = 0; |
700 | spin_unlock_irqrestore(&cs->lock, flags); | ||
701 | if (have_data) { | 731 | if (have_data) { |
702 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); | 732 | gig_dbg(DEBUG_INTR, "%s-->BH", __func__); |
703 | gigaset_schedule_event(cs); | 733 | gigaset_schedule_event(cs); |
@@ -719,8 +749,11 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
719 | int i, rc; | 749 | int i, rc; |
720 | 750 | ||
721 | /* status codes not worth bothering the tasklet with */ | 751 | /* status codes not worth bothering the tasklet with */ |
722 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || | 752 | if (unlikely(urb->status == -ENOENT || |
723 | urb->status == -EINPROGRESS)) { | 753 | urb->status == -ECONNRESET || |
754 | urb->status == -EINPROGRESS || | ||
755 | urb->status == -ENODEV || | ||
756 | urb->status == -ESHUTDOWN)) { | ||
724 | gig_dbg(DEBUG_ISO, "%s: %s", | 757 | gig_dbg(DEBUG_ISO, "%s: %s", |
725 | __func__, get_usb_statmsg(urb->status)); | 758 | __func__, get_usb_statmsg(urb->status)); |
726 | return; | 759 | return; |
@@ -740,9 +773,9 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
740 | for (i = 0; i < BAS_NUMFRAMES; i++) { | 773 | for (i = 0; i < BAS_NUMFRAMES; i++) { |
741 | ubc->isoinlost += urb->iso_frame_desc[i].actual_length; | 774 | ubc->isoinlost += urb->iso_frame_desc[i].actual_length; |
742 | if (unlikely(urb->iso_frame_desc[i].status != 0 && | 775 | if (unlikely(urb->iso_frame_desc[i].status != 0 && |
743 | urb->iso_frame_desc[i].status != -EINPROGRESS)) { | 776 | urb->iso_frame_desc[i].status != |
777 | -EINPROGRESS)) | ||
744 | ubc->loststatus = urb->iso_frame_desc[i].status; | 778 | ubc->loststatus = urb->iso_frame_desc[i].status; |
745 | } | ||
746 | urb->iso_frame_desc[i].status = 0; | 779 | urb->iso_frame_desc[i].status = 0; |
747 | urb->iso_frame_desc[i].actual_length = 0; | 780 | urb->iso_frame_desc[i].actual_length = 0; |
748 | } | 781 | } |
@@ -754,10 +787,10 @@ static void read_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
754 | gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", | 787 | gig_dbg(DEBUG_ISO, "%s: isoc read overrun/resubmit", |
755 | __func__); | 788 | __func__); |
756 | rc = usb_submit_urb(urb, SLAB_ATOMIC); | 789 | rc = usb_submit_urb(urb, SLAB_ATOMIC); |
757 | if (unlikely(rc != 0)) { | 790 | if (unlikely(rc != 0 && rc != -ENODEV)) { |
758 | dev_err(bcs->cs->dev, | 791 | dev_err(bcs->cs->dev, |
759 | "could not resubmit isochronous read " | 792 | "could not resubmit isochronous read " |
760 | "URB: %s\n", get_usb_statmsg(rc)); | 793 | "URB: %s\n", get_usb_rcmsg(rc)); |
761 | dump_urb(DEBUG_ISO, "isoc read", urb); | 794 | dump_urb(DEBUG_ISO, "isoc read", urb); |
762 | error_hangup(bcs); | 795 | error_hangup(bcs); |
763 | } | 796 | } |
@@ -780,8 +813,11 @@ static void write_iso_callback(struct urb *urb, struct pt_regs *regs) | |||
780 | unsigned long flags; | 813 | unsigned long flags; |
781 | 814 | ||
782 | /* status codes not worth bothering the tasklet with */ | 815 | /* status codes not worth bothering the tasklet with */ |
783 | if (unlikely(urb->status == -ENOENT || urb->status == -ECONNRESET || | 816 | if (unlikely(urb->status == -ENOENT || |
784 | urb->status == -EINPROGRESS)) { | 817 | urb->status == -ECONNRESET || |
818 | urb->status == -EINPROGRESS || | ||
819 | urb->status == -ENODEV || | ||
820 | urb->status == -ESHUTDOWN)) { | ||
785 | gig_dbg(DEBUG_ISO, "%s: %s", | 821 | gig_dbg(DEBUG_ISO, "%s: %s", |
786 | __func__, get_usb_statmsg(urb->status)); | 822 | __func__, get_usb_statmsg(urb->status)); |
787 | return; | 823 | return; |
@@ -822,7 +858,6 @@ static int starturbs(struct bc_state *bcs) | |||
822 | for (k = 0; k < BAS_INURBS; k++) { | 858 | for (k = 0; k < BAS_INURBS; k++) { |
823 | urb = ubc->isoinurbs[k]; | 859 | urb = ubc->isoinurbs[k]; |
824 | if (!urb) { | 860 | if (!urb) { |
825 | dev_err(bcs->cs->dev, "isoinurbs[%d]==NULL\n", k); | ||
826 | rc = -EFAULT; | 861 | rc = -EFAULT; |
827 | goto error; | 862 | goto error; |
828 | } | 863 | } |
@@ -844,12 +879,8 @@ static int starturbs(struct bc_state *bcs) | |||
844 | } | 879 | } |
845 | 880 | ||
846 | dump_urb(DEBUG_ISO, "Initial isoc read", urb); | 881 | dump_urb(DEBUG_ISO, "Initial isoc read", urb); |
847 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) { | 882 | if ((rc = usb_submit_urb(urb, SLAB_ATOMIC)) != 0) |
848 | dev_err(bcs->cs->dev, | ||
849 | "could not submit isochronous read URB %d: %s\n", | ||
850 | k, get_usb_statmsg(rc)); | ||
851 | goto error; | 883 | goto error; |
852 | } | ||
853 | } | 884 | } |
854 | 885 | ||
855 | /* initialize L2 transmission */ | 886 | /* initialize L2 transmission */ |
@@ -859,7 +890,6 @@ static int starturbs(struct bc_state *bcs) | |||
859 | for (k = 0; k < BAS_OUTURBS; ++k) { | 890 | for (k = 0; k < BAS_OUTURBS; ++k) { |
860 | urb = ubc->isoouturbs[k].urb; | 891 | urb = ubc->isoouturbs[k].urb; |
861 | if (!urb) { | 892 | if (!urb) { |
862 | dev_err(bcs->cs->dev, "isoouturbs[%d].urb==NULL\n", k); | ||
863 | rc = -EFAULT; | 893 | rc = -EFAULT; |
864 | goto error; | 894 | goto error; |
865 | } | 895 | } |
@@ -885,12 +915,8 @@ static int starturbs(struct bc_state *bcs) | |||
885 | for (k = 0; k < 2; ++k) { | 915 | for (k = 0; k < 2; ++k) { |
886 | dump_urb(DEBUG_ISO, "Initial isoc write", urb); | 916 | dump_urb(DEBUG_ISO, "Initial isoc write", urb); |
887 | rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); | 917 | rc = usb_submit_urb(ubc->isoouturbs[k].urb, SLAB_ATOMIC); |
888 | if (rc != 0) { | 918 | if (rc != 0) |
889 | dev_err(bcs->cs->dev, | ||
890 | "could not submit isochronous write URB %d: %s\n", | ||
891 | k, get_usb_statmsg(rc)); | ||
892 | goto error; | 919 | goto error; |
893 | } | ||
894 | } | 920 | } |
895 | dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb); | 921 | dump_urb(DEBUG_ISO, "Initial isoc write (free)", urb); |
896 | ubc->isooutfree = &ubc->isoouturbs[2]; | 922 | ubc->isooutfree = &ubc->isoouturbs[2]; |
@@ -916,15 +942,15 @@ static void stopurbs(struct bas_bc_state *ubc) | |||
916 | for (k = 0; k < BAS_INURBS; ++k) { | 942 | for (k = 0; k < BAS_INURBS; ++k) { |
917 | rc = usb_unlink_urb(ubc->isoinurbs[k]); | 943 | rc = usb_unlink_urb(ubc->isoinurbs[k]); |
918 | gig_dbg(DEBUG_ISO, | 944 | gig_dbg(DEBUG_ISO, |
919 | "%s: isoc input URB %d unlinked, result = %d", | 945 | "%s: isoc input URB %d unlinked, result = %s", |
920 | __func__, k, rc); | 946 | __func__, k, get_usb_rcmsg(rc)); |
921 | } | 947 | } |
922 | 948 | ||
923 | for (k = 0; k < BAS_OUTURBS; ++k) { | 949 | for (k = 0; k < BAS_OUTURBS; ++k) { |
924 | rc = usb_unlink_urb(ubc->isoouturbs[k].urb); | 950 | rc = usb_unlink_urb(ubc->isoouturbs[k].urb); |
925 | gig_dbg(DEBUG_ISO, | 951 | gig_dbg(DEBUG_ISO, |
926 | "%s: isoc output URB %d unlinked, result = %d", | 952 | "%s: isoc output URB %d unlinked, result = %s", |
927 | __func__, k, rc); | 953 | __func__, k, get_usb_rcmsg(rc)); |
928 | } | 954 | } |
929 | } | 955 | } |
930 | 956 | ||
@@ -934,7 +960,7 @@ static void stopurbs(struct bas_bc_state *ubc) | |||
934 | /* submit_iso_write_urb | 960 | /* submit_iso_write_urb |
935 | * fill and submit the next isochronous write URB | 961 | * fill and submit the next isochronous write URB |
936 | * parameters: | 962 | * parameters: |
937 | * bcs B channel state structure | 963 | * ucx context structure containing URB |
938 | * return value: | 964 | * return value: |
939 | * number of frames submitted in URB | 965 | * number of frames submitted in URB |
940 | * 0 if URB not submitted because no data available (isooutbuf busy) | 966 | * 0 if URB not submitted because no data available (isooutbuf busy) |
@@ -946,7 +972,6 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
946 | struct bas_bc_state *ubc = ucx->bcs->hw.bas; | 972 | struct bas_bc_state *ubc = ucx->bcs->hw.bas; |
947 | struct usb_iso_packet_descriptor *ifd; | 973 | struct usb_iso_packet_descriptor *ifd; |
948 | int corrbytes, nframe, rc; | 974 | int corrbytes, nframe, rc; |
949 | unsigned long flags; | ||
950 | 975 | ||
951 | /* urb->dev is clobbered by USB subsystem */ | 976 | /* urb->dev is clobbered by USB subsystem */ |
952 | urb->dev = ucx->bcs->cs->hw.bas->udev; | 977 | urb->dev = ucx->bcs->cs->hw.bas->udev; |
@@ -992,20 +1017,22 @@ static int submit_iso_write_urb(struct isow_urbctx_t *ucx) | |||
992 | ifd->status = 0; | 1017 | ifd->status = 0; |
993 | ifd->actual_length = 0; | 1018 | ifd->actual_length = 0; |
994 | } | 1019 | } |
995 | if ((urb->number_of_packets = nframe) > 0) { | 1020 | if (unlikely(nframe == 0)) |
996 | spin_lock_irqsave(&ucx->bcs->cs->lock, flags); | 1021 | return 0; /* no data to send */ |
997 | rc = ucx->bcs->cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | 1022 | urb->number_of_packets = nframe; |
998 | spin_unlock_irqrestore(&ucx->bcs->cs->lock, flags); | ||
999 | 1023 | ||
1000 | if (rc) { | 1024 | rc = usb_submit_urb(urb, SLAB_ATOMIC); |
1025 | if (unlikely(rc)) { | ||
1026 | if (rc == -ENODEV) | ||
1027 | /* device removed - give up silently */ | ||
1028 | gig_dbg(DEBUG_ISO, "%s: disconnected", __func__); | ||
1029 | else | ||
1001 | dev_err(ucx->bcs->cs->dev, | 1030 | dev_err(ucx->bcs->cs->dev, |
1002 | "could not submit isochronous write URB: %s\n", | 1031 | "could not submit isochronous write URB: %s\n", |
1003 | get_usb_statmsg(rc)); | 1032 | get_usb_rcmsg(rc)); |
1004 | dump_urb(DEBUG_ISO, "isoc write", urb); | 1033 | return rc; |
1005 | return rc; | ||
1006 | } | ||
1007 | ++ubc->numsub; | ||
1008 | } | 1034 | } |
1035 | ++ubc->numsub; | ||
1009 | return nframe; | 1036 | return nframe; |
1010 | } | 1037 | } |
1011 | 1038 | ||
@@ -1028,6 +1055,7 @@ static void write_iso_tasklet(unsigned long data) | |||
1028 | int i; | 1055 | int i; |
1029 | struct sk_buff *skb; | 1056 | struct sk_buff *skb; |
1030 | int len; | 1057 | int len; |
1058 | int rc; | ||
1031 | 1059 | ||
1032 | /* loop while completed URBs arrive in time */ | 1060 | /* loop while completed URBs arrive in time */ |
1033 | for (;;) { | 1061 | for (;;) { |
@@ -1057,7 +1085,8 @@ static void write_iso_tasklet(unsigned long data) | |||
1057 | ubc->isooutfree = NULL; | 1085 | ubc->isooutfree = NULL; |
1058 | spin_unlock_irqrestore(&ubc->isooutlock, flags); | 1086 | spin_unlock_irqrestore(&ubc->isooutlock, flags); |
1059 | if (next) { | 1087 | if (next) { |
1060 | if (submit_iso_write_urb(next) <= 0) { | 1088 | rc = submit_iso_write_urb(next); |
1089 | if (unlikely(rc <= 0 && rc != -ENODEV)) { | ||
1061 | /* could not submit URB, put it back */ | 1090 | /* could not submit URB, put it back */ |
1062 | spin_lock_irqsave(&ubc->isooutlock, flags); | 1091 | spin_lock_irqsave(&ubc->isooutlock, flags); |
1063 | if (ubc->isooutfree == NULL) { | 1092 | if (ubc->isooutfree == NULL) { |
@@ -1077,17 +1106,18 @@ static void write_iso_tasklet(unsigned long data) | |||
1077 | /* process completed URB */ | 1106 | /* process completed URB */ |
1078 | urb = done->urb; | 1107 | urb = done->urb; |
1079 | switch (urb->status) { | 1108 | switch (urb->status) { |
1109 | case -EXDEV: /* partial completion */ | ||
1110 | gig_dbg(DEBUG_ISO, "%s: URB partially completed", | ||
1111 | __func__); | ||
1112 | /* fall through - what's the difference anyway? */ | ||
1080 | case 0: /* normal completion */ | 1113 | case 0: /* normal completion */ |
1081 | break; | 1114 | /* inspect individual frames |
1082 | case -EXDEV: /* inspect individual frames */ | 1115 | * assumptions (for lack of documentation): |
1083 | /* assumptions (for lack of documentation): | 1116 | * - actual_length bytes of first frame in error are |
1084 | * - actual_length bytes of the frame in error are | ||
1085 | * successfully sent | 1117 | * successfully sent |
1086 | * - all following frames are not sent at all | 1118 | * - all following frames are not sent at all |
1087 | */ | 1119 | */ |
1088 | gig_dbg(DEBUG_ISO, "%s: URB partially completed", | 1120 | offset = done->limit; /* default (no error) */ |
1089 | __func__); | ||
1090 | offset = done->limit; /* just in case */ | ||
1091 | for (i = 0; i < BAS_NUMFRAMES; i++) { | 1121 | for (i = 0; i < BAS_NUMFRAMES; i++) { |
1092 | ifd = &urb->iso_frame_desc[i]; | 1122 | ifd = &urb->iso_frame_desc[i]; |
1093 | if (ifd->status || | 1123 | if (ifd->status || |
@@ -1122,7 +1152,7 @@ static void write_iso_tasklet(unsigned long data) | |||
1122 | } | 1152 | } |
1123 | #endif | 1153 | #endif |
1124 | break; | 1154 | break; |
1125 | case -EPIPE: //FIXME is this the code for "underrun"? | 1155 | case -EPIPE: /* stall - probably underrun */ |
1126 | dev_err(cs->dev, "isochronous write stalled\n"); | 1156 | dev_err(cs->dev, "isochronous write stalled\n"); |
1127 | error_hangup(bcs); | 1157 | error_hangup(bcs); |
1128 | break; | 1158 | break; |
@@ -1142,7 +1172,8 @@ static void write_iso_tasklet(unsigned long data) | |||
1142 | spin_unlock_irqrestore(&ubc->isooutlock, flags); | 1172 | spin_unlock_irqrestore(&ubc->isooutlock, flags); |
1143 | if (next) { | 1173 | if (next) { |
1144 | /* only one URB still active - resubmit one */ | 1174 | /* only one URB still active - resubmit one */ |
1145 | if (submit_iso_write_urb(next) <= 0) { | 1175 | rc = submit_iso_write_urb(next); |
1176 | if (unlikely(rc <= 0 && rc != -ENODEV)) { | ||
1146 | /* couldn't submit */ | 1177 | /* couldn't submit */ |
1147 | error_hangup(bcs); | 1178 | error_hangup(bcs); |
1148 | } | 1179 | } |
@@ -1222,10 +1253,9 @@ static void read_iso_tasklet(unsigned long data) | |||
1222 | break; | 1253 | break; |
1223 | case -ENOENT: | 1254 | case -ENOENT: |
1224 | case -ECONNRESET: | 1255 | case -ECONNRESET: |
1225 | gig_dbg(DEBUG_ISO, "%s: URB canceled", __func__); | 1256 | case -EINPROGRESS: |
1226 | continue; /* -> skip */ | 1257 | gig_dbg(DEBUG_ISO, "%s: %s", |
1227 | case -EINPROGRESS: /* huh? */ | 1258 | __func__, get_usb_statmsg(urb->status)); |
1228 | gig_dbg(DEBUG_ISO, "%s: URB still pending", __func__); | ||
1229 | continue; /* -> skip */ | 1259 | continue; /* -> skip */ |
1230 | case -EPIPE: | 1260 | case -EPIPE: |
1231 | dev_err(cs->dev, "isochronous read stalled\n"); | 1261 | dev_err(cs->dev, "isochronous read stalled\n"); |
@@ -1290,13 +1320,11 @@ static void read_iso_tasklet(unsigned long data) | |||
1290 | urb->dev = bcs->cs->hw.bas->udev; | 1320 | urb->dev = bcs->cs->hw.bas->udev; |
1291 | urb->transfer_flags = URB_ISO_ASAP; | 1321 | urb->transfer_flags = URB_ISO_ASAP; |
1292 | urb->number_of_packets = BAS_NUMFRAMES; | 1322 | urb->number_of_packets = BAS_NUMFRAMES; |
1293 | spin_lock_irqsave(&cs->lock, flags); | 1323 | rc = usb_submit_urb(urb, SLAB_ATOMIC); |
1294 | rc = cs->connected ? usb_submit_urb(urb, SLAB_ATOMIC) : -ENODEV; | 1324 | if (unlikely(rc != 0 && rc != -ENODEV)) { |
1295 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1296 | if (rc) { | ||
1297 | dev_err(cs->dev, | 1325 | dev_err(cs->dev, |
1298 | "could not resubmit isochronous read URB: %s\n", | 1326 | "could not resubmit isochronous read URB: %s\n", |
1299 | get_usb_statmsg(rc)); | 1327 | get_usb_rcmsg(rc)); |
1300 | dump_urb(DEBUG_ISO, "resubmit iso read", urb); | 1328 | dump_urb(DEBUG_ISO, "resubmit iso read", urb); |
1301 | error_hangup(bcs); | 1329 | error_hangup(bcs); |
1302 | } | 1330 | } |
@@ -1397,7 +1425,6 @@ static void write_ctrl_callback(struct urb *urb, struct pt_regs *regs) | |||
1397 | * timeout timeout in seconds (0: no timeout) | 1425 | * timeout timeout in seconds (0: no timeout) |
1398 | * return value: | 1426 | * return value: |
1399 | * 0 on success | 1427 | * 0 on success |
1400 | * -EINVAL if a NULL pointer is encountered somewhere | ||
1401 | * -EBUSY if another request is pending | 1428 | * -EBUSY if another request is pending |
1402 | * any URB submission error code | 1429 | * any URB submission error code |
1403 | */ | 1430 | */ |
@@ -1418,12 +1445,6 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) | |||
1418 | req, ucs->pending); | 1445 | req, ucs->pending); |
1419 | return -EBUSY; | 1446 | return -EBUSY; |
1420 | } | 1447 | } |
1421 | if (ucs->urb_ctrl->status == -EINPROGRESS) { | ||
1422 | spin_unlock_irqrestore(&ucs->lock, flags); | ||
1423 | dev_err(bcs->cs->dev, | ||
1424 | "could not submit request 0x%02x: URB busy\n", req); | ||
1425 | return -EBUSY; | ||
1426 | } | ||
1427 | 1448 | ||
1428 | ucs->dr_ctrl.bRequestType = OUT_VENDOR_REQ; | 1449 | ucs->dr_ctrl.bRequestType = OUT_VENDOR_REQ; |
1429 | ucs->dr_ctrl.bRequest = req; | 1450 | ucs->dr_ctrl.bRequest = req; |
@@ -1465,22 +1486,36 @@ static int req_submit(struct bc_state *bcs, int req, int val, int timeout) | |||
1465 | static int gigaset_init_bchannel(struct bc_state *bcs) | 1486 | static int gigaset_init_bchannel(struct bc_state *bcs) |
1466 | { | 1487 | { |
1467 | int req, ret; | 1488 | int req, ret; |
1489 | unsigned long flags; | ||
1490 | |||
1491 | spin_lock_irqsave(&bcs->cs->lock, flags); | ||
1492 | if (unlikely(!bcs->cs->connected)) { | ||
1493 | gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); | ||
1494 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
1495 | return -ENODEV; | ||
1496 | } | ||
1468 | 1497 | ||
1469 | if ((ret = starturbs(bcs)) < 0) { | 1498 | if ((ret = starturbs(bcs)) < 0) { |
1470 | dev_err(bcs->cs->dev, | 1499 | dev_err(bcs->cs->dev, |
1471 | "could not start isochronous I/O for channel %d\n", | 1500 | "could not start isochronous I/O for channel B%d: %s\n", |
1472 | bcs->channel + 1); | 1501 | bcs->channel + 1, |
1473 | error_hangup(bcs); | 1502 | ret == -EFAULT ? "null URB" : get_usb_rcmsg(ret)); |
1503 | if (ret != -ENODEV) | ||
1504 | error_hangup(bcs); | ||
1505 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
1474 | return ret; | 1506 | return ret; |
1475 | } | 1507 | } |
1476 | 1508 | ||
1477 | req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; | 1509 | req = bcs->channel ? HD_OPEN_B2CHANNEL : HD_OPEN_B1CHANNEL; |
1478 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { | 1510 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) { |
1479 | dev_err(bcs->cs->dev, "could not open channel %d: %s\n", | 1511 | dev_err(bcs->cs->dev, "could not open channel B%d\n", |
1480 | bcs->channel + 1, get_usb_statmsg(ret)); | 1512 | bcs->channel + 1); |
1481 | stopurbs(bcs->hw.bas); | 1513 | stopurbs(bcs->hw.bas); |
1482 | error_hangup(bcs); | 1514 | if (ret != -ENODEV) |
1515 | error_hangup(bcs); | ||
1483 | } | 1516 | } |
1517 | |||
1518 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
1484 | return ret; | 1519 | return ret; |
1485 | } | 1520 | } |
1486 | 1521 | ||
@@ -1497,19 +1532,30 @@ static int gigaset_init_bchannel(struct bc_state *bcs) | |||
1497 | static int gigaset_close_bchannel(struct bc_state *bcs) | 1532 | static int gigaset_close_bchannel(struct bc_state *bcs) |
1498 | { | 1533 | { |
1499 | int req, ret; | 1534 | int req, ret; |
1535 | unsigned long flags; | ||
1536 | |||
1537 | spin_lock_irqsave(&bcs->cs->lock, flags); | ||
1538 | if (unlikely(!bcs->cs->connected)) { | ||
1539 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
1540 | gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); | ||
1541 | return -ENODEV; | ||
1542 | } | ||
1500 | 1543 | ||
1501 | if (!(atomic_read(&bcs->cs->hw.bas->basstate) & | 1544 | if (!(atomic_read(&bcs->cs->hw.bas->basstate) & |
1502 | (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { | 1545 | (bcs->channel ? BS_B2OPEN : BS_B1OPEN))) { |
1503 | /* channel not running: just signal common.c */ | 1546 | /* channel not running: just signal common.c */ |
1547 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
1504 | gigaset_bchannel_down(bcs); | 1548 | gigaset_bchannel_down(bcs); |
1505 | return 0; | 1549 | return 0; |
1506 | } | 1550 | } |
1507 | 1551 | ||
1552 | /* channel running: tell device to close it */ | ||
1508 | req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; | 1553 | req = bcs->channel ? HD_CLOSE_B2CHANNEL : HD_CLOSE_B1CHANNEL; |
1509 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) | 1554 | if ((ret = req_submit(bcs, req, 0, BAS_TIMEOUT)) < 0) |
1510 | dev_err(bcs->cs->dev, | 1555 | dev_err(bcs->cs->dev, "closing channel B%d failed\n", |
1511 | "could not submit HD_CLOSE_BxCHANNEL request: %s\n", | 1556 | bcs->channel + 1); |
1512 | get_usb_statmsg(ret)); | 1557 | |
1558 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
1513 | return ret; | 1559 | return ret; |
1514 | } | 1560 | } |
1515 | 1561 | ||
@@ -1545,8 +1591,6 @@ static void complete_cb(struct cardstate *cs) | |||
1545 | kfree(cb); | 1591 | kfree(cb); |
1546 | } | 1592 | } |
1547 | 1593 | ||
1548 | static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len); | ||
1549 | |||
1550 | /* write_command_callback | 1594 | /* write_command_callback |
1551 | * USB completion handler for AT command transmission | 1595 | * USB completion handler for AT command transmission |
1552 | * called by the USB subsystem in interrupt context | 1596 | * called by the USB subsystem in interrupt context |
@@ -1560,13 +1604,17 @@ static void write_command_callback(struct urb *urb, struct pt_regs *regs) | |||
1560 | struct bas_cardstate *ucs = cs->hw.bas; | 1604 | struct bas_cardstate *ucs = cs->hw.bas; |
1561 | unsigned long flags; | 1605 | unsigned long flags; |
1562 | 1606 | ||
1607 | update_basstate(ucs, 0, BS_ATWRPEND); | ||
1608 | |||
1563 | /* check status */ | 1609 | /* check status */ |
1564 | switch (urb->status) { | 1610 | switch (urb->status) { |
1565 | case 0: /* normal completion */ | 1611 | case 0: /* normal completion */ |
1566 | break; | 1612 | break; |
1567 | case -ENOENT: /* canceled */ | 1613 | case -ENOENT: /* cancelled */ |
1568 | case -ECONNRESET: /* canceled (async) */ | 1614 | case -ECONNRESET: /* cancelled (async) */ |
1569 | case -EINPROGRESS: /* pending */ | 1615 | case -EINPROGRESS: /* pending */ |
1616 | case -ENODEV: /* device removed */ | ||
1617 | case -ESHUTDOWN: /* device shut down */ | ||
1570 | /* ignore silently */ | 1618 | /* ignore silently */ |
1571 | gig_dbg(DEBUG_USBREQ, "%s: %s", | 1619 | gig_dbg(DEBUG_USBREQ, "%s: %s", |
1572 | __func__, get_usb_statmsg(urb->status)); | 1620 | __func__, get_usb_statmsg(urb->status)); |
@@ -1627,19 +1675,17 @@ static void atrdy_timeout(unsigned long data) | |||
1627 | * len length of command to send | 1675 | * len length of command to send |
1628 | * return value: | 1676 | * return value: |
1629 | * 0 on success | 1677 | * 0 on success |
1630 | * -EFAULT if a NULL pointer is encountered somewhere | ||
1631 | * -EBUSY if another request is pending | 1678 | * -EBUSY if another request is pending |
1632 | * any URB submission error code | 1679 | * any URB submission error code |
1633 | */ | 1680 | */ |
1634 | static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | 1681 | static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) |
1635 | { | 1682 | { |
1636 | struct bas_cardstate *ucs = cs->hw.bas; | 1683 | struct bas_cardstate *ucs = cs->hw.bas; |
1637 | unsigned long flags; | 1684 | int rc; |
1638 | int ret; | ||
1639 | 1685 | ||
1640 | gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); | 1686 | gig_dbg(DEBUG_USBREQ, "-------> HD_WRITE_ATMESSAGE (%d)", len); |
1641 | 1687 | ||
1642 | if (ucs->urb_cmd_out->status == -EINPROGRESS) { | 1688 | if (update_basstate(ucs, BS_ATWRPEND, 0) & BS_ATWRPEND) { |
1643 | dev_err(cs->dev, | 1689 | dev_err(cs->dev, |
1644 | "could not submit HD_WRITE_ATMESSAGE: URB busy\n"); | 1690 | "could not submit HD_WRITE_ATMESSAGE: URB busy\n"); |
1645 | return -EBUSY; | 1691 | return -EBUSY; |
@@ -1654,29 +1700,22 @@ static int atwrite_submit(struct cardstate *cs, unsigned char *buf, int len) | |||
1654 | usb_sndctrlpipe(ucs->udev, 0), | 1700 | usb_sndctrlpipe(ucs->udev, 0), |
1655 | (unsigned char*) &ucs->dr_cmd_out, buf, len, | 1701 | (unsigned char*) &ucs->dr_cmd_out, buf, len, |
1656 | write_command_callback, cs); | 1702 | write_command_callback, cs); |
1657 | 1703 | rc = usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC); | |
1658 | spin_lock_irqsave(&cs->lock, flags); | 1704 | if (unlikely(rc)) { |
1659 | ret = cs->connected ? usb_submit_urb(ucs->urb_cmd_out, SLAB_ATOMIC) : -ENODEV; | 1705 | update_basstate(ucs, 0, BS_ATWRPEND); |
1660 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1661 | |||
1662 | if (ret) { | ||
1663 | dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", | 1706 | dev_err(cs->dev, "could not submit HD_WRITE_ATMESSAGE: %s\n", |
1664 | get_usb_statmsg(ret)); | 1707 | get_usb_rcmsg(rc)); |
1665 | return ret; | 1708 | return rc; |
1666 | } | 1709 | } |
1667 | 1710 | ||
1668 | /* submitted successfully */ | 1711 | /* submitted successfully, start timeout if necessary */ |
1669 | update_basstate(ucs, 0, BS_ATREADY); | 1712 | if (!(update_basstate(ucs, BS_ATTIMER, BS_ATREADY) & BS_ATTIMER)) { |
1670 | |||
1671 | /* start timeout if necessary */ | ||
1672 | if (!(atomic_read(&ucs->basstate) & BS_ATTIMER)) { | ||
1673 | gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", | 1713 | gig_dbg(DEBUG_OUTPUT, "setting ATREADY timeout of %d/10 secs", |
1674 | ATRDY_TIMEOUT); | 1714 | ATRDY_TIMEOUT); |
1675 | ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; | 1715 | ucs->timer_atrdy.expires = jiffies + ATRDY_TIMEOUT * HZ / 10; |
1676 | ucs->timer_atrdy.data = (unsigned long) cs; | 1716 | ucs->timer_atrdy.data = (unsigned long) cs; |
1677 | ucs->timer_atrdy.function = atrdy_timeout; | 1717 | ucs->timer_atrdy.function = atrdy_timeout; |
1678 | add_timer(&ucs->timer_atrdy); | 1718 | add_timer(&ucs->timer_atrdy); |
1679 | update_basstate(ucs, BS_ATTIMER, 0); | ||
1680 | } | 1719 | } |
1681 | return 0; | 1720 | return 0; |
1682 | } | 1721 | } |
@@ -1702,7 +1741,6 @@ static int start_cbsend(struct cardstate *cs) | |||
1702 | gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); | 1741 | gig_dbg(DEBUG_TRANSCMD|DEBUG_LOCKCMD, "AT channel not open"); |
1703 | rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); | 1742 | rc = req_submit(cs->bcs, HD_OPEN_ATCHANNEL, 0, BAS_TIMEOUT); |
1704 | if (rc < 0) { | 1743 | if (rc < 0) { |
1705 | dev_err(cs->dev, "could not open AT channel\n"); | ||
1706 | /* flush command queue */ | 1744 | /* flush command queue */ |
1707 | spin_lock_irqsave(&cs->cmdlock, flags); | 1745 | spin_lock_irqsave(&cs->cmdlock, flags); |
1708 | while (cs->cmdbuf != NULL) | 1746 | while (cs->cmdbuf != NULL) |
@@ -1786,8 +1824,14 @@ static int gigaset_write_cmd(struct cardstate *cs, | |||
1786 | cs->lastcmdbuf = cb; | 1824 | cs->lastcmdbuf = cb; |
1787 | spin_unlock_irqrestore(&cs->cmdlock, flags); | 1825 | spin_unlock_irqrestore(&cs->cmdlock, flags); |
1788 | 1826 | ||
1827 | spin_lock_irqsave(&cs->lock, flags); | ||
1828 | if (unlikely(!cs->connected)) { | ||
1829 | spin_unlock_irqrestore(&cs->lock, flags); | ||
1830 | gig_dbg(DEBUG_USBREQ, "%s: not connected", __func__); | ||
1831 | return -ENODEV; | ||
1832 | } | ||
1789 | status = start_cbsend(cs); | 1833 | status = start_cbsend(cs); |
1790 | 1834 | spin_unlock_irqrestore(&cs->lock, flags); | |
1791 | return status < 0 ? status : len; | 1835 | return status < 0 ? status : len; |
1792 | } | 1836 | } |
1793 | 1837 | ||
@@ -1849,12 +1893,32 @@ static int gigaset_brkchars(struct cardstate *cs, const unsigned char buf[6]) | |||
1849 | */ | 1893 | */ |
1850 | static int gigaset_freebcshw(struct bc_state *bcs) | 1894 | static int gigaset_freebcshw(struct bc_state *bcs) |
1851 | { | 1895 | { |
1852 | if (!bcs->hw.bas) | 1896 | struct bas_bc_state *ubc = bcs->hw.bas; |
1897 | int i; | ||
1898 | |||
1899 | if (!ubc) | ||
1853 | return 0; | 1900 | return 0; |
1854 | 1901 | ||
1855 | if (bcs->hw.bas->isooutbuf) | 1902 | /* kill URBs and tasklets before freeing - better safe than sorry */ |
1856 | kfree(bcs->hw.bas->isooutbuf); | 1903 | atomic_set(&ubc->running, 0); |
1857 | kfree(bcs->hw.bas); | 1904 | for (i = 0; i < BAS_OUTURBS; ++i) |
1905 | if (ubc->isoouturbs[i].urb) { | ||
1906 | gig_dbg(DEBUG_INIT, "%s: killing iso out URB %d", | ||
1907 | __func__, i); | ||
1908 | usb_kill_urb(ubc->isoouturbs[i].urb); | ||
1909 | usb_free_urb(ubc->isoouturbs[i].urb); | ||
1910 | } | ||
1911 | for (i = 0; i < BAS_INURBS; ++i) | ||
1912 | if (ubc->isoinurbs[i]) { | ||
1913 | gig_dbg(DEBUG_INIT, "%s: killing iso in URB %d", | ||
1914 | __func__, i); | ||
1915 | usb_kill_urb(ubc->isoinurbs[i]); | ||
1916 | usb_free_urb(ubc->isoinurbs[i]); | ||
1917 | } | ||
1918 | tasklet_kill(&ubc->sent_tasklet); | ||
1919 | tasklet_kill(&ubc->rcvd_tasklet); | ||
1920 | kfree(ubc->isooutbuf); | ||
1921 | kfree(ubc); | ||
1858 | bcs->hw.bas = NULL; | 1922 | bcs->hw.bas = NULL; |
1859 | return 1; | 1923 | return 1; |
1860 | } | 1924 | } |
@@ -1931,13 +1995,9 @@ static void gigaset_reinitbcshw(struct bc_state *bcs) | |||
1931 | 1995 | ||
1932 | static void gigaset_freecshw(struct cardstate *cs) | 1996 | static void gigaset_freecshw(struct cardstate *cs) |
1933 | { | 1997 | { |
1934 | struct bas_cardstate *ucs = cs->hw.bas; | 1998 | /* timers, URBs and rcvbuf are disposed of in disconnect */ |
1935 | |||
1936 | del_timer(&ucs->timer_ctrl); | ||
1937 | del_timer(&ucs->timer_atrdy); | ||
1938 | del_timer(&ucs->timer_cmd_in); | ||
1939 | |||
1940 | kfree(cs->hw.bas); | 1999 | kfree(cs->hw.bas); |
2000 | cs->hw.bas = NULL; | ||
1941 | } | 2001 | } |
1942 | 2002 | ||
1943 | static int gigaset_initcshw(struct cardstate *cs) | 2003 | static int gigaset_initcshw(struct cardstate *cs) |
@@ -2041,23 +2101,13 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2041 | struct bas_bc_state *ubc; | 2101 | struct bas_bc_state *ubc; |
2042 | struct usb_endpoint_descriptor *endpoint; | 2102 | struct usb_endpoint_descriptor *endpoint; |
2043 | int i, j; | 2103 | int i, j; |
2044 | int ret; | 2104 | int rc; |
2045 | 2105 | ||
2046 | gig_dbg(DEBUG_ANY, | 2106 | gig_dbg(DEBUG_ANY, |
2047 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", | 2107 | "%s: Check if device matches .. (Vendor: 0x%x, Product: 0x%x)", |
2048 | __func__, le16_to_cpu(udev->descriptor.idVendor), | 2108 | __func__, le16_to_cpu(udev->descriptor.idVendor), |
2049 | le16_to_cpu(udev->descriptor.idProduct)); | 2109 | le16_to_cpu(udev->descriptor.idProduct)); |
2050 | 2110 | ||
2051 | /* See if the device offered us matches what we can accept */ | ||
2052 | if ((le16_to_cpu(udev->descriptor.idVendor) != USB_GIGA_VENDOR_ID) || | ||
2053 | (le16_to_cpu(udev->descriptor.idProduct) != USB_GIGA_PRODUCT_ID && | ||
2054 | le16_to_cpu(udev->descriptor.idProduct) != USB_4175_PRODUCT_ID && | ||
2055 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX303_PRODUCT_ID && | ||
2056 | le16_to_cpu(udev->descriptor.idProduct) != USB_SX353_PRODUCT_ID)) { | ||
2057 | gig_dbg(DEBUG_ANY, "%s: unmatched ID - exiting", __func__); | ||
2058 | return -ENODEV; | ||
2059 | } | ||
2060 | |||
2061 | /* set required alternate setting */ | 2111 | /* set required alternate setting */ |
2062 | hostif = interface->cur_altsetting; | 2112 | hostif = interface->cur_altsetting; |
2063 | if (hostif->desc.bAlternateSetting != 3) { | 2113 | if (hostif->desc.bAlternateSetting != 3) { |
@@ -2105,45 +2155,22 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2105 | * - three for the different uses of the default control pipe | 2155 | * - three for the different uses of the default control pipe |
2106 | * - three for each isochronous pipe | 2156 | * - three for each isochronous pipe |
2107 | */ | 2157 | */ |
2108 | ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL); | 2158 | if (!(ucs->urb_int_in = usb_alloc_urb(0, SLAB_KERNEL)) || |
2109 | if (!ucs->urb_int_in) { | 2159 | !(ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL)) || |
2110 | dev_err(cs->dev, "no free urbs available\n"); | 2160 | !(ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL)) || |
2111 | goto error; | 2161 | !(ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL))) |
2112 | } | 2162 | goto allocerr; |
2113 | ucs->urb_cmd_in = usb_alloc_urb(0, SLAB_KERNEL); | ||
2114 | if (!ucs->urb_cmd_in) { | ||
2115 | dev_err(cs->dev, "no free urbs available\n"); | ||
2116 | goto error; | ||
2117 | } | ||
2118 | ucs->urb_cmd_out = usb_alloc_urb(0, SLAB_KERNEL); | ||
2119 | if (!ucs->urb_cmd_out) { | ||
2120 | dev_err(cs->dev, "no free urbs available\n"); | ||
2121 | goto error; | ||
2122 | } | ||
2123 | ucs->urb_ctrl = usb_alloc_urb(0, SLAB_KERNEL); | ||
2124 | if (!ucs->urb_ctrl) { | ||
2125 | dev_err(cs->dev, "no free urbs available\n"); | ||
2126 | goto error; | ||
2127 | } | ||
2128 | 2163 | ||
2129 | for (j = 0; j < 2; ++j) { | 2164 | for (j = 0; j < 2; ++j) { |
2130 | ubc = cs->bcs[j].hw.bas; | 2165 | ubc = cs->bcs[j].hw.bas; |
2131 | for (i = 0; i < BAS_OUTURBS; ++i) { | 2166 | for (i = 0; i < BAS_OUTURBS; ++i) |
2132 | ubc->isoouturbs[i].urb = | 2167 | if (!(ubc->isoouturbs[i].urb = |
2133 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); | 2168 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL))) |
2134 | if (!ubc->isoouturbs[i].urb) { | 2169 | goto allocerr; |
2135 | dev_err(cs->dev, "no free urbs available\n"); | 2170 | for (i = 0; i < BAS_INURBS; ++i) |
2136 | goto error; | 2171 | if (!(ubc->isoinurbs[i] = |
2137 | } | 2172 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL))) |
2138 | } | 2173 | goto allocerr; |
2139 | for (i = 0; i < BAS_INURBS; ++i) { | ||
2140 | ubc->isoinurbs[i] = | ||
2141 | usb_alloc_urb(BAS_NUMFRAMES, SLAB_KERNEL); | ||
2142 | if (!ubc->isoinurbs[i]) { | ||
2143 | dev_err(cs->dev, "no free urbs available\n"); | ||
2144 | goto error; | ||
2145 | } | ||
2146 | } | ||
2147 | } | 2174 | } |
2148 | 2175 | ||
2149 | ucs->rcvbuf = NULL; | 2176 | ucs->rcvbuf = NULL; |
@@ -2156,15 +2183,14 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2156 | (endpoint->bEndpointAddress) & 0x0f), | 2183 | (endpoint->bEndpointAddress) & 0x0f), |
2157 | ucs->int_in_buf, 3, read_int_callback, cs, | 2184 | ucs->int_in_buf, 3, read_int_callback, cs, |
2158 | endpoint->bInterval); | 2185 | endpoint->bInterval); |
2159 | ret = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL); | 2186 | if ((rc = usb_submit_urb(ucs->urb_int_in, SLAB_KERNEL)) != 0) { |
2160 | if (ret) { | ||
2161 | dev_err(cs->dev, "could not submit interrupt URB: %s\n", | 2187 | dev_err(cs->dev, "could not submit interrupt URB: %s\n", |
2162 | get_usb_statmsg(ret)); | 2188 | get_usb_rcmsg(rc)); |
2163 | goto error; | 2189 | goto error; |
2164 | } | 2190 | } |
2165 | 2191 | ||
2166 | /* tell the device that the driver is ready */ | 2192 | /* tell the device that the driver is ready */ |
2167 | if ((ret = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0)) != 0) | 2193 | if ((rc = req_submit(cs->bcs, HD_DEVICE_INIT_ACK, 0, 0)) != 0) |
2168 | goto error; | 2194 | goto error; |
2169 | 2195 | ||
2170 | /* tell common part that the device is ready */ | 2196 | /* tell common part that the device is ready */ |
@@ -2179,6 +2205,8 @@ static int gigaset_probe(struct usb_interface *interface, | |||
2179 | 2205 | ||
2180 | return 0; | 2206 | return 0; |
2181 | 2207 | ||
2208 | allocerr: | ||
2209 | dev_err(cs->dev, "could not allocate URBs\n"); | ||
2182 | error: | 2210 | error: |
2183 | freeurbs(cs); | 2211 | freeurbs(cs); |
2184 | usb_set_intfdata(interface, NULL); | 2212 | usb_set_intfdata(interface, NULL); |
@@ -2193,19 +2221,34 @@ static void gigaset_disconnect(struct usb_interface *interface) | |||
2193 | { | 2221 | { |
2194 | struct cardstate *cs; | 2222 | struct cardstate *cs; |
2195 | struct bas_cardstate *ucs; | 2223 | struct bas_cardstate *ucs; |
2224 | int j; | ||
2196 | 2225 | ||
2197 | cs = usb_get_intfdata(interface); | 2226 | cs = usb_get_intfdata(interface); |
2198 | 2227 | ||
2199 | ucs = cs->hw.bas; | 2228 | ucs = cs->hw.bas; |
2200 | 2229 | ||
2201 | dev_info(cs->dev, "disconnecting Gigaset base\n"); | 2230 | dev_info(cs->dev, "disconnecting Gigaset base\n"); |
2231 | |||
2232 | /* mark base as not ready, all channels disconnected */ | ||
2233 | atomic_set(&ucs->basstate, 0); | ||
2234 | |||
2235 | /* tell LL all channels are down */ | ||
2236 | //FIXME shouldn't gigaset_stop() do this? | ||
2237 | for (j = 0; j < 2; ++j) | ||
2238 | gigaset_bchannel_down(cs->bcs + j); | ||
2239 | |||
2240 | /* stop driver (common part) */ | ||
2202 | gigaset_stop(cs); | 2241 | gigaset_stop(cs); |
2242 | |||
2243 | /* stop timers and URBs, free ressources */ | ||
2244 | del_timer_sync(&ucs->timer_ctrl); | ||
2245 | del_timer_sync(&ucs->timer_atrdy); | ||
2246 | del_timer_sync(&ucs->timer_cmd_in); | ||
2203 | freeurbs(cs); | 2247 | freeurbs(cs); |
2204 | usb_set_intfdata(interface, NULL); | 2248 | usb_set_intfdata(interface, NULL); |
2205 | kfree(ucs->rcvbuf); | 2249 | kfree(ucs->rcvbuf); |
2206 | ucs->rcvbuf = NULL; | 2250 | ucs->rcvbuf = NULL; |
2207 | ucs->rcvbuf_size = 0; | 2251 | ucs->rcvbuf_size = 0; |
2208 | atomic_set(&ucs->basstate, 0); | ||
2209 | usb_put_dev(ucs->udev); | 2252 | usb_put_dev(ucs->udev); |
2210 | ucs->interface = NULL; | 2253 | ucs->interface = NULL; |
2211 | ucs->udev = NULL; | 2254 | ucs->udev = NULL; |
@@ -2277,6 +2320,8 @@ error: if (cardstate) | |||
2277 | */ | 2320 | */ |
2278 | static void __exit bas_gigaset_exit(void) | 2321 | static void __exit bas_gigaset_exit(void) |
2279 | { | 2322 | { |
2323 | struct bas_cardstate *ucs = cardstate->hw.bas; | ||
2324 | |||
2280 | gigaset_blockdriver(driver); /* => probe will fail | 2325 | gigaset_blockdriver(driver); /* => probe will fail |
2281 | * => no gigaset_start any more | 2326 | * => no gigaset_start any more |
2282 | */ | 2327 | */ |
@@ -2284,14 +2329,26 @@ static void __exit bas_gigaset_exit(void) | |||
2284 | gigaset_shutdown(cardstate); | 2329 | gigaset_shutdown(cardstate); |
2285 | /* from now on, no isdn callback should be possible */ | 2330 | /* from now on, no isdn callback should be possible */ |
2286 | 2331 | ||
2287 | if (atomic_read(&cardstate->hw.bas->basstate) & BS_ATOPEN) { | 2332 | /* close all still open channels */ |
2288 | gig_dbg(DEBUG_ANY, "closing AT channel"); | 2333 | if (atomic_read(&ucs->basstate) & BS_B1OPEN) { |
2289 | if (req_submit(cardstate->bcs, | 2334 | gig_dbg(DEBUG_INIT, "closing B1 channel"); |
2290 | HD_CLOSE_ATCHANNEL, 0, BAS_TIMEOUT) >= 0) { | 2335 | usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), |
2291 | /* successfully submitted */ | 2336 | HD_CLOSE_B1CHANNEL, OUT_VENDOR_REQ, 0, 0, |
2292 | //FIXME wait for completion? | 2337 | NULL, 0, BAS_TIMEOUT); |
2293 | } | 2338 | } |
2339 | if (atomic_read(&ucs->basstate) & BS_B2OPEN) { | ||
2340 | gig_dbg(DEBUG_INIT, "closing B2 channel"); | ||
2341 | usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), | ||
2342 | HD_CLOSE_B2CHANNEL, OUT_VENDOR_REQ, 0, 0, | ||
2343 | NULL, 0, BAS_TIMEOUT); | ||
2344 | } | ||
2345 | if (atomic_read(&ucs->basstate) & BS_ATOPEN) { | ||
2346 | gig_dbg(DEBUG_INIT, "closing AT channel"); | ||
2347 | usb_control_msg(ucs->udev, usb_sndctrlpipe(ucs->udev, 0), | ||
2348 | HD_CLOSE_ATCHANNEL, OUT_VENDOR_REQ, 0, 0, | ||
2349 | NULL, 0, BAS_TIMEOUT); | ||
2294 | } | 2350 | } |
2351 | atomic_set(&ucs->basstate, 0); | ||
2295 | 2352 | ||
2296 | /* deregister this driver with the USB subsystem */ | 2353 | /* deregister this driver with the USB subsystem */ |
2297 | usb_deregister(&gigaset_usb_driver); | 2354 | usb_deregister(&gigaset_usb_driver); |
diff --git a/drivers/isdn/gigaset/common.c b/drivers/isdn/gigaset/common.c index 749b3da1236e..e55767b2ccd3 100644 --- a/drivers/isdn/gigaset/common.c +++ b/drivers/isdn/gigaset/common.c | |||
@@ -781,8 +781,7 @@ error: if (cs) | |||
781 | } | 781 | } |
782 | EXPORT_SYMBOL_GPL(gigaset_initcs); | 782 | EXPORT_SYMBOL_GPL(gigaset_initcs); |
783 | 783 | ||
784 | /* ReInitialize the b-channel structure */ | 784 | /* ReInitialize the b-channel structure on hangup */ |
785 | /* e.g. called on hangup, disconnect */ | ||
786 | void gigaset_bcs_reinit(struct bc_state *bcs) | 785 | void gigaset_bcs_reinit(struct bc_state *bcs) |
787 | { | 786 | { |
788 | struct sk_buff *skb; | 787 | struct sk_buff *skb; |
diff --git a/drivers/isdn/gigaset/ev-layer.c b/drivers/isdn/gigaset/ev-layer.c index 1ba3424a286b..18e05c09b71c 100644 --- a/drivers/isdn/gigaset/ev-layer.c +++ b/drivers/isdn/gigaset/ev-layer.c | |||
@@ -373,6 +373,9 @@ struct reply_t gigaset_tab_cid_m10x[] = /* for M10x */ | |||
373 | 373 | ||
374 | {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}}, | 374 | {EV_TIMEOUT, 750,750, -1, 0, 0, {ACT_CONNTIMEOUT}}, |
375 | 375 | ||
376 | /* B channel closed (general case) */ | ||
377 | {EV_BC_CLOSED, -1, -1, -1, -1,-1, {ACT_NOTIFY_BC_DOWN}}, //FIXME | ||
378 | |||
376 | /* misc. */ | 379 | /* misc. */ |
377 | {EV_PROTO_L2, -1, -1, -1, -1,-1, {ACT_PROTO_L2}}, //FIXME | 380 | {EV_PROTO_L2, -1, -1, -1, -1,-1, {ACT_PROTO_L2}}, //FIXME |
378 | 381 | ||
diff --git a/drivers/isdn/gigaset/gigaset.h b/drivers/isdn/gigaset/gigaset.h index 9d21ba8757b0..22b9693f7c0a 100644 --- a/drivers/isdn/gigaset/gigaset.h +++ b/drivers/isdn/gigaset/gigaset.h | |||
@@ -75,7 +75,7 @@ extern int gigaset_debuglevel; /* "needs" cast to (enum debuglevel) */ | |||
75 | * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and | 75 | * e.g. 'insmod usb_gigaset.o debug=0x2c' will set DEBUG_OPEN, DEBUG_CMD and |
76 | * DEBUG_INTR. | 76 | * DEBUG_INTR. |
77 | */ | 77 | */ |
78 | enum debuglevel { /* up to 24 bits (atomic_t) */ | 78 | enum debuglevel { |
79 | DEBUG_REG = 0x0002, /* serial port I/O register operations */ | 79 | DEBUG_REG = 0x0002, /* serial port I/O register operations */ |
80 | DEBUG_OPEN = 0x0004, /* open/close serial port */ | 80 | DEBUG_OPEN = 0x0004, /* open/close serial port */ |
81 | DEBUG_INTR = 0x0008, /* interrupt processing */ | 81 | DEBUG_INTR = 0x0008, /* interrupt processing */ |
@@ -141,7 +141,7 @@ enum debuglevel { /* up to 24 bits (atomic_t) */ | |||
141 | printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \ | 141 | printk(KERN_DEBUG KBUILD_MODNAME ": " format "\n", \ |
142 | ## arg); \ | 142 | ## arg); \ |
143 | } while (0) | 143 | } while (0) |
144 | #define DEBUG_DEFAULT (DEBUG_INIT | DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ) | 144 | #define DEBUG_DEFAULT (DEBUG_TRANSCMD | DEBUG_CMD | DEBUG_USBREQ) |
145 | 145 | ||
146 | #else | 146 | #else |
147 | 147 | ||
@@ -627,8 +627,7 @@ struct gigaset_ops { | |||
627 | /* Called by gigaset_freecs() for freeing bcs->hw.xxx */ | 627 | /* Called by gigaset_freecs() for freeing bcs->hw.xxx */ |
628 | int (*freebcshw)(struct bc_state *bcs); | 628 | int (*freebcshw)(struct bc_state *bcs); |
629 | 629 | ||
630 | /* Called by gigaset_stop() or gigaset_bchannel_down() for resetting | 630 | /* Called by gigaset_bchannel_down() for resetting bcs->hw.xxx */ |
631 | bcs->hw.xxx */ | ||
632 | void (*reinitbcshw)(struct bc_state *bcs); | 631 | void (*reinitbcshw)(struct bc_state *bcs); |
633 | 632 | ||
634 | /* Called by gigaset_initcs() for setting up cs->hw.xxx */ | 633 | /* Called by gigaset_initcs() for setting up cs->hw.xxx */ |
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c index 0815dbfb8291..1654fa413575 100644 --- a/drivers/isdn/gigaset/i4l.c +++ b/drivers/isdn/gigaset/i4l.c | |||
@@ -73,7 +73,7 @@ static int writebuf_from_LL(int driverID, int channel, int ack, | |||
73 | len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]); | 73 | len, skblen, (unsigned) skb->head[0], (unsigned) skb->head[1]); |
74 | 74 | ||
75 | /* pass to device-specific module */ | 75 | /* pass to device-specific module */ |
76 | return cs->ops->send_skb(bcs, skb); //FIXME cs->ops->send_skb() must handle !cs->connected correctly | 76 | return cs->ops->send_skb(bcs, skb); |
77 | } | 77 | } |
78 | 78 | ||
79 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) | 79 | void gigaset_skb_sent(struct bc_state *bcs, struct sk_buff *skb) |
diff --git a/drivers/isdn/gigaset/isocdata.c b/drivers/isdn/gigaset/isocdata.c index 45f017ed6e8c..8667daaa1a82 100644 --- a/drivers/isdn/gigaset/isocdata.c +++ b/drivers/isdn/gigaset/isocdata.c | |||
@@ -992,14 +992,18 @@ int gigaset_isoc_send_skb(struct bc_state *bcs, struct sk_buff *skb) | |||
992 | int len = skb->len; | 992 | int len = skb->len; |
993 | unsigned long flags; | 993 | unsigned long flags; |
994 | 994 | ||
995 | spin_lock_irqsave(&bcs->cs->lock, flags); | ||
996 | if (!bcs->cs->connected) { | ||
997 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | ||
998 | return -ENODEV; | ||
999 | } | ||
1000 | |||
995 | skb_queue_tail(&bcs->squeue, skb); | 1001 | skb_queue_tail(&bcs->squeue, skb); |
996 | gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d", | 1002 | gig_dbg(DEBUG_ISO, "%s: skb queued, qlen=%d", |
997 | __func__, skb_queue_len(&bcs->squeue)); | 1003 | __func__, skb_queue_len(&bcs->squeue)); |
998 | 1004 | ||
999 | /* tasklet submits URB if necessary */ | 1005 | /* tasklet submits URB if necessary */ |
1000 | spin_lock_irqsave(&bcs->cs->lock, flags); | 1006 | tasklet_schedule(&bcs->hw.bas->sent_tasklet); |
1001 | if (bcs->cs->connected) | ||
1002 | tasklet_schedule(&bcs->hw.bas->sent_tasklet); | ||
1003 | spin_unlock_irqrestore(&bcs->cs->lock, flags); | 1007 | spin_unlock_irqrestore(&bcs->cs->lock, flags); |
1004 | 1008 | ||
1005 | return len; /* ok so far */ | 1009 | return len; /* ok so far */ |
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c index 5ebfd1d138da..5282fec17075 100644 --- a/drivers/macintosh/therm_adt746x.c +++ b/drivers/macintosh/therm_adt746x.c | |||
@@ -627,8 +627,8 @@ thermostat_init(void) | |||
627 | if(therm_type == ADT7460) | 627 | if(therm_type == ADT7460) |
628 | device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); | 628 | device_create_file(&of_dev->dev, &dev_attr_sensor2_fan_speed); |
629 | 629 | ||
630 | #ifndef CONFIG_I2C_KEYWEST | 630 | #ifndef CONFIG_I2C_POWERMAC |
631 | request_module("i2c-keywest"); | 631 | request_module("i2c-powermac"); |
632 | #endif | 632 | #endif |
633 | 633 | ||
634 | return i2c_add_driver(&thermostat_driver); | 634 | return i2c_add_driver(&thermostat_driver); |
diff --git a/drivers/md/md.c b/drivers/md/md.c index 434ca39d19c1..d7316b829a62 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -279,11 +279,6 @@ static inline int mddev_lock(mddev_t * mddev) | |||
279 | return mutex_lock_interruptible(&mddev->reconfig_mutex); | 279 | return mutex_lock_interruptible(&mddev->reconfig_mutex); |
280 | } | 280 | } |
281 | 281 | ||
282 | static inline void mddev_lock_uninterruptible(mddev_t * mddev) | ||
283 | { | ||
284 | mutex_lock(&mddev->reconfig_mutex); | ||
285 | } | ||
286 | |||
287 | static inline int mddev_trylock(mddev_t * mddev) | 282 | static inline int mddev_trylock(mddev_t * mddev) |
288 | { | 283 | { |
289 | return mutex_trylock(&mddev->reconfig_mutex); | 284 | return mutex_trylock(&mddev->reconfig_mutex); |
@@ -2458,9 +2453,11 @@ md_attr_show(struct kobject *kobj, struct attribute *attr, char *page) | |||
2458 | 2453 | ||
2459 | if (!entry->show) | 2454 | if (!entry->show) |
2460 | return -EIO; | 2455 | return -EIO; |
2461 | mddev_lock(mddev); | 2456 | rv = mddev_lock(mddev); |
2462 | rv = entry->show(mddev, page); | 2457 | if (!rv) { |
2463 | mddev_unlock(mddev); | 2458 | rv = entry->show(mddev, page); |
2459 | mddev_unlock(mddev); | ||
2460 | } | ||
2464 | return rv; | 2461 | return rv; |
2465 | } | 2462 | } |
2466 | 2463 | ||
@@ -2474,9 +2471,11 @@ md_attr_store(struct kobject *kobj, struct attribute *attr, | |||
2474 | 2471 | ||
2475 | if (!entry->store) | 2472 | if (!entry->store) |
2476 | return -EIO; | 2473 | return -EIO; |
2477 | mddev_lock(mddev); | 2474 | rv = mddev_lock(mddev); |
2478 | rv = entry->store(mddev, page, length); | 2475 | if (!rv) { |
2479 | mddev_unlock(mddev); | 2476 | rv = entry->store(mddev, page, length); |
2477 | mddev_unlock(mddev); | ||
2478 | } | ||
2480 | return rv; | 2479 | return rv; |
2481 | } | 2480 | } |
2482 | 2481 | ||
@@ -4341,8 +4340,9 @@ static int md_seq_show(struct seq_file *seq, void *v) | |||
4341 | return 0; | 4340 | return 0; |
4342 | } | 4341 | } |
4343 | 4342 | ||
4344 | if (mddev_lock(mddev)!=0) | 4343 | if (mddev_lock(mddev) < 0) |
4345 | return -EINTR; | 4344 | return -EINTR; |
4345 | |||
4346 | if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) { | 4346 | if (mddev->pers || mddev->raid_disks || !list_empty(&mddev->disks)) { |
4347 | seq_printf(seq, "%s : %sactive", mdname(mddev), | 4347 | seq_printf(seq, "%s : %sactive", mdname(mddev), |
4348 | mddev->pers ? "" : "in"); | 4348 | mddev->pers ? "" : "in"); |
diff --git a/drivers/mmc/pxamci.c b/drivers/mmc/pxamci.c index eb9a8826e9b5..eb42cb349420 100644 --- a/drivers/mmc/pxamci.c +++ b/drivers/mmc/pxamci.c | |||
@@ -65,11 +65,6 @@ struct pxamci_host { | |||
65 | unsigned int dma_dir; | 65 | unsigned int dma_dir; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static inline unsigned int ns_to_clocks(unsigned int ns) | ||
69 | { | ||
70 | return (ns * (CLOCKRATE / 1000000) + 999) / 1000; | ||
71 | } | ||
72 | |||
73 | static void pxamci_stop_clock(struct pxamci_host *host) | 68 | static void pxamci_stop_clock(struct pxamci_host *host) |
74 | { | 69 | { |
75 | if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { | 70 | if (readl(host->base + MMC_STAT) & STAT_CLK_EN) { |
@@ -113,6 +108,7 @@ static void pxamci_disable_irq(struct pxamci_host *host, unsigned int mask) | |||
113 | static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) | 108 | static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) |
114 | { | 109 | { |
115 | unsigned int nob = data->blocks; | 110 | unsigned int nob = data->blocks; |
111 | unsigned long long clks; | ||
116 | unsigned int timeout; | 112 | unsigned int timeout; |
117 | u32 dcmd; | 113 | u32 dcmd; |
118 | int i; | 114 | int i; |
@@ -125,7 +121,9 @@ static void pxamci_setup_data(struct pxamci_host *host, struct mmc_data *data) | |||
125 | writel(nob, host->base + MMC_NOB); | 121 | writel(nob, host->base + MMC_NOB); |
126 | writel(1 << data->blksz_bits, host->base + MMC_BLKLEN); | 122 | writel(1 << data->blksz_bits, host->base + MMC_BLKLEN); |
127 | 123 | ||
128 | timeout = ns_to_clocks(data->timeout_ns) + data->timeout_clks; | 124 | clks = (unsigned long long)data->timeout_ns * CLOCKRATE; |
125 | do_div(clks, 1000000000UL); | ||
126 | timeout = (unsigned int)clks + (data->timeout_clks << host->clkrt); | ||
129 | writel((timeout + 255) / 256, host->base + MMC_RDTO); | 127 | writel((timeout + 255) / 256, host->base + MMC_RDTO); |
130 | 128 | ||
131 | if (data->flags & MMC_DATA_READ) { | 129 | if (data->flags & MMC_DATA_READ) { |
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index add8dc4aa7b0..c99e87838f92 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c | |||
@@ -3768,6 +3768,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, | |||
3768 | ps_page->ps_page[j] = NULL; | 3768 | ps_page->ps_page[j] = NULL; |
3769 | skb->len += length; | 3769 | skb->len += length; |
3770 | skb->data_len += length; | 3770 | skb->data_len += length; |
3771 | skb->truesize += length; | ||
3771 | } | 3772 | } |
3772 | 3773 | ||
3773 | copydone: | 3774 | copydone: |
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c index 7627a75f4f7c..9788b1ef2e7d 100644 --- a/drivers/net/forcedeth.c +++ b/drivers/net/forcedeth.c | |||
@@ -105,6 +105,7 @@ | |||
105 | * 0.50: 20 Jan 2006: Add 8021pq tagging support. | 105 | * 0.50: 20 Jan 2006: Add 8021pq tagging support. |
106 | * 0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings. | 106 | * 0.51: 20 Jan 2006: Add 64bit consistent memory allocation for rings. |
107 | * 0.52: 20 Jan 2006: Add MSI/MSIX support. | 107 | * 0.52: 20 Jan 2006: Add MSI/MSIX support. |
108 | * 0.53: 19 Mar 2006: Fix init from low power mode and add hw reset. | ||
108 | * | 109 | * |
109 | * Known bugs: | 110 | * Known bugs: |
110 | * We suspect that on some hardware no TX done interrupts are generated. | 111 | * We suspect that on some hardware no TX done interrupts are generated. |
@@ -116,7 +117,7 @@ | |||
116 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few | 117 | * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few |
117 | * superfluous timer interrupts from the nic. | 118 | * superfluous timer interrupts from the nic. |
118 | */ | 119 | */ |
119 | #define FORCEDETH_VERSION "0.52" | 120 | #define FORCEDETH_VERSION "0.53" |
120 | #define DRV_NAME "forcedeth" | 121 | #define DRV_NAME "forcedeth" |
121 | 122 | ||
122 | #include <linux/module.h> | 123 | #include <linux/module.h> |
@@ -160,6 +161,7 @@ | |||
160 | #define DEV_HAS_VLAN 0x0020 /* device supports vlan tagging and striping */ | 161 | #define DEV_HAS_VLAN 0x0020 /* device supports vlan tagging and striping */ |
161 | #define DEV_HAS_MSI 0x0040 /* device supports MSI */ | 162 | #define DEV_HAS_MSI 0x0040 /* device supports MSI */ |
162 | #define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ | 163 | #define DEV_HAS_MSI_X 0x0080 /* device supports MSI-X */ |
164 | #define DEV_HAS_POWER_CNTRL 0x0100 /* device supports power savings */ | ||
163 | 165 | ||
164 | enum { | 166 | enum { |
165 | NvRegIrqStatus = 0x000, | 167 | NvRegIrqStatus = 0x000, |
@@ -203,6 +205,8 @@ enum { | |||
203 | #define NVREG_MISC1_HD 0x02 | 205 | #define NVREG_MISC1_HD 0x02 |
204 | #define NVREG_MISC1_FORCE 0x3b0f3c | 206 | #define NVREG_MISC1_FORCE 0x3b0f3c |
205 | 207 | ||
208 | NvRegMacReset = 0x3c, | ||
209 | #define NVREG_MAC_RESET_ASSERT 0x0F3 | ||
206 | NvRegTransmitterControl = 0x084, | 210 | NvRegTransmitterControl = 0x084, |
207 | #define NVREG_XMITCTL_START 0x01 | 211 | #define NVREG_XMITCTL_START 0x01 |
208 | NvRegTransmitterStatus = 0x088, | 212 | NvRegTransmitterStatus = 0x088, |
@@ -326,6 +330,10 @@ enum { | |||
326 | NvRegMSIXMap0 = 0x3e0, | 330 | NvRegMSIXMap0 = 0x3e0, |
327 | NvRegMSIXMap1 = 0x3e4, | 331 | NvRegMSIXMap1 = 0x3e4, |
328 | NvRegMSIXIrqStatus = 0x3f0, | 332 | NvRegMSIXIrqStatus = 0x3f0, |
333 | |||
334 | NvRegPowerState2 = 0x600, | ||
335 | #define NVREG_POWERSTATE2_POWERUP_MASK 0x0F11 | ||
336 | #define NVREG_POWERSTATE2_POWERUP_REV_A3 0x0001 | ||
329 | }; | 337 | }; |
330 | 338 | ||
331 | /* Big endian: should work, but is untested */ | 339 | /* Big endian: should work, but is untested */ |
@@ -414,7 +422,8 @@ typedef union _ring_type { | |||
414 | #define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) | 422 | #define NV_RX3_VLAN_TAG_MASK (0x0000FFFF) |
415 | 423 | ||
416 | /* Miscelaneous hardware related defines: */ | 424 | /* Miscelaneous hardware related defines: */ |
417 | #define NV_PCI_REGSZ 0x270 | 425 | #define NV_PCI_REGSZ_VER1 0x270 |
426 | #define NV_PCI_REGSZ_VER2 0x604 | ||
418 | 427 | ||
419 | /* various timeout delays: all in usec */ | 428 | /* various timeout delays: all in usec */ |
420 | #define NV_TXRX_RESET_DELAY 4 | 429 | #define NV_TXRX_RESET_DELAY 4 |
@@ -431,6 +440,7 @@ typedef union _ring_type { | |||
431 | #define NV_MIIBUSY_DELAY 50 | 440 | #define NV_MIIBUSY_DELAY 50 |
432 | #define NV_MIIPHY_DELAY 10 | 441 | #define NV_MIIPHY_DELAY 10 |
433 | #define NV_MIIPHY_DELAYMAX 10000 | 442 | #define NV_MIIPHY_DELAYMAX 10000 |
443 | #define NV_MAC_RESET_DELAY 64 | ||
434 | 444 | ||
435 | #define NV_WAKEUPPATTERNS 5 | 445 | #define NV_WAKEUPPATTERNS 5 |
436 | #define NV_WAKEUPMASKENTRIES 4 | 446 | #define NV_WAKEUPMASKENTRIES 4 |
@@ -552,6 +562,8 @@ struct fe_priv { | |||
552 | u32 desc_ver; | 562 | u32 desc_ver; |
553 | u32 txrxctl_bits; | 563 | u32 txrxctl_bits; |
554 | u32 vlanctl_bits; | 564 | u32 vlanctl_bits; |
565 | u32 driver_data; | ||
566 | u32 register_size; | ||
555 | 567 | ||
556 | void __iomem *base; | 568 | void __iomem *base; |
557 | 569 | ||
@@ -919,6 +931,24 @@ static void nv_txrx_reset(struct net_device *dev) | |||
919 | pci_push(base); | 931 | pci_push(base); |
920 | } | 932 | } |
921 | 933 | ||
934 | static void nv_mac_reset(struct net_device *dev) | ||
935 | { | ||
936 | struct fe_priv *np = netdev_priv(dev); | ||
937 | u8 __iomem *base = get_hwbase(dev); | ||
938 | |||
939 | dprintk(KERN_DEBUG "%s: nv_mac_reset\n", dev->name); | ||
940 | writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl); | ||
941 | pci_push(base); | ||
942 | writel(NVREG_MAC_RESET_ASSERT, base + NvRegMacReset); | ||
943 | pci_push(base); | ||
944 | udelay(NV_MAC_RESET_DELAY); | ||
945 | writel(0, base + NvRegMacReset); | ||
946 | pci_push(base); | ||
947 | udelay(NV_MAC_RESET_DELAY); | ||
948 | writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl); | ||
949 | pci_push(base); | ||
950 | } | ||
951 | |||
922 | /* | 952 | /* |
923 | * nv_get_stats: dev->get_stats function | 953 | * nv_get_stats: dev->get_stats function |
924 | * Get latest stats value from the nic. | 954 | * Get latest stats value from the nic. |
@@ -1331,7 +1361,7 @@ static void nv_tx_timeout(struct net_device *dev) | |||
1331 | dev->name, (unsigned long)np->ring_addr, | 1361 | dev->name, (unsigned long)np->ring_addr, |
1332 | np->next_tx, np->nic_tx); | 1362 | np->next_tx, np->nic_tx); |
1333 | printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); | 1363 | printk(KERN_INFO "%s: Dumping tx registers\n", dev->name); |
1334 | for (i=0;i<0x400;i+= 32) { | 1364 | for (i=0;i<=np->register_size;i+= 32) { |
1335 | printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", | 1365 | printk(KERN_INFO "%3x: %08x %08x %08x %08x %08x %08x %08x %08x\n", |
1336 | i, | 1366 | i, |
1337 | readl(base + i + 0), readl(base + i + 4), | 1367 | readl(base + i + 0), readl(base + i + 4), |
@@ -2488,11 +2518,11 @@ static int nv_set_settings(struct net_device *dev, struct ethtool_cmd *ecmd) | |||
2488 | } | 2518 | } |
2489 | 2519 | ||
2490 | #define FORCEDETH_REGS_VER 1 | 2520 | #define FORCEDETH_REGS_VER 1 |
2491 | #define FORCEDETH_REGS_SIZE 0x400 /* 256 32-bit registers */ | ||
2492 | 2521 | ||
2493 | static int nv_get_regs_len(struct net_device *dev) | 2522 | static int nv_get_regs_len(struct net_device *dev) |
2494 | { | 2523 | { |
2495 | return FORCEDETH_REGS_SIZE; | 2524 | struct fe_priv *np = netdev_priv(dev); |
2525 | return np->register_size; | ||
2496 | } | 2526 | } |
2497 | 2527 | ||
2498 | static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) | 2528 | static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf) |
@@ -2504,7 +2534,7 @@ static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void | |||
2504 | 2534 | ||
2505 | regs->version = FORCEDETH_REGS_VER; | 2535 | regs->version = FORCEDETH_REGS_VER; |
2506 | spin_lock_irq(&np->lock); | 2536 | spin_lock_irq(&np->lock); |
2507 | for (i=0;i<FORCEDETH_REGS_SIZE/sizeof(u32);i++) | 2537 | for (i = 0;i <= np->register_size/sizeof(u32); i++) |
2508 | rbuf[i] = readl(base + i*sizeof(u32)); | 2538 | rbuf[i] = readl(base + i*sizeof(u32)); |
2509 | spin_unlock_irq(&np->lock); | 2539 | spin_unlock_irq(&np->lock); |
2510 | } | 2540 | } |
@@ -2608,6 +2638,8 @@ static int nv_open(struct net_device *dev) | |||
2608 | dprintk(KERN_DEBUG "nv_open: begin\n"); | 2638 | dprintk(KERN_DEBUG "nv_open: begin\n"); |
2609 | 2639 | ||
2610 | /* 1) erase previous misconfiguration */ | 2640 | /* 1) erase previous misconfiguration */ |
2641 | if (np->driver_data & DEV_HAS_POWER_CNTRL) | ||
2642 | nv_mac_reset(dev); | ||
2611 | /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */ | 2643 | /* 4.1-1: stop adapter: ignored, 4.3 seems to be overkill */ |
2612 | writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); | 2644 | writel(NVREG_MCASTADDRA_FORCE, base + NvRegMulticastAddrA); |
2613 | writel(0, base + NvRegMulticastAddrB); | 2645 | writel(0, base + NvRegMulticastAddrB); |
@@ -2878,6 +2910,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2878 | unsigned long addr; | 2910 | unsigned long addr; |
2879 | u8 __iomem *base; | 2911 | u8 __iomem *base; |
2880 | int err, i; | 2912 | int err, i; |
2913 | u32 powerstate; | ||
2881 | 2914 | ||
2882 | dev = alloc_etherdev(sizeof(struct fe_priv)); | 2915 | dev = alloc_etherdev(sizeof(struct fe_priv)); |
2883 | err = -ENOMEM; | 2916 | err = -ENOMEM; |
@@ -2910,6 +2943,11 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2910 | if (err < 0) | 2943 | if (err < 0) |
2911 | goto out_disable; | 2944 | goto out_disable; |
2912 | 2945 | ||
2946 | if (id->driver_data & (DEV_HAS_VLAN|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL)) | ||
2947 | np->register_size = NV_PCI_REGSZ_VER2; | ||
2948 | else | ||
2949 | np->register_size = NV_PCI_REGSZ_VER1; | ||
2950 | |||
2913 | err = -EINVAL; | 2951 | err = -EINVAL; |
2914 | addr = 0; | 2952 | addr = 0; |
2915 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { | 2953 | for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
@@ -2918,7 +2956,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2918 | pci_resource_len(pci_dev, i), | 2956 | pci_resource_len(pci_dev, i), |
2919 | pci_resource_flags(pci_dev, i)); | 2957 | pci_resource_flags(pci_dev, i)); |
2920 | if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && | 2958 | if (pci_resource_flags(pci_dev, i) & IORESOURCE_MEM && |
2921 | pci_resource_len(pci_dev, i) >= NV_PCI_REGSZ) { | 2959 | pci_resource_len(pci_dev, i) >= np->register_size) { |
2922 | addr = pci_resource_start(pci_dev, i); | 2960 | addr = pci_resource_start(pci_dev, i); |
2923 | break; | 2961 | break; |
2924 | } | 2962 | } |
@@ -2929,6 +2967,9 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2929 | goto out_relreg; | 2967 | goto out_relreg; |
2930 | } | 2968 | } |
2931 | 2969 | ||
2970 | /* copy of driver data */ | ||
2971 | np->driver_data = id->driver_data; | ||
2972 | |||
2932 | /* handle different descriptor versions */ | 2973 | /* handle different descriptor versions */ |
2933 | if (id->driver_data & DEV_HAS_HIGH_DMA) { | 2974 | if (id->driver_data & DEV_HAS_HIGH_DMA) { |
2934 | /* packet format 3: supports 40-bit addressing */ | 2975 | /* packet format 3: supports 40-bit addressing */ |
@@ -2986,7 +3027,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
2986 | } | 3027 | } |
2987 | 3028 | ||
2988 | err = -ENOMEM; | 3029 | err = -ENOMEM; |
2989 | np->base = ioremap(addr, NV_PCI_REGSZ); | 3030 | np->base = ioremap(addr, np->register_size); |
2990 | if (!np->base) | 3031 | if (!np->base) |
2991 | goto out_relreg; | 3032 | goto out_relreg; |
2992 | dev->base_addr = (unsigned long)np->base; | 3033 | dev->base_addr = (unsigned long)np->base; |
@@ -3062,6 +3103,20 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i | |||
3062 | writel(0, base + NvRegWakeUpFlags); | 3103 | writel(0, base + NvRegWakeUpFlags); |
3063 | np->wolenabled = 0; | 3104 | np->wolenabled = 0; |
3064 | 3105 | ||
3106 | if (id->driver_data & DEV_HAS_POWER_CNTRL) { | ||
3107 | u8 revision_id; | ||
3108 | pci_read_config_byte(pci_dev, PCI_REVISION_ID, &revision_id); | ||
3109 | |||
3110 | /* take phy and nic out of low power mode */ | ||
3111 | powerstate = readl(base + NvRegPowerState2); | ||
3112 | powerstate &= ~NVREG_POWERSTATE2_POWERUP_MASK; | ||
3113 | if ((id->device == PCI_DEVICE_ID_NVIDIA_NVENET_12 || | ||
3114 | id->device == PCI_DEVICE_ID_NVIDIA_NVENET_13) && | ||
3115 | revision_id >= 0xA3) | ||
3116 | powerstate |= NVREG_POWERSTATE2_POWERUP_REV_A3; | ||
3117 | writel(powerstate, base + NvRegPowerState2); | ||
3118 | } | ||
3119 | |||
3065 | if (np->desc_ver == DESC_VER_1) { | 3120 | if (np->desc_ver == DESC_VER_1) { |
3066 | np->tx_flags = NV_TX_VALID; | 3121 | np->tx_flags = NV_TX_VALID; |
3067 | } else { | 3122 | } else { |
@@ -3223,19 +3278,19 @@ static struct pci_device_id pci_tbl[] = { | |||
3223 | }, | 3278 | }, |
3224 | { /* MCP51 Ethernet Controller */ | 3279 | { /* MCP51 Ethernet Controller */ |
3225 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), | 3280 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12), |
3226 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, | 3281 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, |
3227 | }, | 3282 | }, |
3228 | { /* MCP51 Ethernet Controller */ | 3283 | { /* MCP51 Ethernet Controller */ |
3229 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), | 3284 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_13), |
3230 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA, | 3285 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_HIGH_DMA|DEV_HAS_POWER_CNTRL, |
3231 | }, | 3286 | }, |
3232 | { /* MCP55 Ethernet Controller */ | 3287 | { /* MCP55 Ethernet Controller */ |
3233 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), | 3288 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14), |
3234 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X, | 3289 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL, |
3235 | }, | 3290 | }, |
3236 | { /* MCP55 Ethernet Controller */ | 3291 | { /* MCP55 Ethernet Controller */ |
3237 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), | 3292 | PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15), |
3238 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X, | 3293 | .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_VLAN|DEV_HAS_MSI|DEV_HAS_MSI_X|DEV_HAS_POWER_CNTRL, |
3239 | }, | 3294 | }, |
3240 | {0,}, | 3295 | {0,}, |
3241 | }; | 3296 | }; |
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 771e25d8c417..218d31764c52 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -210,7 +210,8 @@ static int gfar_probe(struct platform_device *pdev) | |||
210 | goto regs_fail; | 210 | goto regs_fail; |
211 | } | 211 | } |
212 | 212 | ||
213 | spin_lock_init(&priv->lock); | 213 | spin_lock_init(&priv->txlock); |
214 | spin_lock_init(&priv->rxlock); | ||
214 | 215 | ||
215 | platform_set_drvdata(pdev, dev); | 216 | platform_set_drvdata(pdev, dev); |
216 | 217 | ||
@@ -515,11 +516,13 @@ void stop_gfar(struct net_device *dev) | |||
515 | phy_stop(priv->phydev); | 516 | phy_stop(priv->phydev); |
516 | 517 | ||
517 | /* Lock it down */ | 518 | /* Lock it down */ |
518 | spin_lock_irqsave(&priv->lock, flags); | 519 | spin_lock_irqsave(&priv->txlock, flags); |
520 | spin_lock(&priv->rxlock); | ||
519 | 521 | ||
520 | gfar_halt(dev); | 522 | gfar_halt(dev); |
521 | 523 | ||
522 | spin_unlock_irqrestore(&priv->lock, flags); | 524 | spin_unlock(&priv->rxlock); |
525 | spin_unlock_irqrestore(&priv->txlock, flags); | ||
523 | 526 | ||
524 | /* Free the IRQs */ | 527 | /* Free the IRQs */ |
525 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { | 528 | if (priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) { |
@@ -605,14 +608,15 @@ void gfar_start(struct net_device *dev) | |||
605 | tempval |= DMACTRL_INIT_SETTINGS; | 608 | tempval |= DMACTRL_INIT_SETTINGS; |
606 | gfar_write(&priv->regs->dmactrl, tempval); | 609 | gfar_write(&priv->regs->dmactrl, tempval); |
607 | 610 | ||
608 | /* Clear THLT, so that the DMA starts polling now */ | ||
609 | gfar_write(®s->tstat, TSTAT_CLEAR_THALT); | ||
610 | |||
611 | /* Make sure we aren't stopped */ | 611 | /* Make sure we aren't stopped */ |
612 | tempval = gfar_read(&priv->regs->dmactrl); | 612 | tempval = gfar_read(&priv->regs->dmactrl); |
613 | tempval &= ~(DMACTRL_GRS | DMACTRL_GTS); | 613 | tempval &= ~(DMACTRL_GRS | DMACTRL_GTS); |
614 | gfar_write(&priv->regs->dmactrl, tempval); | 614 | gfar_write(&priv->regs->dmactrl, tempval); |
615 | 615 | ||
616 | /* Clear THLT/RHLT, so that the DMA starts polling now */ | ||
617 | gfar_write(®s->tstat, TSTAT_CLEAR_THALT); | ||
618 | gfar_write(®s->rstat, RSTAT_CLEAR_RHALT); | ||
619 | |||
616 | /* Unmask the interrupts we look for */ | 620 | /* Unmask the interrupts we look for */ |
617 | gfar_write(®s->imask, IMASK_DEFAULT); | 621 | gfar_write(®s->imask, IMASK_DEFAULT); |
618 | } | 622 | } |
@@ -928,12 +932,13 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
928 | struct txfcb *fcb = NULL; | 932 | struct txfcb *fcb = NULL; |
929 | struct txbd8 *txbdp; | 933 | struct txbd8 *txbdp; |
930 | u16 status; | 934 | u16 status; |
935 | unsigned long flags; | ||
931 | 936 | ||
932 | /* Update transmit stats */ | 937 | /* Update transmit stats */ |
933 | priv->stats.tx_bytes += skb->len; | 938 | priv->stats.tx_bytes += skb->len; |
934 | 939 | ||
935 | /* Lock priv now */ | 940 | /* Lock priv now */ |
936 | spin_lock_irq(&priv->lock); | 941 | spin_lock_irqsave(&priv->txlock, flags); |
937 | 942 | ||
938 | /* Point at the first free tx descriptor */ | 943 | /* Point at the first free tx descriptor */ |
939 | txbdp = priv->cur_tx; | 944 | txbdp = priv->cur_tx; |
@@ -1004,7 +1009,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1004 | gfar_write(&priv->regs->tstat, TSTAT_CLEAR_THALT); | 1009 | gfar_write(&priv->regs->tstat, TSTAT_CLEAR_THALT); |
1005 | 1010 | ||
1006 | /* Unlock priv */ | 1011 | /* Unlock priv */ |
1007 | spin_unlock_irq(&priv->lock); | 1012 | spin_unlock_irqrestore(&priv->txlock, flags); |
1008 | 1013 | ||
1009 | return 0; | 1014 | return 0; |
1010 | } | 1015 | } |
@@ -1049,7 +1054,7 @@ static void gfar_vlan_rx_register(struct net_device *dev, | |||
1049 | unsigned long flags; | 1054 | unsigned long flags; |
1050 | u32 tempval; | 1055 | u32 tempval; |
1051 | 1056 | ||
1052 | spin_lock_irqsave(&priv->lock, flags); | 1057 | spin_lock_irqsave(&priv->rxlock, flags); |
1053 | 1058 | ||
1054 | priv->vlgrp = grp; | 1059 | priv->vlgrp = grp; |
1055 | 1060 | ||
@@ -1076,7 +1081,7 @@ static void gfar_vlan_rx_register(struct net_device *dev, | |||
1076 | gfar_write(&priv->regs->rctrl, tempval); | 1081 | gfar_write(&priv->regs->rctrl, tempval); |
1077 | } | 1082 | } |
1078 | 1083 | ||
1079 | spin_unlock_irqrestore(&priv->lock, flags); | 1084 | spin_unlock_irqrestore(&priv->rxlock, flags); |
1080 | } | 1085 | } |
1081 | 1086 | ||
1082 | 1087 | ||
@@ -1085,12 +1090,12 @@ static void gfar_vlan_rx_kill_vid(struct net_device *dev, uint16_t vid) | |||
1085 | struct gfar_private *priv = netdev_priv(dev); | 1090 | struct gfar_private *priv = netdev_priv(dev); |
1086 | unsigned long flags; | 1091 | unsigned long flags; |
1087 | 1092 | ||
1088 | spin_lock_irqsave(&priv->lock, flags); | 1093 | spin_lock_irqsave(&priv->rxlock, flags); |
1089 | 1094 | ||
1090 | if (priv->vlgrp) | 1095 | if (priv->vlgrp) |
1091 | priv->vlgrp->vlan_devices[vid] = NULL; | 1096 | priv->vlgrp->vlan_devices[vid] = NULL; |
1092 | 1097 | ||
1093 | spin_unlock_irqrestore(&priv->lock, flags); | 1098 | spin_unlock_irqrestore(&priv->rxlock, flags); |
1094 | } | 1099 | } |
1095 | 1100 | ||
1096 | 1101 | ||
@@ -1179,7 +1184,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs) | |||
1179 | gfar_write(&priv->regs->ievent, IEVENT_TX_MASK); | 1184 | gfar_write(&priv->regs->ievent, IEVENT_TX_MASK); |
1180 | 1185 | ||
1181 | /* Lock priv */ | 1186 | /* Lock priv */ |
1182 | spin_lock(&priv->lock); | 1187 | spin_lock(&priv->txlock); |
1183 | bdp = priv->dirty_tx; | 1188 | bdp = priv->dirty_tx; |
1184 | while ((bdp->status & TXBD_READY) == 0) { | 1189 | while ((bdp->status & TXBD_READY) == 0) { |
1185 | /* If dirty_tx and cur_tx are the same, then either the */ | 1190 | /* If dirty_tx and cur_tx are the same, then either the */ |
@@ -1224,7 +1229,7 @@ static irqreturn_t gfar_transmit(int irq, void *dev_id, struct pt_regs *regs) | |||
1224 | else | 1229 | else |
1225 | gfar_write(&priv->regs->txic, 0); | 1230 | gfar_write(&priv->regs->txic, 0); |
1226 | 1231 | ||
1227 | spin_unlock(&priv->lock); | 1232 | spin_unlock(&priv->txlock); |
1228 | 1233 | ||
1229 | return IRQ_HANDLED; | 1234 | return IRQ_HANDLED; |
1230 | } | 1235 | } |
@@ -1305,9 +1310,10 @@ irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs) | |||
1305 | { | 1310 | { |
1306 | struct net_device *dev = (struct net_device *) dev_id; | 1311 | struct net_device *dev = (struct net_device *) dev_id; |
1307 | struct gfar_private *priv = netdev_priv(dev); | 1312 | struct gfar_private *priv = netdev_priv(dev); |
1308 | |||
1309 | #ifdef CONFIG_GFAR_NAPI | 1313 | #ifdef CONFIG_GFAR_NAPI |
1310 | u32 tempval; | 1314 | u32 tempval; |
1315 | #else | ||
1316 | unsigned long flags; | ||
1311 | #endif | 1317 | #endif |
1312 | 1318 | ||
1313 | /* Clear IEVENT, so rx interrupt isn't called again | 1319 | /* Clear IEVENT, so rx interrupt isn't called again |
@@ -1330,7 +1336,7 @@ irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs) | |||
1330 | } | 1336 | } |
1331 | #else | 1337 | #else |
1332 | 1338 | ||
1333 | spin_lock(&priv->lock); | 1339 | spin_lock_irqsave(&priv->rxlock, flags); |
1334 | gfar_clean_rx_ring(dev, priv->rx_ring_size); | 1340 | gfar_clean_rx_ring(dev, priv->rx_ring_size); |
1335 | 1341 | ||
1336 | /* If we are coalescing interrupts, update the timer */ | 1342 | /* If we are coalescing interrupts, update the timer */ |
@@ -1341,7 +1347,7 @@ irqreturn_t gfar_receive(int irq, void *dev_id, struct pt_regs *regs) | |||
1341 | else | 1347 | else |
1342 | gfar_write(&priv->regs->rxic, 0); | 1348 | gfar_write(&priv->regs->rxic, 0); |
1343 | 1349 | ||
1344 | spin_unlock(&priv->lock); | 1350 | spin_unlock_irqrestore(&priv->rxlock, flags); |
1345 | #endif | 1351 | #endif |
1346 | 1352 | ||
1347 | return IRQ_HANDLED; | 1353 | return IRQ_HANDLED; |
@@ -1490,13 +1496,6 @@ int gfar_clean_rx_ring(struct net_device *dev, int rx_work_limit) | |||
1490 | /* Update the current rxbd pointer to be the next one */ | 1496 | /* Update the current rxbd pointer to be the next one */ |
1491 | priv->cur_rx = bdp; | 1497 | priv->cur_rx = bdp; |
1492 | 1498 | ||
1493 | /* If no packets have arrived since the | ||
1494 | * last one we processed, clear the IEVENT RX and | ||
1495 | * BSY bits so that another interrupt won't be | ||
1496 | * generated when we set IMASK */ | ||
1497 | if (bdp->status & RXBD_EMPTY) | ||
1498 | gfar_write(&priv->regs->ievent, IEVENT_RX_MASK); | ||
1499 | |||
1500 | return howmany; | 1499 | return howmany; |
1501 | } | 1500 | } |
1502 | 1501 | ||
@@ -1516,7 +1515,7 @@ static int gfar_poll(struct net_device *dev, int *budget) | |||
1516 | rx_work_limit -= howmany; | 1515 | rx_work_limit -= howmany; |
1517 | *budget -= howmany; | 1516 | *budget -= howmany; |
1518 | 1517 | ||
1519 | if (rx_work_limit >= 0) { | 1518 | if (rx_work_limit > 0) { |
1520 | netif_rx_complete(dev); | 1519 | netif_rx_complete(dev); |
1521 | 1520 | ||
1522 | /* Clear the halt bit in RSTAT */ | 1521 | /* Clear the halt bit in RSTAT */ |
@@ -1533,7 +1532,8 @@ static int gfar_poll(struct net_device *dev, int *budget) | |||
1533 | gfar_write(&priv->regs->rxic, 0); | 1532 | gfar_write(&priv->regs->rxic, 0); |
1534 | } | 1533 | } |
1535 | 1534 | ||
1536 | return (rx_work_limit < 0) ? 1 : 0; | 1535 | /* Return 1 if there's more work to do */ |
1536 | return (rx_work_limit > 0) ? 0 : 1; | ||
1537 | } | 1537 | } |
1538 | #endif | 1538 | #endif |
1539 | 1539 | ||
@@ -1629,7 +1629,7 @@ static void adjust_link(struct net_device *dev) | |||
1629 | struct phy_device *phydev = priv->phydev; | 1629 | struct phy_device *phydev = priv->phydev; |
1630 | int new_state = 0; | 1630 | int new_state = 0; |
1631 | 1631 | ||
1632 | spin_lock_irqsave(&priv->lock, flags); | 1632 | spin_lock_irqsave(&priv->txlock, flags); |
1633 | if (phydev->link) { | 1633 | if (phydev->link) { |
1634 | u32 tempval = gfar_read(®s->maccfg2); | 1634 | u32 tempval = gfar_read(®s->maccfg2); |
1635 | u32 ecntrl = gfar_read(®s->ecntrl); | 1635 | u32 ecntrl = gfar_read(®s->ecntrl); |
@@ -1694,7 +1694,7 @@ static void adjust_link(struct net_device *dev) | |||
1694 | if (new_state && netif_msg_link(priv)) | 1694 | if (new_state && netif_msg_link(priv)) |
1695 | phy_print_status(phydev); | 1695 | phy_print_status(phydev); |
1696 | 1696 | ||
1697 | spin_unlock_irqrestore(&priv->lock, flags); | 1697 | spin_unlock_irqrestore(&priv->txlock, flags); |
1698 | } | 1698 | } |
1699 | 1699 | ||
1700 | /* Update the hash table based on the current list of multicast | 1700 | /* Update the hash table based on the current list of multicast |
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index d37d5401be6e..127c98cf3336 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -656,43 +656,62 @@ struct gfar { | |||
656 | * the buffer descriptor determines the actual condition. | 656 | * the buffer descriptor determines the actual condition. |
657 | */ | 657 | */ |
658 | struct gfar_private { | 658 | struct gfar_private { |
659 | /* pointers to arrays of skbuffs for tx and rx */ | 659 | /* Fields controlled by TX lock */ |
660 | spinlock_t txlock; | ||
661 | |||
662 | /* Pointer to the array of skbuffs */ | ||
660 | struct sk_buff ** tx_skbuff; | 663 | struct sk_buff ** tx_skbuff; |
661 | struct sk_buff ** rx_skbuff; | ||
662 | 664 | ||
663 | /* indices pointing to the next free sbk in skb arrays */ | 665 | /* next free skb in the array */ |
664 | u16 skb_curtx; | 666 | u16 skb_curtx; |
665 | u16 skb_currx; | ||
666 | 667 | ||
667 | /* index of the first skb which hasn't been transmitted | 668 | /* First skb in line to be transmitted */ |
668 | * yet. */ | ||
669 | u16 skb_dirtytx; | 669 | u16 skb_dirtytx; |
670 | 670 | ||
671 | /* Configuration info for the coalescing features */ | 671 | /* Configuration info for the coalescing features */ |
672 | unsigned char txcoalescing; | 672 | unsigned char txcoalescing; |
673 | unsigned short txcount; | 673 | unsigned short txcount; |
674 | unsigned short txtime; | 674 | unsigned short txtime; |
675 | |||
676 | /* Buffer descriptor pointers */ | ||
677 | struct txbd8 *tx_bd_base; /* First tx buffer descriptor */ | ||
678 | struct txbd8 *cur_tx; /* Next free ring entry */ | ||
679 | struct txbd8 *dirty_tx; /* First buffer in line | ||
680 | to be transmitted */ | ||
681 | unsigned int tx_ring_size; | ||
682 | |||
683 | /* RX Locked fields */ | ||
684 | spinlock_t rxlock; | ||
685 | |||
686 | /* skb array and index */ | ||
687 | struct sk_buff ** rx_skbuff; | ||
688 | u16 skb_currx; | ||
689 | |||
690 | /* RX Coalescing values */ | ||
675 | unsigned char rxcoalescing; | 691 | unsigned char rxcoalescing; |
676 | unsigned short rxcount; | 692 | unsigned short rxcount; |
677 | unsigned short rxtime; | 693 | unsigned short rxtime; |
678 | 694 | ||
679 | /* GFAR addresses */ | 695 | struct rxbd8 *rx_bd_base; /* First Rx buffers */ |
680 | struct rxbd8 *rx_bd_base; /* Base addresses of Rx and Tx Buffers */ | ||
681 | struct txbd8 *tx_bd_base; | ||
682 | struct rxbd8 *cur_rx; /* Next free rx ring entry */ | 696 | struct rxbd8 *cur_rx; /* Next free rx ring entry */ |
683 | struct txbd8 *cur_tx; /* Next free ring entry */ | 697 | |
684 | struct txbd8 *dirty_tx; /* The Ring entry to be freed. */ | 698 | /* RX parameters */ |
685 | struct gfar __iomem *regs; /* Pointer to the GFAR memory mapped Registers */ | 699 | unsigned int rx_ring_size; |
686 | u32 __iomem *hash_regs[16]; | ||
687 | int hash_width; | ||
688 | struct net_device_stats stats; /* linux network statistics */ | ||
689 | struct gfar_extra_stats extra_stats; | ||
690 | spinlock_t lock; | ||
691 | unsigned int rx_buffer_size; | 700 | unsigned int rx_buffer_size; |
692 | unsigned int rx_stash_size; | 701 | unsigned int rx_stash_size; |
693 | unsigned int rx_stash_index; | 702 | unsigned int rx_stash_index; |
694 | unsigned int tx_ring_size; | 703 | |
695 | unsigned int rx_ring_size; | 704 | struct vlan_group *vlgrp; |
705 | |||
706 | /* Unprotected fields */ | ||
707 | /* Pointer to the GFAR memory mapped Registers */ | ||
708 | struct gfar __iomem *regs; | ||
709 | |||
710 | /* Hash registers and their width */ | ||
711 | u32 __iomem *hash_regs[16]; | ||
712 | int hash_width; | ||
713 | |||
714 | /* global parameters */ | ||
696 | unsigned int fifo_threshold; | 715 | unsigned int fifo_threshold; |
697 | unsigned int fifo_starve; | 716 | unsigned int fifo_starve; |
698 | unsigned int fifo_starve_off; | 717 | unsigned int fifo_starve_off; |
@@ -702,13 +721,15 @@ struct gfar_private { | |||
702 | extended_hash:1, | 721 | extended_hash:1, |
703 | bd_stash_en:1; | 722 | bd_stash_en:1; |
704 | unsigned short padding; | 723 | unsigned short padding; |
705 | struct vlan_group *vlgrp; | 724 | |
706 | /* Info structure initialized by board setup code */ | ||
707 | unsigned int interruptTransmit; | 725 | unsigned int interruptTransmit; |
708 | unsigned int interruptReceive; | 726 | unsigned int interruptReceive; |
709 | unsigned int interruptError; | 727 | unsigned int interruptError; |
728 | |||
729 | /* info structure initialized by platform code */ | ||
710 | struct gianfar_platform_data *einfo; | 730 | struct gianfar_platform_data *einfo; |
711 | 731 | ||
732 | /* PHY stuff */ | ||
712 | struct phy_device *phydev; | 733 | struct phy_device *phydev; |
713 | struct mii_bus *mii_bus; | 734 | struct mii_bus *mii_bus; |
714 | int oldspeed; | 735 | int oldspeed; |
@@ -716,6 +737,10 @@ struct gfar_private { | |||
716 | int oldlink; | 737 | int oldlink; |
717 | 738 | ||
718 | uint32_t msg_enable; | 739 | uint32_t msg_enable; |
740 | |||
741 | /* Network Statistics */ | ||
742 | struct net_device_stats stats; | ||
743 | struct gfar_extra_stats extra_stats; | ||
719 | }; | 744 | }; |
720 | 745 | ||
721 | static inline u32 gfar_read(volatile unsigned __iomem *addr) | 746 | static inline u32 gfar_read(volatile unsigned __iomem *addr) |
diff --git a/drivers/net/gianfar_ethtool.c b/drivers/net/gianfar_ethtool.c index 5de7b2e259dc..d69698c695ef 100644 --- a/drivers/net/gianfar_ethtool.c +++ b/drivers/net/gianfar_ethtool.c | |||
@@ -455,10 +455,14 @@ static int gfar_sringparam(struct net_device *dev, struct ethtool_ringparam *rva | |||
455 | 455 | ||
456 | /* Halt TX and RX, and process the frames which | 456 | /* Halt TX and RX, and process the frames which |
457 | * have already been received */ | 457 | * have already been received */ |
458 | spin_lock_irqsave(&priv->lock, flags); | 458 | spin_lock_irqsave(&priv->txlock, flags); |
459 | spin_lock(&priv->rxlock); | ||
460 | |||
459 | gfar_halt(dev); | 461 | gfar_halt(dev); |
460 | gfar_clean_rx_ring(dev, priv->rx_ring_size); | 462 | gfar_clean_rx_ring(dev, priv->rx_ring_size); |
461 | spin_unlock_irqrestore(&priv->lock, flags); | 463 | |
464 | spin_unlock(&priv->rxlock); | ||
465 | spin_unlock_irqrestore(&priv->txlock, flags); | ||
462 | 466 | ||
463 | /* Now we take down the rings to rebuild them */ | 467 | /* Now we take down the rings to rebuild them */ |
464 | stop_gfar(dev); | 468 | stop_gfar(dev); |
@@ -488,10 +492,14 @@ static int gfar_set_rx_csum(struct net_device *dev, uint32_t data) | |||
488 | 492 | ||
489 | /* Halt TX and RX, and process the frames which | 493 | /* Halt TX and RX, and process the frames which |
490 | * have already been received */ | 494 | * have already been received */ |
491 | spin_lock_irqsave(&priv->lock, flags); | 495 | spin_lock_irqsave(&priv->txlock, flags); |
496 | spin_lock(&priv->rxlock); | ||
497 | |||
492 | gfar_halt(dev); | 498 | gfar_halt(dev); |
493 | gfar_clean_rx_ring(dev, priv->rx_ring_size); | 499 | gfar_clean_rx_ring(dev, priv->rx_ring_size); |
494 | spin_unlock_irqrestore(&priv->lock, flags); | 500 | |
501 | spin_unlock(&priv->rxlock); | ||
502 | spin_unlock_irqrestore(&priv->txlock, flags); | ||
495 | 503 | ||
496 | /* Now we take down the rings to rebuild them */ | 504 | /* Now we take down the rings to rebuild them */ |
497 | stop_gfar(dev); | 505 | stop_gfar(dev); |
@@ -523,7 +531,7 @@ static int gfar_set_tx_csum(struct net_device *dev, uint32_t data) | |||
523 | if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) | 531 | if (!(priv->einfo->device_flags & FSL_GIANFAR_DEV_HAS_CSUM)) |
524 | return -EOPNOTSUPP; | 532 | return -EOPNOTSUPP; |
525 | 533 | ||
526 | spin_lock_irqsave(&priv->lock, flags); | 534 | spin_lock_irqsave(&priv->txlock, flags); |
527 | gfar_halt(dev); | 535 | gfar_halt(dev); |
528 | 536 | ||
529 | if (data) | 537 | if (data) |
@@ -532,7 +540,7 @@ static int gfar_set_tx_csum(struct net_device *dev, uint32_t data) | |||
532 | dev->features &= ~NETIF_F_IP_CSUM; | 540 | dev->features &= ~NETIF_F_IP_CSUM; |
533 | 541 | ||
534 | gfar_start(dev); | 542 | gfar_start(dev); |
535 | spin_unlock_irqrestore(&priv->lock, flags); | 543 | spin_unlock_irqrestore(&priv->txlock, flags); |
536 | 544 | ||
537 | return 0; | 545 | return 0; |
538 | } | 546 | } |
diff --git a/drivers/net/gianfar_sysfs.c b/drivers/net/gianfar_sysfs.c index 51ef181b1368..a6d5c43199cb 100644 --- a/drivers/net/gianfar_sysfs.c +++ b/drivers/net/gianfar_sysfs.c | |||
@@ -82,7 +82,7 @@ static ssize_t gfar_set_bd_stash(struct class_device *cdev, | |||
82 | else | 82 | else |
83 | return count; | 83 | return count; |
84 | 84 | ||
85 | spin_lock_irqsave(&priv->lock, flags); | 85 | spin_lock_irqsave(&priv->rxlock, flags); |
86 | 86 | ||
87 | /* Set the new stashing value */ | 87 | /* Set the new stashing value */ |
88 | priv->bd_stash_en = new_setting; | 88 | priv->bd_stash_en = new_setting; |
@@ -96,7 +96,7 @@ static ssize_t gfar_set_bd_stash(struct class_device *cdev, | |||
96 | 96 | ||
97 | gfar_write(&priv->regs->attr, temp); | 97 | gfar_write(&priv->regs->attr, temp); |
98 | 98 | ||
99 | spin_unlock_irqrestore(&priv->lock, flags); | 99 | spin_unlock_irqrestore(&priv->rxlock, flags); |
100 | 100 | ||
101 | return count; | 101 | return count; |
102 | } | 102 | } |
@@ -118,7 +118,7 @@ static ssize_t gfar_set_rx_stash_size(struct class_device *cdev, | |||
118 | u32 temp; | 118 | u32 temp; |
119 | unsigned long flags; | 119 | unsigned long flags; |
120 | 120 | ||
121 | spin_lock_irqsave(&priv->lock, flags); | 121 | spin_lock_irqsave(&priv->rxlock, flags); |
122 | if (length > priv->rx_buffer_size) | 122 | if (length > priv->rx_buffer_size) |
123 | return count; | 123 | return count; |
124 | 124 | ||
@@ -142,7 +142,7 @@ static ssize_t gfar_set_rx_stash_size(struct class_device *cdev, | |||
142 | 142 | ||
143 | gfar_write(&priv->regs->attr, temp); | 143 | gfar_write(&priv->regs->attr, temp); |
144 | 144 | ||
145 | spin_unlock_irqrestore(&priv->lock, flags); | 145 | spin_unlock_irqrestore(&priv->rxlock, flags); |
146 | 146 | ||
147 | return count; | 147 | return count; |
148 | } | 148 | } |
@@ -166,7 +166,7 @@ static ssize_t gfar_set_rx_stash_index(struct class_device *cdev, | |||
166 | u32 temp; | 166 | u32 temp; |
167 | unsigned long flags; | 167 | unsigned long flags; |
168 | 168 | ||
169 | spin_lock_irqsave(&priv->lock, flags); | 169 | spin_lock_irqsave(&priv->rxlock, flags); |
170 | if (index > priv->rx_stash_size) | 170 | if (index > priv->rx_stash_size) |
171 | return count; | 171 | return count; |
172 | 172 | ||
@@ -180,7 +180,7 @@ static ssize_t gfar_set_rx_stash_index(struct class_device *cdev, | |||
180 | temp |= ATTRELI_EI(index); | 180 | temp |= ATTRELI_EI(index); |
181 | gfar_write(&priv->regs->attreli, flags); | 181 | gfar_write(&priv->regs->attreli, flags); |
182 | 182 | ||
183 | spin_unlock_irqrestore(&priv->lock, flags); | 183 | spin_unlock_irqrestore(&priv->rxlock, flags); |
184 | 184 | ||
185 | return count; | 185 | return count; |
186 | } | 186 | } |
@@ -205,7 +205,7 @@ static ssize_t gfar_set_fifo_threshold(struct class_device *cdev, | |||
205 | if (length > GFAR_MAX_FIFO_THRESHOLD) | 205 | if (length > GFAR_MAX_FIFO_THRESHOLD) |
206 | return count; | 206 | return count; |
207 | 207 | ||
208 | spin_lock_irqsave(&priv->lock, flags); | 208 | spin_lock_irqsave(&priv->txlock, flags); |
209 | 209 | ||
210 | priv->fifo_threshold = length; | 210 | priv->fifo_threshold = length; |
211 | 211 | ||
@@ -214,7 +214,7 @@ static ssize_t gfar_set_fifo_threshold(struct class_device *cdev, | |||
214 | temp |= length; | 214 | temp |= length; |
215 | gfar_write(&priv->regs->fifo_tx_thr, temp); | 215 | gfar_write(&priv->regs->fifo_tx_thr, temp); |
216 | 216 | ||
217 | spin_unlock_irqrestore(&priv->lock, flags); | 217 | spin_unlock_irqrestore(&priv->txlock, flags); |
218 | 218 | ||
219 | return count; | 219 | return count; |
220 | } | 220 | } |
@@ -240,7 +240,7 @@ static ssize_t gfar_set_fifo_starve(struct class_device *cdev, | |||
240 | if (num > GFAR_MAX_FIFO_STARVE) | 240 | if (num > GFAR_MAX_FIFO_STARVE) |
241 | return count; | 241 | return count; |
242 | 242 | ||
243 | spin_lock_irqsave(&priv->lock, flags); | 243 | spin_lock_irqsave(&priv->txlock, flags); |
244 | 244 | ||
245 | priv->fifo_starve = num; | 245 | priv->fifo_starve = num; |
246 | 246 | ||
@@ -249,7 +249,7 @@ static ssize_t gfar_set_fifo_starve(struct class_device *cdev, | |||
249 | temp |= num; | 249 | temp |= num; |
250 | gfar_write(&priv->regs->fifo_tx_starve, temp); | 250 | gfar_write(&priv->regs->fifo_tx_starve, temp); |
251 | 251 | ||
252 | spin_unlock_irqrestore(&priv->lock, flags); | 252 | spin_unlock_irqrestore(&priv->txlock, flags); |
253 | 253 | ||
254 | return count; | 254 | return count; |
255 | } | 255 | } |
@@ -274,7 +274,7 @@ static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev, | |||
274 | if (num > GFAR_MAX_FIFO_STARVE_OFF) | 274 | if (num > GFAR_MAX_FIFO_STARVE_OFF) |
275 | return count; | 275 | return count; |
276 | 276 | ||
277 | spin_lock_irqsave(&priv->lock, flags); | 277 | spin_lock_irqsave(&priv->txlock, flags); |
278 | 278 | ||
279 | priv->fifo_starve_off = num; | 279 | priv->fifo_starve_off = num; |
280 | 280 | ||
@@ -283,7 +283,7 @@ static ssize_t gfar_set_fifo_starve_off(struct class_device *cdev, | |||
283 | temp |= num; | 283 | temp |= num; |
284 | gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp); | 284 | gfar_write(&priv->regs->fifo_tx_starve_shutoff, temp); |
285 | 285 | ||
286 | spin_unlock_irqrestore(&priv->lock, flags); | 286 | spin_unlock_irqrestore(&priv->txlock, flags); |
287 | 287 | ||
288 | return count; | 288 | return count; |
289 | } | 289 | } |
diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 08b218c5bfbc..93c494bcd18d 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c | |||
@@ -226,7 +226,7 @@ struct net_device * __init ne_probe(int unit) | |||
226 | netdev_boot_setup_check(dev); | 226 | netdev_boot_setup_check(dev); |
227 | 227 | ||
228 | #ifdef CONFIG_TOSHIBA_RBTX4938 | 228 | #ifdef CONFIG_TOSHIBA_RBTX4938 |
229 | dev->base_addr = 0x07f20280; | 229 | dev->base_addr = RBTX4938_RTL_8019_BASE; |
230 | dev->irq = RBTX4938_RTL_8019_IRQ; | 230 | dev->irq = RBTX4938_RTL_8019_IRQ; |
231 | #endif | 231 | #endif |
232 | err = do_ne_probe(dev); | 232 | err = do_ne_probe(dev); |
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c index 506e777c5f06..d090df413049 100644 --- a/drivers/net/pcmcia/pcnet_cs.c +++ b/drivers/net/pcmcia/pcnet_cs.c | |||
@@ -1639,6 +1639,7 @@ static struct pcmcia_device_id pcnet_ids[] = { | |||
1639 | PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722), | 1639 | PCMCIA_DEVICE_PROD_ID12("CONTEC", "C-NET(PC)C-10L", 0x21cab552, 0xf6f90722), |
1640 | PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2), | 1640 | PCMCIA_DEVICE_PROD_ID12("corega", "FEther PCC-TXF", 0x0a21501a, 0xa51564a2), |
1641 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd), | 1641 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-T", 0x5261440f, 0xfa9d85bd), |
1642 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega EtherII PCC-TD", 0x5261440f, 0xc49bd73d), | ||
1642 | PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d), | 1643 | PCMCIA_DEVICE_PROD_ID12("Corega K.K.", "corega EtherII PCC-TD", 0xd4fdcbd8, 0xc49bd73d), |
1643 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-T", 0x5261440f, 0x6705fcaa), | 1644 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega Ether PCC-T", 0x5261440f, 0x6705fcaa), |
1644 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FastEther PCC-TX", 0x5261440f, 0x485e85d9), | 1645 | PCMCIA_DEVICE_PROD_ID12("corega K.K.", "corega FastEther PCC-TX", 0x5261440f, 0x485e85d9), |
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 67b0eab16589..227df9876a2c 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -51,7 +51,7 @@ | |||
51 | #include "sky2.h" | 51 | #include "sky2.h" |
52 | 52 | ||
53 | #define DRV_NAME "sky2" | 53 | #define DRV_NAME "sky2" |
54 | #define DRV_VERSION "1.1" | 54 | #define DRV_VERSION "1.2" |
55 | #define PFX DRV_NAME " " | 55 | #define PFX DRV_NAME " " |
56 | 56 | ||
57 | /* | 57 | /* |
@@ -925,8 +925,7 @@ static inline struct sk_buff *sky2_alloc_skb(unsigned int size, gfp_t gfp_mask) | |||
925 | skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); | 925 | skb = alloc_skb(size + RX_SKB_ALIGN, gfp_mask); |
926 | if (likely(skb)) { | 926 | if (likely(skb)) { |
927 | unsigned long p = (unsigned long) skb->data; | 927 | unsigned long p = (unsigned long) skb->data; |
928 | skb_reserve(skb, | 928 | skb_reserve(skb, ALIGN(p, RX_SKB_ALIGN) - p); |
929 | ((p + RX_SKB_ALIGN - 1) & ~(RX_SKB_ALIGN - 1)) - p); | ||
930 | } | 929 | } |
931 | 930 | ||
932 | return skb; | 931 | return skb; |
@@ -1686,13 +1685,12 @@ static void sky2_tx_timeout(struct net_device *dev) | |||
1686 | } | 1685 | } |
1687 | 1686 | ||
1688 | 1687 | ||
1689 | #define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) | ||
1690 | /* Want receive buffer size to be multiple of 64 bits | 1688 | /* Want receive buffer size to be multiple of 64 bits |
1691 | * and incl room for vlan and truncation | 1689 | * and incl room for vlan and truncation |
1692 | */ | 1690 | */ |
1693 | static inline unsigned sky2_buf_size(int mtu) | 1691 | static inline unsigned sky2_buf_size(int mtu) |
1694 | { | 1692 | { |
1695 | return roundup(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; | 1693 | return ALIGN(mtu + ETH_HLEN + VLAN_HLEN, 8) + 8; |
1696 | } | 1694 | } |
1697 | 1695 | ||
1698 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) | 1696 | static int sky2_change_mtu(struct net_device *dev, int new_mtu) |
@@ -2086,6 +2084,20 @@ static void sky2_descriptor_error(struct sky2_hw *hw, unsigned port, | |||
2086 | } | 2084 | } |
2087 | } | 2085 | } |
2088 | 2086 | ||
2087 | /* If idle then force a fake soft NAPI poll once a second | ||
2088 | * to work around cases where sharing an edge triggered interrupt. | ||
2089 | */ | ||
2090 | static void sky2_idle(unsigned long arg) | ||
2091 | { | ||
2092 | struct net_device *dev = (struct net_device *) arg; | ||
2093 | |||
2094 | local_irq_disable(); | ||
2095 | if (__netif_rx_schedule_prep(dev)) | ||
2096 | __netif_rx_schedule(dev); | ||
2097 | local_irq_enable(); | ||
2098 | } | ||
2099 | |||
2100 | |||
2089 | static int sky2_poll(struct net_device *dev0, int *budget) | 2101 | static int sky2_poll(struct net_device *dev0, int *budget) |
2090 | { | 2102 | { |
2091 | struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; | 2103 | struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; |
@@ -2093,6 +2105,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2093 | int work_done = 0; | 2105 | int work_done = 0; |
2094 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); | 2106 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); |
2095 | 2107 | ||
2108 | restart_poll: | ||
2096 | if (unlikely(status & ~Y2_IS_STAT_BMU)) { | 2109 | if (unlikely(status & ~Y2_IS_STAT_BMU)) { |
2097 | if (status & Y2_IS_HW_ERR) | 2110 | if (status & Y2_IS_HW_ERR) |
2098 | sky2_hw_intr(hw); | 2111 | sky2_hw_intr(hw); |
@@ -2123,7 +2136,7 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2123 | } | 2136 | } |
2124 | 2137 | ||
2125 | if (status & Y2_IS_STAT_BMU) { | 2138 | if (status & Y2_IS_STAT_BMU) { |
2126 | work_done = sky2_status_intr(hw, work_limit); | 2139 | work_done += sky2_status_intr(hw, work_limit - work_done); |
2127 | *budget -= work_done; | 2140 | *budget -= work_done; |
2128 | dev0->quota -= work_done; | 2141 | dev0->quota -= work_done; |
2129 | 2142 | ||
@@ -2133,9 +2146,24 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2133 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); | 2146 | sky2_write32(hw, STAT_CTRL, SC_STAT_CLR_IRQ); |
2134 | } | 2147 | } |
2135 | 2148 | ||
2136 | netif_rx_complete(dev0); | 2149 | mod_timer(&hw->idle_timer, jiffies + HZ); |
2150 | |||
2151 | local_irq_disable(); | ||
2152 | __netif_rx_complete(dev0); | ||
2137 | 2153 | ||
2138 | status = sky2_read32(hw, B0_Y2_SP_LISR); | 2154 | status = sky2_read32(hw, B0_Y2_SP_LISR); |
2155 | |||
2156 | if (unlikely(status)) { | ||
2157 | /* More work pending, try and keep going */ | ||
2158 | if (__netif_rx_schedule_prep(dev0)) { | ||
2159 | __netif_rx_reschedule(dev0, work_done); | ||
2160 | status = sky2_read32(hw, B0_Y2_SP_EISR); | ||
2161 | local_irq_enable(); | ||
2162 | goto restart_poll; | ||
2163 | } | ||
2164 | } | ||
2165 | |||
2166 | local_irq_enable(); | ||
2139 | return 0; | 2167 | return 0; |
2140 | } | 2168 | } |
2141 | 2169 | ||
@@ -2153,8 +2181,6 @@ static irqreturn_t sky2_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2153 | prefetch(&hw->st_le[hw->st_idx]); | 2181 | prefetch(&hw->st_le[hw->st_idx]); |
2154 | if (likely(__netif_rx_schedule_prep(dev0))) | 2182 | if (likely(__netif_rx_schedule_prep(dev0))) |
2155 | __netif_rx_schedule(dev0); | 2183 | __netif_rx_schedule(dev0); |
2156 | else | ||
2157 | printk(KERN_DEBUG PFX "irq race detected\n"); | ||
2158 | 2184 | ||
2159 | return IRQ_HANDLED; | 2185 | return IRQ_HANDLED; |
2160 | } | 2186 | } |
@@ -2193,7 +2219,7 @@ static inline u32 sky2_clk2us(const struct sky2_hw *hw, u32 clk) | |||
2193 | } | 2219 | } |
2194 | 2220 | ||
2195 | 2221 | ||
2196 | static int sky2_reset(struct sky2_hw *hw) | 2222 | static int __devinit sky2_reset(struct sky2_hw *hw) |
2197 | { | 2223 | { |
2198 | u16 status; | 2224 | u16 status; |
2199 | u8 t8, pmd_type; | 2225 | u8 t8, pmd_type; |
@@ -3276,6 +3302,8 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
3276 | 3302 | ||
3277 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); | 3303 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); |
3278 | 3304 | ||
3305 | setup_timer(&hw->idle_timer, sky2_idle, (unsigned long) dev); | ||
3306 | |||
3279 | pci_set_drvdata(pdev, hw); | 3307 | pci_set_drvdata(pdev, hw); |
3280 | 3308 | ||
3281 | return 0; | 3309 | return 0; |
@@ -3311,13 +3339,15 @@ static void __devexit sky2_remove(struct pci_dev *pdev) | |||
3311 | if (!hw) | 3339 | if (!hw) |
3312 | return; | 3340 | return; |
3313 | 3341 | ||
3342 | del_timer_sync(&hw->idle_timer); | ||
3343 | |||
3344 | sky2_write32(hw, B0_IMSK, 0); | ||
3314 | dev0 = hw->dev[0]; | 3345 | dev0 = hw->dev[0]; |
3315 | dev1 = hw->dev[1]; | 3346 | dev1 = hw->dev[1]; |
3316 | if (dev1) | 3347 | if (dev1) |
3317 | unregister_netdev(dev1); | 3348 | unregister_netdev(dev1); |
3318 | unregister_netdev(dev0); | 3349 | unregister_netdev(dev0); |
3319 | 3350 | ||
3320 | sky2_write32(hw, B0_IMSK, 0); | ||
3321 | sky2_set_power_state(hw, PCI_D3hot); | 3351 | sky2_set_power_state(hw, PCI_D3hot); |
3322 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); | 3352 | sky2_write16(hw, B0_Y2LED, LED_STAT_OFF); |
3323 | sky2_write8(hw, B0_CTST, CS_RST_SET); | 3353 | sky2_write8(hw, B0_CTST, CS_RST_SET); |
diff --git a/drivers/net/sky2.h b/drivers/net/sky2.h index 89dd18cd12f0..b026f5653f04 100644 --- a/drivers/net/sky2.h +++ b/drivers/net/sky2.h | |||
@@ -1880,6 +1880,8 @@ struct sky2_hw { | |||
1880 | struct sky2_status_le *st_le; | 1880 | struct sky2_status_le *st_le; |
1881 | u32 st_idx; | 1881 | u32 st_idx; |
1882 | dma_addr_t st_dma; | 1882 | dma_addr_t st_dma; |
1883 | |||
1884 | struct timer_list idle_timer; | ||
1883 | int msi_detected; | 1885 | int msi_detected; |
1884 | wait_queue_head_t msi_wait; | 1886 | wait_queue_head_t msi_wait; |
1885 | }; | 1887 | }; |
diff --git a/drivers/net/sungem_phy.c b/drivers/net/sungem_phy.c index cb0aba95d4e3..046371ee5bbe 100644 --- a/drivers/net/sungem_phy.c +++ b/drivers/net/sungem_phy.c | |||
@@ -275,7 +275,7 @@ static int bcm5411_init(struct mii_phy* phy) | |||
275 | return 0; | 275 | return 0; |
276 | } | 276 | } |
277 | 277 | ||
278 | static int bcm5411_suspend(struct mii_phy* phy) | 278 | static int generic_suspend(struct mii_phy* phy) |
279 | { | 279 | { |
280 | phy_write(phy, MII_BMCR, BMCR_PDOWN); | 280 | phy_write(phy, MII_BMCR, BMCR_PDOWN); |
281 | 281 | ||
@@ -738,7 +738,7 @@ static struct mii_phy_def bcm5401_phy_def = { | |||
738 | /* Broadcom BCM 5411 */ | 738 | /* Broadcom BCM 5411 */ |
739 | static struct mii_phy_ops bcm5411_phy_ops = { | 739 | static struct mii_phy_ops bcm5411_phy_ops = { |
740 | .init = bcm5411_init, | 740 | .init = bcm5411_init, |
741 | .suspend = bcm5411_suspend, | 741 | .suspend = generic_suspend, |
742 | .setup_aneg = bcm54xx_setup_aneg, | 742 | .setup_aneg = bcm54xx_setup_aneg, |
743 | .setup_forced = bcm54xx_setup_forced, | 743 | .setup_forced = bcm54xx_setup_forced, |
744 | .poll_link = genmii_poll_link, | 744 | .poll_link = genmii_poll_link, |
@@ -757,7 +757,7 @@ static struct mii_phy_def bcm5411_phy_def = { | |||
757 | /* Broadcom BCM 5421 */ | 757 | /* Broadcom BCM 5421 */ |
758 | static struct mii_phy_ops bcm5421_phy_ops = { | 758 | static struct mii_phy_ops bcm5421_phy_ops = { |
759 | .init = bcm5421_init, | 759 | .init = bcm5421_init, |
760 | .suspend = bcm5411_suspend, | 760 | .suspend = generic_suspend, |
761 | .setup_aneg = bcm54xx_setup_aneg, | 761 | .setup_aneg = bcm54xx_setup_aneg, |
762 | .setup_forced = bcm54xx_setup_forced, | 762 | .setup_forced = bcm54xx_setup_forced, |
763 | .poll_link = genmii_poll_link, | 763 | .poll_link = genmii_poll_link, |
@@ -776,7 +776,7 @@ static struct mii_phy_def bcm5421_phy_def = { | |||
776 | /* Broadcom BCM 5421 built-in K2 */ | 776 | /* Broadcom BCM 5421 built-in K2 */ |
777 | static struct mii_phy_ops bcm5421k2_phy_ops = { | 777 | static struct mii_phy_ops bcm5421k2_phy_ops = { |
778 | .init = bcm5421_init, | 778 | .init = bcm5421_init, |
779 | .suspend = bcm5411_suspend, | 779 | .suspend = generic_suspend, |
780 | .setup_aneg = bcm54xx_setup_aneg, | 780 | .setup_aneg = bcm54xx_setup_aneg, |
781 | .setup_forced = bcm54xx_setup_forced, | 781 | .setup_forced = bcm54xx_setup_forced, |
782 | .poll_link = genmii_poll_link, | 782 | .poll_link = genmii_poll_link, |
@@ -795,7 +795,7 @@ static struct mii_phy_def bcm5421k2_phy_def = { | |||
795 | /* Broadcom BCM 5462 built-in Vesta */ | 795 | /* Broadcom BCM 5462 built-in Vesta */ |
796 | static struct mii_phy_ops bcm5462V_phy_ops = { | 796 | static struct mii_phy_ops bcm5462V_phy_ops = { |
797 | .init = bcm5421_init, | 797 | .init = bcm5421_init, |
798 | .suspend = bcm5411_suspend, | 798 | .suspend = generic_suspend, |
799 | .setup_aneg = bcm54xx_setup_aneg, | 799 | .setup_aneg = bcm54xx_setup_aneg, |
800 | .setup_forced = bcm54xx_setup_forced, | 800 | .setup_forced = bcm54xx_setup_forced, |
801 | .poll_link = genmii_poll_link, | 801 | .poll_link = genmii_poll_link, |
@@ -816,6 +816,7 @@ static struct mii_phy_def bcm5462V_phy_def = { | |||
816 | * would be useful here) --BenH. | 816 | * would be useful here) --BenH. |
817 | */ | 817 | */ |
818 | static struct mii_phy_ops marvell_phy_ops = { | 818 | static struct mii_phy_ops marvell_phy_ops = { |
819 | .suspend = generic_suspend, | ||
819 | .setup_aneg = marvell_setup_aneg, | 820 | .setup_aneg = marvell_setup_aneg, |
820 | .setup_forced = marvell_setup_forced, | 821 | .setup_forced = marvell_setup_forced, |
821 | .poll_link = genmii_poll_link, | 822 | .poll_link = genmii_poll_link, |
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index bad09ebdb50b..e0874cbfefea 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig | |||
@@ -6,7 +6,7 @@ menu "Wireless LAN (non-hamradio)" | |||
6 | depends on NETDEVICES | 6 | depends on NETDEVICES |
7 | 7 | ||
8 | config NET_RADIO | 8 | config NET_RADIO |
9 | bool "Wireless LAN drivers (non-hamradio)" | 9 | bool "Wireless LAN drivers (non-hamradio) & Wireless Extensions" |
10 | select WIRELESS_EXT | 10 | select WIRELESS_EXT |
11 | ---help--- | 11 | ---help--- |
12 | Support for wireless LANs and everything having to do with radio, | 12 | Support for wireless LANs and everything having to do with radio, |
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c index 108d9fed8f07..00764ddd74d8 100644 --- a/drivers/net/wireless/airo.c +++ b/drivers/net/wireless/airo.c | |||
@@ -3139,6 +3139,7 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) | |||
3139 | } | 3139 | } |
3140 | if ( status & EV_LINK ) { | 3140 | if ( status & EV_LINK ) { |
3141 | union iwreq_data wrqu; | 3141 | union iwreq_data wrqu; |
3142 | int scan_forceloss = 0; | ||
3142 | /* The link status has changed, if you want to put a | 3143 | /* The link status has changed, if you want to put a |
3143 | monitor hook in, do it here. (Remember that | 3144 | monitor hook in, do it here. (Remember that |
3144 | interrupts are still disabled!) | 3145 | interrupts are still disabled!) |
@@ -3157,7 +3158,8 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) | |||
3157 | code) */ | 3158 | code) */ |
3158 | #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason | 3159 | #define AUTHFAIL 0x0300 /* Authentication failure (low byte is reason |
3159 | code) */ | 3160 | code) */ |
3160 | #define ASSOCIATED 0x0400 /* Assocatied */ | 3161 | #define ASSOCIATED 0x0400 /* Associated */ |
3162 | #define REASSOCIATED 0x0600 /* Reassociated? Only on firmware >= 5.30.17 */ | ||
3161 | #define RC_RESERVED 0 /* Reserved return code */ | 3163 | #define RC_RESERVED 0 /* Reserved return code */ |
3162 | #define RC_NOREASON 1 /* Unspecified reason */ | 3164 | #define RC_NOREASON 1 /* Unspecified reason */ |
3163 | #define RC_AUTHINV 2 /* Previous authentication invalid */ | 3165 | #define RC_AUTHINV 2 /* Previous authentication invalid */ |
@@ -3174,44 +3176,30 @@ static irqreturn_t airo_interrupt ( int irq, void* dev_id, struct pt_regs *regs) | |||
3174 | leaving BSS */ | 3176 | leaving BSS */ |
3175 | #define RC_NOAUTH 9 /* Station requesting (Re)Association is not | 3177 | #define RC_NOAUTH 9 /* Station requesting (Re)Association is not |
3176 | Authenticated with the responding station */ | 3178 | Authenticated with the responding station */ |
3177 | if (newStatus != ASSOCIATED) { | 3179 | if (newStatus == FORCELOSS && apriv->scan_timeout > 0) |
3178 | if (auto_wep && !apriv->expires) { | 3180 | scan_forceloss = 1; |
3179 | apriv->expires = RUN_AT(3*HZ); | 3181 | if(newStatus == ASSOCIATED || newStatus == REASSOCIATED) { |
3180 | wake_up_interruptible(&apriv->thr_wait); | ||
3181 | } | ||
3182 | } else { | ||
3183 | struct task_struct *task = apriv->task; | ||
3184 | if (auto_wep) | 3182 | if (auto_wep) |
3185 | apriv->expires = 0; | 3183 | apriv->expires = 0; |
3186 | if (task) | 3184 | if (apriv->task) |
3187 | wake_up_process (task); | 3185 | wake_up_process (apriv->task); |
3188 | set_bit(FLAG_UPDATE_UNI, &apriv->flags); | 3186 | set_bit(FLAG_UPDATE_UNI, &apriv->flags); |
3189 | set_bit(FLAG_UPDATE_MULTI, &apriv->flags); | 3187 | set_bit(FLAG_UPDATE_MULTI, &apriv->flags); |
3190 | } | 3188 | |
3191 | /* Question : is ASSOCIATED the only status | ||
3192 | * that is valid ? We want to catch handover | ||
3193 | * and reassociations as valid status | ||
3194 | * Jean II */ | ||
3195 | if(newStatus == ASSOCIATED) { | ||
3196 | #if 0 | ||
3197 | /* FIXME: Grabbing scan results here | ||
3198 | * seems to be too early??? Just wait for | ||
3199 | * timeout instead. */ | ||
3200 | if (apriv->scan_timeout > 0) { | ||
3201 | set_bit(JOB_SCAN_RESULTS, &apriv->flags); | ||
3202 | wake_up_interruptible(&apriv->thr_wait); | ||
3203 | } | ||
3204 | #endif | ||
3205 | if (down_trylock(&apriv->sem) != 0) { | 3189 | if (down_trylock(&apriv->sem) != 0) { |
3206 | set_bit(JOB_EVENT, &apriv->flags); | 3190 | set_bit(JOB_EVENT, &apriv->flags); |
3207 | wake_up_interruptible(&apriv->thr_wait); | 3191 | wake_up_interruptible(&apriv->thr_wait); |
3208 | } else | 3192 | } else |
3209 | airo_send_event(dev); | 3193 | airo_send_event(dev); |
3210 | } else { | 3194 | } else if (!scan_forceloss) { |
3211 | memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); | 3195 | if (auto_wep && !apriv->expires) { |
3212 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 3196 | apriv->expires = RUN_AT(3*HZ); |
3197 | wake_up_interruptible(&apriv->thr_wait); | ||
3198 | } | ||
3213 | 3199 | ||
3214 | /* Send event to user space */ | 3200 | /* Send event to user space */ |
3201 | memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN); | ||
3202 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | ||
3215 | wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL); | 3203 | wireless_send_event(dev, SIOCGIWAP, &wrqu,NULL); |
3216 | } | 3204 | } |
3217 | } | 3205 | } |
@@ -7136,10 +7124,10 @@ static int airo_set_scan(struct net_device *dev, | |||
7136 | goto out; | 7124 | goto out; |
7137 | 7125 | ||
7138 | /* Initiate a scan command */ | 7126 | /* Initiate a scan command */ |
7127 | ai->scan_timeout = RUN_AT(3*HZ); | ||
7139 | memset(&cmd, 0, sizeof(cmd)); | 7128 | memset(&cmd, 0, sizeof(cmd)); |
7140 | cmd.cmd=CMD_LISTBSS; | 7129 | cmd.cmd=CMD_LISTBSS; |
7141 | issuecommand(ai, &cmd, &rsp); | 7130 | issuecommand(ai, &cmd, &rsp); |
7142 | ai->scan_timeout = RUN_AT(3*HZ); | ||
7143 | wake = 1; | 7131 | wake = 1; |
7144 | 7132 | ||
7145 | out: | 7133 | out: |
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c index 87afa6878f26..8606c88886fc 100644 --- a/drivers/net/wireless/atmel.c +++ b/drivers/net/wireless/atmel.c | |||
@@ -3463,6 +3463,7 @@ static void atmel_command_irq(struct atmel_private *priv) | |||
3463 | u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET)); | 3463 | u8 status = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_STATUS_OFFSET)); |
3464 | u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET)); | 3464 | u8 command = atmel_rmem8(priv, atmel_co(priv, CMD_BLOCK_COMMAND_OFFSET)); |
3465 | int fast_scan; | 3465 | int fast_scan; |
3466 | union iwreq_data wrqu; | ||
3466 | 3467 | ||
3467 | if (status == CMD_STATUS_IDLE || | 3468 | if (status == CMD_STATUS_IDLE || |
3468 | status == CMD_STATUS_IN_PROGRESS) | 3469 | status == CMD_STATUS_IN_PROGRESS) |
@@ -3487,6 +3488,7 @@ static void atmel_command_irq(struct atmel_private *priv) | |||
3487 | atmel_scan(priv, 1); | 3488 | atmel_scan(priv, 1); |
3488 | } else { | 3489 | } else { |
3489 | int bss_index = retrieve_bss(priv); | 3490 | int bss_index = retrieve_bss(priv); |
3491 | int notify_scan_complete = 1; | ||
3490 | if (bss_index != -1) { | 3492 | if (bss_index != -1) { |
3491 | atmel_join_bss(priv, bss_index); | 3493 | atmel_join_bss(priv, bss_index); |
3492 | } else if (priv->operating_mode == IW_MODE_ADHOC && | 3494 | } else if (priv->operating_mode == IW_MODE_ADHOC && |
@@ -3495,8 +3497,14 @@ static void atmel_command_irq(struct atmel_private *priv) | |||
3495 | } else { | 3497 | } else { |
3496 | priv->fast_scan = !fast_scan; | 3498 | priv->fast_scan = !fast_scan; |
3497 | atmel_scan(priv, 1); | 3499 | atmel_scan(priv, 1); |
3500 | notify_scan_complete = 0; | ||
3498 | } | 3501 | } |
3499 | priv->site_survey_state = SITE_SURVEY_COMPLETED; | 3502 | priv->site_survey_state = SITE_SURVEY_COMPLETED; |
3503 | if (notify_scan_complete) { | ||
3504 | wrqu.data.length = 0; | ||
3505 | wrqu.data.flags = 0; | ||
3506 | wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); | ||
3507 | } | ||
3500 | } | 3508 | } |
3501 | break; | 3509 | break; |
3502 | 3510 | ||
@@ -3509,6 +3517,9 @@ static void atmel_command_irq(struct atmel_private *priv) | |||
3509 | priv->site_survey_state = SITE_SURVEY_COMPLETED; | 3517 | priv->site_survey_state = SITE_SURVEY_COMPLETED; |
3510 | if (priv->station_is_associated) { | 3518 | if (priv->station_is_associated) { |
3511 | atmel_enter_state(priv, STATION_STATE_READY); | 3519 | atmel_enter_state(priv, STATION_STATE_READY); |
3520 | wrqu.data.length = 0; | ||
3521 | wrqu.data.flags = 0; | ||
3522 | wireless_send_event(priv->dev, SIOCGIWSCAN, &wrqu, NULL); | ||
3512 | } else { | 3523 | } else { |
3513 | atmel_scan(priv, 1); | 3524 | atmel_scan(priv, 1); |
3514 | } | 3525 | } |
diff --git a/drivers/net/wireless/bcm43xx/Kconfig b/drivers/net/wireless/bcm43xx/Kconfig index 418465600a77..25ea4748f0b9 100644 --- a/drivers/net/wireless/bcm43xx/Kconfig +++ b/drivers/net/wireless/bcm43xx/Kconfig | |||
@@ -17,8 +17,11 @@ config BCM43XX_DEBUG | |||
17 | 17 | ||
18 | config BCM43XX_DMA | 18 | config BCM43XX_DMA |
19 | bool | 19 | bool |
20 | depends on BCM43XX | ||
21 | |||
20 | config BCM43XX_PIO | 22 | config BCM43XX_PIO |
21 | bool | 23 | bool |
24 | depends on BCM43XX | ||
22 | 25 | ||
23 | choice | 26 | choice |
24 | prompt "BCM43xx data transfer mode" | 27 | prompt "BCM43xx data transfer mode" |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx.h b/drivers/net/wireless/bcm43xx/bcm43xx.h index dcadd295de4f..2e83083935e1 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx.h | |||
@@ -15,7 +15,6 @@ | |||
15 | 15 | ||
16 | #include "bcm43xx_debugfs.h" | 16 | #include "bcm43xx_debugfs.h" |
17 | #include "bcm43xx_leds.h" | 17 | #include "bcm43xx_leds.h" |
18 | #include "bcm43xx_sysfs.h" | ||
19 | 18 | ||
20 | 19 | ||
21 | #define PFX KBUILD_MODNAME ": " | 20 | #define PFX KBUILD_MODNAME ": " |
@@ -638,8 +637,6 @@ struct bcm43xx_key { | |||
638 | }; | 637 | }; |
639 | 638 | ||
640 | struct bcm43xx_private { | 639 | struct bcm43xx_private { |
641 | struct bcm43xx_sysfs sysfs; | ||
642 | |||
643 | struct ieee80211_device *ieee; | 640 | struct ieee80211_device *ieee; |
644 | struct ieee80211softmac_device *softmac; | 641 | struct ieee80211softmac_device *softmac; |
645 | 642 | ||
@@ -772,6 +769,20 @@ struct bcm43xx_private * bcm43xx_priv(struct net_device *dev) | |||
772 | return ieee80211softmac_priv(dev); | 769 | return ieee80211softmac_priv(dev); |
773 | } | 770 | } |
774 | 771 | ||
772 | struct device; | ||
773 | |||
774 | static inline | ||
775 | struct bcm43xx_private * dev_to_bcm(struct device *dev) | ||
776 | { | ||
777 | struct net_device *net_dev; | ||
778 | struct bcm43xx_private *bcm; | ||
779 | |||
780 | net_dev = dev_get_drvdata(dev); | ||
781 | bcm = bcm43xx_priv(net_dev); | ||
782 | |||
783 | return bcm; | ||
784 | } | ||
785 | |||
775 | 786 | ||
776 | /* Helper function, which returns a boolean. | 787 | /* Helper function, which returns a boolean. |
777 | * TRUE, if PIO is used; FALSE, if DMA is used. | 788 | * TRUE, if PIO is used; FALSE, if DMA is used. |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c index d2c3401e9b70..35a4fcb6d923 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_debugfs.c | |||
@@ -452,12 +452,12 @@ void bcm43xx_printk_dump(const char *data, | |||
452 | size_t i; | 452 | size_t i; |
453 | char c; | 453 | char c; |
454 | 454 | ||
455 | printk(KERN_INFO PFX "Data dump (%s, %u bytes):", | 455 | printk(KERN_INFO PFX "Data dump (%s, %zd bytes):", |
456 | description, size); | 456 | description, size); |
457 | for (i = 0; i < size; i++) { | 457 | for (i = 0; i < size; i++) { |
458 | c = data[i]; | 458 | c = data[i]; |
459 | if (i % 8 == 0) | 459 | if (i % 8 == 0) |
460 | printk("\n" KERN_INFO PFX "0x%08x: 0x%02x, ", i, c & 0xff); | 460 | printk("\n" KERN_INFO PFX "0x%08zx: 0x%02x, ", i, c & 0xff); |
461 | else | 461 | else |
462 | printk("0x%02x, ", c & 0xff); | 462 | printk("0x%02x, ", c & 0xff); |
463 | } | 463 | } |
@@ -472,12 +472,12 @@ void bcm43xx_printk_bitdump(const unsigned char *data, | |||
472 | int j; | 472 | int j; |
473 | const unsigned char *d; | 473 | const unsigned char *d; |
474 | 474 | ||
475 | printk(KERN_INFO PFX "*** Bitdump (%s, %u bytes, %s) ***", | 475 | printk(KERN_INFO PFX "*** Bitdump (%s, %zd bytes, %s) ***", |
476 | description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB"); | 476 | description, bytes, msb_to_lsb ? "MSB to LSB" : "LSB to MSB"); |
477 | for (i = 0; i < bytes; i++) { | 477 | for (i = 0; i < bytes; i++) { |
478 | d = data + i; | 478 | d = data + i; |
479 | if (i % 8 == 0) | 479 | if (i % 8 == 0) |
480 | printk("\n" KERN_INFO PFX "0x%08x: ", i); | 480 | printk("\n" KERN_INFO PFX "0x%08zx: ", i); |
481 | if (msb_to_lsb) { | 481 | if (msb_to_lsb) { |
482 | for (j = 7; j >= 0; j--) { | 482 | for (j = 7; j >= 0; j--) { |
483 | if (*d & (1 << j)) | 483 | if (*d & (1 << j)) |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c index c3681b8f09b4..bbecba02e697 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.c | |||
@@ -196,8 +196,9 @@ static int alloc_ringmemory(struct bcm43xx_dmaring *ring) | |||
196 | } | 196 | } |
197 | if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) { | 197 | if (ring->dmabase + BCM43xx_DMA_RINGMEMSIZE > BCM43xx_DMA_BUSADDRMAX) { |
198 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G " | 198 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RINGMEMORY >1G " |
199 | "(0x%08x, len: %lu)\n", | 199 | "(0x%llx, len: %lu)\n", |
200 | ring->dmabase, BCM43xx_DMA_RINGMEMSIZE); | 200 | (unsigned long long)ring->dmabase, |
201 | BCM43xx_DMA_RINGMEMSIZE); | ||
201 | dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, | 202 | dma_free_coherent(dev, BCM43xx_DMA_RINGMEMSIZE, |
202 | ring->vbase, ring->dmabase); | 203 | ring->vbase, ring->dmabase); |
203 | return -ENOMEM; | 204 | return -ENOMEM; |
@@ -307,8 +308,8 @@ static int setup_rx_descbuffer(struct bcm43xx_dmaring *ring, | |||
307 | unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); | 308 | unmap_descbuffer(ring, dmaaddr, ring->rx_buffersize, 0); |
308 | dev_kfree_skb_any(skb); | 309 | dev_kfree_skb_any(skb); |
309 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G " | 310 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA RX SKB >1G " |
310 | "(0x%08x, len: %u)\n", | 311 | "(0x%llx, len: %u)\n", |
311 | dmaaddr, ring->rx_buffersize); | 312 | (unsigned long long)dmaaddr, ring->rx_buffersize); |
312 | return -ENOMEM; | 313 | return -ENOMEM; |
313 | } | 314 | } |
314 | meta->skb = skb; | 315 | meta->skb = skb; |
@@ -729,8 +730,8 @@ static int dma_tx_fragment(struct bcm43xx_dmaring *ring, | |||
729 | if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) { | 730 | if (unlikely(meta->dmaaddr + skb->len > BCM43xx_DMA_BUSADDRMAX)) { |
730 | return_slot(ring, slot); | 731 | return_slot(ring, slot); |
731 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G " | 732 | printk(KERN_ERR PFX ">>>FATAL ERROR<<< DMA TX SKB >1G " |
732 | "(0x%08x, len: %u)\n", | 733 | "(0x%llx, len: %u)\n", |
733 | meta->dmaaddr, skb->len); | 734 | (unsigned long long)meta->dmaaddr, skb->len); |
734 | return -ENOMEM; | 735 | return -ENOMEM; |
735 | } | 736 | } |
736 | 737 | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h index 2d520e4b0276..b7d77638ba8c 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_dma.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_dma.h | |||
@@ -213,6 +213,14 @@ static inline | |||
213 | void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) | 213 | void bcm43xx_dma_rx(struct bcm43xx_dmaring *ring) |
214 | { | 214 | { |
215 | } | 215 | } |
216 | static inline | ||
217 | void bcm43xx_dma_tx_suspend(struct bcm43xx_dmaring *ring) | ||
218 | { | ||
219 | } | ||
220 | static inline | ||
221 | void bcm43xx_dma_tx_resume(struct bcm43xx_dmaring *ring) | ||
222 | { | ||
223 | } | ||
216 | 224 | ||
217 | #endif /* CONFIG_BCM43XX_DMA */ | 225 | #endif /* CONFIG_BCM43XX_DMA */ |
218 | #endif /* BCM43xx_DMA_H_ */ | 226 | #endif /* BCM43xx_DMA_H_ */ |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index c37371fc9e01..9a06e61df0a2 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -52,6 +52,7 @@ | |||
52 | #include "bcm43xx_wx.h" | 52 | #include "bcm43xx_wx.h" |
53 | #include "bcm43xx_ethtool.h" | 53 | #include "bcm43xx_ethtool.h" |
54 | #include "bcm43xx_xmit.h" | 54 | #include "bcm43xx_xmit.h" |
55 | #include "bcm43xx_sysfs.h" | ||
55 | 56 | ||
56 | 57 | ||
57 | MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver"); | 58 | MODULE_DESCRIPTION("Broadcom BCM43xx wireless driver"); |
@@ -3522,6 +3523,7 @@ static inline int bcm43xx_tx(struct bcm43xx_private *bcm, | |||
3522 | err = bcm43xx_pio_tx(bcm, txb); | 3523 | err = bcm43xx_pio_tx(bcm, txb); |
3523 | else | 3524 | else |
3524 | err = bcm43xx_dma_tx(bcm, txb); | 3525 | err = bcm43xx_dma_tx(bcm, txb); |
3526 | bcm->net_dev->trans_start = jiffies; | ||
3525 | 3527 | ||
3526 | return err; | 3528 | return err; |
3527 | } | 3529 | } |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c index 0a66f43ca0c0..33137165727f 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_phy.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_phy.c | |||
@@ -2151,6 +2151,7 @@ int bcm43xx_phy_init_tssi2dbm_table(struct bcm43xx_private *bcm) | |||
2151 | phy->tssi2dbm = NULL; | 2151 | phy->tssi2dbm = NULL; |
2152 | printk(KERN_ERR PFX "Could not generate " | 2152 | printk(KERN_ERR PFX "Could not generate " |
2153 | "tssi2dBm table\n"); | 2153 | "tssi2dBm table\n"); |
2154 | kfree(dyn_tssi2dbm); | ||
2154 | return -ENODEV; | 2155 | return -ENODEV; |
2155 | } | 2156 | } |
2156 | phy->tssi2dbm = dyn_tssi2dbm; | 2157 | phy->tssi2dbm = dyn_tssi2dbm; |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c index c59ddd40680d..0aa1bd269a25 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include "bcm43xx_pio.h" | 27 | #include "bcm43xx_pio.h" |
28 | #include "bcm43xx_main.h" | 28 | #include "bcm43xx_main.h" |
29 | #include "bcm43xx_xmit.h" | 29 | #include "bcm43xx_xmit.h" |
30 | #include "bcm43xx_power.h" | ||
30 | 31 | ||
31 | #include <linux/delay.h> | 32 | #include <linux/delay.h> |
32 | 33 | ||
@@ -44,10 +45,10 @@ static void tx_octet(struct bcm43xx_pioqueue *queue, | |||
44 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, | 45 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, |
45 | octet); | 46 | octet); |
46 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | 47 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, |
47 | BCM43xx_PIO_TXCTL_WRITEHI); | 48 | BCM43xx_PIO_TXCTL_WRITELO); |
48 | } else { | 49 | } else { |
49 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | 50 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, |
50 | BCM43xx_PIO_TXCTL_WRITEHI); | 51 | BCM43xx_PIO_TXCTL_WRITELO); |
51 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, | 52 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, |
52 | octet); | 53 | octet); |
53 | } | 54 | } |
@@ -103,7 +104,7 @@ static void tx_complete(struct bcm43xx_pioqueue *queue, | |||
103 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, | 104 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXDATA, |
104 | skb->data[skb->len - 1]); | 105 | skb->data[skb->len - 1]); |
105 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | 106 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, |
106 | BCM43xx_PIO_TXCTL_WRITEHI | | 107 | BCM43xx_PIO_TXCTL_WRITELO | |
107 | BCM43xx_PIO_TXCTL_COMPLETE); | 108 | BCM43xx_PIO_TXCTL_COMPLETE); |
108 | } else { | 109 | } else { |
109 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | 110 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, |
@@ -112,9 +113,10 @@ static void tx_complete(struct bcm43xx_pioqueue *queue, | |||
112 | } | 113 | } |
113 | 114 | ||
114 | static u16 generate_cookie(struct bcm43xx_pioqueue *queue, | 115 | static u16 generate_cookie(struct bcm43xx_pioqueue *queue, |
115 | int packetindex) | 116 | struct bcm43xx_pio_txpacket *packet) |
116 | { | 117 | { |
117 | u16 cookie = 0x0000; | 118 | u16 cookie = 0x0000; |
119 | int packetindex; | ||
118 | 120 | ||
119 | /* We use the upper 4 bits for the PIO | 121 | /* We use the upper 4 bits for the PIO |
120 | * controller ID and the lower 12 bits | 122 | * controller ID and the lower 12 bits |
@@ -135,6 +137,7 @@ static u16 generate_cookie(struct bcm43xx_pioqueue *queue, | |||
135 | default: | 137 | default: |
136 | assert(0); | 138 | assert(0); |
137 | } | 139 | } |
140 | packetindex = pio_txpacket_getindex(packet); | ||
138 | assert(((u16)packetindex & 0xF000) == 0x0000); | 141 | assert(((u16)packetindex & 0xF000) == 0x0000); |
139 | cookie |= (u16)packetindex; | 142 | cookie |= (u16)packetindex; |
140 | 143 | ||
@@ -184,7 +187,7 @@ static void pio_tx_write_fragment(struct bcm43xx_pioqueue *queue, | |||
184 | bcm43xx_generate_txhdr(queue->bcm, | 187 | bcm43xx_generate_txhdr(queue->bcm, |
185 | &txhdr, skb->data, skb->len, | 188 | &txhdr, skb->data, skb->len, |
186 | (packet->xmitted_frags == 0), | 189 | (packet->xmitted_frags == 0), |
187 | generate_cookie(queue, pio_txpacket_getindex(packet))); | 190 | generate_cookie(queue, packet)); |
188 | 191 | ||
189 | tx_start(queue); | 192 | tx_start(queue); |
190 | octets = skb->len + sizeof(txhdr); | 193 | octets = skb->len + sizeof(txhdr); |
@@ -241,7 +244,7 @@ static int pio_tx_packet(struct bcm43xx_pio_txpacket *packet) | |||
241 | queue->tx_devq_packets++; | 244 | queue->tx_devq_packets++; |
242 | queue->tx_devq_used += octets; | 245 | queue->tx_devq_used += octets; |
243 | 246 | ||
244 | assert(packet->xmitted_frags <= packet->txb->nr_frags); | 247 | assert(packet->xmitted_frags < packet->txb->nr_frags); |
245 | packet->xmitted_frags++; | 248 | packet->xmitted_frags++; |
246 | packet->xmitted_octets += octets; | 249 | packet->xmitted_octets += octets; |
247 | } | 250 | } |
@@ -257,8 +260,14 @@ static void tx_tasklet(unsigned long d) | |||
257 | unsigned long flags; | 260 | unsigned long flags; |
258 | struct bcm43xx_pio_txpacket *packet, *tmp_packet; | 261 | struct bcm43xx_pio_txpacket *packet, *tmp_packet; |
259 | int err; | 262 | int err; |
263 | u16 txctl; | ||
260 | 264 | ||
261 | bcm43xx_lock_mmio(bcm, flags); | 265 | bcm43xx_lock_mmio(bcm, flags); |
266 | |||
267 | txctl = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); | ||
268 | if (txctl & BCM43xx_PIO_TXCTL_SUSPEND) | ||
269 | goto out_unlock; | ||
270 | |||
262 | list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) { | 271 | list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) { |
263 | assert(packet->xmitted_frags < packet->txb->nr_frags); | 272 | assert(packet->xmitted_frags < packet->txb->nr_frags); |
264 | if (packet->xmitted_frags == 0) { | 273 | if (packet->xmitted_frags == 0) { |
@@ -288,6 +297,7 @@ static void tx_tasklet(unsigned long d) | |||
288 | next_packet: | 297 | next_packet: |
289 | continue; | 298 | continue; |
290 | } | 299 | } |
300 | out_unlock: | ||
291 | bcm43xx_unlock_mmio(bcm, flags); | 301 | bcm43xx_unlock_mmio(bcm, flags); |
292 | } | 302 | } |
293 | 303 | ||
@@ -330,12 +340,19 @@ struct bcm43xx_pioqueue * bcm43xx_setup_pioqueue(struct bcm43xx_private *bcm, | |||
330 | (unsigned long)queue); | 340 | (unsigned long)queue); |
331 | 341 | ||
332 | value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); | 342 | value = bcm43xx_read32(bcm, BCM43xx_MMIO_STATUS_BITFIELD); |
333 | value |= BCM43xx_SBF_XFER_REG_BYTESWAP; | 343 | value &= ~BCM43xx_SBF_XFER_REG_BYTESWAP; |
334 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value); | 344 | bcm43xx_write32(bcm, BCM43xx_MMIO_STATUS_BITFIELD, value); |
335 | 345 | ||
336 | qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE); | 346 | qsize = bcm43xx_read16(bcm, queue->mmio_base + BCM43xx_PIO_TXQBUFSIZE); |
347 | if (qsize == 0) { | ||
348 | printk(KERN_ERR PFX "ERROR: This card does not support PIO " | ||
349 | "operation mode. Please use DMA mode " | ||
350 | "(module parameter pio=0).\n"); | ||
351 | goto err_freequeue; | ||
352 | } | ||
337 | if (qsize <= BCM43xx_PIO_TXQADJUST) { | 353 | if (qsize <= BCM43xx_PIO_TXQADJUST) { |
338 | printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n", qsize); | 354 | printk(KERN_ERR PFX "PIO tx device-queue too small (%u)\n", |
355 | qsize); | ||
339 | goto err_freequeue; | 356 | goto err_freequeue; |
340 | } | 357 | } |
341 | qsize -= BCM43xx_PIO_TXQADJUST; | 358 | qsize -= BCM43xx_PIO_TXQADJUST; |
@@ -444,15 +461,10 @@ int bcm43xx_pio_tx(struct bcm43xx_private *bcm, | |||
444 | { | 461 | { |
445 | struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1; | 462 | struct bcm43xx_pioqueue *queue = bcm43xx_current_pio(bcm)->queue1; |
446 | struct bcm43xx_pio_txpacket *packet; | 463 | struct bcm43xx_pio_txpacket *packet; |
447 | u16 tmp; | ||
448 | 464 | ||
449 | assert(!queue->tx_suspended); | 465 | assert(!queue->tx_suspended); |
450 | assert(!list_empty(&queue->txfree)); | 466 | assert(!list_empty(&queue->txfree)); |
451 | 467 | ||
452 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL); | ||
453 | if (tmp & BCM43xx_PIO_TXCTL_SUSPEND) | ||
454 | return -EBUSY; | ||
455 | |||
456 | packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list); | 468 | packet = list_entry(queue->txfree.next, struct bcm43xx_pio_txpacket, list); |
457 | packet->txb = txb; | 469 | packet->txb = txb; |
458 | packet->xmitted_frags = 0; | 470 | packet->xmitted_frags = 0; |
@@ -462,7 +474,7 @@ int bcm43xx_pio_tx(struct bcm43xx_private *bcm, | |||
462 | assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS); | 474 | assert(queue->nr_txfree < BCM43xx_PIO_MAXTXPACKETS); |
463 | 475 | ||
464 | /* Suspend TX, if we are out of packets in the "free" queue. */ | 476 | /* Suspend TX, if we are out of packets in the "free" queue. */ |
465 | if (unlikely(list_empty(&queue->txfree))) { | 477 | if (list_empty(&queue->txfree)) { |
466 | netif_stop_queue(queue->bcm->net_dev); | 478 | netif_stop_queue(queue->bcm->net_dev); |
467 | queue->tx_suspended = 1; | 479 | queue->tx_suspended = 1; |
468 | } | 480 | } |
@@ -480,15 +492,15 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, | |||
480 | 492 | ||
481 | queue = parse_cookie(bcm, status->cookie, &packet); | 493 | queue = parse_cookie(bcm, status->cookie, &packet); |
482 | assert(queue); | 494 | assert(queue); |
483 | //TODO | 495 | |
484 | if (!queue) | ||
485 | return; | ||
486 | free_txpacket(packet, 1); | 496 | free_txpacket(packet, 1); |
487 | if (unlikely(queue->tx_suspended)) { | 497 | if (queue->tx_suspended) { |
488 | queue->tx_suspended = 0; | 498 | queue->tx_suspended = 0; |
489 | netif_wake_queue(queue->bcm->net_dev); | 499 | netif_wake_queue(queue->bcm->net_dev); |
490 | } | 500 | } |
491 | /* If there are packets on the txqueue, poke the tasklet. */ | 501 | /* If there are packets on the txqueue, poke the tasklet |
502 | * to transmit them. | ||
503 | */ | ||
492 | if (!list_empty(&queue->txqueue)) | 504 | if (!list_empty(&queue->txqueue)) |
493 | tasklet_schedule(&queue->txtask); | 505 | tasklet_schedule(&queue->txtask); |
494 | } | 506 | } |
@@ -519,12 +531,9 @@ void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) | |||
519 | int i, preamble_readwords; | 531 | int i, preamble_readwords; |
520 | struct sk_buff *skb; | 532 | struct sk_buff *skb; |
521 | 533 | ||
522 | return; | ||
523 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL); | 534 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXCTL); |
524 | if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE)) { | 535 | if (!(tmp & BCM43xx_PIO_RXCTL_DATAAVAILABLE)) |
525 | dprintkl(KERN_ERR PFX "PIO RX: No data available\n");//TODO: remove this printk. | ||
526 | return; | 536 | return; |
527 | } | ||
528 | bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL, | 537 | bcm43xx_pio_write(queue, BCM43xx_PIO_RXCTL, |
529 | BCM43xx_PIO_RXCTL_DATAAVAILABLE); | 538 | BCM43xx_PIO_RXCTL_DATAAVAILABLE); |
530 | 539 | ||
@@ -538,8 +547,7 @@ return; | |||
538 | return; | 547 | return; |
539 | data_ready: | 548 | data_ready: |
540 | 549 | ||
541 | //FIXME: endianess in this function. | 550 | len = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); |
542 | len = le16_to_cpu(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA)); | ||
543 | if (unlikely(len > 0x700)) { | 551 | if (unlikely(len > 0x700)) { |
544 | pio_rx_error(queue, 0, "len > 0x700"); | 552 | pio_rx_error(queue, 0, "len > 0x700"); |
545 | return; | 553 | return; |
@@ -555,7 +563,7 @@ data_ready: | |||
555 | preamble_readwords = 18 / sizeof(u16); | 563 | preamble_readwords = 18 / sizeof(u16); |
556 | for (i = 0; i < preamble_readwords; i++) { | 564 | for (i = 0; i < preamble_readwords; i++) { |
557 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); | 565 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); |
558 | preamble[i + 1] = cpu_to_be16(tmp);//FIXME? | 566 | preamble[i + 1] = cpu_to_le16(tmp); |
559 | } | 567 | } |
560 | rxhdr = (struct bcm43xx_rxhdr *)preamble; | 568 | rxhdr = (struct bcm43xx_rxhdr *)preamble; |
561 | rxflags2 = le16_to_cpu(rxhdr->flags2); | 569 | rxflags2 = le16_to_cpu(rxhdr->flags2); |
@@ -591,16 +599,40 @@ data_ready: | |||
591 | } | 599 | } |
592 | skb_put(skb, len); | 600 | skb_put(skb, len); |
593 | for (i = 0; i < len - 1; i += 2) { | 601 | for (i = 0; i < len - 1; i += 2) { |
594 | tmp = cpu_to_be16(bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA)); | 602 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); |
595 | *((u16 *)(skb->data + i)) = tmp; | 603 | *((u16 *)(skb->data + i)) = cpu_to_le16(tmp); |
596 | } | 604 | } |
597 | if (len % 2) { | 605 | if (len % 2) { |
598 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); | 606 | tmp = bcm43xx_pio_read(queue, BCM43xx_PIO_RXDATA); |
599 | skb->data[len - 1] = (tmp & 0x00FF); | 607 | skb->data[len - 1] = (tmp & 0x00FF); |
608 | /* The specs say the following is required, but | ||
609 | * it is wrong and corrupts the PLCP. If we don't do | ||
610 | * this, the PLCP seems to be correct. So ifdef it out for now. | ||
611 | */ | ||
612 | #if 0 | ||
600 | if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) | 613 | if (rxflags2 & BCM43xx_RXHDR_FLAGS2_TYPE2FRAME) |
601 | skb->data[0x20] = (tmp & 0xFF00) >> 8; | 614 | skb->data[2] = (tmp & 0xFF00) >> 8; |
602 | else | 615 | else |
603 | skb->data[0x1E] = (tmp & 0xFF00) >> 8; | 616 | skb->data[0] = (tmp & 0xFF00) >> 8; |
617 | #endif | ||
604 | } | 618 | } |
619 | skb_trim(skb, len - IEEE80211_FCS_LEN); | ||
605 | bcm43xx_rx(queue->bcm, skb, rxhdr); | 620 | bcm43xx_rx(queue->bcm, skb, rxhdr); |
606 | } | 621 | } |
622 | |||
623 | void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue) | ||
624 | { | ||
625 | bcm43xx_power_saving_ctl_bits(queue->bcm, -1, 1); | ||
626 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | ||
627 | bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) | ||
628 | | BCM43xx_PIO_TXCTL_SUSPEND); | ||
629 | } | ||
630 | |||
631 | void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) | ||
632 | { | ||
633 | bcm43xx_pio_write(queue, BCM43xx_PIO_TXCTL, | ||
634 | bcm43xx_pio_read(queue, BCM43xx_PIO_TXCTL) | ||
635 | & ~BCM43xx_PIO_TXCTL_SUSPEND); | ||
636 | bcm43xx_power_saving_ctl_bits(queue->bcm, -1, -1); | ||
637 | tasklet_schedule(&queue->txtask); | ||
638 | } | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h index 970627bc1769..dfc78209e3a3 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_pio.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_pio.h | |||
@@ -14,8 +14,8 @@ | |||
14 | #define BCM43xx_PIO_RXCTL 0x08 | 14 | #define BCM43xx_PIO_RXCTL 0x08 |
15 | #define BCM43xx_PIO_RXDATA 0x0A | 15 | #define BCM43xx_PIO_RXDATA 0x0A |
16 | 16 | ||
17 | #define BCM43xx_PIO_TXCTL_WRITEHI (1 << 0) | 17 | #define BCM43xx_PIO_TXCTL_WRITELO (1 << 0) |
18 | #define BCM43xx_PIO_TXCTL_WRITELO (1 << 1) | 18 | #define BCM43xx_PIO_TXCTL_WRITEHI (1 << 1) |
19 | #define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2) | 19 | #define BCM43xx_PIO_TXCTL_COMPLETE (1 << 2) |
20 | #define BCM43xx_PIO_TXCTL_INIT (1 << 3) | 20 | #define BCM43xx_PIO_TXCTL_INIT (1 << 3) |
21 | #define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7) | 21 | #define BCM43xx_PIO_TXCTL_SUSPEND (1 << 7) |
@@ -95,6 +95,7 @@ void bcm43xx_pio_write(struct bcm43xx_pioqueue *queue, | |||
95 | u16 offset, u16 value) | 95 | u16 offset, u16 value) |
96 | { | 96 | { |
97 | bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value); | 97 | bcm43xx_write16(queue->bcm, queue->mmio_base + offset, value); |
98 | mmiowb(); | ||
98 | } | 99 | } |
99 | 100 | ||
100 | 101 | ||
@@ -107,6 +108,9 @@ void bcm43xx_pio_handle_xmitstatus(struct bcm43xx_private *bcm, | |||
107 | struct bcm43xx_xmitstatus *status); | 108 | struct bcm43xx_xmitstatus *status); |
108 | void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); | 109 | void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue); |
109 | 110 | ||
111 | void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue); | ||
112 | void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue); | ||
113 | |||
110 | #else /* CONFIG_BCM43XX_PIO */ | 114 | #else /* CONFIG_BCM43XX_PIO */ |
111 | 115 | ||
112 | static inline | 116 | static inline |
@@ -133,6 +137,14 @@ static inline | |||
133 | void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) | 137 | void bcm43xx_pio_rx(struct bcm43xx_pioqueue *queue) |
134 | { | 138 | { |
135 | } | 139 | } |
140 | static inline | ||
141 | void bcm43xx_pio_tx_suspend(struct bcm43xx_pioqueue *queue) | ||
142 | { | ||
143 | } | ||
144 | static inline | ||
145 | void bcm43xx_pio_tx_resume(struct bcm43xx_pioqueue *queue) | ||
146 | { | ||
147 | } | ||
136 | 148 | ||
137 | #endif /* CONFIG_BCM43XX_PIO */ | 149 | #endif /* CONFIG_BCM43XX_PIO */ |
138 | #endif /* BCM43xx_PIO_H_ */ | 150 | #endif /* BCM43xx_PIO_H_ */ |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.c b/drivers/net/wireless/bcm43xx/bcm43xx_power.c index 3c92b62807c5..6569da3a7a39 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_power.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.c | |||
@@ -35,77 +35,101 @@ | |||
35 | #include "bcm43xx_main.h" | 35 | #include "bcm43xx_main.h" |
36 | 36 | ||
37 | 37 | ||
38 | /* Get the Slow Clock Source */ | ||
39 | static int bcm43xx_pctl_get_slowclksrc(struct bcm43xx_private *bcm) | ||
40 | { | ||
41 | u32 tmp; | ||
42 | int err; | ||
43 | |||
44 | assert(bcm->current_core == &bcm->core_chipcommon); | ||
45 | if (bcm->current_core->rev < 6) { | ||
46 | if (bcm->bustype == BCM43xx_BUSTYPE_PCMCIA || | ||
47 | bcm->bustype == BCM43xx_BUSTYPE_SB) | ||
48 | return BCM43xx_PCTL_CLKSRC_XTALOS; | ||
49 | if (bcm->bustype == BCM43xx_BUSTYPE_PCI) { | ||
50 | err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp); | ||
51 | assert(!err); | ||
52 | if (tmp & 0x10) | ||
53 | return BCM43xx_PCTL_CLKSRC_PCI; | ||
54 | return BCM43xx_PCTL_CLKSRC_XTALOS; | ||
55 | } | ||
56 | } | ||
57 | if (bcm->current_core->rev < 10) { | ||
58 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); | ||
59 | tmp &= 0x7; | ||
60 | if (tmp == 0) | ||
61 | return BCM43xx_PCTL_CLKSRC_LOPWROS; | ||
62 | if (tmp == 1) | ||
63 | return BCM43xx_PCTL_CLKSRC_XTALOS; | ||
64 | if (tmp == 2) | ||
65 | return BCM43xx_PCTL_CLKSRC_PCI; | ||
66 | } | ||
67 | |||
68 | return BCM43xx_PCTL_CLKSRC_XTALOS; | ||
69 | } | ||
70 | |||
38 | /* Get max/min slowclock frequency | 71 | /* Get max/min slowclock frequency |
39 | * as described in http://bcm-specs.sipsolutions.net/PowerControl | 72 | * as described in http://bcm-specs.sipsolutions.net/PowerControl |
40 | */ | 73 | */ |
41 | static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, | 74 | static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, |
42 | int get_max) | 75 | int get_max) |
43 | { | 76 | { |
44 | int limit = 0; | 77 | int limit; |
78 | int clocksrc; | ||
45 | int divisor; | 79 | int divisor; |
46 | int selection; | ||
47 | int err; | ||
48 | u32 tmp; | 80 | u32 tmp; |
49 | struct bcm43xx_coreinfo *old_core; | ||
50 | 81 | ||
51 | if (!(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL)) | 82 | assert(bcm->chipcommon_capabilities & BCM43xx_CAPABILITIES_PCTL); |
52 | goto out; | 83 | assert(bcm->current_core == &bcm->core_chipcommon); |
53 | old_core = bcm->current_core; | ||
54 | err = bcm43xx_switch_core(bcm, &bcm->core_chipcommon); | ||
55 | if (err) | ||
56 | goto out; | ||
57 | 84 | ||
85 | clocksrc = bcm43xx_pctl_get_slowclksrc(bcm); | ||
58 | if (bcm->current_core->rev < 6) { | 86 | if (bcm->current_core->rev < 6) { |
59 | if ((bcm->bustype == BCM43xx_BUSTYPE_PCMCIA) || | 87 | switch (clocksrc) { |
60 | (bcm->bustype == BCM43xx_BUSTYPE_SB)) { | 88 | case BCM43xx_PCTL_CLKSRC_PCI: |
61 | selection = 1; | 89 | divisor = 64; |
90 | break; | ||
91 | case BCM43xx_PCTL_CLKSRC_XTALOS: | ||
62 | divisor = 32; | 92 | divisor = 32; |
63 | } else { | 93 | break; |
64 | err = bcm43xx_pci_read_config32(bcm, BCM43xx_PCTL_OUT, &tmp); | 94 | default: |
65 | if (err) { | 95 | assert(0); |
66 | printk(KERN_ERR PFX "clockfreqlimit pcicfg read failure\n"); | 96 | divisor = 1; |
67 | goto out_switchback; | ||
68 | } | ||
69 | if (tmp & 0x10) { | ||
70 | /* PCI */ | ||
71 | selection = 2; | ||
72 | divisor = 64; | ||
73 | } else { | ||
74 | /* XTAL */ | ||
75 | selection = 1; | ||
76 | divisor = 32; | ||
77 | } | ||
78 | } | 97 | } |
79 | } else if (bcm->current_core->rev < 10) { | 98 | } else if (bcm->current_core->rev < 10) { |
80 | selection = (tmp & 0x07); | 99 | switch (clocksrc) { |
81 | if (selection) { | 100 | case BCM43xx_PCTL_CLKSRC_LOPWROS: |
101 | divisor = 1; | ||
102 | break; | ||
103 | case BCM43xx_PCTL_CLKSRC_XTALOS: | ||
104 | case BCM43xx_PCTL_CLKSRC_PCI: | ||
82 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); | 105 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SLOWCLKCTL); |
83 | divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); | 106 | divisor = ((tmp & 0xFFFF0000) >> 16) + 1; |
84 | } else | 107 | divisor *= 4; |
108 | break; | ||
109 | default: | ||
110 | assert(0); | ||
85 | divisor = 1; | 111 | divisor = 1; |
112 | } | ||
86 | } else { | 113 | } else { |
87 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL); | 114 | tmp = bcm43xx_read32(bcm, BCM43xx_CHIPCOMMON_SYSCLKCTL); |
88 | divisor = 4 * (1 + ((tmp & 0xFFFF0000) >> 16)); | 115 | divisor = ((tmp & 0xFFFF0000) >> 16) + 1; |
89 | selection = 1; | 116 | divisor *= 4; |
90 | } | 117 | } |
91 | 118 | ||
92 | switch (selection) { | 119 | switch (clocksrc) { |
93 | case 0: | 120 | case BCM43xx_PCTL_CLKSRC_LOPWROS: |
94 | /* LPO */ | ||
95 | if (get_max) | 121 | if (get_max) |
96 | limit = 43000; | 122 | limit = 43000; |
97 | else | 123 | else |
98 | limit = 25000; | 124 | limit = 25000; |
99 | break; | 125 | break; |
100 | case 1: | 126 | case BCM43xx_PCTL_CLKSRC_XTALOS: |
101 | /* XTAL */ | ||
102 | if (get_max) | 127 | if (get_max) |
103 | limit = 20200000; | 128 | limit = 20200000; |
104 | else | 129 | else |
105 | limit = 19800000; | 130 | limit = 19800000; |
106 | break; | 131 | break; |
107 | case 2: | 132 | case BCM43xx_PCTL_CLKSRC_PCI: |
108 | /* PCI */ | ||
109 | if (get_max) | 133 | if (get_max) |
110 | limit = 34000000; | 134 | limit = 34000000; |
111 | else | 135 | else |
@@ -113,17 +137,14 @@ static int bcm43xx_pctl_clockfreqlimit(struct bcm43xx_private *bcm, | |||
113 | break; | 137 | break; |
114 | default: | 138 | default: |
115 | assert(0); | 139 | assert(0); |
140 | limit = 0; | ||
116 | } | 141 | } |
117 | limit /= divisor; | 142 | limit /= divisor; |
118 | 143 | ||
119 | out_switchback: | ||
120 | err = bcm43xx_switch_core(bcm, old_core); | ||
121 | assert(err == 0); | ||
122 | |||
123 | out: | ||
124 | return limit; | 144 | return limit; |
125 | } | 145 | } |
126 | 146 | ||
147 | |||
127 | /* init power control | 148 | /* init power control |
128 | * as described in http://bcm-specs.sipsolutions.net/PowerControl | 149 | * as described in http://bcm-specs.sipsolutions.net/PowerControl |
129 | */ | 150 | */ |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_power.h b/drivers/net/wireless/bcm43xx/bcm43xx_power.h index 5f63640810bd..c966ab3a5a8c 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_power.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_power.h | |||
@@ -33,6 +33,15 @@ | |||
33 | 33 | ||
34 | #include <linux/types.h> | 34 | #include <linux/types.h> |
35 | 35 | ||
36 | /* Clock sources */ | ||
37 | enum { | ||
38 | /* PCI clock */ | ||
39 | BCM43xx_PCTL_CLKSRC_PCI, | ||
40 | /* Crystal slow clock oscillator */ | ||
41 | BCM43xx_PCTL_CLKSRC_XTALOS, | ||
42 | /* Low power oscillator */ | ||
43 | BCM43xx_PCTL_CLKSRC_LOPWROS, | ||
44 | }; | ||
36 | 45 | ||
37 | struct bcm43xx_private; | 46 | struct bcm43xx_private; |
38 | 47 | ||
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c index c44d890b949b..b438f48e891d 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.c | |||
@@ -71,14 +71,46 @@ static int get_boolean(const char *buf, size_t count) | |||
71 | return -EINVAL; | 71 | return -EINVAL; |
72 | } | 72 | } |
73 | 73 | ||
74 | static int sprom2hex(const u16 *sprom, char *buf, size_t buf_len) | ||
75 | { | ||
76 | int i, pos = 0; | ||
77 | |||
78 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { | ||
79 | pos += snprintf(buf + pos, buf_len - pos - 1, | ||
80 | "%04X", swab16(sprom[i]) & 0xFFFF); | ||
81 | } | ||
82 | pos += snprintf(buf + pos, buf_len - pos - 1, "\n"); | ||
83 | |||
84 | return pos + 1; | ||
85 | } | ||
86 | |||
87 | static int hex2sprom(u16 *sprom, const char *dump, size_t len) | ||
88 | { | ||
89 | char tmp[5] = { 0 }; | ||
90 | int cnt = 0; | ||
91 | unsigned long parsed; | ||
92 | |||
93 | if (len < BCM43xx_SPROM_SIZE * sizeof(u16) * 2) | ||
94 | return -EINVAL; | ||
95 | |||
96 | while (cnt < BCM43xx_SPROM_SIZE) { | ||
97 | memcpy(tmp, dump, 4); | ||
98 | dump += 4; | ||
99 | parsed = simple_strtoul(tmp, NULL, 16); | ||
100 | sprom[cnt++] = swab16((u16)parsed); | ||
101 | } | ||
102 | |||
103 | return 0; | ||
104 | } | ||
105 | |||
74 | static ssize_t bcm43xx_attr_sprom_show(struct device *dev, | 106 | static ssize_t bcm43xx_attr_sprom_show(struct device *dev, |
75 | struct device_attribute *attr, | 107 | struct device_attribute *attr, |
76 | char *buf) | 108 | char *buf) |
77 | { | 109 | { |
78 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); | 110 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
79 | u16 *sprom; | 111 | u16 *sprom; |
80 | unsigned long flags; | 112 | unsigned long flags; |
81 | int i, err; | 113 | int err; |
82 | 114 | ||
83 | if (!capable(CAP_NET_ADMIN)) | 115 | if (!capable(CAP_NET_ADMIN)) |
84 | return -EPERM; | 116 | return -EPERM; |
@@ -91,55 +123,53 @@ static ssize_t bcm43xx_attr_sprom_show(struct device *dev, | |||
91 | bcm43xx_lock_mmio(bcm, flags); | 123 | bcm43xx_lock_mmio(bcm, flags); |
92 | assert(bcm->initialized); | 124 | assert(bcm->initialized); |
93 | err = bcm43xx_sprom_read(bcm, sprom); | 125 | err = bcm43xx_sprom_read(bcm, sprom); |
94 | if (!err) { | 126 | if (!err) |
95 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { | 127 | err = sprom2hex(sprom, buf, PAGE_SIZE); |
96 | buf[i * 2] = sprom[i] & 0x00FF; | ||
97 | buf[i * 2 + 1] = (sprom[i] & 0xFF00) >> 8; | ||
98 | } | ||
99 | } | ||
100 | bcm43xx_unlock_mmio(bcm, flags); | 128 | bcm43xx_unlock_mmio(bcm, flags); |
101 | kfree(sprom); | 129 | kfree(sprom); |
102 | 130 | ||
103 | return err ? err : BCM43xx_SPROM_SIZE * sizeof(u16); | 131 | return err; |
104 | } | 132 | } |
105 | 133 | ||
106 | static ssize_t bcm43xx_attr_sprom_store(struct device *dev, | 134 | static ssize_t bcm43xx_attr_sprom_store(struct device *dev, |
107 | struct device_attribute *attr, | 135 | struct device_attribute *attr, |
108 | const char *buf, size_t count) | 136 | const char *buf, size_t count) |
109 | { | 137 | { |
110 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_sprom); | 138 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
111 | u16 *sprom; | 139 | u16 *sprom; |
112 | unsigned long flags; | 140 | unsigned long flags; |
113 | int i, err; | 141 | int err; |
114 | 142 | ||
115 | if (!capable(CAP_NET_ADMIN)) | 143 | if (!capable(CAP_NET_ADMIN)) |
116 | return -EPERM; | 144 | return -EPERM; |
117 | 145 | ||
118 | if (count != BCM43xx_SPROM_SIZE * sizeof(u16)) | ||
119 | return -EINVAL; | ||
120 | sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), | 146 | sprom = kmalloc(BCM43xx_SPROM_SIZE * sizeof(*sprom), |
121 | GFP_KERNEL); | 147 | GFP_KERNEL); |
122 | if (!sprom) | 148 | if (!sprom) |
123 | return -ENOMEM; | 149 | return -ENOMEM; |
124 | for (i = 0; i < BCM43xx_SPROM_SIZE; i++) { | 150 | err = hex2sprom(sprom, buf, count); |
125 | sprom[i] = buf[i * 2] & 0xFF; | 151 | if (err) |
126 | sprom[i] |= ((u16)(buf[i * 2 + 1] & 0xFF)) << 8; | 152 | goto out_kfree; |
127 | } | ||
128 | bcm43xx_lock_mmio(bcm, flags); | 153 | bcm43xx_lock_mmio(bcm, flags); |
129 | assert(bcm->initialized); | 154 | assert(bcm->initialized); |
130 | err = bcm43xx_sprom_write(bcm, sprom); | 155 | err = bcm43xx_sprom_write(bcm, sprom); |
131 | bcm43xx_unlock_mmio(bcm, flags); | 156 | bcm43xx_unlock_mmio(bcm, flags); |
157 | out_kfree: | ||
132 | kfree(sprom); | 158 | kfree(sprom); |
133 | 159 | ||
134 | return err ? err : count; | 160 | return err ? err : count; |
135 | 161 | ||
136 | } | 162 | } |
137 | 163 | ||
164 | static DEVICE_ATTR(sprom, 0600, | ||
165 | bcm43xx_attr_sprom_show, | ||
166 | bcm43xx_attr_sprom_store); | ||
167 | |||
138 | static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, | 168 | static ssize_t bcm43xx_attr_interfmode_show(struct device *dev, |
139 | struct device_attribute *attr, | 169 | struct device_attribute *attr, |
140 | char *buf) | 170 | char *buf) |
141 | { | 171 | { |
142 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); | 172 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
143 | unsigned long flags; | 173 | unsigned long flags; |
144 | int err; | 174 | int err; |
145 | ssize_t count = 0; | 175 | ssize_t count = 0; |
@@ -175,7 +205,7 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, | |||
175 | struct device_attribute *attr, | 205 | struct device_attribute *attr, |
176 | const char *buf, size_t count) | 206 | const char *buf, size_t count) |
177 | { | 207 | { |
178 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_interfmode); | 208 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
179 | unsigned long flags; | 209 | unsigned long flags; |
180 | int err; | 210 | int err; |
181 | int mode; | 211 | int mode; |
@@ -215,11 +245,15 @@ static ssize_t bcm43xx_attr_interfmode_store(struct device *dev, | |||
215 | return err ? err : count; | 245 | return err ? err : count; |
216 | } | 246 | } |
217 | 247 | ||
248 | static DEVICE_ATTR(interference, 0644, | ||
249 | bcm43xx_attr_interfmode_show, | ||
250 | bcm43xx_attr_interfmode_store); | ||
251 | |||
218 | static ssize_t bcm43xx_attr_preamble_show(struct device *dev, | 252 | static ssize_t bcm43xx_attr_preamble_show(struct device *dev, |
219 | struct device_attribute *attr, | 253 | struct device_attribute *attr, |
220 | char *buf) | 254 | char *buf) |
221 | { | 255 | { |
222 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); | 256 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
223 | unsigned long flags; | 257 | unsigned long flags; |
224 | int err; | 258 | int err; |
225 | ssize_t count; | 259 | ssize_t count; |
@@ -245,7 +279,7 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev, | |||
245 | struct device_attribute *attr, | 279 | struct device_attribute *attr, |
246 | const char *buf, size_t count) | 280 | const char *buf, size_t count) |
247 | { | 281 | { |
248 | struct bcm43xx_private *bcm = devattr_to_bcm(attr, attr_preamble); | 282 | struct bcm43xx_private *bcm = dev_to_bcm(dev); |
249 | unsigned long flags; | 283 | unsigned long flags; |
250 | int err; | 284 | int err; |
251 | int value; | 285 | int value; |
@@ -267,56 +301,41 @@ static ssize_t bcm43xx_attr_preamble_store(struct device *dev, | |||
267 | return err ? err : count; | 301 | return err ? err : count; |
268 | } | 302 | } |
269 | 303 | ||
304 | static DEVICE_ATTR(shortpreamble, 0644, | ||
305 | bcm43xx_attr_preamble_show, | ||
306 | bcm43xx_attr_preamble_store); | ||
307 | |||
270 | int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) | 308 | int bcm43xx_sysfs_register(struct bcm43xx_private *bcm) |
271 | { | 309 | { |
272 | struct device *dev = &bcm->pci_dev->dev; | 310 | struct device *dev = &bcm->pci_dev->dev; |
273 | struct bcm43xx_sysfs *sysfs = &bcm->sysfs; | ||
274 | int err; | 311 | int err; |
275 | 312 | ||
276 | assert(bcm->initialized); | 313 | assert(bcm->initialized); |
277 | 314 | ||
278 | sysfs->attr_sprom.attr.name = "sprom"; | 315 | err = device_create_file(dev, &dev_attr_sprom); |
279 | sysfs->attr_sprom.attr.owner = THIS_MODULE; | ||
280 | sysfs->attr_sprom.attr.mode = 0600; | ||
281 | sysfs->attr_sprom.show = bcm43xx_attr_sprom_show; | ||
282 | sysfs->attr_sprom.store = bcm43xx_attr_sprom_store; | ||
283 | err = device_create_file(dev, &sysfs->attr_sprom); | ||
284 | if (err) | 316 | if (err) |
285 | goto out; | 317 | goto out; |
286 | 318 | err = device_create_file(dev, &dev_attr_interference); | |
287 | sysfs->attr_interfmode.attr.name = "interference"; | ||
288 | sysfs->attr_interfmode.attr.owner = THIS_MODULE; | ||
289 | sysfs->attr_interfmode.attr.mode = 0600; | ||
290 | sysfs->attr_interfmode.show = bcm43xx_attr_interfmode_show; | ||
291 | sysfs->attr_interfmode.store = bcm43xx_attr_interfmode_store; | ||
292 | err = device_create_file(dev, &sysfs->attr_interfmode); | ||
293 | if (err) | 319 | if (err) |
294 | goto err_remove_sprom; | 320 | goto err_remove_sprom; |
295 | 321 | err = device_create_file(dev, &dev_attr_shortpreamble); | |
296 | sysfs->attr_preamble.attr.name = "shortpreamble"; | ||
297 | sysfs->attr_preamble.attr.owner = THIS_MODULE; | ||
298 | sysfs->attr_preamble.attr.mode = 0600; | ||
299 | sysfs->attr_preamble.show = bcm43xx_attr_preamble_show; | ||
300 | sysfs->attr_preamble.store = bcm43xx_attr_preamble_store; | ||
301 | err = device_create_file(dev, &sysfs->attr_preamble); | ||
302 | if (err) | 322 | if (err) |
303 | goto err_remove_interfmode; | 323 | goto err_remove_interfmode; |
304 | 324 | ||
305 | out: | 325 | out: |
306 | return err; | 326 | return err; |
307 | err_remove_interfmode: | 327 | err_remove_interfmode: |
308 | device_remove_file(dev, &sysfs->attr_interfmode); | 328 | device_remove_file(dev, &dev_attr_interference); |
309 | err_remove_sprom: | 329 | err_remove_sprom: |
310 | device_remove_file(dev, &sysfs->attr_sprom); | 330 | device_remove_file(dev, &dev_attr_sprom); |
311 | goto out; | 331 | goto out; |
312 | } | 332 | } |
313 | 333 | ||
314 | void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm) | 334 | void bcm43xx_sysfs_unregister(struct bcm43xx_private *bcm) |
315 | { | 335 | { |
316 | struct device *dev = &bcm->pci_dev->dev; | 336 | struct device *dev = &bcm->pci_dev->dev; |
317 | struct bcm43xx_sysfs *sysfs = &bcm->sysfs; | ||
318 | 337 | ||
319 | device_remove_file(dev, &sysfs->attr_preamble); | 338 | device_remove_file(dev, &dev_attr_shortpreamble); |
320 | device_remove_file(dev, &sysfs->attr_interfmode); | 339 | device_remove_file(dev, &dev_attr_interference); |
321 | device_remove_file(dev, &sysfs->attr_sprom); | 340 | device_remove_file(dev, &dev_attr_sprom); |
322 | } | 341 | } |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h index 57f14514e3e0..cc701df71e2a 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h +++ b/drivers/net/wireless/bcm43xx/bcm43xx_sysfs.h | |||
@@ -1,22 +1,6 @@ | |||
1 | #ifndef BCM43xx_SYSFS_H_ | 1 | #ifndef BCM43xx_SYSFS_H_ |
2 | #define BCM43xx_SYSFS_H_ | 2 | #define BCM43xx_SYSFS_H_ |
3 | 3 | ||
4 | #include <linux/device.h> | ||
5 | |||
6 | |||
7 | struct bcm43xx_sysfs { | ||
8 | struct device_attribute attr_sprom; | ||
9 | struct device_attribute attr_interfmode; | ||
10 | struct device_attribute attr_preamble; | ||
11 | }; | ||
12 | |||
13 | #define devattr_to_bcm(attr, attr_name) ({ \ | ||
14 | struct bcm43xx_sysfs *__s; struct bcm43xx_private *__p; \ | ||
15 | __s = container_of((attr), struct bcm43xx_sysfs, attr_name); \ | ||
16 | __p = container_of(__s, struct bcm43xx_private, sysfs); \ | ||
17 | __p; \ | ||
18 | }) | ||
19 | |||
20 | struct bcm43xx_private; | 4 | struct bcm43xx_private; |
21 | 5 | ||
22 | int bcm43xx_sysfs_register(struct bcm43xx_private *bcm); | 6 | int bcm43xx_sysfs_register(struct bcm43xx_private *bcm); |
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c index 3daee828ef4b..3edbb481a0a0 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_wx.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_wx.c | |||
@@ -962,22 +962,22 @@ static const struct iw_priv_args bcm43xx_priv_wx_args[] = { | |||
962 | { | 962 | { |
963 | .cmd = PRIV_WX_SET_SHORTPREAMBLE, | 963 | .cmd = PRIV_WX_SET_SHORTPREAMBLE, |
964 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 964 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
965 | .name = "set_shortpreambl", | 965 | .name = "set_shortpreamb", |
966 | }, | 966 | }, |
967 | { | 967 | { |
968 | .cmd = PRIV_WX_GET_SHORTPREAMBLE, | 968 | .cmd = PRIV_WX_GET_SHORTPREAMBLE, |
969 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, | 969 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, |
970 | .name = "get_shortpreambl", | 970 | .name = "get_shortpreamb", |
971 | }, | 971 | }, |
972 | { | 972 | { |
973 | .cmd = PRIV_WX_SET_SWENCRYPTION, | 973 | .cmd = PRIV_WX_SET_SWENCRYPTION, |
974 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, | 974 | .set_args = IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, |
975 | .name = "set_swencryption", | 975 | .name = "set_swencrypt", |
976 | }, | 976 | }, |
977 | { | 977 | { |
978 | .cmd = PRIV_WX_GET_SWENCRYPTION, | 978 | .cmd = PRIV_WX_GET_SWENCRYPTION, |
979 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, | 979 | .get_args = IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | MAX_WX_STRING, |
980 | .name = "get_swencryption", | 980 | .name = "get_swencrypt", |
981 | }, | 981 | }, |
982 | { | 982 | { |
983 | .cmd = PRIV_WX_SPROM_WRITE, | 983 | .cmd = PRIV_WX_SPROM_WRITE, |
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c index 8b37e824dfcb..8399de581893 100644 --- a/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/drivers/net/wireless/hostap/hostap_ioctl.c | |||
@@ -1860,7 +1860,7 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1860 | memset(&iwe, 0, sizeof(iwe)); | 1860 | memset(&iwe, 0, sizeof(iwe)); |
1861 | iwe.cmd = SIOCGIWFREQ; | 1861 | iwe.cmd = SIOCGIWFREQ; |
1862 | if (scan) { | 1862 | if (scan) { |
1863 | chan = scan->chid; | 1863 | chan = le16_to_cpu(scan->chid); |
1864 | } else if (bss) { | 1864 | } else if (bss) { |
1865 | chan = bss->chan; | 1865 | chan = bss->chan; |
1866 | } else { | 1866 | } else { |
@@ -1868,7 +1868,7 @@ static char * __prism2_translate_scan(local_info_t *local, | |||
1868 | } | 1868 | } |
1869 | 1869 | ||
1870 | if (chan > 0) { | 1870 | if (chan > 0) { |
1871 | iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000; | 1871 | iwe.u.freq.m = freq_list[chan - 1] * 100000; |
1872 | iwe.u.freq.e = 1; | 1872 | iwe.u.freq.e = 1; |
1873 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, | 1873 | current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, |
1874 | IW_EV_FREQ_LEN); | 1874 | IW_EV_FREQ_LEN); |
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 8dfdfbd5966c..06523e2a8471 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -390,7 +390,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
390 | } | 390 | } |
391 | } else { | 391 | } else { |
392 | struct { | 392 | struct { |
393 | __le16 qual, signal, noise; | 393 | __le16 qual, signal, noise, unused; |
394 | } __attribute__ ((packed)) cq; | 394 | } __attribute__ ((packed)) cq; |
395 | 395 | ||
396 | err = HERMES_READ_RECORD(hw, USER_BAP, | 396 | err = HERMES_READ_RECORD(hw, USER_BAP, |
diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c index 4e53be9c03ab..bbeabe3fc4c6 100644 --- a/drivers/parisc/pdc_stable.c +++ b/drivers/parisc/pdc_stable.c | |||
@@ -535,7 +535,7 @@ pdcs_auto_read(struct subsystem *entry, char *buf, int knob) | |||
535 | { | 535 | { |
536 | char *out = buf; | 536 | char *out = buf; |
537 | struct pdcspath_entry *pathentry; | 537 | struct pdcspath_entry *pathentry; |
538 | 538 | ||
539 | if (!entry || !buf) | 539 | if (!entry || !buf) |
540 | return -EINVAL; | 540 | return -EINVAL; |
541 | 541 | ||
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 42b32ff2fca6..278f325021ee 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c | |||
@@ -178,6 +178,11 @@ extern struct proc_dir_entry * proc_mckinley_root; | |||
178 | #define ROPE6_CTL 0x230 | 178 | #define ROPE6_CTL 0x230 |
179 | #define ROPE7_CTL 0x238 | 179 | #define ROPE7_CTL 0x238 |
180 | 180 | ||
181 | #define IOC_ROPE0_CFG 0x500 /* pluto only */ | ||
182 | #define IOC_ROPE_AO 0x10 /* Allow "Relaxed Ordering" */ | ||
183 | |||
184 | |||
185 | |||
181 | #define HF_ENABLE 0x40 | 186 | #define HF_ENABLE 0x40 |
182 | 187 | ||
183 | 188 | ||
@@ -1759,19 +1764,33 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, | |||
1759 | 1764 | ||
1760 | sba_dev->num_ioc = num_ioc; | 1765 | sba_dev->num_ioc = num_ioc; |
1761 | for (i = 0; i < num_ioc; i++) { | 1766 | for (i = 0; i < num_ioc; i++) { |
1762 | /* | 1767 | unsigned long ioc_hpa = sba_dev->ioc[i].ioc_hpa; |
1763 | ** Make sure the box crashes if we get any errors on a rope. | 1768 | unsigned int j; |
1764 | */ | 1769 | |
1765 | WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE0_CTL); | 1770 | for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) { |
1766 | WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE1_CTL); | 1771 | |
1767 | WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE2_CTL); | 1772 | /* |
1768 | WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE3_CTL); | 1773 | * Clear ROPE(N)_CONFIG AO bit. |
1769 | WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE4_CTL); | 1774 | * Disables "NT Ordering" (~= !"Relaxed Ordering") |
1770 | WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE5_CTL); | 1775 | * Overrides bit 1 in DMA Hint Sets. |
1771 | WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE6_CTL); | 1776 | * Improves netperf UDP_STREAM by ~10% for bcm5701. |
1772 | WRITE_REG(HF_ENABLE, sba_dev->ioc[i].ioc_hpa + ROPE7_CTL); | 1777 | */ |
1773 | 1778 | if (IS_PLUTO(sba_dev->iodc)) { | |
1774 | /* flush out the writes */ | 1779 | unsigned long rope_cfg, cfg_val; |
1780 | |||
1781 | rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j; | ||
1782 | cfg_val = READ_REG(rope_cfg); | ||
1783 | cfg_val &= ~IOC_ROPE_AO; | ||
1784 | WRITE_REG(cfg_val, rope_cfg); | ||
1785 | } | ||
1786 | |||
1787 | /* | ||
1788 | ** Make sure the box crashes on rope errors. | ||
1789 | */ | ||
1790 | WRITE_REG(HF_ENABLE, ioc_hpa + ROPE0_CTL + j); | ||
1791 | } | ||
1792 | |||
1793 | /* flush out the last writes */ | ||
1775 | READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL); | 1794 | READ_REG(sba_dev->ioc[i].ioc_hpa + ROPE7_CTL); |
1776 | 1795 | ||
1777 | DBG_INIT(" ioc[%d] ROPE_CFG 0x%Lx ROPE_DBG 0x%Lx\n", | 1796 | DBG_INIT(" ioc[%d] ROPE_CFG 0x%Lx ROPE_DBG 0x%Lx\n", |
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c index 719b863bc20e..828eb45062de 100644 --- a/drivers/parisc/superio.c +++ b/drivers/parisc/superio.c | |||
@@ -155,7 +155,7 @@ superio_init(struct pci_dev *pcidev) | |||
155 | struct pci_dev *pdev = sio->lio_pdev; | 155 | struct pci_dev *pdev = sio->lio_pdev; |
156 | u16 word; | 156 | u16 word; |
157 | 157 | ||
158 | if (sio->suckyio_irq_enabled) | 158 | if (sio->suckyio_irq_enabled) |
159 | return; | 159 | return; |
160 | 160 | ||
161 | BUG_ON(!pdev); | 161 | BUG_ON(!pdev); |
@@ -194,7 +194,7 @@ superio_init(struct pci_dev *pcidev) | |||
194 | request_region (sio->acpi_base, 0x1f, "acpi"); | 194 | request_region (sio->acpi_base, 0x1f, "acpi"); |
195 | 195 | ||
196 | /* Enable the legacy I/O function */ | 196 | /* Enable the legacy I/O function */ |
197 | pci_read_config_word (pdev, PCI_COMMAND, &word); | 197 | pci_read_config_word (pdev, PCI_COMMAND, &word); |
198 | word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO; | 198 | word |= PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_IO; |
199 | pci_write_config_word (pdev, PCI_COMMAND, word); | 199 | pci_write_config_word (pdev, PCI_COMMAND, word); |
200 | 200 | ||
diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index d5890027f8af..48bbf32fd980 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c | |||
@@ -97,7 +97,7 @@ static struct superio_struct { /* For Super-IO chips autodetection */ | |||
97 | int io; | 97 | int io; |
98 | int irq; | 98 | int irq; |
99 | int dma; | 99 | int dma; |
100 | } superios[NR_SUPERIOS] __devinitdata = { {0,},}; | 100 | } superios[NR_SUPERIOS] = { {0,},}; |
101 | 101 | ||
102 | static int user_specified; | 102 | static int user_specified; |
103 | #if defined(CONFIG_PARPORT_PC_SUPERIO) || \ | 103 | #if defined(CONFIG_PARPORT_PC_SUPERIO) || \ |
@@ -1557,7 +1557,7 @@ static int __devinit get_superio_dma (struct parport *p) | |||
1557 | return PARPORT_DMA_NONE; | 1557 | return PARPORT_DMA_NONE; |
1558 | } | 1558 | } |
1559 | 1559 | ||
1560 | static int __devinit get_superio_irq (struct parport *p) | 1560 | static int get_superio_irq (struct parport *p) |
1561 | { | 1561 | { |
1562 | int i=0; | 1562 | int i=0; |
1563 | while( (superios[i].io != p->base) && (i<NR_SUPERIOS)) | 1563 | while( (superios[i].io != p->base) && (i<NR_SUPERIOS)) |
@@ -1579,7 +1579,7 @@ static int __devinit get_superio_irq (struct parport *p) | |||
1579 | * this shall always be the case!) | 1579 | * this shall always be the case!) |
1580 | * | 1580 | * |
1581 | */ | 1581 | */ |
1582 | static int __devinit parport_SPP_supported(struct parport *pb) | 1582 | static int parport_SPP_supported(struct parport *pb) |
1583 | { | 1583 | { |
1584 | unsigned char r, w; | 1584 | unsigned char r, w; |
1585 | 1585 | ||
@@ -1660,7 +1660,7 @@ static int __devinit parport_SPP_supported(struct parport *pb) | |||
1660 | * two bits of ECR aren't writable, so we check by writing ECR and | 1660 | * two bits of ECR aren't writable, so we check by writing ECR and |
1661 | * reading it back to see if it's what we expect. | 1661 | * reading it back to see if it's what we expect. |
1662 | */ | 1662 | */ |
1663 | static int __devinit parport_ECR_present(struct parport *pb) | 1663 | static int parport_ECR_present(struct parport *pb) |
1664 | { | 1664 | { |
1665 | struct parport_pc_private *priv = pb->private_data; | 1665 | struct parport_pc_private *priv = pb->private_data; |
1666 | unsigned char r = 0xc; | 1666 | unsigned char r = 0xc; |
@@ -1712,7 +1712,7 @@ static int __devinit parport_ECR_present(struct parport *pb) | |||
1712 | * be misdetected here is rather academic. | 1712 | * be misdetected here is rather academic. |
1713 | */ | 1713 | */ |
1714 | 1714 | ||
1715 | static int __devinit parport_PS2_supported(struct parport *pb) | 1715 | static int parport_PS2_supported(struct parport *pb) |
1716 | { | 1716 | { |
1717 | int ok = 0; | 1717 | int ok = 0; |
1718 | 1718 | ||
@@ -1868,7 +1868,7 @@ static int __devinit parport_ECP_supported(struct parport *pb) | |||
1868 | } | 1868 | } |
1869 | #endif | 1869 | #endif |
1870 | 1870 | ||
1871 | static int __devinit parport_ECPPS2_supported(struct parport *pb) | 1871 | static int parport_ECPPS2_supported(struct parport *pb) |
1872 | { | 1872 | { |
1873 | const struct parport_pc_private *priv = pb->private_data; | 1873 | const struct parport_pc_private *priv = pb->private_data; |
1874 | int result; | 1874 | int result; |
@@ -1886,7 +1886,7 @@ static int __devinit parport_ECPPS2_supported(struct parport *pb) | |||
1886 | 1886 | ||
1887 | /* EPP mode detection */ | 1887 | /* EPP mode detection */ |
1888 | 1888 | ||
1889 | static int __devinit parport_EPP_supported(struct parport *pb) | 1889 | static int parport_EPP_supported(struct parport *pb) |
1890 | { | 1890 | { |
1891 | const struct parport_pc_private *priv = pb->private_data; | 1891 | const struct parport_pc_private *priv = pb->private_data; |
1892 | 1892 | ||
@@ -1931,7 +1931,7 @@ static int __devinit parport_EPP_supported(struct parport *pb) | |||
1931 | return 1; | 1931 | return 1; |
1932 | } | 1932 | } |
1933 | 1933 | ||
1934 | static int __devinit parport_ECPEPP_supported(struct parport *pb) | 1934 | static int parport_ECPEPP_supported(struct parport *pb) |
1935 | { | 1935 | { |
1936 | struct parport_pc_private *priv = pb->private_data; | 1936 | struct parport_pc_private *priv = pb->private_data; |
1937 | int result; | 1937 | int result; |
@@ -2073,7 +2073,7 @@ static int __devinit irq_probe_SPP(struct parport *pb) | |||
2073 | * When ECP is available we can autoprobe for IRQs. | 2073 | * When ECP is available we can autoprobe for IRQs. |
2074 | * NOTE: If we can autoprobe it, we can register the IRQ. | 2074 | * NOTE: If we can autoprobe it, we can register the IRQ. |
2075 | */ | 2075 | */ |
2076 | static int __devinit parport_irq_probe(struct parport *pb) | 2076 | static int parport_irq_probe(struct parport *pb) |
2077 | { | 2077 | { |
2078 | struct parport_pc_private *priv = pb->private_data; | 2078 | struct parport_pc_private *priv = pb->private_data; |
2079 | 2079 | ||
@@ -2779,7 +2779,7 @@ static struct parport_pc_pci { | |||
2779 | /* If set, this is called after probing for ports. If 'failed' | 2779 | /* If set, this is called after probing for ports. If 'failed' |
2780 | * is non-zero we couldn't use any of the ports. */ | 2780 | * is non-zero we couldn't use any of the ports. */ |
2781 | void (*postinit_hook) (struct pci_dev *pdev, int failed); | 2781 | void (*postinit_hook) (struct pci_dev *pdev, int failed); |
2782 | } cards[] __devinitdata = { | 2782 | } cards[] = { |
2783 | /* siig_1p_10x */ { 1, { { 2, 3 }, } }, | 2783 | /* siig_1p_10x */ { 1, { { 2, 3 }, } }, |
2784 | /* siig_2p_10x */ { 2, { { 2, 3 }, { 4, 5 }, } }, | 2784 | /* siig_2p_10x */ { 2, { { 2, 3 }, { 4, 5 }, } }, |
2785 | /* siig_1p_20x */ { 1, { { 0, 1 }, } }, | 2785 | /* siig_1p_20x */ { 1, { { 0, 1 }, } }, |
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 827550d25c9e..c42ae2cf8d64 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -865,6 +865,35 @@ static void __init quirk_eisa_bridge(struct pci_dev *dev) | |||
865 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge ); | 865 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_eisa_bridge ); |
866 | 866 | ||
867 | /* | 867 | /* |
868 | * On the MSI-K8T-Neo2Fir Board, the internal Soundcard is disabled | ||
869 | * when a PCI-Soundcard is added. The BIOS only gives Options | ||
870 | * "Disabled" and "AUTO". This Quirk Sets the corresponding | ||
871 | * Register-Value to enable the Soundcard. | ||
872 | */ | ||
873 | static void __init k8t_sound_hostbridge(struct pci_dev *dev) | ||
874 | { | ||
875 | unsigned char val; | ||
876 | |||
877 | printk(KERN_INFO "PCI: Quirk-MSI-K8T Soundcard On\n"); | ||
878 | pci_read_config_byte(dev, 0x50, &val); | ||
879 | if (val == 0x88 || val == 0xc8) { | ||
880 | pci_write_config_byte(dev, 0x50, val & (~0x40)); | ||
881 | |||
882 | /* Verify the Change for Status output */ | ||
883 | pci_read_config_byte(dev, 0x50, &val); | ||
884 | if (val & 0x40) | ||
885 | printk(KERN_INFO "PCI: MSI-K8T soundcard still off\n"); | ||
886 | else | ||
887 | printk(KERN_INFO "PCI: MSI-K8T soundcard on\n"); | ||
888 | } else { | ||
889 | printk(KERN_INFO "PCI: Unexpected Value in PCI-Register: " | ||
890 | "no Change!\n"); | ||
891 | } | ||
892 | |||
893 | } | ||
894 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge); | ||
895 | |||
896 | /* | ||
868 | * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge | 897 | * On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge |
869 | * is not activated. The myth is that Asus said that they do not want the | 898 | * is not activated. The myth is that Asus said that they do not want the |
870 | * users to be irritated by just another PCI Device in the Win98 device | 899 | * users to be irritated by just another PCI Device in the Win98 device |
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig index cba6c9eef28e..61cb4b29f55c 100644 --- a/drivers/pcmcia/Kconfig +++ b/drivers/pcmcia/Kconfig | |||
@@ -250,7 +250,7 @@ config M32R_CFC_NUM | |||
250 | 250 | ||
251 | config PCMCIA_VRC4171 | 251 | config PCMCIA_VRC4171 |
252 | tristate "NEC VRC4171 Card Controllers support" | 252 | tristate "NEC VRC4171 Card Controllers support" |
253 | depends on VRC4171 && PCMCIA | 253 | depends on CPU_VR41XX && ISA && PCMCIA |
254 | 254 | ||
255 | config PCMCIA_VRC4173 | 255 | config PCMCIA_VRC4173 |
256 | tristate "NEC VRC4173 CARDU support" | 256 | tristate "NEC VRC4173 CARDU support" |
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index ae10d1eed65e..48d3b3d30c21 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c | |||
@@ -236,11 +236,11 @@ static void pcmcia_check_driver(struct pcmcia_driver *p_drv) | |||
236 | /** | 236 | /** |
237 | * pcmcia_load_firmware - load CIS from userspace if device-provided is broken | 237 | * pcmcia_load_firmware - load CIS from userspace if device-provided is broken |
238 | * @dev - the pcmcia device which needs a CIS override | 238 | * @dev - the pcmcia device which needs a CIS override |
239 | * @filename - requested filename in /lib/firmware/cis/ | 239 | * @filename - requested filename in /lib/firmware/ |
240 | * | 240 | * |
241 | * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if | 241 | * This uses the in-kernel firmware loading mechanism to use a "fake CIS" if |
242 | * the one provided by the card is broken. The firmware files reside in | 242 | * the one provided by the card is broken. The firmware files reside in |
243 | * /lib/firmware/cis/ in userspace. | 243 | * /lib/firmware/ in userspace. |
244 | */ | 244 | */ |
245 | static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) | 245 | static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename) |
246 | { | 246 | { |
@@ -298,9 +298,6 @@ static inline int pcmcia_load_firmware(struct pcmcia_device *dev, char * filenam | |||
298 | * | 298 | * |
299 | * Registers a PCMCIA driver with the PCMCIA bus core. | 299 | * Registers a PCMCIA driver with the PCMCIA bus core. |
300 | */ | 300 | */ |
301 | static int pcmcia_device_probe(struct device *dev); | ||
302 | static int pcmcia_device_remove(struct device * dev); | ||
303 | |||
304 | int pcmcia_register_driver(struct pcmcia_driver *driver) | 301 | int pcmcia_register_driver(struct pcmcia_driver *driver) |
305 | { | 302 | { |
306 | if (!driver) | 303 | if (!driver) |
@@ -400,7 +397,7 @@ static int pcmcia_device_probe(struct device * dev) | |||
400 | * call which will then check whether there are two | 397 | * call which will then check whether there are two |
401 | * pseudo devices, and if not, add the second one. | 398 | * pseudo devices, and if not, add the second one. |
402 | */ | 399 | */ |
403 | did = (struct pcmcia_device_id *) p_dev->dev.driver_data; | 400 | did = p_dev->dev.driver_data; |
404 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && | 401 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && |
405 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) | 402 | (p_dev->socket->device_count == 1) && (p_dev->device_no == 0)) |
406 | pcmcia_add_pseudo_device(p_dev->socket); | 403 | pcmcia_add_pseudo_device(p_dev->socket); |
@@ -448,7 +445,6 @@ static void pcmcia_card_remove(struct pcmcia_socket *s, struct pcmcia_device *le | |||
448 | return; | 445 | return; |
449 | } | 446 | } |
450 | 447 | ||
451 | |||
452 | static int pcmcia_device_remove(struct device * dev) | 448 | static int pcmcia_device_remove(struct device * dev) |
453 | { | 449 | { |
454 | struct pcmcia_device *p_dev; | 450 | struct pcmcia_device *p_dev; |
@@ -463,7 +459,7 @@ static int pcmcia_device_remove(struct device * dev) | |||
463 | * pseudo multi-function card, we need to unbind | 459 | * pseudo multi-function card, we need to unbind |
464 | * all devices | 460 | * all devices |
465 | */ | 461 | */ |
466 | did = (struct pcmcia_device_id *) p_dev->dev.driver_data; | 462 | did = p_dev->dev.driver_data; |
467 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && | 463 | if (did && (did->match_flags & PCMCIA_DEV_ID_MATCH_DEVICE_NO) && |
468 | (p_dev->socket->device_count != 0) && | 464 | (p_dev->socket->device_count != 0) && |
469 | (p_dev->device_no == 0)) | 465 | (p_dev->device_no == 0)) |
@@ -476,6 +472,8 @@ static int pcmcia_device_remove(struct device * dev) | |||
476 | if (p_drv->remove) | 472 | if (p_drv->remove) |
477 | p_drv->remove(p_dev); | 473 | p_drv->remove(p_dev); |
478 | 474 | ||
475 | p_dev->dev_node = NULL; | ||
476 | |||
479 | /* check for proper unloading */ | 477 | /* check for proper unloading */ |
480 | if (p_dev->_irq || p_dev->_io || p_dev->_locked) | 478 | if (p_dev->_irq || p_dev->_io || p_dev->_locked) |
481 | printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", | 479 | printk(KERN_INFO "pcmcia: driver %s did not release config properly\n", |
@@ -628,7 +626,7 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f | |||
628 | } | 626 | } |
629 | 627 | ||
630 | /* Add to the list in pcmcia_bus_socket */ | 628 | /* Add to the list in pcmcia_bus_socket */ |
631 | list_add_tail(&p_dev->socket_device_list, &s->devices_list); | 629 | list_add(&p_dev->socket_device_list, &s->devices_list); |
632 | 630 | ||
633 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); | 631 | spin_unlock_irqrestore(&pcmcia_dev_list_lock, flags); |
634 | 632 | ||
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c index 45063b4e5b78..3131bb0a0095 100644 --- a/drivers/pcmcia/pcmcia_resource.c +++ b/drivers/pcmcia/pcmcia_resource.c | |||
@@ -88,7 +88,6 @@ static int alloc_io_space(struct pcmcia_socket *s, u_int attr, ioaddr_t *base, | |||
88 | } | 88 | } |
89 | if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { | 89 | if ((s->features & SS_CAP_STATIC_MAP) && s->io_offset) { |
90 | *base = s->io_offset | (*base & 0x0fff); | 90 | *base = s->io_offset | (*base & 0x0fff); |
91 | s->io[0].res->flags = (s->io[0].res->flags & ~IORESOURCE_BITS) | (attr & IORESOURCE_BITS); | ||
92 | return 0; | 91 | return 0; |
93 | } | 92 | } |
94 | /* Check for an already-allocated window that must conflict with | 93 | /* Check for an already-allocated window that must conflict with |
@@ -209,7 +208,6 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, | |||
209 | if (!(s->state & SOCKET_PRESENT)) | 208 | if (!(s->state & SOCKET_PRESENT)) |
210 | return CS_NO_CARD; | 209 | return CS_NO_CARD; |
211 | 210 | ||
212 | config->Function = p_dev->func; | ||
213 | 211 | ||
214 | #ifdef CONFIG_CARDBUS | 212 | #ifdef CONFIG_CARDBUS |
215 | if (s->state & SOCKET_CARDBUS) { | 213 | if (s->state & SOCKET_CARDBUS) { |
@@ -223,14 +221,22 @@ int pccard_get_configuration_info(struct pcmcia_socket *s, | |||
223 | config->AssignedIRQ = s->irq.AssignedIRQ; | 221 | config->AssignedIRQ = s->irq.AssignedIRQ; |
224 | if (config->AssignedIRQ) | 222 | if (config->AssignedIRQ) |
225 | config->Attributes |= CONF_ENABLE_IRQ; | 223 | config->Attributes |= CONF_ENABLE_IRQ; |
226 | config->BasePort1 = s->io[0].res->start; | 224 | if (s->io[0].res) { |
227 | config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1; | 225 | config->BasePort1 = s->io[0].res->start; |
226 | config->NumPorts1 = s->io[0].res->end - config->BasePort1 + 1; | ||
227 | } | ||
228 | } | 228 | } |
229 | return CS_SUCCESS; | 229 | return CS_SUCCESS; |
230 | } | 230 | } |
231 | #endif | 231 | #endif |
232 | 232 | ||
233 | c = (p_dev) ? p_dev->function_config : NULL; | 233 | if (p_dev) { |
234 | c = p_dev->function_config; | ||
235 | config->Function = p_dev->func; | ||
236 | } else { | ||
237 | c = NULL; | ||
238 | config->Function = 0; | ||
239 | } | ||
234 | 240 | ||
235 | if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { | 241 | if ((c == NULL) || !(c->state & CONFIG_LOCKED)) { |
236 | config->Attributes = 0; | 242 | config->Attributes = 0; |
@@ -947,7 +953,5 @@ void pcmcia_disable_device(struct pcmcia_device *p_dev) { | |||
947 | pcmcia_release_irq(p_dev, &p_dev->irq); | 953 | pcmcia_release_irq(p_dev, &p_dev->irq); |
948 | if (&p_dev->win) | 954 | if (&p_dev->win) |
949 | pcmcia_release_window(p_dev->win); | 955 | pcmcia_release_window(p_dev->win); |
950 | |||
951 | p_dev->dev_node = NULL; | ||
952 | } | 956 | } |
953 | EXPORT_SYMBOL(pcmcia_disable_device); | 957 | EXPORT_SYMBOL(pcmcia_disable_device); |
diff --git a/drivers/pcmcia/pxa2xx_sharpsl.c b/drivers/pcmcia/pxa2xx_sharpsl.c index fd3647368955..b7b9e149c5b9 100644 --- a/drivers/pcmcia/pxa2xx_sharpsl.c +++ b/drivers/pcmcia/pxa2xx_sharpsl.c | |||
@@ -26,14 +26,6 @@ | |||
26 | #include "soc_common.h" | 26 | #include "soc_common.h" |
27 | 27 | ||
28 | #define NO_KEEP_VS 0x0001 | 28 | #define NO_KEEP_VS 0x0001 |
29 | |||
30 | /* PCMCIA to Scoop linkage | ||
31 | |||
32 | There is no easy way to link multiple scoop devices into one | ||
33 | single entity for the pxa2xx_pcmcia device so this structure | ||
34 | is used which is setup by the platform code | ||
35 | */ | ||
36 | struct scoop_pcmcia_config *platform_scoop_config; | ||
37 | #define SCOOP_DEV platform_scoop_config->devs | 29 | #define SCOOP_DEV platform_scoop_config->devs |
38 | 30 | ||
39 | static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) | 31 | static void sharpsl_pcmcia_init_reset(struct soc_pcmcia_socket *skt) |
diff --git a/drivers/pnp/manager.c b/drivers/pnp/manager.c index c4256aa32bcb..6fff109bdab6 100644 --- a/drivers/pnp/manager.c +++ b/drivers/pnp/manager.c | |||
@@ -479,7 +479,7 @@ int pnp_auto_config_dev(struct pnp_dev *dev) | |||
479 | int pnp_start_dev(struct pnp_dev *dev) | 479 | int pnp_start_dev(struct pnp_dev *dev) |
480 | { | 480 | { |
481 | if (!pnp_can_write(dev)) { | 481 | if (!pnp_can_write(dev)) { |
482 | pnp_info("Device %s does not supported activation.", dev->dev.bus_id); | 482 | pnp_info("Device %s does not support activation.", dev->dev.bus_id); |
483 | return -EINVAL; | 483 | return -EINVAL; |
484 | } | 484 | } |
485 | 485 | ||
@@ -503,7 +503,7 @@ int pnp_start_dev(struct pnp_dev *dev) | |||
503 | int pnp_stop_dev(struct pnp_dev *dev) | 503 | int pnp_stop_dev(struct pnp_dev *dev) |
504 | { | 504 | { |
505 | if (!pnp_can_disable(dev)) { | 505 | if (!pnp_can_disable(dev)) { |
506 | pnp_info("Device %s does not supported disabling.", dev->dev.bus_id); | 506 | pnp_info("Device %s does not support disabling.", dev->dev.bus_id); |
507 | return -EINVAL; | 507 | return -EINVAL; |
508 | } | 508 | } |
509 | if (dev->protocol->disable(dev)<0) { | 509 | if (dev->protocol->disable(dev)<0) { |
diff --git a/drivers/scsi/ahci.c b/drivers/scsi/ahci.c index 1b8429cb3c96..d23f00230a76 100644 --- a/drivers/scsi/ahci.c +++ b/drivers/scsi/ahci.c | |||
@@ -73,6 +73,7 @@ enum { | |||
73 | RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ | 73 | RX_FIS_D2H_REG = 0x40, /* offset of D2H Register FIS data */ |
74 | 74 | ||
75 | board_ahci = 0, | 75 | board_ahci = 0, |
76 | board_ahci_vt8251 = 1, | ||
76 | 77 | ||
77 | /* global controller registers */ | 78 | /* global controller registers */ |
78 | HOST_CAP = 0x00, /* host capabilities */ | 79 | HOST_CAP = 0x00, /* host capabilities */ |
@@ -153,6 +154,9 @@ enum { | |||
153 | 154 | ||
154 | /* hpriv->flags bits */ | 155 | /* hpriv->flags bits */ |
155 | AHCI_FLAG_MSI = (1 << 0), | 156 | AHCI_FLAG_MSI = (1 << 0), |
157 | |||
158 | /* ap->flags bits */ | ||
159 | AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24), | ||
156 | }; | 160 | }; |
157 | 161 | ||
158 | struct ahci_cmd_hdr { | 162 | struct ahci_cmd_hdr { |
@@ -255,6 +259,16 @@ static const struct ata_port_info ahci_port_info[] = { | |||
255 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | 259 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ |
256 | .port_ops = &ahci_ops, | 260 | .port_ops = &ahci_ops, |
257 | }, | 261 | }, |
262 | /* board_ahci_vt8251 */ | ||
263 | { | ||
264 | .sht = &ahci_sht, | ||
265 | .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | | ||
266 | ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | | ||
267 | AHCI_FLAG_RESET_NEEDS_CLO, | ||
268 | .pio_mask = 0x1f, /* pio0-4 */ | ||
269 | .udma_mask = 0x7f, /* udma0-6 ; FIXME */ | ||
270 | .port_ops = &ahci_ops, | ||
271 | }, | ||
258 | }; | 272 | }; |
259 | 273 | ||
260 | static const struct pci_device_id ahci_pci_tbl[] = { | 274 | static const struct pci_device_id ahci_pci_tbl[] = { |
@@ -296,6 +310,8 @@ static const struct pci_device_id ahci_pci_tbl[] = { | |||
296 | board_ahci }, /* ATI SB600 non-raid */ | 310 | board_ahci }, /* ATI SB600 non-raid */ |
297 | { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | 311 | { PCI_VENDOR_ID_ATI, 0x4381, PCI_ANY_ID, PCI_ANY_ID, 0, 0, |
298 | board_ahci }, /* ATI SB600 raid */ | 312 | board_ahci }, /* ATI SB600 raid */ |
313 | { PCI_VENDOR_ID_VIA, 0x3349, PCI_ANY_ID, PCI_ANY_ID, 0, 0, | ||
314 | board_ahci_vt8251 }, /* VIA VT8251 */ | ||
299 | { } /* terminate list */ | 315 | { } /* terminate list */ |
300 | }; | 316 | }; |
301 | 317 | ||
@@ -516,9 +532,29 @@ static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, u32 opts) | |||
516 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); | 532 | pp->cmd_slot[0].tbl_addr_hi = cpu_to_le32((pp->cmd_tbl_dma >> 16) >> 16); |
517 | } | 533 | } |
518 | 534 | ||
519 | static int ahci_softreset(struct ata_port *ap, unsigned int *class) | 535 | static int ahci_clo(struct ata_port *ap) |
520 | { | 536 | { |
537 | void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; | ||
521 | struct ahci_host_priv *hpriv = ap->host_set->private_data; | 538 | struct ahci_host_priv *hpriv = ap->host_set->private_data; |
539 | u32 tmp; | ||
540 | |||
541 | if (!(hpriv->cap & HOST_CAP_CLO)) | ||
542 | return -EOPNOTSUPP; | ||
543 | |||
544 | tmp = readl(port_mmio + PORT_CMD); | ||
545 | tmp |= PORT_CMD_CLO; | ||
546 | writel(tmp, port_mmio + PORT_CMD); | ||
547 | |||
548 | tmp = ata_wait_register(port_mmio + PORT_CMD, | ||
549 | PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); | ||
550 | if (tmp & PORT_CMD_CLO) | ||
551 | return -EIO; | ||
552 | |||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | static int ahci_softreset(struct ata_port *ap, unsigned int *class) | ||
557 | { | ||
522 | struct ahci_port_priv *pp = ap->private_data; | 558 | struct ahci_port_priv *pp = ap->private_data; |
523 | void __iomem *mmio = ap->host_set->mmio_base; | 559 | void __iomem *mmio = ap->host_set->mmio_base; |
524 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); | 560 | void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); |
@@ -547,21 +583,13 @@ static int ahci_softreset(struct ata_port *ap, unsigned int *class) | |||
547 | /* check BUSY/DRQ, perform Command List Override if necessary */ | 583 | /* check BUSY/DRQ, perform Command List Override if necessary */ |
548 | ahci_tf_read(ap, &tf); | 584 | ahci_tf_read(ap, &tf); |
549 | if (tf.command & (ATA_BUSY | ATA_DRQ)) { | 585 | if (tf.command & (ATA_BUSY | ATA_DRQ)) { |
550 | if (!(hpriv->cap & HOST_CAP_CLO)) { | 586 | rc = ahci_clo(ap); |
551 | rc = -EIO; | ||
552 | reason = "port busy but no CLO"; | ||
553 | goto fail_restart; | ||
554 | } | ||
555 | |||
556 | tmp = readl(port_mmio + PORT_CMD); | ||
557 | tmp |= PORT_CMD_CLO; | ||
558 | writel(tmp, port_mmio + PORT_CMD); | ||
559 | 587 | ||
560 | tmp = ata_wait_register(port_mmio + PORT_CMD, | 588 | if (rc == -EOPNOTSUPP) { |
561 | PORT_CMD_CLO, PORT_CMD_CLO, 1, 500); | 589 | reason = "port busy but CLO unavailable"; |
562 | if (tmp & PORT_CMD_CLO) { | 590 | goto fail_restart; |
563 | rc = -EIO; | 591 | } else if (rc) { |
564 | reason = "CLO failed"; | 592 | reason = "port busy but CLO failed"; |
565 | goto fail_restart; | 593 | goto fail_restart; |
566 | } | 594 | } |
567 | } | 595 | } |
@@ -672,6 +700,12 @@ static void ahci_postreset(struct ata_port *ap, unsigned int *class) | |||
672 | 700 | ||
673 | static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes) | 701 | static int ahci_probe_reset(struct ata_port *ap, unsigned int *classes) |
674 | { | 702 | { |
703 | if ((ap->flags & AHCI_FLAG_RESET_NEEDS_CLO) && | ||
704 | (ata_busy_wait(ap, ATA_BUSY, 1000) & ATA_BUSY)) { | ||
705 | /* ATA_BUSY hasn't cleared, so send a CLO */ | ||
706 | ahci_clo(ap); | ||
707 | } | ||
708 | |||
675 | return ata_drive_probe_reset(ap, ata_std_probeinit, | 709 | return ata_drive_probe_reset(ap, ata_std_probeinit, |
676 | ahci_softreset, ahci_hardreset, | 710 | ahci_softreset, ahci_hardreset, |
677 | ahci_postreset, classes); | 711 | ahci_postreset, classes); |
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c index e9c10c0a30fc..321a40f33b50 100644 --- a/drivers/serial/m32r_sio.c +++ b/drivers/serial/m32r_sio.c | |||
@@ -1057,7 +1057,6 @@ static void m32r_sio_console_write(struct console *co, const char *s, | |||
1057 | { | 1057 | { |
1058 | struct uart_sio_port *up = &m32r_sio_ports[co->index]; | 1058 | struct uart_sio_port *up = &m32r_sio_ports[co->index]; |
1059 | unsigned int ier; | 1059 | unsigned int ier; |
1060 | int i; | ||
1061 | 1060 | ||
1062 | /* | 1061 | /* |
1063 | * First save the UER then disable the interrupts | 1062 | * First save the UER then disable the interrupts |
diff --git a/drivers/usb/gadget/inode.c b/drivers/usb/gadget/inode.c index 42b457030b03..0eb010a3f5bc 100644 --- a/drivers/usb/gadget/inode.c +++ b/drivers/usb/gadget/inode.c | |||
@@ -1614,6 +1614,7 @@ static int activate_ep_files (struct dev_data *dev) | |||
1614 | data, &ep_config_operations, | 1614 | data, &ep_config_operations, |
1615 | &data->dentry); | 1615 | &data->dentry); |
1616 | if (!data->inode) { | 1616 | if (!data->inode) { |
1617 | usb_ep_free_request(ep, data->req); | ||
1617 | kfree (data); | 1618 | kfree (data); |
1618 | goto enomem; | 1619 | goto enomem; |
1619 | } | 1620 | } |
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c index 9a6b5b39b88e..387a18a47ac2 100644 --- a/drivers/video/aty/radeon_base.c +++ b/drivers/video/aty/radeon_base.c | |||
@@ -2265,7 +2265,7 @@ static struct bin_attribute edid2_attr = { | |||
2265 | }; | 2265 | }; |
2266 | 2266 | ||
2267 | 2267 | ||
2268 | static int radeonfb_pci_register (struct pci_dev *pdev, | 2268 | static int __devinit radeonfb_pci_register (struct pci_dev *pdev, |
2269 | const struct pci_device_id *ent) | 2269 | const struct pci_device_id *ent) |
2270 | { | 2270 | { |
2271 | struct fb_info *info; | 2271 | struct fb_info *info; |
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index 8d8eadb64853..372aa1776827 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c | |||
@@ -674,13 +674,19 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
674 | total_size = info->fix.smem_len; | 674 | total_size = info->fix.smem_len; |
675 | 675 | ||
676 | if (p > total_size) | 676 | if (p > total_size) |
677 | return 0; | 677 | return -EFBIG; |
678 | 678 | ||
679 | if (count >= total_size) | 679 | if (count > total_size) { |
680 | err = -EFBIG; | ||
680 | count = total_size; | 681 | count = total_size; |
682 | } | ||
683 | |||
684 | if (count + p > total_size) { | ||
685 | if (!err) | ||
686 | err = -ENOSPC; | ||
681 | 687 | ||
682 | if (count + p > total_size) | ||
683 | count = total_size - p; | 688 | count = total_size - p; |
689 | } | ||
684 | 690 | ||
685 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, | 691 | buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, |
686 | GFP_KERNEL); | 692 | GFP_KERNEL); |
@@ -722,7 +728,7 @@ fb_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | |||
722 | 728 | ||
723 | kfree(buffer); | 729 | kfree(buffer); |
724 | 730 | ||
725 | return (err) ? err : cnt; | 731 | return (cnt) ? cnt : err; |
726 | } | 732 | } |
727 | 733 | ||
728 | #ifdef CONFIG_KMOD | 734 | #ifdef CONFIG_KMOD |
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c index 5fe197943deb..4e963930b50a 100644 --- a/drivers/video/pm2fb.c +++ b/drivers/video/pm2fb.c | |||
@@ -73,8 +73,8 @@ static char *mode __devinitdata = NULL; | |||
73 | * these flags allow the user to specify that requests for +ve sync | 73 | * these flags allow the user to specify that requests for +ve sync |
74 | * should be silently turned in -ve sync. | 74 | * should be silently turned in -ve sync. |
75 | */ | 75 | */ |
76 | static int lowhsync __devinitdata = 0; | 76 | static int lowhsync; |
77 | static int lowvsync __devinitdata = 0; | 77 | static int lowvsync; |
78 | 78 | ||
79 | /* | 79 | /* |
80 | * The hardware state of the graphics card that isn't part of the | 80 | * The hardware state of the graphics card that isn't part of the |
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c index 10e6b3aab9ea..0da624e6524f 100644 --- a/drivers/video/savage/savagefb_driver.c +++ b/drivers/video/savage/savagefb_driver.c | |||
@@ -73,7 +73,7 @@ | |||
73 | /* --------------------------------------------------------------------- */ | 73 | /* --------------------------------------------------------------------- */ |
74 | 74 | ||
75 | 75 | ||
76 | static char *mode_option __initdata = NULL; | 76 | static char *mode_option __devinitdata = NULL; |
77 | 77 | ||
78 | #ifdef MODULE | 78 | #ifdef MODULE |
79 | 79 | ||
@@ -1545,7 +1545,7 @@ static int __devinit savage_map_mmio (struct fb_info *info) | |||
1545 | return 0; | 1545 | return 0; |
1546 | } | 1546 | } |
1547 | 1547 | ||
1548 | static void __devinit savage_unmap_mmio (struct fb_info *info) | 1548 | static void savage_unmap_mmio (struct fb_info *info) |
1549 | { | 1549 | { |
1550 | struct savagefb_par *par = info->par; | 1550 | struct savagefb_par *par = info->par; |
1551 | DBG ("savage_unmap_mmio"); | 1551 | DBG ("savage_unmap_mmio"); |
@@ -1597,7 +1597,7 @@ static int __devinit savage_map_video (struct fb_info *info, | |||
1597 | return 0; | 1597 | return 0; |
1598 | } | 1598 | } |
1599 | 1599 | ||
1600 | static void __devinit savage_unmap_video (struct fb_info *info) | 1600 | static void savage_unmap_video (struct fb_info *info) |
1601 | { | 1601 | { |
1602 | struct savagefb_par *par = info->par; | 1602 | struct savagefb_par *par = info->par; |
1603 | 1603 | ||
@@ -1614,7 +1614,7 @@ static void __devinit savage_unmap_video (struct fb_info *info) | |||
1614 | } | 1614 | } |
1615 | } | 1615 | } |
1616 | 1616 | ||
1617 | static int __devinit savage_init_hw (struct savagefb_par *par) | 1617 | static int savage_init_hw (struct savagefb_par *par) |
1618 | { | 1618 | { |
1619 | unsigned char config1, m, n, n1, n2, sr8, cr3f, cr66 = 0, tmp; | 1619 | unsigned char config1, m, n, n1, n2, sr8, cr3f, cr66 = 0, tmp; |
1620 | 1620 | ||
diff --git a/fs/Kconfig b/fs/Kconfig index 2524629dc835..f9b5842c8d2d 100644 --- a/fs/Kconfig +++ b/fs/Kconfig | |||
@@ -842,6 +842,12 @@ config TMPFS | |||
842 | config HUGETLBFS | 842 | config HUGETLBFS |
843 | bool "HugeTLB file system support" | 843 | bool "HugeTLB file system support" |
844 | depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN | 844 | depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || BROKEN |
845 | help | ||
846 | hugetlbfs is a filesystem backing for HugeTLB pages, based on | ||
847 | ramfs. For architectures that support it, say Y here and read | ||
848 | <file:Documentation/vm/hugetlbpage.txt> for details. | ||
849 | |||
850 | If unsure, say N. | ||
845 | 851 | ||
846 | config HUGETLB_PAGE | 852 | config HUGETLB_PAGE |
847 | def_bool HUGETLBFS | 853 | def_bool HUGETLBFS |
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 8a2de038882e..1a27ecb46c9a 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES | |||
@@ -1,7 +1,11 @@ | |||
1 | Version 1.42 | 1 | Version 1.42 |
2 | ------------ | 2 | ------------ |
3 | Fix slow oplock break when mounted to different servers at the same time and | 3 | Fix slow oplock break when mounted to different servers at the same time and |
4 | the tids match and we try to find matching fid on wrong server. | 4 | the tids match and we try to find matching fid on wrong server. Fix read |
5 | looping when signing required by server (2.6.16 kernel only). Fix readdir | ||
6 | vs. rename race which could cause each to hang. Return . and .. even | ||
7 | if server does not. Allow searches to skip first three entries and | ||
8 | begin at any location. Fix oops in find_writeable_file. | ||
5 | 9 | ||
6 | Version 1.41 | 10 | Version 1.41 |
7 | ------------ | 11 | ------------ |
diff --git a/fs/cifs/README b/fs/cifs/README index b2b4d0803761..0355003f4f0a 100644 --- a/fs/cifs/README +++ b/fs/cifs/README | |||
@@ -511,6 +511,14 @@ LinuxExtensionsEnabled If set to one then the client will attempt to | |||
511 | support and want to map the uid and gid fields | 511 | support and want to map the uid and gid fields |
512 | to values supplied at mount (rather than the | 512 | to values supplied at mount (rather than the |
513 | actual values, then set this to zero. (default 1) | 513 | actual values, then set this to zero. (default 1) |
514 | Experimental When set to 1 used to enable certain experimental | ||
515 | features (currently enables multipage writes | ||
516 | when signing is enabled, the multipage write | ||
517 | performance enhancement was disabled when | ||
518 | signing turned on in case buffer was modified | ||
519 | just before it was sent, also this flag will | ||
520 | be used to use the new experimental sessionsetup | ||
521 | code). | ||
514 | 522 | ||
515 | These experimental features and tracing can be enabled by changing flags in | 523 | These experimental features and tracing can be enabled by changing flags in |
516 | /proc/fs/cifs (after the cifs module has been installed or built into the | 524 | /proc/fs/cifs (after the cifs module has been installed or built into the |
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index d4b713e5affb..c262d8874ce9 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/vfs.h> | 33 | #include <linux/vfs.h> |
34 | #include <linux/mempool.h> | 34 | #include <linux/mempool.h> |
35 | #include <linux/delay.h> | 35 | #include <linux/delay.h> |
36 | #include <linux/kthread.h> | ||
36 | #include "cifsfs.h" | 37 | #include "cifsfs.h" |
37 | #include "cifspdu.h" | 38 | #include "cifspdu.h" |
38 | #define DECLARE_GLOBALS_HERE | 39 | #define DECLARE_GLOBALS_HERE |
@@ -75,9 +76,6 @@ unsigned int cifs_max_pending = CIFS_MAX_REQ; | |||
75 | module_param(cifs_max_pending, int, 0); | 76 | module_param(cifs_max_pending, int, 0); |
76 | MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); | 77 | MODULE_PARM_DESC(cifs_max_pending,"Simultaneous requests to server. Default: 50 Range: 2 to 256"); |
77 | 78 | ||
78 | static DECLARE_COMPLETION(cifs_oplock_exited); | ||
79 | static DECLARE_COMPLETION(cifs_dnotify_exited); | ||
80 | |||
81 | extern mempool_t *cifs_sm_req_poolp; | 79 | extern mempool_t *cifs_sm_req_poolp; |
82 | extern mempool_t *cifs_req_poolp; | 80 | extern mempool_t *cifs_req_poolp; |
83 | extern mempool_t *cifs_mid_poolp; | 81 | extern mempool_t *cifs_mid_poolp; |
@@ -841,10 +839,6 @@ static int cifs_oplock_thread(void * dummyarg) | |||
841 | __u16 netfid; | 839 | __u16 netfid; |
842 | int rc; | 840 | int rc; |
843 | 841 | ||
844 | daemonize("cifsoplockd"); | ||
845 | allow_signal(SIGTERM); | ||
846 | |||
847 | oplockThread = current; | ||
848 | do { | 842 | do { |
849 | if (try_to_freeze()) | 843 | if (try_to_freeze()) |
850 | continue; | 844 | continue; |
@@ -900,9 +894,9 @@ static int cifs_oplock_thread(void * dummyarg) | |||
900 | set_current_state(TASK_INTERRUPTIBLE); | 894 | set_current_state(TASK_INTERRUPTIBLE); |
901 | schedule_timeout(1); /* yield in case q were corrupt */ | 895 | schedule_timeout(1); /* yield in case q were corrupt */ |
902 | } | 896 | } |
903 | } while(!signal_pending(current)); | 897 | } while (!kthread_should_stop()); |
904 | oplockThread = NULL; | 898 | |
905 | complete_and_exit (&cifs_oplock_exited, 0); | 899 | return 0; |
906 | } | 900 | } |
907 | 901 | ||
908 | static int cifs_dnotify_thread(void * dummyarg) | 902 | static int cifs_dnotify_thread(void * dummyarg) |
@@ -910,10 +904,6 @@ static int cifs_dnotify_thread(void * dummyarg) | |||
910 | struct list_head *tmp; | 904 | struct list_head *tmp; |
911 | struct cifsSesInfo *ses; | 905 | struct cifsSesInfo *ses; |
912 | 906 | ||
913 | daemonize("cifsdnotifyd"); | ||
914 | allow_signal(SIGTERM); | ||
915 | |||
916 | dnotifyThread = current; | ||
917 | do { | 907 | do { |
918 | if(try_to_freeze()) | 908 | if(try_to_freeze()) |
919 | continue; | 909 | continue; |
@@ -931,8 +921,9 @@ static int cifs_dnotify_thread(void * dummyarg) | |||
931 | wake_up_all(&ses->server->response_q); | 921 | wake_up_all(&ses->server->response_q); |
932 | } | 922 | } |
933 | read_unlock(&GlobalSMBSeslock); | 923 | read_unlock(&GlobalSMBSeslock); |
934 | } while(!signal_pending(current)); | 924 | } while (!kthread_should_stop()); |
935 | complete_and_exit (&cifs_dnotify_exited, 0); | 925 | |
926 | return 0; | ||
936 | } | 927 | } |
937 | 928 | ||
938 | static int __init | 929 | static int __init |
@@ -982,32 +973,48 @@ init_cifs(void) | |||
982 | } | 973 | } |
983 | 974 | ||
984 | rc = cifs_init_inodecache(); | 975 | rc = cifs_init_inodecache(); |
985 | if (!rc) { | 976 | if (rc) |
986 | rc = cifs_init_mids(); | 977 | goto out_clean_proc; |
987 | if (!rc) { | 978 | |
988 | rc = cifs_init_request_bufs(); | 979 | rc = cifs_init_mids(); |
989 | if (!rc) { | 980 | if (rc) |
990 | rc = register_filesystem(&cifs_fs_type); | 981 | goto out_destroy_inodecache; |
991 | if (!rc) { | 982 | |
992 | rc = (int)kernel_thread(cifs_oplock_thread, NULL, | 983 | rc = cifs_init_request_bufs(); |
993 | CLONE_FS | CLONE_FILES | CLONE_VM); | 984 | if (rc) |
994 | if(rc > 0) { | 985 | goto out_destroy_mids; |
995 | rc = (int)kernel_thread(cifs_dnotify_thread, NULL, | 986 | |
996 | CLONE_FS | CLONE_FILES | CLONE_VM); | 987 | rc = register_filesystem(&cifs_fs_type); |
997 | if(rc > 0) | 988 | if (rc) |
998 | return 0; | 989 | goto out_destroy_request_bufs; |
999 | else | 990 | |
1000 | cERROR(1,("error %d create dnotify thread", rc)); | 991 | oplockThread = kthread_run(cifs_oplock_thread, NULL, "cifsoplockd"); |
1001 | } else { | 992 | if (IS_ERR(oplockThread)) { |
1002 | cERROR(1,("error %d create oplock thread",rc)); | 993 | rc = PTR_ERR(oplockThread); |
1003 | } | 994 | cERROR(1,("error %d create oplock thread", rc)); |
1004 | } | 995 | goto out_unregister_filesystem; |
1005 | cifs_destroy_request_bufs(); | ||
1006 | } | ||
1007 | cifs_destroy_mids(); | ||
1008 | } | ||
1009 | cifs_destroy_inodecache(); | ||
1010 | } | 996 | } |
997 | |||
998 | dnotifyThread = kthread_run(cifs_dnotify_thread, NULL, "cifsdnotifyd"); | ||
999 | if (IS_ERR(dnotifyThread)) { | ||
1000 | rc = PTR_ERR(dnotifyThread); | ||
1001 | cERROR(1,("error %d create dnotify thread", rc)); | ||
1002 | goto out_stop_oplock_thread; | ||
1003 | } | ||
1004 | |||
1005 | return 0; | ||
1006 | |||
1007 | out_stop_oplock_thread: | ||
1008 | kthread_stop(oplockThread); | ||
1009 | out_unregister_filesystem: | ||
1010 | unregister_filesystem(&cifs_fs_type); | ||
1011 | out_destroy_request_bufs: | ||
1012 | cifs_destroy_request_bufs(); | ||
1013 | out_destroy_mids: | ||
1014 | cifs_destroy_mids(); | ||
1015 | out_destroy_inodecache: | ||
1016 | cifs_destroy_inodecache(); | ||
1017 | out_clean_proc: | ||
1011 | #ifdef CONFIG_PROC_FS | 1018 | #ifdef CONFIG_PROC_FS |
1012 | cifs_proc_clean(); | 1019 | cifs_proc_clean(); |
1013 | #endif | 1020 | #endif |
@@ -1025,14 +1032,8 @@ exit_cifs(void) | |||
1025 | cifs_destroy_inodecache(); | 1032 | cifs_destroy_inodecache(); |
1026 | cifs_destroy_mids(); | 1033 | cifs_destroy_mids(); |
1027 | cifs_destroy_request_bufs(); | 1034 | cifs_destroy_request_bufs(); |
1028 | if(oplockThread) { | 1035 | kthread_stop(oplockThread); |
1029 | send_sig(SIGTERM, oplockThread, 1); | 1036 | kthread_stop(dnotifyThread); |
1030 | wait_for_completion(&cifs_oplock_exited); | ||
1031 | } | ||
1032 | if(dnotifyThread) { | ||
1033 | send_sig(SIGTERM, dnotifyThread, 1); | ||
1034 | wait_for_completion(&cifs_dnotify_exited); | ||
1035 | } | ||
1036 | } | 1037 | } |
1037 | 1038 | ||
1038 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); | 1039 | MODULE_AUTHOR("Steve French <sfrench@us.ibm.com>"); |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index d705500aa283..fd36892eda55 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -3119,7 +3119,7 @@ findFirstRetry: | |||
3119 | psrch_inf->endOfSearch = FALSE; | 3119 | psrch_inf->endOfSearch = FALSE; |
3120 | 3120 | ||
3121 | psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); | 3121 | psrch_inf->entries_in_buffer = le16_to_cpu(parms->SearchCount); |
3122 | psrch_inf->index_of_last_entry = | 3122 | psrch_inf->index_of_last_entry = 2 /* skip . and .. */ + |
3123 | psrch_inf->entries_in_buffer; | 3123 | psrch_inf->entries_in_buffer; |
3124 | *pnetfid = parms->SearchHandle; | 3124 | *pnetfid = parms->SearchHandle; |
3125 | } else { | 3125 | } else { |
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 0b86d5ca9014..d2ec806a4f32 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c | |||
@@ -3447,6 +3447,12 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, | |||
3447 | pSesInfo->server->secMode, | 3447 | pSesInfo->server->secMode, |
3448 | pSesInfo->server->capabilities, | 3448 | pSesInfo->server->capabilities, |
3449 | pSesInfo->server->timeZone)); | 3449 | pSesInfo->server->timeZone)); |
3450 | #ifdef CONFIG_CIFS_EXPERIMENTAL | ||
3451 | if(experimEnabled > 1) | ||
3452 | rc = CIFS_SessSetup(xid, pSesInfo, CIFS_NTLM /* type */, | ||
3453 | &ntlmv2_flag, nls_info); | ||
3454 | else | ||
3455 | #endif | ||
3450 | if (extended_security | 3456 | if (extended_security |
3451 | && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) | 3457 | && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY) |
3452 | && (pSesInfo->server->secType == NTLMSSP)) { | 3458 | && (pSesInfo->server->secType == NTLMSSP)) { |
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 1d0ca3eaaca5..82315edc77d7 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c | |||
@@ -139,9 +139,7 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, | |||
139 | cifs_sb = CIFS_SB(inode->i_sb); | 139 | cifs_sb = CIFS_SB(inode->i_sb); |
140 | pTcon = cifs_sb->tcon; | 140 | pTcon = cifs_sb->tcon; |
141 | 141 | ||
142 | mutex_lock(&direntry->d_sb->s_vfs_rename_mutex); | ||
143 | full_path = build_path_from_dentry(direntry); | 142 | full_path = build_path_from_dentry(direntry); |
144 | mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex); | ||
145 | if(full_path == NULL) { | 143 | if(full_path == NULL) { |
146 | FreeXid(xid); | 144 | FreeXid(xid); |
147 | return -ENOMEM; | 145 | return -ENOMEM; |
@@ -316,9 +314,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, | |||
316 | cifs_sb = CIFS_SB(inode->i_sb); | 314 | cifs_sb = CIFS_SB(inode->i_sb); |
317 | pTcon = cifs_sb->tcon; | 315 | pTcon = cifs_sb->tcon; |
318 | 316 | ||
319 | mutex_lock(&direntry->d_sb->s_vfs_rename_mutex); | ||
320 | full_path = build_path_from_dentry(direntry); | 317 | full_path = build_path_from_dentry(direntry); |
321 | mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex); | ||
322 | if(full_path == NULL) | 318 | if(full_path == NULL) |
323 | rc = -ENOMEM; | 319 | rc = -ENOMEM; |
324 | else if (pTcon->ses->capabilities & CAP_UNIX) { | 320 | else if (pTcon->ses->capabilities & CAP_UNIX) { |
@@ -440,6 +436,20 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name | |||
440 | cifs_sb = CIFS_SB(parent_dir_inode->i_sb); | 436 | cifs_sb = CIFS_SB(parent_dir_inode->i_sb); |
441 | pTcon = cifs_sb->tcon; | 437 | pTcon = cifs_sb->tcon; |
442 | 438 | ||
439 | /* | ||
440 | * Don't allow the separator character in a path component. | ||
441 | * The VFS will not allow "/", but "\" is allowed by posix. | ||
442 | */ | ||
443 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)) { | ||
444 | int i; | ||
445 | for (i = 0; i < direntry->d_name.len; i++) | ||
446 | if (direntry->d_name.name[i] == '\\') { | ||
447 | cFYI(1, ("Invalid file name")); | ||
448 | FreeXid(xid); | ||
449 | return ERR_PTR(-EINVAL); | ||
450 | } | ||
451 | } | ||
452 | |||
443 | /* can not grab the rename sem here since it would | 453 | /* can not grab the rename sem here since it would |
444 | deadlock in the cases (beginning of sys_rename itself) | 454 | deadlock in the cases (beginning of sys_rename itself) |
445 | in which we already have the sb rename sem */ | 455 | in which we already have the sb rename sem */ |
diff --git a/fs/cifs/fcntl.c b/fs/cifs/fcntl.c index ec4dfe9bf5ef..633a93811328 100644 --- a/fs/cifs/fcntl.c +++ b/fs/cifs/fcntl.c | |||
@@ -86,9 +86,7 @@ int cifs_dir_notify(struct file * file, unsigned long arg) | |||
86 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 86 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); |
87 | pTcon = cifs_sb->tcon; | 87 | pTcon = cifs_sb->tcon; |
88 | 88 | ||
89 | mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex); | ||
90 | full_path = build_path_from_dentry(file->f_dentry); | 89 | full_path = build_path_from_dentry(file->f_dentry); |
91 | mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex); | ||
92 | 90 | ||
93 | if(full_path == NULL) { | 91 | if(full_path == NULL) { |
94 | rc = -ENOMEM; | 92 | rc = -ENOMEM; |
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 5c497c529772..e152bf6afa60 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c | |||
@@ -203,9 +203,7 @@ int cifs_open(struct inode *inode, struct file *file) | |||
203 | } | 203 | } |
204 | } | 204 | } |
205 | 205 | ||
206 | mutex_lock(&inode->i_sb->s_vfs_rename_mutex); | ||
207 | full_path = build_path_from_dentry(file->f_dentry); | 206 | full_path = build_path_from_dentry(file->f_dentry); |
208 | mutex_unlock(&inode->i_sb->s_vfs_rename_mutex); | ||
209 | if (full_path == NULL) { | 207 | if (full_path == NULL) { |
210 | FreeXid(xid); | 208 | FreeXid(xid); |
211 | return -ENOMEM; | 209 | return -ENOMEM; |
@@ -906,8 +904,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
906 | if (rc != 0) | 904 | if (rc != 0) |
907 | break; | 905 | break; |
908 | } | 906 | } |
909 | /* BB FIXME We can not sign across two buffers yet */ | 907 | if(experimEnabled || (pTcon->ses->server->secMode & |
910 | if((pTcon->ses->server->secMode & | ||
911 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) { | 908 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) == 0) { |
912 | struct kvec iov[2]; | 909 | struct kvec iov[2]; |
913 | unsigned int len; | 910 | unsigned int len; |
@@ -923,13 +920,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data, | |||
923 | *poffset, &bytes_written, | 920 | *poffset, &bytes_written, |
924 | iov, 1, long_op); | 921 | iov, 1, long_op); |
925 | } else | 922 | } else |
926 | /* BB FIXME fixup indentation of line below */ | 923 | rc = CIFSSMBWrite(xid, pTcon, |
927 | rc = CIFSSMBWrite(xid, pTcon, | 924 | open_file->netfid, |
928 | open_file->netfid, | 925 | min_t(const int, cifs_sb->wsize, |
929 | min_t(const int, cifs_sb->wsize, | 926 | write_size - total_written), |
930 | write_size - total_written), | 927 | *poffset, &bytes_written, |
931 | *poffset, &bytes_written, | 928 | write_data + total_written, |
932 | write_data + total_written, NULL, long_op); | 929 | NULL, long_op); |
933 | } | 930 | } |
934 | if (rc || (bytes_written == 0)) { | 931 | if (rc || (bytes_written == 0)) { |
935 | if (total_written) | 932 | if (total_written) |
@@ -968,6 +965,16 @@ struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *cifs_inode) | |||
968 | struct cifsFileInfo *open_file; | 965 | struct cifsFileInfo *open_file; |
969 | int rc; | 966 | int rc; |
970 | 967 | ||
968 | /* Having a null inode here (because mapping->host was set to zero by | ||
969 | the VFS or MM) should not happen but we had reports of on oops (due to | ||
970 | it being zero) during stress testcases so we need to check for it */ | ||
971 | |||
972 | if(cifs_inode == NULL) { | ||
973 | cERROR(1,("Null inode passed to cifs_writeable_file")); | ||
974 | dump_stack(); | ||
975 | return NULL; | ||
976 | } | ||
977 | |||
971 | read_lock(&GlobalSMBSeslock); | 978 | read_lock(&GlobalSMBSeslock); |
972 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { | 979 | list_for_each_entry(open_file, &cifs_inode->openFileList, flist) { |
973 | if (open_file->closePend) | 980 | if (open_file->closePend) |
@@ -1093,12 +1100,11 @@ static int cifs_writepages(struct address_space *mapping, | |||
1093 | if (cifs_sb->wsize < PAGE_CACHE_SIZE) | 1100 | if (cifs_sb->wsize < PAGE_CACHE_SIZE) |
1094 | return generic_writepages(mapping, wbc); | 1101 | return generic_writepages(mapping, wbc); |
1095 | 1102 | ||
1096 | /* BB FIXME we do not have code to sign across multiple buffers yet, | ||
1097 | so go to older writepage style write which we can sign if needed */ | ||
1098 | if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) | 1103 | if((cifs_sb->tcon->ses) && (cifs_sb->tcon->ses->server)) |
1099 | if(cifs_sb->tcon->ses->server->secMode & | 1104 | if(cifs_sb->tcon->ses->server->secMode & |
1100 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) | 1105 | (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) |
1101 | return generic_writepages(mapping, wbc); | 1106 | if(!experimEnabled) |
1107 | return generic_writepages(mapping, wbc); | ||
1102 | 1108 | ||
1103 | /* | 1109 | /* |
1104 | * BB: Is this meaningful for a non-block-device file system? | 1110 | * BB: Is this meaningful for a non-block-device file system? |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 957ddd1571c6..4093764ef461 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -722,9 +722,7 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode) | |||
722 | cifs_sb = CIFS_SB(inode->i_sb); | 722 | cifs_sb = CIFS_SB(inode->i_sb); |
723 | pTcon = cifs_sb->tcon; | 723 | pTcon = cifs_sb->tcon; |
724 | 724 | ||
725 | mutex_lock(&inode->i_sb->s_vfs_rename_mutex); | ||
726 | full_path = build_path_from_dentry(direntry); | 725 | full_path = build_path_from_dentry(direntry); |
727 | mutex_unlock(&inode->i_sb->s_vfs_rename_mutex); | ||
728 | if (full_path == NULL) { | 726 | if (full_path == NULL) { |
729 | FreeXid(xid); | 727 | FreeXid(xid); |
730 | return -ENOMEM; | 728 | return -ENOMEM; |
@@ -807,9 +805,7 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
807 | cifs_sb = CIFS_SB(inode->i_sb); | 805 | cifs_sb = CIFS_SB(inode->i_sb); |
808 | pTcon = cifs_sb->tcon; | 806 | pTcon = cifs_sb->tcon; |
809 | 807 | ||
810 | mutex_lock(&inode->i_sb->s_vfs_rename_mutex); | ||
811 | full_path = build_path_from_dentry(direntry); | 808 | full_path = build_path_from_dentry(direntry); |
812 | mutex_unlock(&inode->i_sb->s_vfs_rename_mutex); | ||
813 | if (full_path == NULL) { | 809 | if (full_path == NULL) { |
814 | FreeXid(xid); | 810 | FreeXid(xid); |
815 | return -ENOMEM; | 811 | return -ENOMEM; |
@@ -1141,9 +1137,7 @@ int cifs_setattr(struct dentry *direntry, struct iattr *attrs) | |||
1141 | rc = 0; | 1137 | rc = 0; |
1142 | } | 1138 | } |
1143 | 1139 | ||
1144 | mutex_lock(&direntry->d_sb->s_vfs_rename_mutex); | ||
1145 | full_path = build_path_from_dentry(direntry); | 1140 | full_path = build_path_from_dentry(direntry); |
1146 | mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex); | ||
1147 | if (full_path == NULL) { | 1141 | if (full_path == NULL) { |
1148 | FreeXid(xid); | 1142 | FreeXid(xid); |
1149 | return -ENOMEM; | 1143 | return -ENOMEM; |
diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 9562f5bba65c..2ec99f833142 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c | |||
@@ -48,10 +48,8 @@ cifs_hardlink(struct dentry *old_file, struct inode *inode, | |||
48 | /* No need to check for cross device links since server will do that | 48 | /* No need to check for cross device links since server will do that |
49 | BB note DFS case in future though (when we may have to check) */ | 49 | BB note DFS case in future though (when we may have to check) */ |
50 | 50 | ||
51 | mutex_lock(&inode->i_sb->s_vfs_rename_mutex); | ||
52 | fromName = build_path_from_dentry(old_file); | 51 | fromName = build_path_from_dentry(old_file); |
53 | toName = build_path_from_dentry(direntry); | 52 | toName = build_path_from_dentry(direntry); |
54 | mutex_unlock(&inode->i_sb->s_vfs_rename_mutex); | ||
55 | if((fromName == NULL) || (toName == NULL)) { | 53 | if((fromName == NULL) || (toName == NULL)) { |
56 | rc = -ENOMEM; | 54 | rc = -ENOMEM; |
57 | goto cifs_hl_exit; | 55 | goto cifs_hl_exit; |
@@ -103,9 +101,7 @@ cifs_follow_link(struct dentry *direntry, struct nameidata *nd) | |||
103 | 101 | ||
104 | xid = GetXid(); | 102 | xid = GetXid(); |
105 | 103 | ||
106 | mutex_lock(&direntry->d_sb->s_vfs_rename_mutex); | ||
107 | full_path = build_path_from_dentry(direntry); | 104 | full_path = build_path_from_dentry(direntry); |
108 | mutex_unlock(&direntry->d_sb->s_vfs_rename_mutex); | ||
109 | 105 | ||
110 | if (!full_path) | 106 | if (!full_path) |
111 | goto out_no_free; | 107 | goto out_no_free; |
@@ -164,9 +160,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname) | |||
164 | cifs_sb = CIFS_SB(inode->i_sb); | 160 | cifs_sb = CIFS_SB(inode->i_sb); |
165 | pTcon = cifs_sb->tcon; | 161 | pTcon = cifs_sb->tcon; |
166 | 162 | ||
167 | mutex_lock(&inode->i_sb->s_vfs_rename_mutex); | ||
168 | full_path = build_path_from_dentry(direntry); | 163 | full_path = build_path_from_dentry(direntry); |
169 | mutex_unlock(&inode->i_sb->s_vfs_rename_mutex); | ||
170 | 164 | ||
171 | if(full_path == NULL) { | 165 | if(full_path == NULL) { |
172 | FreeXid(xid); | 166 | FreeXid(xid); |
diff --git a/fs/cifs/ntlmssp.c b/fs/cifs/ntlmssp.c index 78866f925747..115359cc7a32 100644 --- a/fs/cifs/ntlmssp.c +++ b/fs/cifs/ntlmssp.c | |||
@@ -121,6 +121,20 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, const int type, | |||
121 | } | 121 | } |
122 | 122 | ||
123 | 123 | ||
124 | /* copy session key */ | ||
125 | |||
126 | /* if Unicode, align strings to two byte boundary */ | ||
127 | |||
128 | /* copy user name */ /* BB Do we need to special case null user name? */ | ||
129 | |||
130 | /* copy domain name */ | ||
131 | |||
132 | /* copy Linux version */ | ||
133 | |||
134 | /* copy network operating system name */ | ||
135 | |||
136 | /* update bcc and smb buffer length */ | ||
137 | |||
124 | /* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */ | 138 | /* rc = SendReceive2(xid, ses, iov, num_iovecs, &resp_buf_type, 0); */ |
125 | /* SMB request buf freed in SendReceive2 */ | 139 | /* SMB request buf freed in SendReceive2 */ |
126 | 140 | ||
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c index 2f6e2825571e..b689c5035124 100644 --- a/fs/cifs/readdir.c +++ b/fs/cifs/readdir.c | |||
@@ -404,9 +404,7 @@ static int initiate_cifs_search(const int xid, struct file *file) | |||
404 | if(pTcon == NULL) | 404 | if(pTcon == NULL) |
405 | return -EINVAL; | 405 | return -EINVAL; |
406 | 406 | ||
407 | mutex_lock(&file->f_dentry->d_sb->s_vfs_rename_mutex); | ||
408 | full_path = build_path_from_dentry(file->f_dentry); | 407 | full_path = build_path_from_dentry(file->f_dentry); |
409 | mutex_unlock(&file->f_dentry->d_sb->s_vfs_rename_mutex); | ||
410 | 408 | ||
411 | if(full_path == NULL) { | 409 | if(full_path == NULL) { |
412 | return -ENOMEM; | 410 | return -ENOMEM; |
@@ -592,6 +590,13 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
592 | first_entry_in_buffer = | 590 | first_entry_in_buffer = |
593 | cifsFile->srch_inf.index_of_last_entry - | 591 | cifsFile->srch_inf.index_of_last_entry - |
594 | cifsFile->srch_inf.entries_in_buffer; | 592 | cifsFile->srch_inf.entries_in_buffer; |
593 | |||
594 | /* if first entry in buf is zero then is first buffer | ||
595 | in search response data which means it is likely . and .. | ||
596 | will be in this buffer, although some servers do not return | ||
597 | . and .. for the root of a drive and for those we need | ||
598 | to start two entries earlier */ | ||
599 | |||
595 | /* dump_cifs_file_struct(file, "In fce ");*/ | 600 | /* dump_cifs_file_struct(file, "In fce ");*/ |
596 | if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && | 601 | if(((index_to_find < cifsFile->srch_inf.index_of_last_entry) && |
597 | is_dir_changed(file)) || | 602 | is_dir_changed(file)) || |
@@ -634,23 +639,14 @@ static int find_cifs_entry(const int xid, struct cifsTconInfo *pTcon, | |||
634 | char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + | 639 | char * end_of_smb = cifsFile->srch_inf.ntwrk_buf_start + |
635 | smbCalcSize((struct smb_hdr *) | 640 | smbCalcSize((struct smb_hdr *) |
636 | cifsFile->srch_inf.ntwrk_buf_start); | 641 | cifsFile->srch_inf.ntwrk_buf_start); |
642 | |||
643 | current_entry = cifsFile->srch_inf.srch_entries_start; | ||
637 | first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry | 644 | first_entry_in_buffer = cifsFile->srch_inf.index_of_last_entry |
638 | - cifsFile->srch_inf.entries_in_buffer; | 645 | - cifsFile->srch_inf.entries_in_buffer; |
639 | pos_in_buf = index_to_find - first_entry_in_buffer; | 646 | pos_in_buf = index_to_find - first_entry_in_buffer; |
640 | cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); | 647 | cFYI(1,("found entry - pos_in_buf %d",pos_in_buf)); |
641 | current_entry = cifsFile->srch_inf.srch_entries_start; | ||
642 | for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { | 648 | for(i=0;(i<(pos_in_buf)) && (current_entry != NULL);i++) { |
643 | /* go entry by entry figuring out which is first */ | 649 | /* go entry by entry figuring out which is first */ |
644 | /* if( . or ..) | ||
645 | skip */ | ||
646 | rc = cifs_entry_is_dot(current_entry,cifsFile); | ||
647 | if(rc == 1) /* is . or .. so skip */ { | ||
648 | cFYI(1,("Entry is .")); /* BB removeme BB */ | ||
649 | /* continue; */ | ||
650 | } else if (rc == 2 ) { | ||
651 | cFYI(1,("Entry is ..")); /* BB removeme BB */ | ||
652 | /* continue; */ | ||
653 | } | ||
654 | current_entry = nxt_dir_entry(current_entry,end_of_smb); | 650 | current_entry = nxt_dir_entry(current_entry,end_of_smb); |
655 | } | 651 | } |
656 | if((current_entry == NULL) && (i < pos_in_buf)) { | 652 | if((current_entry == NULL) && (i < pos_in_buf)) { |
@@ -770,6 +766,11 @@ static int cifs_filldir(char *pfindEntry, struct file *file, | |||
770 | if(file->f_dentry == NULL) | 766 | if(file->f_dentry == NULL) |
771 | return -ENOENT; | 767 | return -ENOENT; |
772 | 768 | ||
769 | rc = cifs_entry_is_dot(pfindEntry,pCifsF); | ||
770 | /* skip . and .. since we added them first */ | ||
771 | if(rc != 0) | ||
772 | return 0; | ||
773 | |||
773 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); | 774 | cifs_sb = CIFS_SB(file->f_dentry->d_sb); |
774 | 775 | ||
775 | qstring.name = scratch_buf; | 776 | qstring.name = scratch_buf; |
@@ -898,22 +899,22 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
898 | 899 | ||
899 | switch ((int) file->f_pos) { | 900 | switch ((int) file->f_pos) { |
900 | case 0: | 901 | case 0: |
901 | /*if (filldir(direntry, ".", 1, file->f_pos, | 902 | if (filldir(direntry, ".", 1, file->f_pos, |
902 | file->f_dentry->d_inode->i_ino, DT_DIR) < 0) { | 903 | file->f_dentry->d_inode->i_ino, DT_DIR) < 0) { |
903 | cERROR(1, ("Filldir for current dir failed ")); | 904 | cERROR(1, ("Filldir for current dir failed")); |
904 | rc = -ENOMEM; | 905 | rc = -ENOMEM; |
905 | break; | 906 | break; |
906 | } | 907 | } |
907 | file->f_pos++; */ | 908 | file->f_pos++; |
908 | case 1: | 909 | case 1: |
909 | /* if (filldir(direntry, "..", 2, file->f_pos, | 910 | if (filldir(direntry, "..", 2, file->f_pos, |
910 | file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { | 911 | file->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { |
911 | cERROR(1, ("Filldir for parent dir failed ")); | 912 | cERROR(1, ("Filldir for parent dir failed ")); |
912 | rc = -ENOMEM; | 913 | rc = -ENOMEM; |
913 | break; | 914 | break; |
914 | } | 915 | } |
915 | file->f_pos++; */ | 916 | file->f_pos++; |
916 | case 2: | 917 | default: |
917 | /* 1) If search is active, | 918 | /* 1) If search is active, |
918 | is in current search buffer? | 919 | is in current search buffer? |
919 | if it before then restart search | 920 | if it before then restart search |
@@ -927,7 +928,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
927 | return rc; | 928 | return rc; |
928 | } | 929 | } |
929 | } | 930 | } |
930 | default: | ||
931 | if(file->private_data == NULL) { | 931 | if(file->private_data == NULL) { |
932 | rc = -EINVAL; | 932 | rc = -EINVAL; |
933 | FreeXid(xid); | 933 | FreeXid(xid); |
@@ -947,8 +947,6 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
947 | kfree(cifsFile->search_resume_name); | 947 | kfree(cifsFile->search_resume_name); |
948 | cifsFile->search_resume_name = NULL; */ | 948 | cifsFile->search_resume_name = NULL; */ |
949 | 949 | ||
950 | /* BB account for . and .. in f_pos as special case */ | ||
951 | |||
952 | rc = find_cifs_entry(xid,pTcon, file, | 950 | rc = find_cifs_entry(xid,pTcon, file, |
953 | ¤t_entry,&num_to_fill); | 951 | ¤t_entry,&num_to_fill); |
954 | if(rc) { | 952 | if(rc) { |
@@ -977,7 +975,8 @@ int cifs_readdir(struct file *file, void *direntry, filldir_t filldir) | |||
977 | num_to_fill, i)); | 975 | num_to_fill, i)); |
978 | break; | 976 | break; |
979 | } | 977 | } |
980 | 978 | /* if buggy server returns . and .. late do | |
979 | we want to check for that here? */ | ||
981 | rc = cifs_filldir(current_entry, file, | 980 | rc = cifs_filldir(current_entry, file, |
982 | filldir, direntry,tmp_buf); | 981 | filldir, direntry,tmp_buf); |
983 | file->f_pos++; | 982 | file->f_pos++; |
diff --git a/fs/cifs/xattr.c b/fs/cifs/xattr.c index 3938444d87b2..7754d641775e 100644 --- a/fs/cifs/xattr.c +++ b/fs/cifs/xattr.c | |||
@@ -62,9 +62,7 @@ int cifs_removexattr(struct dentry * direntry, const char * ea_name) | |||
62 | cifs_sb = CIFS_SB(sb); | 62 | cifs_sb = CIFS_SB(sb); |
63 | pTcon = cifs_sb->tcon; | 63 | pTcon = cifs_sb->tcon; |
64 | 64 | ||
65 | mutex_lock(&sb->s_vfs_rename_mutex); | ||
66 | full_path = build_path_from_dentry(direntry); | 65 | full_path = build_path_from_dentry(direntry); |
67 | mutex_unlock(&sb->s_vfs_rename_mutex); | ||
68 | if(full_path == NULL) { | 66 | if(full_path == NULL) { |
69 | FreeXid(xid); | 67 | FreeXid(xid); |
70 | return -ENOMEM; | 68 | return -ENOMEM; |
@@ -116,9 +114,7 @@ int cifs_setxattr(struct dentry * direntry, const char * ea_name, | |||
116 | cifs_sb = CIFS_SB(sb); | 114 | cifs_sb = CIFS_SB(sb); |
117 | pTcon = cifs_sb->tcon; | 115 | pTcon = cifs_sb->tcon; |
118 | 116 | ||
119 | mutex_lock(&sb->s_vfs_rename_mutex); | ||
120 | full_path = build_path_from_dentry(direntry); | 117 | full_path = build_path_from_dentry(direntry); |
121 | mutex_unlock(&sb->s_vfs_rename_mutex); | ||
122 | if(full_path == NULL) { | 118 | if(full_path == NULL) { |
123 | FreeXid(xid); | 119 | FreeXid(xid); |
124 | return -ENOMEM; | 120 | return -ENOMEM; |
@@ -223,9 +219,7 @@ ssize_t cifs_getxattr(struct dentry * direntry, const char * ea_name, | |||
223 | cifs_sb = CIFS_SB(sb); | 219 | cifs_sb = CIFS_SB(sb); |
224 | pTcon = cifs_sb->tcon; | 220 | pTcon = cifs_sb->tcon; |
225 | 221 | ||
226 | mutex_lock(&sb->s_vfs_rename_mutex); | ||
227 | full_path = build_path_from_dentry(direntry); | 222 | full_path = build_path_from_dentry(direntry); |
228 | mutex_unlock(&sb->s_vfs_rename_mutex); | ||
229 | if(full_path == NULL) { | 223 | if(full_path == NULL) { |
230 | FreeXid(xid); | 224 | FreeXid(xid); |
231 | return -ENOMEM; | 225 | return -ENOMEM; |
@@ -341,9 +335,7 @@ ssize_t cifs_listxattr(struct dentry * direntry, char * data, size_t buf_size) | |||
341 | cifs_sb = CIFS_SB(sb); | 335 | cifs_sb = CIFS_SB(sb); |
342 | pTcon = cifs_sb->tcon; | 336 | pTcon = cifs_sb->tcon; |
343 | 337 | ||
344 | mutex_lock(&sb->s_vfs_rename_mutex); | ||
345 | full_path = build_path_from_dentry(direntry); | 338 | full_path = build_path_from_dentry(direntry); |
346 | mutex_unlock(&sb->s_vfs_rename_mutex); | ||
347 | if(full_path == NULL) { | 339 | if(full_path == NULL) { |
348 | FreeXid(xid); | 340 | FreeXid(xid); |
349 | return -ENOMEM; | 341 | return -ENOMEM; |
diff --git a/fs/compat.c b/fs/compat.c index 7f8e26ea427c..2e32bd340474 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1217,6 +1217,10 @@ static ssize_t compat_do_readv_writev(int type, struct file *file, | |||
1217 | if (ret < 0) | 1217 | if (ret < 0) |
1218 | goto out; | 1218 | goto out; |
1219 | 1219 | ||
1220 | ret = security_file_permission(file, type == READ ? MAY_READ:MAY_WRITE); | ||
1221 | if (ret) | ||
1222 | goto out; | ||
1223 | |||
1220 | fnv = NULL; | 1224 | fnv = NULL; |
1221 | if (type == READ) { | 1225 | if (type == READ) { |
1222 | fn = file->f_op->read; | 1226 | fn = file->f_op->read; |
@@ -712,7 +712,7 @@ static int de_thread(struct task_struct *tsk) | |||
712 | attach_pid(current, PIDTYPE_PID, current->pid); | 712 | attach_pid(current, PIDTYPE_PID, current->pid); |
713 | attach_pid(current, PIDTYPE_PGID, current->signal->pgrp); | 713 | attach_pid(current, PIDTYPE_PGID, current->signal->pgrp); |
714 | attach_pid(current, PIDTYPE_SID, current->signal->session); | 714 | attach_pid(current, PIDTYPE_SID, current->signal->session); |
715 | list_add_tail(¤t->tasks, &init_task.tasks); | 715 | list_add_tail_rcu(¤t->tasks, &init_task.tasks); |
716 | 716 | ||
717 | current->group_leader = current; | 717 | current->group_leader = current; |
718 | leader->group_leader = current; | 718 | leader->group_leader = current; |
diff --git a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c index aaf1da17b6d4..8c22aa9a7fbb 100644 --- a/fs/ext3/ioctl.c +++ b/fs/ext3/ioctl.c | |||
@@ -48,6 +48,7 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
48 | if (!S_ISDIR(inode->i_mode)) | 48 | if (!S_ISDIR(inode->i_mode)) |
49 | flags &= ~EXT3_DIRSYNC_FL; | 49 | flags &= ~EXT3_DIRSYNC_FL; |
50 | 50 | ||
51 | mutex_lock(&inode->i_mutex); | ||
51 | oldflags = ei->i_flags; | 52 | oldflags = ei->i_flags; |
52 | 53 | ||
53 | /* The JOURNAL_DATA flag is modifiable only by root */ | 54 | /* The JOURNAL_DATA flag is modifiable only by root */ |
@@ -60,8 +61,10 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
60 | * This test looks nicer. Thanks to Pauline Middelink | 61 | * This test looks nicer. Thanks to Pauline Middelink |
61 | */ | 62 | */ |
62 | if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) { | 63 | if ((flags ^ oldflags) & (EXT3_APPEND_FL | EXT3_IMMUTABLE_FL)) { |
63 | if (!capable(CAP_LINUX_IMMUTABLE)) | 64 | if (!capable(CAP_LINUX_IMMUTABLE)) { |
65 | mutex_unlock(&inode->i_mutex); | ||
64 | return -EPERM; | 66 | return -EPERM; |
67 | } | ||
65 | } | 68 | } |
66 | 69 | ||
67 | /* | 70 | /* |
@@ -69,14 +72,18 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
69 | * the relevant capability. | 72 | * the relevant capability. |
70 | */ | 73 | */ |
71 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) { | 74 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) { |
72 | if (!capable(CAP_SYS_RESOURCE)) | 75 | if (!capable(CAP_SYS_RESOURCE)) { |
76 | mutex_unlock(&inode->i_mutex); | ||
73 | return -EPERM; | 77 | return -EPERM; |
78 | } | ||
74 | } | 79 | } |
75 | 80 | ||
76 | 81 | ||
77 | handle = ext3_journal_start(inode, 1); | 82 | handle = ext3_journal_start(inode, 1); |
78 | if (IS_ERR(handle)) | 83 | if (IS_ERR(handle)) { |
84 | mutex_unlock(&inode->i_mutex); | ||
79 | return PTR_ERR(handle); | 85 | return PTR_ERR(handle); |
86 | } | ||
80 | if (IS_SYNC(inode)) | 87 | if (IS_SYNC(inode)) |
81 | handle->h_sync = 1; | 88 | handle->h_sync = 1; |
82 | err = ext3_reserve_inode_write(handle, inode, &iloc); | 89 | err = ext3_reserve_inode_write(handle, inode, &iloc); |
@@ -93,11 +100,14 @@ int ext3_ioctl (struct inode * inode, struct file * filp, unsigned int cmd, | |||
93 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); | 100 | err = ext3_mark_iloc_dirty(handle, inode, &iloc); |
94 | flags_err: | 101 | flags_err: |
95 | ext3_journal_stop(handle); | 102 | ext3_journal_stop(handle); |
96 | if (err) | 103 | if (err) { |
104 | mutex_unlock(&inode->i_mutex); | ||
97 | return err; | 105 | return err; |
106 | } | ||
98 | 107 | ||
99 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) | 108 | if ((jflag ^ oldflags) & (EXT3_JOURNAL_DATA_FL)) |
100 | err = ext3_change_inode_journal_flag(inode, jflag); | 109 | err = ext3_change_inode_journal_flag(inode, jflag); |
110 | mutex_unlock(&inode->i_mutex); | ||
101 | return err; | 111 | return err; |
102 | } | 112 | } |
103 | case EXT3_IOC_GETVERSION: | 113 | case EXT3_IOC_GETVERSION: |
diff --git a/fs/ext3/resize.c b/fs/ext3/resize.c index c5ffa8523968..8aac5334680d 100644 --- a/fs/ext3/resize.c +++ b/fs/ext3/resize.c | |||
@@ -213,7 +213,7 @@ static int setup_new_group_blocks(struct super_block *sb, | |||
213 | goto exit_bh; | 213 | goto exit_bh; |
214 | } | 214 | } |
215 | lock_buffer(bh); | 215 | lock_buffer(bh); |
216 | memcpy(gdb->b_data, sbi->s_group_desc[i], bh->b_size); | 216 | memcpy(gdb->b_data, sbi->s_group_desc[i]->b_data, bh->b_size); |
217 | set_buffer_uptodate(gdb); | 217 | set_buffer_uptodate(gdb); |
218 | unlock_buffer(bh); | 218 | unlock_buffer(bh); |
219 | ext3_journal_dirty_metadata(handle, gdb); | 219 | ext3_journal_dirty_metadata(handle, gdb); |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index cc750c68fe70..104a62dadb94 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -128,14 +128,24 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req) | |||
128 | } | 128 | } |
129 | } | 129 | } |
130 | 130 | ||
131 | void fuse_remove_background(struct fuse_conn *fc, struct fuse_req *req) | 131 | /* |
132 | * Called with sbput_sem held for read (request_end) or write | ||
133 | * (fuse_put_super). By the time fuse_put_super() is finished, all | ||
134 | * inodes belonging to background requests must be released, so the | ||
135 | * iputs have to be done within the locked region. | ||
136 | */ | ||
137 | void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req) | ||
132 | { | 138 | { |
133 | list_del_init(&req->bg_entry); | 139 | iput(req->inode); |
140 | iput(req->inode2); | ||
141 | spin_lock(&fc->lock); | ||
142 | list_del(&req->bg_entry); | ||
134 | if (fc->num_background == FUSE_MAX_BACKGROUND) { | 143 | if (fc->num_background == FUSE_MAX_BACKGROUND) { |
135 | fc->blocked = 0; | 144 | fc->blocked = 0; |
136 | wake_up_all(&fc->blocked_waitq); | 145 | wake_up_all(&fc->blocked_waitq); |
137 | } | 146 | } |
138 | fc->num_background--; | 147 | fc->num_background--; |
148 | spin_unlock(&fc->lock); | ||
139 | } | 149 | } |
140 | 150 | ||
141 | /* | 151 | /* |
@@ -165,27 +175,22 @@ static void request_end(struct fuse_conn *fc, struct fuse_req *req) | |||
165 | wake_up(&req->waitq); | 175 | wake_up(&req->waitq); |
166 | fuse_put_request(fc, req); | 176 | fuse_put_request(fc, req); |
167 | } else { | 177 | } else { |
168 | struct inode *inode = req->inode; | ||
169 | struct inode *inode2 = req->inode2; | ||
170 | struct file *file = req->file; | ||
171 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; | 178 | void (*end) (struct fuse_conn *, struct fuse_req *) = req->end; |
172 | req->end = NULL; | 179 | req->end = NULL; |
173 | req->inode = NULL; | ||
174 | req->inode2 = NULL; | ||
175 | req->file = NULL; | ||
176 | if (!list_empty(&req->bg_entry)) | ||
177 | fuse_remove_background(fc, req); | ||
178 | spin_unlock(&fc->lock); | 180 | spin_unlock(&fc->lock); |
181 | down_read(&fc->sbput_sem); | ||
182 | if (fc->mounted) | ||
183 | fuse_release_background(fc, req); | ||
184 | up_read(&fc->sbput_sem); | ||
185 | |||
186 | /* fput must go outside sbput_sem, otherwise it can deadlock */ | ||
187 | if (req->file) | ||
188 | fput(req->file); | ||
179 | 189 | ||
180 | if (end) | 190 | if (end) |
181 | end(fc, req); | 191 | end(fc, req); |
182 | else | 192 | else |
183 | fuse_put_request(fc, req); | 193 | fuse_put_request(fc, req); |
184 | |||
185 | if (file) | ||
186 | fput(file); | ||
187 | iput(inode); | ||
188 | iput(inode2); | ||
189 | } | 194 | } |
190 | } | 195 | } |
191 | 196 | ||
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 59661c481d9d..0474202cb5dc 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -258,9 +258,15 @@ struct fuse_conn { | |||
258 | /** waitq for blocked connection */ | 258 | /** waitq for blocked connection */ |
259 | wait_queue_head_t blocked_waitq; | 259 | wait_queue_head_t blocked_waitq; |
260 | 260 | ||
261 | /** RW semaphore for exclusion with fuse_put_super() */ | ||
262 | struct rw_semaphore sbput_sem; | ||
263 | |||
261 | /** The next unique request id */ | 264 | /** The next unique request id */ |
262 | u64 reqctr; | 265 | u64 reqctr; |
263 | 266 | ||
267 | /** Mount is active */ | ||
268 | unsigned mounted; | ||
269 | |||
264 | /** Connection established, cleared on umount, connection | 270 | /** Connection established, cleared on umount, connection |
265 | abort and device release */ | 271 | abort and device release */ |
266 | unsigned connected; | 272 | unsigned connected; |
@@ -471,11 +477,11 @@ void request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); | |||
471 | void request_send_background(struct fuse_conn *fc, struct fuse_req *req); | 477 | void request_send_background(struct fuse_conn *fc, struct fuse_req *req); |
472 | 478 | ||
473 | /** | 479 | /** |
474 | * Remove request from the the background list | 480 | * Release inodes and file associated with background request |
475 | */ | 481 | */ |
476 | void fuse_remove_background(struct fuse_conn *fc, struct fuse_req *req); | 482 | void fuse_release_background(struct fuse_conn *fc, struct fuse_req *req); |
477 | 483 | ||
478 | /** Abort all requests */ | 484 | /* Abort all requests */ |
479 | void fuse_abort_conn(struct fuse_conn *fc); | 485 | void fuse_abort_conn(struct fuse_conn *fc); |
480 | 486 | ||
481 | /** | 487 | /** |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 43a6fc0db8a7..7627022446b2 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -204,26 +204,17 @@ static void fuse_put_super(struct super_block *sb) | |||
204 | { | 204 | { |
205 | struct fuse_conn *fc = get_fuse_conn_super(sb); | 205 | struct fuse_conn *fc = get_fuse_conn_super(sb); |
206 | 206 | ||
207 | down_write(&fc->sbput_sem); | ||
208 | while (!list_empty(&fc->background)) | ||
209 | fuse_release_background(fc, | ||
210 | list_entry(fc->background.next, | ||
211 | struct fuse_req, bg_entry)); | ||
212 | |||
207 | spin_lock(&fc->lock); | 213 | spin_lock(&fc->lock); |
214 | fc->mounted = 0; | ||
208 | fc->connected = 0; | 215 | fc->connected = 0; |
209 | while (!list_empty(&fc->background)) { | ||
210 | struct fuse_req *req = list_entry(fc->background.next, | ||
211 | struct fuse_req, bg_entry); | ||
212 | struct inode *inode = req->inode; | ||
213 | struct inode *inode2 = req->inode2; | ||
214 | |||
215 | /* File would hold a reference to vfsmount */ | ||
216 | BUG_ON(req->file); | ||
217 | req->inode = NULL; | ||
218 | req->inode2 = NULL; | ||
219 | fuse_remove_background(fc, req); | ||
220 | |||
221 | spin_unlock(&fc->lock); | ||
222 | iput(inode); | ||
223 | iput(inode2); | ||
224 | spin_lock(&fc->lock); | ||
225 | } | ||
226 | spin_unlock(&fc->lock); | 216 | spin_unlock(&fc->lock); |
217 | up_write(&fc->sbput_sem); | ||
227 | /* Flush all readers on this fs */ | 218 | /* Flush all readers on this fs */ |
228 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); | 219 | kill_fasync(&fc->fasync, SIGIO, POLL_IN); |
229 | wake_up_all(&fc->waitq); | 220 | wake_up_all(&fc->waitq); |
@@ -395,6 +386,7 @@ static struct fuse_conn *new_conn(void) | |||
395 | INIT_LIST_HEAD(&fc->processing); | 386 | INIT_LIST_HEAD(&fc->processing); |
396 | INIT_LIST_HEAD(&fc->io); | 387 | INIT_LIST_HEAD(&fc->io); |
397 | INIT_LIST_HEAD(&fc->background); | 388 | INIT_LIST_HEAD(&fc->background); |
389 | init_rwsem(&fc->sbput_sem); | ||
398 | kobj_set_kset_s(fc, connections_subsys); | 390 | kobj_set_kset_s(fc, connections_subsys); |
399 | kobject_init(&fc->kobj); | 391 | kobject_init(&fc->kobj); |
400 | atomic_set(&fc->num_waiting, 0); | 392 | atomic_set(&fc->num_waiting, 0); |
@@ -508,11 +500,6 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
508 | if (file->f_op != &fuse_dev_operations) | 500 | if (file->f_op != &fuse_dev_operations) |
509 | return -EINVAL; | 501 | return -EINVAL; |
510 | 502 | ||
511 | /* Setting file->private_data can't race with other mount() | ||
512 | instances, since BKL is held for ->get_sb() */ | ||
513 | if (file->private_data) | ||
514 | return -EINVAL; | ||
515 | |||
516 | fc = new_conn(); | 503 | fc = new_conn(); |
517 | if (!fc) | 504 | if (!fc) |
518 | return -ENOMEM; | 505 | return -ENOMEM; |
@@ -548,7 +535,14 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
548 | if (err) | 535 | if (err) |
549 | goto err_free_req; | 536 | goto err_free_req; |
550 | 537 | ||
538 | /* Setting file->private_data can't race with other mount() | ||
539 | instances, since BKL is held for ->get_sb() */ | ||
540 | err = -EINVAL; | ||
541 | if (file->private_data) | ||
542 | goto err_kobject_del; | ||
543 | |||
551 | sb->s_root = root_dentry; | 544 | sb->s_root = root_dentry; |
545 | fc->mounted = 1; | ||
552 | fc->connected = 1; | 546 | fc->connected = 1; |
553 | kobject_get(&fc->kobj); | 547 | kobject_get(&fc->kobj); |
554 | file->private_data = fc; | 548 | file->private_data = fc; |
@@ -563,6 +557,8 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
563 | 557 | ||
564 | return 0; | 558 | return 0; |
565 | 559 | ||
560 | err_kobject_del: | ||
561 | kobject_del(&fc->kobj); | ||
566 | err_free_req: | 562 | err_free_req: |
567 | fuse_request_free(init_req); | 563 | fuse_request_free(init_req); |
568 | err_put_root: | 564 | err_put_root: |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index d2b66bad7d50..3ef739120dff 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
@@ -650,7 +650,7 @@ static void nlmsvc_grant_callback(struct rpc_task *task, void *data) | |||
650 | svc_wake_up(block->b_daemon); | 650 | svc_wake_up(block->b_daemon); |
651 | } | 651 | } |
652 | 652 | ||
653 | void nlmsvc_grant_release(void *data) | 653 | static void nlmsvc_grant_release(void *data) |
654 | { | 654 | { |
655 | struct nlm_rqst *call = data; | 655 | struct nlm_rqst *call = data; |
656 | 656 | ||
diff --git a/fs/locks.c b/fs/locks.c index dda83d6cd48b..efad798824dc 100644 --- a/fs/locks.c +++ b/fs/locks.c | |||
@@ -2230,7 +2230,12 @@ void steal_locks(fl_owner_t from) | |||
2230 | 2230 | ||
2231 | lock_kernel(); | 2231 | lock_kernel(); |
2232 | j = 0; | 2232 | j = 0; |
2233 | rcu_read_lock(); | 2233 | |
2234 | /* | ||
2235 | * We are not taking a ref to the file structures, so | ||
2236 | * we need to acquire ->file_lock. | ||
2237 | */ | ||
2238 | spin_lock(&files->file_lock); | ||
2234 | fdt = files_fdtable(files); | 2239 | fdt = files_fdtable(files); |
2235 | for (;;) { | 2240 | for (;;) { |
2236 | unsigned long set; | 2241 | unsigned long set; |
@@ -2248,7 +2253,7 @@ void steal_locks(fl_owner_t from) | |||
2248 | set >>= 1; | 2253 | set >>= 1; |
2249 | } | 2254 | } |
2250 | } | 2255 | } |
2251 | rcu_read_unlock(); | 2256 | spin_unlock(&files->file_lock); |
2252 | unlock_kernel(); | 2257 | unlock_kernel(); |
2253 | } | 2258 | } |
2254 | EXPORT_SYMBOL(steal_locks); | 2259 | EXPORT_SYMBOL(steal_locks); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index a23f34894167..cae74dd4c7f5 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -128,15 +128,14 @@ struct inode_operations nfs4_dir_inode_operations = { | |||
128 | static int | 128 | static int |
129 | nfs_opendir(struct inode *inode, struct file *filp) | 129 | nfs_opendir(struct inode *inode, struct file *filp) |
130 | { | 130 | { |
131 | int res = 0; | 131 | int res; |
132 | 132 | ||
133 | dfprintk(VFS, "NFS: opendir(%s/%ld)\n", | 133 | dfprintk(VFS, "NFS: opendir(%s/%ld)\n", |
134 | inode->i_sb->s_id, inode->i_ino); | 134 | inode->i_sb->s_id, inode->i_ino); |
135 | 135 | ||
136 | lock_kernel(); | 136 | lock_kernel(); |
137 | /* Call generic open code in order to cache credentials */ | 137 | /* Call generic open code in order to cache credentials */ |
138 | if (!res) | 138 | res = nfs_open(inode, filp); |
139 | res = nfs_open(inode, filp); | ||
140 | unlock_kernel(); | 139 | unlock_kernel(); |
141 | return res; | 140 | return res; |
142 | } | 141 | } |
diff --git a/fs/nfs/direct.c b/fs/nfs/direct.c index 0f583cb16ddb..3c72b0c07283 100644 --- a/fs/nfs/direct.c +++ b/fs/nfs/direct.c | |||
@@ -112,10 +112,9 @@ static void nfs_direct_write_complete(struct nfs_direct_req *dreq, struct inode | |||
112 | */ | 112 | */ |
113 | ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs) | 113 | ssize_t nfs_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov, loff_t pos, unsigned long nr_segs) |
114 | { | 114 | { |
115 | struct dentry *dentry = iocb->ki_filp->f_dentry; | ||
116 | |||
117 | dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n", | 115 | dprintk("NFS: nfs_direct_IO (%s) off/no(%Ld/%lu) EINVAL\n", |
118 | dentry->d_name.name, (long long) pos, nr_segs); | 116 | iocb->ki_filp->f_dentry->d_name.name, |
117 | (long long) pos, nr_segs); | ||
119 | 118 | ||
120 | return -EINVAL; | 119 | return -EINVAL; |
121 | } | 120 | } |
@@ -468,7 +467,6 @@ static const struct rpc_call_ops nfs_commit_direct_ops = { | |||
468 | static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | 467 | static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) |
469 | { | 468 | { |
470 | struct nfs_write_data *data = dreq->commit_data; | 469 | struct nfs_write_data *data = dreq->commit_data; |
471 | struct rpc_task *task = &data->task; | ||
472 | 470 | ||
473 | data->inode = dreq->inode; | 471 | data->inode = dreq->inode; |
474 | data->cred = dreq->ctx->cred; | 472 | data->cred = dreq->ctx->cred; |
@@ -489,7 +487,7 @@ static void nfs_direct_commit_schedule(struct nfs_direct_req *dreq) | |||
489 | /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ | 487 | /* Note: task.tk_ops->rpc_release will free dreq->commit_data */ |
490 | dreq->commit_data = NULL; | 488 | dreq->commit_data = NULL; |
491 | 489 | ||
492 | dprintk("NFS: %5u initiated commit call\n", task->tk_pid); | 490 | dprintk("NFS: %5u initiated commit call\n", data->task.tk_pid); |
493 | 491 | ||
494 | lock_kernel(); | 492 | lock_kernel(); |
495 | rpc_execute(&data->task); | 493 | rpc_execute(&data->task); |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index f1df2c8d9259..fade02c15e6e 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -534,10 +534,9 @@ static int nfs_lock(struct file *filp, int cmd, struct file_lock *fl) | |||
534 | */ | 534 | */ |
535 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) | 535 | static int nfs_flock(struct file *filp, int cmd, struct file_lock *fl) |
536 | { | 536 | { |
537 | struct inode * inode = filp->f_mapping->host; | ||
538 | |||
539 | dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n", | 537 | dprintk("NFS: nfs_flock(f=%s/%ld, t=%x, fl=%x)\n", |
540 | inode->i_sb->s_id, inode->i_ino, | 538 | filp->f_dentry->d_inode->i_sb->s_id, |
539 | filp->f_dentry->d_inode->i_ino, | ||
541 | fl->fl_type, fl->fl_flags); | 540 | fl->fl_type, fl->fl_flags); |
542 | 541 | ||
543 | /* | 542 | /* |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 2f7656b911b6..d0b991a92327 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -700,12 +700,9 @@ static int nfs_show_stats(struct seq_file *m, struct vfsmount *mnt) | |||
700 | /* | 700 | /* |
701 | * Display superblock I/O counters | 701 | * Display superblock I/O counters |
702 | */ | 702 | */ |
703 | for (cpu = 0; cpu < NR_CPUS; cpu++) { | 703 | for_each_possible_cpu(cpu) { |
704 | struct nfs_iostats *stats; | 704 | struct nfs_iostats *stats; |
705 | 705 | ||
706 | if (!cpu_possible(cpu)) | ||
707 | continue; | ||
708 | |||
709 | preempt_disable(); | 706 | preempt_disable(); |
710 | stats = per_cpu_ptr(nfss->io_stats, cpu); | 707 | stats = per_cpu_ptr(nfss->io_stats, cpu); |
711 | 708 | ||
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 47ece1dd3c67..d86c0db7b1e8 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1218,7 +1218,7 @@ out: | |||
1218 | return status; | 1218 | return status; |
1219 | } | 1219 | } |
1220 | 1220 | ||
1221 | static void nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state) | 1221 | static int nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, struct nfs4_state *state) |
1222 | { | 1222 | { |
1223 | struct file *filp; | 1223 | struct file *filp; |
1224 | 1224 | ||
@@ -1227,8 +1227,10 @@ static void nfs4_intent_set_file(struct nameidata *nd, struct dentry *dentry, st | |||
1227 | struct nfs_open_context *ctx; | 1227 | struct nfs_open_context *ctx; |
1228 | ctx = (struct nfs_open_context *)filp->private_data; | 1228 | ctx = (struct nfs_open_context *)filp->private_data; |
1229 | ctx->state = state; | 1229 | ctx->state = state; |
1230 | } else | 1230 | return 0; |
1231 | nfs4_close_state(state, nd->intent.open.flags); | 1231 | } |
1232 | nfs4_close_state(state, nd->intent.open.flags); | ||
1233 | return PTR_ERR(filp); | ||
1232 | } | 1234 | } |
1233 | 1235 | ||
1234 | struct dentry * | 1236 | struct dentry * |
@@ -1835,7 +1837,7 @@ nfs4_proc_create(struct inode *dir, struct dentry *dentry, struct iattr *sattr, | |||
1835 | nfs_setattr_update_inode(state->inode, sattr); | 1837 | nfs_setattr_update_inode(state->inode, sattr); |
1836 | } | 1838 | } |
1837 | if (status == 0 && nd != NULL && (nd->flags & LOOKUP_OPEN)) | 1839 | if (status == 0 && nd != NULL && (nd->flags & LOOKUP_OPEN)) |
1838 | nfs4_intent_set_file(nd, dentry, state); | 1840 | status = nfs4_intent_set_file(nd, dentry, state); |
1839 | else | 1841 | else |
1840 | nfs4_close_state(state, flags); | 1842 | nfs4_close_state(state, flags); |
1841 | out: | 1843 | out: |
@@ -331,7 +331,10 @@ out: | |||
331 | 331 | ||
332 | asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) | 332 | asmlinkage long sys_ftruncate(unsigned int fd, unsigned long length) |
333 | { | 333 | { |
334 | return do_sys_ftruncate(fd, length, 1); | 334 | long ret = do_sys_ftruncate(fd, length, 1); |
335 | /* avoid REGPARM breakage on x86: */ | ||
336 | prevent_tail_call(ret); | ||
337 | return ret; | ||
335 | } | 338 | } |
336 | 339 | ||
337 | /* LFS versions of truncate are only needed on 32 bit machines */ | 340 | /* LFS versions of truncate are only needed on 32 bit machines */ |
@@ -343,7 +346,10 @@ asmlinkage long sys_truncate64(const char __user * path, loff_t length) | |||
343 | 346 | ||
344 | asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) | 347 | asmlinkage long sys_ftruncate64(unsigned int fd, loff_t length) |
345 | { | 348 | { |
346 | return do_sys_ftruncate(fd, length, 0); | 349 | long ret = do_sys_ftruncate(fd, length, 0); |
350 | /* avoid REGPARM breakage on x86: */ | ||
351 | prevent_tail_call(ret); | ||
352 | return ret; | ||
347 | } | 353 | } |
348 | #endif | 354 | #endif |
349 | 355 | ||
@@ -1093,20 +1099,30 @@ long do_sys_open(int dfd, const char __user *filename, int flags, int mode) | |||
1093 | 1099 | ||
1094 | asmlinkage long sys_open(const char __user *filename, int flags, int mode) | 1100 | asmlinkage long sys_open(const char __user *filename, int flags, int mode) |
1095 | { | 1101 | { |
1102 | long ret; | ||
1103 | |||
1096 | if (force_o_largefile()) | 1104 | if (force_o_largefile()) |
1097 | flags |= O_LARGEFILE; | 1105 | flags |= O_LARGEFILE; |
1098 | 1106 | ||
1099 | return do_sys_open(AT_FDCWD, filename, flags, mode); | 1107 | ret = do_sys_open(AT_FDCWD, filename, flags, mode); |
1108 | /* avoid REGPARM breakage on x86: */ | ||
1109 | prevent_tail_call(ret); | ||
1110 | return ret; | ||
1100 | } | 1111 | } |
1101 | EXPORT_SYMBOL_GPL(sys_open); | 1112 | EXPORT_SYMBOL_GPL(sys_open); |
1102 | 1113 | ||
1103 | asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, | 1114 | asmlinkage long sys_openat(int dfd, const char __user *filename, int flags, |
1104 | int mode) | 1115 | int mode) |
1105 | { | 1116 | { |
1117 | long ret; | ||
1118 | |||
1106 | if (force_o_largefile()) | 1119 | if (force_o_largefile()) |
1107 | flags |= O_LARGEFILE; | 1120 | flags |= O_LARGEFILE; |
1108 | 1121 | ||
1109 | return do_sys_open(dfd, filename, flags, mode); | 1122 | ret = do_sys_open(dfd, filename, flags, mode); |
1123 | /* avoid REGPARM breakage on x86: */ | ||
1124 | prevent_tail_call(ret); | ||
1125 | return ret; | ||
1110 | } | 1126 | } |
1111 | EXPORT_SYMBOL_GPL(sys_openat); | 1127 | EXPORT_SYMBOL_GPL(sys_openat); |
1112 | 1128 | ||
diff --git a/fs/proc/base.c b/fs/proc/base.c index a3a3eecef689..6cc77dc3f3ff 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -297,16 +297,20 @@ static int proc_fd_link(struct inode *inode, struct dentry **dentry, struct vfsm | |||
297 | 297 | ||
298 | files = get_files_struct(task); | 298 | files = get_files_struct(task); |
299 | if (files) { | 299 | if (files) { |
300 | rcu_read_lock(); | 300 | /* |
301 | * We are not taking a ref to the file structure, so we must | ||
302 | * hold ->file_lock. | ||
303 | */ | ||
304 | spin_lock(&files->file_lock); | ||
301 | file = fcheck_files(files, fd); | 305 | file = fcheck_files(files, fd); |
302 | if (file) { | 306 | if (file) { |
303 | *mnt = mntget(file->f_vfsmnt); | 307 | *mnt = mntget(file->f_vfsmnt); |
304 | *dentry = dget(file->f_dentry); | 308 | *dentry = dget(file->f_dentry); |
305 | rcu_read_unlock(); | 309 | spin_unlock(&files->file_lock); |
306 | put_files_struct(files); | 310 | put_files_struct(files); |
307 | return 0; | 311 | return 0; |
308 | } | 312 | } |
309 | rcu_read_unlock(); | 313 | spin_unlock(&files->file_lock); |
310 | put_files_struct(files); | 314 | put_files_struct(files); |
311 | } | 315 | } |
312 | return -ENOENT; | 316 | return -ENOENT; |
@@ -1523,7 +1527,12 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1523 | if (!files) | 1527 | if (!files) |
1524 | goto out_unlock; | 1528 | goto out_unlock; |
1525 | inode->i_mode = S_IFLNK; | 1529 | inode->i_mode = S_IFLNK; |
1526 | rcu_read_lock(); | 1530 | |
1531 | /* | ||
1532 | * We are not taking a ref to the file structure, so we must | ||
1533 | * hold ->file_lock. | ||
1534 | */ | ||
1535 | spin_lock(&files->file_lock); | ||
1527 | file = fcheck_files(files, fd); | 1536 | file = fcheck_files(files, fd); |
1528 | if (!file) | 1537 | if (!file) |
1529 | goto out_unlock2; | 1538 | goto out_unlock2; |
@@ -1531,7 +1540,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1531 | inode->i_mode |= S_IRUSR | S_IXUSR; | 1540 | inode->i_mode |= S_IRUSR | S_IXUSR; |
1532 | if (file->f_mode & 2) | 1541 | if (file->f_mode & 2) |
1533 | inode->i_mode |= S_IWUSR | S_IXUSR; | 1542 | inode->i_mode |= S_IWUSR | S_IXUSR; |
1534 | rcu_read_unlock(); | 1543 | spin_unlock(&files->file_lock); |
1535 | put_files_struct(files); | 1544 | put_files_struct(files); |
1536 | inode->i_op = &proc_pid_link_inode_operations; | 1545 | inode->i_op = &proc_pid_link_inode_operations; |
1537 | inode->i_size = 64; | 1546 | inode->i_size = 64; |
@@ -1541,7 +1550,7 @@ static struct dentry *proc_lookupfd(struct inode * dir, struct dentry * dentry, | |||
1541 | return NULL; | 1550 | return NULL; |
1542 | 1551 | ||
1543 | out_unlock2: | 1552 | out_unlock2: |
1544 | rcu_read_unlock(); | 1553 | spin_unlock(&files->file_lock); |
1545 | put_files_struct(files); | 1554 | put_files_struct(files); |
1546 | out_unlock: | 1555 | out_unlock: |
1547 | iput(inode); | 1556 | iput(inode); |
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c index 58c418fbca2c..97ae1b92bc47 100644 --- a/fs/reiserfs/xattr_acl.c +++ b/fs/reiserfs/xattr_acl.c | |||
@@ -408,8 +408,9 @@ int reiserfs_cache_default_acl(struct inode *inode) | |||
408 | acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); | 408 | acl = reiserfs_get_acl(inode, ACL_TYPE_DEFAULT); |
409 | reiserfs_read_unlock_xattrs(inode->i_sb); | 409 | reiserfs_read_unlock_xattrs(inode->i_sb); |
410 | reiserfs_read_unlock_xattr_i(inode); | 410 | reiserfs_read_unlock_xattr_i(inode); |
411 | ret = acl ? 1 : 0; | 411 | ret = (acl && !IS_ERR(acl)); |
412 | posix_acl_release(acl); | 412 | if (ret) |
413 | posix_acl_release(acl); | ||
413 | } | 414 | } |
414 | 415 | ||
415 | return ret; | 416 | return ret; |
diff --git a/fs/splice.c b/fs/splice.c index 8d57e89924a6..447ebc0a37f3 100644 --- a/fs/splice.c +++ b/fs/splice.c | |||
@@ -27,15 +27,22 @@ | |||
27 | #include <linux/buffer_head.h> | 27 | #include <linux/buffer_head.h> |
28 | #include <linux/module.h> | 28 | #include <linux/module.h> |
29 | #include <linux/syscalls.h> | 29 | #include <linux/syscalls.h> |
30 | #include <linux/uio.h> | ||
31 | |||
32 | struct partial_page { | ||
33 | unsigned int offset; | ||
34 | unsigned int len; | ||
35 | }; | ||
30 | 36 | ||
31 | /* | 37 | /* |
32 | * Passed to the actors | 38 | * Passed to splice_to_pipe |
33 | */ | 39 | */ |
34 | struct splice_desc { | 40 | struct splice_pipe_desc { |
35 | unsigned int len, total_len; /* current and remaining length */ | 41 | struct page **pages; /* page map */ |
42 | struct partial_page *partial; /* pages[] may not be contig */ | ||
43 | int nr_pages; /* number of pages in map */ | ||
36 | unsigned int flags; /* splice flags */ | 44 | unsigned int flags; /* splice flags */ |
37 | struct file *file; /* file to read/write */ | 45 | struct pipe_buf_operations *ops;/* ops associated with output pipe */ |
38 | loff_t pos; /* file position */ | ||
39 | }; | 46 | }; |
40 | 47 | ||
41 | /* | 48 | /* |
@@ -50,7 +57,8 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *info, | |||
50 | struct page *page = buf->page; | 57 | struct page *page = buf->page; |
51 | struct address_space *mapping = page_mapping(page); | 58 | struct address_space *mapping = page_mapping(page); |
52 | 59 | ||
53 | WARN_ON(!PageLocked(page)); | 60 | lock_page(page); |
61 | |||
54 | WARN_ON(!PageUptodate(page)); | 62 | WARN_ON(!PageUptodate(page)); |
55 | 63 | ||
56 | /* | 64 | /* |
@@ -65,8 +73,10 @@ static int page_cache_pipe_buf_steal(struct pipe_inode_info *info, | |||
65 | if (PagePrivate(page)) | 73 | if (PagePrivate(page)) |
66 | try_to_release_page(page, mapping_gfp_mask(mapping)); | 74 | try_to_release_page(page, mapping_gfp_mask(mapping)); |
67 | 75 | ||
68 | if (!remove_mapping(mapping, page)) | 76 | if (!remove_mapping(mapping, page)) { |
77 | unlock_page(page); | ||
69 | return 1; | 78 | return 1; |
79 | } | ||
70 | 80 | ||
71 | buf->flags |= PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU; | 81 | buf->flags |= PIPE_BUF_FLAG_STOLEN | PIPE_BUF_FLAG_LRU; |
72 | return 0; | 82 | return 0; |
@@ -125,6 +135,19 @@ static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info, | |||
125 | kunmap(buf->page); | 135 | kunmap(buf->page); |
126 | } | 136 | } |
127 | 137 | ||
138 | static void *user_page_pipe_buf_map(struct file *file, | ||
139 | struct pipe_inode_info *pipe, | ||
140 | struct pipe_buffer *buf) | ||
141 | { | ||
142 | return kmap(buf->page); | ||
143 | } | ||
144 | |||
145 | static void user_page_pipe_buf_unmap(struct pipe_inode_info *pipe, | ||
146 | struct pipe_buffer *buf) | ||
147 | { | ||
148 | kunmap(buf->page); | ||
149 | } | ||
150 | |||
128 | static void page_cache_pipe_buf_get(struct pipe_inode_info *info, | 151 | static void page_cache_pipe_buf_get(struct pipe_inode_info *info, |
129 | struct pipe_buffer *buf) | 152 | struct pipe_buffer *buf) |
130 | { | 153 | { |
@@ -140,19 +163,33 @@ static struct pipe_buf_operations page_cache_pipe_buf_ops = { | |||
140 | .get = page_cache_pipe_buf_get, | 163 | .get = page_cache_pipe_buf_get, |
141 | }; | 164 | }; |
142 | 165 | ||
166 | static int user_page_pipe_buf_steal(struct pipe_inode_info *pipe, | ||
167 | struct pipe_buffer *buf) | ||
168 | { | ||
169 | return 1; | ||
170 | } | ||
171 | |||
172 | static struct pipe_buf_operations user_page_pipe_buf_ops = { | ||
173 | .can_merge = 0, | ||
174 | .map = user_page_pipe_buf_map, | ||
175 | .unmap = user_page_pipe_buf_unmap, | ||
176 | .release = page_cache_pipe_buf_release, | ||
177 | .steal = user_page_pipe_buf_steal, | ||
178 | .get = page_cache_pipe_buf_get, | ||
179 | }; | ||
180 | |||
143 | /* | 181 | /* |
144 | * Pipe output worker. This sets up our pipe format with the page cache | 182 | * Pipe output worker. This sets up our pipe format with the page cache |
145 | * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). | 183 | * pipe buffer operations. Otherwise very similar to the regular pipe_writev(). |
146 | */ | 184 | */ |
147 | static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, | 185 | static ssize_t splice_to_pipe(struct pipe_inode_info *pipe, |
148 | int nr_pages, unsigned long offset, | 186 | struct splice_pipe_desc *spd) |
149 | unsigned long len, unsigned int flags) | ||
150 | { | 187 | { |
151 | int ret, do_wakeup, i; | 188 | int ret, do_wakeup, page_nr; |
152 | 189 | ||
153 | ret = 0; | 190 | ret = 0; |
154 | do_wakeup = 0; | 191 | do_wakeup = 0; |
155 | i = 0; | 192 | page_nr = 0; |
156 | 193 | ||
157 | if (pipe->inode) | 194 | if (pipe->inode) |
158 | mutex_lock(&pipe->inode->i_mutex); | 195 | mutex_lock(&pipe->inode->i_mutex); |
@@ -168,27 +205,19 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, | |||
168 | if (pipe->nrbufs < PIPE_BUFFERS) { | 205 | if (pipe->nrbufs < PIPE_BUFFERS) { |
169 | int newbuf = (pipe->curbuf + pipe->nrbufs) & (PIPE_BUFFERS - 1); | 206 | int newbuf = (pipe->curbuf + pipe->nrbufs) & (PIPE_BUFFERS - 1); |
170 | struct pipe_buffer *buf = pipe->bufs + newbuf; | 207 | struct pipe_buffer *buf = pipe->bufs + newbuf; |
171 | struct page *page = pages[i++]; | ||
172 | unsigned long this_len; | ||
173 | |||
174 | this_len = PAGE_CACHE_SIZE - offset; | ||
175 | if (this_len > len) | ||
176 | this_len = len; | ||
177 | 208 | ||
178 | buf->page = page; | 209 | buf->page = spd->pages[page_nr]; |
179 | buf->offset = offset; | 210 | buf->offset = spd->partial[page_nr].offset; |
180 | buf->len = this_len; | 211 | buf->len = spd->partial[page_nr].len; |
181 | buf->ops = &page_cache_pipe_buf_ops; | 212 | buf->ops = spd->ops; |
182 | pipe->nrbufs++; | 213 | pipe->nrbufs++; |
214 | page_nr++; | ||
215 | ret += buf->len; | ||
216 | |||
183 | if (pipe->inode) | 217 | if (pipe->inode) |
184 | do_wakeup = 1; | 218 | do_wakeup = 1; |
185 | 219 | ||
186 | ret += this_len; | 220 | if (!--spd->nr_pages) |
187 | len -= this_len; | ||
188 | offset = 0; | ||
189 | if (!--nr_pages) | ||
190 | break; | ||
191 | if (!len) | ||
192 | break; | 221 | break; |
193 | if (pipe->nrbufs < PIPE_BUFFERS) | 222 | if (pipe->nrbufs < PIPE_BUFFERS) |
194 | continue; | 223 | continue; |
@@ -196,7 +225,7 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, | |||
196 | break; | 225 | break; |
197 | } | 226 | } |
198 | 227 | ||
199 | if (flags & SPLICE_F_NONBLOCK) { | 228 | if (spd->flags & SPLICE_F_NONBLOCK) { |
200 | if (!ret) | 229 | if (!ret) |
201 | ret = -EAGAIN; | 230 | ret = -EAGAIN; |
202 | break; | 231 | break; |
@@ -231,8 +260,8 @@ static ssize_t move_to_pipe(struct pipe_inode_info *pipe, struct page **pages, | |||
231 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); | 260 | kill_fasync(&pipe->fasync_readers, SIGIO, POLL_IN); |
232 | } | 261 | } |
233 | 262 | ||
234 | while (i < nr_pages) | 263 | while (page_nr < spd->nr_pages) |
235 | page_cache_release(pages[i++]); | 264 | page_cache_release(spd->pages[page_nr++]); |
236 | 265 | ||
237 | return ret; | 266 | return ret; |
238 | } | 267 | } |
@@ -243,15 +272,24 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
243 | unsigned int flags) | 272 | unsigned int flags) |
244 | { | 273 | { |
245 | struct address_space *mapping = in->f_mapping; | 274 | struct address_space *mapping = in->f_mapping; |
246 | unsigned int offset, nr_pages; | 275 | unsigned int loff, nr_pages; |
247 | struct page *pages[PIPE_BUFFERS]; | 276 | struct page *pages[PIPE_BUFFERS]; |
277 | struct partial_page partial[PIPE_BUFFERS]; | ||
248 | struct page *page; | 278 | struct page *page; |
249 | pgoff_t index; | 279 | pgoff_t index, end_index; |
250 | int i, error; | 280 | loff_t isize; |
281 | size_t total_len; | ||
282 | int error; | ||
283 | struct splice_pipe_desc spd = { | ||
284 | .pages = pages, | ||
285 | .partial = partial, | ||
286 | .flags = flags, | ||
287 | .ops = &page_cache_pipe_buf_ops, | ||
288 | }; | ||
251 | 289 | ||
252 | index = *ppos >> PAGE_CACHE_SHIFT; | 290 | index = *ppos >> PAGE_CACHE_SHIFT; |
253 | offset = *ppos & ~PAGE_CACHE_MASK; | 291 | loff = *ppos & ~PAGE_CACHE_MASK; |
254 | nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; | 292 | nr_pages = (len + loff + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT; |
255 | 293 | ||
256 | if (nr_pages > PIPE_BUFFERS) | 294 | if (nr_pages > PIPE_BUFFERS) |
257 | nr_pages = PIPE_BUFFERS; | 295 | nr_pages = PIPE_BUFFERS; |
@@ -261,14 +299,24 @@ __generic_file_splice_read(struct file *in, loff_t *ppos, | |||
261 | * read-ahead if this is a non-zero offset (we are likely doing small | 299 | * read-ahead if this is a non-zero offset (we are likely doing small |
262 | * chunk splice and the page is already there) for a single page. | 300 | * chunk splice and the page is already there) for a single page. |
263 | */ | 301 | */ |
264 | if (!offset || nr_pages > 1) | 302 | if (!loff || spd.nr_pages > 1) |
265 | do_page_cache_readahead(mapping, in, index, nr_pages); | 303 | do_page_cache_readahead(mapping, in, index, spd.nr_pages); |
266 | 304 | ||
267 | /* | 305 | /* |
268 | * Now fill in the holes: | 306 | * Now fill in the holes: |
269 | */ | 307 | */ |
270 | error = 0; | 308 | error = 0; |
271 | for (i = 0; i < nr_pages; i++, index++) { | 309 | total_len = 0; |
310 | for (spd.nr_pages = 0; spd.nr_pages < nr_pages; spd.nr_pages++, index++) { | ||
311 | unsigned int this_len; | ||
312 | |||
313 | if (!len) | ||
314 | break; | ||
315 | |||
316 | /* | ||
317 | * this_len is the max we'll use from this page | ||
318 | */ | ||
319 | this_len = min_t(unsigned long, len, PAGE_CACHE_SIZE - loff); | ||
272 | find_page: | 320 | find_page: |
273 | /* | 321 | /* |
274 | * lookup the page for this index | 322 | * lookup the page for this index |
@@ -276,14 +324,6 @@ find_page: | |||
276 | page = find_get_page(mapping, index); | 324 | page = find_get_page(mapping, index); |
277 | if (!page) { | 325 | if (!page) { |
278 | /* | 326 | /* |
279 | * If in nonblock mode then dont block on | ||
280 | * readpage (we've kicked readahead so there | ||
281 | * will be asynchronous progress): | ||
282 | */ | ||
283 | if (flags & SPLICE_F_NONBLOCK) | ||
284 | break; | ||
285 | |||
286 | /* | ||
287 | * page didn't exist, allocate one | 327 | * page didn't exist, allocate one |
288 | */ | 328 | */ |
289 | page = page_cache_alloc_cold(mapping); | 329 | page = page_cache_alloc_cold(mapping); |
@@ -304,6 +344,13 @@ find_page: | |||
304 | * If the page isn't uptodate, we may need to start io on it | 344 | * If the page isn't uptodate, we may need to start io on it |
305 | */ | 345 | */ |
306 | if (!PageUptodate(page)) { | 346 | if (!PageUptodate(page)) { |
347 | /* | ||
348 | * If in nonblock mode then dont block on waiting | ||
349 | * for an in-flight io page | ||
350 | */ | ||
351 | if (flags & SPLICE_F_NONBLOCK) | ||
352 | break; | ||
353 | |||
307 | lock_page(page); | 354 | lock_page(page); |
308 | 355 | ||
309 | /* | 356 | /* |
@@ -336,13 +383,46 @@ readpage: | |||
336 | goto find_page; | 383 | goto find_page; |
337 | break; | 384 | break; |
338 | } | 385 | } |
386 | |||
387 | /* | ||
388 | * i_size must be checked after ->readpage(). | ||
389 | */ | ||
390 | isize = i_size_read(mapping->host); | ||
391 | end_index = (isize - 1) >> PAGE_CACHE_SHIFT; | ||
392 | if (unlikely(!isize || index > end_index)) { | ||
393 | page_cache_release(page); | ||
394 | break; | ||
395 | } | ||
396 | |||
397 | /* | ||
398 | * if this is the last page, see if we need to shrink | ||
399 | * the length and stop | ||
400 | */ | ||
401 | if (end_index == index) { | ||
402 | loff = PAGE_CACHE_SIZE - (isize & ~PAGE_CACHE_MASK); | ||
403 | if (total_len + loff > isize) { | ||
404 | page_cache_release(page); | ||
405 | break; | ||
406 | } | ||
407 | /* | ||
408 | * force quit after adding this page | ||
409 | */ | ||
410 | nr_pages = spd.nr_pages; | ||
411 | this_len = min(this_len, loff); | ||
412 | loff = 0; | ||
413 | } | ||
339 | } | 414 | } |
340 | fill_it: | 415 | fill_it: |
341 | pages[i] = page; | 416 | pages[spd.nr_pages] = page; |
417 | partial[spd.nr_pages].offset = loff; | ||
418 | partial[spd.nr_pages].len = this_len; | ||
419 | len -= this_len; | ||
420 | total_len += this_len; | ||
421 | loff = 0; | ||
342 | } | 422 | } |
343 | 423 | ||
344 | if (i) | 424 | if (spd.nr_pages) |
345 | return move_to_pipe(pipe, pages, i, offset, len, flags); | 425 | return splice_to_pipe(pipe, &spd); |
346 | 426 | ||
347 | return error; | 427 | return error; |
348 | } | 428 | } |
@@ -369,17 +449,20 @@ ssize_t generic_file_splice_read(struct file *in, loff_t *ppos, | |||
369 | while (len) { | 449 | while (len) { |
370 | ret = __generic_file_splice_read(in, ppos, pipe, len, flags); | 450 | ret = __generic_file_splice_read(in, ppos, pipe, len, flags); |
371 | 451 | ||
372 | if (ret <= 0) | 452 | if (ret < 0) |
373 | break; | 453 | break; |
454 | else if (!ret) { | ||
455 | if (spliced) | ||
456 | break; | ||
457 | if (flags & SPLICE_F_NONBLOCK) { | ||
458 | ret = -EAGAIN; | ||
459 | break; | ||
460 | } | ||
461 | } | ||
374 | 462 | ||
375 | *ppos += ret; | 463 | *ppos += ret; |
376 | len -= ret; | 464 | len -= ret; |
377 | spliced += ret; | 465 | spliced += ret; |
378 | |||
379 | if (!(flags & SPLICE_F_NONBLOCK)) | ||
380 | continue; | ||
381 | ret = -EAGAIN; | ||
382 | break; | ||
383 | } | 466 | } |
384 | 467 | ||
385 | if (spliced) | 468 | if (spliced) |
@@ -392,14 +475,13 @@ EXPORT_SYMBOL(generic_file_splice_read); | |||
392 | 475 | ||
393 | /* | 476 | /* |
394 | * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos' | 477 | * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos' |
395 | * using sendpage(). | 478 | * using sendpage(). Return the number of bytes sent. |
396 | */ | 479 | */ |
397 | static int pipe_to_sendpage(struct pipe_inode_info *info, | 480 | static int pipe_to_sendpage(struct pipe_inode_info *info, |
398 | struct pipe_buffer *buf, struct splice_desc *sd) | 481 | struct pipe_buffer *buf, struct splice_desc *sd) |
399 | { | 482 | { |
400 | struct file *file = sd->file; | 483 | struct file *file = sd->file; |
401 | loff_t pos = sd->pos; | 484 | loff_t pos = sd->pos; |
402 | unsigned int offset; | ||
403 | ssize_t ret; | 485 | ssize_t ret; |
404 | void *ptr; | 486 | void *ptr; |
405 | int more; | 487 | int more; |
@@ -414,16 +496,13 @@ static int pipe_to_sendpage(struct pipe_inode_info *info, | |||
414 | if (IS_ERR(ptr)) | 496 | if (IS_ERR(ptr)) |
415 | return PTR_ERR(ptr); | 497 | return PTR_ERR(ptr); |
416 | 498 | ||
417 | offset = pos & ~PAGE_CACHE_MASK; | ||
418 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; | 499 | more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; |
419 | 500 | ||
420 | ret = file->f_op->sendpage(file, buf->page, offset, sd->len, &pos,more); | 501 | ret = file->f_op->sendpage(file, buf->page, buf->offset, sd->len, |
502 | &pos, more); | ||
421 | 503 | ||
422 | buf->ops->unmap(info, buf); | 504 | buf->ops->unmap(info, buf); |
423 | if (ret == sd->len) | 505 | return ret; |
424 | return 0; | ||
425 | |||
426 | return -EIO; | ||
427 | } | 506 | } |
428 | 507 | ||
429 | /* | 508 | /* |
@@ -452,7 +531,7 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
452 | struct file *file = sd->file; | 531 | struct file *file = sd->file; |
453 | struct address_space *mapping = file->f_mapping; | 532 | struct address_space *mapping = file->f_mapping; |
454 | gfp_t gfp_mask = mapping_gfp_mask(mapping); | 533 | gfp_t gfp_mask = mapping_gfp_mask(mapping); |
455 | unsigned int offset; | 534 | unsigned int offset, this_len; |
456 | struct page *page; | 535 | struct page *page; |
457 | pgoff_t index; | 536 | pgoff_t index; |
458 | char *src; | 537 | char *src; |
@@ -468,20 +547,22 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
468 | index = sd->pos >> PAGE_CACHE_SHIFT; | 547 | index = sd->pos >> PAGE_CACHE_SHIFT; |
469 | offset = sd->pos & ~PAGE_CACHE_MASK; | 548 | offset = sd->pos & ~PAGE_CACHE_MASK; |
470 | 549 | ||
550 | this_len = sd->len; | ||
551 | if (this_len + offset > PAGE_CACHE_SIZE) | ||
552 | this_len = PAGE_CACHE_SIZE - offset; | ||
553 | |||
471 | /* | 554 | /* |
472 | * Reuse buf page, if SPLICE_F_MOVE is set. | 555 | * Reuse buf page, if SPLICE_F_MOVE is set. |
473 | */ | 556 | */ |
474 | if (sd->flags & SPLICE_F_MOVE) { | 557 | if (sd->flags & SPLICE_F_MOVE) { |
475 | /* | 558 | /* |
476 | * If steal succeeds, buf->page is now pruned from the vm | 559 | * If steal succeeds, buf->page is now pruned from the vm |
477 | * side (LRU and page cache) and we can reuse it. | 560 | * side (LRU and page cache) and we can reuse it. The page |
561 | * will also be looked on successful return. | ||
478 | */ | 562 | */ |
479 | if (buf->ops->steal(info, buf)) | 563 | if (buf->ops->steal(info, buf)) |
480 | goto find_page; | 564 | goto find_page; |
481 | 565 | ||
482 | /* | ||
483 | * this will also set the page locked | ||
484 | */ | ||
485 | page = buf->page; | 566 | page = buf->page; |
486 | if (add_to_page_cache(page, mapping, index, gfp_mask)) | 567 | if (add_to_page_cache(page, mapping, index, gfp_mask)) |
487 | goto find_page; | 568 | goto find_page; |
@@ -490,18 +571,30 @@ static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf, | |||
490 | lru_cache_add(page); | 571 | lru_cache_add(page); |
491 | } else { | 572 | } else { |
492 | find_page: | 573 | find_page: |
493 | ret = -ENOMEM; | 574 | page = find_lock_page(mapping, index); |
494 | page = find_or_create_page(mapping, index, gfp_mask); | 575 | if (!page) { |
495 | if (!page) | 576 | ret = -ENOMEM; |
496 | goto out_nomem; | 577 | page = page_cache_alloc_cold(mapping); |
578 | if (unlikely(!page)) | ||
579 | goto out_nomem; | ||
580 | |||
581 | /* | ||
582 | * This will also lock the page | ||
583 | */ | ||
584 | ret = add_to_page_cache_lru(page, mapping, index, | ||
585 | gfp_mask); | ||
586 | if (unlikely(ret)) | ||
587 | goto out; | ||
588 | } | ||
497 | 589 | ||
498 | /* | 590 | /* |
499 | * If the page is uptodate, it is also locked. If it isn't | 591 | * We get here with the page locked. If the page is also |
500 | * uptodate, we can mark it uptodate if we are filling the | 592 | * uptodate, we don't need to do more. If it isn't, we |
501 | * full page. Otherwise we need to read it in first... | 593 | * may need to bring it in if we are not going to overwrite |
594 | * the full page. | ||
502 | */ | 595 | */ |
503 | if (!PageUptodate(page)) { | 596 | if (!PageUptodate(page)) { |
504 | if (sd->len < PAGE_CACHE_SIZE) { | 597 | if (this_len < PAGE_CACHE_SIZE) { |
505 | ret = mapping->a_ops->readpage(file, page); | 598 | ret = mapping->a_ops->readpage(file, page); |
506 | if (unlikely(ret)) | 599 | if (unlikely(ret)) |
507 | goto out; | 600 | goto out; |
@@ -520,14 +613,12 @@ find_page: | |||
520 | ret = -EIO; | 613 | ret = -EIO; |
521 | goto out; | 614 | goto out; |
522 | } | 615 | } |
523 | } else { | 616 | } else |
524 | WARN_ON(!PageLocked(page)); | ||
525 | SetPageUptodate(page); | 617 | SetPageUptodate(page); |
526 | } | ||
527 | } | 618 | } |
528 | } | 619 | } |
529 | 620 | ||
530 | ret = mapping->a_ops->prepare_write(file, page, 0, sd->len); | 621 | ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); |
531 | if (ret == AOP_TRUNCATED_PAGE) { | 622 | if (ret == AOP_TRUNCATED_PAGE) { |
532 | page_cache_release(page); | 623 | page_cache_release(page); |
533 | goto find_page; | 624 | goto find_page; |
@@ -537,41 +628,42 @@ find_page: | |||
537 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) { | 628 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) { |
538 | char *dst = kmap_atomic(page, KM_USER0); | 629 | char *dst = kmap_atomic(page, KM_USER0); |
539 | 630 | ||
540 | memcpy(dst + offset, src + buf->offset, sd->len); | 631 | memcpy(dst + offset, src + buf->offset, this_len); |
541 | flush_dcache_page(page); | 632 | flush_dcache_page(page); |
542 | kunmap_atomic(dst, KM_USER0); | 633 | kunmap_atomic(dst, KM_USER0); |
543 | } | 634 | } |
544 | 635 | ||
545 | ret = mapping->a_ops->commit_write(file, page, 0, sd->len); | 636 | ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); |
546 | if (ret == AOP_TRUNCATED_PAGE) { | 637 | if (ret == AOP_TRUNCATED_PAGE) { |
547 | page_cache_release(page); | 638 | page_cache_release(page); |
548 | goto find_page; | 639 | goto find_page; |
549 | } else if (ret) | 640 | } else if (ret) |
550 | goto out; | 641 | goto out; |
551 | 642 | ||
643 | /* | ||
644 | * Return the number of bytes written. | ||
645 | */ | ||
646 | ret = this_len; | ||
552 | mark_page_accessed(page); | 647 | mark_page_accessed(page); |
553 | balance_dirty_pages_ratelimited(mapping); | 648 | balance_dirty_pages_ratelimited(mapping); |
554 | out: | 649 | out: |
555 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) { | 650 | if (!(buf->flags & PIPE_BUF_FLAG_STOLEN)) |
556 | page_cache_release(page); | 651 | page_cache_release(page); |
557 | unlock_page(page); | 652 | |
558 | } | 653 | unlock_page(page); |
559 | out_nomem: | 654 | out_nomem: |
560 | buf->ops->unmap(info, buf); | 655 | buf->ops->unmap(info, buf); |
561 | return ret; | 656 | return ret; |
562 | } | 657 | } |
563 | 658 | ||
564 | typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, | ||
565 | struct splice_desc *); | ||
566 | |||
567 | /* | 659 | /* |
568 | * Pipe input worker. Most of this logic works like a regular pipe, the | 660 | * Pipe input worker. Most of this logic works like a regular pipe, the |
569 | * key here is the 'actor' worker passed in that actually moves the data | 661 | * key here is the 'actor' worker passed in that actually moves the data |
570 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. | 662 | * to the wanted destination. See pipe_to_file/pipe_to_sendpage above. |
571 | */ | 663 | */ |
572 | static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | 664 | ssize_t splice_from_pipe(struct pipe_inode_info *pipe, struct file *out, |
573 | loff_t *ppos, size_t len, unsigned int flags, | 665 | loff_t *ppos, size_t len, unsigned int flags, |
574 | splice_actor *actor) | 666 | splice_actor *actor) |
575 | { | 667 | { |
576 | int ret, do_wakeup, err; | 668 | int ret, do_wakeup, err; |
577 | struct splice_desc sd; | 669 | struct splice_desc sd; |
@@ -597,16 +689,22 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
597 | sd.len = sd.total_len; | 689 | sd.len = sd.total_len; |
598 | 690 | ||
599 | err = actor(pipe, buf, &sd); | 691 | err = actor(pipe, buf, &sd); |
600 | if (err) { | 692 | if (err <= 0) { |
601 | if (!ret && err != -ENODATA) | 693 | if (!ret && err != -ENODATA) |
602 | ret = err; | 694 | ret = err; |
603 | 695 | ||
604 | break; | 696 | break; |
605 | } | 697 | } |
606 | 698 | ||
607 | ret += sd.len; | 699 | ret += err; |
608 | buf->offset += sd.len; | 700 | buf->offset += err; |
609 | buf->len -= sd.len; | 701 | buf->len -= err; |
702 | |||
703 | sd.len -= err; | ||
704 | sd.pos += err; | ||
705 | sd.total_len -= err; | ||
706 | if (sd.len) | ||
707 | continue; | ||
610 | 708 | ||
611 | if (!buf->len) { | 709 | if (!buf->len) { |
612 | buf->ops = NULL; | 710 | buf->ops = NULL; |
@@ -617,8 +715,6 @@ static ssize_t move_from_pipe(struct pipe_inode_info *pipe, struct file *out, | |||
617 | do_wakeup = 1; | 715 | do_wakeup = 1; |
618 | } | 716 | } |
619 | 717 | ||
620 | sd.pos += sd.len; | ||
621 | sd.total_len -= sd.len; | ||
622 | if (!sd.total_len) | 718 | if (!sd.total_len) |
623 | break; | 719 | break; |
624 | } | 720 | } |
@@ -686,23 +782,27 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out, | |||
686 | struct address_space *mapping = out->f_mapping; | 782 | struct address_space *mapping = out->f_mapping; |
687 | ssize_t ret; | 783 | ssize_t ret; |
688 | 784 | ||
689 | ret = move_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); | 785 | ret = splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_file); |
690 | 786 | if (ret > 0) { | |
691 | /* | ||
692 | * If file or inode is SYNC and we actually wrote some data, sync it. | ||
693 | */ | ||
694 | if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(mapping->host)) | ||
695 | && ret > 0) { | ||
696 | struct inode *inode = mapping->host; | 787 | struct inode *inode = mapping->host; |
697 | int err; | ||
698 | 788 | ||
699 | mutex_lock(&inode->i_mutex); | 789 | *ppos += ret; |
700 | err = generic_osync_inode(mapping->host, mapping, | 790 | |
701 | OSYNC_METADATA|OSYNC_DATA); | 791 | /* |
702 | mutex_unlock(&inode->i_mutex); | 792 | * If file or inode is SYNC and we actually wrote some data, |
793 | * sync it. | ||
794 | */ | ||
795 | if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { | ||
796 | int err; | ||
797 | |||
798 | mutex_lock(&inode->i_mutex); | ||
799 | err = generic_osync_inode(inode, mapping, | ||
800 | OSYNC_METADATA|OSYNC_DATA); | ||
801 | mutex_unlock(&inode->i_mutex); | ||
703 | 802 | ||
704 | if (err) | 803 | if (err) |
705 | ret = err; | 804 | ret = err; |
805 | } | ||
706 | } | 806 | } |
707 | 807 | ||
708 | return ret; | 808 | return ret; |
@@ -724,7 +824,7 @@ EXPORT_SYMBOL(generic_file_splice_write); | |||
724 | ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, | 824 | ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, |
725 | loff_t *ppos, size_t len, unsigned int flags) | 825 | loff_t *ppos, size_t len, unsigned int flags) |
726 | { | 826 | { |
727 | return move_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage); | 827 | return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage); |
728 | } | 828 | } |
729 | 829 | ||
730 | EXPORT_SYMBOL(generic_splice_sendpage); | 830 | EXPORT_SYMBOL(generic_splice_sendpage); |
@@ -811,7 +911,7 @@ long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, | |||
811 | 911 | ||
812 | /* | 912 | /* |
813 | * We don't have an immediate reader, but we'll read the stuff | 913 | * We don't have an immediate reader, but we'll read the stuff |
814 | * out of the pipe right after the move_to_pipe(). So set | 914 | * out of the pipe right after the splice_to_pipe(). So set |
815 | * PIPE_READERS appropriately. | 915 | * PIPE_READERS appropriately. |
816 | */ | 916 | */ |
817 | pipe->readers = 1; | 917 | pipe->readers = 1; |
@@ -904,6 +1004,7 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
904 | { | 1004 | { |
905 | struct pipe_inode_info *pipe; | 1005 | struct pipe_inode_info *pipe; |
906 | loff_t offset, *off; | 1006 | loff_t offset, *off; |
1007 | long ret; | ||
907 | 1008 | ||
908 | pipe = in->f_dentry->d_inode->i_pipe; | 1009 | pipe = in->f_dentry->d_inode->i_pipe; |
909 | if (pipe) { | 1010 | if (pipe) { |
@@ -918,7 +1019,12 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
918 | } else | 1019 | } else |
919 | off = &out->f_pos; | 1020 | off = &out->f_pos; |
920 | 1021 | ||
921 | return do_splice_from(pipe, out, off, len, flags); | 1022 | ret = do_splice_from(pipe, out, off, len, flags); |
1023 | |||
1024 | if (off_out && copy_to_user(off_out, off, sizeof(loff_t))) | ||
1025 | ret = -EFAULT; | ||
1026 | |||
1027 | return ret; | ||
922 | } | 1028 | } |
923 | 1029 | ||
924 | pipe = out->f_dentry->d_inode->i_pipe; | 1030 | pipe = out->f_dentry->d_inode->i_pipe; |
@@ -934,12 +1040,185 @@ static long do_splice(struct file *in, loff_t __user *off_in, | |||
934 | } else | 1040 | } else |
935 | off = &in->f_pos; | 1041 | off = &in->f_pos; |
936 | 1042 | ||
937 | return do_splice_to(in, off, pipe, len, flags); | 1043 | ret = do_splice_to(in, off, pipe, len, flags); |
1044 | |||
1045 | if (off_in && copy_to_user(off_in, off, sizeof(loff_t))) | ||
1046 | ret = -EFAULT; | ||
1047 | |||
1048 | return ret; | ||
938 | } | 1049 | } |
939 | 1050 | ||
940 | return -EINVAL; | 1051 | return -EINVAL; |
941 | } | 1052 | } |
942 | 1053 | ||
1054 | /* | ||
1055 | * Map an iov into an array of pages and offset/length tupples. With the | ||
1056 | * partial_page structure, we can map several non-contiguous ranges into | ||
1057 | * our ones pages[] map instead of splitting that operation into pieces. | ||
1058 | * Could easily be exported as a generic helper for other users, in which | ||
1059 | * case one would probably want to add a 'max_nr_pages' parameter as well. | ||
1060 | */ | ||
1061 | static int get_iovec_page_array(const struct iovec __user *iov, | ||
1062 | unsigned int nr_vecs, struct page **pages, | ||
1063 | struct partial_page *partial) | ||
1064 | { | ||
1065 | int buffers = 0, error = 0; | ||
1066 | |||
1067 | /* | ||
1068 | * It's ok to take the mmap_sem for reading, even | ||
1069 | * across a "get_user()". | ||
1070 | */ | ||
1071 | down_read(¤t->mm->mmap_sem); | ||
1072 | |||
1073 | while (nr_vecs) { | ||
1074 | unsigned long off, npages; | ||
1075 | void __user *base; | ||
1076 | size_t len; | ||
1077 | int i; | ||
1078 | |||
1079 | /* | ||
1080 | * Get user address base and length for this iovec. | ||
1081 | */ | ||
1082 | error = get_user(base, &iov->iov_base); | ||
1083 | if (unlikely(error)) | ||
1084 | break; | ||
1085 | error = get_user(len, &iov->iov_len); | ||
1086 | if (unlikely(error)) | ||
1087 | break; | ||
1088 | |||
1089 | /* | ||
1090 | * Sanity check this iovec. 0 read succeeds. | ||
1091 | */ | ||
1092 | if (unlikely(!len)) | ||
1093 | break; | ||
1094 | error = -EFAULT; | ||
1095 | if (unlikely(!base)) | ||
1096 | break; | ||
1097 | |||
1098 | /* | ||
1099 | * Get this base offset and number of pages, then map | ||
1100 | * in the user pages. | ||
1101 | */ | ||
1102 | off = (unsigned long) base & ~PAGE_MASK; | ||
1103 | npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; | ||
1104 | if (npages > PIPE_BUFFERS - buffers) | ||
1105 | npages = PIPE_BUFFERS - buffers; | ||
1106 | |||
1107 | error = get_user_pages(current, current->mm, | ||
1108 | (unsigned long) base, npages, 0, 0, | ||
1109 | &pages[buffers], NULL); | ||
1110 | |||
1111 | if (unlikely(error <= 0)) | ||
1112 | break; | ||
1113 | |||
1114 | /* | ||
1115 | * Fill this contiguous range into the partial page map. | ||
1116 | */ | ||
1117 | for (i = 0; i < error; i++) { | ||
1118 | const int plen = min_t(size_t, len, PAGE_SIZE) - off; | ||
1119 | |||
1120 | partial[buffers].offset = off; | ||
1121 | partial[buffers].len = plen; | ||
1122 | |||
1123 | off = 0; | ||
1124 | len -= plen; | ||
1125 | buffers++; | ||
1126 | } | ||
1127 | |||
1128 | /* | ||
1129 | * We didn't complete this iov, stop here since it probably | ||
1130 | * means we have to move some of this into a pipe to | ||
1131 | * be able to continue. | ||
1132 | */ | ||
1133 | if (len) | ||
1134 | break; | ||
1135 | |||
1136 | /* | ||
1137 | * Don't continue if we mapped fewer pages than we asked for, | ||
1138 | * or if we mapped the max number of pages that we have | ||
1139 | * room for. | ||
1140 | */ | ||
1141 | if (error < npages || buffers == PIPE_BUFFERS) | ||
1142 | break; | ||
1143 | |||
1144 | nr_vecs--; | ||
1145 | iov++; | ||
1146 | } | ||
1147 | |||
1148 | up_read(¤t->mm->mmap_sem); | ||
1149 | |||
1150 | if (buffers) | ||
1151 | return buffers; | ||
1152 | |||
1153 | return error; | ||
1154 | } | ||
1155 | |||
1156 | /* | ||
1157 | * vmsplice splices a user address range into a pipe. It can be thought of | ||
1158 | * as splice-from-memory, where the regular splice is splice-from-file (or | ||
1159 | * to file). In both cases the output is a pipe, naturally. | ||
1160 | * | ||
1161 | * Note that vmsplice only supports splicing _from_ user memory to a pipe, | ||
1162 | * not the other way around. Splicing from user memory is a simple operation | ||
1163 | * that can be supported without any funky alignment restrictions or nasty | ||
1164 | * vm tricks. We simply map in the user memory and fill them into a pipe. | ||
1165 | * The reverse isn't quite as easy, though. There are two possible solutions | ||
1166 | * for that: | ||
1167 | * | ||
1168 | * - memcpy() the data internally, at which point we might as well just | ||
1169 | * do a regular read() on the buffer anyway. | ||
1170 | * - Lots of nasty vm tricks, that are neither fast nor flexible (it | ||
1171 | * has restriction limitations on both ends of the pipe). | ||
1172 | * | ||
1173 | * Alas, it isn't here. | ||
1174 | * | ||
1175 | */ | ||
1176 | static long do_vmsplice(struct file *file, const struct iovec __user *iov, | ||
1177 | unsigned long nr_segs, unsigned int flags) | ||
1178 | { | ||
1179 | struct pipe_inode_info *pipe = file->f_dentry->d_inode->i_pipe; | ||
1180 | struct page *pages[PIPE_BUFFERS]; | ||
1181 | struct partial_page partial[PIPE_BUFFERS]; | ||
1182 | struct splice_pipe_desc spd = { | ||
1183 | .pages = pages, | ||
1184 | .partial = partial, | ||
1185 | .flags = flags, | ||
1186 | .ops = &user_page_pipe_buf_ops, | ||
1187 | }; | ||
1188 | |||
1189 | if (unlikely(!pipe)) | ||
1190 | return -EBADF; | ||
1191 | if (unlikely(nr_segs > UIO_MAXIOV)) | ||
1192 | return -EINVAL; | ||
1193 | else if (unlikely(!nr_segs)) | ||
1194 | return 0; | ||
1195 | |||
1196 | spd.nr_pages = get_iovec_page_array(iov, nr_segs, pages, partial); | ||
1197 | if (spd.nr_pages <= 0) | ||
1198 | return spd.nr_pages; | ||
1199 | |||
1200 | return splice_to_pipe(pipe, &spd); | ||
1201 | } | ||
1202 | |||
1203 | asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, | ||
1204 | unsigned long nr_segs, unsigned int flags) | ||
1205 | { | ||
1206 | struct file *file; | ||
1207 | long error; | ||
1208 | int fput; | ||
1209 | |||
1210 | error = -EBADF; | ||
1211 | file = fget_light(fd, &fput); | ||
1212 | if (file) { | ||
1213 | if (file->f_mode & FMODE_WRITE) | ||
1214 | error = do_vmsplice(file, iov, nr_segs, flags); | ||
1215 | |||
1216 | fput_light(file, fput); | ||
1217 | } | ||
1218 | |||
1219 | return error; | ||
1220 | } | ||
1221 | |||
943 | asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, | 1222 | asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, |
944 | int fd_out, loff_t __user *off_out, | 1223 | int fd_out, loff_t __user *off_out, |
945 | size_t len, unsigned int flags) | 1224 | size_t len, unsigned int flags) |
@@ -979,7 +1258,9 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
979 | size_t len, unsigned int flags) | 1258 | size_t len, unsigned int flags) |
980 | { | 1259 | { |
981 | struct pipe_buffer *ibuf, *obuf; | 1260 | struct pipe_buffer *ibuf, *obuf; |
982 | int ret = 0, do_wakeup = 0, i; | 1261 | int ret, do_wakeup, i, ipipe_first; |
1262 | |||
1263 | ret = do_wakeup = ipipe_first = 0; | ||
983 | 1264 | ||
984 | /* | 1265 | /* |
985 | * Potential ABBA deadlock, work around it by ordering lock | 1266 | * Potential ABBA deadlock, work around it by ordering lock |
@@ -987,6 +1268,7 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
987 | * could deadlock (one doing tee from A -> B, the other from B -> A). | 1268 | * could deadlock (one doing tee from A -> B, the other from B -> A). |
988 | */ | 1269 | */ |
989 | if (ipipe->inode < opipe->inode) { | 1270 | if (ipipe->inode < opipe->inode) { |
1271 | ipipe_first = 1; | ||
990 | mutex_lock(&ipipe->inode->i_mutex); | 1272 | mutex_lock(&ipipe->inode->i_mutex); |
991 | mutex_lock(&opipe->inode->i_mutex); | 1273 | mutex_lock(&opipe->inode->i_mutex); |
992 | } else { | 1274 | } else { |
@@ -1035,9 +1317,11 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
1035 | 1317 | ||
1036 | /* | 1318 | /* |
1037 | * We have input available, but no output room. | 1319 | * We have input available, but no output room. |
1038 | * If we already copied data, return that. | 1320 | * If we already copied data, return that. If we |
1321 | * need to drop the opipe lock, it must be ordered | ||
1322 | * last to avoid deadlocks. | ||
1039 | */ | 1323 | */ |
1040 | if (flags & SPLICE_F_NONBLOCK) { | 1324 | if ((flags & SPLICE_F_NONBLOCK) || !ipipe_first) { |
1041 | if (!ret) | 1325 | if (!ret) |
1042 | ret = -EAGAIN; | 1326 | ret = -EAGAIN; |
1043 | break; | 1327 | break; |
@@ -1071,7 +1355,12 @@ static int link_pipe(struct pipe_inode_info *ipipe, | |||
1071 | if (ret) | 1355 | if (ret) |
1072 | break; | 1356 | break; |
1073 | } | 1357 | } |
1074 | if (flags & SPLICE_F_NONBLOCK) { | 1358 | /* |
1359 | * pipe_wait() drops the ipipe mutex. To avoid deadlocks | ||
1360 | * with another process, we can only safely do that if | ||
1361 | * the ipipe lock is ordered last. | ||
1362 | */ | ||
1363 | if ((flags & SPLICE_F_NONBLOCK) || ipipe_first) { | ||
1075 | if (!ret) | 1364 | if (!ret) |
1076 | ret = -EAGAIN; | 1365 | ret = -EAGAIN; |
1077 | break; | 1366 | break; |
diff --git a/include/asm-i386/atomic.h b/include/asm-i386/atomic.h index 22d80ece95cb..4ddce5296a78 100644 --- a/include/asm-i386/atomic.h +++ b/include/asm-i386/atomic.h | |||
@@ -183,6 +183,7 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) | |||
183 | { | 183 | { |
184 | int __i; | 184 | int __i; |
185 | #ifdef CONFIG_M386 | 185 | #ifdef CONFIG_M386 |
186 | unsigned long flags; | ||
186 | if(unlikely(boot_cpu_data.x86==3)) | 187 | if(unlikely(boot_cpu_data.x86==3)) |
187 | goto no_xadd; | 188 | goto no_xadd; |
188 | #endif | 189 | #endif |
@@ -196,10 +197,10 @@ static __inline__ int atomic_add_return(int i, atomic_t *v) | |||
196 | 197 | ||
197 | #ifdef CONFIG_M386 | 198 | #ifdef CONFIG_M386 |
198 | no_xadd: /* Legacy 386 processor */ | 199 | no_xadd: /* Legacy 386 processor */ |
199 | local_irq_disable(); | 200 | local_irq_save(flags); |
200 | __i = atomic_read(v); | 201 | __i = atomic_read(v); |
201 | atomic_set(v, i + __i); | 202 | atomic_set(v, i + __i); |
202 | local_irq_enable(); | 203 | local_irq_restore(flags); |
203 | return i + __i; | 204 | return i + __i; |
204 | #endif | 205 | #endif |
205 | } | 206 | } |
diff --git a/include/asm-i386/cpufeature.h b/include/asm-i386/cpufeature.h index 5c0b5876b931..b44bfc6239cb 100644 --- a/include/asm-i386/cpufeature.h +++ b/include/asm-i386/cpufeature.h | |||
@@ -71,6 +71,7 @@ | |||
71 | #define X86_FEATURE_P4 (3*32+ 7) /* P4 */ | 71 | #define X86_FEATURE_P4 (3*32+ 7) /* P4 */ |
72 | #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */ | 72 | #define X86_FEATURE_CONSTANT_TSC (3*32+ 8) /* TSC ticks at a constant rate */ |
73 | #define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */ | 73 | #define X86_FEATURE_UP (3*32+ 9) /* smp kernel running on up */ |
74 | #define X86_FEATURE_FXSAVE_LEAK (3*32+10) /* FXSAVE leaks FOP/FIP/FOP */ | ||
74 | 75 | ||
75 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ | 76 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ |
76 | #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ | 77 | #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ |
diff --git a/include/asm-i386/i387.h b/include/asm-i386/i387.h index 152d0baa576a..7b1f01191e70 100644 --- a/include/asm-i386/i387.h +++ b/include/asm-i386/i387.h | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/sched.h> | 14 | #include <linux/sched.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/kernel_stat.h> | ||
16 | #include <asm/processor.h> | 17 | #include <asm/processor.h> |
17 | #include <asm/sigcontext.h> | 18 | #include <asm/sigcontext.h> |
18 | #include <asm/user.h> | 19 | #include <asm/user.h> |
@@ -38,17 +39,38 @@ extern void init_fpu(struct task_struct *); | |||
38 | extern void kernel_fpu_begin(void); | 39 | extern void kernel_fpu_begin(void); |
39 | #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) | 40 | #define kernel_fpu_end() do { stts(); preempt_enable(); } while(0) |
40 | 41 | ||
42 | /* We need a safe address that is cheap to find and that is already | ||
43 | in L1 during context switch. The best choices are unfortunately | ||
44 | different for UP and SMP */ | ||
45 | #ifdef CONFIG_SMP | ||
46 | #define safe_address (__per_cpu_offset[0]) | ||
47 | #else | ||
48 | #define safe_address (kstat_cpu(0).cpustat.user) | ||
49 | #endif | ||
50 | |||
41 | /* | 51 | /* |
42 | * These must be called with preempt disabled | 52 | * These must be called with preempt disabled |
43 | */ | 53 | */ |
44 | static inline void __save_init_fpu( struct task_struct *tsk ) | 54 | static inline void __save_init_fpu( struct task_struct *tsk ) |
45 | { | 55 | { |
56 | /* Use more nops than strictly needed in case the compiler | ||
57 | varies code */ | ||
46 | alternative_input( | 58 | alternative_input( |
47 | "fnsave %1 ; fwait ;" GENERIC_NOP2, | 59 | "fnsave %[fx] ;fwait;" GENERIC_NOP8 GENERIC_NOP4, |
48 | "fxsave %1 ; fnclex", | 60 | "fxsave %[fx]\n" |
61 | "bt $7,%[fsw] ; jc 1f ; fnclex\n1:", | ||
49 | X86_FEATURE_FXSR, | 62 | X86_FEATURE_FXSR, |
50 | "m" (tsk->thread.i387.fxsave) | 63 | [fx] "m" (tsk->thread.i387.fxsave), |
51 | :"memory"); | 64 | [fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory"); |
65 | /* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception | ||
66 | is pending. Clear the x87 state here by setting it to fixed | ||
67 | values. __per_cpu_offset[0] is a random variable that should be in L1 */ | ||
68 | alternative_input( | ||
69 | GENERIC_NOP8 GENERIC_NOP2, | ||
70 | "emms\n\t" /* clear stack tags */ | ||
71 | "fildl %[addr]", /* set F?P to defined value */ | ||
72 | X86_FEATURE_FXSAVE_LEAK, | ||
73 | [addr] "m" (safe_address)); | ||
52 | task_thread_info(tsk)->status &= ~TS_USEDFPU; | 74 | task_thread_info(tsk)->status &= ~TS_USEDFPU; |
53 | } | 75 | } |
54 | 76 | ||
diff --git a/include/asm-i386/unistd.h b/include/asm-i386/unistd.h index d81d6cfc1bb4..eb4b152c82fc 100644 --- a/include/asm-i386/unistd.h +++ b/include/asm-i386/unistd.h | |||
@@ -321,8 +321,9 @@ | |||
321 | #define __NR_splice 313 | 321 | #define __NR_splice 313 |
322 | #define __NR_sync_file_range 314 | 322 | #define __NR_sync_file_range 314 |
323 | #define __NR_tee 315 | 323 | #define __NR_tee 315 |
324 | #define __NR_vmsplice 316 | ||
324 | 325 | ||
325 | #define NR_syscalls 316 | 326 | #define NR_syscalls 317 |
326 | 327 | ||
327 | /* | 328 | /* |
328 | * user-visible error numbers are in the range -1 - -128: see | 329 | * user-visible error numbers are in the range -1 - -128: see |
diff --git a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h index a40ebec6aeeb..7107763168bf 100644 --- a/include/asm-ia64/unistd.h +++ b/include/asm-ia64/unistd.h | |||
@@ -290,12 +290,13 @@ | |||
290 | #define __NR_get_robust_list 1299 | 290 | #define __NR_get_robust_list 1299 |
291 | #define __NR_sync_file_range 1300 | 291 | #define __NR_sync_file_range 1300 |
292 | #define __NR_tee 1301 | 292 | #define __NR_tee 1301 |
293 | #define __NR_vmsplice 1302 | ||
293 | 294 | ||
294 | #ifdef __KERNEL__ | 295 | #ifdef __KERNEL__ |
295 | 296 | ||
296 | #include <linux/config.h> | 297 | #include <linux/config.h> |
297 | 298 | ||
298 | #define NR_syscalls 278 /* length of syscall table */ | 299 | #define NR_syscalls 279 /* length of syscall table */ |
299 | 300 | ||
300 | #define __ARCH_WANT_SYS_RT_SIGACTION | 301 | #define __ARCH_WANT_SYS_RT_SIGACTION |
301 | 302 | ||
diff --git a/include/asm-m32r/assembler.h b/include/asm-m32r/assembler.h index b7f4d8aaeb46..1a1aa17edd33 100644 --- a/include/asm-m32r/assembler.h +++ b/include/asm-m32r/assembler.h | |||
@@ -109,6 +109,9 @@ | |||
109 | push r13 | 109 | push r13 |
110 | mvfachi r13 | 110 | mvfachi r13 |
111 | push r13 | 111 | push r13 |
112 | ldi r13, #0 | ||
113 | push r13 ; dummy push acc1h | ||
114 | push r13 ; dummy push acc1l | ||
112 | #else | 115 | #else |
113 | #error unknown isa configuration | 116 | #error unknown isa configuration |
114 | #endif | 117 | #endif |
@@ -156,6 +159,8 @@ | |||
156 | pop r13 | 159 | pop r13 |
157 | mvtaclo r13, a1 | 160 | mvtaclo r13, a1 |
158 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | 161 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) |
162 | pop r13 ; dummy pop acc1h | ||
163 | pop r13 ; dummy pop acc1l | ||
159 | pop r13 | 164 | pop r13 |
160 | mvtachi r13 | 165 | mvtachi r13 |
161 | pop r13 | 166 | pop r13 |
diff --git a/include/asm-m32r/mappi3/mappi3_pld.h b/include/asm-m32r/mappi3/mappi3_pld.h index 1d3c25d61bcb..031369a7afc8 100644 --- a/include/asm-m32r/mappi3/mappi3_pld.h +++ b/include/asm-m32r/mappi3/mappi3_pld.h | |||
@@ -53,16 +53,14 @@ | |||
53 | /* Power Control of MMC and CF */ | 53 | /* Power Control of MMC and CF */ |
54 | #define PLD_CPCR __reg16(PLD_BASE + 0x14000) | 54 | #define PLD_CPCR __reg16(PLD_BASE + 0x14000) |
55 | 55 | ||
56 | 56 | /* ICU */ | |
57 | /*==== ICU ====*/ | 57 | #define M32R_IRQ_PC104 (5) /* INT4(PC/104) */ |
58 | #define M32R_IRQ_PC104 (5) /* INT4(PC/104) */ | 58 | #define M32R_IRQ_I2C (28) /* I2C-BUS */ |
59 | #define M32R_IRQ_I2C (28) /* I2C-BUS */ | 59 | #define PLD_IRQ_CFIREQ (6) /* INT5 CFC Card Interrupt */ |
60 | #define PLD_IRQ_CFIREQ (6) /* INT5 CFC Card Interrupt */ | 60 | #define PLD_IRQ_CFC_INSERT (7) /* INT6 CFC Card Insert & Eject */ |
61 | #define PLD_IRQ_CFC_INSERT (7) /* INT6 CFC Card Insert */ | 61 | #define PLD_IRQ_IDEIREQ (8) /* INT7 IDE Interrupt */ |
62 | #define PLD_IRQ_IDEIREQ (8) /* INT7 IDE Interrupt */ | 62 | #define PLD_IRQ_MMCCARD (43) /* MMC Card Insert */ |
63 | #define PLD_IRQ_MMCCARD (43) /* MMC Card Insert */ | 63 | #define PLD_IRQ_MMCIRQ (44) /* MMC Transfer Done */ |
64 | #define PLD_IRQ_MMCIRQ (44) /* MMC Transfer Done */ | ||
65 | |||
66 | 64 | ||
67 | #if 0 | 65 | #if 0 |
68 | /* LED Control | 66 | /* LED Control |
@@ -97,7 +95,6 @@ | |||
97 | #define PLD_CRC16ADATA __reg16(PLD_BASE + 0x18008) | 95 | #define PLD_CRC16ADATA __reg16(PLD_BASE + 0x18008) |
98 | #define PLD_CRC16AINDATA __reg16(PLD_BASE + 0x1800a) | 96 | #define PLD_CRC16AINDATA __reg16(PLD_BASE + 0x1800a) |
99 | 97 | ||
100 | |||
101 | #if 0 | 98 | #if 0 |
102 | /* RTC */ | 99 | /* RTC */ |
103 | #define PLD_RTCCR __reg16(PLD_BASE + 0x1c000) | 100 | #define PLD_RTCCR __reg16(PLD_BASE + 0x1c000) |
@@ -140,4 +137,7 @@ | |||
140 | 137 | ||
141 | #endif | 138 | #endif |
142 | 139 | ||
140 | /* Reset Control */ | ||
141 | #define PLD_REBOOT __reg16(PLD_BASE + 0x38000) | ||
142 | |||
143 | #endif /* _MAPPI3_PLD.H */ | 143 | #endif /* _MAPPI3_PLD.H */ |
diff --git a/include/asm-m32r/ptrace.h b/include/asm-m32r/ptrace.h index 0d058b2d844e..53c792452dfc 100644 --- a/include/asm-m32r/ptrace.h +++ b/include/asm-m32r/ptrace.h | |||
@@ -43,6 +43,14 @@ | |||
43 | #define PT_ACC1L 18 | 43 | #define PT_ACC1L 18 |
44 | #define PT_ACCH PT_ACC0H | 44 | #define PT_ACCH PT_ACC0H |
45 | #define PT_ACCL PT_ACC0L | 45 | #define PT_ACCL PT_ACC0L |
46 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | ||
47 | #define PT_ACCH 15 | ||
48 | #define PT_ACCL 16 | ||
49 | #define PT_DUMMY_ACC1H 17 | ||
50 | #define PT_DUMMY_ACC1L 18 | ||
51 | #else | ||
52 | #error unknown isa conifiguration | ||
53 | #endif | ||
46 | #define PT_PSW 19 | 54 | #define PT_PSW 19 |
47 | #define PT_BPC 20 | 55 | #define PT_BPC 20 |
48 | #define PT_BBPSW 21 | 56 | #define PT_BBPSW 21 |
@@ -52,21 +60,6 @@ | |||
52 | #define PT_LR 25 | 60 | #define PT_LR 25 |
53 | #define PT_SPI 26 | 61 | #define PT_SPI 26 |
54 | #define PT_ORIGR0 27 | 62 | #define PT_ORIGR0 27 |
55 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | ||
56 | #define PT_ACCH 15 | ||
57 | #define PT_ACCL 16 | ||
58 | #define PT_PSW 17 | ||
59 | #define PT_BPC 18 | ||
60 | #define PT_BBPSW 19 | ||
61 | #define PT_BBPC 20 | ||
62 | #define PT_SPU 21 | ||
63 | #define PT_FP 22 | ||
64 | #define PT_LR 23 | ||
65 | #define PT_SPI 24 | ||
66 | #define PT_ORIGR0 25 | ||
67 | #else | ||
68 | #error unknown isa conifiguration | ||
69 | #endif | ||
70 | 63 | ||
71 | /* virtual pt_reg entry for gdb */ | 64 | /* virtual pt_reg entry for gdb */ |
72 | #define PT_PC 30 | 65 | #define PT_PC 30 |
@@ -121,6 +114,8 @@ struct pt_regs { | |||
121 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | 114 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) |
122 | unsigned long acch; | 115 | unsigned long acch; |
123 | unsigned long accl; | 116 | unsigned long accl; |
117 | unsigned long dummy_acc1h; | ||
118 | unsigned long dummy_acc1l; | ||
124 | #else | 119 | #else |
125 | #error unknown isa configuration | 120 | #error unknown isa configuration |
126 | #endif | 121 | #endif |
diff --git a/include/asm-m32r/semaphore.h b/include/asm-m32r/semaphore.h index bf447c52a0a1..81750edc8916 100644 --- a/include/asm-m32r/semaphore.h +++ b/include/asm-m32r/semaphore.h | |||
@@ -9,7 +9,7 @@ | |||
9 | * SMP- and interrupt-safe semaphores.. | 9 | * SMP- and interrupt-safe semaphores.. |
10 | * | 10 | * |
11 | * Copyright (C) 1996 Linus Torvalds | 11 | * Copyright (C) 1996 Linus Torvalds |
12 | * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org> | 12 | * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/config.h> | 15 | #include <linux/config.h> |
@@ -77,27 +77,8 @@ asmlinkage void __up(struct semaphore * sem); | |||
77 | */ | 77 | */ |
78 | static inline void down(struct semaphore * sem) | 78 | static inline void down(struct semaphore * sem) |
79 | { | 79 | { |
80 | unsigned long flags; | ||
81 | long count; | ||
82 | |||
83 | might_sleep(); | 80 | might_sleep(); |
84 | local_irq_save(flags); | 81 | if (unlikely(atomic_dec_return(&sem->count) < 0)) |
85 | __asm__ __volatile__ ( | ||
86 | "# down \n\t" | ||
87 | DCACHE_CLEAR("%0", "r4", "%1") | ||
88 | M32R_LOCK" %0, @%1; \n\t" | ||
89 | "addi %0, #-1; \n\t" | ||
90 | M32R_UNLOCK" %0, @%1; \n\t" | ||
91 | : "=&r" (count) | ||
92 | : "r" (&sem->count) | ||
93 | : "memory" | ||
94 | #ifdef CONFIG_CHIP_M32700_TS1 | ||
95 | , "r4" | ||
96 | #endif /* CONFIG_CHIP_M32700_TS1 */ | ||
97 | ); | ||
98 | local_irq_restore(flags); | ||
99 | |||
100 | if (unlikely(count < 0)) | ||
101 | __down(sem); | 82 | __down(sem); |
102 | } | 83 | } |
103 | 84 | ||
@@ -107,28 +88,10 @@ static inline void down(struct semaphore * sem) | |||
107 | */ | 88 | */ |
108 | static inline int down_interruptible(struct semaphore * sem) | 89 | static inline int down_interruptible(struct semaphore * sem) |
109 | { | 90 | { |
110 | unsigned long flags; | ||
111 | long count; | ||
112 | int result = 0; | 91 | int result = 0; |
113 | 92 | ||
114 | might_sleep(); | 93 | might_sleep(); |
115 | local_irq_save(flags); | 94 | if (unlikely(atomic_dec_return(&sem->count) < 0)) |
116 | __asm__ __volatile__ ( | ||
117 | "# down_interruptible \n\t" | ||
118 | DCACHE_CLEAR("%0", "r4", "%1") | ||
119 | M32R_LOCK" %0, @%1; \n\t" | ||
120 | "addi %0, #-1; \n\t" | ||
121 | M32R_UNLOCK" %0, @%1; \n\t" | ||
122 | : "=&r" (count) | ||
123 | : "r" (&sem->count) | ||
124 | : "memory" | ||
125 | #ifdef CONFIG_CHIP_M32700_TS1 | ||
126 | , "r4" | ||
127 | #endif /* CONFIG_CHIP_M32700_TS1 */ | ||
128 | ); | ||
129 | local_irq_restore(flags); | ||
130 | |||
131 | if (unlikely(count < 0)) | ||
132 | result = __down_interruptible(sem); | 95 | result = __down_interruptible(sem); |
133 | 96 | ||
134 | return result; | 97 | return result; |
@@ -174,26 +137,7 @@ static inline int down_trylock(struct semaphore * sem) | |||
174 | */ | 137 | */ |
175 | static inline void up(struct semaphore * sem) | 138 | static inline void up(struct semaphore * sem) |
176 | { | 139 | { |
177 | unsigned long flags; | 140 | if (unlikely(atomic_inc_return(&sem->count) <= 0)) |
178 | long count; | ||
179 | |||
180 | local_irq_save(flags); | ||
181 | __asm__ __volatile__ ( | ||
182 | "# up \n\t" | ||
183 | DCACHE_CLEAR("%0", "r4", "%1") | ||
184 | M32R_LOCK" %0, @%1; \n\t" | ||
185 | "addi %0, #1; \n\t" | ||
186 | M32R_UNLOCK" %0, @%1; \n\t" | ||
187 | : "=&r" (count) | ||
188 | : "r" (&sem->count) | ||
189 | : "memory" | ||
190 | #ifdef CONFIG_CHIP_M32700_TS1 | ||
191 | , "r4" | ||
192 | #endif /* CONFIG_CHIP_M32700_TS1 */ | ||
193 | ); | ||
194 | local_irq_restore(flags); | ||
195 | |||
196 | if (unlikely(count <= 0)) | ||
197 | __up(sem); | 141 | __up(sem); |
198 | } | 142 | } |
199 | 143 | ||
diff --git a/include/asm-m32r/sigcontext.h b/include/asm-m32r/sigcontext.h index c233e2def2a3..942b8a30937d 100644 --- a/include/asm-m32r/sigcontext.h +++ b/include/asm-m32r/sigcontext.h | |||
@@ -32,6 +32,8 @@ struct sigcontext { | |||
32 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) | 32 | #elif defined(CONFIG_ISA_M32R2) || defined(CONFIG_ISA_M32R) |
33 | unsigned long sc_acch; | 33 | unsigned long sc_acch; |
34 | unsigned long sc_accl; | 34 | unsigned long sc_accl; |
35 | unsigned long sc_dummy_acc1h; | ||
36 | unsigned long sc_dummy_acc1l; | ||
35 | #else | 37 | #else |
36 | #error unknown isa configuration | 38 | #error unknown isa configuration |
37 | #endif | 39 | #endif |
diff --git a/include/asm-m32r/system.h b/include/asm-m32r/system.h index c5ab5da56d21..e55013f378e5 100644 --- a/include/asm-m32r/system.h +++ b/include/asm-m32r/system.h | |||
@@ -6,8 +6,8 @@ | |||
6 | * License. See the file "COPYING" in the main directory of this archive | 6 | * License. See the file "COPYING" in the main directory of this archive |
7 | * for more details. | 7 | * for more details. |
8 | * | 8 | * |
9 | * Copyright (C) 2001 by Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto | 9 | * Copyright (C) 2001 Hiroyuki Kondo, Hirokazu Takata, and Hitoshi Yamamoto |
10 | * Copyright (C) 2004 Hirokazu Takata <takata at linux-m32r.org> | 10 | * Copyright (C) 2004, 2006 Hirokazu Takata <takata at linux-m32r.org> |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/config.h> | 13 | #include <linux/config.h> |
@@ -19,49 +19,28 @@ | |||
19 | * switch_to(prev, next) should switch from task `prev' to `next' | 19 | * switch_to(prev, next) should switch from task `prev' to `next' |
20 | * `prev' will never be the same as `next'. | 20 | * `prev' will never be the same as `next'. |
21 | * | 21 | * |
22 | * `next' and `prev' should be struct task_struct, but it isn't always defined | 22 | * `next' and `prev' should be task_t, but it isn't always defined |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #define switch_to(prev, next, last) do { \ | 25 | #define switch_to(prev, next, last) do { \ |
26 | register unsigned long arg0 __asm__ ("r0") = (unsigned long)prev; \ | ||
27 | register unsigned long arg1 __asm__ ("r1") = (unsigned long)next; \ | ||
28 | register unsigned long *oldsp __asm__ ("r2") = &(prev->thread.sp); \ | ||
29 | register unsigned long *newsp __asm__ ("r3") = &(next->thread.sp); \ | ||
30 | register unsigned long *oldlr __asm__ ("r4") = &(prev->thread.lr); \ | ||
31 | register unsigned long *newlr __asm__ ("r5") = &(next->thread.lr); \ | ||
32 | register struct task_struct *__last __asm__ ("r6"); \ | ||
33 | __asm__ __volatile__ ( \ | 26 | __asm__ __volatile__ ( \ |
34 | "st r8, @-r15 \n\t" \ | 27 | " seth lr, #high(1f) \n" \ |
35 | "st r9, @-r15 \n\t" \ | 28 | " or3 lr, lr, #low(1f) \n" \ |
36 | "st r10, @-r15 \n\t" \ | 29 | " st lr, @%4 ; store old LR \n" \ |
37 | "st r11, @-r15 \n\t" \ | 30 | " ld lr, @%5 ; load new LR \n" \ |
38 | "st r12, @-r15 \n\t" \ | 31 | " st sp, @%2 ; store old SP \n" \ |
39 | "st r13, @-r15 \n\t" \ | 32 | " ld sp, @%3 ; load new SP \n" \ |
40 | "st r14, @-r15 \n\t" \ | 33 | " push %1 ; store `prev' on new stack \n" \ |
41 | "seth r14, #high(1f) \n\t" \ | 34 | " jmp lr \n" \ |
42 | "or3 r14, r14, #low(1f) \n\t" \ | 35 | " .fillinsn \n" \ |
43 | "st r14, @r4 ; store old LR \n\t" \ | 36 | "1: \n" \ |
44 | "st r15, @r2 ; store old SP \n\t" \ | 37 | " pop %0 ; restore `__last' from new stack \n" \ |
45 | "ld r15, @r3 ; load new SP \n\t" \ | 38 | : "=r" (last) \ |
46 | "st r0, @-r15 ; store 'prev' onto new stack \n\t" \ | 39 | : "0" (prev), \ |
47 | "ld r14, @r5 ; load new LR \n\t" \ | 40 | "r" (&(prev->thread.sp)), "r" (&(next->thread.sp)), \ |
48 | "jmp r14 \n\t" \ | 41 | "r" (&(prev->thread.lr)), "r" (&(next->thread.lr)) \ |
49 | ".fillinsn \n " \ | 42 | : "memory", "lr" \ |
50 | "1: \n\t" \ | ||
51 | "ld r6, @r15+ ; load 'prev' from new stack \n\t" \ | ||
52 | "ld r14, @r15+ \n\t" \ | ||
53 | "ld r13, @r15+ \n\t" \ | ||
54 | "ld r12, @r15+ \n\t" \ | ||
55 | "ld r11, @r15+ \n\t" \ | ||
56 | "ld r10, @r15+ \n\t" \ | ||
57 | "ld r9, @r15+ \n\t" \ | ||
58 | "ld r8, @r15+ \n\t" \ | ||
59 | : "=&r" (__last) \ | ||
60 | : "r" (arg0), "r" (arg1), "r" (oldsp), "r" (newsp), \ | ||
61 | "r" (oldlr), "r" (newlr) \ | ||
62 | : "memory" \ | ||
63 | ); \ | 43 | ); \ |
64 | last = __last; \ | ||
65 | } while(0) | 44 | } while(0) |
66 | 45 | ||
67 | /* | 46 | /* |
@@ -167,8 +146,8 @@ extern void __xchg_called_with_bad_pointer(void); | |||
167 | #define DCACHE_CLEAR(reg0, reg1, addr) | 146 | #define DCACHE_CLEAR(reg0, reg1, addr) |
168 | #endif /* CONFIG_CHIP_M32700_TS1 */ | 147 | #endif /* CONFIG_CHIP_M32700_TS1 */ |
169 | 148 | ||
170 | static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, | 149 | static inline unsigned long |
171 | int size) | 150 | __xchg(unsigned long x, volatile void * ptr, int size) |
172 | { | 151 | { |
173 | unsigned long flags; | 152 | unsigned long flags; |
174 | unsigned long tmp = 0; | 153 | unsigned long tmp = 0; |
@@ -220,7 +199,7 @@ static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, | |||
220 | 199 | ||
221 | #define __HAVE_ARCH_CMPXCHG 1 | 200 | #define __HAVE_ARCH_CMPXCHG 1 |
222 | 201 | ||
223 | static __inline__ unsigned long | 202 | static inline unsigned long |
224 | __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new) | 203 | __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new) |
225 | { | 204 | { |
226 | unsigned long flags; | 205 | unsigned long flags; |
@@ -254,7 +233,7 @@ __cmpxchg_u32(volatile unsigned int *p, unsigned int old, unsigned int new) | |||
254 | if something tries to do an invalid cmpxchg(). */ | 233 | if something tries to do an invalid cmpxchg(). */ |
255 | extern void __cmpxchg_called_with_bad_pointer(void); | 234 | extern void __cmpxchg_called_with_bad_pointer(void); |
256 | 235 | ||
257 | static __inline__ unsigned long | 236 | static inline unsigned long |
258 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | 237 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) |
259 | { | 238 | { |
260 | switch (size) { | 239 | switch (size) { |
diff --git a/include/asm-mips/asmmacro.h b/include/asm-mips/asmmacro.h index 30b18ea6cb11..f54aa147ec19 100644 --- a/include/asm-mips/asmmacro.h +++ b/include/asm-mips/asmmacro.h | |||
@@ -17,7 +17,26 @@ | |||
17 | #ifdef CONFIG_64BIT | 17 | #ifdef CONFIG_64BIT |
18 | #include <asm/asmmacro-64.h> | 18 | #include <asm/asmmacro-64.h> |
19 | #endif | 19 | #endif |
20 | #ifdef CONFIG_MIPS_MT_SMTC | ||
21 | #include <asm/mipsmtregs.h> | ||
22 | #endif | ||
20 | 23 | ||
24 | #ifdef CONFIG_MIPS_MT_SMTC | ||
25 | .macro local_irq_enable reg=t0 | ||
26 | mfc0 \reg, CP0_TCSTATUS | ||
27 | ori \reg, \reg, TCSTATUS_IXMT | ||
28 | xori \reg, \reg, TCSTATUS_IXMT | ||
29 | mtc0 \reg, CP0_TCSTATUS | ||
30 | ehb | ||
31 | .endm | ||
32 | |||
33 | .macro local_irq_disable reg=t0 | ||
34 | mfc0 \reg, CP0_TCSTATUS | ||
35 | ori \reg, \reg, TCSTATUS_IXMT | ||
36 | mtc0 \reg, CP0_TCSTATUS | ||
37 | ehb | ||
38 | .endm | ||
39 | #else | ||
21 | .macro local_irq_enable reg=t0 | 40 | .macro local_irq_enable reg=t0 |
22 | mfc0 \reg, CP0_STATUS | 41 | mfc0 \reg, CP0_STATUS |
23 | ori \reg, \reg, 1 | 42 | ori \reg, \reg, 1 |
@@ -32,6 +51,7 @@ | |||
32 | mtc0 \reg, CP0_STATUS | 51 | mtc0 \reg, CP0_STATUS |
33 | irq_disable_hazard | 52 | irq_disable_hazard |
34 | .endm | 53 | .endm |
54 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
35 | 55 | ||
36 | #ifdef CONFIG_CPU_SB1 | 56 | #ifdef CONFIG_CPU_SB1 |
37 | .macro fpu_enable_hazard | 57 | .macro fpu_enable_hazard |
@@ -48,4 +68,31 @@ | |||
48 | .endm | 68 | .endm |
49 | #endif | 69 | #endif |
50 | 70 | ||
71 | /* | ||
72 | * Temporary until all gas have MT ASE support | ||
73 | */ | ||
74 | .macro DMT reg=0 | ||
75 | .word (0x41600bc1 | (\reg << 16)) | ||
76 | .endm | ||
77 | |||
78 | .macro EMT reg=0 | ||
79 | .word (0x41600be1 | (\reg << 16)) | ||
80 | .endm | ||
81 | |||
82 | .macro DVPE reg=0 | ||
83 | .word (0x41600001 | (\reg << 16)) | ||
84 | .endm | ||
85 | |||
86 | .macro EVPE reg=0 | ||
87 | .word (0x41600021 | (\reg << 16)) | ||
88 | .endm | ||
89 | |||
90 | .macro MFTR rt=0, rd=0, u=0, sel=0 | ||
91 | .word (0x41000000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)) | ||
92 | .endm | ||
93 | |||
94 | .macro MTTR rt=0, rd=0, u=0, sel=0 | ||
95 | .word (0x41800000 | (\rt << 16) | (\rd << 11) | (\u << 5) | (\sel)) | ||
96 | .endm | ||
97 | |||
51 | #endif /* _ASM_ASMMACRO_H */ | 98 | #endif /* _ASM_ASMMACRO_H */ |
diff --git a/include/asm-mips/cacheflush.h b/include/asm-mips/cacheflush.h index aeae9fabf4a9..47bc8f6c20d2 100644 --- a/include/asm-mips/cacheflush.h +++ b/include/asm-mips/cacheflush.h | |||
@@ -74,6 +74,7 @@ static inline void copy_from_user_page(struct vm_area_struct *vma, | |||
74 | 74 | ||
75 | extern void (*flush_cache_sigtramp)(unsigned long addr); | 75 | extern void (*flush_cache_sigtramp)(unsigned long addr); |
76 | extern void (*flush_icache_all)(void); | 76 | extern void (*flush_icache_all)(void); |
77 | extern void (*local_flush_data_cache_page)(void * addr); | ||
77 | extern void (*flush_data_cache_page)(unsigned long addr); | 78 | extern void (*flush_data_cache_page)(unsigned long addr); |
78 | 79 | ||
79 | /* | 80 | /* |
diff --git a/include/asm-mips/cpu-features.h b/include/asm-mips/cpu-features.h index 3f2b6d9ac45e..254e11ed247b 100644 --- a/include/asm-mips/cpu-features.h +++ b/include/asm-mips/cpu-features.h | |||
@@ -40,7 +40,7 @@ | |||
40 | #define cpu_has_sb1_cache (cpu_data[0].options & MIPS_CPU_SB1_CACHE) | 40 | #define cpu_has_sb1_cache (cpu_data[0].options & MIPS_CPU_SB1_CACHE) |
41 | #endif | 41 | #endif |
42 | #ifndef cpu_has_fpu | 42 | #ifndef cpu_has_fpu |
43 | #define cpu_has_fpu (cpu_data[0].options & MIPS_CPU_FPU) | 43 | #define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU) |
44 | #endif | 44 | #endif |
45 | #ifndef cpu_has_32fpr | 45 | #ifndef cpu_has_32fpr |
46 | #define cpu_has_32fpr (cpu_data[0].options & MIPS_CPU_32FPR) | 46 | #define cpu_has_32fpr (cpu_data[0].options & MIPS_CPU_32FPR) |
diff --git a/include/asm-mips/cpu-info.h b/include/asm-mips/cpu-info.h index 140be1c67da7..6572ac703662 100644 --- a/include/asm-mips/cpu-info.h +++ b/include/asm-mips/cpu-info.h | |||
@@ -73,6 +73,16 @@ struct cpuinfo_mips { | |||
73 | struct cache_desc dcache; /* Primary D or combined I/D cache */ | 73 | struct cache_desc dcache; /* Primary D or combined I/D cache */ |
74 | struct cache_desc scache; /* Secondary cache */ | 74 | struct cache_desc scache; /* Secondary cache */ |
75 | struct cache_desc tcache; /* Tertiary/split secondary cache */ | 75 | struct cache_desc tcache; /* Tertiary/split secondary cache */ |
76 | #if defined(CONFIG_MIPS_MT_SMTC) | ||
77 | /* | ||
78 | * In the MIPS MT "SMTC" model, each TC is considered | ||
79 | * to be a "CPU" for the purposes of scheduling, but | ||
80 | * exception resources, ASID spaces, etc, are common | ||
81 | * to all TCs within the same VPE. | ||
82 | */ | ||
83 | int vpe_id; /* Virtual Processor number */ | ||
84 | int tc_id; /* Thread Context number */ | ||
85 | #endif /* CONFIG_MIPS_MT */ | ||
76 | void *data; /* Additional data */ | 86 | void *data; /* Additional data */ |
77 | } __attribute__((aligned(SMP_CACHE_BYTES))); | 87 | } __attribute__((aligned(SMP_CACHE_BYTES))); |
78 | 88 | ||
diff --git a/include/asm-mips/ds1742.h b/include/asm-mips/ds1742.h new file mode 100644 index 000000000000..c2f2c32da637 --- /dev/null +++ b/include/asm-mips/ds1742.h | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org) | ||
7 | */ | ||
8 | #ifndef _ASM_DS1742_H | ||
9 | #define _ASM_DS1742_H | ||
10 | |||
11 | #include <ds1742.h> | ||
12 | |||
13 | #endif /* _ASM_DS1742_H */ | ||
diff --git a/include/asm-mips/elf.h b/include/asm-mips/elf.h index 851f013adad3..bdc9de2df1ef 100644 --- a/include/asm-mips/elf.h +++ b/include/asm-mips/elf.h | |||
@@ -119,8 +119,49 @@ | |||
119 | #define SHT_MIPS_CONFLICT 0x70000002 | 119 | #define SHT_MIPS_CONFLICT 0x70000002 |
120 | #define SHT_MIPS_GPTAB 0x70000003 | 120 | #define SHT_MIPS_GPTAB 0x70000003 |
121 | #define SHT_MIPS_UCODE 0x70000004 | 121 | #define SHT_MIPS_UCODE 0x70000004 |
122 | 122 | #define SHT_MIPS_DEBUG 0x70000005 | |
123 | #define SHF_MIPS_GPREL 0x10000000 | 123 | #define SHT_MIPS_REGINFO 0x70000006 |
124 | #define SHT_MIPS_PACKAGE 0x70000007 | ||
125 | #define SHT_MIPS_PACKSYM 0x70000008 | ||
126 | #define SHT_MIPS_RELD 0x70000009 | ||
127 | #define SHT_MIPS_IFACE 0x7000000b | ||
128 | #define SHT_MIPS_CONTENT 0x7000000c | ||
129 | #define SHT_MIPS_OPTIONS 0x7000000d | ||
130 | #define SHT_MIPS_SHDR 0x70000010 | ||
131 | #define SHT_MIPS_FDESC 0x70000011 | ||
132 | #define SHT_MIPS_EXTSYM 0x70000012 | ||
133 | #define SHT_MIPS_DENSE 0x70000013 | ||
134 | #define SHT_MIPS_PDESC 0x70000014 | ||
135 | #define SHT_MIPS_LOCSYM 0x70000015 | ||
136 | #define SHT_MIPS_AUXSYM 0x70000016 | ||
137 | #define SHT_MIPS_OPTSYM 0x70000017 | ||
138 | #define SHT_MIPS_LOCSTR 0x70000018 | ||
139 | #define SHT_MIPS_LINE 0x70000019 | ||
140 | #define SHT_MIPS_RFDESC 0x7000001a | ||
141 | #define SHT_MIPS_DELTASYM 0x7000001b | ||
142 | #define SHT_MIPS_DELTAINST 0x7000001c | ||
143 | #define SHT_MIPS_DELTACLASS 0x7000001d | ||
144 | #define SHT_MIPS_DWARF 0x7000001e | ||
145 | #define SHT_MIPS_DELTADECL 0x7000001f | ||
146 | #define SHT_MIPS_SYMBOL_LIB 0x70000020 | ||
147 | #define SHT_MIPS_EVENTS 0x70000021 | ||
148 | #define SHT_MIPS_TRANSLATE 0x70000022 | ||
149 | #define SHT_MIPS_PIXIE 0x70000023 | ||
150 | #define SHT_MIPS_XLATE 0x70000024 | ||
151 | #define SHT_MIPS_XLATE_DEBUG 0x70000025 | ||
152 | #define SHT_MIPS_WHIRL 0x70000026 | ||
153 | #define SHT_MIPS_EH_REGION 0x70000027 | ||
154 | #define SHT_MIPS_XLATE_OLD 0x70000028 | ||
155 | #define SHT_MIPS_PDR_EXCEPTION 0x70000029 | ||
156 | |||
157 | #define SHF_MIPS_GPREL 0x10000000 | ||
158 | #define SHF_MIPS_MERGE 0x20000000 | ||
159 | #define SHF_MIPS_ADDR 0x40000000 | ||
160 | #define SHF_MIPS_STRING 0x80000000 | ||
161 | #define SHF_MIPS_NOSTRIP 0x08000000 | ||
162 | #define SHF_MIPS_LOCAL 0x04000000 | ||
163 | #define SHF_MIPS_NAMES 0x02000000 | ||
164 | #define SHF_MIPS_NODUPES 0x01000000 | ||
124 | 165 | ||
125 | #ifndef ELF_ARCH | 166 | #ifndef ELF_ARCH |
126 | /* ELF register definitions */ | 167 | /* ELF register definitions */ |
diff --git a/include/asm-mips/fpu.h b/include/asm-mips/fpu.h index 9c828b1f8218..b0f50015e252 100644 --- a/include/asm-mips/fpu.h +++ b/include/asm-mips/fpu.h | |||
@@ -21,6 +21,10 @@ | |||
21 | #include <asm/processor.h> | 21 | #include <asm/processor.h> |
22 | #include <asm/current.h> | 22 | #include <asm/current.h> |
23 | 23 | ||
24 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
25 | #include <asm/mips_mt.h> | ||
26 | #endif | ||
27 | |||
24 | struct sigcontext; | 28 | struct sigcontext; |
25 | struct sigcontext32; | 29 | struct sigcontext32; |
26 | 30 | ||
diff --git a/include/asm-mips/hazards.h b/include/asm-mips/hazards.h index feb29a793888..dadc05188db7 100644 --- a/include/asm-mips/hazards.h +++ b/include/asm-mips/hazards.h | |||
@@ -284,6 +284,8 @@ do { \ | |||
284 | #define instruction_hazard() do { } while (0) | 284 | #define instruction_hazard() do { } while (0) |
285 | #endif | 285 | #endif |
286 | 286 | ||
287 | extern void mips_ihb(void); | ||
288 | |||
287 | #endif /* __ASSEMBLY__ */ | 289 | #endif /* __ASSEMBLY__ */ |
288 | 290 | ||
289 | #endif /* _ASM_HAZARDS_H */ | 291 | #endif /* _ASM_HAZARDS_H */ |
diff --git a/include/asm-mips/interrupt.h b/include/asm-mips/interrupt.h index 774348734fa0..4bb9c06f4410 100644 --- a/include/asm-mips/interrupt.h +++ b/include/asm-mips/interrupt.h | |||
@@ -19,7 +19,12 @@ __asm__ ( | |||
19 | " .set push \n" | 19 | " .set push \n" |
20 | " .set reorder \n" | 20 | " .set reorder \n" |
21 | " .set noat \n" | 21 | " .set noat \n" |
22 | #ifdef CONFIG_CPU_MIPSR2 | 22 | #ifdef CONFIG_MIPS_MT_SMTC |
23 | " mfc0 $1, $2, 1 # SMTC - clear TCStatus.IXMT \n" | ||
24 | " ori $1, 0x400 \n" | ||
25 | " xori $1, 0x400 \n" | ||
26 | " mtc0 $1, $2, 1 \n" | ||
27 | #elif defined(CONFIG_CPU_MIPSR2) | ||
23 | " ei \n" | 28 | " ei \n" |
24 | #else | 29 | #else |
25 | " mfc0 $1,$12 \n" | 30 | " mfc0 $1,$12 \n" |
@@ -62,7 +67,12 @@ __asm__ ( | |||
62 | " .macro local_irq_disable\n" | 67 | " .macro local_irq_disable\n" |
63 | " .set push \n" | 68 | " .set push \n" |
64 | " .set noat \n" | 69 | " .set noat \n" |
65 | #ifdef CONFIG_CPU_MIPSR2 | 70 | #ifdef CONFIG_MIPS_MT_SMTC |
71 | " mfc0 $1, $2, 1 \n" | ||
72 | " ori $1, 0x400 \n" | ||
73 | " .set noreorder \n" | ||
74 | " mtc0 $1, $2, 1 \n" | ||
75 | #elif defined(CONFIG_CPU_MIPSR2) | ||
66 | " di \n" | 76 | " di \n" |
67 | #else | 77 | #else |
68 | " mfc0 $1,$12 \n" | 78 | " mfc0 $1,$12 \n" |
@@ -88,7 +98,11 @@ __asm__ ( | |||
88 | " .macro local_save_flags flags \n" | 98 | " .macro local_save_flags flags \n" |
89 | " .set push \n" | 99 | " .set push \n" |
90 | " .set reorder \n" | 100 | " .set reorder \n" |
101 | #ifdef CONFIG_MIPS_MT_SMTC | ||
102 | " mfc0 \\flags, $2, 1 \n" | ||
103 | #else | ||
91 | " mfc0 \\flags, $12 \n" | 104 | " mfc0 \\flags, $12 \n" |
105 | #endif | ||
92 | " .set pop \n" | 106 | " .set pop \n" |
93 | " .endm \n"); | 107 | " .endm \n"); |
94 | 108 | ||
@@ -102,7 +116,13 @@ __asm__ ( | |||
102 | " .set push \n" | 116 | " .set push \n" |
103 | " .set reorder \n" | 117 | " .set reorder \n" |
104 | " .set noat \n" | 118 | " .set noat \n" |
105 | #ifdef CONFIG_CPU_MIPSR2 | 119 | #ifdef CONFIG_MIPS_MT_SMTC |
120 | " mfc0 \\result, $2, 1 \n" | ||
121 | " ori $1, \\result, 0x400 \n" | ||
122 | " .set noreorder \n" | ||
123 | " mtc0 $1, $2, 1 \n" | ||
124 | " andi \\result, \\result, 0x400 \n" | ||
125 | #elif defined(CONFIG_CPU_MIPSR2) | ||
106 | " di \\result \n" | 126 | " di \\result \n" |
107 | " andi \\result, 1 \n" | 127 | " andi \\result, 1 \n" |
108 | #else | 128 | #else |
@@ -128,7 +148,14 @@ __asm__ ( | |||
128 | " .set push \n" | 148 | " .set push \n" |
129 | " .set noreorder \n" | 149 | " .set noreorder \n" |
130 | " .set noat \n" | 150 | " .set noat \n" |
131 | #if defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | 151 | #ifdef CONFIG_MIPS_MT_SMTC |
152 | "mfc0 $1, $2, 1 \n" | ||
153 | "andi \\flags, 0x400 \n" | ||
154 | "ori $1, 0x400 \n" | ||
155 | "xori $1, 0x400 \n" | ||
156 | "or \\flags, $1 \n" | ||
157 | "mtc0 \\flags, $2, 1 \n" | ||
158 | #elif defined(CONFIG_CPU_MIPSR2) && defined(CONFIG_IRQ_CPU) | ||
132 | /* | 159 | /* |
133 | * Slow, but doesn't suffer from a relativly unlikely race | 160 | * Slow, but doesn't suffer from a relativly unlikely race |
134 | * condition we're having since days 1. | 161 | * condition we're having since days 1. |
@@ -167,11 +194,29 @@ do { \ | |||
167 | : "memory"); \ | 194 | : "memory"); \ |
168 | } while(0) | 195 | } while(0) |
169 | 196 | ||
170 | #define irqs_disabled() \ | 197 | static inline int irqs_disabled(void) |
171 | ({ \ | 198 | { |
172 | unsigned long flags; \ | 199 | #ifdef CONFIG_MIPS_MT_SMTC |
173 | local_save_flags(flags); \ | 200 | /* |
174 | !(flags & 1); \ | 201 | * SMTC model uses TCStatus.IXMT to disable interrupts for a thread/CPU |
175 | }) | 202 | */ |
203 | unsigned long __result; | ||
204 | |||
205 | __asm__ __volatile__( | ||
206 | " .set noreorder \n" | ||
207 | " mfc0 %0, $2, 1 \n" | ||
208 | " andi %0, 0x400 \n" | ||
209 | " slt %0, $0, %0 \n" | ||
210 | " .set reorder \n" | ||
211 | : "=r" (__result)); | ||
212 | |||
213 | return __result; | ||
214 | #else | ||
215 | unsigned long flags; | ||
216 | local_save_flags(flags); | ||
217 | |||
218 | return !(flags & 1); | ||
219 | #endif | ||
220 | } | ||
176 | 221 | ||
177 | #endif /* _ASM_INTERRUPT_H */ | 222 | #endif /* _ASM_INTERRUPT_H */ |
diff --git a/include/asm-mips/irq.h b/include/asm-mips/irq.h index 8a342ccb34a8..dde677f02bc0 100644 --- a/include/asm-mips/irq.h +++ b/include/asm-mips/irq.h | |||
@@ -11,6 +11,9 @@ | |||
11 | 11 | ||
12 | #include <linux/config.h> | 12 | #include <linux/config.h> |
13 | #include <linux/linkage.h> | 13 | #include <linux/linkage.h> |
14 | |||
15 | #include <asm/mipsmtregs.h> | ||
16 | |||
14 | #include <irq.h> | 17 | #include <irq.h> |
15 | 18 | ||
16 | #ifdef CONFIG_I8259 | 19 | #ifdef CONFIG_I8259 |
@@ -26,6 +29,23 @@ struct pt_regs; | |||
26 | 29 | ||
27 | extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs); | 30 | extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs); |
28 | 31 | ||
32 | #ifdef CONFIG_MIPS_MT_SMTC | ||
33 | /* | ||
34 | * Clear interrupt mask handling "backstop" if irq_hwmask | ||
35 | * entry so indicates. This implies that the ack() or end() | ||
36 | * functions will take over re-enabling the low-level mask. | ||
37 | * Otherwise it will be done on return from exception. | ||
38 | */ | ||
39 | #define __DO_IRQ_SMTC_HOOK() \ | ||
40 | do { \ | ||
41 | if (irq_hwmask[irq] & 0x0000ff00) \ | ||
42 | write_c0_tccontext(read_c0_tccontext() & \ | ||
43 | ~(irq_hwmask[irq] & 0x0000ff00)); \ | ||
44 | } while (0) | ||
45 | #else | ||
46 | #define __DO_IRQ_SMTC_HOOK() do { } while (0) | ||
47 | #endif | ||
48 | |||
29 | #ifdef CONFIG_PREEMPT | 49 | #ifdef CONFIG_PREEMPT |
30 | 50 | ||
31 | /* | 51 | /* |
@@ -39,6 +59,7 @@ extern asmlinkage unsigned int do_IRQ(unsigned int irq, struct pt_regs *regs); | |||
39 | #define do_IRQ(irq, regs) \ | 59 | #define do_IRQ(irq, regs) \ |
40 | do { \ | 60 | do { \ |
41 | irq_enter(); \ | 61 | irq_enter(); \ |
62 | __DO_IRQ_SMTC_HOOK(); \ | ||
42 | __do_IRQ((irq), (regs)); \ | 63 | __do_IRQ((irq), (regs)); \ |
43 | irq_exit(); \ | 64 | irq_exit(); \ |
44 | } while (0) | 65 | } while (0) |
@@ -46,5 +67,14 @@ do { \ | |||
46 | #endif | 67 | #endif |
47 | 68 | ||
48 | extern void arch_init_irq(void); | 69 | extern void arch_init_irq(void); |
70 | extern void spurious_interrupt(struct pt_regs *regs); | ||
71 | |||
72 | #ifdef CONFIG_MIPS_MT_SMTC | ||
73 | struct irqaction; | ||
74 | |||
75 | extern unsigned long irq_hwmask[]; | ||
76 | extern int setup_irq_smtc(unsigned int irq, struct irqaction * new, | ||
77 | unsigned long hwmask); | ||
78 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
49 | 79 | ||
50 | #endif /* _ASM_IRQ_H */ | 80 | #endif /* _ASM_IRQ_H */ |
diff --git a/include/asm-mips/kspd.h b/include/asm-mips/kspd.h new file mode 100644 index 000000000000..4e9e724c8935 --- /dev/null +++ b/include/asm-mips/kspd.h | |||
@@ -0,0 +1,36 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can distribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License (Version 2) as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
11 | * for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #ifndef _ASM_KSPD_H | ||
20 | #define _ASM_KSPD_H | ||
21 | |||
22 | struct kspd_notifications { | ||
23 | void (*kspd_sp_exit)(int sp_id); | ||
24 | |||
25 | struct list_head list; | ||
26 | }; | ||
27 | |||
28 | #ifdef CONFIG_MIPS_APSP_KSPD | ||
29 | extern void kspd_notify(struct kspd_notifications *notify); | ||
30 | #else | ||
31 | static inline void kspd_notify(struct kspd_notifications *notify) | ||
32 | { | ||
33 | } | ||
34 | #endif | ||
35 | |||
36 | #endif | ||
diff --git a/include/asm-mips/mach-generic/ide.h b/include/asm-mips/mach-generic/ide.h index 550979a9ea9d..e3315359500a 100644 --- a/include/asm-mips/mach-generic/ide.h +++ b/include/asm-mips/mach-generic/ide.h | |||
@@ -104,65 +104,107 @@ static __inline__ unsigned long ide_default_io_base(int index) | |||
104 | #endif | 104 | #endif |
105 | 105 | ||
106 | /* MIPS port and memory-mapped I/O string operations. */ | 106 | /* MIPS port and memory-mapped I/O string operations. */ |
107 | static inline void __ide_flush_prologue(void) | ||
108 | { | ||
109 | #ifdef CONFIG_SMP | ||
110 | if (cpu_has_dc_aliases) | ||
111 | preempt_disable(); | ||
112 | #endif | ||
113 | } | ||
114 | |||
115 | static inline void __ide_flush_epilogue(void) | ||
116 | { | ||
117 | #ifdef CONFIG_SMP | ||
118 | if (cpu_has_dc_aliases) | ||
119 | preempt_enable(); | ||
120 | #endif | ||
121 | } | ||
107 | 122 | ||
108 | static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size) | 123 | static inline void __ide_flush_dcache_range(unsigned long addr, unsigned long size) |
109 | { | 124 | { |
110 | if (cpu_has_dc_aliases) { | 125 | if (cpu_has_dc_aliases) { |
111 | unsigned long end = addr + size; | 126 | unsigned long end = addr + size; |
112 | for (; addr < end; addr += PAGE_SIZE) | 127 | |
113 | flush_dcache_page(virt_to_page(addr)); | 128 | while (addr < end) { |
129 | local_flush_data_cache_page((void *)addr); | ||
130 | addr += PAGE_SIZE; | ||
131 | } | ||
114 | } | 132 | } |
115 | } | 133 | } |
116 | 134 | ||
135 | /* | ||
136 | * insw() and gang might be called with interrupts disabled, so we can't | ||
137 | * send IPIs for flushing due to the potencial of deadlocks, see the comment | ||
138 | * above smp_call_function() in arch/mips/kernel/smp.c. We work around the | ||
139 | * problem by disabling preemption so we know we actually perform the flush | ||
140 | * on the processor that actually has the lines to be flushed which hopefully | ||
141 | * is even better for performance anyway. | ||
142 | */ | ||
117 | static inline void __ide_insw(unsigned long port, void *addr, | 143 | static inline void __ide_insw(unsigned long port, void *addr, |
118 | unsigned int count) | 144 | unsigned int count) |
119 | { | 145 | { |
146 | __ide_flush_prologue(); | ||
120 | insw(port, addr, count); | 147 | insw(port, addr, count); |
121 | __ide_flush_dcache_range((unsigned long)addr, count * 2); | 148 | __ide_flush_dcache_range((unsigned long)addr, count * 2); |
149 | __ide_flush_epilogue(); | ||
122 | } | 150 | } |
123 | 151 | ||
124 | static inline void __ide_insl(unsigned long port, void *addr, unsigned int count) | 152 | static inline void __ide_insl(unsigned long port, void *addr, unsigned int count) |
125 | { | 153 | { |
154 | __ide_flush_prologue(); | ||
126 | insl(port, addr, count); | 155 | insl(port, addr, count); |
127 | __ide_flush_dcache_range((unsigned long)addr, count * 4); | 156 | __ide_flush_dcache_range((unsigned long)addr, count * 4); |
157 | __ide_flush_epilogue(); | ||
128 | } | 158 | } |
129 | 159 | ||
130 | static inline void __ide_outsw(unsigned long port, const void *addr, | 160 | static inline void __ide_outsw(unsigned long port, const void *addr, |
131 | unsigned long count) | 161 | unsigned long count) |
132 | { | 162 | { |
163 | __ide_flush_prologue(); | ||
133 | outsw(port, addr, count); | 164 | outsw(port, addr, count); |
134 | __ide_flush_dcache_range((unsigned long)addr, count * 2); | 165 | __ide_flush_dcache_range((unsigned long)addr, count * 2); |
166 | __ide_flush_epilogue(); | ||
135 | } | 167 | } |
136 | 168 | ||
137 | static inline void __ide_outsl(unsigned long port, const void *addr, | 169 | static inline void __ide_outsl(unsigned long port, const void *addr, |
138 | unsigned long count) | 170 | unsigned long count) |
139 | { | 171 | { |
172 | __ide_flush_prologue(); | ||
140 | outsl(port, addr, count); | 173 | outsl(port, addr, count); |
141 | __ide_flush_dcache_range((unsigned long)addr, count * 4); | 174 | __ide_flush_dcache_range((unsigned long)addr, count * 4); |
175 | __ide_flush_epilogue(); | ||
142 | } | 176 | } |
143 | 177 | ||
144 | static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count) | 178 | static inline void __ide_mm_insw(void __iomem *port, void *addr, u32 count) |
145 | { | 179 | { |
180 | __ide_flush_prologue(); | ||
146 | readsw(port, addr, count); | 181 | readsw(port, addr, count); |
147 | __ide_flush_dcache_range((unsigned long)addr, count * 2); | 182 | __ide_flush_dcache_range((unsigned long)addr, count * 2); |
183 | __ide_flush_epilogue(); | ||
148 | } | 184 | } |
149 | 185 | ||
150 | static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count) | 186 | static inline void __ide_mm_insl(void __iomem *port, void *addr, u32 count) |
151 | { | 187 | { |
188 | __ide_flush_prologue(); | ||
152 | readsl(port, addr, count); | 189 | readsl(port, addr, count); |
153 | __ide_flush_dcache_range((unsigned long)addr, count * 4); | 190 | __ide_flush_dcache_range((unsigned long)addr, count * 4); |
191 | __ide_flush_epilogue(); | ||
154 | } | 192 | } |
155 | 193 | ||
156 | static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count) | 194 | static inline void __ide_mm_outsw(void __iomem *port, void *addr, u32 count) |
157 | { | 195 | { |
196 | __ide_flush_prologue(); | ||
158 | writesw(port, addr, count); | 197 | writesw(port, addr, count); |
159 | __ide_flush_dcache_range((unsigned long)addr, count * 2); | 198 | __ide_flush_dcache_range((unsigned long)addr, count * 2); |
199 | __ide_flush_epilogue(); | ||
160 | } | 200 | } |
161 | 201 | ||
162 | static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count) | 202 | static inline void __ide_mm_outsl(void __iomem * port, void *addr, u32 count) |
163 | { | 203 | { |
204 | __ide_flush_prologue(); | ||
164 | writesl(port, addr, count); | 205 | writesl(port, addr, count); |
165 | __ide_flush_dcache_range((unsigned long)addr, count * 4); | 206 | __ide_flush_dcache_range((unsigned long)addr, count * 4); |
207 | __ide_flush_epilogue(); | ||
166 | } | 208 | } |
167 | 209 | ||
168 | /* ide_insw calls insw, not __ide_insw. Why? */ | 210 | /* ide_insw calls insw, not __ide_insw. Why? */ |
diff --git a/include/asm-mips/mach-jmr3927/ds1742.h b/include/asm-mips/mach-jmr3927/ds1742.h index cff6192d4bdb..8a8fef6d07fa 100644 --- a/include/asm-mips/mach-jmr3927/ds1742.h +++ b/include/asm-mips/mach-jmr3927/ds1742.h | |||
@@ -3,14 +3,14 @@ | |||
3 | * License. See the file "COPYING" in the main directory of this archive | 3 | * License. See the file "COPYING" in the main directory of this archive |
4 | * for more details. | 4 | * for more details. |
5 | * | 5 | * |
6 | * Copyright (C) 2003 by Ralf Baechle | 6 | * Copyright (C) 2003, 06 by Ralf Baechle |
7 | */ | 7 | */ |
8 | #ifndef __ASM_MACH_JMR3927_DS1742_H | 8 | #ifndef __ASM_MACH_JMR3927_DS1742_H |
9 | #define __ASM_MACH_JMR3927_DS1742_H | 9 | #define __ASM_MACH_JMR3927_DS1742_H |
10 | 10 | ||
11 | #include <asm/jmr3927/jmr3927.h> | 11 | #include <asm/jmr3927/jmr3927.h> |
12 | 12 | ||
13 | #define rtc_read(reg) (jmr3927_nvram_in(addr)) | 13 | #define rtc_read(reg) (jmr3927_nvram_in(reg)) |
14 | #define rtc_write(data, reg) (jmr3927_nvram_out((data),(reg))) | 14 | #define rtc_write(data, reg) (jmr3927_nvram_out((data),(reg))) |
15 | 15 | ||
16 | #endif /* __ASM_MACH_JMR3927_DS1742_H */ | 16 | #endif /* __ASM_MACH_JMR3927_DS1742_H */ |
diff --git a/include/asm-mips/mach-mips/param.h b/include/asm-mips/mach-mips/param.h new file mode 100644 index 000000000000..805ef6d27d3c --- /dev/null +++ b/include/asm-mips/mach-mips/param.h | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * This file is subject to the terms and conditions of the GNU General Public | ||
3 | * License. See the file "COPYING" in the main directory of this archive | ||
4 | * for more details. | ||
5 | * | ||
6 | * Copyright (C) 2003 by Ralf Baechle | ||
7 | */ | ||
8 | #ifndef __ASM_MACH_MIPS_PARAM_H | ||
9 | #define __ASM_MACH_MIPS_PARAM_H | ||
10 | |||
11 | #define HZ 100 /* Internal kernel timer frequency */ | ||
12 | |||
13 | #endif /* __ASM_MACH_MIPS_PARAM_H */ | ||
diff --git a/include/asm-mips/marvell.h b/include/asm-mips/marvell.h index 9225b3397a4f..6bb2125bb053 100644 --- a/include/asm-mips/marvell.h +++ b/include/asm-mips/marvell.h | |||
@@ -53,4 +53,6 @@ struct mv_pci_controller { | |||
53 | unsigned long config_vreg; | 53 | unsigned long config_vreg; |
54 | }; | 54 | }; |
55 | 55 | ||
56 | extern void ll_mv64340_irq(struct pt_regs *regs); | ||
57 | |||
56 | #endif /* __ASM_MIPS_MARVELL_H */ | 58 | #endif /* __ASM_MIPS_MARVELL_H */ |
diff --git a/include/asm-mips/mips-boards/atlas.h b/include/asm-mips/mips-boards/atlas.h index 0998151fb3a1..a8ae12d120ee 100644 --- a/include/asm-mips/mips-boards/atlas.h +++ b/include/asm-mips/mips-boards/atlas.h | |||
@@ -33,13 +33,29 @@ | |||
33 | #define ATLAS_RTC_ADR_REG 0x1f000800 | 33 | #define ATLAS_RTC_ADR_REG 0x1f000800 |
34 | #define ATLAS_RTC_DAT_REG 0x1f000808 | 34 | #define ATLAS_RTC_DAT_REG 0x1f000808 |
35 | 35 | ||
36 | |||
37 | /* | 36 | /* |
38 | * Atlas interrupt controller register base. | 37 | * Atlas interrupt controller register base. |
39 | */ | 38 | */ |
40 | #define ATLAS_ICTRL_REGS_BASE 0x1f000000 | 39 | #define ATLAS_ICTRL_REGS_BASE 0x1f000000 |
41 | 40 | ||
42 | /* | 41 | /* |
42 | * Atlas registers are memory mapped on 64-bit aligned boundaries and | ||
43 | * only word access are allowed. | ||
44 | */ | ||
45 | struct atlas_ictrl_regs { | ||
46 | volatile unsigned int intraw; | ||
47 | int dummy1; | ||
48 | volatile unsigned int intseten; | ||
49 | int dummy2; | ||
50 | volatile unsigned int intrsten; | ||
51 | int dummy3; | ||
52 | volatile unsigned int intenable; | ||
53 | int dummy4; | ||
54 | volatile unsigned int intstatus; | ||
55 | int dummy5; | ||
56 | }; | ||
57 | |||
58 | /* | ||
43 | * Atlas UART register base. | 59 | * Atlas UART register base. |
44 | */ | 60 | */ |
45 | #define ATLAS_UART_REGS_BASE 0x1f000900 | 61 | #define ATLAS_UART_REGS_BASE 0x1f000900 |
diff --git a/include/asm-mips/mips-boards/atlasint.h b/include/asm-mips/mips-boards/atlasint.h index bba35c183d08..fd7ebc54fa90 100644 --- a/include/asm-mips/mips-boards/atlasint.h +++ b/include/asm-mips/mips-boards/atlasint.h | |||
@@ -62,23 +62,4 @@ | |||
62 | #define ATLASINT_RES31 (ATLASINT_BASE+31) | 62 | #define ATLASINT_RES31 (ATLASINT_BASE+31) |
63 | #define ATLASINT_END (ATLASINT_BASE+31) | 63 | #define ATLASINT_END (ATLASINT_BASE+31) |
64 | 64 | ||
65 | /* | ||
66 | * Atlas registers are memory mapped on 64-bit aligned boundaries and | ||
67 | * only word access are allowed. | ||
68 | */ | ||
69 | struct atlas_ictrl_regs { | ||
70 | volatile unsigned int intraw; | ||
71 | int dummy1; | ||
72 | volatile unsigned int intseten; | ||
73 | int dummy2; | ||
74 | volatile unsigned int intrsten; | ||
75 | int dummy3; | ||
76 | volatile unsigned int intenable; | ||
77 | int dummy4; | ||
78 | volatile unsigned int intstatus; | ||
79 | int dummy5; | ||
80 | }; | ||
81 | |||
82 | extern void atlasint_init(void); | ||
83 | |||
84 | #endif /* !(_MIPS_ATLASINT_H) */ | 65 | #endif /* !(_MIPS_ATLASINT_H) */ |
diff --git a/include/asm-mips/mips_mt.h b/include/asm-mips/mips_mt.h new file mode 100644 index 000000000000..c31a312b9783 --- /dev/null +++ b/include/asm-mips/mips_mt.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * Definitions and decalrations for MIPS MT support | ||
3 | * that are common between SMTC, VSMP, and/or AP/SP | ||
4 | * kernel models. | ||
5 | */ | ||
6 | #ifndef __ASM_MIPS_MT_H | ||
7 | #define __ASM_MIPS_MT_H | ||
8 | |||
9 | extern cpumask_t mt_fpu_cpumask; | ||
10 | extern unsigned long mt_fpemul_threshold; | ||
11 | |||
12 | extern void mips_mt_regdump(unsigned long previous_mvpcontrol_value); | ||
13 | extern void mips_mt_set_cpuoptions(void); | ||
14 | |||
15 | #endif /* __ASM_MIPS_MT_H */ | ||
diff --git a/include/asm-mips/mipsmtregs.h b/include/asm-mips/mipsmtregs.h index a669c0702c66..f637ce70758f 100644 --- a/include/asm-mips/mipsmtregs.h +++ b/include/asm-mips/mipsmtregs.h | |||
@@ -165,7 +165,7 @@ | |||
165 | 165 | ||
166 | #ifndef __ASSEMBLY__ | 166 | #ifndef __ASSEMBLY__ |
167 | 167 | ||
168 | extern void mips_mt_regdump(void); | 168 | extern void mips_mt_regdump(unsigned long previous_mvpcontrol_value); |
169 | 169 | ||
170 | static inline unsigned int dvpe(void) | 170 | static inline unsigned int dvpe(void) |
171 | { | 171 | { |
@@ -234,7 +234,7 @@ static inline void __raw_emt(void) | |||
234 | __asm__ __volatile__( | 234 | __asm__ __volatile__( |
235 | " .set noreorder \n" | 235 | " .set noreorder \n" |
236 | " .set mips32r2 \n" | 236 | " .set mips32r2 \n" |
237 | " emt \n" | 237 | " .word 0x41600be1 # emt \n" |
238 | " ehb \n" | 238 | " ehb \n" |
239 | " .set mips0 \n" | 239 | " .set mips0 \n" |
240 | " .set reorder"); | 240 | " .set reorder"); |
@@ -282,8 +282,11 @@ static inline void ehb(void) | |||
282 | \ | 282 | \ |
283 | __asm__ __volatile__( \ | 283 | __asm__ __volatile__( \ |
284 | " .set push \n" \ | 284 | " .set push \n" \ |
285 | " .set noat \n" \ | ||
285 | " .set mips32r2 \n" \ | 286 | " .set mips32r2 \n" \ |
286 | " mftgpr %0," #rt " \n" \ | 287 | " # mftgpr $1," #rt " \n" \ |
288 | " .word 0x41000820 | (" #rt " << 16) \n" \ | ||
289 | " move %0, $1 \n" \ | ||
287 | " .set pop \n" \ | 290 | " .set pop \n" \ |
288 | : "=r" (__res)); \ | 291 | : "=r" (__res)); \ |
289 | \ | 292 | \ |
@@ -295,9 +298,7 @@ static inline void ehb(void) | |||
295 | unsigned long __res; \ | 298 | unsigned long __res; \ |
296 | \ | 299 | \ |
297 | __asm__ __volatile__( \ | 300 | __asm__ __volatile__( \ |
298 | ".set noat\n\t" \ | 301 | " mftr %0, " #rt ", " #u ", " #sel " \n" \ |
299 | "mftr\t%0, " #rt ", " #u ", " #sel "\n\t" \ | ||
300 | ".set at\n\t" \ | ||
301 | : "=r" (__res)); \ | 302 | : "=r" (__res)); \ |
302 | \ | 303 | \ |
303 | __res; \ | 304 | __res; \ |
@@ -364,6 +365,9 @@ do { \ | |||
364 | #define read_vpe_c0_ebase() mftc0(15,1) | 365 | #define read_vpe_c0_ebase() mftc0(15,1) |
365 | #define write_vpe_c0_ebase(val) mttc0(15, 1, val) | 366 | #define write_vpe_c0_ebase(val) mttc0(15, 1, val) |
366 | #define write_vpe_c0_compare(val) mttc0(11, 0, val) | 367 | #define write_vpe_c0_compare(val) mttc0(11, 0, val) |
368 | #define read_vpe_c0_badvaddr() mftc0(8, 0) | ||
369 | #define read_vpe_c0_epc() mftc0(14, 0) | ||
370 | #define write_vpe_c0_epc(val) mttc0(14, 0, val) | ||
367 | 371 | ||
368 | 372 | ||
369 | /* TC */ | 373 | /* TC */ |
diff --git a/include/asm-mips/mipsregs.h b/include/asm-mips/mipsregs.h index 035ba0a9b0df..a2ef579f6b1a 100644 --- a/include/asm-mips/mipsregs.h +++ b/include/asm-mips/mipsregs.h | |||
@@ -836,6 +836,9 @@ do { \ | |||
836 | #define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ | 836 | #define read_c0_cache() __read_32bit_c0_register($7, 0) /* TX39xx */ |
837 | #define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) | 837 | #define write_c0_cache(val) __write_32bit_c0_register($7, 0, val) |
838 | 838 | ||
839 | #define read_c0_badvaddr() __read_ulong_c0_register($8, 0) | ||
840 | #define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) | ||
841 | |||
839 | #define read_c0_count() __read_32bit_c0_register($9, 0) | 842 | #define read_c0_count() __read_32bit_c0_register($9, 0) |
840 | #define write_c0_count(val) __write_32bit_c0_register($9, 0, val) | 843 | #define write_c0_count(val) __write_32bit_c0_register($9, 0, val) |
841 | 844 | ||
@@ -858,7 +861,19 @@ do { \ | |||
858 | #define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val) | 861 | #define write_c0_compare3(val) __write_32bit_c0_register($11, 7, val) |
859 | 862 | ||
860 | #define read_c0_status() __read_32bit_c0_register($12, 0) | 863 | #define read_c0_status() __read_32bit_c0_register($12, 0) |
864 | #ifdef CONFIG_MIPS_MT_SMTC | ||
865 | #define write_c0_status(val) \ | ||
866 | do { \ | ||
867 | __write_32bit_c0_register($12, 0, val); \ | ||
868 | __ehb(); \ | ||
869 | } while (0) | ||
870 | #else | ||
871 | /* | ||
872 | * Legacy non-SMTC code, which may be hazardous | ||
873 | * but which might not support EHB | ||
874 | */ | ||
861 | #define write_c0_status(val) __write_32bit_c0_register($12, 0, val) | 875 | #define write_c0_status(val) __write_32bit_c0_register($12, 0, val) |
876 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
862 | 877 | ||
863 | #define read_c0_cause() __read_32bit_c0_register($13, 0) | 878 | #define read_c0_cause() __read_32bit_c0_register($13, 0) |
864 | #define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) | 879 | #define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) |
@@ -1001,6 +1016,9 @@ do { \ | |||
1001 | #define read_c0_taglo() __read_32bit_c0_register($28, 0) | 1016 | #define read_c0_taglo() __read_32bit_c0_register($28, 0) |
1002 | #define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) | 1017 | #define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) |
1003 | 1018 | ||
1019 | #define read_c0_dtaglo() __read_32bit_c0_register($28, 2) | ||
1020 | #define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val) | ||
1021 | |||
1004 | #define read_c0_taghi() __read_32bit_c0_register($29, 0) | 1022 | #define read_c0_taghi() __read_32bit_c0_register($29, 0) |
1005 | #define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) | 1023 | #define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) |
1006 | 1024 | ||
@@ -1354,15 +1372,119 @@ static inline void tlb_write_random(void) | |||
1354 | /* | 1372 | /* |
1355 | * Manipulate bits in a c0 register. | 1373 | * Manipulate bits in a c0 register. |
1356 | */ | 1374 | */ |
1375 | #ifndef CONFIG_MIPS_MT_SMTC | ||
1376 | /* | ||
1377 | * SMTC Linux requires shutting-down microthread scheduling | ||
1378 | * during CP0 register read-modify-write sequences. | ||
1379 | */ | ||
1380 | #define __BUILD_SET_C0(name) \ | ||
1381 | static inline unsigned int \ | ||
1382 | set_c0_##name(unsigned int set) \ | ||
1383 | { \ | ||
1384 | unsigned int res; \ | ||
1385 | \ | ||
1386 | res = read_c0_##name(); \ | ||
1387 | res |= set; \ | ||
1388 | write_c0_##name(res); \ | ||
1389 | \ | ||
1390 | return res; \ | ||
1391 | } \ | ||
1392 | \ | ||
1393 | static inline unsigned int \ | ||
1394 | clear_c0_##name(unsigned int clear) \ | ||
1395 | { \ | ||
1396 | unsigned int res; \ | ||
1397 | \ | ||
1398 | res = read_c0_##name(); \ | ||
1399 | res &= ~clear; \ | ||
1400 | write_c0_##name(res); \ | ||
1401 | \ | ||
1402 | return res; \ | ||
1403 | } \ | ||
1404 | \ | ||
1405 | static inline unsigned int \ | ||
1406 | change_c0_##name(unsigned int change, unsigned int new) \ | ||
1407 | { \ | ||
1408 | unsigned int res; \ | ||
1409 | \ | ||
1410 | res = read_c0_##name(); \ | ||
1411 | res &= ~change; \ | ||
1412 | res |= (new & change); \ | ||
1413 | write_c0_##name(res); \ | ||
1414 | \ | ||
1415 | return res; \ | ||
1416 | } | ||
1417 | |||
1418 | #else /* SMTC versions that manage MT scheduling */ | ||
1419 | |||
1420 | #include <asm/interrupt.h> | ||
1421 | |||
1422 | /* | ||
1423 | * This is a duplicate of dmt() in mipsmtregs.h to avoid problems with | ||
1424 | * header file recursion. | ||
1425 | */ | ||
1426 | static inline unsigned int __dmt(void) | ||
1427 | { | ||
1428 | int res; | ||
1429 | |||
1430 | __asm__ __volatile__( | ||
1431 | " .set push \n" | ||
1432 | " .set mips32r2 \n" | ||
1433 | " .set noat \n" | ||
1434 | " .word 0x41610BC1 # dmt $1 \n" | ||
1435 | " ehb \n" | ||
1436 | " move %0, $1 \n" | ||
1437 | " .set pop \n" | ||
1438 | : "=r" (res)); | ||
1439 | |||
1440 | instruction_hazard(); | ||
1441 | |||
1442 | return res; | ||
1443 | } | ||
1444 | |||
1445 | #define __VPECONTROL_TE_SHIFT 15 | ||
1446 | #define __VPECONTROL_TE (1UL << __VPECONTROL_TE_SHIFT) | ||
1447 | |||
1448 | #define __EMT_ENABLE __VPECONTROL_TE | ||
1449 | |||
1450 | static inline void __emt(unsigned int previous) | ||
1451 | { | ||
1452 | if ((previous & __EMT_ENABLE)) | ||
1453 | __asm__ __volatile__( | ||
1454 | " .set noreorder \n" | ||
1455 | " .set mips32r2 \n" | ||
1456 | " .word 0x41600be1 # emt \n" | ||
1457 | " ehb \n" | ||
1458 | " .set mips0 \n" | ||
1459 | " .set reorder \n"); | ||
1460 | } | ||
1461 | |||
1462 | static inline void __ehb(void) | ||
1463 | { | ||
1464 | __asm__ __volatile__( | ||
1465 | " ehb \n"); | ||
1466 | } | ||
1467 | |||
1468 | /* | ||
1469 | * Note that local_irq_save/restore affect TC-specific IXMT state, | ||
1470 | * not Status.IE as in non-SMTC kernel. | ||
1471 | */ | ||
1472 | |||
1357 | #define __BUILD_SET_C0(name) \ | 1473 | #define __BUILD_SET_C0(name) \ |
1358 | static inline unsigned int \ | 1474 | static inline unsigned int \ |
1359 | set_c0_##name(unsigned int set) \ | 1475 | set_c0_##name(unsigned int set) \ |
1360 | { \ | 1476 | { \ |
1361 | unsigned int res; \ | 1477 | unsigned int res; \ |
1478 | unsigned int omt; \ | ||
1479 | unsigned int flags; \ | ||
1362 | \ | 1480 | \ |
1481 | local_irq_save(flags); \ | ||
1482 | omt = __dmt(); \ | ||
1363 | res = read_c0_##name(); \ | 1483 | res = read_c0_##name(); \ |
1364 | res |= set; \ | 1484 | res |= set; \ |
1365 | write_c0_##name(res); \ | 1485 | write_c0_##name(res); \ |
1486 | __emt(omt); \ | ||
1487 | local_irq_restore(flags); \ | ||
1366 | \ | 1488 | \ |
1367 | return res; \ | 1489 | return res; \ |
1368 | } \ | 1490 | } \ |
@@ -1371,10 +1493,16 @@ static inline unsigned int \ | |||
1371 | clear_c0_##name(unsigned int clear) \ | 1493 | clear_c0_##name(unsigned int clear) \ |
1372 | { \ | 1494 | { \ |
1373 | unsigned int res; \ | 1495 | unsigned int res; \ |
1496 | unsigned int omt; \ | ||
1497 | unsigned int flags; \ | ||
1374 | \ | 1498 | \ |
1499 | local_irq_save(flags); \ | ||
1500 | omt = __dmt(); \ | ||
1375 | res = read_c0_##name(); \ | 1501 | res = read_c0_##name(); \ |
1376 | res &= ~clear; \ | 1502 | res &= ~clear; \ |
1377 | write_c0_##name(res); \ | 1503 | write_c0_##name(res); \ |
1504 | __emt(omt); \ | ||
1505 | local_irq_restore(flags); \ | ||
1378 | \ | 1506 | \ |
1379 | return res; \ | 1507 | return res; \ |
1380 | } \ | 1508 | } \ |
@@ -1383,14 +1511,22 @@ static inline unsigned int \ | |||
1383 | change_c0_##name(unsigned int change, unsigned int new) \ | 1511 | change_c0_##name(unsigned int change, unsigned int new) \ |
1384 | { \ | 1512 | { \ |
1385 | unsigned int res; \ | 1513 | unsigned int res; \ |
1514 | unsigned int omt; \ | ||
1515 | unsigned int flags; \ | ||
1386 | \ | 1516 | \ |
1517 | local_irq_save(flags); \ | ||
1518 | \ | ||
1519 | omt = __dmt(); \ | ||
1387 | res = read_c0_##name(); \ | 1520 | res = read_c0_##name(); \ |
1388 | res &= ~change; \ | 1521 | res &= ~change; \ |
1389 | res |= (new & change); \ | 1522 | res |= (new & change); \ |
1390 | write_c0_##name(res); \ | 1523 | write_c0_##name(res); \ |
1524 | __emt(omt); \ | ||
1525 | local_irq_restore(flags); \ | ||
1391 | \ | 1526 | \ |
1392 | return res; \ | 1527 | return res; \ |
1393 | } | 1528 | } |
1529 | #endif | ||
1394 | 1530 | ||
1395 | __BUILD_SET_C0(status) | 1531 | __BUILD_SET_C0(status) |
1396 | __BUILD_SET_C0(cause) | 1532 | __BUILD_SET_C0(cause) |
diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h index 61cf22588137..6e09f4c87211 100644 --- a/include/asm-mips/mmu_context.h +++ b/include/asm-mips/mmu_context.h | |||
@@ -17,6 +17,10 @@ | |||
17 | #include <linux/slab.h> | 17 | #include <linux/slab.h> |
18 | #include <asm/cacheflush.h> | 18 | #include <asm/cacheflush.h> |
19 | #include <asm/tlbflush.h> | 19 | #include <asm/tlbflush.h> |
20 | #ifdef CONFIG_MIPS_MT_SMTC | ||
21 | #include <asm/mipsmtregs.h> | ||
22 | #include <asm/smtc.h> | ||
23 | #endif /* SMTC */ | ||
20 | 24 | ||
21 | /* | 25 | /* |
22 | * For the fast tlb miss handlers, we keep a per cpu array of pointers | 26 | * For the fast tlb miss handlers, we keep a per cpu array of pointers |
@@ -54,6 +58,14 @@ extern unsigned long pgd_current[]; | |||
54 | #define ASID_INC 0x1 | 58 | #define ASID_INC 0x1 |
55 | #define ASID_MASK 0xfff | 59 | #define ASID_MASK 0xfff |
56 | 60 | ||
61 | /* SMTC/34K debug hack - but maybe we'll keep it */ | ||
62 | #elif defined(CONFIG_MIPS_MT_SMTC) | ||
63 | |||
64 | #define ASID_INC 0x1 | ||
65 | extern unsigned long smtc_asid_mask; | ||
66 | #define ASID_MASK (smtc_asid_mask) | ||
67 | #define HW_ASID_MASK 0xff | ||
68 | /* End SMTC/34K debug hack */ | ||
57 | #else /* FIXME: not correct for R6000 */ | 69 | #else /* FIXME: not correct for R6000 */ |
58 | 70 | ||
59 | #define ASID_INC 0x1 | 71 | #define ASID_INC 0x1 |
@@ -76,6 +88,8 @@ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) | |||
76 | #define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) | 88 | #define ASID_VERSION_MASK ((unsigned long)~(ASID_MASK|(ASID_MASK-1))) |
77 | #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1) | 89 | #define ASID_FIRST_VERSION ((unsigned long)(~ASID_VERSION_MASK) + 1) |
78 | 90 | ||
91 | #ifndef CONFIG_MIPS_MT_SMTC | ||
92 | /* Normal, classic MIPS get_new_mmu_context */ | ||
79 | static inline void | 93 | static inline void |
80 | get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | 94 | get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) |
81 | { | 95 | { |
@@ -91,6 +105,12 @@ get_new_mmu_context(struct mm_struct *mm, unsigned long cpu) | |||
91 | cpu_context(cpu, mm) = asid_cache(cpu) = asid; | 105 | cpu_context(cpu, mm) = asid_cache(cpu) = asid; |
92 | } | 106 | } |
93 | 107 | ||
108 | #else /* CONFIG_MIPS_MT_SMTC */ | ||
109 | |||
110 | #define get_new_mmu_context(mm,cpu) smtc_get_new_mmu_context((mm),(cpu)) | ||
111 | |||
112 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
113 | |||
94 | /* | 114 | /* |
95 | * Initialize the context related info for a new mm_struct | 115 | * Initialize the context related info for a new mm_struct |
96 | * instance. | 116 | * instance. |
@@ -111,14 +131,46 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | |||
111 | { | 131 | { |
112 | unsigned int cpu = smp_processor_id(); | 132 | unsigned int cpu = smp_processor_id(); |
113 | unsigned long flags; | 133 | unsigned long flags; |
114 | 134 | #ifdef CONFIG_MIPS_MT_SMTC | |
135 | unsigned long oldasid; | ||
136 | unsigned long mtflags; | ||
137 | int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id; | ||
115 | local_irq_save(flags); | 138 | local_irq_save(flags); |
139 | mtflags = dvpe(); | ||
140 | #else /* Not SMTC */ | ||
141 | local_irq_save(flags); | ||
142 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
116 | 143 | ||
117 | /* Check if our ASID is of an older version and thus invalid */ | 144 | /* Check if our ASID is of an older version and thus invalid */ |
118 | if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK) | 145 | if ((cpu_context(cpu, next) ^ asid_cache(cpu)) & ASID_VERSION_MASK) |
119 | get_new_mmu_context(next, cpu); | 146 | get_new_mmu_context(next, cpu); |
120 | 147 | #ifdef CONFIG_MIPS_MT_SMTC | |
148 | /* | ||
149 | * If the EntryHi ASID being replaced happens to be | ||
150 | * the value flagged at ASID recycling time as having | ||
151 | * an extended life, clear the bit showing it being | ||
152 | * in use by this "CPU", and if that's the last bit, | ||
153 | * free up the ASID value for use and flush any old | ||
154 | * instances of it from the TLB. | ||
155 | */ | ||
156 | oldasid = (read_c0_entryhi() & ASID_MASK); | ||
157 | if(smtc_live_asid[mytlb][oldasid]) { | ||
158 | smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); | ||
159 | if(smtc_live_asid[mytlb][oldasid] == 0) | ||
160 | smtc_flush_tlb_asid(oldasid); | ||
161 | } | ||
162 | /* | ||
163 | * Tread softly on EntryHi, and so long as we support | ||
164 | * having ASID_MASK smaller than the hardware maximum, | ||
165 | * make sure no "soft" bits become "hard"... | ||
166 | */ | ||
167 | write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | ||
168 | | (cpu_context(cpu, next) & ASID_MASK)); | ||
169 | ehb(); /* Make sure it propagates to TCStatus */ | ||
170 | evpe(mtflags); | ||
171 | #else | ||
121 | write_c0_entryhi(cpu_context(cpu, next)); | 172 | write_c0_entryhi(cpu_context(cpu, next)); |
173 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
122 | TLBMISS_HANDLER_SETUP_PGD(next->pgd); | 174 | TLBMISS_HANDLER_SETUP_PGD(next->pgd); |
123 | 175 | ||
124 | /* | 176 | /* |
@@ -151,12 +203,34 @@ activate_mm(struct mm_struct *prev, struct mm_struct *next) | |||
151 | unsigned long flags; | 203 | unsigned long flags; |
152 | unsigned int cpu = smp_processor_id(); | 204 | unsigned int cpu = smp_processor_id(); |
153 | 205 | ||
206 | #ifdef CONFIG_MIPS_MT_SMTC | ||
207 | unsigned long oldasid; | ||
208 | unsigned long mtflags; | ||
209 | int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id; | ||
210 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
211 | |||
154 | local_irq_save(flags); | 212 | local_irq_save(flags); |
155 | 213 | ||
156 | /* Unconditionally get a new ASID. */ | 214 | /* Unconditionally get a new ASID. */ |
157 | get_new_mmu_context(next, cpu); | 215 | get_new_mmu_context(next, cpu); |
158 | 216 | ||
217 | #ifdef CONFIG_MIPS_MT_SMTC | ||
218 | /* See comments for similar code above */ | ||
219 | mtflags = dvpe(); | ||
220 | oldasid = read_c0_entryhi() & ASID_MASK; | ||
221 | if(smtc_live_asid[mytlb][oldasid]) { | ||
222 | smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); | ||
223 | if(smtc_live_asid[mytlb][oldasid] == 0) | ||
224 | smtc_flush_tlb_asid(oldasid); | ||
225 | } | ||
226 | /* See comments for similar code above */ | ||
227 | write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | | ||
228 | (cpu_context(cpu, next) & ASID_MASK)); | ||
229 | ehb(); /* Make sure it propagates to TCStatus */ | ||
230 | evpe(mtflags); | ||
231 | #else | ||
159 | write_c0_entryhi(cpu_context(cpu, next)); | 232 | write_c0_entryhi(cpu_context(cpu, next)); |
233 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
160 | TLBMISS_HANDLER_SETUP_PGD(next->pgd); | 234 | TLBMISS_HANDLER_SETUP_PGD(next->pgd); |
161 | 235 | ||
162 | /* mark mmu ownership change */ | 236 | /* mark mmu ownership change */ |
@@ -174,17 +248,49 @@ static inline void | |||
174 | drop_mmu_context(struct mm_struct *mm, unsigned cpu) | 248 | drop_mmu_context(struct mm_struct *mm, unsigned cpu) |
175 | { | 249 | { |
176 | unsigned long flags; | 250 | unsigned long flags; |
251 | #ifdef CONFIG_MIPS_MT_SMTC | ||
252 | unsigned long oldasid; | ||
253 | /* Can't use spinlock because called from TLB flush within DVPE */ | ||
254 | unsigned int prevvpe; | ||
255 | int mytlb = (smtc_status & SMTC_TLB_SHARED) ? 0 : cpu_data[cpu].vpe_id; | ||
256 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
177 | 257 | ||
178 | local_irq_save(flags); | 258 | local_irq_save(flags); |
179 | 259 | ||
180 | if (cpu_isset(cpu, mm->cpu_vm_mask)) { | 260 | if (cpu_isset(cpu, mm->cpu_vm_mask)) { |
181 | get_new_mmu_context(mm, cpu); | 261 | get_new_mmu_context(mm, cpu); |
262 | #ifdef CONFIG_MIPS_MT_SMTC | ||
263 | /* See comments for similar code above */ | ||
264 | prevvpe = dvpe(); | ||
265 | oldasid = (read_c0_entryhi() & ASID_MASK); | ||
266 | if(smtc_live_asid[mytlb][oldasid]) { | ||
267 | smtc_live_asid[mytlb][oldasid] &= ~(0x1 << cpu); | ||
268 | if(smtc_live_asid[mytlb][oldasid] == 0) | ||
269 | smtc_flush_tlb_asid(oldasid); | ||
270 | } | ||
271 | /* See comments for similar code above */ | ||
272 | write_c0_entryhi((read_c0_entryhi() & ~HW_ASID_MASK) | ||
273 | | cpu_asid(cpu, mm)); | ||
274 | ehb(); /* Make sure it propagates to TCStatus */ | ||
275 | evpe(prevvpe); | ||
276 | #else /* not CONFIG_MIPS_MT_SMTC */ | ||
182 | write_c0_entryhi(cpu_asid(cpu, mm)); | 277 | write_c0_entryhi(cpu_asid(cpu, mm)); |
278 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
183 | } else { | 279 | } else { |
184 | /* will get a new context next time */ | 280 | /* will get a new context next time */ |
281 | #ifndef CONFIG_MIPS_MT_SMTC | ||
185 | cpu_context(cpu, mm) = 0; | 282 | cpu_context(cpu, mm) = 0; |
283 | #else /* SMTC */ | ||
284 | int i; | ||
285 | |||
286 | /* SMTC shares the TLB (and ASIDs) across VPEs */ | ||
287 | for (i = 0; i < num_online_cpus(); i++) { | ||
288 | if((smtc_status & SMTC_TLB_SHARED) | ||
289 | || (cpu_data[i].vpe_id == cpu_data[cpu].vpe_id)) | ||
290 | cpu_context(i, mm) = 0; | ||
291 | } | ||
292 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
186 | } | 293 | } |
187 | |||
188 | local_irq_restore(flags); | 294 | local_irq_restore(flags); |
189 | } | 295 | } |
190 | 296 | ||
diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 39d2bd50fece..0fb75f0762e0 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #define _ASM_PROCESSOR_H | 12 | #define _ASM_PROCESSOR_H |
13 | 13 | ||
14 | #include <linux/config.h> | 14 | #include <linux/config.h> |
15 | #include <linux/cpumask.h> | ||
15 | #include <linux/threads.h> | 16 | #include <linux/threads.h> |
16 | 17 | ||
17 | #include <asm/cachectl.h> | 18 | #include <asm/cachectl.h> |
@@ -107,6 +108,10 @@ struct mips_dsp_state { | |||
107 | 108 | ||
108 | #define INIT_DSP {{0,},} | 109 | #define INIT_DSP {{0,},} |
109 | 110 | ||
111 | #define INIT_CPUMASK { \ | ||
112 | {0,} \ | ||
113 | } | ||
114 | |||
110 | typedef struct { | 115 | typedef struct { |
111 | unsigned long seg; | 116 | unsigned long seg; |
112 | } mm_segment_t; | 117 | } mm_segment_t; |
@@ -129,6 +134,12 @@ struct thread_struct { | |||
129 | 134 | ||
130 | /* Saved fpu/fpu emulator stuff. */ | 135 | /* Saved fpu/fpu emulator stuff. */ |
131 | union mips_fpu_union fpu; | 136 | union mips_fpu_union fpu; |
137 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
138 | /* Emulated instruction count */ | ||
139 | unsigned long emulated_fp; | ||
140 | /* Saved per-thread scheduler affinity mask */ | ||
141 | cpumask_t user_cpus_allowed; | ||
142 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
132 | 143 | ||
133 | /* Saved state of the DSP ASE, if available. */ | 144 | /* Saved state of the DSP ASE, if available. */ |
134 | struct mips_dsp_state dsp; | 145 | struct mips_dsp_state dsp; |
@@ -142,6 +153,7 @@ struct thread_struct { | |||
142 | #define MF_LOGADE 2 /* Log address errors to syslog */ | 153 | #define MF_LOGADE 2 /* Log address errors to syslog */ |
143 | #define MF_32BIT_REGS 4 /* also implies 16/32 fprs */ | 154 | #define MF_32BIT_REGS 4 /* also implies 16/32 fprs */ |
144 | #define MF_32BIT_ADDR 8 /* 32-bit address space (o32/n32) */ | 155 | #define MF_32BIT_ADDR 8 /* 32-bit address space (o32/n32) */ |
156 | #define MF_FPUBOUND 0x10 /* thread bound to FPU-full CPU set */ | ||
145 | unsigned long mflags; | 157 | unsigned long mflags; |
146 | unsigned long irix_trampoline; /* Wheee... */ | 158 | unsigned long irix_trampoline; /* Wheee... */ |
147 | unsigned long irix_oldctx; | 159 | unsigned long irix_oldctx; |
@@ -153,6 +165,12 @@ struct thread_struct { | |||
153 | #define MF_N32 MF_32BIT_ADDR | 165 | #define MF_N32 MF_32BIT_ADDR |
154 | #define MF_N64 0 | 166 | #define MF_N64 0 |
155 | 167 | ||
168 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
169 | #define FPAFF_INIT 0, INIT_CPUMASK, | ||
170 | #else | ||
171 | #define FPAFF_INIT | ||
172 | #endif /* CONFIG_MIPS_MT_FPAFF */ | ||
173 | |||
156 | #define INIT_THREAD { \ | 174 | #define INIT_THREAD { \ |
157 | /* \ | 175 | /* \ |
158 | * saved main processor registers \ | 176 | * saved main processor registers \ |
@@ -168,6 +186,10 @@ struct thread_struct { | |||
168 | */ \ | 186 | */ \ |
169 | INIT_FPU, \ | 187 | INIT_FPU, \ |
170 | /* \ | 188 | /* \ |
189 | * fpu affinity state (null if not FPAFF) \ | ||
190 | */ \ | ||
191 | FPAFF_INIT \ | ||
192 | /* \ | ||
171 | * saved dsp/dsp emulator stuff \ | 193 | * saved dsp/dsp emulator stuff \ |
172 | */ \ | 194 | */ \ |
173 | INIT_DSP, \ | 195 | INIT_DSP, \ |
diff --git a/include/asm-mips/ptrace.h b/include/asm-mips/ptrace.h index 95c5839ac465..fa9d8713c12a 100644 --- a/include/asm-mips/ptrace.h +++ b/include/asm-mips/ptrace.h | |||
@@ -45,6 +45,10 @@ struct pt_regs { | |||
45 | unsigned long cp0_badvaddr; | 45 | unsigned long cp0_badvaddr; |
46 | unsigned long cp0_cause; | 46 | unsigned long cp0_cause; |
47 | unsigned long cp0_epc; | 47 | unsigned long cp0_epc; |
48 | #ifdef CONFIG_MIPS_MT_SMTC | ||
49 | unsigned long cp0_tcstatus; | ||
50 | unsigned long smtc_pad; | ||
51 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
48 | }; | 52 | }; |
49 | 53 | ||
50 | /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ | 54 | /* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */ |
diff --git a/include/asm-mips/r4kcache.h b/include/asm-mips/r4kcache.h index 90c374700977..3c8e3c8d1a9a 100644 --- a/include/asm-mips/r4kcache.h +++ b/include/asm-mips/r4kcache.h | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <asm/asm.h> | 15 | #include <asm/asm.h> |
16 | #include <asm/cacheops.h> | 16 | #include <asm/cacheops.h> |
17 | #include <asm/cpu-features.h> | 17 | #include <asm/cpu-features.h> |
18 | #include <asm/mipsmtregs.h> | ||
18 | 19 | ||
19 | /* | 20 | /* |
20 | * This macro return a properly sign-extended address suitable as base address | 21 | * This macro return a properly sign-extended address suitable as base address |
@@ -37,16 +38,120 @@ | |||
37 | " cache %0, %1 \n" \ | 38 | " cache %0, %1 \n" \ |
38 | " .set pop \n" \ | 39 | " .set pop \n" \ |
39 | : \ | 40 | : \ |
40 | : "i" (op), "m" (*(unsigned char *)(addr))) | 41 | : "i" (op), "R" (*(unsigned char *)(addr))) |
42 | |||
43 | #ifdef CONFIG_MIPS_MT | ||
44 | /* | ||
45 | * Temporary hacks for SMTC debug. Optionally force single-threaded | ||
46 | * execution during I-cache flushes. | ||
47 | */ | ||
48 | |||
49 | #define PROTECT_CACHE_FLUSHES 1 | ||
50 | |||
51 | #ifdef PROTECT_CACHE_FLUSHES | ||
52 | |||
53 | extern int mt_protiflush; | ||
54 | extern int mt_protdflush; | ||
55 | extern void mt_cflush_lockdown(void); | ||
56 | extern void mt_cflush_release(void); | ||
57 | |||
58 | #define BEGIN_MT_IPROT \ | ||
59 | unsigned long flags = 0; \ | ||
60 | unsigned long mtflags = 0; \ | ||
61 | if(mt_protiflush) { \ | ||
62 | local_irq_save(flags); \ | ||
63 | ehb(); \ | ||
64 | mtflags = dvpe(); \ | ||
65 | mt_cflush_lockdown(); \ | ||
66 | } | ||
67 | |||
68 | #define END_MT_IPROT \ | ||
69 | if(mt_protiflush) { \ | ||
70 | mt_cflush_release(); \ | ||
71 | evpe(mtflags); \ | ||
72 | local_irq_restore(flags); \ | ||
73 | } | ||
74 | |||
75 | #define BEGIN_MT_DPROT \ | ||
76 | unsigned long flags = 0; \ | ||
77 | unsigned long mtflags = 0; \ | ||
78 | if(mt_protdflush) { \ | ||
79 | local_irq_save(flags); \ | ||
80 | ehb(); \ | ||
81 | mtflags = dvpe(); \ | ||
82 | mt_cflush_lockdown(); \ | ||
83 | } | ||
84 | |||
85 | #define END_MT_DPROT \ | ||
86 | if(mt_protdflush) { \ | ||
87 | mt_cflush_release(); \ | ||
88 | evpe(mtflags); \ | ||
89 | local_irq_restore(flags); \ | ||
90 | } | ||
91 | |||
92 | #else | ||
93 | |||
94 | #define BEGIN_MT_IPROT | ||
95 | #define BEGIN_MT_DPROT | ||
96 | #define END_MT_IPROT | ||
97 | #define END_MT_DPROT | ||
98 | |||
99 | #endif /* PROTECT_CACHE_FLUSHES */ | ||
100 | |||
101 | #define __iflush_prologue \ | ||
102 | unsigned long redundance; \ | ||
103 | extern int mt_n_iflushes; \ | ||
104 | BEGIN_MT_IPROT \ | ||
105 | for (redundance = 0; redundance < mt_n_iflushes; redundance++) { | ||
106 | |||
107 | #define __iflush_epilogue \ | ||
108 | END_MT_IPROT \ | ||
109 | } | ||
110 | |||
111 | #define __dflush_prologue \ | ||
112 | unsigned long redundance; \ | ||
113 | extern int mt_n_dflushes; \ | ||
114 | BEGIN_MT_DPROT \ | ||
115 | for (redundance = 0; redundance < mt_n_dflushes; redundance++) { | ||
116 | |||
117 | #define __dflush_epilogue \ | ||
118 | END_MT_DPROT \ | ||
119 | } | ||
120 | |||
121 | #define __inv_dflush_prologue __dflush_prologue | ||
122 | #define __inv_dflush_epilogue __dflush_epilogue | ||
123 | #define __sflush_prologue { | ||
124 | #define __sflush_epilogue } | ||
125 | #define __inv_sflush_prologue __sflush_prologue | ||
126 | #define __inv_sflush_epilogue __sflush_epilogue | ||
127 | |||
128 | #else /* CONFIG_MIPS_MT */ | ||
129 | |||
130 | #define __iflush_prologue { | ||
131 | #define __iflush_epilogue } | ||
132 | #define __dflush_prologue { | ||
133 | #define __dflush_epilogue } | ||
134 | #define __inv_dflush_prologue { | ||
135 | #define __inv_dflush_epilogue } | ||
136 | #define __sflush_prologue { | ||
137 | #define __sflush_epilogue } | ||
138 | #define __inv_sflush_prologue { | ||
139 | #define __inv_sflush_epilogue } | ||
140 | |||
141 | #endif /* CONFIG_MIPS_MT */ | ||
41 | 142 | ||
42 | static inline void flush_icache_line_indexed(unsigned long addr) | 143 | static inline void flush_icache_line_indexed(unsigned long addr) |
43 | { | 144 | { |
145 | __iflush_prologue | ||
44 | cache_op(Index_Invalidate_I, addr); | 146 | cache_op(Index_Invalidate_I, addr); |
147 | __iflush_epilogue | ||
45 | } | 148 | } |
46 | 149 | ||
47 | static inline void flush_dcache_line_indexed(unsigned long addr) | 150 | static inline void flush_dcache_line_indexed(unsigned long addr) |
48 | { | 151 | { |
152 | __dflush_prologue | ||
49 | cache_op(Index_Writeback_Inv_D, addr); | 153 | cache_op(Index_Writeback_Inv_D, addr); |
154 | __dflush_epilogue | ||
50 | } | 155 | } |
51 | 156 | ||
52 | static inline void flush_scache_line_indexed(unsigned long addr) | 157 | static inline void flush_scache_line_indexed(unsigned long addr) |
@@ -56,17 +161,23 @@ static inline void flush_scache_line_indexed(unsigned long addr) | |||
56 | 161 | ||
57 | static inline void flush_icache_line(unsigned long addr) | 162 | static inline void flush_icache_line(unsigned long addr) |
58 | { | 163 | { |
164 | __iflush_prologue | ||
59 | cache_op(Hit_Invalidate_I, addr); | 165 | cache_op(Hit_Invalidate_I, addr); |
166 | __iflush_epilogue | ||
60 | } | 167 | } |
61 | 168 | ||
62 | static inline void flush_dcache_line(unsigned long addr) | 169 | static inline void flush_dcache_line(unsigned long addr) |
63 | { | 170 | { |
171 | __dflush_prologue | ||
64 | cache_op(Hit_Writeback_Inv_D, addr); | 172 | cache_op(Hit_Writeback_Inv_D, addr); |
173 | __dflush_epilogue | ||
65 | } | 174 | } |
66 | 175 | ||
67 | static inline void invalidate_dcache_line(unsigned long addr) | 176 | static inline void invalidate_dcache_line(unsigned long addr) |
68 | { | 177 | { |
178 | __dflush_prologue | ||
69 | cache_op(Hit_Invalidate_D, addr); | 179 | cache_op(Hit_Invalidate_D, addr); |
180 | __dflush_epilogue | ||
70 | } | 181 | } |
71 | 182 | ||
72 | static inline void invalidate_scache_line(unsigned long addr) | 183 | static inline void invalidate_scache_line(unsigned long addr) |
@@ -239,9 +350,13 @@ static inline void blast_##pfx##cache##lsize(void) \ | |||
239 | current_cpu_data.desc.waybit; \ | 350 | current_cpu_data.desc.waybit; \ |
240 | unsigned long ws, addr; \ | 351 | unsigned long ws, addr; \ |
241 | \ | 352 | \ |
353 | __##pfx##flush_prologue \ | ||
354 | \ | ||
242 | for (ws = 0; ws < ws_end; ws += ws_inc) \ | 355 | for (ws = 0; ws < ws_end; ws += ws_inc) \ |
243 | for (addr = start; addr < end; addr += lsize * 32) \ | 356 | for (addr = start; addr < end; addr += lsize * 32) \ |
244 | cache##lsize##_unroll32(addr|ws,indexop); \ | 357 | cache##lsize##_unroll32(addr|ws,indexop); \ |
358 | \ | ||
359 | __##pfx##flush_epilogue \ | ||
245 | } \ | 360 | } \ |
246 | \ | 361 | \ |
247 | static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \ | 362 | static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \ |
@@ -249,10 +364,14 @@ static inline void blast_##pfx##cache##lsize##_page(unsigned long page) \ | |||
249 | unsigned long start = page; \ | 364 | unsigned long start = page; \ |
250 | unsigned long end = page + PAGE_SIZE; \ | 365 | unsigned long end = page + PAGE_SIZE; \ |
251 | \ | 366 | \ |
367 | __##pfx##flush_prologue \ | ||
368 | \ | ||
252 | do { \ | 369 | do { \ |
253 | cache##lsize##_unroll32(start,hitop); \ | 370 | cache##lsize##_unroll32(start,hitop); \ |
254 | start += lsize * 32; \ | 371 | start += lsize * 32; \ |
255 | } while (start < end); \ | 372 | } while (start < end); \ |
373 | \ | ||
374 | __##pfx##flush_epilogue \ | ||
256 | } \ | 375 | } \ |
257 | \ | 376 | \ |
258 | static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \ | 377 | static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) \ |
@@ -265,9 +384,13 @@ static inline void blast_##pfx##cache##lsize##_page_indexed(unsigned long page) | |||
265 | current_cpu_data.desc.waybit; \ | 384 | current_cpu_data.desc.waybit; \ |
266 | unsigned long ws, addr; \ | 385 | unsigned long ws, addr; \ |
267 | \ | 386 | \ |
387 | __##pfx##flush_prologue \ | ||
388 | \ | ||
268 | for (ws = 0; ws < ws_end; ws += ws_inc) \ | 389 | for (ws = 0; ws < ws_end; ws += ws_inc) \ |
269 | for (addr = start; addr < end; addr += lsize * 32) \ | 390 | for (addr = start; addr < end; addr += lsize * 32) \ |
270 | cache##lsize##_unroll32(addr|ws,indexop); \ | 391 | cache##lsize##_unroll32(addr|ws,indexop); \ |
392 | \ | ||
393 | __##pfx##flush_epilogue \ | ||
271 | } | 394 | } |
272 | 395 | ||
273 | __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16) | 396 | __BUILD_BLAST_CACHE(d, dcache, Index_Writeback_Inv_D, Hit_Writeback_Inv_D, 16) |
@@ -288,12 +411,17 @@ static inline void prot##blast_##pfx##cache##_range(unsigned long start, \ | |||
288 | unsigned long lsize = cpu_##desc##_line_size(); \ | 411 | unsigned long lsize = cpu_##desc##_line_size(); \ |
289 | unsigned long addr = start & ~(lsize - 1); \ | 412 | unsigned long addr = start & ~(lsize - 1); \ |
290 | unsigned long aend = (end - 1) & ~(lsize - 1); \ | 413 | unsigned long aend = (end - 1) & ~(lsize - 1); \ |
414 | \ | ||
415 | __##pfx##flush_prologue \ | ||
416 | \ | ||
291 | while (1) { \ | 417 | while (1) { \ |
292 | prot##cache_op(hitop, addr); \ | 418 | prot##cache_op(hitop, addr); \ |
293 | if (addr == aend) \ | 419 | if (addr == aend) \ |
294 | break; \ | 420 | break; \ |
295 | addr += lsize; \ | 421 | addr += lsize; \ |
296 | } \ | 422 | } \ |
423 | \ | ||
424 | __##pfx##flush_epilogue \ | ||
297 | } | 425 | } |
298 | 426 | ||
299 | __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) | 427 | __BUILD_BLAST_CACHE_RANGE(d, dcache, Hit_Writeback_Inv_D, protected_) |
diff --git a/include/asm-mips/rtc.h b/include/asm-mips/rtc.h index a2abc4572b63..82ad401c7dca 100644 --- a/include/asm-mips/rtc.h +++ b/include/asm-mips/rtc.h | |||
@@ -32,7 +32,7 @@ static inline unsigned int get_rtc_time(struct rtc_time *time) | |||
32 | { | 32 | { |
33 | unsigned long nowtime; | 33 | unsigned long nowtime; |
34 | 34 | ||
35 | nowtime = rtc_get_time(); | 35 | nowtime = rtc_mips_get_time(); |
36 | to_tm(nowtime, time); | 36 | to_tm(nowtime, time); |
37 | time->tm_year -= 1900; | 37 | time->tm_year -= 1900; |
38 | 38 | ||
@@ -47,7 +47,7 @@ static inline int set_rtc_time(struct rtc_time *time) | |||
47 | nowtime = mktime(time->tm_year+1900, time->tm_mon+1, | 47 | nowtime = mktime(time->tm_year+1900, time->tm_mon+1, |
48 | time->tm_mday, time->tm_hour, time->tm_min, | 48 | time->tm_mday, time->tm_hour, time->tm_min, |
49 | time->tm_sec); | 49 | time->tm_sec); |
50 | ret = rtc_set_time(nowtime); | 50 | ret = rtc_mips_set_time(nowtime); |
51 | 51 | ||
52 | return ret; | 52 | return ret; |
53 | } | 53 | } |
diff --git a/include/asm-mips/rtlx.h b/include/asm-mips/rtlx.h index 1298c3fdf6c9..76cd51c6be39 100644 --- a/include/asm-mips/rtlx.h +++ b/include/asm-mips/rtlx.h | |||
@@ -3,32 +3,46 @@ | |||
3 | * | 3 | * |
4 | */ | 4 | */ |
5 | 5 | ||
6 | #ifndef _RTLX_H | 6 | #ifndef __ASM_RTLX_H |
7 | #define _RTLX_H_ | 7 | #define __ASM_RTLX_H_ |
8 | 8 | ||
9 | #define LX_NODE_BASE 10 | 9 | #define LX_NODE_BASE 10 |
10 | 10 | ||
11 | #define MIPSCPU_INT_BASE 16 | 11 | #define MIPSCPU_INT_BASE 16 |
12 | #define MIPS_CPU_RTLX_IRQ 0 | 12 | #define MIPS_CPU_RTLX_IRQ 0 |
13 | 13 | ||
14 | #define RTLX_VERSION 1 | 14 | #define RTLX_VERSION 2 |
15 | #define RTLX_xID 0x12345600 | 15 | #define RTLX_xID 0x12345600 |
16 | #define RTLX_ID (RTLX_xID | RTLX_VERSION) | 16 | #define RTLX_ID (RTLX_xID | RTLX_VERSION) |
17 | #define RTLX_CHANNELS 8 | 17 | #define RTLX_CHANNELS 8 |
18 | 18 | ||
19 | #define RTLX_BUFFER_SIZE 1024 | 19 | #define RTLX_CHANNEL_STDIO 0 |
20 | #define RTLX_CHANNEL_DBG 1 | ||
21 | #define RTLX_CHANNEL_SYSIO 2 | ||
20 | 22 | ||
21 | /* | 23 | extern int rtlx_open(int index, int can_sleep); |
22 | * lx_state bits | 24 | extern int rtlx_release(int index); |
23 | */ | 25 | extern ssize_t rtlx_read(int index, void *buff, size_t count, int user); |
24 | #define RTLX_STATE_OPENED 1UL | 26 | extern ssize_t rtlx_write(int index, void *buffer, size_t count, int user); |
27 | extern unsigned int rtlx_read_poll(int index, int can_sleep); | ||
28 | extern unsigned int rtlx_write_poll(int index); | ||
29 | |||
30 | enum rtlx_state { | ||
31 | RTLX_STATE_UNUSED, | ||
32 | RTLX_STATE_INITIALISED, | ||
33 | RTLX_STATE_REMOTE_READY, | ||
34 | RTLX_STATE_OPENED | ||
35 | }; | ||
36 | |||
37 | #define RTLX_BUFFER_SIZE 1024 | ||
25 | 38 | ||
26 | /* each channel supports read and write. | 39 | /* each channel supports read and write. |
27 | linux (vpe0) reads lx_buffer and writes rt_buffer | 40 | linux (vpe0) reads lx_buffer and writes rt_buffer |
28 | SP (vpe1) reads rt_buffer and writes lx_buffer | 41 | SP (vpe1) reads rt_buffer and writes lx_buffer |
29 | */ | 42 | */ |
30 | struct rtlx_channel { | 43 | struct rtlx_channel { |
31 | unsigned long lx_state; | 44 | enum rtlx_state rt_state; |
45 | enum rtlx_state lx_state; | ||
32 | 46 | ||
33 | int buffer_size; | 47 | int buffer_size; |
34 | 48 | ||
@@ -38,15 +52,13 @@ struct rtlx_channel { | |||
38 | 52 | ||
39 | int lx_write, lx_read; | 53 | int lx_write, lx_read; |
40 | char *lx_buffer; | 54 | char *lx_buffer; |
41 | |||
42 | void *queues; | ||
43 | |||
44 | }; | 55 | }; |
45 | 56 | ||
46 | struct rtlx_info { | 57 | struct rtlx_info { |
47 | unsigned long id; | 58 | unsigned long id; |
59 | enum rtlx_state state; | ||
48 | 60 | ||
49 | struct rtlx_channel channel[RTLX_CHANNELS]; | 61 | struct rtlx_channel channel[RTLX_CHANNELS]; |
50 | }; | 62 | }; |
51 | 63 | ||
52 | #endif /* _RTLX_H_ */ | 64 | #endif /* __ASM_RTLX_H_ */ |
diff --git a/include/asm-mips/serial.h b/include/asm-mips/serial.h index 7b2366412203..7196ceb0e948 100644 --- a/include/asm-mips/serial.h +++ b/include/asm-mips/serial.h | |||
@@ -77,15 +77,15 @@ | |||
77 | #include <asm/it8712.h> | 77 | #include <asm/it8712.h> |
78 | #define ITE_SERIAL_PORT_DEFNS \ | 78 | #define ITE_SERIAL_PORT_DEFNS \ |
79 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ | 79 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ |
80 | .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ | 80 | .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \ |
81 | { .baud_base = (24000000/(16*13)), .port = (IT8172_PCI_IO_BASE + IT8712_UART1_PORT), \ | 81 | { .baud_base = (24000000/(16*13)), .port = (IT8172_PCI_IO_BASE + IT8712_UART1_PORT), \ |
82 | .irq = IT8172_SERIRQ_4, .flags = STD_COM_FLAGS, .type = 0x3 }, \ | 82 | .irq = IT8172_SERIRQ_4, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \ |
83 | /* Smart Card Reader 0 */ \ | 83 | /* Smart Card Reader 0 */ \ |
84 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR0_BASE), \ | 84 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR0_BASE), \ |
85 | .irq = IT8172_SCR0_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ | 85 | .irq = IT8172_SCR0_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \ |
86 | /* Smart Card Reader 1 */ \ | 86 | /* Smart Card Reader 1 */ \ |
87 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ | 87 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ |
88 | .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, | 88 | .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, |
89 | #else | 89 | #else |
90 | #define ITE_SERIAL_PORT_DEFNS | 90 | #define ITE_SERIAL_PORT_DEFNS |
91 | #endif | 91 | #endif |
@@ -95,10 +95,10 @@ | |||
95 | #include <asm/it8172/it8172_int.h> | 95 | #include <asm/it8172/it8172_int.h> |
96 | #define IVR_SERIAL_PORT_DEFNS \ | 96 | #define IVR_SERIAL_PORT_DEFNS \ |
97 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ | 97 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_UART_BASE), \ |
98 | .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, \ | 98 | .irq = IT8172_UART_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, \ |
99 | /* Smart Card Reader 1 */ \ | 99 | /* Smart Card Reader 1 */ \ |
100 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ | 100 | { .baud_base = BASE_BAUD, .port = (IT8172_PCI_IO_BASE + IT_SCR1_BASE), \ |
101 | .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .type = 0x3 }, | 101 | .irq = IT8172_SCR1_IRQ, .flags = STD_COM_FLAGS, .port = PORT_16550 }, |
102 | #else | 102 | #else |
103 | #define IVR_SERIAL_PORT_DEFNS | 103 | #define IVR_SERIAL_PORT_DEFNS |
104 | #endif | 104 | #endif |
diff --git a/include/asm-mips/smtc.h b/include/asm-mips/smtc.h new file mode 100644 index 000000000000..e1941d1b8726 --- /dev/null +++ b/include/asm-mips/smtc.h | |||
@@ -0,0 +1,55 @@ | |||
1 | #ifndef _ASM_SMTC_MT_H | ||
2 | #define _ASM_SMTC_MT_H | ||
3 | |||
4 | /* | ||
5 | * Definitions for SMTC multitasking on MIPS MT cores | ||
6 | */ | ||
7 | |||
8 | #include <asm/mips_mt.h> | ||
9 | |||
10 | /* | ||
11 | * System-wide SMTC status information | ||
12 | */ | ||
13 | |||
14 | extern unsigned int smtc_status; | ||
15 | |||
16 | #define SMTC_TLB_SHARED 0x00000001 | ||
17 | #define SMTC_MTC_ACTIVE 0x00000002 | ||
18 | |||
19 | /* | ||
20 | * TLB/ASID Management information | ||
21 | */ | ||
22 | |||
23 | #define MAX_SMTC_TLBS 2 | ||
24 | #define MAX_SMTC_ASIDS 256 | ||
25 | #if NR_CPUS <= 8 | ||
26 | typedef char asiduse; | ||
27 | #else | ||
28 | #if NR_CPUS <= 16 | ||
29 | typedef short asiduse; | ||
30 | #else | ||
31 | typedef long asiduse; | ||
32 | #endif | ||
33 | #endif | ||
34 | |||
35 | extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS]; | ||
36 | |||
37 | void smtc_get_new_mmu_context(struct mm_struct *mm, unsigned long cpu); | ||
38 | |||
39 | void smtc_flush_tlb_asid(unsigned long asid); | ||
40 | extern int mipsmt_build_cpu_map(int startslot); | ||
41 | extern void mipsmt_prepare_cpus(void); | ||
42 | extern void smtc_smp_finish(void); | ||
43 | extern void smtc_boot_secondary(int cpu, struct task_struct *t); | ||
44 | |||
45 | /* | ||
46 | * Sharing the TLB between multiple VPEs means that the | ||
47 | * "random" index selection function is not allowed to | ||
48 | * select the current value of the Index register. To | ||
49 | * avoid additional TLB pressure, the Index registers | ||
50 | * are "parked" with an non-Valid value. | ||
51 | */ | ||
52 | |||
53 | #define PARKED_INDEX ((unsigned int)0x80000000) | ||
54 | |||
55 | #endif /* _ASM_SMTC_MT_H */ | ||
diff --git a/include/asm-mips/smtc_ipi.h b/include/asm-mips/smtc_ipi.h new file mode 100644 index 000000000000..f22c3e2f993a --- /dev/null +++ b/include/asm-mips/smtc_ipi.h | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * Definitions used in MIPS MT SMTC "Interprocessor Interrupt" code. | ||
3 | */ | ||
4 | #ifndef __ASM_SMTC_IPI_H | ||
5 | #define __ASM_SMTC_IPI_H | ||
6 | |||
7 | //#define SMTC_IPI_DEBUG | ||
8 | |||
9 | #ifdef SMTC_IPI_DEBUG | ||
10 | #include <asm/mipsregs.h> | ||
11 | #include <asm/mipsmtregs.h> | ||
12 | #endif /* SMTC_IPI_DEBUG */ | ||
13 | |||
14 | /* | ||
15 | * An IPI "message" | ||
16 | */ | ||
17 | |||
18 | struct smtc_ipi { | ||
19 | struct smtc_ipi *flink; | ||
20 | int type; | ||
21 | void *arg; | ||
22 | int dest; | ||
23 | #ifdef SMTC_IPI_DEBUG | ||
24 | int sender; | ||
25 | long stamp; | ||
26 | #endif /* SMTC_IPI_DEBUG */ | ||
27 | }; | ||
28 | |||
29 | /* | ||
30 | * Defined IPI Types | ||
31 | */ | ||
32 | |||
33 | #define LINUX_SMP_IPI 1 | ||
34 | #define SMTC_CLOCK_TICK 2 | ||
35 | |||
36 | /* | ||
37 | * A queue of IPI messages | ||
38 | */ | ||
39 | |||
40 | struct smtc_ipi_q { | ||
41 | struct smtc_ipi *head; | ||
42 | spinlock_t lock; | ||
43 | struct smtc_ipi *tail; | ||
44 | int depth; | ||
45 | }; | ||
46 | |||
47 | extern struct smtc_ipi_q IPIQ[NR_CPUS]; | ||
48 | extern struct smtc_ipi_q freeIPIq; | ||
49 | |||
50 | static inline void smtc_ipi_nq(struct smtc_ipi_q *q, struct smtc_ipi *p) | ||
51 | { | ||
52 | long flags; | ||
53 | |||
54 | spin_lock_irqsave(&q->lock, flags); | ||
55 | if (q->head == NULL) | ||
56 | q->head = q->tail = p; | ||
57 | else | ||
58 | q->tail->flink = p; | ||
59 | p->flink = NULL; | ||
60 | q->tail = p; | ||
61 | q->depth++; | ||
62 | #ifdef SMTC_IPI_DEBUG | ||
63 | p->sender = read_c0_tcbind(); | ||
64 | p->stamp = read_c0_count(); | ||
65 | #endif /* SMTC_IPI_DEBUG */ | ||
66 | spin_unlock_irqrestore(&q->lock, flags); | ||
67 | } | ||
68 | |||
69 | static inline struct smtc_ipi *smtc_ipi_dq(struct smtc_ipi_q *q) | ||
70 | { | ||
71 | struct smtc_ipi *p; | ||
72 | long flags; | ||
73 | |||
74 | spin_lock_irqsave(&q->lock, flags); | ||
75 | if (q->head == NULL) | ||
76 | p = NULL; | ||
77 | else { | ||
78 | p = q->head; | ||
79 | q->head = q->head->flink; | ||
80 | q->depth--; | ||
81 | /* Arguably unnecessary, but leaves queue cleaner */ | ||
82 | if (q->head == NULL) | ||
83 | q->tail = NULL; | ||
84 | } | ||
85 | spin_unlock_irqrestore(&q->lock, flags); | ||
86 | return p; | ||
87 | } | ||
88 | |||
89 | static inline void smtc_ipi_req(struct smtc_ipi_q *q, struct smtc_ipi *p) | ||
90 | { | ||
91 | long flags; | ||
92 | |||
93 | spin_lock_irqsave(&q->lock, flags); | ||
94 | if (q->head == NULL) { | ||
95 | q->head = q->tail = p; | ||
96 | p->flink = NULL; | ||
97 | } else { | ||
98 | p->flink = q->head; | ||
99 | q->head = p; | ||
100 | } | ||
101 | q->depth++; | ||
102 | spin_unlock_irqrestore(&q->lock, flags); | ||
103 | } | ||
104 | |||
105 | static inline int smtc_ipi_qdepth(struct smtc_ipi_q *q) | ||
106 | { | ||
107 | long flags; | ||
108 | int retval; | ||
109 | |||
110 | spin_lock_irqsave(&q->lock, flags); | ||
111 | retval = q->depth; | ||
112 | spin_unlock_irqrestore(&q->lock, flags); | ||
113 | return retval; | ||
114 | } | ||
115 | |||
116 | extern void smtc_send_ipi(int cpu, int type, unsigned int action); | ||
117 | |||
118 | #endif /* __ASM_SMTC_IPI_H */ | ||
diff --git a/include/asm-mips/smtc_proc.h b/include/asm-mips/smtc_proc.h new file mode 100644 index 000000000000..25da651f1f5f --- /dev/null +++ b/include/asm-mips/smtc_proc.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * Definitions for SMTC /proc entries | ||
3 | * Copyright(C) 2005 MIPS Technologies Inc. | ||
4 | */ | ||
5 | #ifndef __ASM_SMTC_PROC_H | ||
6 | #define __ASM_SMTC_PROC_H | ||
7 | |||
8 | /* | ||
9 | * per-"CPU" statistics | ||
10 | */ | ||
11 | |||
12 | struct smtc_cpu_proc { | ||
13 | unsigned long timerints; | ||
14 | unsigned long selfipis; | ||
15 | }; | ||
16 | |||
17 | extern struct smtc_cpu_proc smtc_cpu_stats[NR_CPUS]; | ||
18 | |||
19 | /* Count of number of recoveries of "stolen" FPU access rights on 34K */ | ||
20 | |||
21 | extern atomic_t smtc_fpu_recoveries; | ||
22 | |||
23 | #endif /* __ASM_SMTC_PROC_H */ | ||
diff --git a/include/asm-mips/stackframe.h b/include/asm-mips/stackframe.h index 2acf3e844f00..c4856a874965 100644 --- a/include/asm-mips/stackframe.h +++ b/include/asm-mips/stackframe.h | |||
@@ -14,9 +14,14 @@ | |||
14 | #include <linux/threads.h> | 14 | #include <linux/threads.h> |
15 | 15 | ||
16 | #include <asm/asm.h> | 16 | #include <asm/asm.h> |
17 | #include <asm/asmmacro.h> | ||
17 | #include <asm/mipsregs.h> | 18 | #include <asm/mipsregs.h> |
18 | #include <asm/asm-offsets.h> | 19 | #include <asm/asm-offsets.h> |
19 | 20 | ||
21 | #ifdef CONFIG_MIPS_MT_SMTC | ||
22 | #include <asm/mipsmtregs.h> | ||
23 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
24 | |||
20 | .macro SAVE_AT | 25 | .macro SAVE_AT |
21 | .set push | 26 | .set push |
22 | .set noat | 27 | .set noat |
@@ -57,13 +62,30 @@ | |||
57 | #ifdef CONFIG_SMP | 62 | #ifdef CONFIG_SMP |
58 | .macro get_saved_sp /* SMP variation */ | 63 | .macro get_saved_sp /* SMP variation */ |
59 | #ifdef CONFIG_32BIT | 64 | #ifdef CONFIG_32BIT |
65 | #ifdef CONFIG_MIPS_MT_SMTC | ||
66 | .set mips32 | ||
67 | mfc0 k0, CP0_TCBIND; | ||
68 | .set mips0 | ||
69 | lui k1, %hi(kernelsp) | ||
70 | srl k0, k0, 19 | ||
71 | /* No need to shift down and up to clear bits 0-1 */ | ||
72 | #else | ||
60 | mfc0 k0, CP0_CONTEXT | 73 | mfc0 k0, CP0_CONTEXT |
61 | lui k1, %hi(kernelsp) | 74 | lui k1, %hi(kernelsp) |
62 | srl k0, k0, 23 | 75 | srl k0, k0, 23 |
76 | #endif | ||
63 | addu k1, k0 | 77 | addu k1, k0 |
64 | LONG_L k1, %lo(kernelsp)(k1) | 78 | LONG_L k1, %lo(kernelsp)(k1) |
65 | #endif | 79 | #endif |
66 | #ifdef CONFIG_64BIT | 80 | #ifdef CONFIG_64BIT |
81 | #ifdef CONFIG_MIPS_MT_SMTC | ||
82 | .set mips64 | ||
83 | mfc0 k0, CP0_TCBIND; | ||
84 | .set mips0 | ||
85 | lui k0, %highest(kernelsp) | ||
86 | dsrl k1, 19 | ||
87 | /* No need to shift down and up to clear bits 0-2 */ | ||
88 | #else | ||
67 | MFC0 k1, CP0_CONTEXT | 89 | MFC0 k1, CP0_CONTEXT |
68 | lui k0, %highest(kernelsp) | 90 | lui k0, %highest(kernelsp) |
69 | dsrl k1, 23 | 91 | dsrl k1, 23 |
@@ -71,20 +93,31 @@ | |||
71 | dsll k0, k0, 16 | 93 | dsll k0, k0, 16 |
72 | daddiu k0, %hi(kernelsp) | 94 | daddiu k0, %hi(kernelsp) |
73 | dsll k0, k0, 16 | 95 | dsll k0, k0, 16 |
96 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
74 | daddu k1, k1, k0 | 97 | daddu k1, k1, k0 |
75 | LONG_L k1, %lo(kernelsp)(k1) | 98 | LONG_L k1, %lo(kernelsp)(k1) |
76 | #endif | 99 | #endif /* CONFIG_64BIT */ |
77 | .endm | 100 | .endm |
78 | 101 | ||
79 | .macro set_saved_sp stackp temp temp2 | 102 | .macro set_saved_sp stackp temp temp2 |
80 | #ifdef CONFIG_32BIT | 103 | #ifdef CONFIG_32BIT |
104 | #ifdef CONFIG_MIPS_MT_SMTC | ||
105 | mfc0 \temp, CP0_TCBIND | ||
106 | srl \temp, 19 | ||
107 | #else | ||
81 | mfc0 \temp, CP0_CONTEXT | 108 | mfc0 \temp, CP0_CONTEXT |
82 | srl \temp, 23 | 109 | srl \temp, 23 |
83 | #endif | 110 | #endif |
111 | #endif | ||
84 | #ifdef CONFIG_64BIT | 112 | #ifdef CONFIG_64BIT |
113 | #ifdef CONFIG_MIPS_MT_SMTC | ||
114 | mfc0 \temp, CP0_TCBIND | ||
115 | dsrl \temp, 19 | ||
116 | #else | ||
85 | MFC0 \temp, CP0_CONTEXT | 117 | MFC0 \temp, CP0_CONTEXT |
86 | dsrl \temp, 23 | 118 | dsrl \temp, 23 |
87 | #endif | 119 | #endif |
120 | #endif | ||
88 | LONG_S \stackp, kernelsp(\temp) | 121 | LONG_S \stackp, kernelsp(\temp) |
89 | .endm | 122 | .endm |
90 | #else | 123 | #else |
@@ -122,10 +155,25 @@ | |||
122 | PTR_SUBU sp, k1, PT_SIZE | 155 | PTR_SUBU sp, k1, PT_SIZE |
123 | LONG_S k0, PT_R29(sp) | 156 | LONG_S k0, PT_R29(sp) |
124 | LONG_S $3, PT_R3(sp) | 157 | LONG_S $3, PT_R3(sp) |
158 | /* | ||
159 | * You might think that you don't need to save $0, | ||
160 | * but the FPU emulator and gdb remote debug stub | ||
161 | * need it to operate correctly | ||
162 | */ | ||
125 | LONG_S $0, PT_R0(sp) | 163 | LONG_S $0, PT_R0(sp) |
126 | mfc0 v1, CP0_STATUS | 164 | mfc0 v1, CP0_STATUS |
127 | LONG_S $2, PT_R2(sp) | 165 | LONG_S $2, PT_R2(sp) |
128 | LONG_S v1, PT_STATUS(sp) | 166 | LONG_S v1, PT_STATUS(sp) |
167 | #ifdef CONFIG_MIPS_MT_SMTC | ||
168 | /* | ||
169 | * Ideally, these instructions would be shuffled in | ||
170 | * to cover the pipeline delay. | ||
171 | */ | ||
172 | .set mips32 | ||
173 | mfc0 v1, CP0_TCSTATUS | ||
174 | .set mips0 | ||
175 | LONG_S v1, PT_TCSTATUS(sp) | ||
176 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
129 | LONG_S $4, PT_R4(sp) | 177 | LONG_S $4, PT_R4(sp) |
130 | mfc0 v1, CP0_CAUSE | 178 | mfc0 v1, CP0_CAUSE |
131 | LONG_S $5, PT_R5(sp) | 179 | LONG_S $5, PT_R5(sp) |
@@ -234,14 +282,36 @@ | |||
234 | .endm | 282 | .endm |
235 | 283 | ||
236 | #else | 284 | #else |
285 | /* | ||
286 | * For SMTC kernel, global IE should be left set, and interrupts | ||
287 | * controlled exclusively via IXMT. | ||
288 | */ | ||
237 | 289 | ||
290 | #ifdef CONFIG_MIPS_MT_SMTC | ||
291 | #define STATMASK 0x1e | ||
292 | #else | ||
293 | #define STATMASK 0x1f | ||
294 | #endif | ||
238 | .macro RESTORE_SOME | 295 | .macro RESTORE_SOME |
239 | .set push | 296 | .set push |
240 | .set reorder | 297 | .set reorder |
241 | .set noat | 298 | .set noat |
299 | #ifdef CONFIG_MIPS_MT_SMTC | ||
300 | .set mips32r2 | ||
301 | /* | ||
302 | * This may not really be necessary if ints are already | ||
303 | * inhibited here. | ||
304 | */ | ||
305 | mfc0 v0, CP0_TCSTATUS | ||
306 | ori v0, TCSTATUS_IXMT | ||
307 | mtc0 v0, CP0_TCSTATUS | ||
308 | ehb | ||
309 | DMT 5 # dmt a1 | ||
310 | jal mips_ihb | ||
311 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
242 | mfc0 a0, CP0_STATUS | 312 | mfc0 a0, CP0_STATUS |
243 | ori a0, 0x1f | 313 | ori a0, STATMASK |
244 | xori a0, 0x1f | 314 | xori a0, STATMASK |
245 | mtc0 a0, CP0_STATUS | 315 | mtc0 a0, CP0_STATUS |
246 | li v1, 0xff00 | 316 | li v1, 0xff00 |
247 | and a0, v1 | 317 | and a0, v1 |
@@ -250,6 +320,26 @@ | |||
250 | and v0, v1 | 320 | and v0, v1 |
251 | or v0, a0 | 321 | or v0, a0 |
252 | mtc0 v0, CP0_STATUS | 322 | mtc0 v0, CP0_STATUS |
323 | #ifdef CONFIG_MIPS_MT_SMTC | ||
324 | /* | ||
325 | * Only after EXL/ERL have been restored to status can we | ||
326 | * restore TCStatus.IXMT. | ||
327 | */ | ||
328 | LONG_L v1, PT_TCSTATUS(sp) | ||
329 | ehb | ||
330 | mfc0 v0, CP0_TCSTATUS | ||
331 | andi v1, TCSTATUS_IXMT | ||
332 | /* We know that TCStatua.IXMT should be set from above */ | ||
333 | xori v0, v0, TCSTATUS_IXMT | ||
334 | or v0, v0, v1 | ||
335 | mtc0 v0, CP0_TCSTATUS | ||
336 | ehb | ||
337 | andi a1, a1, VPECONTROL_TE | ||
338 | beqz a1, 1f | ||
339 | emt | ||
340 | 1: | ||
341 | .set mips0 | ||
342 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
253 | LONG_L v1, PT_EPC(sp) | 343 | LONG_L v1, PT_EPC(sp) |
254 | MTC0 v1, CP0_EPC | 344 | MTC0 v1, CP0_EPC |
255 | LONG_L $31, PT_R31(sp) | 345 | LONG_L $31, PT_R31(sp) |
@@ -302,11 +392,33 @@ | |||
302 | * Set cp0 enable bit as sign that we're running on the kernel stack | 392 | * Set cp0 enable bit as sign that we're running on the kernel stack |
303 | */ | 393 | */ |
304 | .macro CLI | 394 | .macro CLI |
395 | #if !defined(CONFIG_MIPS_MT_SMTC) | ||
305 | mfc0 t0, CP0_STATUS | 396 | mfc0 t0, CP0_STATUS |
306 | li t1, ST0_CU0 | 0x1f | 397 | li t1, ST0_CU0 | 0x1f |
307 | or t0, t1 | 398 | or t0, t1 |
308 | xori t0, 0x1f | 399 | xori t0, 0x1f |
309 | mtc0 t0, CP0_STATUS | 400 | mtc0 t0, CP0_STATUS |
401 | #else /* CONFIG_MIPS_MT_SMTC */ | ||
402 | /* | ||
403 | * For SMTC, we need to set privilege | ||
404 | * and disable interrupts only for the | ||
405 | * current TC, using the TCStatus register. | ||
406 | */ | ||
407 | mfc0 t0,CP0_TCSTATUS | ||
408 | /* Fortunately CU 0 is in the same place in both registers */ | ||
409 | /* Set TCU0, TMX, TKSU (for later inversion) and IXMT */ | ||
410 | li t1, ST0_CU0 | 0x08001c00 | ||
411 | or t0,t1 | ||
412 | /* Clear TKSU, leave IXMT */ | ||
413 | xori t0, 0x00001800 | ||
414 | mtc0 t0, CP0_TCSTATUS | ||
415 | ehb | ||
416 | /* We need to leave the global IE bit set, but clear EXL...*/ | ||
417 | mfc0 t0, CP0_STATUS | ||
418 | ori t0, ST0_EXL | ST0_ERL | ||
419 | xori t0, ST0_EXL | ST0_ERL | ||
420 | mtc0 t0, CP0_STATUS | ||
421 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
310 | irq_disable_hazard | 422 | irq_disable_hazard |
311 | .endm | 423 | .endm |
312 | 424 | ||
@@ -315,11 +427,35 @@ | |||
315 | * Set cp0 enable bit as sign that we're running on the kernel stack | 427 | * Set cp0 enable bit as sign that we're running on the kernel stack |
316 | */ | 428 | */ |
317 | .macro STI | 429 | .macro STI |
430 | #if !defined(CONFIG_MIPS_MT_SMTC) | ||
318 | mfc0 t0, CP0_STATUS | 431 | mfc0 t0, CP0_STATUS |
319 | li t1, ST0_CU0 | 0x1f | 432 | li t1, ST0_CU0 | 0x1f |
320 | or t0, t1 | 433 | or t0, t1 |
321 | xori t0, 0x1e | 434 | xori t0, 0x1e |
322 | mtc0 t0, CP0_STATUS | 435 | mtc0 t0, CP0_STATUS |
436 | #else /* CONFIG_MIPS_MT_SMTC */ | ||
437 | /* | ||
438 | * For SMTC, we need to set privilege | ||
439 | * and enable interrupts only for the | ||
440 | * current TC, using the TCStatus register. | ||
441 | */ | ||
442 | ehb | ||
443 | mfc0 t0,CP0_TCSTATUS | ||
444 | /* Fortunately CU 0 is in the same place in both registers */ | ||
445 | /* Set TCU0, TKSU (for later inversion) and IXMT */ | ||
446 | li t1, ST0_CU0 | 0x08001c00 | ||
447 | or t0,t1 | ||
448 | /* Clear TKSU *and* IXMT */ | ||
449 | xori t0, 0x00001c00 | ||
450 | mtc0 t0, CP0_TCSTATUS | ||
451 | ehb | ||
452 | /* We need to leave the global IE bit set, but clear EXL...*/ | ||
453 | mfc0 t0, CP0_STATUS | ||
454 | ori t0, ST0_EXL | ||
455 | xori t0, ST0_EXL | ||
456 | mtc0 t0, CP0_STATUS | ||
457 | /* irq_enable_hazard below should expand to EHB for 24K/34K cpus */ | ||
458 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
323 | irq_enable_hazard | 459 | irq_enable_hazard |
324 | .endm | 460 | .endm |
325 | 461 | ||
@@ -328,11 +464,56 @@ | |||
328 | * Set cp0 enable bit as sign that we're running on the kernel stack | 464 | * Set cp0 enable bit as sign that we're running on the kernel stack |
329 | */ | 465 | */ |
330 | .macro KMODE | 466 | .macro KMODE |
467 | #ifdef CONFIG_MIPS_MT_SMTC | ||
468 | /* | ||
469 | * This gets baroque in SMTC. We want to | ||
470 | * protect the non-atomic clearing of EXL | ||
471 | * with DMT/EMT, but we don't want to take | ||
472 | * an interrupt while DMT is still in effect. | ||
473 | */ | ||
474 | |||
475 | /* KMODE gets invoked from both reorder and noreorder code */ | ||
476 | .set push | ||
477 | .set mips32r2 | ||
478 | .set noreorder | ||
479 | mfc0 v0, CP0_TCSTATUS | ||
480 | andi v1, v0, TCSTATUS_IXMT | ||
481 | ori v0, TCSTATUS_IXMT | ||
482 | mtc0 v0, CP0_TCSTATUS | ||
483 | ehb | ||
484 | DMT 2 # dmt v0 | ||
485 | /* | ||
486 | * We don't know a priori if ra is "live" | ||
487 | */ | ||
488 | move t0, ra | ||
489 | jal mips_ihb | ||
490 | nop /* delay slot */ | ||
491 | move ra, t0 | ||
492 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
331 | mfc0 t0, CP0_STATUS | 493 | mfc0 t0, CP0_STATUS |
332 | li t1, ST0_CU0 | 0x1e | 494 | li t1, ST0_CU0 | 0x1e |
333 | or t0, t1 | 495 | or t0, t1 |
334 | xori t0, 0x1e | 496 | xori t0, 0x1e |
335 | mtc0 t0, CP0_STATUS | 497 | mtc0 t0, CP0_STATUS |
498 | #ifdef CONFIG_MIPS_MT_SMTC | ||
499 | ehb | ||
500 | andi v0, v0, VPECONTROL_TE | ||
501 | beqz v0, 2f | ||
502 | nop /* delay slot */ | ||
503 | emt | ||
504 | 2: | ||
505 | mfc0 v0, CP0_TCSTATUS | ||
506 | /* Clear IXMT, then OR in previous value */ | ||
507 | ori v0, TCSTATUS_IXMT | ||
508 | xori v0, TCSTATUS_IXMT | ||
509 | or v0, v1, v0 | ||
510 | mtc0 v0, CP0_TCSTATUS | ||
511 | /* | ||
512 | * irq_disable_hazard below should expand to EHB | ||
513 | * on 24K/34K CPUS | ||
514 | */ | ||
515 | .set pop | ||
516 | #endif /* CONFIG_MIPS_MT_SMTC */ | ||
336 | irq_disable_hazard | 517 | irq_disable_hazard |
337 | .endm | 518 | .endm |
338 | 519 | ||
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 4097fac5ac3c..261f71d16a07 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h | |||
@@ -155,6 +155,37 @@ extern asmlinkage void *resume(void *last, void *next, void *next_ti); | |||
155 | 155 | ||
156 | struct task_struct; | 156 | struct task_struct; |
157 | 157 | ||
158 | #ifdef CONFIG_MIPS_MT_FPAFF | ||
159 | |||
160 | /* | ||
161 | * Handle the scheduler resume end of FPU affinity management. We do this | ||
162 | * inline to try to keep the overhead down. If we have been forced to run on | ||
163 | * a "CPU" with an FPU because of a previous high level of FP computation, | ||
164 | * but did not actually use the FPU during the most recent time-slice (CU1 | ||
165 | * isn't set), we undo the restriction on cpus_allowed. | ||
166 | * | ||
167 | * We're not calling set_cpus_allowed() here, because we have no need to | ||
168 | * force prompt migration - we're already switching the current CPU to a | ||
169 | * different thread. | ||
170 | */ | ||
171 | |||
172 | #define switch_to(prev,next,last) \ | ||
173 | do { \ | ||
174 | if (cpu_has_fpu && \ | ||
175 | (prev->thread.mflags & MF_FPUBOUND) && \ | ||
176 | (!(KSTK_STATUS(prev) & ST0_CU1))) { \ | ||
177 | prev->thread.mflags &= ~MF_FPUBOUND; \ | ||
178 | prev->cpus_allowed = prev->thread.user_cpus_allowed; \ | ||
179 | } \ | ||
180 | if (cpu_has_dsp) \ | ||
181 | __save_dsp(prev); \ | ||
182 | next->thread.emulated_fp = 0; \ | ||
183 | (last) = resume(prev, next, next->thread_info); \ | ||
184 | if (cpu_has_dsp) \ | ||
185 | __restore_dsp(current); \ | ||
186 | } while(0) | ||
187 | |||
188 | #else | ||
158 | #define switch_to(prev,next,last) \ | 189 | #define switch_to(prev,next,last) \ |
159 | do { \ | 190 | do { \ |
160 | if (cpu_has_dsp) \ | 191 | if (cpu_has_dsp) \ |
@@ -163,6 +194,7 @@ do { \ | |||
163 | if (cpu_has_dsp) \ | 194 | if (cpu_has_dsp) \ |
164 | __restore_dsp(current); \ | 195 | __restore_dsp(current); \ |
165 | } while(0) | 196 | } while(0) |
197 | #endif | ||
166 | 198 | ||
167 | /* | 199 | /* |
168 | * On SMP systems, when the scheduler does migration-cost autodetection, | 200 | * On SMP systems, when the scheduler does migration-cost autodetection, |
@@ -440,8 +472,8 @@ static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, | |||
440 | extern void set_handler (unsigned long offset, void *addr, unsigned long len); | 472 | extern void set_handler (unsigned long offset, void *addr, unsigned long len); |
441 | extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len); | 473 | extern void set_uncached_handler (unsigned long offset, void *addr, unsigned long len); |
442 | extern void *set_vi_handler (int n, void *addr); | 474 | extern void *set_vi_handler (int n, void *addr); |
443 | extern void *set_vi_srs_handler (int n, void *addr, int regset); | ||
444 | extern void *set_except_vector(int n, void *addr); | 475 | extern void *set_except_vector(int n, void *addr); |
476 | extern unsigned long ebase; | ||
445 | extern void per_cpu_trap_init(void); | 477 | extern void per_cpu_trap_init(void); |
446 | 478 | ||
447 | extern NORET_TYPE void die(const char *, struct pt_regs *); | 479 | extern NORET_TYPE void die(const char *, struct pt_regs *); |
diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index b5c78a4a0192..1068fe9a0a58 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h | |||
@@ -324,16 +324,18 @@ | |||
324 | #define __NR_pselect6 (__NR_Linux + 301) | 324 | #define __NR_pselect6 (__NR_Linux + 301) |
325 | #define __NR_ppoll (__NR_Linux + 302) | 325 | #define __NR_ppoll (__NR_Linux + 302) |
326 | #define __NR_unshare (__NR_Linux + 303) | 326 | #define __NR_unshare (__NR_Linux + 303) |
327 | #define __NR_splice (__NR_Linux + 304) | ||
328 | #define __NR_sync_file_range (__NR_Linux + 305) | ||
327 | 329 | ||
328 | /* | 330 | /* |
329 | * Offset of the last Linux o32 flavoured syscall | 331 | * Offset of the last Linux o32 flavoured syscall |
330 | */ | 332 | */ |
331 | #define __NR_Linux_syscalls 303 | 333 | #define __NR_Linux_syscalls 305 |
332 | 334 | ||
333 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ | 335 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI32 */ |
334 | 336 | ||
335 | #define __NR_O32_Linux 4000 | 337 | #define __NR_O32_Linux 4000 |
336 | #define __NR_O32_Linux_syscalls 303 | 338 | #define __NR_O32_Linux_syscalls 305 |
337 | 339 | ||
338 | #if _MIPS_SIM == _MIPS_SIM_ABI64 | 340 | #if _MIPS_SIM == _MIPS_SIM_ABI64 |
339 | 341 | ||
@@ -604,16 +606,18 @@ | |||
604 | #define __NR_pselect6 (__NR_Linux + 260) | 606 | #define __NR_pselect6 (__NR_Linux + 260) |
605 | #define __NR_ppoll (__NR_Linux + 261) | 607 | #define __NR_ppoll (__NR_Linux + 261) |
606 | #define __NR_unshare (__NR_Linux + 262) | 608 | #define __NR_unshare (__NR_Linux + 262) |
609 | #define __NR_splice (__NR_Linux + 263) | ||
610 | #define __NR_sync_file_range (__NR_Linux + 264) | ||
607 | 611 | ||
608 | /* | 612 | /* |
609 | * Offset of the last Linux 64-bit flavoured syscall | 613 | * Offset of the last Linux 64-bit flavoured syscall |
610 | */ | 614 | */ |
611 | #define __NR_Linux_syscalls 262 | 615 | #define __NR_Linux_syscalls 264 |
612 | 616 | ||
613 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ | 617 | #endif /* _MIPS_SIM == _MIPS_SIM_ABI64 */ |
614 | 618 | ||
615 | #define __NR_64_Linux 5000 | 619 | #define __NR_64_Linux 5000 |
616 | #define __NR_64_Linux_syscalls 262 | 620 | #define __NR_64_Linux_syscalls 264 |
617 | 621 | ||
618 | #if _MIPS_SIM == _MIPS_SIM_NABI32 | 622 | #if _MIPS_SIM == _MIPS_SIM_NABI32 |
619 | 623 | ||
@@ -888,16 +892,18 @@ | |||
888 | #define __NR_pselect6 (__NR_Linux + 264) | 892 | #define __NR_pselect6 (__NR_Linux + 264) |
889 | #define __NR_ppoll (__NR_Linux + 265) | 893 | #define __NR_ppoll (__NR_Linux + 265) |
890 | #define __NR_unshare (__NR_Linux + 266) | 894 | #define __NR_unshare (__NR_Linux + 266) |
895 | #define __NR_splice (__NR_Linux + 267) | ||
896 | #define __NR_sync_file_range (__NR_Linux + 268) | ||
891 | 897 | ||
892 | /* | 898 | /* |
893 | * Offset of the last N32 flavoured syscall | 899 | * Offset of the last N32 flavoured syscall |
894 | */ | 900 | */ |
895 | #define __NR_Linux_syscalls 266 | 901 | #define __NR_Linux_syscalls 268 |
896 | 902 | ||
897 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ | 903 | #endif /* _MIPS_SIM == _MIPS_SIM_NABI32 */ |
898 | 904 | ||
899 | #define __NR_N32_Linux 6000 | 905 | #define __NR_N32_Linux 6000 |
900 | #define __NR_N32_Linux_syscalls 266 | 906 | #define __NR_N32_Linux_syscalls 268 |
901 | 907 | ||
902 | #ifndef __ASSEMBLY__ | 908 | #ifndef __ASSEMBLY__ |
903 | 909 | ||
diff --git a/include/asm-mips/vpe.h b/include/asm-mips/vpe.h new file mode 100644 index 000000000000..c6e1b961537d --- /dev/null +++ b/include/asm-mips/vpe.h | |||
@@ -0,0 +1,37 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2005 MIPS Technologies, Inc. All rights reserved. | ||
3 | * | ||
4 | * This program is free software; you can distribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License (Version 2) as | ||
6 | * published by the Free Software Foundation. | ||
7 | * | ||
8 | * This program is distributed in the hope it will be useful, but WITHOUT | ||
9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
10 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | ||
11 | * for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along | ||
14 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
15 | * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #ifndef _ASM_VPE_H | ||
20 | #define _ASM_VPE_H | ||
21 | |||
22 | struct vpe_notifications { | ||
23 | void (*start)(int vpe); | ||
24 | void (*stop)(int vpe); | ||
25 | |||
26 | struct list_head list; | ||
27 | }; | ||
28 | |||
29 | |||
30 | extern int vpe_notify(int index, struct vpe_notifications *notify); | ||
31 | |||
32 | extern void *vpe_get_shared(int index); | ||
33 | extern int vpe_getuid(int index); | ||
34 | extern int vpe_getgid(int index); | ||
35 | extern char *vpe_getcwd(int index); | ||
36 | |||
37 | #endif /* _ASM_VPE_H */ | ||
diff --git a/include/asm-parisc/io.h b/include/asm-parisc/io.h index 29da31194b91..244f6b8883f4 100644 --- a/include/asm-parisc/io.h +++ b/include/asm-parisc/io.h | |||
@@ -126,24 +126,17 @@ static inline void gsc_writeq(unsigned long long val, unsigned long addr) | |||
126 | 126 | ||
127 | extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); | 127 | extern void __iomem * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); |
128 | 128 | ||
129 | extern inline void __iomem * ioremap(unsigned long offset, unsigned long size) | 129 | /* Most machines react poorly to I/O-space being cacheable... Instead let's |
130 | { | 130 | * define ioremap() in terms of ioremap_nocache(). |
131 | return __ioremap(offset, size, 0); | ||
132 | } | ||
133 | |||
134 | /* | ||
135 | * This one maps high address device memory and turns off caching for that area. | ||
136 | * it's useful if some control registers are in such an area and write combining | ||
137 | * or read caching is not desirable: | ||
138 | */ | 131 | */ |
139 | extern inline void * ioremap_nocache(unsigned long offset, unsigned long size) | 132 | extern inline void __iomem * ioremap(unsigned long offset, unsigned long size) |
140 | { | 133 | { |
141 | return __ioremap(offset, size, _PAGE_NO_CACHE /* _PAGE_PCD */); | 134 | return __ioremap(offset, size, _PAGE_NO_CACHE); |
142 | } | 135 | } |
136 | #define ioremap_nocache(off, sz) ioremap((off), (sz)) | ||
143 | 137 | ||
144 | extern void iounmap(void __iomem *addr); | 138 | extern void iounmap(void __iomem *addr); |
145 | 139 | ||
146 | |||
147 | static inline unsigned char __raw_readb(const volatile void __iomem *addr) | 140 | static inline unsigned char __raw_readb(const volatile void __iomem *addr) |
148 | { | 141 | { |
149 | return (*(volatile unsigned char __force *) (addr)); | 142 | return (*(volatile unsigned char __force *) (addr)); |
diff --git a/include/asm-parisc/page.h b/include/asm-parisc/page.h index 45e02aa5bf4b..c0dd461fb8f1 100644 --- a/include/asm-parisc/page.h +++ b/include/asm-parisc/page.h | |||
@@ -1,13 +1,30 @@ | |||
1 | #ifndef _PARISC_PAGE_H | 1 | #ifndef _PARISC_PAGE_H |
2 | #define _PARISC_PAGE_H | 2 | #define _PARISC_PAGE_H |
3 | 3 | ||
4 | /* PAGE_SHIFT determines the page size */ | 4 | #if !defined(__KERNEL__) |
5 | #define PAGE_SHIFT 12 | 5 | /* this is for userspace applications (4k page size) */ |
6 | #define PAGE_SIZE (1UL << PAGE_SHIFT) | 6 | # define PAGE_SHIFT 12 /* 4k */ |
7 | #define PAGE_MASK (~(PAGE_SIZE-1)) | 7 | # define PAGE_SIZE (1UL << PAGE_SHIFT) |
8 | # define PAGE_MASK (~(PAGE_SIZE-1)) | ||
9 | #endif | ||
10 | |||
8 | 11 | ||
9 | #ifdef __KERNEL__ | 12 | #ifdef __KERNEL__ |
10 | #include <linux/config.h> | 13 | #include <linux/config.h> |
14 | |||
15 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) | ||
16 | # define PAGE_SHIFT 12 /* 4k */ | ||
17 | #elif defined(CONFIG_PARISC_PAGE_SIZE_16KB) | ||
18 | # define PAGE_SHIFT 14 /* 16k */ | ||
19 | #elif defined(CONFIG_PARISC_PAGE_SIZE_64KB) | ||
20 | # define PAGE_SHIFT 16 /* 64k */ | ||
21 | #else | ||
22 | # error "unknown default kernel page size" | ||
23 | #endif | ||
24 | #define PAGE_SIZE (1UL << PAGE_SHIFT) | ||
25 | #define PAGE_MASK (~(PAGE_SIZE-1)) | ||
26 | |||
27 | |||
11 | #ifndef __ASSEMBLY__ | 28 | #ifndef __ASSEMBLY__ |
12 | 29 | ||
13 | #include <asm/types.h> | 30 | #include <asm/types.h> |
diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index 4e34c6b44059..aec089eb8b85 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h | |||
@@ -59,16 +59,15 @@ | |||
59 | #define ISTACK_SIZE 32768 /* Interrupt Stack Size */ | 59 | #define ISTACK_SIZE 32768 /* Interrupt Stack Size */ |
60 | #define ISTACK_ORDER 3 | 60 | #define ISTACK_ORDER 3 |
61 | 61 | ||
62 | /* This is the size of the initially mapped kernel memory (i.e. currently | 62 | /* This is the size of the initially mapped kernel memory */ |
63 | * 0 to 1<<23 == 8MB */ | ||
64 | #ifdef CONFIG_64BIT | 63 | #ifdef CONFIG_64BIT |
65 | #define KERNEL_INITIAL_ORDER 24 | 64 | #define KERNEL_INITIAL_ORDER 24 /* 0 to 1<<24 = 16MB */ |
66 | #else | 65 | #else |
67 | #define KERNEL_INITIAL_ORDER 23 | 66 | #define KERNEL_INITIAL_ORDER 23 /* 0 to 1<<23 = 8MB */ |
68 | #endif | 67 | #endif |
69 | #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) | 68 | #define KERNEL_INITIAL_SIZE (1 << KERNEL_INITIAL_ORDER) |
70 | 69 | ||
71 | #ifdef CONFIG_64BIT | 70 | #if defined(CONFIG_64BIT) && defined(CONFIG_PARISC_PAGE_SIZE_4KB) |
72 | #define PT_NLEVELS 3 | 71 | #define PT_NLEVELS 3 |
73 | #define PGD_ORDER 1 /* Number of pages per pgd */ | 72 | #define PGD_ORDER 1 /* Number of pages per pgd */ |
74 | #define PMD_ORDER 1 /* Number of pages per pmd */ | 73 | #define PMD_ORDER 1 /* Number of pages per pmd */ |
@@ -111,11 +110,15 @@ | |||
111 | #define MAX_ADDRBITS (PGDIR_SHIFT + BITS_PER_PGD) | 110 | #define MAX_ADDRBITS (PGDIR_SHIFT + BITS_PER_PGD) |
112 | #define MAX_ADDRESS (1UL << MAX_ADDRBITS) | 111 | #define MAX_ADDRESS (1UL << MAX_ADDRBITS) |
113 | 112 | ||
114 | #define SPACEID_SHIFT (MAX_ADDRBITS - 32) | 113 | #define SPACEID_SHIFT (MAX_ADDRBITS - 32) |
115 | 114 | ||
116 | /* This calculates the number of initial pages we need for the initial | 115 | /* This calculates the number of initial pages we need for the initial |
117 | * page tables */ | 116 | * page tables */ |
118 | #define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PMD_SHIFT)) | 117 | #if (KERNEL_INITIAL_ORDER) >= (PMD_SHIFT) |
118 | # define PT_INITIAL (1 << (KERNEL_INITIAL_ORDER - PMD_SHIFT)) | ||
119 | #else | ||
120 | # define PT_INITIAL (1) /* all initial PTEs fit into one page */ | ||
121 | #endif | ||
119 | 122 | ||
120 | /* | 123 | /* |
121 | * pgd entries used up by user/kernel: | 124 | * pgd entries used up by user/kernel: |
@@ -160,6 +163,10 @@ extern void *vmalloc_start; | |||
160 | * to zero */ | 163 | * to zero */ |
161 | #define PTE_SHIFT xlate_pabit(_PAGE_USER_BIT) | 164 | #define PTE_SHIFT xlate_pabit(_PAGE_USER_BIT) |
162 | 165 | ||
166 | /* PFN_PTE_SHIFT defines the shift of a PTE value to access the PFN field */ | ||
167 | #define PFN_PTE_SHIFT 12 | ||
168 | |||
169 | |||
163 | /* this is how many bits may be used by the file functions */ | 170 | /* this is how many bits may be used by the file functions */ |
164 | #define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_SHIFT) | 171 | #define PTE_FILE_MAX_BITS (BITS_PER_LONG - PTE_SHIFT) |
165 | 172 | ||
@@ -188,7 +195,8 @@ extern void *vmalloc_start; | |||
188 | /* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds | 195 | /* The pgd/pmd contains a ptr (in phys addr space); since all pgds/pmds |
189 | * are page-aligned, we don't care about the PAGE_OFFSET bits, except | 196 | * are page-aligned, we don't care about the PAGE_OFFSET bits, except |
190 | * for a few meta-information bits, so we shift the address to be | 197 | * for a few meta-information bits, so we shift the address to be |
191 | * able to effectively address 40-bits of physical address space. */ | 198 | * able to effectively address 40/42/44-bits of physical address space |
199 | * depending on 4k/16k/64k PAGE_SIZE */ | ||
192 | #define _PxD_PRESENT_BIT 31 | 200 | #define _PxD_PRESENT_BIT 31 |
193 | #define _PxD_ATTACHED_BIT 30 | 201 | #define _PxD_ATTACHED_BIT 30 |
194 | #define _PxD_VALID_BIT 29 | 202 | #define _PxD_VALID_BIT 29 |
@@ -198,7 +206,7 @@ extern void *vmalloc_start; | |||
198 | #define PxD_FLAG_VALID (1 << xlate_pabit(_PxD_VALID_BIT)) | 206 | #define PxD_FLAG_VALID (1 << xlate_pabit(_PxD_VALID_BIT)) |
199 | #define PxD_FLAG_MASK (0xf) | 207 | #define PxD_FLAG_MASK (0xf) |
200 | #define PxD_FLAG_SHIFT (4) | 208 | #define PxD_FLAG_SHIFT (4) |
201 | #define PxD_VALUE_SHIFT (8) | 209 | #define PxD_VALUE_SHIFT (8) /* (PAGE_SHIFT-PxD_FLAG_SHIFT) */ |
202 | 210 | ||
203 | #ifndef __ASSEMBLY__ | 211 | #ifndef __ASSEMBLY__ |
204 | 212 | ||
@@ -246,6 +254,7 @@ extern void *vmalloc_start; | |||
246 | #define __S110 PAGE_RWX | 254 | #define __S110 PAGE_RWX |
247 | #define __S111 PAGE_RWX | 255 | #define __S111 PAGE_RWX |
248 | 256 | ||
257 | |||
249 | extern pgd_t swapper_pg_dir[]; /* declared in init_task.c */ | 258 | extern pgd_t swapper_pg_dir[]; /* declared in init_task.c */ |
250 | 259 | ||
251 | /* initial page tables for 0-8MB for kernel */ | 260 | /* initial page tables for 0-8MB for kernel */ |
@@ -272,7 +281,7 @@ extern unsigned long *empty_zero_page; | |||
272 | #define pgd_flag(x) (pgd_val(x) & PxD_FLAG_MASK) | 281 | #define pgd_flag(x) (pgd_val(x) & PxD_FLAG_MASK) |
273 | #define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT) | 282 | #define pgd_address(x) ((unsigned long)(pgd_val(x) &~ PxD_FLAG_MASK) << PxD_VALUE_SHIFT) |
274 | 283 | ||
275 | #ifdef CONFIG_64BIT | 284 | #if PT_NLEVELS == 3 |
276 | /* The first entry of the permanent pmd is not there if it contains | 285 | /* The first entry of the permanent pmd is not there if it contains |
277 | * the gateway marker */ | 286 | * the gateway marker */ |
278 | #define pmd_none(x) (!pmd_val(x) || pmd_flag(x) == PxD_FLAG_ATTACHED) | 287 | #define pmd_none(x) (!pmd_val(x) || pmd_flag(x) == PxD_FLAG_ATTACHED) |
@@ -282,7 +291,7 @@ extern unsigned long *empty_zero_page; | |||
282 | #define pmd_bad(x) (!(pmd_flag(x) & PxD_FLAG_VALID)) | 291 | #define pmd_bad(x) (!(pmd_flag(x) & PxD_FLAG_VALID)) |
283 | #define pmd_present(x) (pmd_flag(x) & PxD_FLAG_PRESENT) | 292 | #define pmd_present(x) (pmd_flag(x) & PxD_FLAG_PRESENT) |
284 | static inline void pmd_clear(pmd_t *pmd) { | 293 | static inline void pmd_clear(pmd_t *pmd) { |
285 | #ifdef CONFIG_64BIT | 294 | #if PT_NLEVELS == 3 |
286 | if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED) | 295 | if (pmd_flag(*pmd) & PxD_FLAG_ATTACHED) |
287 | /* This is the entry pointing to the permanent pmd | 296 | /* This is the entry pointing to the permanent pmd |
288 | * attached to the pgd; cannot clear it */ | 297 | * attached to the pgd; cannot clear it */ |
@@ -303,7 +312,7 @@ static inline void pmd_clear(pmd_t *pmd) { | |||
303 | #define pgd_bad(x) (!(pgd_flag(x) & PxD_FLAG_VALID)) | 312 | #define pgd_bad(x) (!(pgd_flag(x) & PxD_FLAG_VALID)) |
304 | #define pgd_present(x) (pgd_flag(x) & PxD_FLAG_PRESENT) | 313 | #define pgd_present(x) (pgd_flag(x) & PxD_FLAG_PRESENT) |
305 | static inline void pgd_clear(pgd_t *pgd) { | 314 | static inline void pgd_clear(pgd_t *pgd) { |
306 | #ifdef CONFIG_64BIT | 315 | #if PT_NLEVELS == 3 |
307 | if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED) | 316 | if(pgd_flag(*pgd) & PxD_FLAG_ATTACHED) |
308 | /* This is the permanent pmd attached to the pgd; cannot | 317 | /* This is the permanent pmd attached to the pgd; cannot |
309 | * free it */ | 318 | * free it */ |
@@ -351,7 +360,7 @@ extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return | |||
351 | ({ \ | 360 | ({ \ |
352 | pte_t __pte; \ | 361 | pte_t __pte; \ |
353 | \ | 362 | \ |
354 | pte_val(__pte) = ((addr)+pgprot_val(pgprot)); \ | 363 | pte_val(__pte) = ((((addr)>>PAGE_SHIFT)<<PFN_PTE_SHIFT) + pgprot_val(pgprot)); \ |
355 | \ | 364 | \ |
356 | __pte; \ | 365 | __pte; \ |
357 | }) | 366 | }) |
@@ -361,20 +370,16 @@ extern inline pte_t pte_mkwrite(pte_t pte) { pte_val(pte) |= _PAGE_WRITE; return | |||
361 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) | 370 | static inline pte_t pfn_pte(unsigned long pfn, pgprot_t pgprot) |
362 | { | 371 | { |
363 | pte_t pte; | 372 | pte_t pte; |
364 | pte_val(pte) = (pfn << PAGE_SHIFT) | pgprot_val(pgprot); | 373 | pte_val(pte) = (pfn << PFN_PTE_SHIFT) | pgprot_val(pgprot); |
365 | return pte; | 374 | return pte; |
366 | } | 375 | } |
367 | 376 | ||
368 | /* This takes a physical page address that is used by the remapping functions */ | ||
369 | #define mk_pte_phys(physpage, pgprot) \ | ||
370 | ({ pte_t __pte; pte_val(__pte) = physpage + pgprot_val(pgprot); __pte; }) | ||
371 | |||
372 | extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | 377 | extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) |
373 | { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } | 378 | { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } |
374 | 379 | ||
375 | /* Permanent address of a page. On parisc we don't have highmem. */ | 380 | /* Permanent address of a page. On parisc we don't have highmem. */ |
376 | 381 | ||
377 | #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) | 382 | #define pte_pfn(x) (pte_val(x) >> PFN_PTE_SHIFT) |
378 | 383 | ||
379 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) | 384 | #define pte_page(pte) (pfn_to_page(pte_pfn(pte))) |
380 | 385 | ||
@@ -499,6 +504,26 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, | |||
499 | 504 | ||
500 | #endif /* !__ASSEMBLY__ */ | 505 | #endif /* !__ASSEMBLY__ */ |
501 | 506 | ||
507 | |||
508 | /* TLB page size encoding - see table 3-1 in parisc20.pdf */ | ||
509 | #define _PAGE_SIZE_ENCODING_4K 0 | ||
510 | #define _PAGE_SIZE_ENCODING_16K 1 | ||
511 | #define _PAGE_SIZE_ENCODING_64K 2 | ||
512 | #define _PAGE_SIZE_ENCODING_256K 3 | ||
513 | #define _PAGE_SIZE_ENCODING_1M 4 | ||
514 | #define _PAGE_SIZE_ENCODING_4M 5 | ||
515 | #define _PAGE_SIZE_ENCODING_16M 6 | ||
516 | #define _PAGE_SIZE_ENCODING_64M 7 | ||
517 | |||
518 | #if defined(CONFIG_PARISC_PAGE_SIZE_4KB) | ||
519 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_4K | ||
520 | #elif defined(CONFIG_PARISC_PAGE_SIZE_16KB) | ||
521 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_16K | ||
522 | #elif defined(CONFIG_PARISC_PAGE_SIZE_64KB) | ||
523 | # define _PAGE_SIZE_ENCODING_DEFAULT _PAGE_SIZE_ENCODING_64K | ||
524 | #endif | ||
525 | |||
526 | |||
502 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ | 527 | #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ |
503 | remap_pfn_range(vma, vaddr, pfn, size, prot) | 528 | remap_pfn_range(vma, vaddr, pfn, size, prot) |
504 | 529 | ||
diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index c56fccbf34ad..0e1a30be2e30 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h | |||
@@ -780,8 +780,14 @@ | |||
780 | #define __NR_readlinkat (__NR_Linux + 285) | 780 | #define __NR_readlinkat (__NR_Linux + 285) |
781 | #define __NR_fchmodat (__NR_Linux + 286) | 781 | #define __NR_fchmodat (__NR_Linux + 286) |
782 | #define __NR_faccessat (__NR_Linux + 287) | 782 | #define __NR_faccessat (__NR_Linux + 287) |
783 | #define __NR_unshare (__NR_Linux + 288) | ||
784 | #define __NR_set_robust_list (__NR_Linux + 289) | ||
785 | #define __NR_get_robust_list (__NR_Linux + 290) | ||
786 | #define __NR_splice (__NR_Linux + 291) | ||
787 | #define __NR_sync_file_range (__NR_Linux + 292) | ||
788 | #define __NR_tee (__NR_Linux + 293) | ||
783 | 789 | ||
784 | #define __NR_Linux_syscalls 288 | 790 | #define __NR_Linux_syscalls 294 |
785 | 791 | ||
786 | #define HPUX_GATEWAY_ADDR 0xC0000004 | 792 | #define HPUX_GATEWAY_ADDR 0xC0000004 |
787 | #define LINUX_GATEWAY_ADDR 0x100 | 793 | #define LINUX_GATEWAY_ADDR 0x100 |
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h index d5677cbec200..18ca29e9105a 100644 --- a/include/asm-powerpc/iommu.h +++ b/include/asm-powerpc/iommu.h | |||
@@ -70,17 +70,18 @@ extern void iommu_free_table(struct device_node *dn); | |||
70 | extern struct iommu_table *iommu_init_table(struct iommu_table * tbl); | 70 | extern struct iommu_table *iommu_init_table(struct iommu_table * tbl); |
71 | 71 | ||
72 | extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, | 72 | extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, |
73 | struct scatterlist *sglist, int nelems, | 73 | struct scatterlist *sglist, int nelems, unsigned long mask, |
74 | enum dma_data_direction direction); | 74 | enum dma_data_direction direction); |
75 | extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, | 75 | extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, |
76 | int nelems, enum dma_data_direction direction); | 76 | int nelems, enum dma_data_direction direction); |
77 | 77 | ||
78 | extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, | 78 | extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, |
79 | dma_addr_t *dma_handle, gfp_t flag); | 79 | dma_addr_t *dma_handle, unsigned long mask, gfp_t flag); |
80 | extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, | 80 | extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, |
81 | void *vaddr, dma_addr_t dma_handle); | 81 | void *vaddr, dma_addr_t dma_handle); |
82 | extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, | 82 | extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, |
83 | size_t size, enum dma_data_direction direction); | 83 | size_t size, unsigned long mask, |
84 | enum dma_data_direction direction); | ||
84 | extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, | 85 | extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, |
85 | size_t size, enum dma_data_direction direction); | 86 | size_t size, enum dma_data_direction direction); |
86 | 87 | ||
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h index 51f87d9993b6..7bc6d73b2823 100644 --- a/include/asm-powerpc/irq.h +++ b/include/asm-powerpc/irq.h | |||
@@ -54,6 +54,13 @@ | |||
54 | */ | 54 | */ |
55 | extern unsigned int virt_irq_to_real_map[NR_IRQS]; | 55 | extern unsigned int virt_irq_to_real_map[NR_IRQS]; |
56 | 56 | ||
57 | /* The maximum virtual IRQ number that we support. This | ||
58 | * can be set by the platform and will be reduced by the | ||
59 | * value of __irq_offset_value. It defaults to and is | ||
60 | * capped by (NR_IRQS - 1). | ||
61 | */ | ||
62 | extern unsigned int virt_irq_max; | ||
63 | |||
57 | /* Create a mapping for a real_irq if it doesn't already exist. | 64 | /* Create a mapping for a real_irq if it doesn't already exist. |
58 | * Return the virtual irq as a convenience. | 65 | * Return the virtual irq as a convenience. |
59 | */ | 66 | */ |
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h index 5ed847680754..0f9254c18914 100644 --- a/include/asm-powerpc/machdep.h +++ b/include/asm-powerpc/machdep.h | |||
@@ -253,7 +253,11 @@ extern struct machdep_calls *machine_id; | |||
253 | 253 | ||
254 | #define __machine_desc __attribute__ ((__section__ (".machine.desc"))) | 254 | #define __machine_desc __attribute__ ((__section__ (".machine.desc"))) |
255 | 255 | ||
256 | #define define_machine(name) struct machdep_calls mach_##name __machine_desc = | 256 | #define define_machine(name) \ |
257 | extern struct machdep_calls mach_##name; \ | ||
258 | EXPORT_SYMBOL(mach_##name); \ | ||
259 | struct machdep_calls mach_##name __machine_desc = | ||
260 | |||
257 | #define machine_is(name) \ | 261 | #define machine_is(name) \ |
258 | ({ \ | 262 | ({ \ |
259 | extern struct machdep_calls mach_##name \ | 263 | extern struct machdep_calls mach_##name \ |
diff --git a/include/asm-powerpc/thread_info.h b/include/asm-powerpc/thread_info.h index ffc7462d77ba..88b553c6b26c 100644 --- a/include/asm-powerpc/thread_info.h +++ b/include/asm-powerpc/thread_info.h | |||
@@ -37,6 +37,8 @@ struct thread_info { | |||
37 | int preempt_count; /* 0 => preemptable, | 37 | int preempt_count; /* 0 => preemptable, |
38 | <0 => BUG */ | 38 | <0 => BUG */ |
39 | struct restart_block restart_block; | 39 | struct restart_block restart_block; |
40 | unsigned long local_flags; /* private flags for thread */ | ||
41 | |||
40 | /* low level flags - has atomic operations done on it */ | 42 | /* low level flags - has atomic operations done on it */ |
41 | unsigned long flags ____cacheline_aligned_in_smp; | 43 | unsigned long flags ____cacheline_aligned_in_smp; |
42 | }; | 44 | }; |
@@ -143,6 +145,12 @@ static inline struct thread_info *current_thread_info(void) | |||
143 | _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) | 145 | _TIF_NEED_RESCHED | _TIF_RESTORE_SIGMASK) |
144 | #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR) | 146 | #define _TIF_PERSYSCALL_MASK (_TIF_RESTOREALL|_TIF_NOERROR) |
145 | 147 | ||
148 | /* Bits in local_flags */ | ||
149 | /* Don't move TLF_NAPPING without adjusting the code in entry_32.S */ | ||
150 | #define TLF_NAPPING 0 /* idle thread enabled NAP mode */ | ||
151 | |||
152 | #define _TLF_NAPPING (1 << TLF_NAPPING) | ||
153 | |||
146 | #endif /* __KERNEL__ */ | 154 | #endif /* __KERNEL__ */ |
147 | 155 | ||
148 | #endif /* _ASM_POWERPC_THREAD_INFO_H */ | 156 | #endif /* _ASM_POWERPC_THREAD_INFO_H */ |
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h index c612f1a62772..34325e292596 100644 --- a/include/asm-powerpc/unistd.h +++ b/include/asm-powerpc/unistd.h | |||
@@ -303,8 +303,9 @@ | |||
303 | #define __NR_unshare 282 | 303 | #define __NR_unshare 282 |
304 | #define __NR_splice 283 | 304 | #define __NR_splice 283 |
305 | #define __NR_tee 284 | 305 | #define __NR_tee 284 |
306 | #define __NR_vmsplice 285 | ||
306 | 307 | ||
307 | #define __NR_syscalls 285 | 308 | #define __NR_syscalls 286 |
308 | 309 | ||
309 | #ifdef __KERNEL__ | 310 | #ifdef __KERNEL__ |
310 | #define __NR__exit __NR_exit | 311 | #define __NR__exit __NR_exit |
diff --git a/include/asm-sparc/unistd.h b/include/asm-sparc/unistd.h index 2a911aa4cae9..32a48f623e2b 100644 --- a/include/asm-sparc/unistd.h +++ b/include/asm-sparc/unistd.h | |||
@@ -248,7 +248,7 @@ | |||
248 | #define __NR_setfsgid 229 /* Linux Specific */ | 248 | #define __NR_setfsgid 229 /* Linux Specific */ |
249 | #define __NR__newselect 230 /* Linux Specific */ | 249 | #define __NR__newselect 230 /* Linux Specific */ |
250 | #define __NR_time 231 /* Linux Specific */ | 250 | #define __NR_time 231 /* Linux Specific */ |
251 | #define __NR_sys_splice 232 /* Linux Specific */ | 251 | #define __NR_splice 232 /* Linux Specific */ |
252 | #define __NR_stime 233 /* Linux Specific */ | 252 | #define __NR_stime 233 /* Linux Specific */ |
253 | #define __NR_statfs64 234 /* Linux Specific */ | 253 | #define __NR_statfs64 234 /* Linux Specific */ |
254 | #define __NR_fstatfs64 235 /* Linux Specific */ | 254 | #define __NR_fstatfs64 235 /* Linux Specific */ |
@@ -271,7 +271,7 @@ | |||
271 | #define __NR_getsid 252 | 271 | #define __NR_getsid 252 |
272 | #define __NR_fdatasync 253 | 272 | #define __NR_fdatasync 253 |
273 | #define __NR_nfsservctl 254 | 273 | #define __NR_nfsservctl 254 |
274 | #define __NR_sys_sync_file_range 255 | 274 | #define __NR_sync_file_range 255 |
275 | #define __NR_clock_settime 256 | 275 | #define __NR_clock_settime 256 |
276 | #define __NR_clock_gettime 257 | 276 | #define __NR_clock_gettime 257 |
277 | #define __NR_clock_getres 258 | 277 | #define __NR_clock_getres 258 |
diff --git a/include/asm-sparc64/unistd.h b/include/asm-sparc64/unistd.h index 6ada6a871cc8..ca80e8aca128 100644 --- a/include/asm-sparc64/unistd.h +++ b/include/asm-sparc64/unistd.h | |||
@@ -250,7 +250,7 @@ | |||
250 | #ifdef __KERNEL__ | 250 | #ifdef __KERNEL__ |
251 | #define __NR_time 231 /* Linux sparc32 */ | 251 | #define __NR_time 231 /* Linux sparc32 */ |
252 | #endif | 252 | #endif |
253 | #define __NR_sys_splice 232 /* Linux Specific */ | 253 | #define __NR_splice 232 /* Linux Specific */ |
254 | #define __NR_stime 233 /* Linux Specific */ | 254 | #define __NR_stime 233 /* Linux Specific */ |
255 | #define __NR_statfs64 234 /* Linux Specific */ | 255 | #define __NR_statfs64 234 /* Linux Specific */ |
256 | #define __NR_fstatfs64 235 /* Linux Specific */ | 256 | #define __NR_fstatfs64 235 /* Linux Specific */ |
@@ -273,7 +273,7 @@ | |||
273 | #define __NR_getsid 252 | 273 | #define __NR_getsid 252 |
274 | #define __NR_fdatasync 253 | 274 | #define __NR_fdatasync 253 |
275 | #define __NR_nfsservctl 254 | 275 | #define __NR_nfsservctl 254 |
276 | #define __NR_sys_sync_file_range 255 | 276 | #define __NR_sync_file_range 255 |
277 | #define __NR_clock_settime 256 | 277 | #define __NR_clock_settime 256 |
278 | #define __NR_clock_gettime 257 | 278 | #define __NR_clock_gettime 257 |
279 | #define __NR_clock_getres 258 | 279 | #define __NR_clock_getres 258 |
diff --git a/include/asm-x86_64/cache.h b/include/asm-x86_64/cache.h index c8043a16152e..f8dff1c67538 100644 --- a/include/asm-x86_64/cache.h +++ b/include/asm-x86_64/cache.h | |||
@@ -20,8 +20,8 @@ | |||
20 | __attribute__((__section__(".data.page_aligned"))) | 20 | __attribute__((__section__(".data.page_aligned"))) |
21 | #endif | 21 | #endif |
22 | 22 | ||
23 | #define __read_mostly __attribute__((__section__(".data.read_mostly"))) | ||
24 | |||
25 | #endif | 23 | #endif |
26 | 24 | ||
25 | #define __read_mostly __attribute__((__section__(".data.read_mostly"))) | ||
26 | |||
27 | #endif | 27 | #endif |
diff --git a/include/asm-x86_64/cpufeature.h b/include/asm-x86_64/cpufeature.h index 76bb6193ae91..662964b74e34 100644 --- a/include/asm-x86_64/cpufeature.h +++ b/include/asm-x86_64/cpufeature.h | |||
@@ -64,6 +64,7 @@ | |||
64 | #define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */ | 64 | #define X86_FEATURE_REP_GOOD (3*32+ 4) /* rep microcode works well on this CPU */ |
65 | #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */ | 65 | #define X86_FEATURE_CONSTANT_TSC (3*32+5) /* TSC runs at constant rate */ |
66 | #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */ | 66 | #define X86_FEATURE_SYNC_RDTSC (3*32+6) /* RDTSC syncs CPU core */ |
67 | #define X86_FEATURE_FXSAVE_LEAK (3*32+7) /* FIP/FOP/FDP leaks through FXSAVE */ | ||
67 | 68 | ||
68 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ | 69 | /* Intel-defined CPU features, CPUID level 0x00000001 (ecx), word 4 */ |
69 | #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ | 70 | #define X86_FEATURE_XMM3 (4*32+ 0) /* Streaming SIMD Extensions-3 */ |
diff --git a/include/asm-x86_64/i387.h b/include/asm-x86_64/i387.h index 876eb9a2fe78..cba8a3b0cded 100644 --- a/include/asm-x86_64/i387.h +++ b/include/asm-x86_64/i387.h | |||
@@ -72,6 +72,23 @@ extern int set_fpregs(struct task_struct *tsk, | |||
72 | #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val)) | 72 | #define set_fpu_swd(t,val) ((t)->thread.i387.fxsave.swd = (val)) |
73 | #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val)) | 73 | #define set_fpu_fxsr_twd(t,val) ((t)->thread.i387.fxsave.twd = (val)) |
74 | 74 | ||
75 | #define X87_FSW_ES (1 << 7) /* Exception Summary */ | ||
76 | |||
77 | /* AMD CPUs don't save/restore FDP/FIP/FOP unless an exception | ||
78 | is pending. Clear the x87 state here by setting it to fixed | ||
79 | values. The kernel data segment can be sometimes 0 and sometimes | ||
80 | new user value. Both should be ok. | ||
81 | Use the PDA as safe address because it should be already in L1. */ | ||
82 | static inline void clear_fpu_state(struct i387_fxsave_struct *fx) | ||
83 | { | ||
84 | if (unlikely(fx->swd & X87_FSW_ES)) | ||
85 | asm volatile("fnclex"); | ||
86 | alternative_input(ASM_NOP8 ASM_NOP2, | ||
87 | " emms\n" /* clear stack tags */ | ||
88 | " fildl %%gs:0", /* load to clear state */ | ||
89 | X86_FEATURE_FXSAVE_LEAK); | ||
90 | } | ||
91 | |||
75 | static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) | 92 | static inline int restore_fpu_checking(struct i387_fxsave_struct *fx) |
76 | { | 93 | { |
77 | int err; | 94 | int err; |
@@ -119,6 +136,7 @@ static inline int save_i387_checking(struct i387_fxsave_struct __user *fx) | |||
119 | #endif | 136 | #endif |
120 | if (unlikely(err)) | 137 | if (unlikely(err)) |
121 | __clear_user(fx, sizeof(struct i387_fxsave_struct)); | 138 | __clear_user(fx, sizeof(struct i387_fxsave_struct)); |
139 | /* No need to clear here because the caller clears USED_MATH */ | ||
122 | return err; | 140 | return err; |
123 | } | 141 | } |
124 | 142 | ||
@@ -149,7 +167,7 @@ static inline void __fxsave_clear(struct task_struct *tsk) | |||
149 | "i" (offsetof(__typeof__(*tsk), | 167 | "i" (offsetof(__typeof__(*tsk), |
150 | thread.i387.fxsave))); | 168 | thread.i387.fxsave))); |
151 | #endif | 169 | #endif |
152 | __asm__ __volatile__("fnclex"); | 170 | clear_fpu_state(&tsk->thread.i387.fxsave); |
153 | } | 171 | } |
154 | 172 | ||
155 | static inline void kernel_fpu_begin(void) | 173 | static inline void kernel_fpu_begin(void) |
diff --git a/include/asm-x86_64/mmzone.h b/include/asm-x86_64/mmzone.h index 6b18cd8f293d..6944e7122df5 100644 --- a/include/asm-x86_64/mmzone.h +++ b/include/asm-x86_64/mmzone.h | |||
@@ -12,7 +12,8 @@ | |||
12 | 12 | ||
13 | #include <asm/smp.h> | 13 | #include <asm/smp.h> |
14 | 14 | ||
15 | #define NODEMAPSIZE 0xfff | 15 | /* Should really switch to dynamic allocation at some point */ |
16 | #define NODEMAPSIZE 0x4fff | ||
16 | 17 | ||
17 | /* Simple perfect hash to map physical addresses to node numbers */ | 18 | /* Simple perfect hash to map physical addresses to node numbers */ |
18 | struct memnode { | 19 | struct memnode { |
diff --git a/include/asm-x86_64/percpu.h b/include/asm-x86_64/percpu.h index 4405b4adeaba..7f33aaf9f7b1 100644 --- a/include/asm-x86_64/percpu.h +++ b/include/asm-x86_64/percpu.h | |||
@@ -26,7 +26,7 @@ | |||
26 | #define percpu_modcopy(pcpudst, src, size) \ | 26 | #define percpu_modcopy(pcpudst, src, size) \ |
27 | do { \ | 27 | do { \ |
28 | unsigned int __i; \ | 28 | unsigned int __i; \ |
29 | for_each_cpu(__i) \ | 29 | for_each_possible_cpu(__i) \ |
30 | memcpy((pcpudst)+__per_cpu_offset(__i), \ | 30 | memcpy((pcpudst)+__per_cpu_offset(__i), \ |
31 | (src), (size)); \ | 31 | (src), (size)); \ |
32 | } while (0) | 32 | } while (0) |
diff --git a/include/asm-x86_64/unistd.h b/include/asm-x86_64/unistd.h index d86494e23b63..feb77cb8c044 100644 --- a/include/asm-x86_64/unistd.h +++ b/include/asm-x86_64/unistd.h | |||
@@ -613,8 +613,12 @@ __SYSCALL(__NR_get_robust_list, sys_get_robust_list) | |||
613 | __SYSCALL(__NR_splice, sys_splice) | 613 | __SYSCALL(__NR_splice, sys_splice) |
614 | #define __NR_tee 276 | 614 | #define __NR_tee 276 |
615 | __SYSCALL(__NR_tee, sys_tee) | 615 | __SYSCALL(__NR_tee, sys_tee) |
616 | #define __NR_sync_file_range 277 | ||
617 | __SYSCALL(__NR_sync_file_range, sys_sync_file_range) | ||
618 | #define __NR_vmsplice 278 | ||
619 | __SYSCALL(__NR_vmsplice, sys_vmsplice) | ||
616 | 620 | ||
617 | #define __NR_syscall_max __NR_tee | 621 | #define __NR_syscall_max __NR_vmsplice |
618 | 622 | ||
619 | #ifndef __NO_STUBS | 623 | #ifndef __NO_STUBS |
620 | 624 | ||
diff --git a/include/asm-xtensa/ioctls.h b/include/asm-xtensa/ioctls.h index 10c443435c11..3b89a772d0a0 100644 --- a/include/asm-xtensa/ioctls.h +++ b/include/asm-xtensa/ioctls.h | |||
@@ -107,6 +107,6 @@ | |||
107 | #define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */ | 107 | #define TIOCSERSETMULTI _IOW('T', 91, struct serial_multiport_struct) /* Set multiport config */ |
108 | 108 | ||
109 | #define TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */ | 109 | #define TIOCMIWAIT _IO('T', 92) /* wait for a change on serial input line(s) */ |
110 | #define TIOCGICOUNT _IOR('T', 93, struct async_icount) /* read serial port inline interrupt counts */ | 110 | #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ |
111 | 111 | ||
112 | #endif /* _XTENSA_IOCTLS_H */ | 112 | #endif /* _XTENSA_IOCTLS_H */ |
diff --git a/include/linux/ide.h b/include/linux/ide.h index 8d2db412ba9c..a8bef1d1371c 100644 --- a/include/linux/ide.h +++ b/include/linux/ide.h | |||
@@ -1220,7 +1220,6 @@ typedef struct ide_pci_enablebit_s { | |||
1220 | enum { | 1220 | enum { |
1221 | /* Uses ISA control ports not PCI ones. */ | 1221 | /* Uses ISA control ports not PCI ones. */ |
1222 | IDEPCI_FLAG_ISA_PORTS = (1 << 0), | 1222 | IDEPCI_FLAG_ISA_PORTS = (1 << 0), |
1223 | IDEPCI_FLAG_FORCE_PDC = (1 << 1), | ||
1224 | }; | 1223 | }; |
1225 | 1224 | ||
1226 | typedef struct ide_pci_device_s { | 1225 | typedef struct ide_pci_device_s { |
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 4ca3e6ad03ec..911206386171 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h | |||
@@ -99,10 +99,7 @@ static inline int __remove_pages(struct zone *zone, unsigned long start_pfn, | |||
99 | return -ENOSYS; | 99 | return -ENOSYS; |
100 | } | 100 | } |
101 | 101 | ||
102 | #if defined(CONFIG_MEMORY_HOTPLUG) || defined(CONFIG_ACPI_HOTPLUG_MEMORY) \ | ||
103 | || defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE) | ||
104 | extern int add_memory(u64 start, u64 size); | 102 | extern int add_memory(u64 start, u64 size); |
105 | extern int remove_memory(u64 start, u64 size); | 103 | extern int remove_memory(u64 start, u64 size); |
106 | #endif | ||
107 | 104 | ||
108 | #endif /* __LINUX_MEMORY_HOTPLUG_H */ | 105 | #endif /* __LINUX_MEMORY_HOTPLUG_H */ |
diff --git a/include/linux/mv643xx.h b/include/linux/mv643xx.h index 955d3069d727..edfa012fad3a 100644 --- a/include/linux/mv643xx.h +++ b/include/linux/mv643xx.h | |||
@@ -13,7 +13,7 @@ | |||
13 | #ifndef __ASM_MV643XX_H | 13 | #ifndef __ASM_MV643XX_H |
14 | #define __ASM_MV643XX_H | 14 | #define __ASM_MV643XX_H |
15 | 15 | ||
16 | #ifdef __MIPS__ | 16 | #ifdef __mips__ |
17 | #include <asm/addrspace.h> | 17 | #include <asm/addrspace.h> |
18 | #include <asm/marvell.h> | 18 | #include <asm/marvell.h> |
19 | #endif | 19 | #endif |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 40ccf8cc4239..01db7b88a2b1 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -829,19 +829,21 @@ static inline void netif_rx_schedule(struct net_device *dev) | |||
829 | __netif_rx_schedule(dev); | 829 | __netif_rx_schedule(dev); |
830 | } | 830 | } |
831 | 831 | ||
832 | /* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). | 832 | |
833 | * Do not inline this? | 833 | static inline void __netif_rx_reschedule(struct net_device *dev, int undo) |
834 | */ | 834 | { |
835 | dev->quota += undo; | ||
836 | list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); | ||
837 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); | ||
838 | } | ||
839 | |||
840 | /* Try to reschedule poll. Called by dev->poll() after netif_rx_complete(). */ | ||
835 | static inline int netif_rx_reschedule(struct net_device *dev, int undo) | 841 | static inline int netif_rx_reschedule(struct net_device *dev, int undo) |
836 | { | 842 | { |
837 | if (netif_rx_schedule_prep(dev)) { | 843 | if (netif_rx_schedule_prep(dev)) { |
838 | unsigned long flags; | 844 | unsigned long flags; |
839 | |||
840 | dev->quota += undo; | ||
841 | |||
842 | local_irq_save(flags); | 845 | local_irq_save(flags); |
843 | list_add_tail(&dev->poll_list, &__get_cpu_var(softnet_data).poll_list); | 846 | __netif_rx_reschedule(dev, undo); |
844 | __raise_softirq_irqoff(NET_RX_SOFTIRQ); | ||
845 | local_irq_restore(flags); | 847 | local_irq_restore(flags); |
846 | return 1; | 848 | return 1; |
847 | } | 849 | } |
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h index f6bdef82a322..38701454e197 100644 --- a/include/linux/netfilter/x_tables.h +++ b/include/linux/netfilter/x_tables.h | |||
@@ -361,7 +361,11 @@ struct compat_xt_entry_target | |||
361 | 361 | ||
362 | struct compat_xt_counters | 362 | struct compat_xt_counters |
363 | { | 363 | { |
364 | #if defined(CONFIG_X86_64) || defined(CONFIG_IA64) | ||
364 | u_int32_t cnt[4]; | 365 | u_int32_t cnt[4]; |
366 | #else | ||
367 | u_int64_t cnt[2]; | ||
368 | #endif | ||
365 | }; | 369 | }; |
366 | 370 | ||
367 | struct compat_xt_counters_info | 371 | struct compat_xt_counters_info |
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index 8d03e10212f5..d6fe048376ab 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -356,6 +356,10 @@ | |||
356 | #define PCI_DEVICE_ID_ATI_IXP300_SATA 0x436e | 356 | #define PCI_DEVICE_ID_ATI_IXP300_SATA 0x436e |
357 | #define PCI_DEVICE_ID_ATI_IXP400_IDE 0x4376 | 357 | #define PCI_DEVICE_ID_ATI_IXP400_IDE 0x4376 |
358 | #define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 | 358 | #define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 |
359 | #define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a | ||
360 | #define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380 | ||
361 | #define PCI_DEVICE_ID_ATI_IXP600_SRAID 0x4381 | ||
362 | #define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c | ||
359 | 363 | ||
360 | #define PCI_VENDOR_ID_VLSI 0x1004 | 364 | #define PCI_VENDOR_ID_VLSI 0x1004 |
361 | #define PCI_DEVICE_ID_VLSI_82C592 0x0005 | 365 | #define PCI_DEVICE_ID_VLSI_82C592 0x0005 |
diff --git a/include/linux/pipe_fs_i.h b/include/linux/pipe_fs_i.h index ef7f33c0be19..0008d4bd4059 100644 --- a/include/linux/pipe_fs_i.h +++ b/include/linux/pipe_fs_i.h | |||
@@ -61,4 +61,21 @@ void __free_pipe_info(struct pipe_inode_info *); | |||
61 | /* from/to, of course */ | 61 | /* from/to, of course */ |
62 | #define SPLICE_F_MORE (0x04) /* expect more data */ | 62 | #define SPLICE_F_MORE (0x04) /* expect more data */ |
63 | 63 | ||
64 | /* | ||
65 | * Passed to the actors | ||
66 | */ | ||
67 | struct splice_desc { | ||
68 | unsigned int len, total_len; /* current and remaining length */ | ||
69 | unsigned int flags; /* splice flags */ | ||
70 | struct file *file; /* file to read/write */ | ||
71 | loff_t pos; /* file position */ | ||
72 | }; | ||
73 | |||
74 | typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *, | ||
75 | struct splice_desc *); | ||
76 | |||
77 | extern ssize_t splice_from_pipe(struct pipe_inode_info *, struct file *, | ||
78 | loff_t *, size_t, unsigned int, | ||
79 | splice_actor *); | ||
80 | |||
64 | #endif | 81 | #endif |
diff --git a/include/linux/sched.h b/include/linux/sched.h index b7d31e2e1729..29b7d4f87d20 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1192,8 +1192,7 @@ extern void wait_task_inactive(task_t * p); | |||
1192 | #define remove_parent(p) list_del_init(&(p)->sibling) | 1192 | #define remove_parent(p) list_del_init(&(p)->sibling) |
1193 | #define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children) | 1193 | #define add_parent(p) list_add_tail(&(p)->sibling,&(p)->parent->children) |
1194 | 1194 | ||
1195 | #define next_task(p) list_entry((p)->tasks.next, struct task_struct, tasks) | 1195 | #define next_task(p) list_entry(rcu_dereference((p)->tasks.next), struct task_struct, tasks) |
1196 | #define prev_task(p) list_entry((p)->tasks.prev, struct task_struct, tasks) | ||
1197 | 1196 | ||
1198 | #define for_each_process(p) \ | 1197 | #define for_each_process(p) \ |
1199 | for (p = &init_task ; (p = next_task(p)) != &init_task ; ) | 1198 | for (p = &init_task ; (p = next_task(p)) != &init_task ; ) |
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index c4619a428d9b..f8f234708b98 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h | |||
@@ -344,6 +344,13 @@ extern void skb_over_panic(struct sk_buff *skb, int len, | |||
344 | void *here); | 344 | void *here); |
345 | extern void skb_under_panic(struct sk_buff *skb, int len, | 345 | extern void skb_under_panic(struct sk_buff *skb, int len, |
346 | void *here); | 346 | void *here); |
347 | extern void skb_truesize_bug(struct sk_buff *skb); | ||
348 | |||
349 | static inline void skb_truesize_check(struct sk_buff *skb) | ||
350 | { | ||
351 | if (unlikely((int)skb->truesize < sizeof(struct sk_buff) + skb->len)) | ||
352 | skb_truesize_bug(skb); | ||
353 | } | ||
347 | 354 | ||
348 | extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, | 355 | extern int skb_append_datato_frags(struct sock *sk, struct sk_buff *skb, |
349 | int getfrag(void *from, char *to, int offset, | 356 | int getfrag(void *from, char *to, int offset, |
diff --git a/include/linux/sunrpc/metrics.h b/include/linux/sunrpc/metrics.h index 8f96e9dc369a..77f78e56c481 100644 --- a/include/linux/sunrpc/metrics.h +++ b/include/linux/sunrpc/metrics.h | |||
@@ -69,9 +69,21 @@ struct rpc_clnt; | |||
69 | /* | 69 | /* |
70 | * EXPORTed functions for managing rpc_iostats structures | 70 | * EXPORTed functions for managing rpc_iostats structures |
71 | */ | 71 | */ |
72 | |||
73 | #ifdef CONFIG_PROC_FS | ||
74 | |||
72 | struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *); | 75 | struct rpc_iostats * rpc_alloc_iostats(struct rpc_clnt *); |
73 | void rpc_count_iostats(struct rpc_task *); | 76 | void rpc_count_iostats(struct rpc_task *); |
74 | void rpc_print_iostats(struct seq_file *, struct rpc_clnt *); | 77 | void rpc_print_iostats(struct seq_file *, struct rpc_clnt *); |
75 | void rpc_free_iostats(struct rpc_iostats *); | 78 | void rpc_free_iostats(struct rpc_iostats *); |
76 | 79 | ||
80 | #else /* CONFIG_PROC_FS */ | ||
81 | |||
82 | static inline struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) { return NULL; } | ||
83 | static inline void rpc_count_iostats(struct rpc_task *task) {} | ||
84 | static inline void rpc_print_iostats(struct seq_file *seq, struct rpc_clnt *clnt) {} | ||
85 | static inline void rpc_free_iostats(struct rpc_iostats *stats) {} | ||
86 | |||
87 | #endif /* CONFIG_PROC_FS */ | ||
88 | |||
77 | #endif /* _LINUX_SUNRPC_METRICS_H */ | 89 | #endif /* _LINUX_SUNRPC_METRICS_H */ |
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 7eebbab7160b..e8bbe8118de8 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
@@ -53,6 +53,7 @@ struct rpc_timeout { | |||
53 | 53 | ||
54 | struct rpc_task; | 54 | struct rpc_task; |
55 | struct rpc_xprt; | 55 | struct rpc_xprt; |
56 | struct seq_file; | ||
56 | 57 | ||
57 | /* | 58 | /* |
58 | * This describes a complete RPC request | 59 | * This describes a complete RPC request |
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h index d3ebc0e68b2b..3996960fc565 100644 --- a/include/linux/syscalls.h +++ b/include/linux/syscalls.h | |||
@@ -574,6 +574,9 @@ asmlinkage long sys_splice(int fd_in, loff_t __user *off_in, | |||
574 | int fd_out, loff_t __user *off_out, | 574 | int fd_out, loff_t __user *off_out, |
575 | size_t len, unsigned int flags); | 575 | size_t len, unsigned int flags); |
576 | 576 | ||
577 | asmlinkage long sys_vmsplice(int fd, const struct iovec __user *iov, | ||
578 | unsigned long nr_segs, unsigned int flags); | ||
579 | |||
577 | asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); | 580 | asmlinkage long sys_tee(int fdin, int fdout, size_t len, unsigned int flags); |
578 | 581 | ||
579 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, | 582 | asmlinkage long sys_sync_file_range(int fd, loff_t offset, loff_t nbytes, |
diff --git a/include/net/ieee80211softmac.h b/include/net/ieee80211softmac.h index b971d8c82bdd..b1ebfbae397f 100644 --- a/include/net/ieee80211softmac.h +++ b/include/net/ieee80211softmac.h | |||
@@ -96,10 +96,13 @@ struct ieee80211softmac_assoc_info { | |||
96 | * | 96 | * |
97 | * bssvalid is true if we found a matching network | 97 | * bssvalid is true if we found a matching network |
98 | * and saved it's BSSID into the bssid above. | 98 | * and saved it's BSSID into the bssid above. |
99 | * | ||
100 | * bssfixed is used for SIOCSIWAP. | ||
99 | */ | 101 | */ |
100 | u8 static_essid:1, | 102 | u8 static_essid:1, |
101 | associating:1, | 103 | associating:1, |
102 | bssvalid:1; | 104 | bssvalid:1, |
105 | bssfixed:1; | ||
103 | 106 | ||
104 | /* Scan retries remaining */ | 107 | /* Scan retries remaining */ |
105 | int scan_retry; | 108 | int scan_retry; |
@@ -267,8 +270,9 @@ extern void ieee80211softmac_stop(struct net_device *dev); | |||
267 | #define IEEE80211SOFTMAC_EVENT_AUTH_FAILED 5 | 270 | #define IEEE80211SOFTMAC_EVENT_AUTH_FAILED 5 |
268 | #define IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT 6 | 271 | #define IEEE80211SOFTMAC_EVENT_AUTH_TIMEOUT 6 |
269 | #define IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND 7 | 272 | #define IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND 7 |
273 | #define IEEE80211SOFTMAC_EVENT_DISASSOCIATED 8 | ||
270 | /* keep this updated! */ | 274 | /* keep this updated! */ |
271 | #define IEEE80211SOFTMAC_EVENT_LAST 7 | 275 | #define IEEE80211SOFTMAC_EVENT_LAST 8 |
272 | /* | 276 | /* |
273 | * If you want to be notified of certain events, you can call | 277 | * If you want to be notified of certain events, you can call |
274 | * ieee80211softmac_notify[_atomic] with | 278 | * ieee80211softmac_notify[_atomic] with |
diff --git a/include/net/ipv6.h b/include/net/ipv6.h index 6d6f0634ae41..4abedb8eaece 100644 --- a/include/net/ipv6.h +++ b/include/net/ipv6.h | |||
@@ -230,7 +230,7 @@ extern int ip6_ra_control(struct sock *sk, int sel, | |||
230 | void (*destructor)(struct sock *)); | 230 | void (*destructor)(struct sock *)); |
231 | 231 | ||
232 | 232 | ||
233 | extern int ipv6_parse_hopopts(struct sk_buff *skb, int); | 233 | extern int ipv6_parse_hopopts(struct sk_buff *skb); |
234 | 234 | ||
235 | extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); | 235 | extern struct ipv6_txoptions * ipv6_dup_options(struct sock *sk, struct ipv6_txoptions *opt); |
236 | extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, | 236 | extern struct ipv6_txoptions * ipv6_renew_options(struct sock *sk, struct ipv6_txoptions *opt, |
diff --git a/include/net/sock.h b/include/net/sock.h index af2b0544586e..ff8b0dad7b0f 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -454,6 +454,7 @@ static inline void sk_stream_set_owner_r(struct sk_buff *skb, struct sock *sk) | |||
454 | 454 | ||
455 | static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb) | 455 | static inline void sk_stream_free_skb(struct sock *sk, struct sk_buff *skb) |
456 | { | 456 | { |
457 | skb_truesize_check(skb); | ||
457 | sock_set_flag(sk, SOCK_QUEUE_SHRUNK); | 458 | sock_set_flag(sk, SOCK_QUEUE_SHRUNK); |
458 | sk->sk_wmem_queued -= skb->truesize; | 459 | sk->sk_wmem_queued -= skb->truesize; |
459 | sk->sk_forward_alloc += skb->truesize; | 460 | sk->sk_forward_alloc += skb->truesize; |
diff --git a/init/Kconfig b/init/Kconfig index f1bc2f0e94e5..3b36a1d53656 100644 --- a/init/Kconfig +++ b/init/Kconfig | |||
@@ -374,15 +374,6 @@ config SLAB | |||
374 | SLOB is more space efficient but does not scale well and is | 374 | SLOB is more space efficient but does not scale well and is |
375 | more susceptible to fragmentation. | 375 | more susceptible to fragmentation. |
376 | 376 | ||
377 | config DOUBLEFAULT | ||
378 | default y | ||
379 | bool "Enable doublefault exception handler" if EMBEDDED && X86_32 | ||
380 | help | ||
381 | This option allows trapping of rare doublefault exceptions that | ||
382 | would otherwise cause a system to silently reboot. Disabling this | ||
383 | option saves about 4k and might cause you much additional grey | ||
384 | hair. | ||
385 | |||
386 | endmenu # General setup | 377 | endmenu # General setup |
387 | 378 | ||
388 | config TINY_SHMEM | 379 | config TINY_SHMEM |
diff --git a/kernel/exit.c b/kernel/exit.c index 1a9787ac6173..f86434d7b3d1 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
@@ -56,7 +56,7 @@ static void __unhash_process(struct task_struct *p) | |||
56 | detach_pid(p, PIDTYPE_PGID); | 56 | detach_pid(p, PIDTYPE_PGID); |
57 | detach_pid(p, PIDTYPE_SID); | 57 | detach_pid(p, PIDTYPE_SID); |
58 | 58 | ||
59 | list_del_init(&p->tasks); | 59 | list_del_rcu(&p->tasks); |
60 | __get_cpu_var(process_counts)--; | 60 | __get_cpu_var(process_counts)--; |
61 | } | 61 | } |
62 | list_del_rcu(&p->thread_group); | 62 | list_del_rcu(&p->thread_group); |
diff --git a/kernel/fork.c b/kernel/fork.c index 54b15f8cda53..d2fa57d480d4 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -180,6 +180,7 @@ static struct task_struct *dup_task_struct(struct task_struct *orig) | |||
180 | atomic_set(&tsk->usage,2); | 180 | atomic_set(&tsk->usage,2); |
181 | atomic_set(&tsk->fs_excl, 0); | 181 | atomic_set(&tsk->fs_excl, 0); |
182 | tsk->btrace_seq = 0; | 182 | tsk->btrace_seq = 0; |
183 | tsk->splice_pipe = NULL; | ||
183 | return tsk; | 184 | return tsk; |
184 | } | 185 | } |
185 | 186 | ||
@@ -1204,7 +1205,7 @@ static task_t *copy_process(unsigned long clone_flags, | |||
1204 | attach_pid(p, PIDTYPE_PGID, process_group(p)); | 1205 | attach_pid(p, PIDTYPE_PGID, process_group(p)); |
1205 | attach_pid(p, PIDTYPE_SID, p->signal->session); | 1206 | attach_pid(p, PIDTYPE_SID, p->signal->session); |
1206 | 1207 | ||
1207 | list_add_tail(&p->tasks, &init_task.tasks); | 1208 | list_add_tail_rcu(&p->tasks, &init_task.tasks); |
1208 | __get_cpu_var(process_counts)++; | 1209 | __get_cpu_var(process_counts)++; |
1209 | } | 1210 | } |
1210 | attach_pid(p, PIDTYPE_PID, p->pid); | 1211 | attach_pid(p, PIDTYPE_PID, p->pid); |
diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index d2a7296c8251..b7f0388bd71c 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c | |||
@@ -836,7 +836,7 @@ static void migrate_hrtimers(int cpu) | |||
836 | } | 836 | } |
837 | #endif /* CONFIG_HOTPLUG_CPU */ | 837 | #endif /* CONFIG_HOTPLUG_CPU */ |
838 | 838 | ||
839 | static int __devinit hrtimer_cpu_notify(struct notifier_block *self, | 839 | static int hrtimer_cpu_notify(struct notifier_block *self, |
840 | unsigned long action, void *hcpu) | 840 | unsigned long action, void *hcpu) |
841 | { | 841 | { |
842 | long cpu = (long)hcpu; | 842 | long cpu = (long)hcpu; |
@@ -860,7 +860,7 @@ static int __devinit hrtimer_cpu_notify(struct notifier_block *self, | |||
860 | return NOTIFY_OK; | 860 | return NOTIFY_OK; |
861 | } | 861 | } |
862 | 862 | ||
863 | static struct notifier_block __devinitdata hrtimers_nb = { | 863 | static struct notifier_block hrtimers_nb = { |
864 | .notifier_call = hrtimer_cpu_notify, | 864 | .notifier_call = hrtimer_cpu_notify, |
865 | }; | 865 | }; |
866 | 866 | ||
diff --git a/kernel/kprobes.c b/kernel/kprobes.c index 1156eb0977d0..1fbf466a29aa 100644 --- a/kernel/kprobes.c +++ b/kernel/kprobes.c | |||
@@ -585,6 +585,9 @@ int __kprobes register_kretprobe(struct kretprobe *rp) | |||
585 | int i; | 585 | int i; |
586 | 586 | ||
587 | rp->kp.pre_handler = pre_handler_kretprobe; | 587 | rp->kp.pre_handler = pre_handler_kretprobe; |
588 | rp->kp.post_handler = NULL; | ||
589 | rp->kp.fault_handler = NULL; | ||
590 | rp->kp.break_handler = NULL; | ||
588 | 591 | ||
589 | /* Pre-allocate memory for max kretprobe instances */ | 592 | /* Pre-allocate memory for max kretprobe instances */ |
590 | if (rp->maxactive <= 0) { | 593 | if (rp->maxactive <= 0) { |
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index c5863d02c89e..3eeedbb13b78 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -240,14 +240,15 @@ static void copy_data_pages(struct pbe *pblist) | |||
240 | * free_pagedir - free pages allocated with alloc_pagedir() | 240 | * free_pagedir - free pages allocated with alloc_pagedir() |
241 | */ | 241 | */ |
242 | 242 | ||
243 | static void free_pagedir(struct pbe *pblist) | 243 | static void free_pagedir(struct pbe *pblist, int clear_nosave_free) |
244 | { | 244 | { |
245 | struct pbe *pbe; | 245 | struct pbe *pbe; |
246 | 246 | ||
247 | while (pblist) { | 247 | while (pblist) { |
248 | pbe = (pblist + PB_PAGE_SKIP)->next; | 248 | pbe = (pblist + PB_PAGE_SKIP)->next; |
249 | ClearPageNosave(virt_to_page(pblist)); | 249 | ClearPageNosave(virt_to_page(pblist)); |
250 | ClearPageNosaveFree(virt_to_page(pblist)); | 250 | if (clear_nosave_free) |
251 | ClearPageNosaveFree(virt_to_page(pblist)); | ||
251 | free_page((unsigned long)pblist); | 252 | free_page((unsigned long)pblist); |
252 | pblist = pbe; | 253 | pblist = pbe; |
253 | } | 254 | } |
@@ -389,7 +390,7 @@ struct pbe *alloc_pagedir(unsigned int nr_pages, gfp_t gfp_mask, int safe_needed | |||
389 | pbe->next = alloc_image_page(gfp_mask, safe_needed); | 390 | pbe->next = alloc_image_page(gfp_mask, safe_needed); |
390 | } | 391 | } |
391 | if (!pbe) { /* get_zeroed_page() failed */ | 392 | if (!pbe) { /* get_zeroed_page() failed */ |
392 | free_pagedir(pblist); | 393 | free_pagedir(pblist, 1); |
393 | pblist = NULL; | 394 | pblist = NULL; |
394 | } else | 395 | } else |
395 | create_pbe_list(pblist, nr_pages); | 396 | create_pbe_list(pblist, nr_pages); |
@@ -736,7 +737,7 @@ static int create_image(struct snapshot_handle *handle) | |||
736 | pblist = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 1); | 737 | pblist = alloc_pagedir(nr_copy_pages, GFP_ATOMIC, 1); |
737 | if (pblist) | 738 | if (pblist) |
738 | copy_page_backup_list(pblist, p); | 739 | copy_page_backup_list(pblist, p); |
739 | free_pagedir(p); | 740 | free_pagedir(p, 0); |
740 | if (!pblist) | 741 | if (!pblist) |
741 | error = -ENOMEM; | 742 | error = -ENOMEM; |
742 | } | 743 | } |
diff --git a/kernel/profile.c b/kernel/profile.c index 5a730fdb1a2c..68afe121e507 100644 --- a/kernel/profile.c +++ b/kernel/profile.c | |||
@@ -299,7 +299,7 @@ out: | |||
299 | } | 299 | } |
300 | 300 | ||
301 | #ifdef CONFIG_HOTPLUG_CPU | 301 | #ifdef CONFIG_HOTPLUG_CPU |
302 | static int __devinit profile_cpu_callback(struct notifier_block *info, | 302 | static int profile_cpu_callback(struct notifier_block *info, |
303 | unsigned long action, void *__cpu) | 303 | unsigned long action, void *__cpu) |
304 | { | 304 | { |
305 | int node, cpu = (unsigned long)__cpu; | 305 | int node, cpu = (unsigned long)__cpu; |
diff --git a/kernel/rcupdate.c b/kernel/rcupdate.c index 13458bbaa1be..6d32ff26f948 100644 --- a/kernel/rcupdate.c +++ b/kernel/rcupdate.c | |||
@@ -520,7 +520,7 @@ static void __devinit rcu_online_cpu(int cpu) | |||
520 | tasklet_init(&per_cpu(rcu_tasklet, cpu), rcu_process_callbacks, 0UL); | 520 | tasklet_init(&per_cpu(rcu_tasklet, cpu), rcu_process_callbacks, 0UL); |
521 | } | 521 | } |
522 | 522 | ||
523 | static int __devinit rcu_cpu_notify(struct notifier_block *self, | 523 | static int rcu_cpu_notify(struct notifier_block *self, |
524 | unsigned long action, void *hcpu) | 524 | unsigned long action, void *hcpu) |
525 | { | 525 | { |
526 | long cpu = (long)hcpu; | 526 | long cpu = (long)hcpu; |
@@ -537,7 +537,7 @@ static int __devinit rcu_cpu_notify(struct notifier_block *self, | |||
537 | return NOTIFY_OK; | 537 | return NOTIFY_OK; |
538 | } | 538 | } |
539 | 539 | ||
540 | static struct notifier_block __devinitdata rcu_nb = { | 540 | static struct notifier_block rcu_nb = { |
541 | .notifier_call = rcu_cpu_notify, | 541 | .notifier_call = rcu_cpu_notify, |
542 | }; | 542 | }; |
543 | 543 | ||
diff --git a/kernel/sched.c b/kernel/sched.c index 365f0b90b4de..4c64f85698ae 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4814,7 +4814,7 @@ static int migration_call(struct notifier_block *nfb, unsigned long action, | |||
4814 | /* Register at highest priority so that task migration (migrate_all_tasks) | 4814 | /* Register at highest priority so that task migration (migrate_all_tasks) |
4815 | * happens before everything else. | 4815 | * happens before everything else. |
4816 | */ | 4816 | */ |
4817 | static struct notifier_block __devinitdata migration_notifier = { | 4817 | static struct notifier_block migration_notifier = { |
4818 | .notifier_call = migration_call, | 4818 | .notifier_call = migration_call, |
4819 | .priority = 10 | 4819 | .priority = 10 |
4820 | }; | 4820 | }; |
diff --git a/kernel/softirq.c b/kernel/softirq.c index ec8fed42a86f..336f92d64e2e 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -446,7 +446,7 @@ static void takeover_tasklets(unsigned int cpu) | |||
446 | } | 446 | } |
447 | #endif /* CONFIG_HOTPLUG_CPU */ | 447 | #endif /* CONFIG_HOTPLUG_CPU */ |
448 | 448 | ||
449 | static int __devinit cpu_callback(struct notifier_block *nfb, | 449 | static int cpu_callback(struct notifier_block *nfb, |
450 | unsigned long action, | 450 | unsigned long action, |
451 | void *hcpu) | 451 | void *hcpu) |
452 | { | 452 | { |
@@ -484,7 +484,7 @@ static int __devinit cpu_callback(struct notifier_block *nfb, | |||
484 | return NOTIFY_OK; | 484 | return NOTIFY_OK; |
485 | } | 485 | } |
486 | 486 | ||
487 | static struct notifier_block __devinitdata cpu_nfb = { | 487 | static struct notifier_block cpu_nfb = { |
488 | .notifier_call = cpu_callback | 488 | .notifier_call = cpu_callback |
489 | }; | 489 | }; |
490 | 490 | ||
diff --git a/kernel/softlockup.c b/kernel/softlockup.c index ced91e1ff564..14c7faf02909 100644 --- a/kernel/softlockup.c +++ b/kernel/softlockup.c | |||
@@ -104,7 +104,7 @@ static int watchdog(void * __bind_cpu) | |||
104 | /* | 104 | /* |
105 | * Create/destroy watchdog threads as CPUs come and go: | 105 | * Create/destroy watchdog threads as CPUs come and go: |
106 | */ | 106 | */ |
107 | static int __devinit | 107 | static int |
108 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 108 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
109 | { | 109 | { |
110 | int hotcpu = (unsigned long)hcpu; | 110 | int hotcpu = (unsigned long)hcpu; |
@@ -140,7 +140,7 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
140 | return NOTIFY_OK; | 140 | return NOTIFY_OK; |
141 | } | 141 | } |
142 | 142 | ||
143 | static struct notifier_block __devinitdata cpu_nfb = { | 143 | static struct notifier_block cpu_nfb = { |
144 | .notifier_call = cpu_callback | 144 | .notifier_call = cpu_callback |
145 | }; | 145 | }; |
146 | 146 | ||
diff --git a/kernel/timer.c b/kernel/timer.c index 883773788836..67eaf0f54096 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1314,7 +1314,7 @@ static void __devinit migrate_timers(int cpu) | |||
1314 | } | 1314 | } |
1315 | #endif /* CONFIG_HOTPLUG_CPU */ | 1315 | #endif /* CONFIG_HOTPLUG_CPU */ |
1316 | 1316 | ||
1317 | static int __devinit timer_cpu_notify(struct notifier_block *self, | 1317 | static int timer_cpu_notify(struct notifier_block *self, |
1318 | unsigned long action, void *hcpu) | 1318 | unsigned long action, void *hcpu) |
1319 | { | 1319 | { |
1320 | long cpu = (long)hcpu; | 1320 | long cpu = (long)hcpu; |
@@ -1334,7 +1334,7 @@ static int __devinit timer_cpu_notify(struct notifier_block *self, | |||
1334 | return NOTIFY_OK; | 1334 | return NOTIFY_OK; |
1335 | } | 1335 | } |
1336 | 1336 | ||
1337 | static struct notifier_block __devinitdata timers_nb = { | 1337 | static struct notifier_block timers_nb = { |
1338 | .notifier_call = timer_cpu_notify, | 1338 | .notifier_call = timer_cpu_notify, |
1339 | }; | 1339 | }; |
1340 | 1340 | ||
diff --git a/kernel/uid16.c b/kernel/uid16.c index aa25605027c8..187e2a423878 100644 --- a/kernel/uid16.c +++ b/kernel/uid16.c | |||
@@ -20,43 +20,67 @@ | |||
20 | 20 | ||
21 | asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group) | 21 | asmlinkage long sys_chown16(const char __user * filename, old_uid_t user, old_gid_t group) |
22 | { | 22 | { |
23 | return sys_chown(filename, low2highuid(user), low2highgid(group)); | 23 | long ret = sys_chown(filename, low2highuid(user), low2highgid(group)); |
24 | /* avoid REGPARM breakage on x86: */ | ||
25 | prevent_tail_call(ret); | ||
26 | return ret; | ||
24 | } | 27 | } |
25 | 28 | ||
26 | asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group) | 29 | asmlinkage long sys_lchown16(const char __user * filename, old_uid_t user, old_gid_t group) |
27 | { | 30 | { |
28 | return sys_lchown(filename, low2highuid(user), low2highgid(group)); | 31 | long ret = sys_lchown(filename, low2highuid(user), low2highgid(group)); |
32 | /* avoid REGPARM breakage on x86: */ | ||
33 | prevent_tail_call(ret); | ||
34 | return ret; | ||
29 | } | 35 | } |
30 | 36 | ||
31 | asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) | 37 | asmlinkage long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group) |
32 | { | 38 | { |
33 | return sys_fchown(fd, low2highuid(user), low2highgid(group)); | 39 | long ret = sys_fchown(fd, low2highuid(user), low2highgid(group)); |
40 | /* avoid REGPARM breakage on x86: */ | ||
41 | prevent_tail_call(ret); | ||
42 | return ret; | ||
34 | } | 43 | } |
35 | 44 | ||
36 | asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) | 45 | asmlinkage long sys_setregid16(old_gid_t rgid, old_gid_t egid) |
37 | { | 46 | { |
38 | return sys_setregid(low2highgid(rgid), low2highgid(egid)); | 47 | long ret = sys_setregid(low2highgid(rgid), low2highgid(egid)); |
48 | /* avoid REGPARM breakage on x86: */ | ||
49 | prevent_tail_call(ret); | ||
50 | return ret; | ||
39 | } | 51 | } |
40 | 52 | ||
41 | asmlinkage long sys_setgid16(old_gid_t gid) | 53 | asmlinkage long sys_setgid16(old_gid_t gid) |
42 | { | 54 | { |
43 | return sys_setgid(low2highgid(gid)); | 55 | long ret = sys_setgid(low2highgid(gid)); |
56 | /* avoid REGPARM breakage on x86: */ | ||
57 | prevent_tail_call(ret); | ||
58 | return ret; | ||
44 | } | 59 | } |
45 | 60 | ||
46 | asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) | 61 | asmlinkage long sys_setreuid16(old_uid_t ruid, old_uid_t euid) |
47 | { | 62 | { |
48 | return sys_setreuid(low2highuid(ruid), low2highuid(euid)); | 63 | long ret = sys_setreuid(low2highuid(ruid), low2highuid(euid)); |
64 | /* avoid REGPARM breakage on x86: */ | ||
65 | prevent_tail_call(ret); | ||
66 | return ret; | ||
49 | } | 67 | } |
50 | 68 | ||
51 | asmlinkage long sys_setuid16(old_uid_t uid) | 69 | asmlinkage long sys_setuid16(old_uid_t uid) |
52 | { | 70 | { |
53 | return sys_setuid(low2highuid(uid)); | 71 | long ret = sys_setuid(low2highuid(uid)); |
72 | /* avoid REGPARM breakage on x86: */ | ||
73 | prevent_tail_call(ret); | ||
74 | return ret; | ||
54 | } | 75 | } |
55 | 76 | ||
56 | asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) | 77 | asmlinkage long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid) |
57 | { | 78 | { |
58 | return sys_setresuid(low2highuid(ruid), low2highuid(euid), | 79 | long ret = sys_setresuid(low2highuid(ruid), low2highuid(euid), |
59 | low2highuid(suid)); | 80 | low2highuid(suid)); |
81 | /* avoid REGPARM breakage on x86: */ | ||
82 | prevent_tail_call(ret); | ||
83 | return ret; | ||
60 | } | 84 | } |
61 | 85 | ||
62 | asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid) | 86 | asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, old_uid_t __user *suid) |
@@ -72,8 +96,11 @@ asmlinkage long sys_getresuid16(old_uid_t __user *ruid, old_uid_t __user *euid, | |||
72 | 96 | ||
73 | asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) | 97 | asmlinkage long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid) |
74 | { | 98 | { |
75 | return sys_setresgid(low2highgid(rgid), low2highgid(egid), | 99 | long ret = sys_setresgid(low2highgid(rgid), low2highgid(egid), |
76 | low2highgid(sgid)); | 100 | low2highgid(sgid)); |
101 | /* avoid REGPARM breakage on x86: */ | ||
102 | prevent_tail_call(ret); | ||
103 | return ret; | ||
77 | } | 104 | } |
78 | 105 | ||
79 | asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid) | 106 | asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, old_gid_t __user *sgid) |
@@ -89,12 +116,18 @@ asmlinkage long sys_getresgid16(old_gid_t __user *rgid, old_gid_t __user *egid, | |||
89 | 116 | ||
90 | asmlinkage long sys_setfsuid16(old_uid_t uid) | 117 | asmlinkage long sys_setfsuid16(old_uid_t uid) |
91 | { | 118 | { |
92 | return sys_setfsuid(low2highuid(uid)); | 119 | long ret = sys_setfsuid(low2highuid(uid)); |
120 | /* avoid REGPARM breakage on x86: */ | ||
121 | prevent_tail_call(ret); | ||
122 | return ret; | ||
93 | } | 123 | } |
94 | 124 | ||
95 | asmlinkage long sys_setfsgid16(old_gid_t gid) | 125 | asmlinkage long sys_setfsgid16(old_gid_t gid) |
96 | { | 126 | { |
97 | return sys_setfsgid(low2highgid(gid)); | 127 | long ret = sys_setfsgid(low2highgid(gid)); |
128 | /* avoid REGPARM breakage on x86: */ | ||
129 | prevent_tail_call(ret); | ||
130 | return ret; | ||
98 | } | 131 | } |
99 | 132 | ||
100 | static int groups16_to_user(old_gid_t __user *grouplist, | 133 | static int groups16_to_user(old_gid_t __user *grouplist, |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index e9e464a90376..880fb415a8f6 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -547,7 +547,7 @@ static void take_over_work(struct workqueue_struct *wq, unsigned int cpu) | |||
547 | } | 547 | } |
548 | 548 | ||
549 | /* We're holding the cpucontrol mutex here */ | 549 | /* We're holding the cpucontrol mutex here */ |
550 | static int __devinit workqueue_cpu_callback(struct notifier_block *nfb, | 550 | static int workqueue_cpu_callback(struct notifier_block *nfb, |
551 | unsigned long action, | 551 | unsigned long action, |
552 | void *hcpu) | 552 | void *hcpu) |
553 | { | 553 | { |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index d57fd9181b18..6ecc180beb71 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -101,7 +101,7 @@ config DEBUG_PREEMPT | |||
101 | 101 | ||
102 | config DEBUG_MUTEXES | 102 | config DEBUG_MUTEXES |
103 | bool "Mutex debugging, deadlock detection" | 103 | bool "Mutex debugging, deadlock detection" |
104 | default y | 104 | default n |
105 | depends on DEBUG_KERNEL | 105 | depends on DEBUG_KERNEL |
106 | help | 106 | help |
107 | This allows mutex semantics violations and mutex related deadlocks | 107 | This allows mutex semantics violations and mutex related deadlocks |
diff --git a/mm/mempolicy.c b/mm/mempolicy.c index dec8249e972d..8778f58880c4 100644 --- a/mm/mempolicy.c +++ b/mm/mempolicy.c | |||
@@ -1761,7 +1761,6 @@ static void gather_stats(struct page *page, void *private, int pte_dirty) | |||
1761 | md->mapcount_max = count; | 1761 | md->mapcount_max = count; |
1762 | 1762 | ||
1763 | md->node[page_to_nid(page)]++; | 1763 | md->node[page_to_nid(page)]++; |
1764 | cond_resched(); | ||
1765 | } | 1764 | } |
1766 | 1765 | ||
1767 | #ifdef CONFIG_HUGETLB_PAGE | 1766 | #ifdef CONFIG_HUGETLB_PAGE |
diff --git a/mm/oom_kill.c b/mm/oom_kill.c index 78747afad6b0..042e6436c3ee 100644 --- a/mm/oom_kill.c +++ b/mm/oom_kill.c | |||
@@ -46,15 +46,25 @@ | |||
46 | unsigned long badness(struct task_struct *p, unsigned long uptime) | 46 | unsigned long badness(struct task_struct *p, unsigned long uptime) |
47 | { | 47 | { |
48 | unsigned long points, cpu_time, run_time, s; | 48 | unsigned long points, cpu_time, run_time, s; |
49 | struct list_head *tsk; | 49 | struct mm_struct *mm; |
50 | struct task_struct *child; | ||
50 | 51 | ||
51 | if (!p->mm) | 52 | task_lock(p); |
53 | mm = p->mm; | ||
54 | if (!mm) { | ||
55 | task_unlock(p); | ||
52 | return 0; | 56 | return 0; |
57 | } | ||
53 | 58 | ||
54 | /* | 59 | /* |
55 | * The memory size of the process is the basis for the badness. | 60 | * The memory size of the process is the basis for the badness. |
56 | */ | 61 | */ |
57 | points = p->mm->total_vm; | 62 | points = mm->total_vm; |
63 | |||
64 | /* | ||
65 | * After this unlock we can no longer dereference local variable `mm' | ||
66 | */ | ||
67 | task_unlock(p); | ||
58 | 68 | ||
59 | /* | 69 | /* |
60 | * Processes which fork a lot of child processes are likely | 70 | * Processes which fork a lot of child processes are likely |
@@ -64,11 +74,11 @@ unsigned long badness(struct task_struct *p, unsigned long uptime) | |||
64 | * child is eating the vast majority of memory, adding only half | 74 | * child is eating the vast majority of memory, adding only half |
65 | * to the parents will make the child our kill candidate of choice. | 75 | * to the parents will make the child our kill candidate of choice. |
66 | */ | 76 | */ |
67 | list_for_each(tsk, &p->children) { | 77 | list_for_each_entry(child, &p->children, sibling) { |
68 | struct task_struct *chld; | 78 | task_lock(child); |
69 | chld = list_entry(tsk, struct task_struct, sibling); | 79 | if (child->mm != mm && child->mm) |
70 | if (chld->mm != p->mm && chld->mm) | 80 | points += child->mm->total_vm/2 + 1; |
71 | points += chld->mm->total_vm/2 + 1; | 81 | task_unlock(child); |
72 | } | 82 | } |
73 | 83 | ||
74 | /* | 84 | /* |
@@ -244,17 +254,24 @@ static void __oom_kill_task(task_t *p, const char *message) | |||
244 | force_sig(SIGKILL, p); | 254 | force_sig(SIGKILL, p); |
245 | } | 255 | } |
246 | 256 | ||
247 | static struct mm_struct *oom_kill_task(task_t *p, const char *message) | 257 | static int oom_kill_task(task_t *p, const char *message) |
248 | { | 258 | { |
249 | struct mm_struct *mm = get_task_mm(p); | 259 | struct mm_struct *mm; |
250 | task_t * g, * q; | 260 | task_t * g, * q; |
251 | 261 | ||
252 | if (!mm) | 262 | mm = p->mm; |
253 | return NULL; | 263 | |
254 | if (mm == &init_mm) { | 264 | /* WARNING: mm may not be dereferenced since we did not obtain its |
255 | mmput(mm); | 265 | * value from get_task_mm(p). This is OK since all we need to do is |
256 | return NULL; | 266 | * compare mm to q->mm below. |
257 | } | 267 | * |
268 | * Furthermore, even if mm contains a non-NULL value, p->mm may | ||
269 | * change to NULL at any time since we do not hold task_lock(p). | ||
270 | * However, this is of no concern to us. | ||
271 | */ | ||
272 | |||
273 | if (mm == NULL || mm == &init_mm) | ||
274 | return 1; | ||
258 | 275 | ||
259 | __oom_kill_task(p, message); | 276 | __oom_kill_task(p, message); |
260 | /* | 277 | /* |
@@ -266,13 +283,12 @@ static struct mm_struct *oom_kill_task(task_t *p, const char *message) | |||
266 | __oom_kill_task(q, message); | 283 | __oom_kill_task(q, message); |
267 | while_each_thread(g, q); | 284 | while_each_thread(g, q); |
268 | 285 | ||
269 | return mm; | 286 | return 0; |
270 | } | 287 | } |
271 | 288 | ||
272 | static struct mm_struct *oom_kill_process(struct task_struct *p, | 289 | static int oom_kill_process(struct task_struct *p, unsigned long points, |
273 | unsigned long points, const char *message) | 290 | const char *message) |
274 | { | 291 | { |
275 | struct mm_struct *mm; | ||
276 | struct task_struct *c; | 292 | struct task_struct *c; |
277 | struct list_head *tsk; | 293 | struct list_head *tsk; |
278 | 294 | ||
@@ -283,9 +299,8 @@ static struct mm_struct *oom_kill_process(struct task_struct *p, | |||
283 | c = list_entry(tsk, struct task_struct, sibling); | 299 | c = list_entry(tsk, struct task_struct, sibling); |
284 | if (c->mm == p->mm) | 300 | if (c->mm == p->mm) |
285 | continue; | 301 | continue; |
286 | mm = oom_kill_task(c, message); | 302 | if (!oom_kill_task(c, message)) |
287 | if (mm) | 303 | return 0; |
288 | return mm; | ||
289 | } | 304 | } |
290 | return oom_kill_task(p, message); | 305 | return oom_kill_task(p, message); |
291 | } | 306 | } |
@@ -300,7 +315,6 @@ static struct mm_struct *oom_kill_process(struct task_struct *p, | |||
300 | */ | 315 | */ |
301 | void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) | 316 | void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) |
302 | { | 317 | { |
303 | struct mm_struct *mm = NULL; | ||
304 | task_t *p; | 318 | task_t *p; |
305 | unsigned long points = 0; | 319 | unsigned long points = 0; |
306 | 320 | ||
@@ -320,12 +334,12 @@ void out_of_memory(struct zonelist *zonelist, gfp_t gfp_mask, int order) | |||
320 | */ | 334 | */ |
321 | switch (constrained_alloc(zonelist, gfp_mask)) { | 335 | switch (constrained_alloc(zonelist, gfp_mask)) { |
322 | case CONSTRAINT_MEMORY_POLICY: | 336 | case CONSTRAINT_MEMORY_POLICY: |
323 | mm = oom_kill_process(current, points, | 337 | oom_kill_process(current, points, |
324 | "No available memory (MPOL_BIND)"); | 338 | "No available memory (MPOL_BIND)"); |
325 | break; | 339 | break; |
326 | 340 | ||
327 | case CONSTRAINT_CPUSET: | 341 | case CONSTRAINT_CPUSET: |
328 | mm = oom_kill_process(current, points, | 342 | oom_kill_process(current, points, |
329 | "No available memory in cpuset"); | 343 | "No available memory in cpuset"); |
330 | break; | 344 | break; |
331 | 345 | ||
@@ -347,8 +361,7 @@ retry: | |||
347 | panic("Out of memory and no killable processes...\n"); | 361 | panic("Out of memory and no killable processes...\n"); |
348 | } | 362 | } |
349 | 363 | ||
350 | mm = oom_kill_process(p, points, "Out of memory"); | 364 | if (oom_kill_process(p, points, "Out of memory")) |
351 | if (!mm) | ||
352 | goto retry; | 365 | goto retry; |
353 | 366 | ||
354 | break; | 367 | break; |
@@ -357,8 +370,6 @@ retry: | |||
357 | out: | 370 | out: |
358 | read_unlock(&tasklist_lock); | 371 | read_unlock(&tasklist_lock); |
359 | cpuset_unlock(); | 372 | cpuset_unlock(); |
360 | if (mm) | ||
361 | mmput(mm); | ||
362 | 373 | ||
363 | /* | 374 | /* |
364 | * Give "p" a good chance of killing itself before we | 375 | * Give "p" a good chance of killing itself before we |
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 97d6827c7d66..ea77c999047e 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -232,11 +232,13 @@ static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags) | |||
232 | * zone->lock is already acquired when we use these. | 232 | * zone->lock is already acquired when we use these. |
233 | * So, we don't need atomic page->flags operations here. | 233 | * So, we don't need atomic page->flags operations here. |
234 | */ | 234 | */ |
235 | static inline unsigned long page_order(struct page *page) { | 235 | static inline unsigned long page_order(struct page *page) |
236 | { | ||
236 | return page_private(page); | 237 | return page_private(page); |
237 | } | 238 | } |
238 | 239 | ||
239 | static inline void set_page_order(struct page *page, int order) { | 240 | static inline void set_page_order(struct page *page, int order) |
241 | { | ||
240 | set_page_private(page, order); | 242 | set_page_private(page, order); |
241 | __SetPageBuddy(page); | 243 | __SetPageBuddy(page); |
242 | } | 244 | } |
@@ -299,9 +301,9 @@ static inline int page_is_buddy(struct page *page, int order) | |||
299 | 301 | ||
300 | if (PageBuddy(page) && page_order(page) == order) { | 302 | if (PageBuddy(page) && page_order(page) == order) { |
301 | BUG_ON(page_count(page) != 0); | 303 | BUG_ON(page_count(page) != 0); |
302 | return 1; | 304 | return 1; |
303 | } | 305 | } |
304 | return 0; | 306 | return 0; |
305 | } | 307 | } |
306 | 308 | ||
307 | /* | 309 | /* |
@@ -1960,7 +1962,7 @@ static inline void free_zone_pagesets(int cpu) | |||
1960 | } | 1962 | } |
1961 | } | 1963 | } |
1962 | 1964 | ||
1963 | static int __cpuinit pageset_cpuup_callback(struct notifier_block *nfb, | 1965 | static int pageset_cpuup_callback(struct notifier_block *nfb, |
1964 | unsigned long action, | 1966 | unsigned long action, |
1965 | void *hcpu) | 1967 | void *hcpu) |
1966 | { | 1968 | { |
diff --git a/mm/shmem.c b/mm/shmem.c index 37eaf42ed2c6..4c5e68e4e9ae 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -46,6 +46,8 @@ | |||
46 | #include <linux/mempolicy.h> | 46 | #include <linux/mempolicy.h> |
47 | #include <linux/namei.h> | 47 | #include <linux/namei.h> |
48 | #include <linux/ctype.h> | 48 | #include <linux/ctype.h> |
49 | #include <linux/migrate.h> | ||
50 | |||
49 | #include <asm/uaccess.h> | 51 | #include <asm/uaccess.h> |
50 | #include <asm/div64.h> | 52 | #include <asm/div64.h> |
51 | #include <asm/pgtable.h> | 53 | #include <asm/pgtable.h> |
@@ -2173,6 +2175,7 @@ static struct address_space_operations shmem_aops = { | |||
2173 | .prepare_write = shmem_prepare_write, | 2175 | .prepare_write = shmem_prepare_write, |
2174 | .commit_write = simple_commit_write, | 2176 | .commit_write = simple_commit_write, |
2175 | #endif | 2177 | #endif |
2178 | .migratepage = migrate_page, | ||
2176 | }; | 2179 | }; |
2177 | 2180 | ||
2178 | static struct file_operations shmem_file_operations = { | 2181 | static struct file_operations shmem_file_operations = { |
@@ -1036,7 +1036,7 @@ static inline void free_alien_cache(struct array_cache **ac_ptr) | |||
1036 | 1036 | ||
1037 | #endif | 1037 | #endif |
1038 | 1038 | ||
1039 | static int __devinit cpuup_callback(struct notifier_block *nfb, | 1039 | static int cpuup_callback(struct notifier_block *nfb, |
1040 | unsigned long action, void *hcpu) | 1040 | unsigned long action, void *hcpu) |
1041 | { | 1041 | { |
1042 | long cpu = (long)hcpu; | 1042 | long cpu = (long)hcpu; |
@@ -354,9 +354,7 @@ void *__alloc_percpu(size_t size) | |||
354 | if (!pdata) | 354 | if (!pdata) |
355 | return NULL; | 355 | return NULL; |
356 | 356 | ||
357 | for (i = 0; i < NR_CPUS; i++) { | 357 | for_each_possible_cpu(i) { |
358 | if (!cpu_possible(i)) | ||
359 | continue; | ||
360 | pdata->ptrs[i] = kmalloc(size, GFP_KERNEL); | 358 | pdata->ptrs[i] = kmalloc(size, GFP_KERNEL); |
361 | if (!pdata->ptrs[i]) | 359 | if (!pdata->ptrs[i]) |
362 | goto unwind_oom; | 360 | goto unwind_oom; |
@@ -383,11 +381,9 @@ free_percpu(const void *objp) | |||
383 | int i; | 381 | int i; |
384 | struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp); | 382 | struct percpu_data *p = (struct percpu_data *) (~(unsigned long) objp); |
385 | 383 | ||
386 | for (i = 0; i < NR_CPUS; i++) { | 384 | for_each_possible_cpu(i) |
387 | if (!cpu_possible(i)) | ||
388 | continue; | ||
389 | kfree(p->ptrs[i]); | 385 | kfree(p->ptrs[i]); |
390 | } | 386 | |
391 | kfree(p); | 387 | kfree(p); |
392 | } | 388 | } |
393 | EXPORT_SYMBOL(free_percpu); | 389 | EXPORT_SYMBOL(free_percpu); |
diff --git a/mm/vmscan.c b/mm/vmscan.c index acdf001d6941..4649a63a8cb6 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1328,7 +1328,7 @@ repeat: | |||
1328 | not required for correctness. So if the last cpu in a node goes | 1328 | not required for correctness. So if the last cpu in a node goes |
1329 | away, we get changed to run anywhere: as the first one comes back, | 1329 | away, we get changed to run anywhere: as the first one comes back, |
1330 | restore their cpu bindings. */ | 1330 | restore their cpu bindings. */ |
1331 | static int __devinit cpu_callback(struct notifier_block *nfb, | 1331 | static int cpu_callback(struct notifier_block *nfb, |
1332 | unsigned long action, void *hcpu) | 1332 | unsigned long action, void *hcpu) |
1333 | { | 1333 | { |
1334 | pg_data_t *pgdat; | 1334 | pg_data_t *pgdat; |
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index 2d24fb400e0c..56f3aa47e758 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/netdevice.h> | 17 | #include <linux/netdevice.h> |
18 | #include <linux/skbuff.h> | 18 | #include <linux/skbuff.h> |
19 | #include <linux/if_vlan.h> | ||
19 | #include <linux/netfilter_bridge.h> | 20 | #include <linux/netfilter_bridge.h> |
20 | #include "br_private.h" | 21 | #include "br_private.h" |
21 | 22 | ||
@@ -29,10 +30,15 @@ static inline int should_deliver(const struct net_bridge_port *p, | |||
29 | return 1; | 30 | return 1; |
30 | } | 31 | } |
31 | 32 | ||
33 | static inline unsigned packet_length(const struct sk_buff *skb) | ||
34 | { | ||
35 | return skb->len - (skb->protocol == htons(ETH_P_8021Q) ? VLAN_HLEN : 0); | ||
36 | } | ||
37 | |||
32 | int br_dev_queue_push_xmit(struct sk_buff *skb) | 38 | int br_dev_queue_push_xmit(struct sk_buff *skb) |
33 | { | 39 | { |
34 | /* drop mtu oversized packets except tso */ | 40 | /* drop mtu oversized packets except tso */ |
35 | if (skb->len > skb->dev->mtu && !skb_shinfo(skb)->tso_size) | 41 | if (packet_length(skb) > skb->dev->mtu && !skb_shinfo(skb)->tso_size) |
36 | kfree_skb(skb); | 42 | kfree_skb(skb); |
37 | else { | 43 | else { |
38 | #ifdef CONFIG_BRIDGE_NETFILTER | 44 | #ifdef CONFIG_BRIDGE_NETFILTER |
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 84b9af76f0a2..3a13ed643459 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -831,7 +831,7 @@ static int translate_table(struct ebt_replace *repl, | |||
831 | return -ENOMEM; | 831 | return -ENOMEM; |
832 | for_each_possible_cpu(i) { | 832 | for_each_possible_cpu(i) { |
833 | newinfo->chainstack[i] = | 833 | newinfo->chainstack[i] = |
834 | vmalloc(udc_cnt * sizeof(struct ebt_chainstack)); | 834 | vmalloc(udc_cnt * sizeof(*(newinfo->chainstack[0]))); |
835 | if (!newinfo->chainstack[i]) { | 835 | if (!newinfo->chainstack[i]) { |
836 | while (i) | 836 | while (i) |
837 | vfree(newinfo->chainstack[--i]); | 837 | vfree(newinfo->chainstack[--i]); |
@@ -841,8 +841,7 @@ static int translate_table(struct ebt_replace *repl, | |||
841 | } | 841 | } |
842 | } | 842 | } |
843 | 843 | ||
844 | cl_s = (struct ebt_cl_stack *) | 844 | cl_s = vmalloc(udc_cnt * sizeof(*cl_s)); |
845 | vmalloc(udc_cnt * sizeof(struct ebt_cl_stack)); | ||
846 | if (!cl_s) | 845 | if (!cl_s) |
847 | return -ENOMEM; | 846 | return -ENOMEM; |
848 | i = 0; /* the i'th udc */ | 847 | i = 0; /* the i'th udc */ |
@@ -944,8 +943,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
944 | 943 | ||
945 | countersize = COUNTER_OFFSET(tmp.nentries) * | 944 | countersize = COUNTER_OFFSET(tmp.nentries) * |
946 | (highest_possible_processor_id()+1); | 945 | (highest_possible_processor_id()+1); |
947 | newinfo = (struct ebt_table_info *) | 946 | newinfo = vmalloc(sizeof(*newinfo) + countersize); |
948 | vmalloc(sizeof(struct ebt_table_info) + countersize); | ||
949 | if (!newinfo) | 947 | if (!newinfo) |
950 | return -ENOMEM; | 948 | return -ENOMEM; |
951 | 949 | ||
@@ -967,8 +965,7 @@ static int do_replace(void __user *user, unsigned int len) | |||
967 | /* the user wants counters back | 965 | /* the user wants counters back |
968 | the check on the size is done later, when we have the lock */ | 966 | the check on the size is done later, when we have the lock */ |
969 | if (tmp.num_counters) { | 967 | if (tmp.num_counters) { |
970 | counterstmp = (struct ebt_counter *) | 968 | counterstmp = vmalloc(tmp.num_counters * sizeof(*counterstmp)); |
971 | vmalloc(tmp.num_counters * sizeof(struct ebt_counter)); | ||
972 | if (!counterstmp) { | 969 | if (!counterstmp) { |
973 | ret = -ENOMEM; | 970 | ret = -ENOMEM; |
974 | goto free_entries; | 971 | goto free_entries; |
@@ -1148,8 +1145,7 @@ int ebt_register_table(struct ebt_table *table) | |||
1148 | 1145 | ||
1149 | countersize = COUNTER_OFFSET(table->table->nentries) * | 1146 | countersize = COUNTER_OFFSET(table->table->nentries) * |
1150 | (highest_possible_processor_id()+1); | 1147 | (highest_possible_processor_id()+1); |
1151 | newinfo = (struct ebt_table_info *) | 1148 | newinfo = vmalloc(sizeof(*newinfo) + countersize); |
1152 | vmalloc(sizeof(struct ebt_table_info) + countersize); | ||
1153 | ret = -ENOMEM; | 1149 | ret = -ENOMEM; |
1154 | if (!newinfo) | 1150 | if (!newinfo) |
1155 | return -ENOMEM; | 1151 | return -ENOMEM; |
@@ -1247,8 +1243,7 @@ static int update_counters(void __user *user, unsigned int len) | |||
1247 | if (hlp.num_counters == 0) | 1243 | if (hlp.num_counters == 0) |
1248 | return -EINVAL; | 1244 | return -EINVAL; |
1249 | 1245 | ||
1250 | if ( !(tmp = (struct ebt_counter *) | 1246 | if (!(tmp = vmalloc(hlp.num_counters * sizeof(*tmp)))) { |
1251 | vmalloc(hlp.num_counters * sizeof(struct ebt_counter))) ){ | ||
1252 | MEMPRINT("Update_counters && nomemory\n"); | 1247 | MEMPRINT("Update_counters && nomemory\n"); |
1253 | return -ENOMEM; | 1248 | return -ENOMEM; |
1254 | } | 1249 | } |
@@ -1377,8 +1372,7 @@ static int copy_everything_to_user(struct ebt_table *t, void __user *user, | |||
1377 | BUGPRINT("Num_counters wrong\n"); | 1372 | BUGPRINT("Num_counters wrong\n"); |
1378 | return -EINVAL; | 1373 | return -EINVAL; |
1379 | } | 1374 | } |
1380 | counterstmp = (struct ebt_counter *) | 1375 | counterstmp = vmalloc(nentries * sizeof(*counterstmp)); |
1381 | vmalloc(nentries * sizeof(struct ebt_counter)); | ||
1382 | if (!counterstmp) { | 1376 | if (!counterstmp) { |
1383 | MEMPRINT("Couldn't copy counters, out of memory\n"); | 1377 | MEMPRINT("Couldn't copy counters, out of memory\n"); |
1384 | return -ENOMEM; | 1378 | return -ENOMEM; |
diff --git a/net/core/dev.c b/net/core/dev.c index 83231a27ae02..3bad1afc89fa 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -2698,7 +2698,8 @@ int dev_ioctl(unsigned int cmd, void __user *arg) | |||
2698 | /* If command is `set a parameter', or | 2698 | /* If command is `set a parameter', or |
2699 | * `get the encoding parameters', check if | 2699 | * `get the encoding parameters', check if |
2700 | * the user has the right to do it */ | 2700 | * the user has the right to do it */ |
2701 | if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE) { | 2701 | if (IW_IS_SET(cmd) || cmd == SIOCGIWENCODE |
2702 | || cmd == SIOCGIWENCODEEXT) { | ||
2702 | if (!capable(CAP_NET_ADMIN)) | 2703 | if (!capable(CAP_NET_ADMIN)) |
2703 | return -EPERM; | 2704 | return -EPERM; |
2704 | } | 2705 | } |
diff --git a/net/core/filter.c b/net/core/filter.c index 93fbd01d2259..5b4486a60cf6 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/timer.h> | 34 | #include <linux/timer.h> |
35 | #include <asm/system.h> | 35 | #include <asm/system.h> |
36 | #include <asm/uaccess.h> | 36 | #include <asm/uaccess.h> |
37 | #include <asm/unaligned.h> | ||
37 | #include <linux/filter.h> | 38 | #include <linux/filter.h> |
38 | 39 | ||
39 | /* No hurry in this branch */ | 40 | /* No hurry in this branch */ |
@@ -177,7 +178,7 @@ unsigned int sk_run_filter(struct sk_buff *skb, struct sock_filter *filter, int | |||
177 | load_w: | 178 | load_w: |
178 | ptr = load_pointer(skb, k, 4, &tmp); | 179 | ptr = load_pointer(skb, k, 4, &tmp); |
179 | if (ptr != NULL) { | 180 | if (ptr != NULL) { |
180 | A = ntohl(*(u32 *)ptr); | 181 | A = ntohl(get_unaligned((u32 *)ptr)); |
181 | continue; | 182 | continue; |
182 | } | 183 | } |
183 | break; | 184 | break; |
@@ -186,7 +187,7 @@ load_w: | |||
186 | load_h: | 187 | load_h: |
187 | ptr = load_pointer(skb, k, 2, &tmp); | 188 | ptr = load_pointer(skb, k, 2, &tmp); |
188 | if (ptr != NULL) { | 189 | if (ptr != NULL) { |
189 | A = ntohs(*(u16 *)ptr); | 190 | A = ntohs(get_unaligned((u16 *)ptr)); |
190 | continue; | 191 | continue; |
191 | } | 192 | } |
192 | break; | 193 | break; |
diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 09464fa8d72f..fb3770f9c094 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c | |||
@@ -112,6 +112,14 @@ void skb_under_panic(struct sk_buff *skb, int sz, void *here) | |||
112 | BUG(); | 112 | BUG(); |
113 | } | 113 | } |
114 | 114 | ||
115 | void skb_truesize_bug(struct sk_buff *skb) | ||
116 | { | ||
117 | printk(KERN_ERR "SKB BUG: Invalid truesize (%u) " | ||
118 | "len=%u, sizeof(sk_buff)=%Zd\n", | ||
119 | skb->truesize, skb->len, sizeof(struct sk_buff)); | ||
120 | } | ||
121 | EXPORT_SYMBOL(skb_truesize_bug); | ||
122 | |||
115 | /* Allocate a new skbuff. We do this ourselves so we can fill in a few | 123 | /* Allocate a new skbuff. We do this ourselves so we can fill in a few |
116 | * 'private' fields and also do memory statistics to find all the | 124 | * 'private' fields and also do memory statistics to find all the |
117 | * [BEEP] leaks. | 125 | * [BEEP] leaks. |
diff --git a/net/core/stream.c b/net/core/stream.c index 35e25259fd95..e9489696f694 100644 --- a/net/core/stream.c +++ b/net/core/stream.c | |||
@@ -176,6 +176,7 @@ void sk_stream_rfree(struct sk_buff *skb) | |||
176 | { | 176 | { |
177 | struct sock *sk = skb->sk; | 177 | struct sock *sk = skb->sk; |
178 | 178 | ||
179 | skb_truesize_check(skb); | ||
179 | atomic_sub(skb->truesize, &sk->sk_rmem_alloc); | 180 | atomic_sub(skb->truesize, &sk->sk_rmem_alloc); |
180 | sk->sk_forward_alloc += skb->truesize; | 181 | sk->sk_forward_alloc += skb->truesize; |
181 | } | 182 | } |
diff --git a/net/core/wireless.c b/net/core/wireless.c index 81d6995fcfdb..d2bc72d318f7 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c | |||
@@ -1726,6 +1726,14 @@ int wireless_rtnetlink_get(struct net_device * dev, | |||
1726 | if(!IW_IS_GET(request->cmd)) | 1726 | if(!IW_IS_GET(request->cmd)) |
1727 | return -EOPNOTSUPP; | 1727 | return -EOPNOTSUPP; |
1728 | 1728 | ||
1729 | /* If command is `get the encoding parameters', check if | ||
1730 | * the user has the right to do it */ | ||
1731 | if (request->cmd == SIOCGIWENCODE || | ||
1732 | request->cmd == SIOCGIWENCODEEXT) { | ||
1733 | if (!capable(CAP_NET_ADMIN)) | ||
1734 | return -EPERM; | ||
1735 | } | ||
1736 | |||
1729 | /* Special cases */ | 1737 | /* Special cases */ |
1730 | if(request->cmd == SIOCGIWSTATS) | 1738 | if(request->cmd == SIOCGIWSTATS) |
1731 | /* Get Wireless Stats */ | 1739 | /* Get Wireless Stats */ |
diff --git a/net/ieee80211/softmac/Kconfig b/net/ieee80211/softmac/Kconfig index 6cd9f3427be6..f2a27cc6ecb1 100644 --- a/net/ieee80211/softmac/Kconfig +++ b/net/ieee80211/softmac/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config IEEE80211_SOFTMAC | 1 | config IEEE80211_SOFTMAC |
2 | tristate "Software MAC add-on to the IEEE 802.11 networking stack" | 2 | tristate "Software MAC add-on to the IEEE 802.11 networking stack" |
3 | depends on IEEE80211 && EXPERIMENTAL | 3 | depends on IEEE80211 && EXPERIMENTAL |
4 | select WIRELESS_EXT | ||
4 | ---help--- | 5 | ---help--- |
5 | This option enables the hardware independent software MAC addon | 6 | This option enables the hardware independent software MAC addon |
6 | for the IEEE 802.11 networking stack. | 7 | for the IEEE 802.11 networking stack. |
diff --git a/net/ieee80211/softmac/ieee80211softmac_assoc.c b/net/ieee80211/softmac/ieee80211softmac_assoc.c index be61de78dfa4..fb79ce7d6439 100644 --- a/net/ieee80211/softmac/ieee80211softmac_assoc.c +++ b/net/ieee80211/softmac/ieee80211softmac_assoc.c | |||
@@ -101,6 +101,7 @@ ieee80211softmac_disassoc(struct ieee80211softmac_device *mac, u16 reason) | |||
101 | /* Do NOT clear bssvalid as that will break ieee80211softmac_assoc_work! */ | 101 | /* Do NOT clear bssvalid as that will break ieee80211softmac_assoc_work! */ |
102 | mac->associated = 0; | 102 | mac->associated = 0; |
103 | mac->associnfo.associating = 0; | 103 | mac->associnfo.associating = 0; |
104 | ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL); | ||
104 | spin_unlock_irqrestore(&mac->lock, flags); | 105 | spin_unlock_irqrestore(&mac->lock, flags); |
105 | } | 106 | } |
106 | 107 | ||
@@ -143,6 +144,12 @@ network_matches_request(struct ieee80211softmac_device *mac, struct ieee80211_ne | |||
143 | if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len)) | 144 | if (!we_support_all_basic_rates(mac, net->rates_ex, net->rates_ex_len)) |
144 | return 0; | 145 | return 0; |
145 | 146 | ||
147 | /* assume that users know what they're doing ... | ||
148 | * (note we don't let them select a net we're incompatible with) */ | ||
149 | if (mac->associnfo.bssfixed) { | ||
150 | return !memcmp(mac->associnfo.bssid, net->bssid, ETH_ALEN); | ||
151 | } | ||
152 | |||
146 | /* if 'ANY' network requested, take any that doesn't have privacy enabled */ | 153 | /* if 'ANY' network requested, take any that doesn't have privacy enabled */ |
147 | if (mac->associnfo.req_essid.len == 0 | 154 | if (mac->associnfo.req_essid.len == 0 |
148 | && !(net->capability & WLAN_CAPABILITY_PRIVACY)) | 155 | && !(net->capability & WLAN_CAPABILITY_PRIVACY)) |
@@ -175,7 +182,7 @@ ieee80211softmac_assoc_work(void *d) | |||
175 | ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); | 182 | ieee80211softmac_disassoc(mac, WLAN_REASON_DISASSOC_STA_HAS_LEFT); |
176 | 183 | ||
177 | /* try to find the requested network in our list, if we found one already */ | 184 | /* try to find the requested network in our list, if we found one already */ |
178 | if (mac->associnfo.bssvalid) | 185 | if (mac->associnfo.bssvalid || mac->associnfo.bssfixed) |
179 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); | 186 | found = ieee80211softmac_get_network_by_bssid(mac, mac->associnfo.bssid); |
180 | 187 | ||
181 | /* Search the ieee80211 networks for this network if we didn't find it by bssid, | 188 | /* Search the ieee80211 networks for this network if we didn't find it by bssid, |
@@ -240,19 +247,25 @@ ieee80211softmac_assoc_work(void *d) | |||
240 | if (ieee80211softmac_start_scan(mac)) | 247 | if (ieee80211softmac_start_scan(mac)) |
241 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); | 248 | dprintk(KERN_INFO PFX "Associate: failed to initiate scan. Is device up?\n"); |
242 | return; | 249 | return; |
243 | } | 250 | } else { |
244 | else { | ||
245 | spin_lock_irqsave(&mac->lock, flags); | 251 | spin_lock_irqsave(&mac->lock, flags); |
246 | mac->associnfo.associating = 0; | 252 | mac->associnfo.associating = 0; |
247 | mac->associated = 0; | 253 | mac->associated = 0; |
248 | spin_unlock_irqrestore(&mac->lock, flags); | 254 | spin_unlock_irqrestore(&mac->lock, flags); |
249 | 255 | ||
250 | dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); | 256 | dprintk(KERN_INFO PFX "Unable to find matching network after scan!\n"); |
257 | /* reset the retry counter for the next user request since we | ||
258 | * break out and don't reschedule ourselves after this point. */ | ||
259 | mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
251 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); | 260 | ieee80211softmac_call_events(mac, IEEE80211SOFTMAC_EVENT_ASSOCIATE_NET_NOT_FOUND, NULL); |
252 | return; | 261 | return; |
253 | } | 262 | } |
254 | } | 263 | } |
255 | 264 | ||
265 | /* reset the retry counter for the next user request since we | ||
266 | * now found a net and will try to associate to it, but not | ||
267 | * schedule this function again. */ | ||
268 | mac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
256 | mac->associnfo.bssvalid = 1; | 269 | mac->associnfo.bssvalid = 1; |
257 | memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN); | 270 | memcpy(mac->associnfo.bssid, found->bssid, ETH_ALEN); |
258 | /* copy the ESSID for displaying it */ | 271 | /* copy the ESSID for displaying it */ |
@@ -373,6 +386,7 @@ ieee80211softmac_handle_disassoc(struct net_device * dev, | |||
373 | spin_lock_irqsave(&mac->lock, flags); | 386 | spin_lock_irqsave(&mac->lock, flags); |
374 | mac->associnfo.bssvalid = 0; | 387 | mac->associnfo.bssvalid = 0; |
375 | mac->associated = 0; | 388 | mac->associated = 0; |
389 | ieee80211softmac_call_events_locked(mac, IEEE80211SOFTMAC_EVENT_DISASSOCIATED, NULL); | ||
376 | schedule_work(&mac->associnfo.work); | 390 | schedule_work(&mac->associnfo.work); |
377 | spin_unlock_irqrestore(&mac->lock, flags); | 391 | spin_unlock_irqrestore(&mac->lock, flags); |
378 | 392 | ||
@@ -391,6 +405,7 @@ ieee80211softmac_handle_reassoc_req(struct net_device * dev, | |||
391 | dprintkl(KERN_INFO PFX "reassoc request from unknown network\n"); | 405 | dprintkl(KERN_INFO PFX "reassoc request from unknown network\n"); |
392 | return 0; | 406 | return 0; |
393 | } | 407 | } |
394 | ieee80211softmac_assoc(mac, network); | 408 | schedule_work(&mac->associnfo.work); |
409 | |||
395 | return 0; | 410 | return 0; |
396 | } | 411 | } |
diff --git a/net/ieee80211/softmac/ieee80211softmac_event.c b/net/ieee80211/softmac/ieee80211softmac_event.c index 0a52bbda1e4c..8cc8f3f0f8e7 100644 --- a/net/ieee80211/softmac/ieee80211softmac_event.c +++ b/net/ieee80211/softmac/ieee80211softmac_event.c | |||
@@ -67,6 +67,7 @@ static char *event_descriptions[IEEE80211SOFTMAC_EVENT_LAST+1] = { | |||
67 | "authenticating failed", | 67 | "authenticating failed", |
68 | "authenticating timed out", | 68 | "authenticating timed out", |
69 | "associating failed because no suitable network was found", | 69 | "associating failed because no suitable network was found", |
70 | "disassociated", | ||
70 | }; | 71 | }; |
71 | 72 | ||
72 | 73 | ||
@@ -128,13 +129,42 @@ void | |||
128 | ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int event, void *event_ctx) | 129 | ieee80211softmac_call_events_locked(struct ieee80211softmac_device *mac, int event, void *event_ctx) |
129 | { | 130 | { |
130 | struct ieee80211softmac_event *eventptr, *tmp; | 131 | struct ieee80211softmac_event *eventptr, *tmp; |
131 | union iwreq_data wrqu; | 132 | struct ieee80211softmac_network *network; |
132 | char *msg; | ||
133 | 133 | ||
134 | if (event >= 0) { | 134 | if (event >= 0) { |
135 | msg = event_descriptions[event]; | 135 | union iwreq_data wrqu; |
136 | wrqu.data.length = strlen(msg); | 136 | int we_event; |
137 | wireless_send_event(mac->dev, IWEVCUSTOM, &wrqu, msg); | 137 | char *msg = NULL; |
138 | |||
139 | switch(event) { | ||
140 | case IEEE80211SOFTMAC_EVENT_ASSOCIATED: | ||
141 | network = (struct ieee80211softmac_network *)event_ctx; | ||
142 | wrqu.data.length = 0; | ||
143 | wrqu.data.flags = 0; | ||
144 | memcpy(wrqu.ap_addr.sa_data, &network->bssid[0], ETH_ALEN); | ||
145 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | ||
146 | we_event = SIOCGIWAP; | ||
147 | break; | ||
148 | case IEEE80211SOFTMAC_EVENT_DISASSOCIATED: | ||
149 | wrqu.data.length = 0; | ||
150 | wrqu.data.flags = 0; | ||
151 | memset(&wrqu, '\0', sizeof (union iwreq_data)); | ||
152 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | ||
153 | we_event = SIOCGIWAP; | ||
154 | break; | ||
155 | case IEEE80211SOFTMAC_EVENT_SCAN_FINISHED: | ||
156 | wrqu.data.length = 0; | ||
157 | wrqu.data.flags = 0; | ||
158 | memset(&wrqu, '\0', sizeof (union iwreq_data)); | ||
159 | we_event = SIOCGIWSCAN; | ||
160 | break; | ||
161 | default: | ||
162 | msg = event_descriptions[event]; | ||
163 | wrqu.data.length = strlen(msg); | ||
164 | we_event = IWEVCUSTOM; | ||
165 | break; | ||
166 | } | ||
167 | wireless_send_event(mac->dev, we_event, &wrqu, msg); | ||
138 | } | 168 | } |
139 | 169 | ||
140 | if (!list_empty(&mac->events)) | 170 | if (!list_empty(&mac->events)) |
diff --git a/net/ieee80211/softmac/ieee80211softmac_io.c b/net/ieee80211/softmac/ieee80211softmac_io.c index febc51dbb412..cc6cd56c85b1 100644 --- a/net/ieee80211/softmac/ieee80211softmac_io.c +++ b/net/ieee80211/softmac/ieee80211softmac_io.c | |||
@@ -180,9 +180,21 @@ ieee80211softmac_assoc_req(struct ieee80211_assoc_request **pkt, | |||
180 | ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid); | 180 | ieee80211softmac_hdr_3addr(mac, &((*pkt)->header), IEEE80211_STYPE_ASSOC_REQ, net->bssid, net->bssid); |
181 | 181 | ||
182 | /* Fill in capability Info */ | 182 | /* Fill in capability Info */ |
183 | (*pkt)->capability = (mac->ieee->iw_mode == IW_MODE_MASTER) || (mac->ieee->iw_mode == IW_MODE_INFRA) ? | 183 | switch (mac->ieee->iw_mode) { |
184 | cpu_to_le16(WLAN_CAPABILITY_ESS) : | 184 | case IW_MODE_INFRA: |
185 | cpu_to_le16(WLAN_CAPABILITY_IBSS); | 185 | (*pkt)->capability = cpu_to_le16(WLAN_CAPABILITY_ESS); |
186 | break; | ||
187 | case IW_MODE_ADHOC: | ||
188 | (*pkt)->capability = cpu_to_le16(WLAN_CAPABILITY_IBSS); | ||
189 | break; | ||
190 | case IW_MODE_AUTO: | ||
191 | (*pkt)->capability = net->capabilities & (WLAN_CAPABILITY_ESS|WLAN_CAPABILITY_IBSS); | ||
192 | break; | ||
193 | default: | ||
194 | /* bleh. we don't ever go to these modes */ | ||
195 | printk(KERN_ERR PFX "invalid iw_mode!\n"); | ||
196 | break; | ||
197 | } | ||
186 | /* Need to add this | 198 | /* Need to add this |
187 | (*pkt)->capability |= mac->ieee->short_slot ? | 199 | (*pkt)->capability |= mac->ieee->short_slot ? |
188 | cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0; | 200 | cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT_TIME) : 0; |
diff --git a/net/ieee80211/softmac/ieee80211softmac_module.c b/net/ieee80211/softmac/ieee80211softmac_module.c index 60f06a31f0d1..be83bdc1644a 100644 --- a/net/ieee80211/softmac/ieee80211softmac_module.c +++ b/net/ieee80211/softmac/ieee80211softmac_module.c | |||
@@ -45,6 +45,8 @@ struct net_device *alloc_ieee80211softmac(int sizeof_priv) | |||
45 | softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; | 45 | softmac->ieee->handle_disassoc = ieee80211softmac_handle_disassoc; |
46 | softmac->scaninfo = NULL; | 46 | softmac->scaninfo = NULL; |
47 | 47 | ||
48 | softmac->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
49 | |||
48 | /* TODO: initialise all the other callbacks in the ieee struct | 50 | /* TODO: initialise all the other callbacks in the ieee struct |
49 | * (once they're written) | 51 | * (once they're written) |
50 | */ | 52 | */ |
diff --git a/net/ieee80211/softmac/ieee80211softmac_scan.c b/net/ieee80211/softmac/ieee80211softmac_scan.c index bb9ab8b45d09..2b9e7edfa3ce 100644 --- a/net/ieee80211/softmac/ieee80211softmac_scan.c +++ b/net/ieee80211/softmac/ieee80211softmac_scan.c | |||
@@ -47,6 +47,7 @@ ieee80211softmac_start_scan(struct ieee80211softmac_device *sm) | |||
47 | sm->scanning = 1; | 47 | sm->scanning = 1; |
48 | spin_unlock_irqrestore(&sm->lock, flags); | 48 | spin_unlock_irqrestore(&sm->lock, flags); |
49 | 49 | ||
50 | netif_tx_disable(sm->ieee->dev); | ||
50 | ret = sm->start_scan(sm->dev); | 51 | ret = sm->start_scan(sm->dev); |
51 | if (ret) { | 52 | if (ret) { |
52 | spin_lock_irqsave(&sm->lock, flags); | 53 | spin_lock_irqsave(&sm->lock, flags); |
@@ -239,6 +240,7 @@ void ieee80211softmac_scan_finished(struct ieee80211softmac_device *sm) | |||
239 | if (net) | 240 | if (net) |
240 | sm->set_channel(sm->dev, net->channel); | 241 | sm->set_channel(sm->dev, net->channel); |
241 | } | 242 | } |
243 | netif_wake_queue(sm->ieee->dev); | ||
242 | ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL); | 244 | ieee80211softmac_call_events(sm, IEEE80211SOFTMAC_EVENT_SCAN_FINISHED, NULL); |
243 | } | 245 | } |
244 | EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished); | 246 | EXPORT_SYMBOL_GPL(ieee80211softmac_scan_finished); |
diff --git a/net/ieee80211/softmac/ieee80211softmac_wx.c b/net/ieee80211/softmac/ieee80211softmac_wx.c index b559aa9b5507..27edb2b5581a 100644 --- a/net/ieee80211/softmac/ieee80211softmac_wx.c +++ b/net/ieee80211/softmac/ieee80211softmac_wx.c | |||
@@ -27,7 +27,8 @@ | |||
27 | #include "ieee80211softmac_priv.h" | 27 | #include "ieee80211softmac_priv.h" |
28 | 28 | ||
29 | #include <net/iw_handler.h> | 29 | #include <net/iw_handler.h> |
30 | 30 | /* for is_broadcast_ether_addr and is_zero_ether_addr */ | |
31 | #include <linux/etherdevice.h> | ||
31 | 32 | ||
32 | int | 33 | int |
33 | ieee80211softmac_wx_trigger_scan(struct net_device *net_dev, | 34 | ieee80211softmac_wx_trigger_scan(struct net_device *net_dev, |
@@ -41,13 +42,23 @@ ieee80211softmac_wx_trigger_scan(struct net_device *net_dev, | |||
41 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_trigger_scan); | 42 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_trigger_scan); |
42 | 43 | ||
43 | 44 | ||
45 | /* if we're still scanning, return -EAGAIN so that userspace tools | ||
46 | * can get the complete scan results, otherwise return 0. */ | ||
44 | int | 47 | int |
45 | ieee80211softmac_wx_get_scan_results(struct net_device *net_dev, | 48 | ieee80211softmac_wx_get_scan_results(struct net_device *net_dev, |
46 | struct iw_request_info *info, | 49 | struct iw_request_info *info, |
47 | union iwreq_data *data, | 50 | union iwreq_data *data, |
48 | char *extra) | 51 | char *extra) |
49 | { | 52 | { |
53 | unsigned long flags; | ||
50 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); | 54 | struct ieee80211softmac_device *sm = ieee80211_priv(net_dev); |
55 | |||
56 | spin_lock_irqsave(&sm->lock, flags); | ||
57 | if (sm->scanning) { | ||
58 | spin_unlock_irqrestore(&sm->lock, flags); | ||
59 | return -EAGAIN; | ||
60 | } | ||
61 | spin_unlock_irqrestore(&sm->lock, flags); | ||
51 | return ieee80211_wx_get_scan(sm->ieee, info, data, extra); | 62 | return ieee80211_wx_get_scan(sm->ieee, info, data, extra); |
52 | } | 63 | } |
53 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_scan_results); | 64 | EXPORT_SYMBOL_GPL(ieee80211softmac_wx_get_scan_results); |
@@ -73,7 +84,6 @@ ieee80211softmac_wx_set_essid(struct net_device *net_dev, | |||
73 | sm->associnfo.static_essid = 1; | 84 | sm->associnfo.static_essid = 1; |
74 | } | 85 | } |
75 | } | 86 | } |
76 | sm->associnfo.scan_retry = IEEE80211SOFTMAC_ASSOC_SCAN_RETRY_LIMIT; | ||
77 | 87 | ||
78 | /* set our requested ESSID length. | 88 | /* set our requested ESSID length. |
79 | * If applicable, we have already copied the data in */ | 89 | * If applicable, we have already copied the data in */ |
@@ -300,8 +310,6 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
300 | char *extra) | 310 | char *extra) |
301 | { | 311 | { |
302 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); | 312 | struct ieee80211softmac_device *mac = ieee80211_priv(net_dev); |
303 | static const unsigned char any[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; | ||
304 | static const unsigned char off[] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; | ||
305 | unsigned long flags; | 313 | unsigned long flags; |
306 | 314 | ||
307 | /* sanity check */ | 315 | /* sanity check */ |
@@ -310,10 +318,17 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
310 | } | 318 | } |
311 | 319 | ||
312 | spin_lock_irqsave(&mac->lock, flags); | 320 | spin_lock_irqsave(&mac->lock, flags); |
313 | if (!memcmp(any, data->ap_addr.sa_data, ETH_ALEN) || | 321 | if (is_broadcast_ether_addr(data->ap_addr.sa_data)) { |
314 | !memcmp(off, data->ap_addr.sa_data, ETH_ALEN)) { | 322 | /* the bssid we have is not to be fixed any longer, |
315 | schedule_work(&mac->associnfo.work); | 323 | * and we should reassociate to the best AP. */ |
316 | goto out; | 324 | mac->associnfo.bssfixed = 0; |
325 | /* force reassociation */ | ||
326 | mac->associnfo.bssvalid = 0; | ||
327 | if (mac->associated) | ||
328 | schedule_work(&mac->associnfo.work); | ||
329 | } else if (is_zero_ether_addr(data->ap_addr.sa_data)) { | ||
330 | /* the bssid we have is no longer fixed */ | ||
331 | mac->associnfo.bssfixed = 0; | ||
317 | } else { | 332 | } else { |
318 | if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { | 333 | if (!memcmp(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN)) { |
319 | if (mac->associnfo.associating || mac->associated) { | 334 | if (mac->associnfo.associating || mac->associated) { |
@@ -323,12 +338,14 @@ ieee80211softmac_wx_set_wap(struct net_device *net_dev, | |||
323 | } else { | 338 | } else { |
324 | /* copy new value in data->ap_addr.sa_data to bssid */ | 339 | /* copy new value in data->ap_addr.sa_data to bssid */ |
325 | memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN); | 340 | memcpy(mac->associnfo.bssid, data->ap_addr.sa_data, ETH_ALEN); |
326 | } | 341 | } |
342 | /* tell the other code that this bssid should be used no matter what */ | ||
343 | mac->associnfo.bssfixed = 1; | ||
327 | /* queue associate if new bssid or (old one again and not associated) */ | 344 | /* queue associate if new bssid or (old one again and not associated) */ |
328 | schedule_work(&mac->associnfo.work); | 345 | schedule_work(&mac->associnfo.work); |
329 | } | 346 | } |
330 | 347 | ||
331 | out: | 348 | out: |
332 | spin_unlock_irqrestore(&mac->lock, flags); | 349 | spin_unlock_irqrestore(&mac->lock, flags); |
333 | return 0; | 350 | return 0; |
334 | } | 351 | } |
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 04a429465665..cd810f41af1a 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c | |||
@@ -290,11 +290,8 @@ static void ipcomp_free_scratches(void) | |||
290 | if (!scratches) | 290 | if (!scratches) |
291 | return; | 291 | return; |
292 | 292 | ||
293 | for_each_possible_cpu(i) { | 293 | for_each_possible_cpu(i) |
294 | void *scratch = *per_cpu_ptr(scratches, i); | 294 | vfree(*per_cpu_ptr(scratches, i)); |
295 | if (scratch) | ||
296 | vfree(scratch); | ||
297 | } | ||
298 | 295 | ||
299 | free_percpu(scratches); | 296 | free_percpu(scratches); |
300 | } | 297 | } |
diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index c60fd5c4ea1e..3d560dec63ab 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig | |||
@@ -345,7 +345,7 @@ config IP_NF_TARGET_LOG | |||
345 | To compile it as a module, choose M here. If unsure, say N. | 345 | To compile it as a module, choose M here. If unsure, say N. |
346 | 346 | ||
347 | config IP_NF_TARGET_ULOG | 347 | config IP_NF_TARGET_ULOG |
348 | tristate "ULOG target support (OBSOLETE)" | 348 | tristate "ULOG target support" |
349 | depends on IP_NF_IPTABLES | 349 | depends on IP_NF_IPTABLES |
350 | ---help--- | 350 | ---help--- |
351 | 351 | ||
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index b871db6adc55..a28ae593b976 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -533,6 +533,7 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss | |||
533 | struct tcp_sock *tp = tcp_sk(sk); | 533 | struct tcp_sock *tp = tcp_sk(sk); |
534 | struct sk_buff *buff; | 534 | struct sk_buff *buff; |
535 | int nsize, old_factor; | 535 | int nsize, old_factor; |
536 | int nlen; | ||
536 | u16 flags; | 537 | u16 flags; |
537 | 538 | ||
538 | BUG_ON(len > skb->len); | 539 | BUG_ON(len > skb->len); |
@@ -551,7 +552,11 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss | |||
551 | buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); | 552 | buff = sk_stream_alloc_skb(sk, nsize, GFP_ATOMIC); |
552 | if (buff == NULL) | 553 | if (buff == NULL) |
553 | return -ENOMEM; /* We'll just try again later. */ | 554 | return -ENOMEM; /* We'll just try again later. */ |
555 | |||
554 | sk_charge_skb(sk, buff); | 556 | sk_charge_skb(sk, buff); |
557 | nlen = skb->len - len - nsize; | ||
558 | buff->truesize += nlen; | ||
559 | skb->truesize -= nlen; | ||
555 | 560 | ||
556 | /* Correct the sequence numbers. */ | 561 | /* Correct the sequence numbers. */ |
557 | TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; | 562 | TCP_SKB_CB(buff)->seq = TCP_SKB_CB(skb)->seq + len; |
@@ -1037,7 +1042,8 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len, | |||
1037 | if (unlikely(buff == NULL)) | 1042 | if (unlikely(buff == NULL)) |
1038 | return -ENOMEM; | 1043 | return -ENOMEM; |
1039 | 1044 | ||
1040 | buff->truesize = nlen; | 1045 | sk_charge_skb(sk, buff); |
1046 | buff->truesize += nlen; | ||
1041 | skb->truesize -= nlen; | 1047 | skb->truesize -= nlen; |
1042 | 1048 | ||
1043 | /* Correct the sequence numbers. */ | 1049 | /* Correct the sequence numbers. */ |
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c index 2a1e7e45b890..a18d4256372c 100644 --- a/net/ipv6/exthdrs.c +++ b/net/ipv6/exthdrs.c | |||
@@ -485,15 +485,27 @@ static struct tlvtype_proc tlvprochopopt_lst[] = { | |||
485 | { -1, } | 485 | { -1, } |
486 | }; | 486 | }; |
487 | 487 | ||
488 | int ipv6_parse_hopopts(struct sk_buff *skb, int nhoff) | 488 | int ipv6_parse_hopopts(struct sk_buff *skb) |
489 | { | 489 | { |
490 | struct inet6_skb_parm *opt = IP6CB(skb); | 490 | struct inet6_skb_parm *opt = IP6CB(skb); |
491 | 491 | ||
492 | /* | ||
493 | * skb->nh.raw is equal to skb->data, and | ||
494 | * skb->h.raw - skb->nh.raw is always equal to | ||
495 | * sizeof(struct ipv6hdr) by definition of | ||
496 | * hop-by-hop options. | ||
497 | */ | ||
498 | if (!pskb_may_pull(skb, sizeof(struct ipv6hdr) + 8) || | ||
499 | !pskb_may_pull(skb, sizeof(struct ipv6hdr) + ((skb->h.raw[1] + 1) << 3))) { | ||
500 | kfree_skb(skb); | ||
501 | return -1; | ||
502 | } | ||
503 | |||
492 | opt->hop = sizeof(struct ipv6hdr); | 504 | opt->hop = sizeof(struct ipv6hdr); |
493 | if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { | 505 | if (ip6_parse_tlv(tlvprochopopt_lst, skb)) { |
494 | skb->h.raw += (skb->h.raw[1]+1)<<3; | 506 | skb->h.raw += (skb->h.raw[1]+1)<<3; |
495 | opt->nhoff = sizeof(struct ipv6hdr); | 507 | opt->nhoff = sizeof(struct ipv6hdr); |
496 | return sizeof(struct ipv6hdr); | 508 | return 1; |
497 | } | 509 | } |
498 | return -1; | 510 | return -1; |
499 | } | 511 | } |
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index 29f73592e68e..aceee252503d 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c | |||
@@ -114,11 +114,10 @@ int ipv6_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt | |||
114 | } | 114 | } |
115 | 115 | ||
116 | if (hdr->nexthdr == NEXTHDR_HOP) { | 116 | if (hdr->nexthdr == NEXTHDR_HOP) { |
117 | if (ipv6_parse_hopopts(skb, IP6CB(skb)->nhoff) < 0) { | 117 | if (ipv6_parse_hopopts(skb) < 0) { |
118 | IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); | 118 | IP6_INC_STATS_BH(IPSTATS_MIB_INHDRERRORS); |
119 | return 0; | 119 | return 0; |
120 | } | 120 | } |
121 | hdr = skb->nh.ipv6h; | ||
122 | } | 121 | } |
123 | 122 | ||
124 | return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); | 123 | return NF_HOOK(PF_INET6,NF_IP6_PRE_ROUTING, skb, dev, NULL, ip6_rcv_finish); |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 642b4b11464f..0a673038344f 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -288,19 +288,6 @@ ip6t_do_table(struct sk_buff **pskb, | |||
288 | table_base = (void *)private->entries[smp_processor_id()]; | 288 | table_base = (void *)private->entries[smp_processor_id()]; |
289 | e = get_entry(table_base, private->hook_entry[hook]); | 289 | e = get_entry(table_base, private->hook_entry[hook]); |
290 | 290 | ||
291 | #ifdef CONFIG_NETFILTER_DEBUG | ||
292 | /* Check noone else using our table */ | ||
293 | if (((struct ip6t_entry *)table_base)->comefrom != 0xdead57ac | ||
294 | && ((struct ip6t_entry *)table_base)->comefrom != 0xeeeeeeec) { | ||
295 | printk("ASSERT: CPU #%u, %s comefrom(%p) = %X\n", | ||
296 | smp_processor_id(), | ||
297 | table->name, | ||
298 | &((struct ip6t_entry *)table_base)->comefrom, | ||
299 | ((struct ip6t_entry *)table_base)->comefrom); | ||
300 | } | ||
301 | ((struct ip6t_entry *)table_base)->comefrom = 0x57acc001; | ||
302 | #endif | ||
303 | |||
304 | /* For return from builtin chain */ | 291 | /* For return from builtin chain */ |
305 | back = get_entry(table_base, private->underflow[hook]); | 292 | back = get_entry(table_base, private->underflow[hook]); |
306 | 293 | ||
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index 91cce8b2d7a5..88c840f1beb6 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -191,16 +191,18 @@ error: | |||
191 | static inline void | 191 | static inline void |
192 | _decode_session6(struct sk_buff *skb, struct flowi *fl) | 192 | _decode_session6(struct sk_buff *skb, struct flowi *fl) |
193 | { | 193 | { |
194 | u16 offset = sizeof(struct ipv6hdr); | 194 | u16 offset = skb->h.raw - skb->nh.raw; |
195 | struct ipv6hdr *hdr = skb->nh.ipv6h; | 195 | struct ipv6hdr *hdr = skb->nh.ipv6h; |
196 | struct ipv6_opt_hdr *exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); | 196 | struct ipv6_opt_hdr *exthdr; |
197 | u8 nexthdr = skb->nh.ipv6h->nexthdr; | 197 | u8 nexthdr = skb->nh.raw[IP6CB(skb)->nhoff]; |
198 | 198 | ||
199 | memset(fl, 0, sizeof(struct flowi)); | 199 | memset(fl, 0, sizeof(struct flowi)); |
200 | ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr); | 200 | ipv6_addr_copy(&fl->fl6_dst, &hdr->daddr); |
201 | ipv6_addr_copy(&fl->fl6_src, &hdr->saddr); | 201 | ipv6_addr_copy(&fl->fl6_src, &hdr->saddr); |
202 | 202 | ||
203 | while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) { | 203 | while (pskb_may_pull(skb, skb->nh.raw + offset + 1 - skb->data)) { |
204 | exthdr = (struct ipv6_opt_hdr*)(skb->nh.raw + offset); | ||
205 | |||
204 | switch (nexthdr) { | 206 | switch (nexthdr) { |
205 | case NEXTHDR_ROUTING: | 207 | case NEXTHDR_ROUTING: |
206 | case NEXTHDR_HOP: | 208 | case NEXTHDR_HOP: |
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index 8f3addf0724c..d62e0f9b9da3 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c | |||
@@ -118,7 +118,8 @@ static inline int llc_fixup_skb(struct sk_buff *skb) | |||
118 | u16 pdulen = eth_hdr(skb)->h_proto, | 118 | u16 pdulen = eth_hdr(skb)->h_proto, |
119 | data_size = ntohs(pdulen) - llc_len; | 119 | data_size = ntohs(pdulen) - llc_len; |
120 | 120 | ||
121 | skb_trim(skb, data_size); | 121 | if (unlikely(pskb_trim_rcsum(skb, data_size))) |
122 | return 0; | ||
122 | } | 123 | } |
123 | return 1; | 124 | return 1; |
124 | } | 125 | } |
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c index e581190fb6c3..f9b83f91371a 100644 --- a/net/netfilter/nf_conntrack_core.c +++ b/net/netfilter/nf_conntrack_core.c | |||
@@ -178,9 +178,6 @@ static struct { | |||
178 | /* allocated slab cache + modules which uses this slab cache */ | 178 | /* allocated slab cache + modules which uses this slab cache */ |
179 | int use; | 179 | int use; |
180 | 180 | ||
181 | /* Initialization */ | ||
182 | int (*init_conntrack)(struct nf_conn *, u_int32_t); | ||
183 | |||
184 | } nf_ct_cache[NF_CT_F_NUM]; | 181 | } nf_ct_cache[NF_CT_F_NUM]; |
185 | 182 | ||
186 | /* protect members of nf_ct_cache except of "use" */ | 183 | /* protect members of nf_ct_cache except of "use" */ |
@@ -208,10 +205,8 @@ nf_ct_proto_find_get(u_int16_t l3proto, u_int8_t protocol) | |||
208 | 205 | ||
209 | preempt_disable(); | 206 | preempt_disable(); |
210 | p = __nf_ct_proto_find(l3proto, protocol); | 207 | p = __nf_ct_proto_find(l3proto, protocol); |
211 | if (p) { | 208 | if (!try_module_get(p->me)) |
212 | if (!try_module_get(p->me)) | 209 | p = &nf_conntrack_generic_protocol; |
213 | p = &nf_conntrack_generic_protocol; | ||
214 | } | ||
215 | preempt_enable(); | 210 | preempt_enable(); |
216 | 211 | ||
217 | return p; | 212 | return p; |
@@ -229,10 +224,8 @@ nf_ct_l3proto_find_get(u_int16_t l3proto) | |||
229 | 224 | ||
230 | preempt_disable(); | 225 | preempt_disable(); |
231 | p = __nf_ct_l3proto_find(l3proto); | 226 | p = __nf_ct_l3proto_find(l3proto); |
232 | if (p) { | 227 | if (!try_module_get(p->me)) |
233 | if (!try_module_get(p->me)) | 228 | p = &nf_conntrack_generic_l3proto; |
234 | p = &nf_conntrack_generic_l3proto; | ||
235 | } | ||
236 | preempt_enable(); | 229 | preempt_enable(); |
237 | 230 | ||
238 | return p; | 231 | return p; |
diff --git a/net/netfilter/nf_conntrack_l3proto_generic.c b/net/netfilter/nf_conntrack_l3proto_generic.c index 7de4f06c63c5..3fc58e454d4e 100644 --- a/net/netfilter/nf_conntrack_l3proto_generic.c +++ b/net/netfilter/nf_conntrack_l3proto_generic.c | |||
@@ -94,5 +94,4 @@ struct nf_conntrack_l3proto nf_conntrack_generic_l3proto = { | |||
94 | .print_conntrack = generic_print_conntrack, | 94 | .print_conntrack = generic_print_conntrack, |
95 | .prepare = generic_prepare, | 95 | .prepare = generic_prepare, |
96 | .get_features = generic_get_features, | 96 | .get_features = generic_get_features, |
97 | .me = THIS_MODULE, | ||
98 | }; | 97 | }; |
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c index 00cf0a4f4d92..17abf60f9570 100644 --- a/net/netfilter/x_tables.c +++ b/net/netfilter/x_tables.c | |||
@@ -529,6 +529,7 @@ int xt_register_table(struct xt_table *table, | |||
529 | 529 | ||
530 | /* Simplifies replace_table code. */ | 530 | /* Simplifies replace_table code. */ |
531 | table->private = bootstrap; | 531 | table->private = bootstrap; |
532 | rwlock_init(&table->lock); | ||
532 | if (!xt_replace_table(table, 0, newinfo, &ret)) | 533 | if (!xt_replace_table(table, 0, newinfo, &ret)) |
533 | goto unlock; | 534 | goto unlock; |
534 | 535 | ||
@@ -538,7 +539,6 @@ int xt_register_table(struct xt_table *table, | |||
538 | /* save number of initial entries */ | 539 | /* save number of initial entries */ |
539 | private->initial_entries = private->number; | 540 | private->initial_entries = private->number; |
540 | 541 | ||
541 | rwlock_init(&table->lock); | ||
542 | list_prepend(&xt[table->af].tables, table); | 542 | list_prepend(&xt[table->af].tables, table); |
543 | 543 | ||
544 | ret = 0; | 544 | ret = 0; |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 6056d20ef429..37640c6fc014 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
@@ -69,6 +69,11 @@ ipt_init_target(struct ipt_entry_target *t, char *table, unsigned int hook) | |||
69 | DPRINTK("ipt_init_target: found %s\n", target->name); | 69 | DPRINTK("ipt_init_target: found %s\n", target->name); |
70 | t->u.kernel.target = target; | 70 | t->u.kernel.target = target; |
71 | 71 | ||
72 | ret = xt_check_target(target, AF_INET, t->u.target_size - sizeof(*t), | ||
73 | table, hook, 0, 0); | ||
74 | if (ret) | ||
75 | return ret; | ||
76 | |||
72 | if (t->u.kernel.target->checkentry | 77 | if (t->u.kernel.target->checkentry |
73 | && !t->u.kernel.target->checkentry(table, NULL, | 78 | && !t->u.kernel.target->checkentry(table, NULL, |
74 | t->u.kernel.target, t->data, | 79 | t->u.kernel.target, t->data, |
diff --git a/net/socket.c b/net/socket.c index 23898f45f713..0ce12dfc7a71 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -490,6 +490,7 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) | |||
490 | struct file *file; | 490 | struct file *file; |
491 | struct socket *sock; | 491 | struct socket *sock; |
492 | 492 | ||
493 | *err = -EBADF; | ||
493 | file = fget_light(fd, fput_needed); | 494 | file = fget_light(fd, fput_needed); |
494 | if (file) { | 495 | if (file) { |
495 | sock = sock_from_file(file, err); | 496 | sock = sock_from_file(file, err); |
diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 900ef31f5a0e..519ebc17c028 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c | |||
@@ -794,7 +794,6 @@ gss_create_cred(struct rpc_auth *auth, struct auth_cred *acred, int flags) | |||
794 | 794 | ||
795 | out_err: | 795 | out_err: |
796 | dprintk("RPC: gss_create_cred failed with error %d\n", err); | 796 | dprintk("RPC: gss_create_cred failed with error %d\n", err); |
797 | if (cred) gss_destroy_cred(&cred->gc_base); | ||
798 | return ERR_PTR(err); | 797 | return ERR_PTR(err); |
799 | } | 798 | } |
800 | 799 | ||
diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 97c981fa6b8e..76b969e6904f 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c | |||
@@ -212,7 +212,6 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, | |||
212 | char *cksumname; | 212 | char *cksumname; |
213 | struct crypto_tfm *tfm = NULL; /* XXX add to ctx? */ | 213 | struct crypto_tfm *tfm = NULL; /* XXX add to ctx? */ |
214 | struct scatterlist sg[1]; | 214 | struct scatterlist sg[1]; |
215 | u32 code = GSS_S_FAILURE; | ||
216 | 215 | ||
217 | switch (cksumtype) { | 216 | switch (cksumtype) { |
218 | case CKSUMTYPE_RSA_MD5: | 217 | case CKSUMTYPE_RSA_MD5: |
@@ -221,13 +220,11 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, | |||
221 | default: | 220 | default: |
222 | dprintk("RPC: krb5_make_checksum:" | 221 | dprintk("RPC: krb5_make_checksum:" |
223 | " unsupported checksum %d", cksumtype); | 222 | " unsupported checksum %d", cksumtype); |
224 | goto out; | 223 | return GSS_S_FAILURE; |
225 | } | 224 | } |
226 | if (!(tfm = crypto_alloc_tfm(cksumname, CRYPTO_TFM_REQ_MAY_SLEEP))) | 225 | if (!(tfm = crypto_alloc_tfm(cksumname, CRYPTO_TFM_REQ_MAY_SLEEP))) |
227 | goto out; | 226 | return GSS_S_FAILURE; |
228 | cksum->len = crypto_tfm_alg_digestsize(tfm); | 227 | cksum->len = crypto_tfm_alg_digestsize(tfm); |
229 | if ((cksum->data = kmalloc(cksum->len, GFP_KERNEL)) == NULL) | ||
230 | goto out; | ||
231 | 228 | ||
232 | crypto_digest_init(tfm); | 229 | crypto_digest_init(tfm); |
233 | sg_set_buf(sg, header, hdrlen); | 230 | sg_set_buf(sg, header, hdrlen); |
@@ -235,10 +232,8 @@ make_checksum(s32 cksumtype, char *header, int hdrlen, struct xdr_buf *body, | |||
235 | process_xdr_buf(body, body_offset, body->len - body_offset, | 232 | process_xdr_buf(body, body_offset, body->len - body_offset, |
236 | checksummer, tfm); | 233 | checksummer, tfm); |
237 | crypto_digest_final(tfm, cksum->data); | 234 | crypto_digest_final(tfm, cksum->data); |
238 | code = 0; | ||
239 | out: | ||
240 | crypto_free_tfm(tfm); | 235 | crypto_free_tfm(tfm); |
241 | return code; | 236 | return 0; |
242 | } | 237 | } |
243 | 238 | ||
244 | EXPORT_SYMBOL(make_checksum); | 239 | EXPORT_SYMBOL(make_checksum); |
diff --git a/net/sunrpc/stats.c b/net/sunrpc/stats.c index dea529666d69..15c2db26767b 100644 --- a/net/sunrpc/stats.c +++ b/net/sunrpc/stats.c | |||
@@ -176,7 +176,8 @@ void rpc_count_iostats(struct rpc_task *task) | |||
176 | op_metrics->om_execute += execute; | 176 | op_metrics->om_execute += execute; |
177 | } | 177 | } |
178 | 178 | ||
179 | void _print_name(struct seq_file *seq, unsigned int op, struct rpc_procinfo *procs) | 179 | static void _print_name(struct seq_file *seq, unsigned int op, |
180 | struct rpc_procinfo *procs) | ||
180 | { | 181 | { |
181 | if (procs[op].p_name) | 182 | if (procs[op].p_name) |
182 | seq_printf(seq, "\t%12s: ", procs[op].p_name); | 183 | seq_printf(seq, "\t%12s: ", procs[op].p_name); |
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c index 953307a9df1d..a3bbc891f959 100644 --- a/net/tipc/name_distr.c +++ b/net/tipc/name_distr.c | |||
@@ -229,8 +229,7 @@ static void node_is_down(struct publication *publ) | |||
229 | publ->node, publ->ref, publ->key); | 229 | publ->node, publ->ref, publ->key); |
230 | assert(p == publ); | 230 | assert(p == publ); |
231 | write_unlock_bh(&tipc_nametbl_lock); | 231 | write_unlock_bh(&tipc_nametbl_lock); |
232 | if (publ) | 232 | kfree(publ); |
233 | kfree(publ); | ||
234 | } | 233 | } |
235 | 234 | ||
236 | /** | 235 | /** |
diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index ae5ab981bb1d..8012d1076876 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c | |||
@@ -5,6 +5,7 @@ | |||
5 | 5 | ||
6 | #include <ctype.h> | 6 | #include <ctype.h> |
7 | #include <stdlib.h> | 7 | #include <stdlib.h> |
8 | #include <stdio.h> | ||
8 | #include <string.h> | 9 | #include <string.h> |
9 | #include <unistd.h> | 10 | #include <unistd.h> |
10 | #include <time.h> | 11 | #include <time.h> |
@@ -531,7 +532,7 @@ int main(int ac, char **av) | |||
531 | break; | 532 | break; |
532 | case 'h': | 533 | case 'h': |
533 | case '?': | 534 | case '?': |
534 | printf("%s [-o|-s] config\n", av[0]); | 535 | fprintf(stderr, "See README for usage info\n"); |
535 | exit(0); | 536 | exit(0); |
536 | } | 537 | } |
537 | } | 538 | } |
diff --git a/security/selinux/ss/mls.c b/security/selinux/ss/mls.c index 640d0bfdbc68..84047f69f9c1 100644 --- a/security/selinux/ss/mls.c +++ b/security/selinux/ss/mls.c | |||
@@ -264,7 +264,7 @@ int mls_context_to_sid(char oldc, | |||
264 | 264 | ||
265 | if (!selinux_mls_enabled) { | 265 | if (!selinux_mls_enabled) { |
266 | if (def_sid != SECSID_NULL && oldc) | 266 | if (def_sid != SECSID_NULL && oldc) |
267 | *scontext += strlen(*scontext); | 267 | *scontext += strlen(*scontext)+1; |
268 | return 0; | 268 | return 0; |
269 | } | 269 | } |
270 | 270 | ||
diff --git a/sound/drivers/mpu401/mpu401_uart.c b/sound/drivers/mpu401/mpu401_uart.c index 8687ae3c66b8..b49a45cbf67a 100644 --- a/sound/drivers/mpu401/mpu401_uart.c +++ b/sound/drivers/mpu401/mpu401_uart.c | |||
@@ -183,7 +183,8 @@ static void snd_mpu401_uart_remove_timer (struct snd_mpu401 *mpu, int input) | |||
183 | 183 | ||
184 | */ | 184 | */ |
185 | 185 | ||
186 | static void snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int ack) | 186 | static int snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, |
187 | int ack) | ||
187 | { | 188 | { |
188 | unsigned long flags; | 189 | unsigned long flags; |
189 | int timeout, ok; | 190 | int timeout, ok; |
@@ -218,9 +219,11 @@ static void snd_mpu401_uart_cmd(struct snd_mpu401 * mpu, unsigned char cmd, int | |||
218 | ok = 1; | 219 | ok = 1; |
219 | } | 220 | } |
220 | spin_unlock_irqrestore(&mpu->input_lock, flags); | 221 | spin_unlock_irqrestore(&mpu->input_lock, flags); |
221 | if (! ok) | 222 | if (!ok) { |
222 | snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); | 223 | snd_printk("cmd: 0x%x failed at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); |
223 | // snd_printk("cmd: 0x%x at 0x%lx (status = 0x%x, data = 0x%x)\n", cmd, mpu->port, mpu->read(mpu, MPU401C(mpu)), mpu->read(mpu, MPU401D(mpu))); | 224 | return 1; |
225 | } | ||
226 | return 0; | ||
224 | } | 227 | } |
225 | 228 | ||
226 | /* | 229 | /* |
@@ -235,12 +238,19 @@ static int snd_mpu401_uart_input_open(struct snd_rawmidi_substream *substream) | |||
235 | if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) | 238 | if (mpu->open_input && (err = mpu->open_input(mpu)) < 0) |
236 | return err; | 239 | return err; |
237 | if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { | 240 | if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) { |
238 | snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); | 241 | if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) |
239 | snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); | 242 | goto error_out; |
243 | if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) | ||
244 | goto error_out; | ||
240 | } | 245 | } |
241 | mpu->substream_input = substream; | 246 | mpu->substream_input = substream; |
242 | set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); | 247 | set_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); |
243 | return 0; | 248 | return 0; |
249 | |||
250 | error_out: | ||
251 | if (mpu->open_input && mpu->close_input) | ||
252 | mpu->close_input(mpu); | ||
253 | return -EIO; | ||
244 | } | 254 | } |
245 | 255 | ||
246 | static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) | 256 | static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) |
@@ -252,39 +262,52 @@ static int snd_mpu401_uart_output_open(struct snd_rawmidi_substream *substream) | |||
252 | if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) | 262 | if (mpu->open_output && (err = mpu->open_output(mpu)) < 0) |
253 | return err; | 263 | return err; |
254 | if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { | 264 | if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) { |
255 | snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1); | 265 | if (snd_mpu401_uart_cmd(mpu, MPU401_RESET, 1)) |
256 | snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1); | 266 | goto error_out; |
267 | if (snd_mpu401_uart_cmd(mpu, MPU401_ENTER_UART, 1)) | ||
268 | goto error_out; | ||
257 | } | 269 | } |
258 | mpu->substream_output = substream; | 270 | mpu->substream_output = substream; |
259 | set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); | 271 | set_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); |
260 | return 0; | 272 | return 0; |
273 | |||
274 | error_out: | ||
275 | if (mpu->open_output && mpu->close_output) | ||
276 | mpu->close_output(mpu); | ||
277 | return -EIO; | ||
261 | } | 278 | } |
262 | 279 | ||
263 | static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream) | 280 | static int snd_mpu401_uart_input_close(struct snd_rawmidi_substream *substream) |
264 | { | 281 | { |
265 | struct snd_mpu401 *mpu; | 282 | struct snd_mpu401 *mpu; |
283 | int err = 0; | ||
266 | 284 | ||
267 | mpu = substream->rmidi->private_data; | 285 | mpu = substream->rmidi->private_data; |
268 | clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); | 286 | clear_bit(MPU401_MODE_BIT_INPUT, &mpu->mode); |
269 | mpu->substream_input = NULL; | 287 | mpu->substream_input = NULL; |
270 | if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) | 288 | if (! test_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode)) |
271 | snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); | 289 | err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); |
272 | if (mpu->close_input) | 290 | if (mpu->close_input) |
273 | mpu->close_input(mpu); | 291 | mpu->close_input(mpu); |
292 | if (err) | ||
293 | return -EIO; | ||
274 | return 0; | 294 | return 0; |
275 | } | 295 | } |
276 | 296 | ||
277 | static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream) | 297 | static int snd_mpu401_uart_output_close(struct snd_rawmidi_substream *substream) |
278 | { | 298 | { |
279 | struct snd_mpu401 *mpu; | 299 | struct snd_mpu401 *mpu; |
300 | int err = 0; | ||
280 | 301 | ||
281 | mpu = substream->rmidi->private_data; | 302 | mpu = substream->rmidi->private_data; |
282 | clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); | 303 | clear_bit(MPU401_MODE_BIT_OUTPUT, &mpu->mode); |
283 | mpu->substream_output = NULL; | 304 | mpu->substream_output = NULL; |
284 | if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) | 305 | if (! test_bit(MPU401_MODE_BIT_INPUT, &mpu->mode)) |
285 | snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); | 306 | err = snd_mpu401_uart_cmd(mpu, MPU401_RESET, 0); |
286 | if (mpu->close_output) | 307 | if (mpu->close_output) |
287 | mpu->close_output(mpu); | 308 | mpu->close_output(mpu); |
309 | if (err) | ||
310 | return -EIO; | ||
288 | return 0; | 311 | return 0; |
289 | } | 312 | } |
290 | 313 | ||
@@ -316,6 +339,7 @@ static void snd_mpu401_uart_input_trigger(struct snd_rawmidi_substream *substrea | |||
316 | snd_mpu401_uart_remove_timer(mpu, 1); | 339 | snd_mpu401_uart_remove_timer(mpu, 1); |
317 | clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); | 340 | clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); |
318 | } | 341 | } |
342 | |||
319 | } | 343 | } |
320 | 344 | ||
321 | /* | 345 | /* |
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 88e52dc84c09..6275266dde2e 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig | |||
@@ -5,23 +5,9 @@ | |||
5 | # | 5 | # |
6 | # Prompt user for primary drivers. | 6 | # Prompt user for primary drivers. |
7 | 7 | ||
8 | config OBSOLETE_OSS_DRIVER | ||
9 | bool "Obsolete OSS drivers" | ||
10 | depends on SOUND_PRIME | ||
11 | help | ||
12 | This option enables support for obsolete OSS drivers that | ||
13 | are scheduled for removal in the near future since there | ||
14 | are ALSA drivers for the same hardware. | ||
15 | |||
16 | Please contact Adrian Bunk <bunk@stusta.de> if you had to | ||
17 | say Y here because your soundcard is not properly supported | ||
18 | by ALSA. | ||
19 | |||
20 | If unsure, say N. | ||
21 | |||
22 | config SOUND_BT878 | 8 | config SOUND_BT878 |
23 | tristate "BT878 audio dma" | 9 | tristate "BT878 audio dma" |
24 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | 10 | depends on SOUND_PRIME && PCI |
25 | ---help--- | 11 | ---help--- |
26 | Audio DMA support for bt878 based grabber boards. As you might have | 12 | Audio DMA support for bt878 based grabber boards. As you might have |
27 | already noticed, bt878 is listed with two functions in /proc/pci. | 13 | already noticed, bt878 is listed with two functions in /proc/pci. |
@@ -35,48 +21,9 @@ config SOUND_BT878 | |||
35 | To compile this driver as a module, choose M here: the module will | 21 | To compile this driver as a module, choose M here: the module will |
36 | be called btaudio. | 22 | be called btaudio. |
37 | 23 | ||
38 | config SOUND_CMPCI | ||
39 | tristate "C-Media PCI (CMI8338/8738)" | ||
40 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | ||
41 | help | ||
42 | Say Y or M if you have a PCI sound card using the CMI8338 | ||
43 | or the CMI8738 chipset. Data on these chips are available at | ||
44 | <http://www.cmedia.com.tw/>. | ||
45 | |||
46 | A userspace utility to control some internal registers of these | ||
47 | chips is available at | ||
48 | <http://member.nifty.ne.jp/Breeze/softwares/unix/cmictl-e.html>. | ||
49 | |||
50 | config SOUND_CMPCI_FM | ||
51 | bool "Enable legacy FM" | ||
52 | depends on SOUND_CMPCI && X86 | ||
53 | help | ||
54 | Say Y here to enable the legacy FM (frequency-modulation) synthesizer | ||
55 | support on a card using the CMI8338 or CMI8378 chipset. Even it is | ||
56 | enabled, you need to set fmio as proper value to enable it. | ||
57 | Say N here if you don't need this. | ||
58 | |||
59 | config SOUND_CMPCI_MIDI | ||
60 | bool "Enable legacy MPU-401" | ||
61 | depends on SOUND_CMPCI && X86 | ||
62 | help | ||
63 | Say Y here to enable the legacy MPU401 MIDI synthesizer support on a | ||
64 | card using the CMI8338 or CMI8378 chipset. Even it is enabled, | ||
65 | you need to set mpuio as proper value to enable it. | ||
66 | Say N here if you don't need this. | ||
67 | |||
68 | config SOUND_CMPCI_JOYSTICK | ||
69 | bool "Enable joystick" | ||
70 | depends on SOUND_CMPCI && X86 && (GAMEPORT=y || SOUND_CMPCI=GAMEPORT) | ||
71 | help | ||
72 | Say Y here in order to enable the joystick port on a sound card using | ||
73 | the CMI8338 or the CMI8738 chipset. You need to config the | ||
74 | gameport support and set joystick parameter as 1 to use it. | ||
75 | Say N here if you don't need this. | ||
76 | |||
77 | config SOUND_EMU10K1 | 24 | config SOUND_EMU10K1 |
78 | tristate "Creative SBLive! (EMU10K1)" | 25 | tristate "Creative SBLive! (EMU10K1)" |
79 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | 26 | depends on SOUND_PRIME && PCI |
80 | ---help--- | 27 | ---help--- |
81 | Say Y or M if you have a PCI sound card using the EMU10K1 chipset, | 28 | Say Y or M if you have a PCI sound card using the EMU10K1 chipset, |
82 | such as the Creative SBLive!, SB PCI512 or Emu-APS. | 29 | such as the Creative SBLive!, SB PCI512 or Emu-APS. |
@@ -108,13 +55,6 @@ config SOUND_FUSION | |||
108 | series) when wired as native sound drivers with AC97 codecs. If | 55 | series) when wired as native sound drivers with AC97 codecs. If |
109 | this driver does not work try the CS4232 driver. | 56 | this driver does not work try the CS4232 driver. |
110 | 57 | ||
111 | config SOUND_CS4281 | ||
112 | tristate "Crystal Sound CS4281" | ||
113 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | ||
114 | help | ||
115 | Picture and feature list at | ||
116 | <http://www.pcbroker.com/crystal4281.html>. | ||
117 | |||
118 | config SOUND_BCM_CS4297A | 58 | config SOUND_BCM_CS4297A |
119 | tristate "Crystal Sound CS4297a (for Swarm)" | 59 | tristate "Crystal Sound CS4297a (for Swarm)" |
120 | depends on SOUND_PRIME && SIBYTE_SWARM | 60 | depends on SOUND_PRIME && SIBYTE_SWARM |
@@ -125,22 +65,9 @@ config SOUND_BCM_CS4297A | |||
125 | note that CONFIG_KGDB should not be enabled at the same | 65 | note that CONFIG_KGDB should not be enabled at the same |
126 | time, since it also attempts to use this UART port. | 66 | time, since it also attempts to use this UART port. |
127 | 67 | ||
128 | config SOUND_ES1370 | ||
129 | tristate "Ensoniq AudioPCI (ES1370)" | ||
130 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | ||
131 | help | ||
132 | Say Y or M if you have a PCI sound card utilizing the Ensoniq | ||
133 | ES1370 chipset, such as Ensoniq's AudioPCI (non-97). To find | ||
134 | out if your sound card uses an ES1370 without removing your | ||
135 | computer's cover, use lspci -n and look for the PCI ID | ||
136 | 1274:5000. Since Ensoniq was bought by Creative Labs, | ||
137 | Sound Blaster 64/PCI models are either ES1370 or ES1371 based. | ||
138 | This driver differs slightly from OSS/Free, so PLEASE READ | ||
139 | <file:Documentation/sound/oss/es1370>. | ||
140 | |||
141 | config SOUND_ES1371 | 68 | config SOUND_ES1371 |
142 | tristate "Creative Ensoniq AudioPCI 97 (ES1371)" | 69 | tristate "Creative Ensoniq AudioPCI 97 (ES1371)" |
143 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | 70 | depends on SOUND_PRIME && PCI |
144 | help | 71 | help |
145 | Say Y or M if you have a PCI sound card utilizing the Ensoniq | 72 | Say Y or M if you have a PCI sound card utilizing the Ensoniq |
146 | ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if | 73 | ES1371 chipset, such as Ensoniq's AudioPCI97. To find out if |
@@ -151,33 +78,6 @@ config SOUND_ES1371 | |||
151 | slightly from OSS/Free, so PLEASE READ | 78 | slightly from OSS/Free, so PLEASE READ |
152 | <file:Documentation/sound/oss/es1371>. | 79 | <file:Documentation/sound/oss/es1371>. |
153 | 80 | ||
154 | config SOUND_ESSSOLO1 | ||
155 | tristate "ESS Technology Solo1" | ||
156 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | ||
157 | help | ||
158 | Say Y or M if you have a PCI sound card utilizing the ESS Technology | ||
159 | Solo1 chip. To find out if your sound card uses a | ||
160 | Solo1 chip without removing your computer's cover, use | ||
161 | lspci -n and look for the PCI ID 125D:1969. This driver | ||
162 | differs slightly from OSS/Free, so PLEASE READ | ||
163 | <file:Documentation/sound/oss/solo1>. | ||
164 | |||
165 | config SOUND_MAESTRO | ||
166 | tristate "ESS Maestro, Maestro2, Maestro2E driver" | ||
167 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | ||
168 | help | ||
169 | Say Y or M if you have a sound system driven by ESS's Maestro line | ||
170 | of PCI sound chips. These include the Maestro 1, Maestro 2, and | ||
171 | Maestro 2E. See <file:Documentation/sound/oss/Maestro> for more | ||
172 | details. | ||
173 | |||
174 | config SOUND_MAESTRO3 | ||
175 | tristate "ESS Maestro3/Allegro driver (EXPERIMENTAL)" | ||
176 | depends on SOUND_PRIME && PCI && EXPERIMENTAL && OBSOLETE_OSS_DRIVER | ||
177 | help | ||
178 | Say Y or M if you have a sound system driven by ESS's Maestro 3 | ||
179 | PCI sound chip. | ||
180 | |||
181 | config SOUND_ICH | 81 | config SOUND_ICH |
182 | tristate "Intel ICH (i8xx) audio support" | 82 | tristate "Intel ICH (i8xx) audio support" |
183 | depends on SOUND_PRIME && PCI | 83 | depends on SOUND_PRIME && PCI |
@@ -185,24 +85,6 @@ config SOUND_ICH | |||
185 | Support for integral audio in Intel's I/O Controller Hub (ICH) | 85 | Support for integral audio in Intel's I/O Controller Hub (ICH) |
186 | chipset, as used on the 810/820/840 motherboards. | 86 | chipset, as used on the 810/820/840 motherboards. |
187 | 87 | ||
188 | config SOUND_HARMONY | ||
189 | tristate "PA Harmony audio driver" | ||
190 | depends on GSC_LASI && SOUND_PRIME && OBSOLETE_OSS_DRIVER | ||
191 | help | ||
192 | Say 'Y' or 'M' to include support for Harmony soundchip | ||
193 | on HP 712, 715/new and many other GSC based machines. | ||
194 | |||
195 | config SOUND_SONICVIBES | ||
196 | tristate "S3 SonicVibes" | ||
197 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | ||
198 | help | ||
199 | Say Y or M if you have a PCI sound card utilizing the S3 | ||
200 | SonicVibes chipset. To find out if your sound card uses a | ||
201 | SonicVibes chip without removing your computer's cover, use | ||
202 | lspci -n and look for the PCI ID 5333:CA00. This driver | ||
203 | differs slightly from OSS/Free, so PLEASE READ | ||
204 | <file:Documentation/sound/oss/sonicvibes>. | ||
205 | |||
206 | config SOUND_VWSND | 88 | config SOUND_VWSND |
207 | tristate "SGI Visual Workstation Sound" | 89 | tristate "SGI Visual Workstation Sound" |
208 | depends on SOUND_PRIME && X86_VISWS | 90 | depends on SOUND_PRIME && X86_VISWS |
@@ -231,10 +113,6 @@ config SOUND_VRC5477 | |||
231 | integrated, multi-function controller chip for MIPS CPUs. Works | 113 | integrated, multi-function controller chip for MIPS CPUs. Works |
232 | with the AC97 codec. | 114 | with the AC97 codec. |
233 | 115 | ||
234 | config SOUND_AU1000 | ||
235 | tristate "Au1000 Sound" | ||
236 | depends on SOUND_PRIME && (SOC_AU1000 || SOC_AU1100 || SOC_AU1500) && OBSOLETE_OSS_DRIVER | ||
237 | |||
238 | config SOUND_AU1550_AC97 | 116 | config SOUND_AU1550_AC97 |
239 | tristate "Au1550 AC97 Sound" | 117 | tristate "Au1550 AC97 Sound" |
240 | depends on SOUND_PRIME && SOC_AU1550 | 118 | depends on SOUND_PRIME && SOC_AU1550 |
@@ -507,7 +385,7 @@ config MSND_FIFOSIZE | |||
507 | 385 | ||
508 | config SOUND_VIA82CXXX | 386 | config SOUND_VIA82CXXX |
509 | tristate "VIA 82C686 Audio Codec" | 387 | tristate "VIA 82C686 Audio Codec" |
510 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | 388 | depends on SOUND_PRIME && PCI |
511 | help | 389 | help |
512 | Say Y here to include support for the audio codec found on VIA | 390 | Say Y here to include support for the audio codec found on VIA |
513 | 82Cxxx-based chips. Typically these are built into a motherboard. | 391 | 82Cxxx-based chips. Typically these are built into a motherboard. |
@@ -576,18 +454,6 @@ config SOUND_AD1889 | |||
576 | Say M here if you have a sound card based on the Analog Devices | 454 | Say M here if you have a sound card based on the Analog Devices |
577 | AD1889 chip. | 455 | AD1889 chip. |
578 | 456 | ||
579 | config SOUND_SGALAXY | ||
580 | tristate "Aztech Sound Galaxy (non-PnP) cards" | ||
581 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | ||
582 | help | ||
583 | This module initializes the older non Plug and Play sound galaxy | ||
584 | cards from Aztech. It supports the Waverider Pro 32 - 3D and the | ||
585 | Galaxy Washington 16. | ||
586 | |||
587 | If you compile the driver into the kernel, you have to add | ||
588 | "sgalaxy=<io>,<irq>,<dma>,<dma2>,<sgbase>" to the kernel command | ||
589 | line. | ||
590 | |||
591 | config SOUND_ADLIB | 457 | config SOUND_ADLIB |
592 | tristate "Adlib Cards" | 458 | tristate "Adlib Cards" |
593 | depends on SOUND_OSS | 459 | depends on SOUND_OSS |
@@ -612,56 +478,6 @@ config SOUND_ACI_MIXER | |||
612 | 478 | ||
613 | This driver is also available as a module and will be called aci. | 479 | This driver is also available as a module and will be called aci. |
614 | 480 | ||
615 | config SOUND_CS4232 | ||
616 | tristate "Crystal CS4232 based (PnP) cards" | ||
617 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | ||
618 | help | ||
619 | Say Y here if you have a card based on the Crystal CS4232 chip set, | ||
620 | which uses its own Plug and Play protocol. | ||
621 | |||
622 | If you compile the driver into the kernel, you have to add | ||
623 | "cs4232=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the kernel | ||
624 | command line. | ||
625 | |||
626 | See <file:Documentation/sound/oss/CS4232> for more information on | ||
627 | configuring this card. | ||
628 | |||
629 | config SOUND_SSCAPE | ||
630 | tristate "Ensoniq SoundScape support" | ||
631 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | ||
632 | help | ||
633 | Answer Y if you have a sound card based on the Ensoniq SoundScape | ||
634 | chipset. Such cards are being manufactured at least by Ensoniq, Spea | ||
635 | and Reveal (Reveal makes also other cards). | ||
636 | |||
637 | If you compile the driver into the kernel, you have to add | ||
638 | "sscape=<io>,<irq>,<dma>,<mpuio>,<mpuirq>" to the kernel command | ||
639 | line. | ||
640 | |||
641 | config SOUND_GUS | ||
642 | tristate "Gravis Ultrasound support" | ||
643 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | ||
644 | help | ||
645 | Say Y here for any type of Gravis Ultrasound card, including the GUS | ||
646 | or GUS MAX. See also <file:Documentation/sound/oss/ultrasound> for more | ||
647 | information on configuring this card with modules. | ||
648 | |||
649 | If you compile the driver into the kernel, you have to add | ||
650 | "gus=<io>,<irq>,<dma>,<dma2>" to the kernel command line. | ||
651 | |||
652 | config SOUND_GUS16 | ||
653 | bool "16 bit sampling option of GUS (_NOT_ GUS MAX)" | ||
654 | depends on SOUND_GUS | ||
655 | help | ||
656 | Support for Gravis Ulstrasound (GUS) cards (other than the GUS), | ||
657 | sampling at 16-bit width. | ||
658 | |||
659 | config SOUND_GUSMAX | ||
660 | bool "GUS MAX support" | ||
661 | depends on SOUND_GUS | ||
662 | help | ||
663 | Support for Gravis Ulstrasound MAX. | ||
664 | |||
665 | config SOUND_VMIDI | 481 | config SOUND_VMIDI |
666 | tristate "Loopback MIDI device support" | 482 | tristate "Loopback MIDI device support" |
667 | depends on SOUND_OSS | 483 | depends on SOUND_OSS |
@@ -742,7 +558,7 @@ config SOUND_MPU401 | |||
742 | 558 | ||
743 | config SOUND_NM256 | 559 | config SOUND_NM256 |
744 | tristate "NM256AV/NM256ZX audio support" | 560 | tristate "NM256AV/NM256ZX audio support" |
745 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | 561 | depends on SOUND_OSS |
746 | help | 562 | help |
747 | Say M here to include audio support for the NeoMagic 256AV/256ZX | 563 | Say M here to include audio support for the NeoMagic 256AV/256ZX |
748 | chipsets. These are the audio chipsets found in the Sony | 564 | chipsets. These are the audio chipsets found in the Sony |
@@ -752,35 +568,6 @@ config SOUND_NM256 | |||
752 | 568 | ||
753 | See <file:Documentation/sound/oss/NM256> for further information. | 569 | See <file:Documentation/sound/oss/NM256> for further information. |
754 | 570 | ||
755 | config SOUND_MAD16 | ||
756 | tristate "OPTi MAD16 and/or Mozart based cards" | ||
757 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | ||
758 | ---help--- | ||
759 | Answer Y if your card has a Mozart (OAK OTI-601) or MAD16 (OPTi | ||
760 | 82C928 or 82C929 or 82C931) audio interface chip. These chips are | ||
761 | quite common so it's possible that many no-name cards have one of | ||
762 | them. In addition the MAD16 chip is used in some cards made by known | ||
763 | manufacturers such as Turtle Beach (Tropez), Reveal (some models) | ||
764 | and Diamond (latest ones). Note however that the Tropez sound cards | ||
765 | have their own driver; if you have one of those, say N here and Y or | ||
766 | M to "Full support for Turtle Beach WaveFront", below. | ||
767 | |||
768 | If you compile the driver into the kernel, you have to add | ||
769 | "mad16=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the | ||
770 | kernel command line. | ||
771 | |||
772 | See also <file:Documentation/sound/oss/Opti> and | ||
773 | <file:Documentation/sound/oss/MAD16> for more information on setting | ||
774 | these cards up as modules. | ||
775 | |||
776 | config MAD16_OLDCARD | ||
777 | bool "Support MIDI in older MAD16 based cards (requires SB)" | ||
778 | depends on SOUND_MAD16 | ||
779 | help | ||
780 | Answer Y (or M) if you have an older card based on the C928 or | ||
781 | Mozart chipset and you want to have MIDI support. If you enable this | ||
782 | option you also need to enable support for Sound Blaster. | ||
783 | |||
784 | config SOUND_PAS | 571 | config SOUND_PAS |
785 | tristate "ProAudioSpectrum 16 support" | 572 | tristate "ProAudioSpectrum 16 support" |
786 | depends on SOUND_OSS | 573 | depends on SOUND_OSS |
@@ -873,53 +660,9 @@ config SOUND_SB | |||
873 | You can say M here to compile this driver as a module; the module is | 660 | You can say M here to compile this driver as a module; the module is |
874 | called sb. | 661 | called sb. |
875 | 662 | ||
876 | config SOUND_AWE32_SYNTH | ||
877 | tristate "AWE32 synth" | ||
878 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | ||
879 | help | ||
880 | Say Y here if you have a Sound Blaster SB32, AWE32-PnP, SB AWE64 or | ||
881 | similar sound card. See <file:Documentation/sound/oss/README.awe>, | ||
882 | <file:Documentation/sound/oss/AWE32> and the Soundblaster-AWE | ||
883 | mini-HOWTO, available from <http://www.tldp.org/docs.html#howto> | ||
884 | for more info. | ||
885 | |||
886 | config SOUND_WAVEFRONT | ||
887 | tristate "Full support for Turtle Beach WaveFront (Tropez Plus, Tropez, Maui) synth/soundcards" | ||
888 | depends on SOUND_OSS && m && OBSOLETE_OSS_DRIVER | ||
889 | help | ||
890 | Answer Y or M if you have a Tropez Plus, Tropez or Maui sound card | ||
891 | and read the files <file:Documentation/sound/oss/Wavefront> and | ||
892 | <file:Documentation/sound/oss/Tropez+>. | ||
893 | |||
894 | config SOUND_MAUI | ||
895 | tristate "Limited support for Turtle Beach Wave Front (Maui, Tropez) synthesizers" | ||
896 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | ||
897 | help | ||
898 | Say Y here if you have a Turtle Beach Wave Front, Maui, or Tropez | ||
899 | sound card. | ||
900 | |||
901 | If you compile the driver into the kernel, you have to add | ||
902 | "maui=<io>,<irq>" to the kernel command line. | ||
903 | |||
904 | config MAUI_HAVE_BOOT | ||
905 | bool "Have OSWF.MOT firmware file" | ||
906 | depends on SOUND_MAUI=y && !STANDALONE | ||
907 | help | ||
908 | Turtle Beach Maui and Tropez sound cards have a microcontroller | ||
909 | which needs to be initialized prior to use. OSWF.MOT is a file | ||
910 | distributed with the card's DOS/Windows drivers. Answer Y if you | ||
911 | have this file. | ||
912 | |||
913 | config MAUI_BOOT_FILE | ||
914 | string "Full pathname of OSWF.MOT firmware file" | ||
915 | depends on MAUI_HAVE_BOOT | ||
916 | default "/etc/sound/oswf.mot" | ||
917 | help | ||
918 | Enter the full pathname of your OSWF.MOT file, starting from /. | ||
919 | |||
920 | config SOUND_YM3812 | 663 | config SOUND_YM3812 |
921 | tristate "Yamaha FM synthesizer (YM3812/OPL-3) support" | 664 | tristate "Yamaha FM synthesizer (YM3812/OPL-3) support" |
922 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | 665 | depends on SOUND_OSS |
923 | ---help--- | 666 | ---help--- |
924 | Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). | 667 | Answer Y if your card has a FM chip made by Yamaha (OPL2/OPL3/OPL4). |
925 | Answering Y is usually a safe and recommended choice, however some | 668 | Answering Y is usually a safe and recommended choice, however some |
@@ -933,18 +676,6 @@ config SOUND_YM3812 | |||
933 | 676 | ||
934 | If unsure, say Y. | 677 | If unsure, say Y. |
935 | 678 | ||
936 | config SOUND_OPL3SA1 | ||
937 | tristate "Yamaha OPL3-SA1 audio controller" | ||
938 | depends on SOUND_OSS && OBSOLETE_OSS_DRIVER | ||
939 | help | ||
940 | Say Y or M if you have a Yamaha OPL3-SA1 sound chip, which is | ||
941 | usually built into motherboards. Read | ||
942 | <file:Documentation/sound/oss/OPL3-SA> for details. | ||
943 | |||
944 | If you compile the driver into the kernel, you have to add | ||
945 | "opl3sa=<io>,<irq>,<dma>,<dma2>,<mpuio>,<mpuirq>" to the kernel | ||
946 | command line. | ||
947 | |||
948 | config SOUND_OPL3SA2 | 679 | config SOUND_OPL3SA2 |
949 | tristate "Yamaha OPL3-SA2 and SA3 based PnP cards" | 680 | tristate "Yamaha OPL3-SA2 and SA3 based PnP cards" |
950 | depends on SOUND_OSS | 681 | depends on SOUND_OSS |
@@ -959,19 +690,6 @@ config SOUND_OPL3SA2 | |||
959 | "opl3sa2=<io>,<irq>,<dma>,<dma2>,<mssio>,<mpuio>" to the kernel | 690 | "opl3sa2=<io>,<irq>,<dma>,<dma2>,<mssio>,<mpuio>" to the kernel |
960 | command line. | 691 | command line. |
961 | 692 | ||
962 | config SOUND_YMFPCI | ||
963 | tristate "Yamaha YMF7xx PCI audio (native mode)" | ||
964 | depends on SOUND_OSS && PCI && OBSOLETE_OSS_DRIVER | ||
965 | help | ||
966 | Support for Yamaha cards including the YMF711, YMF715, YMF718, | ||
967 | YMF719, YMF724, Waveforce 192XG, and Waveforce 192 Digital. | ||
968 | |||
969 | config SOUND_YMFPCI_LEGACY | ||
970 | bool "Yamaha PCI legacy ports support" | ||
971 | depends on SOUND_YMFPCI | ||
972 | help | ||
973 | Support for YMF7xx PCI cards emulating an MP401. | ||
974 | |||
975 | config SOUND_UART6850 | 693 | config SOUND_UART6850 |
976 | tristate "6850 UART support" | 694 | tristate "6850 UART support" |
977 | depends on SOUND_OSS | 695 | depends on SOUND_OSS |
@@ -1101,30 +819,6 @@ config SOUND_KAHLUA | |||
1101 | tristate "XpressAudio Sound Blaster emulation" | 819 | tristate "XpressAudio Sound Blaster emulation" |
1102 | depends on SOUND_SB | 820 | depends on SOUND_SB |
1103 | 821 | ||
1104 | config SOUND_ALI5455 | ||
1105 | tristate "ALi5455 audio support" | ||
1106 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | ||
1107 | |||
1108 | config SOUND_FORTE | ||
1109 | tristate "ForteMedia FM801 driver" | ||
1110 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | ||
1111 | help | ||
1112 | Say Y or M if you want driver support for the ForteMedia FM801 PCI | ||
1113 | audio controller (Abit AU10, Genius Sound Maker, HP Workstation | ||
1114 | zx2000, and others). | ||
1115 | |||
1116 | config SOUND_RME96XX | ||
1117 | tristate "RME Hammerfall (RME96XX) support" | ||
1118 | depends on SOUND_PRIME && PCI && OBSOLETE_OSS_DRIVER | ||
1119 | help | ||
1120 | Say Y or M if you have a Hammerfall or Hammerfall light | ||
1121 | multichannel card from RME. If you want to access advanced | ||
1122 | features of the card, read <file:Documentation/sound/oss/rme96xx>. | ||
1123 | |||
1124 | config SOUND_AD1980 | ||
1125 | tristate "AD1980 front/back switch plugin" | ||
1126 | depends on SOUND_PRIME && OBSOLETE_OSS_DRIVER | ||
1127 | |||
1128 | config SOUND_SH_DAC_AUDIO | 822 | config SOUND_SH_DAC_AUDIO |
1129 | tristate "SuperH DAC audio support" | 823 | tristate "SuperH DAC audio support" |
1130 | depends on SOUND_PRIME && CPU_SH3 | 824 | depends on SOUND_PRIME && CPU_SH3 |
diff --git a/sound/oss/ad1889.c b/sound/oss/ad1889.c index 54dabf862802..a4ca7569e700 100644 --- a/sound/oss/ad1889.c +++ b/sound/oss/ad1889.c | |||
@@ -75,7 +75,7 @@ static inline void ad1889_set_wav_rate(ad1889_dev_t *dev, int rate) | |||
75 | 75 | ||
76 | DBG("Setting WAV rate to %d\n", rate); | 76 | DBG("Setting WAV rate to %d\n", rate); |
77 | dev->state[AD_WAV_STATE].dmabuf.rate = rate; | 77 | dev->state[AD_WAV_STATE].dmabuf.rate = rate; |
78 | AD1889_WRITEW(dev, AD_DSWAS, rate); | 78 | AD1889_WRITEW(dev, AD_DS_WAS, rate); |
79 | 79 | ||
80 | /* Cycle the DAC to enable the new rate */ | 80 | /* Cycle the DAC to enable the new rate */ |
81 | ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0x0200); | 81 | ac97_codec->codec_write(dev->ac97_codec, AC97_POWER_CONTROL, 0x0200); |
@@ -89,14 +89,14 @@ static inline void ad1889_set_wav_fmt(ad1889_dev_t *dev, int fmt) | |||
89 | 89 | ||
90 | DBG("Setting WAV format to 0x%x\n", fmt); | 90 | DBG("Setting WAV format to 0x%x\n", fmt); |
91 | 91 | ||
92 | tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); | 92 | tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC); |
93 | if (fmt & AFMT_S16_LE) { | 93 | if (fmt & AFMT_S16_LE) { |
94 | //tmp |= 0x0100; /* set WA16 */ | 94 | //tmp |= 0x0100; /* set WA16 */ |
95 | tmp |= 0x0300; /* set WA16 stereo */ | 95 | tmp |= 0x0300; /* set WA16 stereo */ |
96 | } else if (fmt & AFMT_U8) { | 96 | } else if (fmt & AFMT_U8) { |
97 | tmp &= ~0x0100; /* clear WA16 */ | 97 | tmp &= ~0x0100; /* clear WA16 */ |
98 | } | 98 | } |
99 | AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); | 99 | AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp); |
100 | } | 100 | } |
101 | 101 | ||
102 | static inline void ad1889_set_adc_fmt(ad1889_dev_t *dev, int fmt) | 102 | static inline void ad1889_set_adc_fmt(ad1889_dev_t *dev, int fmt) |
@@ -105,13 +105,13 @@ static inline void ad1889_set_adc_fmt(ad1889_dev_t *dev, int fmt) | |||
105 | 105 | ||
106 | DBG("Setting ADC format to 0x%x\n", fmt); | 106 | DBG("Setting ADC format to 0x%x\n", fmt); |
107 | 107 | ||
108 | tmp = AD1889_READW(ad1889_dev, AD_DSRAMC); | 108 | tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC); |
109 | if (fmt & AFMT_S16_LE) { | 109 | if (fmt & AFMT_S16_LE) { |
110 | tmp |= 0x0100; /* set WA16 */ | 110 | tmp |= 0x0100; /* set WA16 */ |
111 | } else if (fmt & AFMT_U8) { | 111 | } else if (fmt & AFMT_U8) { |
112 | tmp &= ~0x0100; /* clear WA16 */ | 112 | tmp &= ~0x0100; /* clear WA16 */ |
113 | } | 113 | } |
114 | AD1889_WRITEW(ad1889_dev, AD_DSRAMC, tmp); | 114 | AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp); |
115 | } | 115 | } |
116 | 116 | ||
117 | static void ad1889_start_wav(ad1889_state_t *state) | 117 | static void ad1889_start_wav(ad1889_state_t *state) |
@@ -145,21 +145,21 @@ static void ad1889_start_wav(ad1889_state_t *state) | |||
145 | dmabuf->rd_ptr, dmabuf->dma_len); | 145 | dmabuf->rd_ptr, dmabuf->dma_len); |
146 | 146 | ||
147 | /* load up the current register set */ | 147 | /* load up the current register set */ |
148 | AD1889_WRITEL(ad1889_dev, AD_DMAWAVCC, cnt); | 148 | AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCC, cnt); |
149 | AD1889_WRITEL(ad1889_dev, AD_DMAWAVICC, cnt); | 149 | AD1889_WRITEL(ad1889_dev, AD_DMA_WAVICC, cnt); |
150 | AD1889_WRITEL(ad1889_dev, AD_DMAWAVCA, dmabuf->dma_handle); | 150 | AD1889_WRITEL(ad1889_dev, AD_DMA_WAVCA, dmabuf->dma_handle); |
151 | 151 | ||
152 | /* TODO: for now we load the base registers with the same thing */ | 152 | /* TODO: for now we load the base registers with the same thing */ |
153 | AD1889_WRITEL(ad1889_dev, AD_DMAWAVBC, cnt); | 153 | AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBC, cnt); |
154 | AD1889_WRITEL(ad1889_dev, AD_DMAWAVIBC, cnt); | 154 | AD1889_WRITEL(ad1889_dev, AD_DMA_WAVIBC, cnt); |
155 | AD1889_WRITEL(ad1889_dev, AD_DMAWAVBA, dmabuf->dma_handle); | 155 | AD1889_WRITEL(ad1889_dev, AD_DMA_WAVBA, dmabuf->dma_handle); |
156 | 156 | ||
157 | /* and we're off to the races... */ | 157 | /* and we're off to the races... */ |
158 | AD1889_WRITEL(ad1889_dev, AD_DMACHSS, 0x8); | 158 | AD1889_WRITEL(ad1889_dev, AD_DMA_CHSS, 0x8); |
159 | tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); | 159 | tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC); |
160 | tmp |= 0x0400; /* set WAEN */ | 160 | tmp |= 0x0400; /* set WAEN */ |
161 | AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); | 161 | AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp); |
162 | (void) AD1889_READW(ad1889_dev, AD_DSWSMC); /* flush posted PCI write */ | 162 | (void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */ |
163 | 163 | ||
164 | dmabuf->enable |= DAC_RUNNING; | 164 | dmabuf->enable |= DAC_RUNNING; |
165 | 165 | ||
@@ -179,10 +179,10 @@ static void ad1889_stop_wav(ad1889_state_t *state) | |||
179 | u16 tmp; | 179 | u16 tmp; |
180 | unsigned long cnt = dmabuf->dma_len; | 180 | unsigned long cnt = dmabuf->dma_len; |
181 | 181 | ||
182 | tmp = AD1889_READW(ad1889_dev, AD_DSWSMC); | 182 | tmp = AD1889_READW(ad1889_dev, AD_DS_WSMC); |
183 | tmp &= ~0x0400; /* clear WAEN */ | 183 | tmp &= ~0x0400; /* clear WAEN */ |
184 | AD1889_WRITEW(ad1889_dev, AD_DSWSMC, tmp); | 184 | AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, tmp); |
185 | (void) AD1889_READW(ad1889_dev, AD_DSWSMC); /* flush posted PCI write */ | 185 | (void) AD1889_READW(ad1889_dev, AD_DS_WSMC); /* flush posted PCI write */ |
186 | pci_unmap_single(ad1889_dev->pci, dmabuf->dma_handle, | 186 | pci_unmap_single(ad1889_dev->pci, dmabuf->dma_handle, |
187 | cnt, PCI_DMA_TODEVICE); | 187 | cnt, PCI_DMA_TODEVICE); |
188 | 188 | ||
@@ -211,7 +211,7 @@ static void ad1889_startstop_adc(ad1889_state_t *state, int start) | |||
211 | 211 | ||
212 | spin_lock_irqsave(&state->card->lock, flags); | 212 | spin_lock_irqsave(&state->card->lock, flags); |
213 | 213 | ||
214 | tmp = AD1889_READW(ad1889_dev, AD_DSRAMC); | 214 | tmp = AD1889_READW(ad1889_dev, AD_DS_RAMC); |
215 | if (start) { | 215 | if (start) { |
216 | state->dmabuf.enable |= ADC_RUNNING; | 216 | state->dmabuf.enable |= ADC_RUNNING; |
217 | tmp |= 0x0004; /* set ADEN */ | 217 | tmp |= 0x0004; /* set ADEN */ |
@@ -219,7 +219,7 @@ static void ad1889_startstop_adc(ad1889_state_t *state, int start) | |||
219 | state->dmabuf.enable &= ~ADC_RUNNING; | 219 | state->dmabuf.enable &= ~ADC_RUNNING; |
220 | tmp &= ~0x0004; /* clear ADEN */ | 220 | tmp &= ~0x0004; /* clear ADEN */ |
221 | } | 221 | } |
222 | AD1889_WRITEW(ad1889_dev, AD_DSRAMC, tmp); | 222 | AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, tmp); |
223 | 223 | ||
224 | spin_unlock_irqrestore(&state->card->lock, flags); | 224 | spin_unlock_irqrestore(&state->card->lock, flags); |
225 | } | 225 | } |
@@ -301,53 +301,53 @@ static int ad1889_read_proc (char *page, char **start, off_t off, | |||
301 | int len, i; | 301 | int len, i; |
302 | ad1889_dev_t *dev = data; | 302 | ad1889_dev_t *dev = data; |
303 | ad1889_reg_t regs[] = { | 303 | ad1889_reg_t regs[] = { |
304 | { "WSMC", AD_DSWSMC, 16 }, | 304 | { "WSMC", AD_DS_WSMC, 16 }, |
305 | { "RAMC", AD_DSRAMC, 16 }, | 305 | { "RAMC", AD_DS_RAMC, 16 }, |
306 | { "WADA", AD_DSWADA, 16 }, | 306 | { "WADA", AD_DS_WADA, 16 }, |
307 | { "SYDA", AD_DSSYDA, 16 }, | 307 | { "SYDA", AD_DS_SYDA, 16 }, |
308 | { "WAS", AD_DSWAS, 16 }, | 308 | { "WAS", AD_DS_WAS, 16 }, |
309 | { "RES", AD_DSRES, 16 }, | 309 | { "RES", AD_DS_RES, 16 }, |
310 | { "CCS", AD_DSCCS, 16 }, | 310 | { "CCS", AD_DS_CCS, 16 }, |
311 | { "ADCBA", AD_DMAADCBA, 32 }, | 311 | { "ADCBA", AD_DMA_ADCBA, 32 }, |
312 | { "ADCCA", AD_DMAADCCA, 32 }, | 312 | { "ADCCA", AD_DMA_ADCCA, 32 }, |
313 | { "ADCBC", AD_DMAADCBC, 32 }, | 313 | { "ADCBC", AD_DMA_ADCBC, 32 }, |
314 | { "ADCCC", AD_DMAADCCC, 32 }, | 314 | { "ADCCC", AD_DMA_ADCCC, 32 }, |
315 | { "ADCIBC", AD_DMAADCIBC, 32 }, | 315 | { "ADCIBC", AD_DMA_ADCIBC, 32 }, |
316 | { "ADCICC", AD_DMAADCICC, 32 }, | 316 | { "ADCICC", AD_DMA_ADCICC, 32 }, |
317 | { "ADCCTRL", AD_DMAADCCTRL, 16 }, | 317 | { "ADCCTRL", AD_DMA_ADCCTRL, 16 }, |
318 | { "WAVBA", AD_DMAWAVBA, 32 }, | 318 | { "WAVBA", AD_DMA_WAVBA, 32 }, |
319 | { "WAVCA", AD_DMAWAVCA, 32 }, | 319 | { "WAVCA", AD_DMA_WAVCA, 32 }, |
320 | { "WAVBC", AD_DMAWAVBC, 32 }, | 320 | { "WAVBC", AD_DMA_WAVBC, 32 }, |
321 | { "WAVCC", AD_DMAWAVCC, 32 }, | 321 | { "WAVCC", AD_DMA_WAVCC, 32 }, |
322 | { "WAVIBC", AD_DMAWAVIBC, 32 }, | 322 | { "WAVIBC", AD_DMA_WAVIBC, 32 }, |
323 | { "WAVICC", AD_DMAWAVICC, 32 }, | 323 | { "WAVICC", AD_DMA_WAVICC, 32 }, |
324 | { "WAVCTRL", AD_DMAWAVCTRL, 16 }, | 324 | { "WAVCTRL", AD_DMA_WAVCTRL, 16 }, |
325 | { "DISR", AD_DMADISR, 32 }, | 325 | { "DISR", AD_DMA_DISR, 32 }, |
326 | { "CHSS", AD_DMACHSS, 32 }, | 326 | { "CHSS", AD_DMA_CHSS, 32 }, |
327 | { "IPC", AD_GPIOIPC, 16 }, | 327 | { "IPC", AD_GPIO_IPC, 16 }, |
328 | { "OP", AD_GPIOOP, 16 }, | 328 | { "OP", AD_GPIO_OP, 16 }, |
329 | { "IP", AD_GPIOIP, 16 }, | 329 | { "IP", AD_GPIO_IP, 16 }, |
330 | { "ACIC", AD_ACIC, 16 }, | 330 | { "ACIC", AD_AC97_ACIC, 16 }, |
331 | { "AC97_RESET", 0x100 + AC97_RESET, 16 }, | 331 | { "AC97_RESET", AD_AC97_BASE + AC97_RESET, 16 }, |
332 | { "AC97_MASTER_VOL_STEREO", 0x100 + AC97_MASTER_VOL_STEREO, 16 }, | 332 | { "AC97_MASTER_VOL_STEREO", AD_AC97_BASE + AC97_MASTER_VOL_STEREO, 16 }, |
333 | { "AC97_HEADPHONE_VOL", 0x100 + AC97_HEADPHONE_VOL, 16 }, | 333 | { "AC97_HEADPHONE_VOL", AD_AC97_BASE + AC97_HEADPHONE_VOL, 16 }, |
334 | { "AC97_MASTER_VOL_MONO", 0x100 + AC97_MASTER_VOL_MONO, 16 }, | 334 | { "AC97_MASTER_VOL_MONO", AD_AC97_BASE + AC97_MASTER_VOL_MONO, 16 }, |
335 | { "AC97_MASTER_TONE", 0x100 + AC97_MASTER_TONE, 16 }, | 335 | { "AC97_MASTER_TONE", AD_AC97_BASE + AC97_MASTER_TONE, 16 }, |
336 | { "AC97_PCBEEP_VOL", 0x100 + AC97_PCBEEP_VOL, 16 }, | 336 | { "AC97_PCBEEP_VOL", AD_AC97_BASE + AC97_PCBEEP_VOL, 16 }, |
337 | { "AC97_PHONE_VOL", 0x100 + AC97_PHONE_VOL, 16 }, | 337 | { "AC97_PHONE_VOL", AD_AC97_BASE + AC97_PHONE_VOL, 16 }, |
338 | { "AC97_MIC_VOL", 0x100 + AC97_MIC_VOL, 16 }, | 338 | { "AC97_MIC_VOL", AD_AC97_BASE + AC97_MIC_VOL, 16 }, |
339 | { "AC97_LINEIN_VOL", 0x100 + AC97_LINEIN_VOL, 16 }, | 339 | { "AC97_LINEIN_VOL", AD_AC97_BASE + AC97_LINEIN_VOL, 16 }, |
340 | { "AC97_CD_VOL", 0x100 + AC97_CD_VOL, 16 }, | 340 | { "AC97_CD_VOL", AD_AC97_BASE + AC97_CD_VOL, 16 }, |
341 | { "AC97_VIDEO_VOL", 0x100 + AC97_VIDEO_VOL, 16 }, | 341 | { "AC97_VIDEO_VOL", AD_AC97_BASE + AC97_VIDEO_VOL, 16 }, |
342 | { "AC97_AUX_VOL", 0x100 + AC97_AUX_VOL, 16 }, | 342 | { "AC97_AUX_VOL", AD_AC97_BASE + AC97_AUX_VOL, 16 }, |
343 | { "AC97_PCMOUT_VOL", 0x100 + AC97_PCMOUT_VOL, 16 }, | 343 | { "AC97_PCMOUT_VOL", AD_AC97_BASE + AC97_PCMOUT_VOL, 16 }, |
344 | { "AC97_RECORD_SELECT", 0x100 + AC97_RECORD_SELECT, 16 }, | 344 | { "AC97_RECORD_SELECT", AD_AC97_BASE + AC97_RECORD_SELECT, 16 }, |
345 | { "AC97_RECORD_GAIN", 0x100 + AC97_RECORD_GAIN, 16 }, | 345 | { "AC97_RECORD_GAIN", AD_AC97_BASE + AC97_RECORD_GAIN, 16 }, |
346 | { "AC97_RECORD_GAIN_MIC", 0x100 + AC97_RECORD_GAIN_MIC, 16 }, | 346 | { "AC97_RECORD_GAIN_MIC", AD_AC97_BASE + AC97_RECORD_GAIN_MIC, 16 }, |
347 | { "AC97_GENERAL_PURPOSE", 0x100 + AC97_GENERAL_PURPOSE, 16 }, | 347 | { "AC97_GENERAL_PURPOSE", AD_AC97_BASE + AC97_GENERAL_PURPOSE, 16 }, |
348 | { "AC97_3D_CONTROL", 0x100 + AC97_3D_CONTROL, 16 }, | 348 | { "AC97_3D_CONTROL", AD_AC97_BASE + AC97_3D_CONTROL, 16 }, |
349 | { "AC97_MODEM_RATE", 0x100 + AC97_MODEM_RATE, 16 }, | 349 | { "AC97_MODEM_RATE", AD_AC97_BASE + AC97_MODEM_RATE, 16 }, |
350 | { "AC97_POWER_CONTROL", 0x100 + AC97_POWER_CONTROL, 16 }, | 350 | { "AC97_POWER_CONTROL", AD_AC97_BASE + AC97_POWER_CONTROL, 16 }, |
351 | { NULL } | 351 | { NULL } |
352 | }; | 352 | }; |
353 | 353 | ||
@@ -400,9 +400,9 @@ static inline unsigned long ad1889_get_dma_addr(ad1889_state_t *state) | |||
400 | } | 400 | } |
401 | 401 | ||
402 | if (dmabuf->enable & DAC_RUNNING) | 402 | if (dmabuf->enable & DAC_RUNNING) |
403 | offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAWAVBA)); | 403 | offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_WAVBA)); |
404 | else | 404 | else |
405 | offset = le32_to_cpu(AD1889_READL(state->card, AD_DMAADCBA)); | 405 | offset = le32_to_cpu(AD1889_READL(state->card, AD_DMA_ADCBA)); |
406 | 406 | ||
407 | return (unsigned long)bus_to_virt((unsigned long)offset) - (unsigned long)dmabuf->rawbuf; | 407 | return (unsigned long)bus_to_virt((unsigned long)offset) - (unsigned long)dmabuf->rawbuf; |
408 | } | 408 | } |
@@ -639,9 +639,9 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
639 | if (val > 5400 && val < 48000) | 639 | if (val > 5400 && val < 48000) |
640 | { | 640 | { |
641 | if (file->f_mode & FMODE_WRITE) | 641 | if (file->f_mode & FMODE_WRITE) |
642 | AD1889_WRITEW(ad1889_dev, AD_DSWAS, val); | 642 | AD1889_WRITEW(ad1889_dev, AD_DS_WAS, val); |
643 | if (file->f_mode & FMODE_READ) | 643 | if (file->f_mode & FMODE_READ) |
644 | AD1889_WRITEW(ad1889_dev, AD_DSRES, val); | 644 | AD1889_WRITEW(ad1889_dev, AD_DS_RES, val); |
645 | } | 645 | } |
646 | return 0; | 646 | return 0; |
647 | 647 | ||
@@ -649,22 +649,22 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
649 | if (get_user(val, p)) | 649 | if (get_user(val, p)) |
650 | return -EFAULT; | 650 | return -EFAULT; |
651 | if (file->f_mode & FMODE_READ) { | 651 | if (file->f_mode & FMODE_READ) { |
652 | val = AD1889_READW(ad1889_dev, AD_DSWSMC); | 652 | val = AD1889_READW(ad1889_dev, AD_DS_WSMC); |
653 | if (val) { | 653 | if (val) { |
654 | val |= 0x0200; /* set WAST */ | 654 | val |= 0x0200; /* set WAST */ |
655 | } else { | 655 | } else { |
656 | val &= ~0x0200; /* clear WAST */ | 656 | val &= ~0x0200; /* clear WAST */ |
657 | } | 657 | } |
658 | AD1889_WRITEW(ad1889_dev, AD_DSWSMC, val); | 658 | AD1889_WRITEW(ad1889_dev, AD_DS_WSMC, val); |
659 | } | 659 | } |
660 | if (file->f_mode & FMODE_WRITE) { | 660 | if (file->f_mode & FMODE_WRITE) { |
661 | val = AD1889_READW(ad1889_dev, AD_DSRAMC); | 661 | val = AD1889_READW(ad1889_dev, AD_DS_RAMC); |
662 | if (val) { | 662 | if (val) { |
663 | val |= 0x0002; /* set ADST */ | 663 | val |= 0x0002; /* set ADST */ |
664 | } else { | 664 | } else { |
665 | val &= ~0x0002; /* clear ADST */ | 665 | val &= ~0x0002; /* clear ADST */ |
666 | } | 666 | } |
667 | AD1889_WRITEW(ad1889_dev, AD_DSRAMC, val); | 667 | AD1889_WRITEW(ad1889_dev, AD_DS_RAMC, val); |
668 | } | 668 | } |
669 | 669 | ||
670 | return 0; | 670 | return 0; |
@@ -739,7 +739,7 @@ static int ad1889_ioctl(struct inode *inode, struct file *file, unsigned int cmd | |||
739 | break; | 739 | break; |
740 | 740 | ||
741 | case SOUND_PCM_READ_RATE: | 741 | case SOUND_PCM_READ_RATE: |
742 | return put_user(AD1889_READW(ad1889_dev, AD_DSWAS), p); | 742 | return put_user(AD1889_READW(ad1889_dev, AD_DS_WAS), p); |
743 | 743 | ||
744 | case SOUND_PCM_READ_CHANNELS: | 744 | case SOUND_PCM_READ_CHANNELS: |
745 | case SOUND_PCM_READ_BITS: | 745 | case SOUND_PCM_READ_BITS: |
@@ -769,7 +769,7 @@ static int ad1889_open(struct inode *inode, struct file *file) | |||
769 | 769 | ||
770 | ad1889_set_wav_rate(ad1889_dev, 48000); | 770 | ad1889_set_wav_rate(ad1889_dev, 48000); |
771 | ad1889_set_wav_fmt(ad1889_dev, AFMT_S16_LE); | 771 | ad1889_set_wav_fmt(ad1889_dev, AFMT_S16_LE); |
772 | AD1889_WRITEW(ad1889_dev, AD_DSWADA, 0x0404); /* attenuation */ | 772 | AD1889_WRITEW(ad1889_dev, AD_DS_WADA, 0x0404); /* attenuation */ |
773 | return nonseekable_open(inode, file); | 773 | return nonseekable_open(inode, file); |
774 | } | 774 | } |
775 | 775 | ||
@@ -826,15 +826,15 @@ static void ad1889_codec_write(struct ac97_codec *ac97, u8 reg, u16 val) | |||
826 | { | 826 | { |
827 | ad1889_dev_t *dev = ac97->private_data; | 827 | ad1889_dev_t *dev = ac97->private_data; |
828 | 828 | ||
829 | //DBG("Writing 0x%x to 0x%lx\n", val, dev->regbase + 0x100 + reg); | 829 | //DBG("Writing 0x%x to 0x%lx\n", val, dev->regbase + AD_AC97_BASE + reg); |
830 | AD1889_WRITEW(dev, 0x100 + reg, val); | 830 | AD1889_WRITEW(dev, AD_AC97_BASE + reg, val); |
831 | } | 831 | } |
832 | 832 | ||
833 | static u16 ad1889_codec_read(struct ac97_codec *ac97, u8 reg) | 833 | static u16 ad1889_codec_read(struct ac97_codec *ac97, u8 reg) |
834 | { | 834 | { |
835 | ad1889_dev_t *dev = ac97->private_data; | 835 | ad1889_dev_t *dev = ac97->private_data; |
836 | //DBG("Reading from 0x%lx\n", dev->regbase + 0x100 + reg); | 836 | //DBG("Reading from 0x%lx\n", dev->regbase + AD_AC97_BASE + reg); |
837 | return AD1889_READW(dev, 0x100 + reg); | 837 | return AD1889_READW(dev, AD_AC97_BASE + reg); |
838 | } | 838 | } |
839 | 839 | ||
840 | static int ad1889_ac97_init(ad1889_dev_t *dev, int id) | 840 | static int ad1889_ac97_init(ad1889_dev_t *dev, int id) |
@@ -883,24 +883,24 @@ static int ad1889_aclink_reset(struct pci_dev * pcidev) | |||
883 | int retry = 200; | 883 | int retry = 200; |
884 | ad1889_dev_t *dev = pci_get_drvdata(pcidev); | 884 | ad1889_dev_t *dev = pci_get_drvdata(pcidev); |
885 | 885 | ||
886 | AD1889_WRITEW(dev, AD_DSCCS, 0x8000); /* turn on clock */ | 886 | AD1889_WRITEW(dev, AD_DS_CCS, 0x8000); /* turn on clock */ |
887 | AD1889_READW(dev, AD_DSCCS); | 887 | AD1889_READW(dev, AD_DS_CCS); |
888 | 888 | ||
889 | WAIT_10MS(); | 889 | WAIT_10MS(); |
890 | 890 | ||
891 | stat = AD1889_READW(dev, AD_ACIC); | 891 | stat = AD1889_READW(dev, AD_AC97_ACIC); |
892 | stat |= 0x0002; /* Reset Disable */ | 892 | stat |= 0x0002; /* Reset Disable */ |
893 | AD1889_WRITEW(dev, AD_ACIC, stat); | 893 | AD1889_WRITEW(dev, AD_AC97_ACIC, stat); |
894 | (void) AD1889_READW(dev, AD_ACIC); /* flush posted write */ | 894 | (void) AD1889_READW(dev, AD_AC97_ACIC); /* flush posted write */ |
895 | 895 | ||
896 | udelay(10); | 896 | udelay(10); |
897 | 897 | ||
898 | stat = AD1889_READW(dev, AD_ACIC); | 898 | stat = AD1889_READW(dev, AD_AC97_ACIC); |
899 | stat |= 0x0001; /* Interface Enable */ | 899 | stat |= 0x0001; /* Interface Enable */ |
900 | AD1889_WRITEW(dev, AD_ACIC, stat); | 900 | AD1889_WRITEW(dev, AD_AC97_ACIC, stat); |
901 | 901 | ||
902 | do { | 902 | do { |
903 | if (AD1889_READW(dev, AD_ACIC) & 0x8000) /* Ready */ | 903 | if (AD1889_READW(dev, AD_AC97_ACIC) & 0x8000) /* Ready */ |
904 | break; | 904 | break; |
905 | WAIT_10MS(); | 905 | WAIT_10MS(); |
906 | retry--; | 906 | retry--; |
@@ -908,16 +908,16 @@ static int ad1889_aclink_reset(struct pci_dev * pcidev) | |||
908 | 908 | ||
909 | if (!retry) { | 909 | if (!retry) { |
910 | printk(KERN_ERR "ad1889_aclink_reset: codec is not ready [0x%x]\n", | 910 | printk(KERN_ERR "ad1889_aclink_reset: codec is not ready [0x%x]\n", |
911 | AD1889_READW(dev, AD_ACIC)); | 911 | AD1889_READW(dev, AD_AC97_ACIC)); |
912 | return -EBUSY; | 912 | return -EBUSY; |
913 | } | 913 | } |
914 | 914 | ||
915 | /* TODO reset AC97 codec */ | 915 | /* TODO reset AC97 codec */ |
916 | /* TODO set wave/adc pci ctrl status */ | 916 | /* TODO set wave/adc pci ctrl status */ |
917 | 917 | ||
918 | stat = AD1889_READW(dev, AD_ACIC); | 918 | stat = AD1889_READW(dev, AD_AC97_ACIC); |
919 | stat |= 0x0004; /* Audio Stream Output Enable */ | 919 | stat |= 0x0004; /* Audio Stream Output Enable */ |
920 | AD1889_WRITEW(dev, AD_ACIC, stat); | 920 | AD1889_WRITEW(dev, AD_AC97_ACIC, stat); |
921 | return 0; | 921 | return 0; |
922 | } | 922 | } |
923 | 923 | ||
@@ -935,10 +935,10 @@ static irqreturn_t ad1889_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
935 | u32 stat; | 935 | u32 stat; |
936 | ad1889_dev_t *dev = (ad1889_dev_t *)dev_id; | 936 | ad1889_dev_t *dev = (ad1889_dev_t *)dev_id; |
937 | 937 | ||
938 | stat = AD1889_READL(dev, AD_DMADISR); | 938 | stat = AD1889_READL(dev, AD_DMA_DISR); |
939 | 939 | ||
940 | /* clear ISR */ | 940 | /* clear ISR */ |
941 | AD1889_WRITEL(dev, AD_DMADISR, stat); | 941 | AD1889_WRITEL(dev, AD_DMA_DISR, stat); |
942 | 942 | ||
943 | if (stat & 0x8) { /* WAVI */ | 943 | if (stat & 0x8) { /* WAVI */ |
944 | DBG("WAV interrupt\n"); | 944 | DBG("WAV interrupt\n"); |
@@ -964,15 +964,15 @@ static void ad1889_initcfg(ad1889_dev_t *dev) | |||
964 | u32 tmp32; | 964 | u32 tmp32; |
965 | 965 | ||
966 | /* make sure the interrupt bits are setup the way we want */ | 966 | /* make sure the interrupt bits are setup the way we want */ |
967 | tmp32 = AD1889_READL(dev, AD_DMAWAVCTRL); | 967 | tmp32 = AD1889_READL(dev, AD_DMA_WAVCTRL); |
968 | tmp32 &= ~0xff; /* flat dma, no sg, mask out the intr bits */ | 968 | tmp32 &= ~0xff; /* flat dma, no sg, mask out the intr bits */ |
969 | tmp32 |= 0x6; /* intr on count, loop */ | 969 | tmp32 |= 0x6; /* intr on count, loop */ |
970 | AD1889_WRITEL(dev, AD_DMAWAVCTRL, tmp32); | 970 | AD1889_WRITEL(dev, AD_DMA_WAVCTRL, tmp32); |
971 | 971 | ||
972 | /* unmute... */ | 972 | /* unmute... */ |
973 | tmp16 = AD1889_READW(dev, AD_DSWADA); | 973 | tmp16 = AD1889_READW(dev, AD_DS_WADA); |
974 | tmp16 &= ~0x8080; | 974 | tmp16 &= ~0x8080; |
975 | AD1889_WRITEW(dev, AD_DSWADA, tmp16); | 975 | AD1889_WRITEW(dev, AD_DS_WADA, tmp16); |
976 | } | 976 | } |
977 | 977 | ||
978 | static int __devinit ad1889_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) | 978 | static int __devinit ad1889_probe(struct pci_dev *pcidev, const struct pci_device_id *ent) |
@@ -1005,7 +1005,7 @@ static int __devinit ad1889_probe(struct pci_dev *pcidev, const struct pci_devic | |||
1005 | goto out1; | 1005 | goto out1; |
1006 | } | 1006 | } |
1007 | 1007 | ||
1008 | dev->regbase = ioremap_nocache(bar, AD_DSIOMEMSIZE); | 1008 | dev->regbase = ioremap_nocache(bar, AD_DS_IOMEMSIZE); |
1009 | if (!dev->regbase) { | 1009 | if (!dev->regbase) { |
1010 | printk(KERN_ERR DEVNAME ": unable to remap iomem\n"); | 1010 | printk(KERN_ERR DEVNAME ": unable to remap iomem\n"); |
1011 | goto out2; | 1011 | goto out2; |
diff --git a/sound/oss/ad1889.h b/sound/oss/ad1889.h index 861b3213f30b..09913765967a 100644 --- a/sound/oss/ad1889.h +++ b/sound/oss/ad1889.h | |||
@@ -1,57 +1,58 @@ | |||
1 | #ifndef _AD1889_H_ | 1 | #ifndef _AD1889_H_ |
2 | #define _AD1889_H_ | 2 | #define _AD1889_H_ |
3 | 3 | ||
4 | #define AD_DSWSMC 0x00 /* DMA input wave/syn mixer control */ | 4 | #define AD_DS_WSMC 0x00 /* DMA input wave/syn mixer control */ |
5 | #define AD_DSRAMC 0x02 /* DMA output resamp/ADC mixer control */ | 5 | #define AD_DS_RAMC 0x02 /* DMA output resamp/ADC mixer control */ |
6 | #define AD_DSWADA 0x04 /* DMA input wave attenuation */ | 6 | #define AD_DS_WADA 0x04 /* DMA input wave attenuation */ |
7 | #define AD_DSSYDA 0x06 /* DMA input syn attentuation */ | 7 | #define AD_DS_SYDA 0x06 /* DMA input syn attentuation */ |
8 | #define AD_DSWAS 0x08 /* wave input sample rate */ | 8 | #define AD_DS_WAS 0x08 /* wave input sample rate */ |
9 | #define AD_DSRES 0x0a /* resampler output sample rate */ | 9 | #define AD_DS_RES 0x0a /* resampler output sample rate */ |
10 | #define AD_DSCCS 0x0c /* chip control/status */ | 10 | #define AD_DS_CCS 0x0c /* chip control/status */ |
11 | 11 | ||
12 | #define AD_DMARESBA 0x40 /* RES base addr */ | 12 | #define AD_DMA_RESBA 0x40 /* RES base addr */ |
13 | #define AD_DMARESCA 0x44 /* RES current addr */ | 13 | #define AD_DMA_RESCA 0x44 /* RES current addr */ |
14 | #define AD_DMARESBC 0x48 /* RES base cnt */ | 14 | #define AD_DMA_RESBC 0x48 /* RES base cnt */ |
15 | #define AD_DMARESCC 0x4c /* RES current count */ | 15 | #define AD_DMA_RESCC 0x4c /* RES current count */ |
16 | #define AD_DMAADCBA 0x50 /* ADC */ | 16 | #define AD_DMA_ADCBA 0x50 /* ADC */ |
17 | #define AD_DMAADCCA 0x54 | 17 | #define AD_DMA_ADCCA 0x54 |
18 | #define AD_DMAADCBC 0x58 | 18 | #define AD_DMA_ADCBC 0x58 |
19 | #define AD_DMAADCCC 0x5c | 19 | #define AD_DMA_ADCCC 0x5c |
20 | #define AD_DMASYNBA 0x60 /* SYN */ | 20 | #define AD_DMA_SYNBA 0x60 /* SYN */ |
21 | #define AD_DMASYNCA 0x64 | 21 | #define AD_DMA_SYNCA 0x64 |
22 | #define AD_DMASYNBC 0x68 | 22 | #define AD_DMA_SYNBC 0x68 |
23 | #define AD_DMASYNCC 0x6c | 23 | #define AD_DMA_SYNCC 0x6c |
24 | #define AD_DMAWAVBA 0x70 /* WAV */ | 24 | #define AD_DMA_WAVBA 0x70 /* WAV */ |
25 | #define AD_DMAWAVCA 0x74 | 25 | #define AD_DMA_WAVCA 0x74 |
26 | #define AD_DMAWAVBC 0x78 | 26 | #define AD_DMA_WAVBC 0x78 |
27 | #define AD_DMAWAVCC 0x7c | 27 | #define AD_DMA_WAVCC 0x7c |
28 | #define AD_DMARESICC 0x80 /* RES interrupt current count */ | 28 | #define AD_DMA_RESICC 0x80 /* RES interrupt current count */ |
29 | #define AD_DMARESIBC 0x84 /* RES interrupt base count */ | 29 | #define AD_DMA_RESIBC 0x84 /* RES interrupt base count */ |
30 | #define AD_DMAADCICC 0x88 /* ADC interrupt current count */ | 30 | #define AD_DMA_ADCICC 0x88 /* ADC interrupt current count */ |
31 | #define AD_DMAADCIBC 0x8c /* ADC interrupt base count */ | 31 | #define AD_DMA_ADCIBC 0x8c /* ADC interrupt base count */ |
32 | #define AD_DMASYNICC 0x90 /* SYN interrupt current count */ | 32 | #define AD_DMA_SYNICC 0x90 /* SYN interrupt current count */ |
33 | #define AD_DMASYNIBC 0x94 /* SYN interrupt base count */ | 33 | #define AD_DMA_SYNIBC 0x94 /* SYN interrupt base count */ |
34 | #define AD_DMAWAVICC 0x98 /* WAV interrupt current count */ | 34 | #define AD_DMA_WAVICC 0x98 /* WAV interrupt current count */ |
35 | #define AD_DMAWAVIBC 0x9c /* WAV interrupt base count */ | 35 | #define AD_DMA_WAVIBC 0x9c /* WAV interrupt base count */ |
36 | #define AD_DMARESCTRL 0xa0 /* RES PCI control/status */ | 36 | #define AD_DMA_RESCTRL 0xa0 /* RES PCI control/status */ |
37 | #define AD_DMAADCCTRL 0xa8 /* ADC PCI control/status */ | 37 | #define AD_DMA_ADCCTRL 0xa8 /* ADC PCI control/status */ |
38 | #define AD_DMASYNCTRL 0xb0 /* SYN PCI control/status */ | 38 | #define AD_DMA_SYNCTRL 0xb0 /* SYN PCI control/status */ |
39 | #define AD_DMAWAVCTRL 0xb8 /* WAV PCI control/status */ | 39 | #define AD_DMA_WAVCTRL 0xb8 /* WAV PCI control/status */ |
40 | #define AD_DMADISR 0xc0 /* PCI DMA intr status */ | 40 | #define AD_DMA_DISR 0xc0 /* PCI DMA intr status */ |
41 | #define AD_DMACHSS 0xc4 /* PCI DMA channel stop status */ | 41 | #define AD_DMA_CHSS 0xc4 /* PCI DMA channel stop status */ |
42 | 42 | ||
43 | #define AD_GPIOIPC 0xc8 /* IO port ctrl */ | 43 | #define AD_GPIO_IPC 0xc8 /* IO port ctrl */ |
44 | #define AD_GPIOOP 0xca /* IO output status */ | 44 | #define AD_GPIO_OP 0xca /* IO output status */ |
45 | #define AD_GPIOIP 0xcc /* IO input status */ | 45 | #define AD_GPIO_IP 0xcc /* IO input status */ |
46 | 46 | ||
47 | /* AC97 registers, 0x100 - 0x17f; see ac97.h */ | 47 | /* AC97 registers, 0x100 - 0x17f; see ac97.h */ |
48 | #define AD_ACIC 0x180 /* AC Link interface ctrl */ | 48 | #define AD_AC97_BASE 0x100 /* ac97 base register */ |
49 | #define AD_AC97_ACIC 0x180 /* AC Link interface ctrl */ | ||
49 | 50 | ||
50 | /* OPL3; BAR1 */ | 51 | /* OPL3; BAR1 */ |
51 | #define AD_OPLM0AS 0x00 /* Music0 address/status */ | 52 | #define AD_OPL_M0AS 0x00 /* Music0 address/status */ |
52 | #define AD_OPLM0DATA 0x01 /* Music0 data */ | 53 | #define AD_OPL_M0DATA 0x01 /* Music0 data */ |
53 | #define AD_OPLM1A 0x02 /* Music1 address */ | 54 | #define AD_OPL_M1A 0x02 /* Music1 address */ |
54 | #define AD_OPLM1DATA 0x03 /* Music1 data */ | 55 | #define AD_OPL_M1DATA 0x03 /* Music1 data */ |
55 | /* 0x04-0x0f reserved */ | 56 | /* 0x04-0x0f reserved */ |
56 | 57 | ||
57 | /* MIDI; BAR2 */ | 58 | /* MIDI; BAR2 */ |
@@ -59,9 +60,9 @@ | |||
59 | #define AD_MISC 0x01 /* MIDI status/cmd */ | 60 | #define AD_MISC 0x01 /* MIDI status/cmd */ |
60 | /* 0x02-0xff reserved */ | 61 | /* 0x02-0xff reserved */ |
61 | 62 | ||
62 | #define AD_DSIOMEMSIZE 512 | 63 | #define AD_DS_IOMEMSIZE 512 |
63 | #define AD_OPLMEMSIZE 16 | 64 | #define AD_OPL_MEMSIZE 16 |
64 | #define AD_MIDIMEMSIZE 16 | 65 | #define AD_MIDI_MEMSIZE 16 |
65 | 66 | ||
66 | #define AD_WAV_STATE 0 | 67 | #define AD_WAV_STATE 0 |
67 | #define AD_ADC_STATE 1 | 68 | #define AD_ADC_STATE 1 |
diff --git a/sound/oss/dmasound/tas_common.c b/sound/oss/dmasound/tas_common.c index 81315996c0f1..882ae98a41b1 100644 --- a/sound/oss/dmasound/tas_common.c +++ b/sound/oss/dmasound/tas_common.c | |||
@@ -195,8 +195,8 @@ tas_init(int driver_id, const char *driver_name) | |||
195 | 195 | ||
196 | printk(KERN_INFO "tas driver [%s])\n", driver_name); | 196 | printk(KERN_INFO "tas driver [%s])\n", driver_name); |
197 | 197 | ||
198 | #ifndef CONFIG_I2C_KEYWEST | 198 | #ifndef CONFIG_I2C_POWERMAC |
199 | request_module("i2c-keywest"); | 199 | request_module("i2c-powermac"); |
200 | #endif | 200 | #endif |
201 | tas_node = find_devices("deq"); | 201 | tas_node = find_devices("deq"); |
202 | if (tas_node == NULL) | 202 | if (tas_node == NULL) |
diff --git a/sound/ppc/daca.c b/sound/ppc/daca.c index aa09ebd9ffb8..46eebf5610e3 100644 --- a/sound/ppc/daca.c +++ b/sound/ppc/daca.c | |||
@@ -255,7 +255,7 @@ int __init snd_pmac_daca_init(struct snd_pmac *chip) | |||
255 | 255 | ||
256 | #ifdef CONFIG_KMOD | 256 | #ifdef CONFIG_KMOD |
257 | if (current->fs->root) | 257 | if (current->fs->root) |
258 | request_module("i2c-keywest"); | 258 | request_module("i2c-powermac"); |
259 | #endif /* CONFIG_KMOD */ | 259 | #endif /* CONFIG_KMOD */ |
260 | 260 | ||
261 | mix = kmalloc(sizeof(*mix), GFP_KERNEL); | 261 | mix = kmalloc(sizeof(*mix), GFP_KERNEL); |
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 1146dd882bb1..70e4ebc70260 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c | |||
@@ -1313,7 +1313,7 @@ int __init snd_pmac_tumbler_init(struct snd_pmac *chip) | |||
1313 | 1313 | ||
1314 | #ifdef CONFIG_KMOD | 1314 | #ifdef CONFIG_KMOD |
1315 | if (current->fs->root) | 1315 | if (current->fs->root) |
1316 | request_module("i2c-keywest"); | 1316 | request_module("i2c-powermac"); |
1317 | #endif /* CONFIG_KMOD */ | 1317 | #endif /* CONFIG_KMOD */ |
1318 | 1318 | ||
1319 | mix = kmalloc(sizeof(*mix), GFP_KERNEL); | 1319 | mix = kmalloc(sizeof(*mix), GFP_KERNEL); |
diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index 33dbcbf77c5b..83acd6cc0b3c 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c | |||
@@ -471,6 +471,7 @@ int main (int argc, char *argv[]) | |||
471 | "ERROR: incorrect format, could not locate file type line %d: '%s'\n", | 471 | "ERROR: incorrect format, could not locate file type line %d: '%s'\n", |
472 | line_nr, line); | 472 | line_nr, line); |
473 | ec = -1; | 473 | ec = -1; |
474 | break; | ||
474 | } | 475 | } |
475 | 476 | ||
476 | if ('\n' == *type) { | 477 | if ('\n' == *type) { |
@@ -506,7 +507,8 @@ int main (int argc, char *argv[]) | |||
506 | line_nr, line); | 507 | line_nr, line); |
507 | } | 508 | } |
508 | } | 509 | } |
509 | cpio_trailer(); | 510 | if (ec == 0) |
511 | cpio_trailer(); | ||
510 | 512 | ||
511 | exit(ec); | 513 | exit(ec); |
512 | } | 514 | } |